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