]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
2 | * "$Id: lp.c 4906 2006-01-10 20:53:28Z mike $" | |
3 | * | |
4 | * "lp" command for the Common UNIX Printing System (CUPS). | |
5 | * | |
6 | * Copyright 1997-2006 by Easy Software Products. | |
7 | * | |
8 | * These coded instructions, statements, and computer programs are the | |
9 | * property of Easy Software Products and are protected by Federal | |
10 | * copyright law. Distribution and use rights are outlined in the file | |
11 | * "LICENSE.txt" which should have been included with this file. If this | |
12 | * file is missing or damaged please contact Easy Software Products | |
13 | * at: | |
14 | * | |
15 | * Attn: CUPS Licensing Information | |
16 | * Easy Software Products | |
17 | * 44141 Airport View Drive, Suite 204 | |
18 | * Hollywood, Maryland 20636 USA | |
19 | * | |
20 | * Voice: (301) 373-9600 | |
21 | * EMail: cups-info@cups.org | |
22 | * WWW: http://www.cups.org | |
23 | * | |
24 | * Contents: | |
25 | * | |
26 | * main() - Parse options and send files for printing. | |
27 | * restart_job() - Restart a job. | |
28 | * set_job_attrs() - Set job attributes. | |
29 | * sighandler() - Signal catcher for when we print from stdin... | |
30 | */ | |
31 | ||
32 | /* | |
33 | * Include necessary headers... | |
34 | */ | |
35 | ||
36 | #include <stdio.h> | |
37 | #include <stdlib.h> | |
38 | #include <errno.h> | |
39 | #include <cups/string.h> | |
40 | #include <cups/cups.h> | |
41 | #include <cups/i18n.h> | |
42 | ||
43 | ||
44 | #ifndef WIN32 | |
45 | # include <unistd.h> | |
46 | # include <signal.h> | |
47 | ||
48 | ||
49 | /* | |
50 | * Local functions. | |
51 | */ | |
52 | ||
53 | void sighandler(int); | |
54 | #endif /* !WIN32 */ | |
55 | int restart_job(int job_id); | |
56 | int set_job_attrs(int job_id, int num_options, cups_option_t *options); | |
57 | ||
58 | ||
59 | /* | |
60 | * Globals... | |
61 | */ | |
62 | ||
63 | char tempfile[1024]; /* Temporary file for printing from stdin */ | |
64 | ||
65 | ||
66 | /* | |
67 | * 'main()' - Parse options and send files for printing. | |
68 | */ | |
69 | ||
70 | int | |
71 | main(int argc, /* I - Number of command-line arguments */ | |
72 | char *argv[]) /* I - Command-line arguments */ | |
73 | { | |
74 | int i, j; /* Looping vars */ | |
75 | int job_id; /* Job ID */ | |
76 | char *printer, /* Printer name */ | |
77 | *instance, /* Instance name */ | |
78 | *val, /* Option value */ | |
79 | *title; /* Job title */ | |
80 | int priority; /* Job priority (1-100) */ | |
81 | int num_copies; /* Number of copies per file */ | |
82 | int num_files; /* Number of files to print */ | |
83 | const char *files[1000]; /* Files to print */ | |
84 | int num_dests; /* Number of destinations */ | |
85 | cups_dest_t *dests, /* Destinations */ | |
86 | *dest; /* Selected destination */ | |
87 | int num_options; /* Number of options */ | |
88 | cups_option_t *options; /* Options */ | |
89 | int silent; /* Silent or verbose output? */ | |
90 | char buffer[8192]; /* Copy buffer */ | |
91 | int temp; /* Temporary file descriptor */ | |
92 | #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) | |
93 | struct sigaction action; /* Signal action */ | |
94 | struct sigaction oldaction; /* Old signal action */ | |
95 | #endif /* HAVE_SIGACTION && !HAVE_SIGSET*/ | |
96 | ||
97 | ||
98 | #ifdef __sun | |
99 | /* | |
100 | * Solaris does some rather strange things to re-queue remote print | |
101 | * jobs. On bootup, the "lp" command is run as "printd" to re-spool | |
102 | * any remote jobs in /var/spool/print. Since CUPS doesn't need this | |
103 | * nonsense, we just need to add the necessary check here to prevent | |
104 | * lp from causing boot problems... | |
105 | */ | |
106 | ||
107 | if ((val = strrchr(argv[0], '/')) != NULL) | |
108 | val ++; | |
109 | else | |
110 | val = argv[0]; | |
111 | ||
112 | if (!strcmp(val, "printd")) | |
113 | return (0); | |
114 | #endif /* __sun */ | |
115 | ||
116 | silent = 0; | |
117 | printer = NULL; | |
118 | num_dests = 0; | |
119 | dests = NULL; | |
120 | num_options = 0; | |
121 | options = NULL; | |
122 | num_files = 0; | |
123 | title = NULL; | |
124 | job_id = 0; | |
125 | ||
126 | for (i = 1; i < argc; i ++) | |
127 | if (argv[i][0] == '-' && argv[i][1]) | |
128 | switch (argv[i][1]) | |
129 | { | |
130 | case 'E' : /* Encrypt */ | |
131 | #ifdef HAVE_SSL | |
132 | cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); | |
133 | #else | |
134 | _cupsLangPrintf(stderr, NULL, | |
135 | _("%s: Sorry, no encryption support compiled in!\n"), | |
136 | argv[0]); | |
137 | #endif /* HAVE_SSL */ | |
138 | break; | |
139 | ||
140 | case 'c' : /* Copy to spool dir (always enabled) */ | |
141 | break; | |
142 | ||
143 | case 'd' : /* Destination printer or class */ | |
144 | if (argv[i][2] != '\0') | |
145 | printer = argv[i] + 2; | |
146 | else | |
147 | { | |
148 | i ++; | |
149 | ||
150 | if (i >= argc) | |
151 | { | |
152 | _cupsLangPuts(stderr, NULL, | |
153 | _("lp: Expected destination after -d option!\n")); | |
154 | return (1); | |
155 | } | |
156 | ||
157 | printer = argv[i]; | |
158 | } | |
159 | ||
160 | if ((instance = strrchr(printer, '/')) != NULL) | |
161 | *instance++ = '\0'; | |
162 | ||
163 | if (num_dests == 0) | |
164 | num_dests = cupsGetDests(&dests); | |
165 | ||
166 | if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL) | |
167 | { | |
168 | for (j = 0; j < dest->num_options; j ++) | |
169 | if (cupsGetOption(dest->options[j].name, num_options, options) == NULL) | |
170 | num_options = cupsAddOption(dest->options[j].name, | |
171 | dest->options[j].value, | |
172 | num_options, &options); | |
173 | } | |
174 | break; | |
175 | ||
176 | case 'f' : /* Form */ | |
177 | if (!argv[i][2]) | |
178 | { | |
179 | i ++; | |
180 | ||
181 | if (i >= argc) | |
182 | { | |
183 | _cupsLangPuts(stderr, NULL, | |
184 | _("lp: Expected form after -f option!\n")); | |
185 | return (1); | |
186 | } | |
187 | } | |
188 | ||
189 | fputs("lp: Warning - form option ignored!\n", stderr); | |
190 | break; | |
191 | ||
192 | case 'h' : /* Destination host */ | |
193 | if (argv[i][2] != '\0') | |
194 | cupsSetServer(argv[i] + 2); | |
195 | else | |
196 | { | |
197 | i ++; | |
198 | ||
199 | if (i >= argc) | |
200 | { | |
201 | _cupsLangPuts(stderr, NULL, | |
202 | _("lp: Expected hostname after -h option!\n")); | |
203 | return (1); | |
204 | } | |
205 | ||
206 | cupsSetServer(argv[i]); | |
207 | } | |
208 | break; | |
209 | ||
210 | case 'i' : /* Change job */ | |
211 | if (argv[i][2]) | |
212 | val = argv[i] + 2; | |
213 | else | |
214 | { | |
215 | i ++; | |
216 | ||
217 | if (i >= argc) | |
218 | { | |
219 | _cupsLangPuts(stderr, NULL, | |
220 | _("lp: Expected job ID after -i option!\n")); | |
221 | return (1); | |
222 | } | |
223 | ||
224 | val = argv[i]; | |
225 | } | |
226 | ||
227 | if (num_files > 0) | |
228 | { | |
229 | _cupsLangPuts(stderr, NULL, | |
230 | _("lp: Error - cannot print files and alter " | |
231 | "jobs simultaneously!\n")); | |
232 | return (1); | |
233 | } | |
234 | ||
235 | if (strrchr(val, '-') != NULL) | |
236 | job_id = atoi(strrchr(val, '-') + 1); | |
237 | else | |
238 | job_id = atoi(val); | |
239 | ||
240 | if (job_id < 0) | |
241 | { | |
242 | _cupsLangPuts(stderr, NULL, _("lp: Error - bad job ID!\n")); | |
243 | break; | |
244 | } | |
245 | break; | |
246 | ||
247 | case 'm' : /* Send email when job is done */ | |
248 | #ifdef __sun | |
249 | case 'p' : /* Notify on completion */ | |
250 | #endif /* __sun */ | |
251 | case 'w' : /* Write to console or email */ | |
252 | break; | |
253 | ||
254 | case 'n' : /* Number of copies */ | |
255 | if (argv[i][2] != '\0') | |
256 | num_copies = atoi(argv[i] + 2); | |
257 | else | |
258 | { | |
259 | i ++; | |
260 | ||
261 | if (i >= argc) | |
262 | { | |
263 | _cupsLangPuts(stderr, NULL, | |
264 | _("lp: Expected copies after -n option!\n")); | |
265 | return (1); | |
266 | } | |
267 | ||
268 | num_copies = atoi(argv[i]); | |
269 | } | |
270 | ||
271 | sprintf(buffer, "%d", num_copies); | |
272 | num_options = cupsAddOption("copies", buffer, num_options, &options); | |
273 | break; | |
274 | ||
275 | case 'o' : /* Option */ | |
276 | if (argv[i][2] != '\0') | |
277 | num_options = cupsParseOptions(argv[i] + 2, num_options, &options); | |
278 | else | |
279 | { | |
280 | i ++; | |
281 | ||
282 | if (i >= argc) | |
283 | { | |
284 | _cupsLangPuts(stderr, NULL, | |
285 | _("lp: Expected option string after -o option!\n")); | |
286 | return (1); | |
287 | } | |
288 | ||
289 | num_options = cupsParseOptions(argv[i], num_options, &options); | |
290 | } | |
291 | break; | |
292 | ||
293 | #ifndef __sun | |
294 | case 'p' : /* Queue priority */ | |
295 | #endif /* !__sun */ | |
296 | case 'q' : /* Queue priority */ | |
297 | if (argv[i][2] != '\0') | |
298 | priority = atoi(argv[i] + 2); | |
299 | else | |
300 | { | |
301 | if ((i + 1) >= argc) | |
302 | { | |
303 | _cupsLangPrintf(stderr, NULL, | |
304 | _("lp: Expected priority after -%c option!\n"), | |
305 | argv[i][1]); | |
306 | return (1); | |
307 | } | |
308 | ||
309 | i ++; | |
310 | ||
311 | priority = atoi(argv[i]); | |
312 | } | |
313 | ||
314 | /* | |
315 | * For 100% Solaris compatibility, need to add: | |
316 | * | |
317 | * priority = 99 * (39 - priority) / 39 + 1; | |
318 | * | |
319 | * However, to keep CUPS lp the same across all platforms | |
320 | * we will break compatibility this far... | |
321 | */ | |
322 | ||
323 | if (priority < 1 || priority > 100) | |
324 | { | |
325 | _cupsLangPuts(stderr, NULL, | |
326 | _("lp: Priority must be between 1 and 100.\n")); | |
327 | return (1); | |
328 | } | |
329 | ||
330 | sprintf(buffer, "%d", priority); | |
331 | num_options = cupsAddOption("job-priority", buffer, num_options, &options); | |
332 | break; | |
333 | ||
334 | case 's' : /* Silent */ | |
335 | silent = 1; | |
336 | break; | |
337 | ||
338 | case 't' : /* Title */ | |
339 | if (argv[i][2] != '\0') | |
340 | title = argv[i] + 2; | |
341 | else | |
342 | { | |
343 | i ++; | |
344 | ||
345 | if (i >= argc) | |
346 | { | |
347 | _cupsLangPuts(stderr, NULL, | |
348 | _("lp: Expected title after -t option!\n")); | |
349 | return (1); | |
350 | } | |
351 | ||
352 | title = argv[i]; | |
353 | } | |
354 | break; | |
355 | ||
356 | case 'y' : /* mode-list */ | |
357 | if (!argv[i][2]) | |
358 | { | |
359 | i ++; | |
360 | ||
361 | if (i >= argc) | |
362 | { | |
363 | _cupsLangPuts(stderr, NULL, | |
364 | _("lp: Expected mode list after -y option!\n")); | |
365 | return (1); | |
366 | } | |
367 | } | |
368 | ||
369 | _cupsLangPuts(stderr, NULL, | |
370 | _("lp: Warning - mode option ignored!\n")); | |
371 | break; | |
372 | ||
373 | case 'H' : /* Hold job */ | |
374 | if (argv[i][2]) | |
375 | val = argv[i] + 2; | |
376 | else | |
377 | { | |
378 | i ++; | |
379 | ||
380 | if (i >= argc) | |
381 | { | |
382 | _cupsLangPuts(stderr, NULL, | |
383 | _("lp: Expected hold name after -H option!\n")); | |
384 | return (1); | |
385 | } | |
386 | ||
387 | val = argv[i]; | |
388 | } | |
389 | ||
390 | if (!strcmp(val, "hold")) | |
391 | num_options = cupsAddOption("job-hold-until", "indefinite", | |
392 | num_options, &options); | |
393 | else if (!strcmp(val, "resume") || | |
394 | !strcmp(val, "release")) | |
395 | num_options = cupsAddOption("job-hold-until", "no-hold", | |
396 | num_options, &options); | |
397 | else if (!strcmp(val, "immediate")) | |
398 | num_options = cupsAddOption("job-priority", "100", | |
399 | num_options, &options); | |
400 | else if (!strcmp(val, "restart")) | |
401 | { | |
402 | if (job_id < 1) | |
403 | { | |
404 | _cupsLangPuts(stderr, NULL, | |
405 | _("lp: Need job ID (-i) before \"-H restart\"!\n")); | |
406 | return (1); | |
407 | } | |
408 | ||
409 | if (restart_job(job_id)) | |
410 | return (1); | |
411 | } | |
412 | else | |
413 | num_options = cupsAddOption("job-hold-until", val, | |
414 | num_options, &options); | |
415 | break; | |
416 | ||
417 | case 'P' : /* Page list */ | |
418 | if (argv[i][2]) | |
419 | val = argv[i] + 2; | |
420 | else | |
421 | { | |
422 | i ++; | |
423 | ||
424 | if (i >= argc) | |
425 | { | |
426 | _cupsLangPuts(stderr, NULL, | |
427 | _("lp: Expected page list after -P option!\n")); | |
428 | return (1); | |
429 | } | |
430 | ||
431 | val = argv[i]; | |
432 | } | |
433 | ||
434 | num_options = cupsAddOption("page-ranges", val, num_options, | |
435 | &options); | |
436 | break; | |
437 | ||
438 | case 'S' : /* character set */ | |
439 | if (!argv[i][2]) | |
440 | { | |
441 | i ++; | |
442 | ||
443 | if (i >= argc) | |
444 | { | |
445 | _cupsLangPuts(stderr, NULL, | |
446 | _("lp: Expected character set after -S option!\n")); | |
447 | return (1); | |
448 | } | |
449 | } | |
450 | ||
451 | _cupsLangPuts(stderr, NULL, | |
452 | _("lp: Warning - character set option ignored!\n")); | |
453 | break; | |
454 | ||
455 | case 'T' : /* Content-Type */ | |
456 | if (!argv[i][2]) | |
457 | { | |
458 | i ++; | |
459 | ||
460 | if (i >= argc) | |
461 | { | |
462 | _cupsLangPuts(stderr, NULL, | |
463 | _("lp: Expected content type after -T option!\n")); | |
464 | return (1); | |
465 | } | |
466 | } | |
467 | ||
468 | _cupsLangPuts(stderr, NULL, | |
469 | _("lp: Warning - content type option ignored!\n")); | |
470 | break; | |
471 | ||
472 | default : | |
473 | _cupsLangPrintf(stderr, NULL, _("lp: Unknown option \'%c\'!\n"), | |
474 | argv[i][1]); | |
475 | return (1); | |
476 | } | |
477 | else if (!strcmp(argv[i], "-")) | |
478 | { | |
479 | if (num_files || job_id) | |
480 | { | |
481 | _cupsLangPuts(stderr, NULL, | |
482 | _("lp: Error - cannot print from stdin if files or a " | |
483 | "job ID are provided!\n")); | |
484 | return (1); | |
485 | } | |
486 | ||
487 | break; | |
488 | } | |
489 | else if (num_files < 1000 && job_id == 0) | |
490 | { | |
491 | /* | |
492 | * Print a file... | |
493 | */ | |
494 | ||
495 | if (access(argv[i], R_OK) != 0) | |
496 | { | |
497 | _cupsLangPrintf(stderr, NULL, _("lp: Unable to access \"%s\" - %s\n"), | |
498 | argv[i], strerror(errno)); | |
499 | return (1); | |
500 | } | |
501 | ||
502 | files[num_files] = argv[i]; | |
503 | num_files ++; | |
504 | ||
505 | if (title == NULL) | |
506 | { | |
507 | if ((title = strrchr(argv[i], '/')) != NULL) | |
508 | title ++; | |
509 | else | |
510 | title = argv[i]; | |
511 | } | |
512 | } | |
513 | else | |
514 | _cupsLangPrintf(stderr, NULL, _("lp: Too many files - \"%s\"\n"), | |
515 | argv[i]); | |
516 | ||
517 | /* | |
518 | * See if we are altering an existing job... | |
519 | */ | |
520 | ||
521 | if (job_id) | |
522 | return (set_job_attrs(job_id, num_options, options)); | |
523 | ||
524 | /* | |
525 | * See if we have any files to print; if not, print from stdin... | |
526 | */ | |
527 | ||
528 | if (printer == NULL) | |
529 | { | |
530 | if (num_dests == 0) | |
531 | num_dests = cupsGetDests(&dests); | |
532 | ||
533 | if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL) | |
534 | { | |
535 | printer = dest->name; | |
536 | ||
537 | for (j = 0; j < dest->num_options; j ++) | |
538 | if (cupsGetOption(dest->options[j].name, num_options, options) == NULL) | |
539 | num_options = cupsAddOption(dest->options[j].name, | |
540 | dest->options[j].value, | |
541 | num_options, &options); | |
542 | } | |
543 | } | |
544 | ||
545 | if (printer == NULL) | |
546 | { | |
547 | val = NULL; | |
548 | ||
549 | if ((printer = getenv("LPDEST")) == NULL) | |
550 | { | |
551 | if ((printer = getenv("PRINTER")) != NULL) | |
552 | { | |
553 | if (!strcmp(printer, "lp")) | |
554 | printer = NULL; | |
555 | else | |
556 | val = "PRINTER"; | |
557 | } | |
558 | } | |
559 | else | |
560 | val = "LPDEST"; | |
561 | ||
562 | if (printer && !cupsGetDest(printer, NULL, num_dests, dests)) | |
563 | _cupsLangPrintf(stderr, NULL, | |
564 | _("lp: error - %s environment variable names " | |
565 | "non-existent destination \"%s\"!\n"), | |
566 | val, printer); | |
567 | else if (cupsLastError() == IPP_NOT_FOUND) | |
568 | _cupsLangPuts(stderr, NULL, | |
569 | _("lp: error - no default destination available.\n")); | |
570 | else | |
571 | _cupsLangPuts(stderr, NULL, | |
572 | _("lp: error - scheduler not responding!\n")); | |
573 | ||
574 | return (1); | |
575 | } | |
576 | ||
577 | if (num_files > 0) | |
578 | job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options); | |
579 | else | |
580 | { | |
581 | num_files = 1; | |
582 | ||
583 | #ifndef WIN32 | |
584 | # if defined(HAVE_SIGSET) | |
585 | sigset(SIGHUP, sighandler); | |
586 | if (sigset(SIGINT, sighandler) == SIG_IGN) | |
587 | sigset(SIGINT, SIG_IGN); | |
588 | sigset(SIGTERM, sighandler); | |
589 | # elif defined(HAVE_SIGACTION) | |
590 | memset(&action, 0, sizeof(action)); | |
591 | action.sa_handler = sighandler; | |
592 | ||
593 | sigaction(SIGHUP, &action, NULL); | |
594 | sigaction(SIGINT, NULL, &oldaction); | |
595 | if (oldaction.sa_handler != SIG_IGN) | |
596 | sigaction(SIGINT, &action, NULL); | |
597 | sigaction(SIGTERM, &action, NULL); | |
598 | # else | |
599 | signal(SIGHUP, sighandler); | |
600 | if (signal(SIGINT, sighandler) == SIG_IGN) | |
601 | signal(SIGINT, SIG_IGN); | |
602 | signal(SIGTERM, sighandler); | |
603 | # endif | |
604 | #endif /* !WIN32 */ | |
605 | ||
606 | temp = cupsTempFd(tempfile, sizeof(tempfile)); | |
607 | ||
608 | if (temp < 0) | |
609 | { | |
610 | _cupsLangPrintf(stderr, NULL, | |
611 | _("lp: unable to create temporary file \"%s\" - %s\n"), | |
612 | tempfile, strerror(errno)); | |
613 | return (1); | |
614 | } | |
615 | ||
616 | while ((i = read(0, buffer, sizeof(buffer))) > 0) | |
617 | if (write(temp, buffer, i) < 0) | |
618 | { | |
619 | _cupsLangPrintf(stderr, NULL, | |
620 | _("lp: error - unable to write to temporary file " | |
621 | "\"%s\" - %s\n"), | |
622 | tempfile, strerror(errno)); | |
623 | close(temp); | |
624 | unlink(tempfile); | |
625 | return (1); | |
626 | } | |
627 | ||
628 | i = lseek(temp, 0, SEEK_CUR); | |
629 | close(temp); | |
630 | ||
631 | if (i == 0) | |
632 | { | |
633 | _cupsLangPuts(stderr, NULL, | |
634 | _("lp: stdin is empty, so no job has been sent.\n")); | |
635 | unlink(tempfile); | |
636 | return (1); | |
637 | } | |
638 | ||
639 | if (title) | |
640 | job_id = cupsPrintFile(printer, tempfile, title, num_options, options); | |
641 | else | |
642 | job_id = cupsPrintFile(printer, tempfile, "(stdin)", num_options, options); | |
643 | ||
644 | unlink(tempfile); | |
645 | } | |
646 | ||
647 | if (job_id < 1) | |
648 | { | |
649 | _cupsLangPrintf(stderr, NULL, | |
650 | _("lp: unable to print file: %s\n"), | |
651 | ippErrorString(cupsLastError())); | |
652 | return (1); | |
653 | } | |
654 | else if (!silent) | |
655 | _cupsLangPrintf(stdout, NULL, | |
656 | _("request id is %s-%d (%d file(s))\n"), | |
657 | printer, job_id, num_files); | |
658 | ||
659 | return (0); | |
660 | } | |
661 | ||
662 | ||
663 | /* | |
664 | * 'restart_job()' - Restart a job. | |
665 | */ | |
666 | ||
667 | int /* O - Exit status */ | |
668 | restart_job(int job_id) /* I - Job ID */ | |
669 | { | |
670 | http_t *http; /* HTTP connection to server */ | |
671 | ipp_t *request, /* IPP request */ | |
672 | *response; /* IPP response */ | |
673 | cups_lang_t *language; /* Language for request */ | |
674 | char uri[HTTP_MAX_URI]; /* URI for job */ | |
675 | ||
676 | ||
677 | http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); | |
678 | ||
679 | language = cupsLangDefault(); | |
680 | ||
681 | request = ippNew(); | |
682 | request->request.op.operation_id = IPP_RESTART_JOB; | |
683 | request->request.op.request_id = 1; | |
684 | ||
685 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, | |
686 | "attributes-charset", NULL, cupsLangEncoding(language)); | |
687 | ||
688 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, | |
689 | "attributes-natural-language", NULL, language->language); | |
690 | ||
691 | sprintf(uri, "ipp://localhost/jobs/%d", job_id); | |
692 | ||
693 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
694 | "job-uri", NULL, uri); | |
695 | ||
696 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, | |
697 | "requesting-user-name", NULL, cupsUser()); | |
698 | ||
699 | if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) | |
700 | { | |
701 | if (response->request.status.status_code > IPP_OK_CONFLICT) | |
702 | { | |
703 | _cupsLangPrintf(stderr, NULL, _("lp: restart-job failed: %s\n"), | |
704 | ippErrorString(response->request.status.status_code)); | |
705 | ippDelete(response); | |
706 | return (1); | |
707 | } | |
708 | ||
709 | ippDelete(response); | |
710 | } | |
711 | else | |
712 | { | |
713 | _cupsLangPrintf(stderr, NULL, _("lp: restart-job failed: %s\n"), | |
714 | ippErrorString(cupsLastError())); | |
715 | return (1); | |
716 | } | |
717 | ||
718 | return (0); | |
719 | } | |
720 | ||
721 | ||
722 | /* | |
723 | * 'set_job_attrs()' - Set job attributes. | |
724 | */ | |
725 | ||
726 | int /* O - Exit status */ | |
727 | set_job_attrs(int job_id, /* I - Job ID */ | |
728 | int num_options,/* I - Number of options */ | |
729 | cups_option_t *options) /* I - Options */ | |
730 | { | |
731 | http_t *http; /* HTTP connection to server */ | |
732 | ipp_t *request, /* IPP request */ | |
733 | *response; /* IPP response */ | |
734 | cups_lang_t *language; /* Language for request */ | |
735 | char uri[HTTP_MAX_URI]; /* URI for job */ | |
736 | ||
737 | ||
738 | if (num_options == 0) | |
739 | return (0); | |
740 | ||
741 | http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); | |
742 | ||
743 | language = cupsLangDefault(); | |
744 | ||
745 | request = ippNew(); | |
746 | request->request.op.operation_id = IPP_SET_JOB_ATTRIBUTES; | |
747 | request->request.op.request_id = 1; | |
748 | ||
749 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, | |
750 | "attributes-charset", NULL, cupsLangEncoding(language)); | |
751 | ||
752 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, | |
753 | "attributes-natural-language", NULL, language->language); | |
754 | ||
755 | sprintf(uri, "ipp://localhost/jobs/%d", job_id); | |
756 | ||
757 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
758 | "job-uri", NULL, uri); | |
759 | ||
760 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, | |
761 | "requesting-user-name", NULL, cupsUser()); | |
762 | ||
763 | cupsEncodeOptions(request, num_options, options); | |
764 | ||
765 | if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) | |
766 | { | |
767 | if (response->request.status.status_code > IPP_OK_CONFLICT) | |
768 | { | |
769 | _cupsLangPrintf(stderr, NULL, _("lp: set-job-attributes failed: %s\n"), | |
770 | ippErrorString(response->request.status.status_code)); | |
771 | ippDelete(response); | |
772 | return (1); | |
773 | } | |
774 | ||
775 | ippDelete(response); | |
776 | } | |
777 | else | |
778 | { | |
779 | _cupsLangPrintf(stderr, NULL, _("lp: set-job-attributes failed: %s\n"), | |
780 | ippErrorString(cupsLastError())); | |
781 | return (1); | |
782 | } | |
783 | ||
784 | return (0); | |
785 | } | |
786 | ||
787 | ||
788 | #ifndef WIN32 | |
789 | /* | |
790 | * 'sighandler()' - Signal catcher for when we print from stdin... | |
791 | */ | |
792 | ||
793 | void | |
794 | sighandler(int s) /* I - Signal number */ | |
795 | { | |
796 | /* | |
797 | * Remove the temporary file we're using to print from stdin... | |
798 | */ | |
799 | ||
800 | unlink(tempfile); | |
801 | ||
802 | /* | |
803 | * Exit... | |
804 | */ | |
805 | ||
806 | exit(s); | |
807 | } | |
808 | #endif /* !WIN32 */ | |
809 | ||
810 | ||
811 | /* | |
812 | * End of "$Id: lp.c 4906 2006-01-10 20:53:28Z mike $". | |
813 | */ |