r21861: Pull the comment and location from CUPS if we don't have one
authorGerald Carter <jerry@samba.org>
Fri, 16 Mar 2007 21:46:58 +0000 (21:46 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:18:39 +0000 (12:18 -0500)
when fetching a printer from ntprinters.tdb.

Slightly modified from original version submitted on
samba-technical ml by Andy Polyakov <appro@fy.chalmers.se>
(This used to be commit e859e1fdcd13c55746a53b5de4a02a3278f41815)

source3/printing/nt_printing.c
source3/printing/print_cups.c

index b3c04913f132258f6b09852ed34739ea37c0fcd0..6289be3e5fb19170cc9cab68c07d1825c494f07e 100644 (file)
@@ -3864,6 +3864,15 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, const char *servern
 
        fstrcpy(info->printername, printername);
 
+#ifdef HAVE_CUPS
+       if ( (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {           
+               /* Pull the location and comment strings from cups if we don't
+                  already have one */
+               if ( !strlen(info->location) || !strlen(info->comment) )
+                       cups_pull_comment_location( info );
+       }
+#endif
+
        len += unpack_devicemode(&info->devmode,dbuf.dptr+len, dbuf.dsize-len);
 
        /*
index 2c942627c6bae50efef8d824cc3b250c5e57824a..0fa73e5a6ca02c7dfa2c8271d3e4e13c15e62fab 100644 (file)
@@ -1198,6 +1198,145 @@ struct printif  cups_printif =
        cups_job_submit,
 };
 
+BOOL cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)
+{
+       http_t          *http = NULL;           /* HTTP connection to server */
+       ipp_t           *request = NULL,        /* IPP Request */
+                       *response = NULL;       /* IPP Response */
+       ipp_attribute_t *attr;          /* Current attribute */
+       cups_lang_t     *language = NULL;       /* Default language */
+       char            *name,          /* printer-name attribute */
+                       *info,          /* printer-info attribute */
+                       *location;      /* printer-location attribute */
+       char            uri[HTTP_MAX_URI];
+       static const char *requested[] =/* Requested attributes */
+                       {
+                         "printer-name",
+                         "printer-info",
+                         "printer-location"
+                       };
+       BOOL ret = False;
+
+       DEBUG(5, ("pulling %s location\n", printer->sharename));
+
+       /*
+        * Make sure we don't ask for passwords...
+        */
+
+        cupsSetPasswordCB(cups_passwd_cb);
+
+       /*
+        * Try to connect to the server...
+        */
+
+       if ((http = cups_connect()) == NULL) {
+               goto out;
+       }
+
+       request = ippNew();
+
+       request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+       request->request.op.request_id   = 1;
+
+       language = cupsLangDefault();
+
+       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+                     "attributes-charset", NULL, cupsLangEncoding(language));
+
+       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+                     "attributes-natural-language", NULL, language->language);
+
+       slprintf(uri, sizeof(uri) - 1, "ipp://%s/printers/%s",
+                lp_cups_server(), printer->sharename);
+
+       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+                     "printer-uri", NULL, uri);
+
+        ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+                     "requested-attributes",
+                     (sizeof(requested) / sizeof(requested[0])),
+                     NULL, requested);
+
+       /*
+        * Do the request and get back a response...
+        */
+
+       if ((response = cupsDoRequest(http, request, "/")) == NULL) {
+               DEBUG(0,("Unable to get printer attributes - %s\n",
+                        ippErrorString(cupsLastError())));
+               goto out;
+       }
+
+       for (attr = response->attrs; attr != NULL;) {
+               /*
+                * Skip leading attributes until we hit a printer...
+                */
+
+               while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+                       attr = attr->next;
+
+               if (attr == NULL)
+                       break;
+
+               /*
+                * Pull the needed attributes from this printer...
+                */
+
+               name       = NULL;
+               info       = NULL;
+               location   = NULL;
+
+               while ( attr && (attr->group_tag == IPP_TAG_PRINTER) ) {
+                       /* Grab the comment if we don't have one */
+                       if ( (strcmp(attr->name, "printer-info") == 0)
+                            && (attr->value_tag == IPP_TAG_TEXT)
+                            && !strlen(printer->comment) ) 
+                       {
+                               DEBUG(5,("cups_pull_comment_location: Using cups comment: %s\n",
+                                        attr->values[0].string.text));                         
+                               pstrcpy(printer->comment,attr->values[0].string.text);
+                       }
+
+                       /* Grab the location if we don't have one */ 
+                       if ( (strcmp(attr->name, "printer-location") == 0)
+                            && (attr->value_tag == IPP_TAG_TEXT) 
+                            && !strlen(printer->location) )
+                       {
+                               DEBUG(5,("cups_pull_comment_location: Using cups location: %s\n",
+                                        attr->values[0].string.text));                         
+                               fstrcpy(printer->location,attr->values[0].string.text);
+                       }
+
+                       attr = attr->next;
+               }
+
+               /*
+                * See if we have everything needed...
+                */
+
+               if (name == NULL)
+                       break;
+
+       }
+
+       ippDelete(response);
+       response = NULL;
+
+       ret = True;
+
+ out:
+       if (response)
+               ippDelete(response);
+
+       if (language)
+               cupsLangFree(language);
+
+       if (http)
+               httpClose(http);
+
+       return ret;
+}
+
 #else
  /* this keeps fussy compilers happy */
  void print_cups_dummy(void);