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