[cups.development] Add Network Printer through libcups API

Michael Sweet msweet at apple.com
Wed Aug 31 10:03:33 PDT 2011


There really is no way to do this in a generic way. You could potentially use the SNMP backend to probe the IP address for a preferred device-uri, make-and-model, and 1284 device ID, and then use the make-and-model and device ID information you get back as input to a CUPS_GET_PPDS request (see the lpinfo sources) which will provide suggested drivers.

However, I question why you are doing this in the first place - Apple already supplies UI that does this (including the IP address) when you add a printer from the Print & Scan pref pane.  Is there some reason you need to duplicate the system-supplied UI?

On Aug 31, 2011, at 9:58 AM, Azuri wrote:

> 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
>> 
>> 
>> 
>> 
>> 
> 
> _______________________________________________
> 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-devel mailing list