]> git.ipfire.org Git - thirdparty/cups.git/blame - systemv/lp.c
Update ipp documentation to reflect the behavior of configuring WiFi on IPP USB printers.
[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 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 655static int /* O - Exit status */
fa73b229 656restart_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
697static int /* O - Exit status */
698set_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
747static void
748usage(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}