Add Network Printer through libcups API

Azuri azuri.shah at fmr.com
Wed Aug 31 09:58:31 PDT 2011


Ok so can you please tell me how to do that. Only info I would have is user input IP address. So how do i create and associate PPD after that. Can you provide me with code snippet how to do it? I read ppd coumentation but not having any success. Thanks.

> 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