]>
git.ipfire.org Git - thirdparty/cups.git/blob - systemv/lp.c
2 * "$Id: lp.c 7170 2008-01-04 02:21:30Z mike $"
4 * "lp" command for the Common UNIX Printing System (CUPS).
6 * Copyright 2007-2008 by Apple Inc.
7 * Copyright 1997-2007 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
17 * main() - Parse options and send files for printing.
18 * restart_job() - Restart a job.
19 * set_job_attrs() - Set job attributes.
23 * Include necessary headers...
29 #include <cups/string.h>
30 #include <cups/cups.h>
31 #include <cups/i18n.h>
38 int restart_job(const char *command
, int job_id
);
39 int set_job_attrs(const char *command
, int job_id
, int num_options
,
40 cups_option_t
*options
);
44 * 'main()' - Parse options and send files for printing.
48 main(int argc
, /* I - Number of command-line arguments */
49 char *argv
[]) /* I - Command-line arguments */
51 int i
, j
; /* Looping vars */
52 int job_id
; /* Job ID */
53 char *printer
, /* Printer name */
54 *instance
, /* Instance name */
55 *val
, /* Option value */
56 *title
; /* Job title */
57 int priority
; /* Job priority (1-100) */
58 int num_copies
; /* Number of copies per file */
59 int num_files
; /* Number of files to print */
60 const char *files
[1000]; /* Files to print */
61 cups_dest_t
*dest
; /* Selected destination */
62 int num_options
; /* Number of options */
63 cups_option_t
*options
; /* Options */
64 int end_options
; /* No more options? */
65 int silent
; /* Silent or verbose output? */
66 char buffer
[8192]; /* Copy buffer */
71 * Solaris does some rather strange things to re-queue remote print
72 * jobs. On bootup, the "lp" command is run as "printd" to re-spool
73 * any remote jobs in /var/spool/print. Since CUPS doesn't need this
74 * nonsense, we just need to add the necessary check here to prevent
75 * lp from causing boot problems...
78 if ((val
= strrchr(argv
[0], '/')) != NULL
)
83 if (!strcmp(val
, "printd"))
99 for (i
= 1; i
< argc
; i
++)
100 if (argv
[i
][0] == '-' && argv
[i
][1] && !end_options
)
103 case 'E' : /* Encrypt */
105 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED
);
107 _cupsLangPrintf(stderr
,
108 _("%s: Sorry, no encryption support compiled in!\n"),
110 #endif /* HAVE_SSL */
113 case 'U' : /* Username */
114 if (argv
[i
][2] != '\0')
115 cupsSetUser(argv
[i
] + 2);
121 _cupsLangPrintf(stderr
,
122 _("%s: Error - expected username after "
128 cupsSetUser(argv
[i
]);
132 case 'c' : /* Copy to spool dir (always enabled) */
135 case 'd' : /* Destination printer or class */
136 if (argv
[i
][2] != '\0')
137 printer
= argv
[i
] + 2;
144 _cupsLangPrintf(stderr
,
145 _("%s: Error - expected destination after "
154 if ((instance
= strrchr(printer
, '/')) != NULL
)
157 if ((dest
= cupsGetNamedDest(NULL
, printer
, instance
)) != NULL
)
159 for (j
= 0; j
< dest
->num_options
; j
++)
160 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
161 num_options
= cupsAddOption(dest
->options
[j
].name
,
162 dest
->options
[j
].value
,
163 num_options
, &options
);
167 case 'f' : /* Form */
174 _cupsLangPrintf(stderr
,
175 _("%s: Error - expected form after \'-f\' "
182 _cupsLangPrintf(stderr
, _("%s: Warning - form option ignored!\n"),
186 case 'h' : /* Destination host */
187 if (argv
[i
][2] != '\0')
188 cupsSetServer(argv
[i
] + 2);
195 _cupsLangPrintf(stderr
,
196 _("%s: Error - expected hostname after "
202 cupsSetServer(argv
[i
]);
206 case 'i' : /* Change job */
215 _cupsLangPrintf(stderr
,
216 _("%s: Expected job ID after \'-i\' option!\n"),
226 _cupsLangPrintf(stderr
,
227 _("%s: Error - cannot print files and alter "
228 "jobs simultaneously!\n"),
233 if (strrchr(val
, '-') != NULL
)
234 job_id
= atoi(strrchr(val
, '-') + 1);
240 _cupsLangPrintf(stderr
, _("%s: Error - bad job ID!\n"), argv
[0]);
245 case 'm' : /* Send email when job is done */
247 case 'p' : /* Notify on completion */
249 case 'w' : /* Write to console or email */
251 char email
[1024]; /* EMail address */
254 snprintf(email
, sizeof(email
), "mailto:%s@%s", cupsUser(),
255 httpGetHostname(NULL
, buffer
, sizeof(buffer
)));
256 num_options
= cupsAddOption("notify-recipient-uri", email
,
257 num_options
, &options
);
263 case 'n' : /* Number of copies */
264 if (argv
[i
][2] != '\0')
265 num_copies
= atoi(argv
[i
] + 2);
272 _cupsLangPrintf(stderr
,
273 _("%s: Error - expected copies after "
279 num_copies
= atoi(argv
[i
]);
282 sprintf(buffer
, "%d", num_copies
);
283 num_options
= cupsAddOption("copies", buffer
, num_options
, &options
);
286 case 'o' : /* Option */
287 if (argv
[i
][2] != '\0')
288 num_options
= cupsParseOptions(argv
[i
] + 2, num_options
, &options
);
295 _cupsLangPrintf(stderr
,
296 _("%s: Error - expected option string after "
302 num_options
= cupsParseOptions(argv
[i
], num_options
, &options
);
307 case 'p' : /* Queue priority */
309 case 'q' : /* Queue priority */
310 if (argv
[i
][2] != '\0')
311 priority
= atoi(argv
[i
] + 2);
316 _cupsLangPrintf(stderr
,
317 _("%s: Error - expected priority after "
318 "\'-%c\' option!\n"),
319 argv
[0], argv
[i
][1]);
325 priority
= atoi(argv
[i
]);
329 * For 100% Solaris compatibility, need to add:
331 * priority = 99 * (39 - priority) / 39 + 1;
333 * However, to keep CUPS lp the same across all platforms
334 * we will break compatibility this far...
337 if (priority
< 1 || priority
> 100)
339 _cupsLangPrintf(stderr
,
340 _("%s: Error - priority must be between 1 and "
346 sprintf(buffer
, "%d", priority
);
347 num_options
= cupsAddOption("job-priority", buffer
, num_options
, &options
);
350 case 's' : /* Silent */
354 case 't' : /* Title */
355 if (argv
[i
][2] != '\0')
363 _cupsLangPrintf(stderr
,
364 _("%s: Error - expected title after "
374 case 'y' : /* mode-list */
381 _cupsLangPrintf(stderr
,
382 _("%s: Error - expected mode list after "
389 _cupsLangPrintf(stderr
,
390 _("%s: Warning - mode option ignored!\n"),
394 case 'H' : /* Hold job */
403 _cupsLangPrintf(stderr
,
404 _("%s: Error - expected hold name after "
413 if (!strcmp(val
, "hold"))
414 num_options
= cupsAddOption("job-hold-until", "indefinite",
415 num_options
, &options
);
416 else if (!strcmp(val
, "resume") ||
417 !strcmp(val
, "release"))
418 num_options
= cupsAddOption("job-hold-until", "no-hold",
419 num_options
, &options
);
420 else if (!strcmp(val
, "immediate"))
422 num_options
= cupsAddOption("job-hold-until", "no-hold",
423 num_options
, &options
);
424 num_options
= cupsAddOption("job-priority", "100",
425 num_options
, &options
);
427 else if (!strcmp(val
, "restart"))
431 _cupsLangPrintf(stderr
,
432 _("%s: Need job ID (\'-i jobid\') before "
433 "\'-H restart\'!\n"),
438 if (restart_job(argv
[0], job_id
))
442 num_options
= cupsAddOption("job-hold-until", val
,
443 num_options
, &options
);
446 case 'P' : /* Page list */
455 _cupsLangPrintf(stderr
,
456 _("%s: Error - expected page list after "
465 num_options
= cupsAddOption("page-ranges", val
, num_options
,
469 case 'S' : /* character set */
476 _cupsLangPrintf(stderr
,
477 _("%s: Error - expected character set after "
484 _cupsLangPrintf(stderr
,
485 _("%s: Warning - character set option ignored!\n"),
489 case 'T' : /* Content-Type */
496 _cupsLangPrintf(stderr
,
497 _("%s: Error - expected content type after "
504 _cupsLangPrintf(stderr
,
505 _("%s: Warning - content type option ignored!\n"),
509 case '-' : /* Stop processing options */
514 _cupsLangPrintf(stderr
, _("%s: Error - unknown option \'%c\'!\n"),
515 argv
[0], argv
[i
][1]);
518 else if (!strcmp(argv
[i
], "-"))
520 if (num_files
|| job_id
)
522 _cupsLangPrintf(stderr
,
523 _("%s: Error - cannot print from stdin if files or a "
524 "job ID are provided!\n"),
531 else if (num_files
< 1000 && job_id
== 0)
537 if (access(argv
[i
], R_OK
) != 0)
539 _cupsLangPrintf(stderr
, _("%s: Error - unable to access \"%s\" - %s\n"),
540 argv
[0], argv
[i
], strerror(errno
));
544 files
[num_files
] = argv
[i
];
549 if ((title
= strrchr(argv
[i
], '/')) != NULL
)
556 _cupsLangPrintf(stderr
, _("%s: Error - too many files - \"%s\"\n"),
560 * See if we are altering an existing job...
564 return (set_job_attrs(argv
[0], job_id
, num_options
, options
));
567 * See if we have any files to print; if not, print from stdin...
572 if ((dest
= cupsGetNamedDest(NULL
, NULL
, NULL
)) != NULL
)
574 printer
= dest
->name
;
576 for (j
= 0; j
< dest
->num_options
; j
++)
577 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
578 num_options
= cupsAddOption(dest
->options
[j
].name
,
579 dest
->options
[j
].value
,
580 num_options
, &options
);
588 if ((printer
= getenv("LPDEST")) == NULL
)
590 if ((printer
= getenv("PRINTER")) != NULL
)
592 if (!strcmp(printer
, "lp"))
601 if (printer
&& !cupsGetNamedDest(NULL
, printer
, NULL
))
602 _cupsLangPrintf(stderr
,
603 _("%s: Error - %s environment variable names "
604 "non-existent destination \"%s\"!\n"),
605 argv
[0], val
, printer
);
606 else if (cupsLastError() == IPP_NOT_FOUND
)
607 _cupsLangPrintf(stderr
,
608 _("%s: Error - no default destination available.\n"),
611 _cupsLangPrintf(stderr
,
612 _("%s: Error - scheduler not responding!\n"),
619 job_id
= cupsPrintFiles(printer
, num_files
, files
, title
, num_options
, options
);
620 else if ((job_id
= cupsCreateJob(CUPS_HTTP_DEFAULT
, printer
,
621 title
? title
: "(stdin)",
622 num_options
, options
)) > 0)
624 http_status_t status
; /* Write status */
625 const char *format
; /* Document format */
626 ssize_t bytes
; /* Bytes read */
629 if (cupsGetOption("raw", num_options
, options
))
630 format
= CUPS_FORMAT_RAW
;
631 else if ((format
= cupsGetOption("document-format", num_options
,
633 format
= CUPS_FORMAT_AUTO
;
635 status
= cupsStartDocument(CUPS_HTTP_DEFAULT
, printer
, job_id
, NULL
,
638 while (status
== HTTP_CONTINUE
&&
639 (bytes
= read(0, buffer
, sizeof(buffer
))) > 0)
640 status
= cupsWriteRequestData(CUPS_HTTP_DEFAULT
, buffer
, bytes
);
642 if (status
!= HTTP_CONTINUE
)
644 _cupsLangPrintf(stderr
,
645 _("%s: Error - unable to queue from stdin - %s\n"),
646 argv
[0], httpStatus(status
));
650 if (cupsFinishDocument(CUPS_HTTP_DEFAULT
, printer
) != IPP_OK
)
656 _cupsLangPrintf(stderr
, "%s: %s\n", argv
[0], cupsLastErrorString());
660 _cupsLangPrintf(stdout
, _("request id is %s-%d (%d file(s))\n"),
661 printer
, job_id
, num_files
);
668 * 'restart_job()' - Restart a job.
671 int /* O - Exit status */
672 restart_job(const char *command
, /* I - Command name */
673 int job_id
) /* I - Job ID */
675 ipp_t
*request
; /* IPP request */
676 char uri
[HTTP_MAX_URI
]; /* URI for job */
679 request
= ippNewRequest(IPP_RESTART_JOB
);
681 sprintf(uri
, "ipp://localhost/jobs/%d", job_id
);
683 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
,
684 "job-uri", NULL
, uri
);
686 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
,
687 "requesting-user-name", NULL
, cupsUser());
689 ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT
, request
, "/jobs"));
691 if (cupsLastError() > IPP_OK_CONFLICT
)
693 _cupsLangPrintf(stderr
, "%s: %s\n", command
, cupsLastErrorString());
702 * 'set_job_attrs()' - Set job attributes.
705 int /* O - Exit status */
706 set_job_attrs(const char *command
, /* I - Command name */
707 int job_id
, /* I - Job ID */
708 int num_options
,/* I - Number of options */
709 cups_option_t
*options
) /* I - Options */
711 ipp_t
*request
; /* IPP request */
712 char uri
[HTTP_MAX_URI
]; /* URI for job */
715 if (num_options
== 0)
718 request
= ippNewRequest(IPP_SET_JOB_ATTRIBUTES
);
720 sprintf(uri
, "ipp://localhost/jobs/%d", job_id
);
722 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
,
723 "job-uri", NULL
, uri
);
725 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
,
726 "requesting-user-name", NULL
, cupsUser());
728 cupsEncodeOptions(request
, num_options
, options
);
730 ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT
, request
, "/jobs"));
732 if (cupsLastError() > IPP_OK_CONFLICT
)
734 _cupsLangPrintf(stderr
, "%s: %s\n", command
, cupsLastErrorString());
743 * End of "$Id: lp.c 7170 2008-01-04 02:21:30Z mike $".