LCOV - code coverage report
Current view: top level - source3/printing - print_iprint.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 510 0.0 %
Date: 2024-04-21 15:09:00 Functions: 0 12 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Support code for Novell iPrint using the Common UNIX Printing
       3             :  * System ("CUPS") libraries
       4             :  *
       5             :  * Copyright 1999-2003 by Michael R Sweet.
       6             :  * Portions Copyright 2005 by Joel J. Smith.
       7             :  *
       8             :  * This program is free software; you can redistribute it and/or modify
       9             :  * it under the terms of the GNU General Public License as published by
      10             :  * the Free Software Foundation; either version 3 of the License, or
      11             :  * (at your option) any later version.
      12             :  *
      13             :  * This program is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  * GNU General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License
      19             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include "includes.h"
      23             : #include "printing.h"
      24             : #include "printing/pcap.h"
      25             : #include "lib/util/string_wrappers.h"
      26             : 
      27             : #ifdef HAVE_IPRINT
      28             : #include <cups/cups.h>
      29             : #include <cups/language.h>
      30             : 
      31             : #define OPERATION_NOVELL_LIST_PRINTERS          0x401A
      32             : #define OPERATION_NOVELL_MGMT                   0x401C
      33             : #define NOVELL_SERVER_SYSNAME                   "sysname="
      34             : #define NOVELL_SERVER_SYSNAME_NETWARE           "NetWare IA32"
      35             : #define NOVELL_SERVER_VERSION_STRING            "iprintserverversion="
      36             : #define NOVELL_SERVER_VERSION_OES_SP1           33554432
      37             : 
      38             : #if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
      39             : #define HAVE_CUPS_1_6 1
      40             : #endif
      41             : 
      42             : #ifndef HAVE_CUPS_1_6
      43             : #define ippGetCount(attr)     attr->num_values
      44             : #define ippGetGroupTag(attr)  attr->group_tag
      45             : #define ippGetName(attr)      attr->name
      46             : #define ippGetValueTag(attr)  attr->value_tag
      47             : #define ippGetStatusCode(ipp) ipp->request.status.status_code
      48             : #define ippGetBoolean(attr, element) attr->values[element].boolean
      49             : #define ippGetInteger(attr, element) attr->values[element].integer
      50             : #define ippGetString(attr, element, language) attr->values[element].string.text
      51             : 
      52             : static ipp_attribute_t *
      53             : ippFirstAttribute(ipp_t *ipp)
      54             : {
      55             :   if (!ipp)
      56             :     return (NULL);
      57             :   return (ipp->current = ipp->attrs);
      58             : }
      59             : 
      60             : static ipp_attribute_t *
      61             : ippNextAttribute(ipp_t *ipp)
      62             : {
      63             :   if (!ipp || !ipp->current)
      64             :     return (NULL);
      65             :   return (ipp->current = ipp->current->next);
      66             : }
      67             : 
      68             : static int ippSetOperation(ipp_t *ipp, ipp_op_t op)
      69             : {
      70             :     ipp->request.op.operation_id = op;
      71             :     return (1);
      72             : }
      73             : 
      74             : static int ippSetRequestId(ipp_t *ipp, int request_id)
      75             : {
      76             :     ipp->request.any.request_id = request_id;
      77             :     return (1);
      78             : }
      79             : #endif
      80             : 
      81             : /*
      82             :  * 'iprint_passwd_cb()' - The iPrint password callback...
      83             :  */
      84             : 
      85             : static const char *                             /* O - Password or NULL */
      86           0 : iprint_passwd_cb(const char *prompt)    /* I - Prompt */
      87             : {
      88             :        /*
      89             :         * Always return NULL to indicate that no password is available...
      90             :         */
      91             : 
      92           0 :         return (NULL);
      93             : }
      94             : 
      95           0 : static const char *iprint_server(void)
      96             : {
      97           0 :         const struct loadparm_substitution *lp_sub =
      98           0 :                 loadparm_s3_global_substitution();
      99           0 :         const char *server = lp_iprint_server(talloc_tos(), lp_sub);
     100             : 
     101           0 :         if ((server != NULL) && (strlen(server) > 0)) {
     102           0 :                 DEBUG(10, ("iprint server explicitly set to %s\n",
     103             :                            server));
     104           0 :                 return server;
     105             :         }
     106             : 
     107           0 :         DEBUG(10, ("iprint server left to default %s\n", cupsServer()));
     108           0 :         return cupsServer();
     109             : }
     110             : 
     111             : /*
     112             :  * Pass in an already connected http_t*
     113             :  * Returns the server version if one can be found, multiplied by
     114             :  * -1 for all NetWare versions.  Returns 0 if a server version
     115             :  * cannot be determined
     116             :  */
     117             : 
     118           0 : static int iprint_get_server_version(http_t *http, char* serviceUri)
     119             : {
     120           0 :         ipp_t           *request = NULL,        /* IPP Request */
     121           0 :                         *response = NULL;       /* IPP Response */
     122           0 :         ipp_attribute_t *attr;                  /* Current attribute */
     123           0 :         cups_lang_t     *language = NULL;       /* Default language */
     124           0 :         char            *ver;                   /* server version pointer */
     125           0 :         char            *vertmp;                /* server version tmp pointer */
     126           0 :         int             serverVersion = 0;      /* server version */
     127           0 :         char            *os;                    /* server os */
     128           0 :         int             osFlag = 0;             /* 0 for NetWare, 1 for anything else */
     129           0 :         char            *temp;                  /* pointer for string manipulation */
     130             : 
     131             :        /*
     132             :         * Build an OPERATION_NOVELL_MGMT("get-server-version") request,
     133             :         * which requires the following attributes:
     134             :         *
     135             :         *    attributes-charset
     136             :         *    attributes-natural-language
     137             :         *    operation-name
     138             :         *    service-uri
     139             :         */
     140             : 
     141           0 :         request = ippNew();
     142             : 
     143           0 :         ippSetOperation(request, (ipp_op_t)OPERATION_NOVELL_MGMT);
     144           0 :         ippSetRequestId(request, 1);
     145             : 
     146           0 :         language = cupsLangDefault();
     147             : 
     148           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
     149             :                      "attributes-charset", NULL, "utf-8");
     150             : 
     151           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
     152           0 :                      "attributes-natural-language", NULL, language->language);
     153             : 
     154           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
     155             :                      "service-uri", NULL, serviceUri);
     156             : 
     157           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
     158             :                       "operation-name", NULL, "get-server-version");
     159             : 
     160             :        /*
     161             :         * Do the request and get back a response...
     162             :         */
     163             : 
     164           0 :         if (((response = cupsDoRequest(http, request, "/ipp/")) == NULL) ||
     165           0 :             (ippGetStatusCode(response) >= IPP_OK_CONFLICT))
     166           0 :                 goto out;
     167             : 
     168           0 :         if (((attr = ippFindAttribute(response, "server-version",
     169             :                                       IPP_TAG_STRING)) != NULL)) {
     170           0 :                 if ((ver = strstr(ippGetString(attr, 0, NULL),
     171             :                                   NOVELL_SERVER_VERSION_STRING)) != NULL) {
     172           0 :                         ver += strlen(NOVELL_SERVER_VERSION_STRING);
     173             :                        /*
     174             :                         * Strangely, libcups stores a IPP_TAG_STRING (octet
     175             :                         * string) as a null-terminated string with no length
     176             :                         * even though it could be binary data with nulls in
     177             :                         * it.  Luckily, in this case the value is not binary.
     178             :                         */
     179           0 :                         serverVersion = strtol(ver, &vertmp, 10);
     180             : 
     181             :                         /* Check for not found, overflow or negative version */
     182           0 :                         if ((ver == vertmp) || (serverVersion < 0))
     183           0 :                                 serverVersion = 0;
     184             :                 }
     185             : 
     186           0 :                 if ((os = strstr(ippGetString(attr, 0, NULL),
     187             :                                   NOVELL_SERVER_SYSNAME)) != NULL) {
     188           0 :                         os += strlen(NOVELL_SERVER_SYSNAME);
     189           0 :                         if ((temp = strchr(os,'<')) != NULL)
     190           0 :                                 *temp = '\0';
     191           0 :                         if (strcmp(os,NOVELL_SERVER_SYSNAME_NETWARE))
     192           0 :                                 osFlag = 1; /* 1 for non-NetWare systems */
     193             :                 }
     194             :         }
     195             : 
     196           0 :  out:
     197           0 :         if (response)
     198           0 :                 ippDelete(response);
     199             : 
     200           0 :         if (language)
     201           0 :                 cupsLangFree(language);
     202             : 
     203           0 :         if (osFlag == 0)
     204           0 :                 serverVersion *= -1;
     205             : 
     206           0 :         return serverVersion;
     207             : }
     208             : 
     209             : 
     210           0 : static int iprint_cache_add_printer(http_t *http,
     211             :                                    int reqId,
     212             :                                    const char *url,
     213             :                                    struct pcap_cache **pcache)
     214             : {
     215           0 :         ipp_t           *request = NULL,        /* IPP Request */
     216           0 :                         *response = NULL;       /* IPP Response */
     217           0 :         ipp_attribute_t *attr;                  /* Current attribute */
     218           0 :         cups_lang_t     *language = NULL;       /* Default language */
     219           0 :         const char      *name,                  /* printer-name attribute */
     220             :                         *info;                  /* printer-info attribute */
     221           0 :         char            smb_enabled,            /* smb-enabled attribute */
     222             :                         secure;                 /* security-enabled attrib. */
     223             : 
     224           0 :         const char      *httpPath;      /* path portion of the printer-uri */
     225             : 
     226           0 :         static const char *pattrs[] =   /* Requested printer attributes */
     227             :                         {
     228             :                           "printer-name",
     229             :                           "security-enabled",
     230             :                           "printer-info",
     231             :                           "smb-enabled"
     232             :                         };
     233             : 
     234           0 :         request = ippNew();
     235             : 
     236           0 :         ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES);
     237           0 :         ippSetRequestId(request, reqId);
     238             : 
     239           0 :         language = cupsLangDefault();
     240             : 
     241           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
     242             :                      "attributes-charset", NULL, "utf-8");
     243             : 
     244           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
     245           0 :                      "attributes-natural-language", NULL, language->language);
     246             : 
     247           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, url);
     248             : 
     249           0 :         ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
     250             :                       "requested-attributes",
     251             :                       (sizeof(pattrs) / sizeof(pattrs[0])),
     252             :                       NULL, pattrs);
     253             : 
     254             :         /*
     255             :          * Do the request and get back a response...
     256             :          */
     257             : 
     258           0 :         if ((httpPath = strstr(url,"://")) == NULL ||
     259           0 :                         (httpPath = strchr(httpPath+3,'/')) == NULL)
     260             :         {
     261           0 :                 ippDelete(request);
     262           0 :                 request = NULL;
     263           0 :                 goto out;
     264             :         }
     265             : 
     266           0 :         if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
     267           0 :                 ipp_status_t lastErr = cupsLastError();
     268             : 
     269             :                /*
     270             :                 * Ignore printers that cannot be queried without credentials
     271             :                 */
     272           0 :                 if (lastErr == IPP_FORBIDDEN ||
     273           0 :                     lastErr == IPP_NOT_AUTHENTICATED ||
     274             :                     lastErr == IPP_NOT_AUTHORIZED)
     275           0 :                         goto out;
     276             : 
     277           0 :                 DEBUG(0,("Unable to get printer list - %s\n",
     278             :                       ippErrorString(lastErr)));
     279           0 :                 goto out;
     280             :         }
     281             : 
     282           0 :         for (attr = ippFirstAttribute(response); attr != NULL;) {
     283             :                /*
     284             :                 * Skip leading attributes until we hit a printer...
     285             :                 */
     286             : 
     287           0 :                 while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
     288           0 :                         attr = ippNextAttribute(response);
     289             : 
     290           0 :                 if (attr == NULL)
     291           0 :                         break;
     292             : 
     293             :                /*
     294             :                 * Pull the needed attributes from this printer...
     295             :                 */
     296             : 
     297           0 :                 name       = NULL;
     298           0 :                 info       = NULL;
     299           0 :                 smb_enabled= 1;
     300           0 :                 secure     = 0;
     301             : 
     302           0 :                 while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) {
     303           0 :                         if (strcmp(ippGetName(attr), "printer-name") == 0 &&
     304           0 :                             ippGetValueTag(attr) == IPP_TAG_NAME)
     305           0 :                                 name = ippGetString(attr, 0, NULL);
     306             : 
     307           0 :                         if (strcmp(ippGetName(attr), "printer-info") == 0 &&
     308           0 :                             (ippGetValueTag(attr) == IPP_TAG_TEXT ||
     309           0 :                             ippGetValueTag(attr) == IPP_TAG_TEXTLANG))
     310           0 :                                 info = ippGetString(attr, 0, NULL);
     311             : 
     312             :                        /*
     313             :                         * If the smb-enabled attribute is present and the
     314             :                         * value is set to 0, don't show the printer.
     315             :                         * If the attribute is not present, assume that the
     316             :                         * printer should show up
     317             :                         */
     318           0 :                         if (!strcmp(ippGetName(attr), "smb-enabled") &&
     319           0 :                             ((ippGetValueTag(attr) == IPP_TAG_INTEGER &&
     320           0 :                             !ippGetInteger(attr, 0)) ||
     321           0 :                             (ippGetValueTag(attr) == IPP_TAG_BOOLEAN &&
     322           0 :                             !ippGetBoolean(attr, 0))))
     323           0 :                                 smb_enabled = 0;
     324             : 
     325             :                        /*
     326             :                         * If the security-enabled attribute is present and the
     327             :                         * value is set to 1, don't show the printer.
     328             :                         * If the attribute is not present, assume that the
     329             :                         * printer should show up
     330             :                         */
     331           0 :                         if (!strcmp(ippGetName(attr), "security-enabled") &&
     332           0 :                             ((ippGetValueTag(attr) == IPP_TAG_INTEGER &&
     333           0 :                             ippGetInteger(attr, 0)) ||
     334           0 :                             (ippGetValueTag(attr) == IPP_TAG_BOOLEAN &&
     335           0 :                             ippGetBoolean(attr, 0))))
     336           0 :                                 secure = 1;
     337             : 
     338           0 :                         attr = ippNextAttribute(response);
     339             :                 }
     340             : 
     341             :                /*
     342             :                 * See if we have everything needed...
     343             :                 * Make sure the printer is not a secure printer
     344             :                 * and make sure smb printing hasn't been explicitly
     345             :                 * disabled for the printer
     346             :                 */
     347             : 
     348           0 :                 if (name != NULL && !secure && smb_enabled)
     349           0 :                         pcap_cache_add_specific(pcache, name, info, NULL);
     350             :         }
     351             : 
     352           0 :  out:
     353           0 :         if (response)
     354           0 :                 ippDelete(response);
     355           0 :         return(0);
     356             : }
     357             : 
     358           0 : bool iprint_cache_reload(struct pcap_cache **_pcache)
     359             : {
     360           0 :         http_t          *http = NULL;           /* HTTP connection to server */
     361           0 :         ipp_t           *request = NULL,        /* IPP Request */
     362           0 :                         *response = NULL;       /* IPP Response */
     363           0 :         ipp_attribute_t *attr;                  /* Current attribute */
     364           0 :         cups_lang_t     *language = NULL;       /* Default language */
     365           0 :         int             i;
     366           0 :         bool ret = false;
     367           0 :         struct pcap_cache *pcache = NULL;
     368             : 
     369           0 :         DEBUG(5, ("reloading iprint printcap cache\n"));
     370             : 
     371             :        /*
     372             :         * Make sure we don't ask for passwords...
     373             :         */
     374             : 
     375           0 :         cupsSetPasswordCB(iprint_passwd_cb);
     376             : 
     377             :        /*
     378             :         * Try to connect to the server...
     379             :         */
     380             : 
     381             : #ifdef HAVE_HTTPCONNECT2
     382           0 :         http = httpConnect2(iprint_server(),
     383             :                             ippPort(),
     384             :                             NULL,
     385             :                             AF_UNSPEC,
     386             :                             HTTP_ENCRYPTION_NEVER,
     387             :                             1, /* blocking */
     388             :                             30 * 1000, /* timeout */
     389             :                             NULL);
     390             : #else
     391             :         http = httpConnect(iprint_server(), ippPort());
     392             : #endif
     393           0 :         if (http == NULL) {
     394           0 :                 DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
     395             :                          iprint_server(), strerror(errno)));
     396           0 :                 goto out;
     397             :         }
     398             : 
     399             :        /*
     400             :         * Build a OPERATION_NOVELL_LIST_PRINTERS request, which requires the following attributes:
     401             :         *
     402             :         *    attributes-charset
     403             :         *    attributes-natural-language
     404             :         */
     405             : 
     406           0 :         request = ippNew();
     407             : 
     408           0 :         ippSetOperation(request, (ipp_op_t)OPERATION_NOVELL_LIST_PRINTERS);
     409           0 :         ippSetRequestId(request, 1);
     410             : 
     411           0 :         language = cupsLangDefault();
     412             : 
     413           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
     414             :                      "attributes-charset", NULL, "utf-8");
     415             : 
     416           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
     417           0 :                      "attributes-natural-language", NULL, language->language);
     418             : 
     419           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
     420             :                      "ipp-server", NULL, "ippSrvr");
     421             : 
     422             :        /*
     423             :         * Do the request and get back a response...
     424             :         */
     425             : 
     426           0 :         if ((response = cupsDoRequest(http, request, "/ipp")) == NULL) {
     427           0 :                 DEBUG(0,("Unable to get printer list - %s\n",
     428             :                          ippErrorString(cupsLastError())));
     429           0 :                 goto out;
     430             :         }
     431             : 
     432           0 :         for (attr = ippFirstAttribute(response); attr != NULL;) {
     433             :                /*
     434             :                 * Skip leading attributes until we hit a printer...
     435             :                 */
     436             : 
     437           0 :                 while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
     438           0 :                         attr = ippNextAttribute(response);
     439             : 
     440           0 :                 if (attr == NULL)
     441           0 :                         break;
     442             : 
     443             :                /*
     444             :                 * Pull the needed attributes from this printer...
     445             :                 */
     446             : 
     447           0 :                 while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER)
     448             :                 {
     449           0 :                         if (strcmp(ippGetName(attr), "printer-name") == 0 &&
     450           0 :                             (ippGetValueTag(attr) == IPP_TAG_URI ||
     451           0 :                              ippGetValueTag(attr) == IPP_TAG_NAME ||
     452           0 :                              ippGetValueTag(attr) == IPP_TAG_TEXT ||
     453           0 :                              ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
     454           0 :                              ippGetValueTag(attr) == IPP_TAG_TEXTLANG))
     455             :                         {
     456           0 :                                 for (i = 0; i<ippGetCount(attr); i++)
     457             :                                 {
     458           0 :                                         const char *url = ippGetString(attr, i, NULL);
     459           0 :                                         if (!url || !strlen(url))
     460           0 :                                                 continue;
     461           0 :                                         iprint_cache_add_printer(http, i+2, url,
     462             :                                                                  &pcache);
     463             :                                 }
     464             :                         }
     465           0 :                         attr = ippNextAttribute(response);
     466             :                 }
     467             :         }
     468             : 
     469           0 :         ret = true;
     470           0 :         *_pcache = pcache;
     471             : 
     472           0 :  out:
     473           0 :         if (response)
     474           0 :                 ippDelete(response);
     475             : 
     476           0 :         if (language)
     477           0 :                 cupsLangFree(language);
     478             : 
     479           0 :         if (http)
     480           0 :                 httpClose(http);
     481             : 
     482           0 :         return ret;
     483             : }
     484             : 
     485             : 
     486             : /*
     487             :  * 'iprint_job_delete()' - Delete a job.
     488             :  */
     489             : 
     490           0 : static int iprint_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob)
     491             : {
     492           0 :         int             ret = 1;                /* Return value */
     493           0 :         http_t          *http = NULL;           /* HTTP connection to server */
     494           0 :         ipp_t           *request = NULL,        /* IPP Request */
     495           0 :                         *response = NULL;       /* IPP Response */
     496           0 :         cups_lang_t     *language = NULL;       /* Default language */
     497           0 :         char            uri[HTTP_MAX_URI];      /* printer-uri attribute */
     498           0 :         char            httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
     499             : 
     500             : 
     501           0 :         DEBUG(5,("iprint_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob));
     502             : 
     503             :        /*
     504             :         * Make sure we don't ask for passwords...
     505             :         */
     506             : 
     507           0 :         cupsSetPasswordCB(iprint_passwd_cb);
     508             : 
     509             :        /*
     510             :         * Try to connect to the server...
     511             :         */
     512             : 
     513             : #ifdef HAVE_HTTPCONNECT2
     514           0 :         http = httpConnect2(iprint_server(),
     515             :                             ippPort(),
     516             :                             NULL,
     517             :                             AF_UNSPEC,
     518             :                             HTTP_ENCRYPTION_NEVER,
     519             :                             1, /* blocking */
     520             :                             30 * 1000, /* timeout */
     521             :                             NULL);
     522             : #else
     523             :         http = httpConnect(iprint_server(), ippPort());
     524             : #endif
     525           0 :         if (http == NULL) {
     526           0 :                 DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
     527             :                          iprint_server(), strerror(errno)));
     528           0 :                 goto out;
     529             :         }
     530             : 
     531             :        /*
     532             :         * Build an IPP_CANCEL_JOB request, which uses the following
     533             :         * attributes:
     534             :         *
     535             :         *    attributes-charset
     536             :         *    attributes-natural-language
     537             :         *    printer-uri
     538             :         *    job-id
     539             :         *    requesting-user-name
     540             :         */
     541             : 
     542           0 :         request = ippNew();
     543             : 
     544           0 :         ippSetOperation(request, IPP_CANCEL_JOB);
     545           0 :         ippSetRequestId(request, 1);
     546             : 
     547           0 :         language = cupsLangDefault();
     548             : 
     549           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
     550             :                      "attributes-charset", NULL, "utf-8");
     551             : 
     552           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
     553           0 :                      "attributes-natural-language", NULL, language->language);
     554             : 
     555           0 :         slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), sharename);
     556             : 
     557           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
     558             : 
     559           0 :         ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob);
     560             : 
     561           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
     562           0 :                      NULL, pjob->user);
     563             : 
     564             :        /*
     565             :         * Do the request and get back a response...
     566             :         */
     567             : 
     568           0 :         slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", sharename);
     569             : 
     570           0 :         if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
     571           0 :                 if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
     572           0 :                         DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
     573             :                                 ippErrorString(cupsLastError())));
     574             :                 } else {
     575           0 :                         ret = 0;
     576             :                 }
     577             :         } else {
     578           0 :                 DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
     579             :                         ippErrorString(cupsLastError())));
     580             :         }
     581             : 
     582           0 :  out:
     583           0 :         if (response)
     584           0 :                 ippDelete(response);
     585             : 
     586           0 :         if (language)
     587           0 :                 cupsLangFree(language);
     588             : 
     589           0 :         if (http)
     590           0 :                 httpClose(http);
     591             : 
     592           0 :         return ret;
     593             : }
     594             : 
     595             : 
     596             : /*
     597             :  * 'iprint_job_pause()' - Pause a job.
     598             :  */
     599             : 
     600           0 : static int iprint_job_pause(int snum, struct printjob *pjob)
     601             : {
     602           0 :         int             ret = 1;                /* Return value */
     603           0 :         http_t          *http = NULL;           /* HTTP connection to server */
     604           0 :         ipp_t           *request = NULL,        /* IPP Request */
     605           0 :                         *response = NULL;       /* IPP Response */
     606           0 :         cups_lang_t     *language = NULL;       /* Default language */
     607           0 :         char            uri[HTTP_MAX_URI];      /* printer-uri attribute */
     608           0 :         char            httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
     609           0 :         const struct loadparm_substitution *lp_sub =
     610           0 :                 loadparm_s3_global_substitution();
     611             : 
     612             : 
     613           0 :         DEBUG(5,("iprint_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
     614             : 
     615             :        /*
     616             :         * Make sure we don't ask for passwords...
     617             :         */
     618             : 
     619           0 :         cupsSetPasswordCB(iprint_passwd_cb);
     620             : 
     621             :        /*
     622             :         * Try to connect to the server...
     623             :         */
     624             : 
     625             : #ifdef HAVE_HTTPCONNECT2
     626           0 :         http = httpConnect2(iprint_server(),
     627             :                             ippPort(),
     628             :                             NULL,
     629             :                             AF_UNSPEC,
     630             :                             HTTP_ENCRYPTION_NEVER,
     631             :                             1, /* blocking */
     632             :                             30 * 1000, /* timeout */
     633             :                             NULL);
     634             : #else
     635             :         http = httpConnect(iprint_server(), ippPort());
     636             : #endif
     637           0 :         if (http == NULL) {
     638           0 :                 DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
     639             :                          iprint_server(), strerror(errno)));
     640           0 :                 goto out;
     641             :         }
     642             : 
     643             :        /*
     644             :         * Build an IPP_HOLD_JOB request, which requires the following
     645             :         * attributes:
     646             :         *
     647             :         *    attributes-charset
     648             :         *    attributes-natural-language
     649             :         *    printer-uri
     650             :         *    job-id
     651             :         *    requesting-user-name
     652             :         */
     653             : 
     654           0 :         request = ippNew();
     655             : 
     656           0 :         ippSetOperation(request, IPP_HOLD_JOB);
     657           0 :         ippSetRequestId(request, 1);
     658             : 
     659           0 :         language = cupsLangDefault();
     660             : 
     661           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
     662             :                      "attributes-charset", NULL, "utf-8");
     663             : 
     664           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
     665           0 :                      "attributes-natural-language", NULL, language->language);
     666             : 
     667           0 :         slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(),
     668             :                  lp_printername(talloc_tos(), lp_sub, snum));
     669             : 
     670           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
     671             : 
     672           0 :         ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob);
     673             : 
     674           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
     675           0 :                      NULL, pjob->user);
     676             : 
     677             :        /*
     678             :         * Do the request and get back a response...
     679             :         */
     680             : 
     681           0 :         slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s",
     682             :                  lp_printername(talloc_tos(), lp_sub, snum));
     683             : 
     684           0 :         if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
     685           0 :                 if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
     686           0 :                         DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
     687             :                                 ippErrorString(cupsLastError())));
     688             :                 } else {
     689           0 :                         ret = 0;
     690             :                 }
     691             :         } else {
     692           0 :                 DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
     693             :                         ippErrorString(cupsLastError())));
     694             :         }
     695             : 
     696           0 :  out:
     697           0 :         if (response)
     698           0 :                 ippDelete(response);
     699             : 
     700           0 :         if (language)
     701           0 :                 cupsLangFree(language);
     702             : 
     703           0 :         if (http)
     704           0 :                 httpClose(http);
     705             : 
     706           0 :         return ret;
     707             : }
     708             : 
     709             : 
     710             : /*
     711             :  * 'iprint_job_resume()' - Resume a paused job.
     712             :  */
     713             : 
     714           0 : static int iprint_job_resume(int snum, struct printjob *pjob)
     715             : {
     716           0 :         int             ret = 1;                /* Return value */
     717           0 :         http_t          *http = NULL;           /* HTTP connection to server */
     718           0 :         ipp_t           *request = NULL,        /* IPP Request */
     719           0 :                         *response = NULL;       /* IPP Response */
     720           0 :         cups_lang_t     *language = NULL;       /* Default language */
     721           0 :         char            uri[HTTP_MAX_URI];      /* printer-uri attribute */
     722           0 :         char            httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
     723           0 :         const struct loadparm_substitution *lp_sub =
     724           0 :                 loadparm_s3_global_substitution();
     725             : 
     726             : 
     727           0 :         DEBUG(5,("iprint_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
     728             : 
     729             :        /*
     730             :         * Make sure we don't ask for passwords...
     731             :         */
     732             : 
     733           0 :         cupsSetPasswordCB(iprint_passwd_cb);
     734             : 
     735             :        /*
     736             :         * Try to connect to the server...
     737             :         */
     738             : 
     739             : #ifdef HAVE_HTTPCONNECT2
     740           0 :         http = httpConnect2(iprint_server(),
     741             :                             ippPort(),
     742             :                             NULL,
     743             :                             AF_UNSPEC,
     744             :                             HTTP_ENCRYPTION_NEVER,
     745             :                             1, /* blocking */
     746             :                             30 * 1000, /* timeout */
     747             :                             NULL);
     748             : #else
     749             :         http = httpConnect(iprint_server(), ippPort());
     750             : #endif
     751           0 :         if (http == NULL) {
     752           0 :                 DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
     753             :                          iprint_server(), strerror(errno)));
     754           0 :                 goto out;
     755             :         }
     756             : 
     757             :        /*
     758             :         * Build an IPP_RELEASE_JOB request, which requires the following
     759             :         * attributes:
     760             :         *
     761             :         *    attributes-charset
     762             :         *    attributes-natural-language
     763             :         *    printer-uri
     764             :         *    job-id
     765             :         *    requesting-user-name
     766             :         */
     767             : 
     768           0 :         request = ippNew();
     769             : 
     770           0 :         ippSetOperation(request, IPP_RELEASE_JOB);
     771           0 :         ippSetRequestId(request, 1);
     772             : 
     773           0 :         language = cupsLangDefault();
     774             : 
     775           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
     776             :                      "attributes-charset", NULL, "utf-8");
     777             : 
     778           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
     779           0 :                      "attributes-natural-language", NULL, language->language);
     780             : 
     781           0 :         slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(),
     782             :                  lp_printername(talloc_tos(), lp_sub, snum));
     783             : 
     784           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
     785             : 
     786           0 :         ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob);
     787             : 
     788           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
     789           0 :                      NULL, pjob->user);
     790             : 
     791             :        /*
     792             :         * Do the request and get back a response...
     793             :         */
     794             : 
     795           0 :         slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s",
     796             :                  lp_printername(talloc_tos(), lp_sub, snum));
     797             : 
     798           0 :         if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
     799           0 :                 if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
     800           0 :                         DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
     801             :                                 ippErrorString(cupsLastError())));
     802             :                 } else {
     803           0 :                         ret = 0;
     804             :                 }
     805             :         } else {
     806           0 :                 DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
     807             :                         ippErrorString(cupsLastError())));
     808             :         }
     809             : 
     810           0 :  out:
     811           0 :         if (response)
     812           0 :                 ippDelete(response);
     813             : 
     814           0 :         if (language)
     815           0 :                 cupsLangFree(language);
     816             : 
     817           0 :         if (http)
     818           0 :                 httpClose(http);
     819             : 
     820           0 :         return ret;
     821             : }
     822             : 
     823             : 
     824             : /*
     825             :  * 'iprint_job_submit()' - Submit a job for printing.
     826             :  */
     827             : 
     828           0 : static int iprint_job_submit(int snum, struct printjob *pjob,
     829             :                              enum printing_types printing_type,
     830             :                              char *lpq_cmd)
     831             : {
     832           0 :         int             ret = 1;                /* Return value */
     833           0 :         http_t          *http = NULL;           /* HTTP connection to server */
     834           0 :         ipp_t           *request = NULL,        /* IPP Request */
     835           0 :                         *response = NULL;       /* IPP Response */
     836           0 :         ipp_attribute_t *attr;          /* Current attribute */
     837           0 :         cups_lang_t     *language = NULL;       /* Default language */
     838           0 :         char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
     839           0 :         const struct loadparm_substitution *lp_sub =
     840           0 :                 loadparm_s3_global_substitution();
     841             : 
     842           0 :         DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
     843             : 
     844             :        /*
     845             :         * Make sure we don't ask for passwords...
     846             :         */
     847             : 
     848           0 :         cupsSetPasswordCB(iprint_passwd_cb);
     849             : 
     850             :        /*
     851             :         * Try to connect to the server...
     852             :         */
     853             : 
     854             : #ifdef HAVE_HTTPCONNECT2
     855           0 :         http = httpConnect2(iprint_server(),
     856             :                             ippPort(),
     857             :                             NULL,
     858             :                             AF_UNSPEC,
     859             :                             HTTP_ENCRYPTION_NEVER,
     860             :                             1, /* blocking */
     861             :                             30 * 1000, /* timeout */
     862             :                             NULL);
     863             : #else
     864             :         http = httpConnect(iprint_server(), ippPort());
     865             : #endif
     866           0 :         if (http == NULL) {
     867           0 :                 DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
     868             :                          iprint_server(), strerror(errno)));
     869           0 :                 goto out;
     870             :         }
     871             : 
     872             :        /*
     873             :         * Build an IPP_PRINT_JOB request, which requires the following
     874             :         * attributes:
     875             :         *
     876             :         *    attributes-charset
     877             :         *    attributes-natural-language
     878             :         *    printer-uri
     879             :         *    requesting-user-name
     880             :         *    [document-data]
     881             :         */
     882             : 
     883           0 :         request = ippNew();
     884             : 
     885           0 :         ippSetOperation(request, IPP_PRINT_JOB);
     886           0 :         ippSetRequestId(request, 1);
     887             : 
     888           0 :         language = cupsLangDefault();
     889             : 
     890           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
     891             :                      "attributes-charset", NULL, "utf-8");
     892             : 
     893           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
     894           0 :                      "attributes-natural-language", NULL, language->language);
     895             : 
     896           0 :         slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(),
     897             :                  lp_printername(talloc_tos(), lp_sub, snum));
     898             : 
     899           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
     900             :                      "printer-uri", NULL, uri);
     901             : 
     902           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
     903           0 :                      NULL, pjob->user);
     904             : 
     905           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
     906             :                      "job-originating-host-name", NULL,
     907           0 :                      pjob->clientmachine);
     908             : 
     909           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
     910           0 :                      pjob->jobname);
     911             : 
     912             :        /*
     913             :         * Do the request and get back a response...
     914             :         */
     915             : 
     916           0 :         slprintf(uri, sizeof(uri) - 1, "/ipp/%s", lp_printername(talloc_tos(), lp_sub, snum));
     917             : 
     918           0 :         if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) {
     919           0 :                 if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
     920           0 :                         DEBUG(0,("Unable to print file to %s - %s\n",
     921             :                                  lp_printername(talloc_tos(), lp_sub, snum),
     922             :                                  ippErrorString(cupsLastError())));
     923             :                 } else {
     924           0 :                         ret = 0;
     925             :                 }
     926             :         } else {
     927           0 :                 DEBUG(0,("Unable to print file to `%s' - %s\n",
     928             :                          lp_printername(talloc_tos(), lp_sub, snum),
     929             :                          ippErrorString(cupsLastError())));
     930             :         }
     931             : 
     932           0 :         if ( ret == 0 )
     933           0 :                 unlink(pjob->filename);
     934             :         /* else print_job_end will do it for us */
     935             : 
     936           0 :         if ( ret == 0 ) {
     937             : 
     938           0 :                 attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER);
     939           0 :                 if (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB)
     940             :                 {
     941           0 :                         pjob->sysjob = ippGetInteger(attr, 0);
     942             :                 }
     943             :         }
     944             : 
     945           0 :  out:
     946           0 :         if (response)
     947           0 :                 ippDelete(response);
     948             : 
     949           0 :         if (language)
     950           0 :                 cupsLangFree(language);
     951             : 
     952           0 :         if (http)
     953           0 :                 httpClose(http);
     954             : 
     955           0 :         return ret;
     956             : }
     957             : 
     958             : /*
     959             :  * 'iprint_queue_get()' - Get all the jobs in the print queue.
     960             :  */
     961             : 
     962           0 : static int iprint_queue_get(const char *sharename,
     963             :                             enum printing_types printing_type,
     964             :                             char *lpq_command,
     965             :                             print_queue_struct **q,
     966             :                             print_status_struct *status)
     967             : {
     968           0 :         fstring         printername;
     969           0 :         http_t          *http = NULL;           /* HTTP connection to server */
     970           0 :         ipp_t           *request = NULL,        /* IPP Request */
     971           0 :                         *response = NULL;       /* IPP Response */
     972           0 :         ipp_attribute_t *attr = NULL;           /* Current attribute */
     973           0 :         cups_lang_t     *language = NULL;       /* Default language */
     974           0 :         char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
     975           0 :         char            serviceUri[HTTP_MAX_URI]; /* service-uri attribute */
     976           0 :         char            httpPath[HTTP_MAX_URI]; /* path portion of the uri */
     977           0 :         int             jobUseUnixTime = 0;     /* Whether job times should
     978             :                                                  * be assumed to be Unix time */
     979           0 :         int             qcount = 0,             /* Number of active queue entries */
     980           0 :                         qalloc = 0;             /* Number of queue entries allocated */
     981           0 :         print_queue_struct *queue = NULL,       /* Queue entries */
     982             :                         *temp;          /* Temporary pointer for queue */
     983           0 :         const char      *user_name,     /* job-originating-user-name attribute */
     984             :                         *job_name;      /* job-name attribute */
     985           0 :         int             job_id;         /* job-id attribute */
     986           0 :         int             job_k_octets;   /* job-k-octets attribute */
     987           0 :         time_t          job_time;       /* time-at-creation attribute */
     988           0 :         time_t          printer_up_time = 0;    /* printer's uptime */
     989           0 :         ipp_jstate_t    job_status;     /* job-status attribute */
     990           0 :         int             job_priority;   /* job-priority attribute */
     991           0 :         static const char *jattrs[] =   /* Requested job attributes */
     992             :                         {
     993             :                           "job-id",
     994             :                           "job-k-octets",
     995             :                           "job-name",
     996             :                           "job-originating-user-name",
     997             :                           "job-priority",
     998             :                           "job-state",
     999             :                           "time-at-creation",
    1000             :                         };
    1001           0 :         static const char *pattrs[] =   /* Requested printer attributes */
    1002             :                         {
    1003             :                           "printer-state",
    1004             :                           "printer-state-message",
    1005             :                           "printer-current-time",
    1006             :                           "printer-up-time"
    1007             :                         };
    1008             : 
    1009           0 :         *q = NULL;
    1010             : 
    1011             :         /* HACK ALERT!!!  The problem with support the 'printer name'
    1012             :            option is that we key the tdb off the sharename.  So we will
    1013             :            overload the lpq_command string to pass in the printername
    1014             :            (which is basically what we do for non-cups printers ... using
    1015             :            the lpq_command to get the queue listing). */
    1016             : 
    1017           0 :         fstrcpy( printername, lpq_command );
    1018             : 
    1019           0 :         DEBUG(5,("iprint_queue_get(%s, %p, %p)\n", printername, q, status));
    1020             : 
    1021             :        /*
    1022             :         * Make sure we don't ask for passwords...
    1023             :         */
    1024             : 
    1025           0 :         cupsSetPasswordCB(iprint_passwd_cb);
    1026             : 
    1027             :        /*
    1028             :         * Try to connect to the server...
    1029             :         */
    1030             : 
    1031             : #ifdef HAVE_HTTPCONNECT2
    1032           0 :         http = httpConnect2(iprint_server(),
    1033             :                             ippPort(),
    1034             :                             NULL,
    1035             :                             AF_UNSPEC,
    1036             :                             HTTP_ENCRYPTION_NEVER,
    1037             :                             1, /* blocking */
    1038             :                             30 * 1000, /* timeout */
    1039             :                             NULL);
    1040             : #else
    1041             :         http = httpConnect(iprint_server(), ippPort());
    1042             : #endif
    1043           0 :         if (http == NULL) {
    1044           0 :                 DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
    1045             :                          iprint_server(), strerror(errno)));
    1046           0 :                 goto out;
    1047             :         }
    1048             : 
    1049             :        /*
    1050             :         * Generate the printer URI and the service URI that goes with it...
    1051             :         */
    1052             : 
    1053           0 :         slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), printername);
    1054           0 :         slprintf(serviceUri, sizeof(serviceUri) - 1, "ipp://%s/ipp/", iprint_server());
    1055             : 
    1056             :        /*
    1057             :         * For Linux iPrint servers from OES SP1 on, the iPrint server
    1058             :         * uses Unix time for job start times unless it detects the iPrint
    1059             :         * client in an http User-Agent header.  (This was done to accommodate
    1060             :         * CUPS broken behavior.  According to RFC 2911, section 4.3.14, job
    1061             :         * start times are supposed to be relative to how long the printer has
    1062             :         * been up.)  Since libcups doesn't allow us to set that header before
    1063             :         * the request is sent, this ugly hack allows us to detect the server
    1064             :         * version and decide how to interpret the job time.
    1065             :         */
    1066           0 :         if (iprint_get_server_version(http, serviceUri) >=
    1067             :             NOVELL_SERVER_VERSION_OES_SP1)
    1068           0 :                 jobUseUnixTime = 1;
    1069             : 
    1070           0 :         request = ippNew();
    1071             : 
    1072           0 :         ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES);
    1073           0 :         ippSetRequestId(request, 2);
    1074             : 
    1075           0 :         language = cupsLangDefault();
    1076             : 
    1077           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
    1078             :                      "attributes-charset", NULL, "utf-8");
    1079             : 
    1080           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
    1081           0 :                      "attributes-natural-language", NULL, language->language);
    1082             : 
    1083           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
    1084             :                      "printer-uri", NULL, uri);
    1085             : 
    1086           0 :         ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
    1087             :                       "requested-attributes",
    1088             :                       (sizeof(pattrs) / sizeof(pattrs[0])),
    1089             :                       NULL, pattrs);
    1090             : 
    1091             :        /*
    1092             :         * Do the request and get back a response...
    1093             :         */
    1094             : 
    1095           0 :         slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername);
    1096             : 
    1097           0 :         if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
    1098           0 :                 DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
    1099             :                          ippErrorString(cupsLastError())));
    1100           0 :                 *q = queue;
    1101           0 :                 goto out;
    1102             :         }
    1103             : 
    1104           0 :         if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
    1105           0 :                 DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
    1106             :                          ippErrorString(ippGetStatusCode(response))));
    1107           0 :                 *q = queue;
    1108           0 :                 goto out;
    1109             :         }
    1110             : 
    1111             :        /*
    1112             :         * Get the current printer status and convert it to the SAMBA values.
    1113             :         */
    1114             : 
    1115           0 :         if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) {
    1116           0 :                 if (ippGetInteger(attr, 0) == IPP_PRINTER_STOPPED)
    1117           0 :                         status->status = LPSTAT_STOPPED;
    1118             :                 else
    1119           0 :                         status->status = LPSTAT_OK;
    1120             :         }
    1121             : 
    1122           0 :         if ((attr = ippFindAttribute(response, "printer-state-message",
    1123             :                                      IPP_TAG_TEXT)) != NULL)
    1124           0 :                 fstrcpy(status->message, ippGetString(attr, 0, NULL));
    1125             : 
    1126           0 :         if ((attr = ippFindAttribute(response, "printer-up-time",
    1127             :                                      IPP_TAG_INTEGER)) != NULL)
    1128           0 :                 printer_up_time = ippGetInteger(attr, 0);
    1129             : 
    1130           0 :         ippDelete(response);
    1131           0 :         response = NULL;
    1132             : 
    1133             :        /*
    1134             :         * Build an IPP_GET_JOBS request, which requires the following
    1135             :         * attributes:
    1136             :         *
    1137             :         *    attributes-charset
    1138             :         *    attributes-natural-language
    1139             :         *    requested-attributes
    1140             :         *    printer-uri
    1141             :         */
    1142             : 
    1143           0 :         request = ippNew();
    1144             : 
    1145           0 :         ippSetOperation(request, IPP_GET_JOBS);
    1146           0 :         ippSetRequestId(request, 3);
    1147             : 
    1148           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
    1149             :                      "attributes-charset", NULL, "utf-8");
    1150             : 
    1151           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
    1152           0 :                      "attributes-natural-language", NULL, language->language);
    1153             : 
    1154           0 :         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
    1155             :                      "printer-uri", NULL, uri);
    1156             : 
    1157           0 :         ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
    1158             :                       "requested-attributes",
    1159             :                       (sizeof(jattrs) / sizeof(jattrs[0])),
    1160             :                       NULL, jattrs);
    1161             : 
    1162             :        /*
    1163             :         * Do the request and get back a response...
    1164             :         */
    1165             : 
    1166           0 :         slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername);
    1167             : 
    1168           0 :         if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
    1169           0 :                 DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
    1170             :                          ippErrorString(cupsLastError())));
    1171           0 :                 goto out;
    1172             :         }
    1173             : 
    1174           0 :         if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
    1175           0 :                 DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
    1176             :                          ippErrorString(ippGetStatusCode(response))));
    1177           0 :                 goto out;
    1178             :         }
    1179             : 
    1180             :        /*
    1181             :         * Process the jobs...
    1182             :         */
    1183             : 
    1184           0 :         qcount = 0;
    1185           0 :         qalloc = 0;
    1186           0 :         queue  = NULL;
    1187             : 
    1188           0 :         for (attr = ippFirstAttribute(response); attr != NULL; attr = ippNextAttribute(response)) {
    1189             :                /*
    1190             :                 * Skip leading attributes until we hit a job...
    1191             :                 */
    1192             : 
    1193           0 :                 while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_JOB)
    1194           0 :                         attr = ippNextAttribute(response);
    1195             : 
    1196           0 :                 if (attr == NULL)
    1197           0 :                         break;
    1198             : 
    1199             :                /*
    1200             :                 * Allocate memory as needed...
    1201             :                 */
    1202           0 :                 if (qcount >= qalloc) {
    1203           0 :                         qalloc += 16;
    1204             : 
    1205           0 :                         queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc);
    1206             : 
    1207           0 :                         if (queue == NULL) {
    1208           0 :                                 DEBUG(0,("iprint_queue_get: Not enough memory!\n"));
    1209           0 :                                 qcount = 0;
    1210           0 :                                 goto out;
    1211             :                         }
    1212             :                 }
    1213             : 
    1214           0 :                 temp = queue + qcount;
    1215           0 :                 memset(temp, 0, sizeof(print_queue_struct));
    1216             : 
    1217             :                /*
    1218             :                 * Pull the needed attributes from this job...
    1219             :                 */
    1220             : 
    1221           0 :                 job_id       = 0;
    1222           0 :                 job_priority = 50;
    1223           0 :                 job_status   = IPP_JOB_PENDING;
    1224           0 :                 job_time     = 0;
    1225           0 :                 job_k_octets = 0;
    1226           0 :                 user_name    = NULL;
    1227           0 :                 job_name     = NULL;
    1228             : 
    1229           0 :                 while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB) {
    1230           0 :                         if (ippGetName(attr) == NULL) {
    1231           0 :                                 attr = ippNextAttribute(response);
    1232           0 :                                 break;
    1233             :                         }
    1234             : 
    1235           0 :                         if (strcmp(ippGetName(attr), "job-id") == 0 &&
    1236           0 :                             ippGetValueTag(attr) == IPP_TAG_INTEGER)
    1237           0 :                                 job_id = ippGetInteger(attr, 0);
    1238             : 
    1239           0 :                         if (strcmp(ippGetName(attr), "job-k-octets") == 0 &&
    1240           0 :                             ippGetValueTag(attr) == IPP_TAG_INTEGER)
    1241           0 :                                 job_k_octets = ippGetInteger(attr, 0);
    1242             : 
    1243           0 :                         if (strcmp(ippGetName(attr), "job-priority") == 0 &&
    1244           0 :                             ippGetValueTag(attr) == IPP_TAG_INTEGER)
    1245           0 :                                 job_priority = ippGetInteger(attr, 0);
    1246             : 
    1247           0 :                         if (strcmp(ippGetName(attr), "job-state") == 0 &&
    1248           0 :                             ippGetValueTag(attr) == IPP_TAG_ENUM)
    1249           0 :                                 job_status = (ipp_jstate_t)ippGetInteger(attr, 0);
    1250             : 
    1251           0 :                         if (strcmp(ippGetName(attr), "time-at-creation") == 0 &&
    1252           0 :                             ippGetValueTag(attr) == IPP_TAG_INTEGER)
    1253             :                         {
    1254             :                                /*
    1255             :                                 * If jobs times are in Unix time, the accuracy of the job
    1256             :                                 * start time depends upon the iPrint server's time being
    1257             :                                 * set correctly.  Otherwise, the accuracy depends upon
    1258             :                                 * the Samba server's time being set correctly
    1259             :                                 */
    1260             : 
    1261           0 :                                 if (jobUseUnixTime)
    1262           0 :                                         job_time = ippGetInteger(attr, 0);
    1263             :                                 else
    1264           0 :                                         job_time = time(NULL) - printer_up_time + ippGetInteger(attr, 0);
    1265             :                         }
    1266             : 
    1267           0 :                         if (strcmp(ippGetName(attr), "job-name") == 0 &&
    1268           0 :                             (ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
    1269           0 :                              ippGetValueTag(attr) == IPP_TAG_NAME))
    1270           0 :                                 job_name = ippGetString(attr, 0, NULL);
    1271             : 
    1272           0 :                         if (strcmp(ippGetName(attr), "job-originating-user-name") == 0 &&
    1273           0 :                             (ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
    1274           0 :                              ippGetValueTag(attr) == IPP_TAG_NAME))
    1275           0 :                                 user_name = ippGetString(attr, 0, NULL);
    1276             : 
    1277           0 :                         attr = ippNextAttribute(response);
    1278             :                 }
    1279             : 
    1280             :                /*
    1281             :                 * See if we have everything needed...
    1282             :                 */
    1283             : 
    1284           0 :                 if (user_name == NULL || job_name == NULL || job_id == 0) {
    1285           0 :                         if (attr == NULL)
    1286           0 :                                 break;
    1287             :                         else
    1288           0 :                                 continue;
    1289             :                 }
    1290             : 
    1291           0 :                 temp->sysjob   = job_id;
    1292           0 :                 temp->size     = job_k_octets * 1024;
    1293           0 :                 temp->status   = job_status == IPP_JOB_PENDING ? LPQ_QUEUED :
    1294           0 :                                  job_status == IPP_JOB_STOPPED ? LPQ_PAUSED :
    1295           0 :                                  job_status == IPP_JOB_HELD ? LPQ_PAUSED :
    1296             :                                  LPQ_PRINTING;
    1297           0 :                 temp->priority = job_priority;
    1298           0 :                 temp->time     = job_time;
    1299           0 :                 strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1);
    1300           0 :                 strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1);
    1301             : 
    1302           0 :                 qcount ++;
    1303             : 
    1304           0 :                 if (attr == NULL)
    1305           0 :                         break;
    1306             :         }
    1307             : 
    1308             :        /*
    1309             :         * Return the job queue...
    1310             :         */
    1311             : 
    1312           0 :         *q = queue;
    1313             : 
    1314           0 :  out:
    1315           0 :         if (response)
    1316           0 :                 ippDelete(response);
    1317             : 
    1318           0 :         if (language)
    1319           0 :                 cupsLangFree(language);
    1320             : 
    1321           0 :         if (http)
    1322           0 :                 httpClose(http);
    1323             : 
    1324           0 :         return qcount;
    1325             : }
    1326             : 
    1327             : 
    1328             : /*
    1329             :  * 'iprint_queue_pause()' - Pause a print queue.
    1330             :  */
    1331             : 
    1332           0 : static int iprint_queue_pause(int snum)
    1333             : {
    1334           0 :         return(-1); /* Not supported without credentials */
    1335             : }
    1336             : 
    1337             : 
    1338             : /*
    1339             :  * 'iprint_queue_resume()' - Restart a print queue.
    1340             :  */
    1341             : 
    1342           0 : static int iprint_queue_resume(int snum)
    1343             : {
    1344           0 :         return(-1); /* Not supported without credentials */
    1345             : }
    1346             : 
    1347             : /*******************************************************************
    1348             :  * iPrint printing interface definitions...
    1349             :  ******************************************************************/
    1350             : 
    1351             : struct printif  iprint_printif =
    1352             : {
    1353             :         PRINT_IPRINT,
    1354             :         iprint_queue_get,
    1355             :         iprint_queue_pause,
    1356             :         iprint_queue_resume,
    1357             :         iprint_job_delete,
    1358             :         iprint_job_pause,
    1359             :         iprint_job_resume,
    1360             :         iprint_job_submit,
    1361             : };
    1362             : 
    1363             : #else
    1364             :  /* this keeps fussy compilers happy */
    1365             :  void print_iprint_dummy(void);
    1366             :  void print_iprint_dummy(void) {}
    1367             : #endif /* HAVE_IPRINT */

Generated by: LCOV version 1.14