[cups.development] Add Network Printer through libcups API

Michael Sweet msweet at apple.com
Wed Aug 31 09:43:29 PDT 2011


Correct, if you do not associate a PPD with the queue, it will not be visible to Mac applications.

On Aug 31, 2011, at 9:38 AM, Azuri wrote:
> So I dont need to use that? Also why is printer not showing up in File->print menu? is ti because I dont have ppd file?
> 
>> As documented, cupsAddDest DOES NOT ADD A QUEUE.
>> 
>> On Aug 31, 2011, at 8:17 AM, Azuri wrote:
>> 
>>> 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
>> 
>> __________________________________________________
>> Michael Sweet, Senior Printing System Engineer, PWG Chair
>> 
> 
> _______________________________________________
> cups-dev mailing list
> cups-dev at easysw.com
> http://lists.easysw.com/mailman/listinfo/cups-dev

________________________________________________________________________
Michael Sweet, Senior Printing System Engineer, PWG Chair









More information about the cups mailing list