Add Network Printer through libcups API

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


Can you please explain me with a snippet how should I do that? How will I knwo the model and driver for the printer user inputs?
>
> 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