[cups.development] Add Network Printer through libcups API

Chad Hulbert Chad.Hulbert at xerox.com
Wed Aug 31 08:26:44 PDT 2011


I believe a PPD is required.  If you don't have one you will need to create
something basic.

-Chad

On 8/31/11 11:17 AM, "Azuri" <azuri.shah at fmr.com> thusly spake:

> I think I should be using cupsAddDest and cupsSetDest to make it visible in
> mac print UI list, so I added the below code. but it still doesn't show up
>  cups_dest_t *mydest;
>     cups_dest_t *newdest;
>     int num_new_dest;
>     num_new_dest = cupsAddDest(printer, NULL, num_new_dest, &newdest);
>     mydest = cupsGetDest(printer, NULL, num_new_dest, newdest);
>     cupsSetDests2(http,num_new_dest, mydest);
>     cupsFreeDests(num_new_dest, mydest);
> 
> 
>> The code I am using is as below. It shows up as raw printer in cups but when
>> I go to any file and click on print this printer doesn't show up.
>> 
>>    http_t *http ;
>>     char *printer = "Test";
>>     char *device = "socket://10.105.152.49:9100";
>>     char *model = "deskjet.ppd";
>>     ipp_t  *request,  /* IPP Request */
>>     *response;  /* IPP Response */
>>     ipp_t  *request_dev,  /* IPP Request */
>>     *response_dev;  /* IPP Response */
>>     ipp_t  *request_ppd,  /* IPP Request */
>>     *response_ppd;  /* IPP Response */
>>     char  uri[HTTP_MAX_URI]; /* URI for printer/class */
>>     char        uri_dev[HTTP_MAX_URI];
>>     char        uri_ppd[HTTP_MAX_URI];
>> 
>>     /*
>>      * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
>> following
>>      * attributes:
>>      *
>>      *    attributes-charset
>>      *    attributes-natural-language
>>      *    printer-uri
>>      */
>>     http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
>> 
>>     /* set printer device */
>>     request_dev = ippNewRequest(CUPS_ADD_PRINTER);
>> 
>>     httpAssembleURIf(HTTP_URI_CODING_ALL, uri_dev, sizeof(uri_dev), "ipp",
>> NULL,
>>                      "localhost", 0, "/printers/%s", printer);
>>     ippAddString(request_dev, IPP_TAG_OPERATION, IPP_TAG_URI,
>>                  "printer-uri", NULL, uri_dev);
>> 
>>     /*
>>      * Add the device URI...
>>      */
>> 
>>     if (device[0] == '/')
>>     {
>>         /*
>>          * Convert filename to URI...
>>          */
>> 
>>         snprintf(uri_dev, sizeof(uri_dev), "file://%s", device);
>>         ippAddString(request_dev, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri",
>> NULL,
>>                      uri_dev);
>>     }
>>     else
>>         ippAddString(request_dev, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri",
>> NULL,
>>                      device);
>> 
>>     /*
>>      * Do the request and get back a response...
>>      */
>> 
>>     if ((response_dev = cupsDoRequest(http, request_dev, "/admin/")) == NULL)
>>     {
>>         _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString());
>> 
>> //        return (1);
>>     }
>>     else if (response_dev->request.status.status_code > IPP_OK_CONFLICT)
>>     {
>>         _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString());
>> 
>>         ippDelete(response_dev);
>> 
>>   //      return (1);
>>     }
>>     else
>>     {
>>         ippDelete(response_dev);
>> 
>>     //    return (0);
>>     }
>> 
>> 
>>     /* enable_printer */
>>     request = ippNewRequest(CUPS_ADD_PRINTER);
>> 
>>     httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
>>                      "localhost", 0, "/printers/%s", printer);
>>     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
>>                  "printer-uri", NULL, uri);
>> 
>>     ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
>>                   IPP_PRINTER_IDLE);
>> 
>>     ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
>> 
>>     /*
>>      * Do the request and get back a response...
>>      */
>> 
>>     if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
>>     {
>>         _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString());
>> 
>>         //return (1);
>>     }
>>     else if (response->request.status.status_code > IPP_OK_CONFLICT)
>>     {
>>         _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString());
>> 
>>         ippDelete(response);
>> 
>>         //return (1);
>>     }
>>     else
>>     {
>>         ippDelete(response);
>> 
>>         //return (0);
>>     }
>> 
>> 
>> 
>> 
>> 
>> 
>>>> Thanks Chad I was able to add a printer and enebale it and I can see it in
>>>> cups webpage. But the problem is user doesn have PPD file or anything. And
>>>> I am not doing anything for PPD file. After I add the printer I can see it
>>>> on cups webpage but cant see int he print menu on any page,where it lists
>>>> all the printers. So how do I make printer visible there?
>>> 
>>> Thanks,
>>> Azuri
>>> 
>>>> The usage message for lpadmin indicates that -p is how you add a printer,
>>>> which ultimately arrives at set_printer_options().  That's where you should
>>>> be looking.
>>>> 
>>>> -Chad
>>>> 
>>>> On 8/30/11 4:59 PM, "Azuri" <azuri.shah at fmr.com> thusly spake:
>>>> 
>>>>> 
>>>>> The code I am currently using from lpadmin.c file is below. I get error
>>>>> saying
>>>>> can't find printer or class.
>>>>> 
>>>>> 
>>>>>  http_t *http ;
>>>>>     char *printer = "socket://10.105.152.49:9100";
>>>>>     char *pclass;
>>>>>     int  i;   /* Looping var */
>>>>>     ipp_t  *request,  /* IPP Request */
>>>>>     *response;  /* IPP Response */
>>>>>     ipp_attribute_t *attr,  /* Current attribute */
>>>>>     *members;  /* Members in class */
>>>>>     char  uri[HTTP_MAX_URI]; /* URI for printer/class */
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>>     /*
>>>>>      * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
>>>>> following
>>>>>      * attributes:
>>>>>      *
>>>>>      *    attributes-charset
>>>>>      *    attributes-natural-language
>>>>>      *    printer-uri
>>>>>      */
>>>>>     http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
>>>>>     request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
>>>>> 
>>>>>     httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
>>>>>                      "localhost", 0, "/classes/%s", pclass);
>>>>>     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
>>>>>                  "printer-uri", NULL, uri);
>>>>> 
>>>>>     /*
>>>>>      * Do the request and get back a response...
>>>>>      */
>>>>> 
>>>>>     response = cupsDoRequest(http, request, "/");
>>>>> 
>>>>>     /*
>>>>>      * Build a CUPS_ADD_CLASS request, which requires the following
>>>>>      * attributes:
>>>>>      *
>>>>>      *    attributes-charset
>>>>>      *    attributes-natural-language
>>>>>      *    printer-uri
>>>>>      *    member-uris
>>>>>      */
>>>>> 
>>>>>     request = ippNewRequest(CUPS_ADD_CLASS);
>>>>> 
>>>>>     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
>>>>>                  "printer-uri", NULL, uri);
>>>>> 
>>>>>     /*
>>>>>      * See if the printer is already in the class...
>>>>>      */
>>>>> 
>>>>>     if (response != NULL &&
>>>>>         (members = ippFindAttribute(response, "member-names",
>>>>> IPP_TAG_NAME))
>>>>> != NULL)
>>>>>         for (i = 0; i < members->num_values; i ++)
>>>>>             if (strcasecmp(printer, members->values[i].string.text) == 0)
>>>>>             {
>>>>> 
>>>>>                 ippDelete(request);
>>>>>                 ippDelete(response);
>>>>>                 //return (0);
>>>>>             }
>>>>> 
>>>>>     /*
>>>>>      * OK, the printer isn't part of the class, so add it...
>>>>>      */
>>>>> 
>>>>>     httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
>>>>>                      "localhost", 0, "/printers/%s", printer);
>>>>> 
>>>>>     if (response != NULL &&
>>>>>         (members = ippFindAttribute(response, "member-uris", IPP_TAG_URI))
>>>>> !=
>>>>> NULL)
>>>>>     {
>>>>>         /*
>>>>>          * Add the printer to the existing list...
>>>>>          */
>>>>> 
>>>>>         attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI,
>>>>>                              "member-uris", members->num_values + 1, NULL,
>>>>> NULL);
>>>>>         for (i = 0; i < members->num_values; i ++)
>>>>>             attr->values[i].string.text =
>>>>> _cupsStrAlloc(members->values[i].string.text);
>>>>> 
>>>>>         attr->values[i].string.text = _cupsStrAlloc(uri);
>>>>>     }
>>>>>     else
>>>>>         ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris",
>>>>> NULL,
>>>>>                      uri);
>>>>> 
>>>>>     /*
>>>>>      * Then send the request...
>>>>>      */
>>>>> 
>>>>>     ippDelete(response);
>>>>> 
>>>>>     if ((response = cupsDoRequest(http, request, "/admin/")) == NULL)
>>>>>     {
>>>>> 
>>>>>     }
>>>>>     else if (response->request.status.status_code > IPP_OK_CONFLICT)
>>>>>     {
>>>>>         _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString());
>>>>> 
>>>>>         ippDelete(response);
>>>>> 
>>>>>     }
>>>>>     else
>>>>>     {
>>>>>         ippDelete(response);
>>>>> 
>>>>>     }
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>>> I did look at lpadmin.c file both its not working . But I am totally
>>>>>> confusd.
>>>>>> I did look more into add_printer_to_class method but its not working. All
>>>>>> I
>>>>>> want is when user enters socket://123.45.45.67 to UI, my code should go
>>>>>> ahead
>>>>>> and add the printer tot he mac. I have spent hello lot of time trying to
>>>>>> figure this out using API's but no success at all so far. Your help will
>>>>>> be
>>>>>> appreciated.
>>>>>> 
>>>>>> Russell,
>>>>>>> 
>>>>>>> Just download the CUPS source and look at the lpadmin tool.
>>>>>>> 
>>>>>>> -Chad
>>>>>>> 
>>>>>>> On 8/30/11 4:30 PM, "Azuri" <azuri.shah at fmr.com> thusly spake:
>>>>>>> 
>>>>>>>>> Russell Stewart wrote:
>>>>>>>>>> Michael Sweet wrote:
>>>>>>>>>> 
>>>>>>>>>>> You need to create an IPP request and send it using
>>>>>>>>>>> cupsDoFileRequest
>>>>>>>>>>> (assuming you are using a PPD file or interface script for the
>>>>>>>>>>> queue)
>>>>>>>>>> 
>>>>>>>>>> OK, I see. So I assume that ippNewRequest() is the method to call for
>>>>>>>>>> creating the IPP request, right?
>>>>>>>>> 
>>>>>>>>> Yes.  See the "CUPS Implementation of IPP" document for documentation
>>>>>>>>> on the attributes and operations:
>>>>>>>>> 
>>>>>>>>>      http://www.cups.org/documentation.php/spec-ipp.html
>>>>>>>>> 
>>>>>>>>> --
>>>>>>>>> ______________________________________________________________________
>>>>>>>>> Michael Sweet, Easy Software Products           mike at easysw dot com
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Can you please provice code on how u did it? I am trying to do the same
>>>>>>>> time
>>>>>>>> but have no success so far. How can I use API's to add printer to my
>>>>>>>> mac. I
>>>>>>>> am
>>>>>>>> developing a Coca app which provides GUI and takes user input to add
>>>>>>>> printer
>>>>>>>> using cups. Please let me know
>>>>>>>> _______________________________________________
>>>>>>>> cups-dev mailing list
>>>>>>>> cups-dev at easysw.com
>>>>>>>> http://lists.easysw.com/mailman/listinfo/cups-dev
>>>>>>> 
>>>>>>> Chad Hulbert
>>>>>>> Software Engineer
>>>>>>> Xerox Corporation
>>>>>>> 800 Phillips Rd
>>>>>>> Webster, NY 14580
>>>>>>> 
>>>>>>> p 585.427.3295  (8*707.3295)
>>>>>>> 
>>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> cups-dev mailing list
>>>>> cups-dev at easysw.com
>>>>> http://lists.easysw.com/mailman/listinfo/cups-dev
>>>> 
>>>> Chad Hulbert
>>>> Software Engineer
>>>> Xerox Corporation
>>>> 800 Phillips Rd
>>>> Webster, NY 14580
>>>> 
>>>> p 585.427.3295  (8*707.3295)
>>>> 
>>> 
>> 
> 
> _______________________________________________
> cups-dev mailing list
> cups-dev at easysw.com
> http://lists.easysw.com/mailman/listinfo/cups-dev

Chad Hulbert
Software Engineer
Xerox Corporation
800 Phillips Rd
Webster, NY 14580

p 585.427.3295  (8*707.3295)





More information about the cups mailing list