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