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