sync'ing up for 3.0alpha20 release
[Samba.git] / source / printing / print_cups.c
blob2df846aa5798c8f2d1e8ffede2adfc30eb865dd4
1 /*
2 * Support code for the Common UNIX Printing System ("CUPS")
4 * Copyright 1999-2001 by Michael R Sweet.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "printing.h"
22 #include "smb.h"
24 #ifdef HAVE_CUPS
25 #include <cups/cups.h>
26 #include <cups/language.h>
30 * CUPS printing interface definitions...
33 static int cups_job_delete(int snum, struct printjob *pjob);
34 static int cups_job_pause(int snum, struct printjob *pjob);
35 static int cups_job_resume(int snum, struct printjob *pjob);
36 static int cups_job_submit(int snum, struct printjob *pjob);
37 static int cups_queue_get(int snum, print_queue_struct **q,
38 print_status_struct *status);
39 static int cups_queue_pause(int snum);
40 static int cups_queue_resume(int snum);
43 struct printif cups_printif =
45 cups_queue_get,
46 cups_queue_pause,
47 cups_queue_resume,
48 cups_job_delete,
49 cups_job_pause,
50 cups_job_resume,
51 cups_job_submit,
55 * 'cups_passwd_cb()' - The CUPS password callback...
58 const char * /* O - Password or NULL */
59 cups_passwd_cb(const char *prompt) /* I - Prompt */
62 * Always return NULL to indicate that no password is available...
65 (void)prompt;
67 return (NULL);
72 * 'cups_printer_fn()' - Call a function for every printer known to the
73 * system.
76 void cups_printer_fn(void (*fn)(char *, char *))
78 /* I - Function to call */
79 http_t *http; /* HTTP connection to server */
80 ipp_t *request, /* IPP Request */
81 *response; /* IPP Response */
82 ipp_attribute_t *attr; /* Current attribute */
83 cups_lang_t *language; /* Default language */
84 char *name, /* printer-name attribute */
85 *make_model, /* printer-make-and-model attribute */
86 *info; /* printer-info attribute */
87 static const char *requested[] =/* Requested attributes */
89 "printer-name",
90 "printer-make-and-model",
91 "printer-info"
92 };
95 DEBUG(5,("cups_printer_fn(%p)\n", fn));
98 * Make sure we don't ask for passwords...
101 cupsSetPasswordCB(cups_passwd_cb);
104 * Try to connect to the server...
107 if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
109 DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
110 cupsServer(), strerror(errno)));
111 return;
115 * Build a CUPS_GET_PRINTERS request, which requires the following
116 * attributes:
118 * attributes-charset
119 * attributes-natural-language
120 * requested-attributes
123 request = ippNew();
125 request->request.op.operation_id = CUPS_GET_PRINTERS;
126 request->request.op.request_id = 1;
128 language = cupsLangDefault();
130 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
131 "attributes-charset", NULL, cupsLangEncoding(language));
133 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
134 "attributes-natural-language", NULL, language->language);
136 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
137 "requested-attributes",
138 (sizeof(requested) / sizeof(requested[0])),
139 NULL, requested);
142 * Do the request and get back a response...
145 if ((response = cupsDoRequest(http, request, "/")) == NULL)
147 DEBUG(0,("Unable to get printer list - %s\n",
148 ippErrorString(cupsLastError())));
149 httpClose(http);
150 return;
153 for (attr = response->attrs; attr != NULL;)
156 * Skip leading attributes until we hit a printer...
159 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
160 attr = attr->next;
162 if (attr == NULL)
163 break;
166 * Pull the needed attributes from this printer...
169 name = NULL;
170 make_model = NULL;
171 info = NULL;
173 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
175 if (strcmp(attr->name, "printer-name") == 0 &&
176 attr->value_tag == IPP_TAG_NAME)
177 name = attr->values[0].string.text;
179 if (strcmp(attr->name, "printer-make-and-model") == 0 &&
180 attr->value_tag == IPP_TAG_TEXT)
181 make_model = attr->values[0].string.text;
183 if (strcmp(attr->name, "printer-info") == 0 &&
184 attr->value_tag == IPP_TAG_TEXT)
185 info = attr->values[0].string.text;
187 attr = attr->next;
191 * See if we have everything needed...
194 if (name == NULL)
195 break;
197 if (info == NULL || !info[0])
198 (*fn)(name, make_model);
199 else
200 (*fn)(name,info);
205 ippDelete(response);
206 httpClose(http);
211 * 'cups_printername_ok()' - Provide the equivalent of pcap_printername_ok()
212 * for CUPS.
215 int /* O - 1 if printer name OK */
216 cups_printername_ok(char *name) /* I - Name of printer */
218 http_t *http; /* HTTP connection to server */
219 ipp_t *request, /* IPP Request */
220 *response; /* IPP Response */
221 cups_lang_t *language; /* Default language */
222 char uri[HTTP_MAX_URI]; /* printer-uri attribute */
225 DEBUG(5,("cups_printername_ok(\"%s\")\n", name));
228 * Make sure we don't ask for passwords...
231 cupsSetPasswordCB(cups_passwd_cb);
234 * Try to connect to the server...
237 if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
239 DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
240 cupsServer(), strerror(errno)));
241 return (0);
245 * Build an IPP_GET_PRINTER_ATTRS request, which requires the following
246 * attributes:
248 * attributes-charset
249 * attributes-natural-language
250 * requested-attributes
251 * printer-uri
254 request = ippNew();
256 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
257 request->request.op.request_id = 1;
259 language = cupsLangDefault();
261 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
262 "attributes-charset", NULL, cupsLangEncoding(language));
264 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
265 "attributes-natural-language", NULL, language->language);
267 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
268 "requested-attributes", NULL, "printer-uri");
270 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", name);
272 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
273 "printer-uri", NULL, uri);
276 * Do the request and get back a response...
279 if ((response = cupsDoRequest(http, request, "/")) == NULL)
281 DEBUG(0,("Unable to get printer status for %s - %s\n", name,
282 ippErrorString(cupsLastError())));
283 httpClose(http);
284 return (0);
287 httpClose(http);
289 if (response->request.status.status_code >= IPP_OK_CONFLICT)
291 DEBUG(0,("Unable to get printer status for %s - %s\n", name,
292 ippErrorString(response->request.status.status_code)));
293 ippDelete(response);
294 return (0);
296 else
298 ippDelete(response);
299 return (1);
305 * 'cups_job_delete()' - Delete a job.
308 static int
309 cups_job_delete(int snum, struct printjob *pjob)
311 int ret; /* Return value */
312 http_t *http; /* HTTP connection to server */
313 ipp_t *request, /* IPP Request */
314 *response; /* IPP Response */
315 cups_lang_t *language; /* Default language */
316 char uri[HTTP_MAX_URI]; /* printer-uri attribute */
319 DEBUG(5,("cups_job_delete(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
322 * Make sure we don't ask for passwords...
325 cupsSetPasswordCB(cups_passwd_cb);
328 * Try to connect to the server...
331 if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
333 DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
334 cupsServer(), strerror(errno)));
335 return (1);
339 * Build an IPP_CANCEL_JOB request, which requires the following
340 * attributes:
342 * attributes-charset
343 * attributes-natural-language
344 * job-uri
345 * requesting-user-name
348 request = ippNew();
350 request->request.op.operation_id = IPP_CANCEL_JOB;
351 request->request.op.request_id = 1;
353 language = cupsLangDefault();
355 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
356 "attributes-charset", NULL, cupsLangEncoding(language));
358 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
359 "attributes-natural-language", NULL, language->language);
361 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
363 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
365 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
366 NULL, pjob->user);
369 * Do the request and get back a response...
372 ret = 1;
374 if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
376 if (response->request.status.status_code >= IPP_OK_CONFLICT)
377 DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
378 ippErrorString(cupsLastError())));
379 else
380 ret = 0;
382 ippDelete(response);
384 else
385 DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
386 ippErrorString(cupsLastError())));
388 httpClose(http);
390 return (ret);
395 * 'cups_job_pause()' - Pause a job.
398 static int
399 cups_job_pause(int snum, struct printjob *pjob)
401 int ret; /* Return value */
402 http_t *http; /* HTTP connection to server */
403 ipp_t *request, /* IPP Request */
404 *response; /* IPP Response */
405 cups_lang_t *language; /* Default language */
406 char uri[HTTP_MAX_URI]; /* printer-uri attribute */
409 DEBUG(5,("cups_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
412 * Make sure we don't ask for passwords...
415 cupsSetPasswordCB(cups_passwd_cb);
418 * Try to connect to the server...
421 if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
423 DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
424 cupsServer(), strerror(errno)));
425 return (1);
429 * Build an IPP_HOLD_JOB request, which requires the following
430 * attributes:
432 * attributes-charset
433 * attributes-natural-language
434 * job-uri
435 * requesting-user-name
438 request = ippNew();
440 request->request.op.operation_id = IPP_HOLD_JOB;
441 request->request.op.request_id = 1;
443 language = cupsLangDefault();
445 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
446 "attributes-charset", NULL, cupsLangEncoding(language));
448 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
449 "attributes-natural-language", NULL, language->language);
451 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
453 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
455 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
456 NULL, pjob->user);
459 * Do the request and get back a response...
462 ret = 1;
464 if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
466 if (response->request.status.status_code >= IPP_OK_CONFLICT)
467 DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
468 ippErrorString(cupsLastError())));
469 else
470 ret = 0;
472 ippDelete(response);
474 else
475 DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
476 ippErrorString(cupsLastError())));
478 httpClose(http);
480 return (ret);
485 * 'cups_job_resume()' - Resume a paused job.
488 static int
489 cups_job_resume(int snum, struct printjob *pjob)
491 int ret; /* Return value */
492 http_t *http; /* HTTP connection to server */
493 ipp_t *request, /* IPP Request */
494 *response; /* IPP Response */
495 cups_lang_t *language; /* Default language */
496 char uri[HTTP_MAX_URI]; /* printer-uri attribute */
499 DEBUG(5,("cups_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
502 * Make sure we don't ask for passwords...
505 cupsSetPasswordCB(cups_passwd_cb);
508 * Try to connect to the server...
511 if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
513 DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
514 cupsServer(), strerror(errno)));
515 return (1);
519 * Build an IPP_RELEASE_JOB request, which requires the following
520 * attributes:
522 * attributes-charset
523 * attributes-natural-language
524 * job-uri
525 * requesting-user-name
528 request = ippNew();
530 request->request.op.operation_id = IPP_RELEASE_JOB;
531 request->request.op.request_id = 1;
533 language = cupsLangDefault();
535 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
536 "attributes-charset", NULL, cupsLangEncoding(language));
538 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
539 "attributes-natural-language", NULL, language->language);
541 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
543 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
545 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
546 NULL, pjob->user);
549 * Do the request and get back a response...
552 ret = 1;
554 if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
556 if (response->request.status.status_code >= IPP_OK_CONFLICT)
557 DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
558 ippErrorString(cupsLastError())));
559 else
560 ret = 0;
562 ippDelete(response);
564 else
565 DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
566 ippErrorString(cupsLastError())));
568 httpClose(http);
570 return (ret);
575 * 'cups_job_submit()' - Submit a job for printing.
578 static int
579 cups_job_submit(int snum, struct printjob *pjob)
581 int ret; /* Return value */
582 http_t *http; /* HTTP connection to server */
583 ipp_t *request, /* IPP Request */
584 *response; /* IPP Response */
585 cups_lang_t *language; /* Default language */
586 char uri[HTTP_MAX_URI]; /* printer-uri attribute */
589 DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
592 * Make sure we don't ask for passwords...
595 cupsSetPasswordCB(cups_passwd_cb);
598 * Try to connect to the server...
601 if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
603 DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
604 cupsServer(), strerror(errno)));
605 return (1);
609 * Build an IPP_PRINT_JOB request, which requires the following
610 * attributes:
612 * attributes-charset
613 * attributes-natural-language
614 * printer-uri
615 * requesting-user-name
616 * [document-data]
619 request = ippNew();
621 request->request.op.operation_id = IPP_PRINT_JOB;
622 request->request.op.request_id = 1;
624 language = cupsLangDefault();
626 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
627 "attributes-charset", NULL, cupsLangEncoding(language));
629 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
630 "attributes-natural-language", NULL, language->language);
632 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
633 PRINTERNAME(snum));
635 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
636 "printer-uri", NULL, uri);
638 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
639 NULL, pjob->user);
641 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
642 pjob->jobname);
645 * Do the request and get back a response...
648 slprintf(uri, sizeof(uri) - 1, "/printers/%s", PRINTERNAME(snum));
650 ret = 1;
651 if ((response = cupsDoFileRequest(http, request, uri,
652 pjob->filename)) != NULL)
654 if (response->request.status.status_code >= IPP_OK_CONFLICT)
655 DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum),
656 ippErrorString(cupsLastError())));
657 else
658 ret = 0;
660 ippDelete(response);
662 else
663 DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum),
664 ippErrorString(cupsLastError())));
666 httpClose(http);
668 if ( ret == 0 )
669 unlink(pjob->filename);
670 /* else print_job_end will do it for us */
672 return (ret);
677 * 'cups_queue_get()' - Get all the jobs in the print queue.
680 static int
681 cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
683 http_t *http; /* HTTP connection to server */
684 ipp_t *request, /* IPP Request */
685 *response; /* IPP Response */
686 ipp_attribute_t *attr; /* Current attribute */
687 cups_lang_t *language; /* Default language */
688 char uri[HTTP_MAX_URI]; /* printer-uri attribute */
689 int qcount, /* Number of active queue entries */
690 qalloc; /* Number of queue entries allocated */
691 print_queue_struct *queue, /* Queue entries */
692 *temp; /* Temporary pointer for queue */
693 const char *user_name, /* job-originating-user-name attribute */
694 *job_name; /* job-name attribute */
695 int job_id; /* job-id attribute */
696 int job_k_octets; /* job-k-octets attribute */
697 time_t job_time; /* time-at-creation attribute */
698 ipp_jstate_t job_status; /* job-status attribute */
699 int job_priority; /* job-priority attribute */
700 static const char *jattrs[] = /* Requested job attributes */
702 "job-id",
703 "job-k-octets",
704 "job-name",
705 "job-originating-user-name",
706 "job-priority",
707 "job-state",
708 "time-at-creation",
710 static const char *pattrs[] = /* Requested printer attributes */
712 "printer-state",
713 "printer-state-message"
717 DEBUG(5,("cups_queue_get(%d, %p, %p)\n", snum, q, status));
720 * Make sure we don't ask for passwords...
723 cupsSetPasswordCB(cups_passwd_cb);
726 * Try to connect to the server...
729 if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
731 DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
732 cupsServer(), strerror(errno)));
733 return (0);
737 * Generate the printer URI...
740 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
741 PRINTERNAME(snum));
744 * Build an IPP_GET_JOBS request, which requires the following
745 * attributes:
747 * attributes-charset
748 * attributes-natural-language
749 * requested-attributes
750 * printer-uri
753 request = ippNew();
755 request->request.op.operation_id = IPP_GET_JOBS;
756 request->request.op.request_id = 1;
758 language = cupsLangDefault();
760 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
761 "attributes-charset", NULL, cupsLangEncoding(language));
763 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
764 "attributes-natural-language", NULL, language->language);
766 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
767 "requested-attributes",
768 (sizeof(jattrs) / sizeof(jattrs[0])),
769 NULL, jattrs);
771 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
772 "printer-uri", NULL, uri);
775 * Do the request and get back a response...
778 if ((response = cupsDoRequest(http, request, "/")) == NULL)
780 DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
781 ippErrorString(cupsLastError())));
782 httpClose(http);
783 return (0);
786 if (response->request.status.status_code >= IPP_OK_CONFLICT)
788 DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
789 ippErrorString(response->request.status.status_code)));
790 ippDelete(response);
791 httpClose(http);
793 return (0);
797 * Process the jobs...
800 qcount = 0;
801 qalloc = 0;
802 queue = NULL;
804 for (attr = response->attrs; attr != NULL; attr = attr->next)
807 * Skip leading attributes until we hit a job...
810 while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
811 attr = attr->next;
813 if (attr == NULL)
814 break;
817 * Allocate memory as needed...
819 if (qcount >= qalloc)
821 qalloc += 16;
823 temp = Realloc(queue, sizeof(print_queue_struct) * qalloc);
825 if (temp == NULL)
827 DEBUG(0,("cups_queue_get: Not enough memory!"));
828 ippDelete(response);
829 httpClose(http);
831 SAFE_FREE(queue);
832 return (0);
835 queue = temp;
838 temp = queue + qcount;
839 memset(temp, 0, sizeof(print_queue_struct));
842 * Pull the needed attributes from this job...
845 job_id = 0;
846 job_priority = 50;
847 job_status = IPP_JOB_PENDING;
848 job_time = 0;
849 job_k_octets = 0;
850 user_name = NULL;
851 job_name = NULL;
853 while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
855 if (attr->name == NULL)
857 attr = attr->next;
858 break;
861 if (strcmp(attr->name, "job-id") == 0 &&
862 attr->value_tag == IPP_TAG_INTEGER)
863 job_id = attr->values[0].integer;
865 if (strcmp(attr->name, "job-k-octets") == 0 &&
866 attr->value_tag == IPP_TAG_INTEGER)
867 job_k_octets = attr->values[0].integer;
869 if (strcmp(attr->name, "job-priority") == 0 &&
870 attr->value_tag == IPP_TAG_INTEGER)
871 job_priority = attr->values[0].integer;
873 if (strcmp(attr->name, "job-state") == 0 &&
874 attr->value_tag == IPP_TAG_ENUM)
875 job_status = (ipp_jstate_t)(attr->values[0].integer);
877 if (strcmp(attr->name, "time-at-creation") == 0 &&
878 attr->value_tag == IPP_TAG_INTEGER)
879 job_time = attr->values[0].integer;
881 if (strcmp(attr->name, "job-name") == 0 &&
882 attr->value_tag == IPP_TAG_NAME)
883 job_name = attr->values[0].string.text;
885 if (strcmp(attr->name, "job-originating-user-name") == 0 &&
886 attr->value_tag == IPP_TAG_NAME)
887 user_name = attr->values[0].string.text;
889 attr = attr->next;
893 * See if we have everything needed...
896 if (user_name == NULL || job_name == NULL || job_id == 0)
898 if (attr == NULL)
899 break;
900 else
901 continue;
904 temp->job = job_id;
905 temp->size = job_k_octets * 1024;
906 temp->status = job_status == IPP_JOB_PENDING ? LPQ_QUEUED :
907 job_status == IPP_JOB_STOPPED ? LPQ_PAUSED :
908 job_status == IPP_JOB_HELD ? LPQ_PAUSED :
909 LPQ_PRINTING;
910 temp->priority = job_priority;
911 temp->time = job_time;
912 strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1);
913 strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1);
915 qcount ++;
917 if (attr == NULL)
918 break;
921 ippDelete(response);
924 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
925 * following attributes:
927 * attributes-charset
928 * attributes-natural-language
929 * requested-attributes
930 * printer-uri
933 request = ippNew();
935 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
936 request->request.op.request_id = 1;
938 language = cupsLangDefault();
940 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
941 "attributes-charset", NULL, cupsLangEncoding(language));
943 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
944 "attributes-natural-language", NULL, language->language);
946 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
947 "requested-attributes",
948 (sizeof(pattrs) / sizeof(pattrs[0])),
949 NULL, pattrs);
951 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
952 "printer-uri", NULL, uri);
955 * Do the request and get back a response...
958 if ((response = cupsDoRequest(http, request, "/")) == NULL)
960 DEBUG(0,("Unable to get printer status for %s - %s\n", PRINTERNAME(snum),
961 ippErrorString(cupsLastError())));
962 httpClose(http);
963 *q = queue;
964 return (qcount);
967 if (response->request.status.status_code >= IPP_OK_CONFLICT)
969 DEBUG(0,("Unable to get printer status for %s - %s\n", PRINTERNAME(snum),
970 ippErrorString(response->request.status.status_code)));
971 ippDelete(response);
972 httpClose(http);
973 *q = queue;
974 return (qcount);
978 * Get the current printer status and convert it to the SAMBA values.
981 if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
983 if (attr->values[0].integer == IPP_PRINTER_STOPPED)
984 status->status = LPSTAT_STOPPED;
985 else
986 status->status = LPSTAT_OK;
989 if ((attr = ippFindAttribute(response, "printer-state-message",
990 IPP_TAG_TEXT)) != NULL)
991 fstrcpy(status->message, attr->values[0].string.text);
993 ippDelete(response);
996 * Return the job queue...
999 httpClose(http);
1001 *q = queue;
1002 return (qcount);
1007 * 'cups_queue_pause()' - Pause a print queue.
1010 static int
1011 cups_queue_pause(int snum)
1013 extern userdom_struct current_user_info;
1014 int ret; /* Return value */
1015 http_t *http; /* HTTP connection to server */
1016 ipp_t *request, /* IPP Request */
1017 *response; /* IPP Response */
1018 cups_lang_t *language; /* Default language */
1019 char uri[HTTP_MAX_URI]; /* printer-uri attribute */
1022 DEBUG(5,("cups_queue_pause(%d)\n", snum));
1025 * Make sure we don't ask for passwords...
1028 cupsSetPasswordCB(cups_passwd_cb);
1031 * Try to connect to the server...
1034 if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
1036 DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
1037 cupsServer(), strerror(errno)));
1038 return (1);
1042 * Build an IPP_PAUSE_PRINTER request, which requires the following
1043 * attributes:
1045 * attributes-charset
1046 * attributes-natural-language
1047 * printer-uri
1048 * requesting-user-name
1051 request = ippNew();
1053 request->request.op.operation_id = IPP_PAUSE_PRINTER;
1054 request->request.op.request_id = 1;
1056 language = cupsLangDefault();
1058 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1059 "attributes-charset", NULL, cupsLangEncoding(language));
1061 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1062 "attributes-natural-language", NULL, language->language);
1064 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
1065 PRINTERNAME(snum));
1067 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
1069 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
1070 NULL, current_user_info.unix_name);
1073 * Do the request and get back a response...
1076 ret = 1;
1078 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
1080 if (response->request.status.status_code >= IPP_OK_CONFLICT)
1081 DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
1082 ippErrorString(cupsLastError())));
1083 else
1084 ret = 0;
1086 ippDelete(response);
1088 else
1089 DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
1090 ippErrorString(cupsLastError())));
1092 httpClose(http);
1094 return (ret);
1099 * 'cups_queue_resume()' - Restart a print queue.
1102 static int
1103 cups_queue_resume(int snum)
1105 extern userdom_struct current_user_info;
1106 int ret; /* Return value */
1107 http_t *http; /* HTTP connection to server */
1108 ipp_t *request, /* IPP Request */
1109 *response; /* IPP Response */
1110 cups_lang_t *language; /* Default language */
1111 char uri[HTTP_MAX_URI]; /* printer-uri attribute */
1114 DEBUG(5,("cups_queue_resume(%d)\n", snum));
1117 * Make sure we don't ask for passwords...
1120 cupsSetPasswordCB(cups_passwd_cb);
1123 * Try to connect to the server...
1126 if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
1128 DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
1129 cupsServer(), strerror(errno)));
1130 return (1);
1134 * Build an IPP_RESUME_PRINTER request, which requires the following
1135 * attributes:
1137 * attributes-charset
1138 * attributes-natural-language
1139 * printer-uri
1140 * requesting-user-name
1143 request = ippNew();
1145 request->request.op.operation_id = IPP_RESUME_PRINTER;
1146 request->request.op.request_id = 1;
1148 language = cupsLangDefault();
1150 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1151 "attributes-charset", NULL, cupsLangEncoding(language));
1153 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1154 "attributes-natural-language", NULL, language->language);
1156 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
1157 PRINTERNAME(snum));
1159 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
1161 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
1162 NULL, current_user_info.unix_name);
1165 * Do the request and get back a response...
1168 ret = 1;
1170 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
1172 if (response->request.status.status_code >= IPP_OK_CONFLICT)
1173 DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
1174 ippErrorString(cupsLastError())));
1175 else
1176 ret = 0;
1178 ippDelete(response);
1180 else
1181 DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
1182 ippErrorString(cupsLastError())));
1184 httpClose(http);
1186 return (ret);
1190 #else
1191 /* this keeps fussy compilers happy */
1192 void print_cups_dummy(void) {}
1193 #endif /* HAVE_CUPS */