printing/print_cups.c

説明を見る。
00001 /*
00002  * Support code for the Common UNIX Printing System ("CUPS")
00003  *
00004  * Copyright 1999-2003 by Michael R Sweet.
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  * 
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "includes.h"
00022 #include "printing.h"
00023 
00024 #ifdef HAVE_CUPS
00025 #include <cups/cups.h>
00026 #include <cups/language.h>
00027 
00028 extern userdom_struct current_user_info;
00029 
00030 /*
00031  * 'cups_passwd_cb()' - The CUPS password callback...
00032  */
00033 
00034 static const char *                             /* O - Password or NULL */
00035 cups_passwd_cb(const char *prompt)      /* I - Prompt */
00036 {
00037         /*
00038          * Always return NULL to indicate that no password is available...
00039          */
00040 
00041         return (NULL);
00042 }
00043 
00044 static http_t *cups_connect(void)
00045 {
00046         http_t *http;
00047         char *server, *p;
00048         int port;
00049         
00050         if (lp_cups_server() != NULL && strlen(lp_cups_server()) > 0) {
00051                 server = smb_xstrdup(lp_cups_server());
00052         } else {
00053                 server = smb_xstrdup(cupsServer());
00054         }
00055 
00056         p = strchr(server, ':');
00057         if (p) {
00058                 port = atoi(p+1);
00059                 *p = '\0';
00060         } else {
00061                 port = ippPort();
00062         }
00063         
00064         DEBUG(10, ("connecting to cups server %s:%d\n",
00065                    server, port));
00066 
00067         if ((http = httpConnect(server, port)) == NULL) {
00068                 DEBUG(0,("Unable to connect to CUPS server %s:%d - %s\n", 
00069                          server, port, strerror(errno)));
00070                 SAFE_FREE(server);
00071                 return NULL;
00072         }
00073 
00074         SAFE_FREE(server);
00075         return http;
00076 }
00077 
00078 BOOL cups_cache_reload(void)
00079 {
00080         http_t          *http = NULL;           /* HTTP connection to server */
00081         ipp_t           *request = NULL,        /* IPP Request */
00082                         *response = NULL;       /* IPP Response */
00083         ipp_attribute_t *attr;          /* Current attribute */
00084         cups_lang_t     *language = NULL;       /* Default language */
00085         char            *name,          /* printer-name attribute */
00086                         *info;          /* printer-info attribute */
00087         static const char *requested[] =/* Requested attributes */
00088                         {
00089                           "printer-name",
00090                           "printer-info"
00091                         };       
00092         BOOL ret = False;
00093 
00094         DEBUG(5, ("reloading cups printcap cache\n"));
00095 
00096        /*
00097         * Make sure we don't ask for passwords...
00098         */
00099 
00100         cupsSetPasswordCB(cups_passwd_cb);
00101 
00102        /*
00103         * Try to connect to the server...
00104         */
00105 
00106         if ((http = cups_connect()) == NULL) {
00107                 goto out;
00108         }
00109 
00110        /*
00111         * Build a CUPS_GET_PRINTERS request, which requires the following
00112         * attributes:
00113         *
00114         *    attributes-charset
00115         *    attributes-natural-language
00116         *    requested-attributes
00117         */
00118 
00119         request = ippNew();
00120 
00121         request->request.op.operation_id = CUPS_GET_PRINTERS;
00122         request->request.op.request_id   = 1;
00123 
00124         language = cupsLangDefault();
00125 
00126         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
00127                      "attributes-charset", NULL, cupsLangEncoding(language));
00128 
00129         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
00130                      "attributes-natural-language", NULL, language->language);
00131 
00132         ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
00133                       "requested-attributes",
00134                       (sizeof(requested) / sizeof(requested[0])),
00135                       NULL, requested);
00136 
00137        /*
00138         * Do the request and get back a response...
00139         */
00140 
00141         if ((response = cupsDoRequest(http, request, "/")) == NULL) {
00142                 DEBUG(0,("Unable to get printer list - %s\n",
00143                          ippErrorString(cupsLastError())));
00144                 goto out;
00145         }
00146 
00147         for (attr = response->attrs; attr != NULL;) {
00148                /*
00149                 * Skip leading attributes until we hit a printer...
00150                 */
00151 
00152                 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
00153                         attr = attr->next;
00154 
00155                 if (attr == NULL)
00156                         break;
00157 
00158                /*
00159                 * Pull the needed attributes from this printer...
00160                 */
00161 
00162                 name       = NULL;
00163                 info       = NULL;
00164 
00165                 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) {
00166                         if (strcmp(attr->name, "printer-name") == 0 &&
00167                             attr->value_tag == IPP_TAG_NAME)
00168                                 name = attr->values[0].string.text;
00169 
00170                         if (strcmp(attr->name, "printer-info") == 0 &&
00171                             attr->value_tag == IPP_TAG_TEXT)
00172                                 info = attr->values[0].string.text;
00173 
00174                         attr = attr->next;
00175                 }
00176 
00177                /*
00178                 * See if we have everything needed...
00179                 */
00180 
00181                 if (name == NULL)
00182                         break;
00183 
00184                 if (!pcap_cache_add(name, info)) {
00185                         goto out;
00186                 }
00187         }
00188 
00189         ippDelete(response);
00190         response = NULL;
00191 
00192        /*
00193         * Build a CUPS_GET_CLASSES request, which requires the following
00194         * attributes:
00195         *
00196         *    attributes-charset
00197         *    attributes-natural-language
00198         *    requested-attributes
00199         */
00200 
00201         request = ippNew();
00202 
00203         request->request.op.operation_id = CUPS_GET_CLASSES;
00204         request->request.op.request_id   = 1;
00205 
00206         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
00207                      "attributes-charset", NULL, cupsLangEncoding(language));
00208 
00209         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
00210                      "attributes-natural-language", NULL, language->language);
00211 
00212         ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
00213                       "requested-attributes",
00214                       (sizeof(requested) / sizeof(requested[0])),
00215                       NULL, requested);
00216 
00217        /*
00218         * Do the request and get back a response...
00219         */
00220 
00221         if ((response = cupsDoRequest(http, request, "/")) == NULL) {
00222                 DEBUG(0,("Unable to get printer list - %s\n",
00223                          ippErrorString(cupsLastError())));
00224                 goto out;
00225         }
00226 
00227         for (attr = response->attrs; attr != NULL;) {
00228                /*
00229                 * Skip leading attributes until we hit a printer...
00230                 */
00231 
00232                 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
00233                         attr = attr->next;
00234 
00235                 if (attr == NULL)
00236                         break;
00237 
00238                /*
00239                 * Pull the needed attributes from this printer...
00240                 */
00241 
00242                 name       = NULL;
00243                 info       = NULL;
00244 
00245                 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) {
00246                         if (strcmp(attr->name, "printer-name") == 0 &&
00247                             attr->value_tag == IPP_TAG_NAME)
00248                                 name = attr->values[0].string.text;
00249 
00250                         if (strcmp(attr->name, "printer-info") == 0 &&
00251                             attr->value_tag == IPP_TAG_TEXT)
00252                                 info = attr->values[0].string.text;
00253 
00254                         attr = attr->next;
00255                 }
00256 
00257                /*
00258                 * See if we have everything needed...
00259                 */
00260 
00261                 if (name == NULL)
00262                         break;
00263 
00264                 if (!pcap_cache_add(name, info)) {
00265                         goto out;
00266                 }
00267         }
00268 
00269         ret = True;
00270 
00271  out:
00272         if (response)
00273                 ippDelete(response);
00274 
00275         if (language)
00276                 cupsLangFree(language);
00277 
00278         if (http)
00279                 httpClose(http);
00280 
00281         return ret;
00282 }
00283 
00284 
00285 /*
00286  * 'cups_job_delete()' - Delete a job.
00287  */
00288 
00289 static int cups_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob)
00290 {
00291         int             ret = 1;                /* Return value */
00292         http_t          *http = NULL;           /* HTTP connection to server */
00293         ipp_t           *request = NULL,        /* IPP Request */
00294                         *response = NULL;       /* IPP Response */
00295         cups_lang_t     *language = NULL;       /* Default language */
00296         char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
00297 
00298 
00299         DEBUG(5,("cups_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob));
00300 
00301        /*
00302         * Make sure we don't ask for passwords...
00303         */
00304 
00305         cupsSetPasswordCB(cups_passwd_cb);
00306 
00307        /*
00308         * Try to connect to the server...
00309         */
00310 
00311         if ((http = cups_connect()) == NULL) {
00312                 goto out;
00313         }
00314 
00315        /*
00316         * Build an IPP_CANCEL_JOB request, which requires the following
00317         * attributes:
00318         *
00319         *    attributes-charset
00320         *    attributes-natural-language
00321         *    job-uri
00322         *    requesting-user-name
00323         */
00324 
00325         request = ippNew();
00326 
00327         request->request.op.operation_id = IPP_CANCEL_JOB;
00328         request->request.op.request_id   = 1;
00329 
00330         language = cupsLangDefault();
00331 
00332         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
00333                      "attributes-charset", NULL, cupsLangEncoding(language));
00334 
00335         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
00336                      "attributes-natural-language", NULL, language->language);
00337 
00338         slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
00339 
00340         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
00341 
00342         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
00343                      NULL, pjob->user);
00344 
00345        /*
00346         * Do the request and get back a response...
00347         */
00348 
00349         if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) {
00350                 if (response->request.status.status_code >= IPP_OK_CONFLICT) {
00351                         DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
00352                                 ippErrorString(cupsLastError())));
00353                 } else {
00354                         ret = 0;
00355                 }
00356         } else {
00357                 DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
00358                         ippErrorString(cupsLastError())));
00359         }
00360 
00361  out:
00362         if (response)
00363                 ippDelete(response);
00364 
00365         if (language)
00366                 cupsLangFree(language);
00367 
00368         if (http)
00369                 httpClose(http);
00370 
00371         return ret;
00372 }
00373 
00374 
00375 /*
00376  * 'cups_job_pause()' - Pause a job.
00377  */
00378 
00379 static int cups_job_pause(int snum, struct printjob *pjob)
00380 {
00381         int             ret = 1;                /* Return value */
00382         http_t          *http = NULL;           /* HTTP connection to server */
00383         ipp_t           *request = NULL,        /* IPP Request */
00384                         *response = NULL;       /* IPP Response */
00385         cups_lang_t     *language = NULL;       /* Default language */
00386         char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
00387 
00388 
00389         DEBUG(5,("cups_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
00390 
00391        /*
00392         * Make sure we don't ask for passwords...
00393         */
00394 
00395         cupsSetPasswordCB(cups_passwd_cb);
00396 
00397        /*
00398         * Try to connect to the server...
00399         */
00400 
00401         if ((http = cups_connect()) == NULL) {
00402                 goto out;
00403         }
00404 
00405        /*
00406         * Build an IPP_HOLD_JOB request, which requires the following
00407         * attributes:
00408         *
00409         *    attributes-charset
00410         *    attributes-natural-language
00411         *    job-uri
00412         *    requesting-user-name
00413         */
00414 
00415         request = ippNew();
00416 
00417         request->request.op.operation_id = IPP_HOLD_JOB;
00418         request->request.op.request_id   = 1;
00419 
00420         language = cupsLangDefault();
00421 
00422         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
00423                      "attributes-charset", NULL, cupsLangEncoding(language));
00424 
00425         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
00426                      "attributes-natural-language", NULL, language->language);
00427 
00428         slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
00429 
00430         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
00431 
00432         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
00433                      NULL, pjob->user);
00434 
00435        /*
00436         * Do the request and get back a response...
00437         */
00438 
00439         if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) {
00440                 if (response->request.status.status_code >= IPP_OK_CONFLICT) {
00441                         DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
00442                                 ippErrorString(cupsLastError())));
00443                 } else {
00444                         ret = 0;
00445                 }
00446         } else {
00447                 DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
00448                         ippErrorString(cupsLastError())));
00449         }
00450 
00451  out:
00452         if (response)
00453                 ippDelete(response);
00454 
00455         if (language)
00456                 cupsLangFree(language);
00457 
00458         if (http)
00459                 httpClose(http);
00460 
00461         return ret;
00462 }
00463 
00464 
00465 /*
00466  * 'cups_job_resume()' - Resume a paused job.
00467  */
00468 
00469 static int cups_job_resume(int snum, struct printjob *pjob)
00470 {
00471         int             ret = 1;                /* Return value */
00472         http_t          *http = NULL;           /* HTTP connection to server */
00473         ipp_t           *request = NULL,        /* IPP Request */
00474                         *response = NULL;       /* IPP Response */
00475         cups_lang_t     *language = NULL;       /* Default language */
00476         char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
00477 
00478 
00479         DEBUG(5,("cups_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
00480 
00481        /*
00482         * Make sure we don't ask for passwords...
00483         */
00484 
00485         cupsSetPasswordCB(cups_passwd_cb);
00486 
00487        /*
00488         * Try to connect to the server...
00489         */
00490 
00491         if ((http = cups_connect()) == NULL) {
00492                 goto out;
00493         }
00494 
00495        /*
00496         * Build an IPP_RELEASE_JOB request, which requires the following
00497         * attributes:
00498         *
00499         *    attributes-charset
00500         *    attributes-natural-language
00501         *    job-uri
00502         *    requesting-user-name
00503         */
00504 
00505         request = ippNew();
00506 
00507         request->request.op.operation_id = IPP_RELEASE_JOB;
00508         request->request.op.request_id   = 1;
00509 
00510         language = cupsLangDefault();
00511 
00512         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
00513                      "attributes-charset", NULL, cupsLangEncoding(language));
00514 
00515         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
00516                      "attributes-natural-language", NULL, language->language);
00517 
00518         slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
00519 
00520         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
00521 
00522         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
00523                      NULL, pjob->user);
00524 
00525        /*
00526         * Do the request and get back a response...
00527         */
00528 
00529         if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) {
00530                 if (response->request.status.status_code >= IPP_OK_CONFLICT) {
00531                         DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
00532                                 ippErrorString(cupsLastError())));
00533                 } else {
00534                         ret = 0;
00535                 }
00536         } else {
00537                 DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
00538                         ippErrorString(cupsLastError())));
00539         }
00540 
00541  out:
00542         if (response)
00543                 ippDelete(response);
00544 
00545         if (language)
00546                 cupsLangFree(language);
00547 
00548         if (http)
00549                 httpClose(http);
00550 
00551         return ret;
00552 }
00553 
00554 
00555 /*
00556  * 'cups_job_submit()' - Submit a job for printing.
00557  */
00558 
00559 static int cups_job_submit(int snum, struct printjob *pjob)
00560 {
00561         int             ret = 1;                /* Return value */
00562         http_t          *http = NULL;           /* HTTP connection to server */
00563         ipp_t           *request = NULL,        /* IPP Request */
00564                         *response = NULL;       /* IPP Response */
00565         cups_lang_t     *language = NULL;       /* Default language */
00566         char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
00567         char            *clientname = NULL;     /* hostname of client for job-originating-host attribute */
00568         pstring         new_jobname;
00569         int             num_options = 0; 
00570         cups_option_t   *options = NULL;
00571 
00572         DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
00573 
00574        /*
00575         * Make sure we don't ask for passwords...
00576         */
00577 
00578         cupsSetPasswordCB(cups_passwd_cb);
00579 
00580        /*
00581         * Try to connect to the server...
00582         */
00583 
00584         if ((http = cups_connect()) == NULL) {
00585                 goto out;
00586         }
00587 
00588        /*
00589         * Build an IPP_PRINT_JOB request, which requires the following
00590         * attributes:
00591         *
00592         *    attributes-charset
00593         *    attributes-natural-language
00594         *    printer-uri
00595         *    requesting-user-name
00596         *    [document-data]
00597         */
00598 
00599         request = ippNew();
00600 
00601         request->request.op.operation_id = IPP_PRINT_JOB;
00602         request->request.op.request_id   = 1;
00603 
00604         language = cupsLangDefault();
00605 
00606         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
00607                      "attributes-charset", NULL, cupsLangEncoding(language));
00608 
00609         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
00610                      "attributes-natural-language", NULL, language->language);
00611 
00612         slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
00613                  PRINTERNAME(snum));
00614 
00615         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
00616                      "printer-uri", NULL, uri);
00617 
00618         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
00619                      NULL, pjob->user);
00620 
00621         clientname = client_name();
00622         if (strcmp(clientname, "UNKNOWN") == 0) {
00623                 clientname = client_addr();
00624         }
00625 
00626         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
00627                      "job-originating-host-name", NULL,
00628                       clientname);
00629 
00630         pstr_sprintf(new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX, 
00631                 (unsigned int)pjob->smbjob, pjob->jobname);
00632 
00633         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
00634                      new_jobname);
00635 
00636         /* 
00637          * add any options defined in smb.conf 
00638          */
00639 
00640         num_options = 0;
00641         options     = NULL;
00642         num_options = cupsParseOptions(lp_cups_options(snum), num_options, &options);
00643 
00644         if ( num_options )
00645                 cupsEncodeOptions(request, num_options, options); 
00646 
00647        /*
00648         * Do the request and get back a response...
00649         */
00650 
00651         slprintf(uri, sizeof(uri) - 1, "/printers/%s", PRINTERNAME(snum));
00652 
00653         if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) {
00654                 if (response->request.status.status_code >= IPP_OK_CONFLICT) {
00655                         DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum),
00656                                  ippErrorString(cupsLastError())));
00657                 } else {
00658                         ret = 0;
00659                 }
00660         } else {
00661                 DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum),
00662                          ippErrorString(cupsLastError())));
00663         }
00664 
00665         if ( ret == 0 )
00666                 unlink(pjob->filename);
00667         /* else print_job_end will do it for us */
00668 
00669  out:
00670         if (response)
00671                 ippDelete(response);
00672 
00673         if (language)
00674                 cupsLangFree(language);
00675 
00676         if (http)
00677                 httpClose(http);
00678 
00679         return ret;
00680 }
00681 
00682 /*
00683  * 'cups_queue_get()' - Get all the jobs in the print queue.
00684  */
00685 
00686 static int cups_queue_get(const char *sharename,
00687                enum printing_types printing_type,
00688                char *lpq_command,
00689                print_queue_struct **q, 
00690                print_status_struct *status)
00691 {
00692         fstring         printername;
00693         http_t          *http = NULL;           /* HTTP connection to server */
00694         ipp_t           *request = NULL,        /* IPP Request */
00695                         *response = NULL;       /* IPP Response */
00696         ipp_attribute_t *attr = NULL;           /* Current attribute */
00697         cups_lang_t     *language = NULL;       /* Default language */
00698         char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
00699         int             qcount = 0,             /* Number of active queue entries */
00700                         qalloc = 0;             /* Number of queue entries allocated */
00701         print_queue_struct *queue = NULL,       /* Queue entries */
00702                         *temp;          /* Temporary pointer for queue */
00703         const char      *user_name,     /* job-originating-user-name attribute */
00704                         *job_name;      /* job-name attribute */
00705         int             job_id;         /* job-id attribute */
00706         int             job_k_octets;   /* job-k-octets attribute */
00707         time_t          job_time;       /* time-at-creation attribute */
00708         ipp_jstate_t    job_status;     /* job-status attribute */
00709         int             job_priority;   /* job-priority attribute */
00710         static const char *jattrs[] =   /* Requested job attributes */
00711                         {
00712                           "job-id",
00713                           "job-k-octets",
00714                           "job-name",
00715                           "job-originating-user-name",
00716                           "job-priority",
00717                           "job-state",
00718                           "time-at-creation",
00719                         };
00720         static const char *pattrs[] =   /* Requested printer attributes */
00721                         {
00722                           "printer-state",
00723                           "printer-state-message"
00724                         };
00725 
00726         *q = NULL;
00727 
00728         /* HACK ALERT!!!  The problem with support the 'printer name' 
00729            option is that we key the tdb off the sharename.  So we will 
00730            overload the lpq_command string to pass in the printername 
00731            (which is basically what we do for non-cups printers ... using 
00732            the lpq_command to get the queue listing). */
00733 
00734         fstrcpy( printername, lpq_command );
00735 
00736         DEBUG(5,("cups_queue_get(%s, %p, %p)\n", printername, q, status));
00737 
00738        /*
00739         * Make sure we don't ask for passwords...
00740         */
00741 
00742         cupsSetPasswordCB(cups_passwd_cb);
00743 
00744        /*
00745         * Try to connect to the server...
00746         */
00747 
00748         if ((http = cups_connect()) == NULL) {
00749                 goto out;
00750         }
00751 
00752        /*
00753         * Generate the printer URI...
00754         */
00755 
00756         slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", printername);
00757 
00758        /*
00759         * Build an IPP_GET_JOBS request, which requires the following
00760         * attributes:
00761         *
00762         *    attributes-charset
00763         *    attributes-natural-language
00764         *    requested-attributes
00765         *    printer-uri
00766         */
00767 
00768         request = ippNew();
00769 
00770         request->request.op.operation_id = IPP_GET_JOBS;
00771         request->request.op.request_id   = 1;
00772 
00773         language = cupsLangDefault();
00774 
00775         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
00776                      "attributes-charset", NULL, cupsLangEncoding(language));
00777 
00778         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
00779                      "attributes-natural-language", NULL, language->language);
00780 
00781         ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
00782                       "requested-attributes",
00783                       (sizeof(jattrs) / sizeof(jattrs[0])),
00784                       NULL, jattrs);
00785 
00786         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
00787                      "printer-uri", NULL, uri);
00788 
00789        /*
00790         * Do the request and get back a response...
00791         */
00792 
00793         if ((response = cupsDoRequest(http, request, "/")) == NULL) {
00794                 DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
00795                          ippErrorString(cupsLastError())));
00796                 goto out;
00797         }
00798 
00799         if (response->request.status.status_code >= IPP_OK_CONFLICT) {
00800                 DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
00801                          ippErrorString(response->request.status.status_code)));
00802                 goto out;
00803         }
00804 
00805        /*
00806         * Process the jobs...
00807         */
00808 
00809         qcount = 0;
00810         qalloc = 0;
00811         queue  = NULL;
00812 
00813         for (attr = response->attrs; attr != NULL; attr = attr->next) {
00814                /*
00815                 * Skip leading attributes until we hit a job...
00816                 */
00817 
00818                 while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
00819                         attr = attr->next;
00820 
00821                 if (attr == NULL)
00822                         break;
00823 
00824                /*
00825                 * Allocate memory as needed...
00826                 */
00827                 if (qcount >= qalloc) {
00828                         qalloc += 16;
00829 
00830                         queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc);
00831 
00832                         if (queue == NULL) {
00833                                 DEBUG(0,("cups_queue_get: Not enough memory!"));
00834                                 qcount = 0;
00835                                 goto out;
00836                         }
00837                 }
00838 
00839                 temp = queue + qcount;
00840                 memset(temp, 0, sizeof(print_queue_struct));
00841 
00842                /*
00843                 * Pull the needed attributes from this job...
00844                 */
00845 
00846                 job_id       = 0;
00847                 job_priority = 50;
00848                 job_status   = IPP_JOB_PENDING;
00849                 job_time     = 0;
00850                 job_k_octets = 0;
00851                 user_name    = NULL;
00852                 job_name     = NULL;
00853 
00854                 while (attr != NULL && attr->group_tag == IPP_TAG_JOB) {
00855                         if (attr->name == NULL) {
00856                                 attr = attr->next;
00857                                 break;
00858                         }
00859 
00860                         if (strcmp(attr->name, "job-id") == 0 &&
00861                             attr->value_tag == IPP_TAG_INTEGER)
00862                                 job_id = attr->values[0].integer;
00863 
00864                         if (strcmp(attr->name, "job-k-octets") == 0 &&
00865                             attr->value_tag == IPP_TAG_INTEGER)
00866                                 job_k_octets = attr->values[0].integer;
00867 
00868                         if (strcmp(attr->name, "job-priority") == 0 &&
00869                             attr->value_tag == IPP_TAG_INTEGER)
00870                                 job_priority = attr->values[0].integer;
00871 
00872                         if (strcmp(attr->name, "job-state") == 0 &&
00873                             attr->value_tag == IPP_TAG_ENUM)
00874                                 job_status = (ipp_jstate_t)(attr->values[0].integer);
00875 
00876                         if (strcmp(attr->name, "time-at-creation") == 0 &&
00877                             attr->value_tag == IPP_TAG_INTEGER)
00878                                 job_time = attr->values[0].integer;
00879 
00880                         if (strcmp(attr->name, "job-name") == 0 &&
00881                             attr->value_tag == IPP_TAG_NAME)
00882                                 job_name = attr->values[0].string.text;
00883 
00884                         if (strcmp(attr->name, "job-originating-user-name") == 0 &&
00885                             attr->value_tag == IPP_TAG_NAME)
00886                                 user_name = attr->values[0].string.text;
00887 
00888                         attr = attr->next;
00889                 }
00890 
00891                /*
00892                 * See if we have everything needed...
00893                 */
00894 
00895                 if (user_name == NULL || job_name == NULL || job_id == 0) {
00896                         if (attr == NULL)
00897                                 break;
00898                         else
00899                                 continue;
00900                 }
00901 
00902                 temp->job      = job_id;
00903                 temp->size     = job_k_octets * 1024;
00904                 temp->status   = job_status == IPP_JOB_PENDING ? LPQ_QUEUED :
00905                                  job_status == IPP_JOB_STOPPED ? LPQ_PAUSED :
00906                                  job_status == IPP_JOB_HELD ? LPQ_PAUSED :
00907                                  LPQ_PRINTING;
00908                 temp->priority = job_priority;
00909                 temp->time     = job_time;
00910                 strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1);
00911                 strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1);
00912 
00913                 qcount ++;
00914 
00915                 if (attr == NULL)
00916                         break;
00917         }
00918 
00919         ippDelete(response);
00920         response = NULL;
00921 
00922        /*
00923         * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
00924         * following attributes:
00925         *
00926         *    attributes-charset
00927         *    attributes-natural-language
00928         *    requested-attributes
00929         *    printer-uri
00930         */
00931 
00932         request = ippNew();
00933 
00934         request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
00935         request->request.op.request_id   = 1;
00936 
00937         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
00938                      "attributes-charset", NULL, cupsLangEncoding(language));
00939 
00940         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
00941                      "attributes-natural-language", NULL, language->language);
00942 
00943         ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
00944                       "requested-attributes",
00945                       (sizeof(pattrs) / sizeof(pattrs[0])),
00946                       NULL, pattrs);
00947 
00948         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
00949                      "printer-uri", NULL, uri);
00950 
00951        /*
00952         * Do the request and get back a response...
00953         */
00954 
00955         if ((response = cupsDoRequest(http, request, "/")) == NULL) {
00956                 DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
00957                          ippErrorString(cupsLastError())));
00958                 *q = queue;
00959                 goto out;
00960         }
00961 
00962         if (response->request.status.status_code >= IPP_OK_CONFLICT) {
00963                 DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
00964                          ippErrorString(response->request.status.status_code)));
00965                 *q = queue;
00966                 goto out;
00967         }
00968 
00969        /*
00970         * Get the current printer status and convert it to the SAMBA values.
00971         */
00972 
00973         if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) {
00974                 if (attr->values[0].integer == IPP_PRINTER_STOPPED)
00975                         status->status = LPSTAT_STOPPED;
00976                 else
00977                         status->status = LPSTAT_OK;
00978         }
00979 
00980         if ((attr = ippFindAttribute(response, "printer-state-message",
00981                                      IPP_TAG_TEXT)) != NULL)
00982                 fstrcpy(status->message, attr->values[0].string.text);
00983 
00984        /*
00985         * Return the job queue...
00986         */
00987 
00988         *q = queue;
00989 
00990  out:
00991         if (response)
00992                 ippDelete(response);
00993 
00994         if (language)
00995                 cupsLangFree(language);
00996 
00997         if (http)
00998                 httpClose(http);
00999 
01000         return qcount;
01001 }
01002 
01003 
01004 /*
01005  * 'cups_queue_pause()' - Pause a print queue.
01006  */
01007 
01008 static int cups_queue_pause(int snum)
01009 {
01010         int             ret = 1;                /* Return value */
01011         http_t          *http = NULL;           /* HTTP connection to server */
01012         ipp_t           *request = NULL,        /* IPP Request */
01013                         *response = NULL;       /* IPP Response */
01014         cups_lang_t     *language = NULL;       /* Default language */
01015         char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
01016 
01017 
01018         DEBUG(5,("cups_queue_pause(%d)\n", snum));
01019 
01020         /*
01021          * Make sure we don't ask for passwords...
01022          */
01023 
01024         cupsSetPasswordCB(cups_passwd_cb);
01025 
01026         /*
01027          * Try to connect to the server...
01028          */
01029 
01030         if ((http = cups_connect()) == NULL) {
01031                 goto out;
01032         }
01033 
01034         /*
01035          * Build an IPP_PAUSE_PRINTER request, which requires the following
01036          * attributes:
01037          *
01038          *    attributes-charset
01039          *    attributes-natural-language
01040          *    printer-uri
01041          *    requesting-user-name
01042          */
01043 
01044         request = ippNew();
01045 
01046         request->request.op.operation_id = IPP_PAUSE_PRINTER;
01047         request->request.op.request_id   = 1;
01048 
01049         language = cupsLangDefault();
01050 
01051         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
01052                      "attributes-charset", NULL, cupsLangEncoding(language));
01053 
01054         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
01055                      "attributes-natural-language", NULL, language->language);
01056 
01057         slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
01058                  PRINTERNAME(snum));
01059 
01060         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
01061 
01062         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
01063                      NULL, current_user_info.unix_name);
01064 
01065        /*
01066         * Do the request and get back a response...
01067         */
01068 
01069         if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) {
01070                 if (response->request.status.status_code >= IPP_OK_CONFLICT) {
01071                         DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
01072                                 ippErrorString(cupsLastError())));
01073                 } else {
01074                         ret = 0;
01075                 }
01076         } else {
01077                 DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
01078                         ippErrorString(cupsLastError())));
01079         }
01080 
01081  out:
01082         if (response)
01083                 ippDelete(response);
01084 
01085         if (language)
01086                 cupsLangFree(language);
01087 
01088         if (http)
01089                 httpClose(http);
01090 
01091         return ret;
01092 }
01093 
01094 
01095 /*
01096  * 'cups_queue_resume()' - Restart a print queue.
01097  */
01098 
01099 static int cups_queue_resume(int snum)
01100 {
01101         int             ret = 1;                /* Return value */
01102         http_t          *http = NULL;           /* HTTP connection to server */
01103         ipp_t           *request = NULL,        /* IPP Request */
01104                         *response = NULL;       /* IPP Response */
01105         cups_lang_t     *language = NULL;       /* Default language */
01106         char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
01107 
01108 
01109         DEBUG(5,("cups_queue_resume(%d)\n", snum));
01110 
01111        /*
01112         * Make sure we don't ask for passwords...
01113         */
01114 
01115         cupsSetPasswordCB(cups_passwd_cb);
01116 
01117        /*
01118         * Try to connect to the server...
01119         */
01120 
01121         if ((http = cups_connect()) == NULL) {
01122                 goto out;
01123         }
01124 
01125        /*
01126         * Build an IPP_RESUME_PRINTER request, which requires the following
01127         * attributes:
01128         *
01129         *    attributes-charset
01130         *    attributes-natural-language
01131         *    printer-uri
01132         *    requesting-user-name
01133         */
01134 
01135         request = ippNew();
01136 
01137         request->request.op.operation_id = IPP_RESUME_PRINTER;
01138         request->request.op.request_id   = 1;
01139 
01140         language = cupsLangDefault();
01141 
01142         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
01143                      "attributes-charset", NULL, cupsLangEncoding(language));
01144 
01145         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
01146                      "attributes-natural-language", NULL, language->language);
01147 
01148         slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
01149                  PRINTERNAME(snum));
01150 
01151         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
01152 
01153         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
01154                      NULL, current_user_info.unix_name);
01155 
01156        /*
01157         * Do the request and get back a response...
01158         */
01159 
01160         if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) {
01161                 if (response->request.status.status_code >= IPP_OK_CONFLICT) {
01162                         DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
01163                                 ippErrorString(cupsLastError())));
01164                 } else {
01165                         ret = 0;
01166                 }
01167         } else {
01168                 DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
01169                         ippErrorString(cupsLastError())));
01170         }
01171 
01172  out:
01173         if (response)
01174                 ippDelete(response);
01175 
01176         if (language)
01177                 cupsLangFree(language);
01178 
01179         if (http)
01180                 httpClose(http);
01181 
01182         return ret;
01183 }
01184 
01185 /*******************************************************************
01186  * CUPS printing interface definitions...
01187  ******************************************************************/
01188 
01189 struct printif  cups_printif =
01190 {
01191         PRINT_CUPS,
01192         cups_queue_get,
01193         cups_queue_pause,
01194         cups_queue_resume,
01195         cups_job_delete,
01196         cups_job_pause,
01197         cups_job_resume,
01198         cups_job_submit,
01199 };
01200 
01201 BOOL cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)
01202 {
01203         http_t          *http = NULL;           /* HTTP connection to server */
01204         ipp_t           *request = NULL,        /* IPP Request */
01205                         *response = NULL;       /* IPP Response */
01206         ipp_attribute_t *attr;          /* Current attribute */
01207         cups_lang_t     *language = NULL;       /* Default language */
01208         char            *name,          /* printer-name attribute */
01209                         *info,          /* printer-info attribute */
01210                         *location;      /* printer-location attribute */
01211         char            uri[HTTP_MAX_URI];
01212         static const char *requested[] =/* Requested attributes */
01213                         {
01214                           "printer-name",
01215                           "printer-info",
01216                           "printer-location"
01217                         };
01218         BOOL ret = False;
01219 
01220         DEBUG(5, ("pulling %s location\n", printer->sharename));
01221 
01222         /*
01223          * Make sure we don't ask for passwords...
01224          */
01225 
01226         cupsSetPasswordCB(cups_passwd_cb);
01227 
01228         /*
01229          * Try to connect to the server...
01230          */
01231 
01232         if ((http = cups_connect()) == NULL) {
01233                 goto out;
01234         }
01235 
01236         request = ippNew();
01237 
01238         request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
01239         request->request.op.request_id   = 1;
01240 
01241         language = cupsLangDefault();
01242 
01243         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
01244                      "attributes-charset", NULL, cupsLangEncoding(language));
01245 
01246         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
01247                      "attributes-natural-language", NULL, language->language);
01248 
01249         slprintf(uri, sizeof(uri) - 1, "ipp://%s/printers/%s",
01250                  lp_cups_server(), printer->sharename);
01251 
01252         ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
01253                      "printer-uri", NULL, uri);
01254 
01255         ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
01256                       "requested-attributes",
01257                       (sizeof(requested) / sizeof(requested[0])),
01258                       NULL, requested);
01259 
01260         /*
01261          * Do the request and get back a response...
01262          */
01263 
01264         if ((response = cupsDoRequest(http, request, "/")) == NULL) {
01265                 DEBUG(0,("Unable to get printer attributes - %s\n",
01266                          ippErrorString(cupsLastError())));
01267                 goto out;
01268         }
01269 
01270         for (attr = response->attrs; attr != NULL;) {
01271                 /*
01272                  * Skip leading attributes until we hit a printer...
01273                  */
01274 
01275                 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
01276                         attr = attr->next;
01277 
01278                 if (attr == NULL)
01279                         break;
01280 
01281                 /*
01282                  * Pull the needed attributes from this printer...
01283                  */
01284 
01285                 name       = NULL;
01286                 info       = NULL;
01287                 location   = NULL;
01288 
01289                 while ( attr && (attr->group_tag == IPP_TAG_PRINTER) ) {
01290                         /* Grab the comment if we don't have one */
01291                         if ( (strcmp(attr->name, "printer-info") == 0)
01292                              && (attr->value_tag == IPP_TAG_TEXT)
01293                              && !strlen(printer->comment) ) 
01294                         {
01295                                 DEBUG(5,("cups_pull_comment_location: Using cups comment: %s\n",
01296                                          attr->values[0].string.text));                         
01297                                 pstrcpy(printer->comment,attr->values[0].string.text);
01298                         }
01299 
01300                         /* Grab the location if we don't have one */ 
01301                         if ( (strcmp(attr->name, "printer-location") == 0)
01302                              && (attr->value_tag == IPP_TAG_TEXT) 
01303                              && !strlen(printer->location) )
01304                         {
01305                                 DEBUG(5,("cups_pull_comment_location: Using cups location: %s\n",
01306                                          attr->values[0].string.text));                         
01307                                 fstrcpy(printer->location,attr->values[0].string.text);
01308                         }
01309 
01310                         attr = attr->next;
01311                 }
01312 
01313                 /*
01314                  * See if we have everything needed...
01315                  */
01316 
01317                 if (name == NULL)
01318                         break;
01319 
01320         }
01321 
01322         ret = True;
01323 
01324  out:
01325         if (response)
01326                 ippDelete(response);
01327 
01328         if (language)
01329                 cupsLangFree(language);
01330 
01331         if (http)
01332                 httpClose(http);
01333 
01334         return ret;
01335 }
01336 
01337 #else
01338  /* this keeps fussy compilers happy */
01339  void print_cups_dummy(void);
01340  void print_cups_dummy(void) {}
01341 #endif /* HAVE_CUPS */

Sambaに対してSat Aug 29 21:23:14 2009に生成されました。  doxygen 1.4.7