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 */
|