1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * "lpr" command for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2007 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups-private.h>
16*5e7646d2SAndroid Build Coastguard Worker
17*5e7646d2SAndroid Build Coastguard Worker
18*5e7646d2SAndroid Build Coastguard Worker /*
19*5e7646d2SAndroid Build Coastguard Worker * Local functions...
20*5e7646d2SAndroid Build Coastguard Worker */
21*5e7646d2SAndroid Build Coastguard Worker
22*5e7646d2SAndroid Build Coastguard Worker static void usage(void) _CUPS_NORETURN;
23*5e7646d2SAndroid Build Coastguard Worker
24*5e7646d2SAndroid Build Coastguard Worker
25*5e7646d2SAndroid Build Coastguard Worker /*
26*5e7646d2SAndroid Build Coastguard Worker * 'main()' - Parse options and send files for printing.
27*5e7646d2SAndroid Build Coastguard Worker */
28*5e7646d2SAndroid Build Coastguard Worker
29*5e7646d2SAndroid Build Coastguard Worker int
main(int argc,char * argv[])30*5e7646d2SAndroid Build Coastguard Worker main(int argc, /* I - Number of command-line arguments */
31*5e7646d2SAndroid Build Coastguard Worker char *argv[]) /* I - Command-line arguments */
32*5e7646d2SAndroid Build Coastguard Worker {
33*5e7646d2SAndroid Build Coastguard Worker int i, j; /* Looping var */
34*5e7646d2SAndroid Build Coastguard Worker int job_id; /* Job ID */
35*5e7646d2SAndroid Build Coastguard Worker char ch; /* Option character */
36*5e7646d2SAndroid Build Coastguard Worker char *printer, /* Destination printer or class */
37*5e7646d2SAndroid Build Coastguard Worker *instance, /* Instance */
38*5e7646d2SAndroid Build Coastguard Worker *opt; /* Option pointer */
39*5e7646d2SAndroid Build Coastguard Worker const char *title; /* Job title */
40*5e7646d2SAndroid Build Coastguard Worker int num_copies; /* Number of copies per file */
41*5e7646d2SAndroid Build Coastguard Worker int num_files; /* Number of files to print */
42*5e7646d2SAndroid Build Coastguard Worker const char *files[1000]; /* Files to print */
43*5e7646d2SAndroid Build Coastguard Worker cups_dest_t *dest; /* Selected destination */
44*5e7646d2SAndroid Build Coastguard Worker int num_options; /* Number of options */
45*5e7646d2SAndroid Build Coastguard Worker cups_option_t *options; /* Options */
46*5e7646d2SAndroid Build Coastguard Worker int deletefile; /* Delete file after print? */
47*5e7646d2SAndroid Build Coastguard Worker char buffer[8192]; /* Copy buffer */
48*5e7646d2SAndroid Build Coastguard Worker
49*5e7646d2SAndroid Build Coastguard Worker
50*5e7646d2SAndroid Build Coastguard Worker _cupsSetLocale(argv);
51*5e7646d2SAndroid Build Coastguard Worker
52*5e7646d2SAndroid Build Coastguard Worker deletefile = 0;
53*5e7646d2SAndroid Build Coastguard Worker printer = NULL;
54*5e7646d2SAndroid Build Coastguard Worker dest = NULL;
55*5e7646d2SAndroid Build Coastguard Worker num_options = 0;
56*5e7646d2SAndroid Build Coastguard Worker options = NULL;
57*5e7646d2SAndroid Build Coastguard Worker num_files = 0;
58*5e7646d2SAndroid Build Coastguard Worker title = NULL;
59*5e7646d2SAndroid Build Coastguard Worker
60*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i < argc; i ++)
61*5e7646d2SAndroid Build Coastguard Worker {
62*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(argv[i], "--help"))
63*5e7646d2SAndroid Build Coastguard Worker usage();
64*5e7646d2SAndroid Build Coastguard Worker else if (argv[i][0] == '-')
65*5e7646d2SAndroid Build Coastguard Worker {
66*5e7646d2SAndroid Build Coastguard Worker for (opt = argv[i] + 1; *opt; opt ++)
67*5e7646d2SAndroid Build Coastguard Worker {
68*5e7646d2SAndroid Build Coastguard Worker switch (ch = *opt)
69*5e7646d2SAndroid Build Coastguard Worker {
70*5e7646d2SAndroid Build Coastguard Worker case 'E' : /* Encrypt */
71*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SSL
72*5e7646d2SAndroid Build Coastguard Worker cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
73*5e7646d2SAndroid Build Coastguard Worker #else
74*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
75*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SSL */
76*5e7646d2SAndroid Build Coastguard Worker break;
77*5e7646d2SAndroid Build Coastguard Worker
78*5e7646d2SAndroid Build Coastguard Worker case 'U' : /* Username */
79*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
80*5e7646d2SAndroid Build Coastguard Worker {
81*5e7646d2SAndroid Build Coastguard Worker cupsSetUser(opt + 1);
82*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
83*5e7646d2SAndroid Build Coastguard Worker }
84*5e7646d2SAndroid Build Coastguard Worker else
85*5e7646d2SAndroid Build Coastguard Worker {
86*5e7646d2SAndroid Build Coastguard Worker i ++;
87*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
88*5e7646d2SAndroid Build Coastguard Worker {
89*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - expected username after \"-U\" option."), argv[0]);
90*5e7646d2SAndroid Build Coastguard Worker usage();
91*5e7646d2SAndroid Build Coastguard Worker }
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker cupsSetUser(argv[i]);
94*5e7646d2SAndroid Build Coastguard Worker }
95*5e7646d2SAndroid Build Coastguard Worker break;
96*5e7646d2SAndroid Build Coastguard Worker
97*5e7646d2SAndroid Build Coastguard Worker case 'H' : /* Connect to host */
98*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
99*5e7646d2SAndroid Build Coastguard Worker {
100*5e7646d2SAndroid Build Coastguard Worker cupsSetServer(opt + 1);
101*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
102*5e7646d2SAndroid Build Coastguard Worker }
103*5e7646d2SAndroid Build Coastguard Worker else
104*5e7646d2SAndroid Build Coastguard Worker {
105*5e7646d2SAndroid Build Coastguard Worker i ++;
106*5e7646d2SAndroid Build Coastguard Worker
107*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
108*5e7646d2SAndroid Build Coastguard Worker {
109*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - expected hostname after \"-H\" option."), argv[0]);
110*5e7646d2SAndroid Build Coastguard Worker usage();
111*5e7646d2SAndroid Build Coastguard Worker }
112*5e7646d2SAndroid Build Coastguard Worker else
113*5e7646d2SAndroid Build Coastguard Worker cupsSetServer(argv[i]);
114*5e7646d2SAndroid Build Coastguard Worker }
115*5e7646d2SAndroid Build Coastguard Worker break;
116*5e7646d2SAndroid Build Coastguard Worker
117*5e7646d2SAndroid Build Coastguard Worker case '1' : /* TROFF font set 1 */
118*5e7646d2SAndroid Build Coastguard Worker case '2' : /* TROFF font set 2 */
119*5e7646d2SAndroid Build Coastguard Worker case '3' : /* TROFF font set 3 */
120*5e7646d2SAndroid Build Coastguard Worker case '4' : /* TROFF font set 4 */
121*5e7646d2SAndroid Build Coastguard Worker case 'i' : /* indent */
122*5e7646d2SAndroid Build Coastguard Worker case 'w' : /* width */
123*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
124*5e7646d2SAndroid Build Coastguard Worker {
125*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
126*5e7646d2SAndroid Build Coastguard Worker }
127*5e7646d2SAndroid Build Coastguard Worker else
128*5e7646d2SAndroid Build Coastguard Worker {
129*5e7646d2SAndroid Build Coastguard Worker i ++;
130*5e7646d2SAndroid Build Coastguard Worker
131*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
132*5e7646d2SAndroid Build Coastguard Worker {
133*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
134*5e7646d2SAndroid Build Coastguard Worker _("%s: Error - expected value after \"-%c\" "
135*5e7646d2SAndroid Build Coastguard Worker "option."), argv[0], ch);
136*5e7646d2SAndroid Build Coastguard Worker usage();
137*5e7646d2SAndroid Build Coastguard Worker }
138*5e7646d2SAndroid Build Coastguard Worker }
139*5e7646d2SAndroid Build Coastguard Worker
140*5e7646d2SAndroid Build Coastguard Worker case 'c' : /* CIFPLOT */
141*5e7646d2SAndroid Build Coastguard Worker case 'd' : /* DVI */
142*5e7646d2SAndroid Build Coastguard Worker case 'f' : /* FORTRAN */
143*5e7646d2SAndroid Build Coastguard Worker case 'g' : /* plot */
144*5e7646d2SAndroid Build Coastguard Worker case 'n' : /* Ditroff */
145*5e7646d2SAndroid Build Coastguard Worker case 't' : /* Troff */
146*5e7646d2SAndroid Build Coastguard Worker case 'v' : /* Raster image */
147*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Warning - \"%c\" format modifier not supported - output may not be correct."), argv[0], ch);
148*5e7646d2SAndroid Build Coastguard Worker break;
149*5e7646d2SAndroid Build Coastguard Worker
150*5e7646d2SAndroid Build Coastguard Worker case 'o' : /* Option */
151*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
152*5e7646d2SAndroid Build Coastguard Worker {
153*5e7646d2SAndroid Build Coastguard Worker num_options = cupsParseOptions(opt + 1, num_options, &options);
154*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
155*5e7646d2SAndroid Build Coastguard Worker }
156*5e7646d2SAndroid Build Coastguard Worker else
157*5e7646d2SAndroid Build Coastguard Worker {
158*5e7646d2SAndroid Build Coastguard Worker i ++;
159*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
160*5e7646d2SAndroid Build Coastguard Worker {
161*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - expected option=value after \"-o\" option."), argv[0]);
162*5e7646d2SAndroid Build Coastguard Worker usage();
163*5e7646d2SAndroid Build Coastguard Worker }
164*5e7646d2SAndroid Build Coastguard Worker
165*5e7646d2SAndroid Build Coastguard Worker num_options = cupsParseOptions(argv[i], num_options, &options);
166*5e7646d2SAndroid Build Coastguard Worker }
167*5e7646d2SAndroid Build Coastguard Worker break;
168*5e7646d2SAndroid Build Coastguard Worker
169*5e7646d2SAndroid Build Coastguard Worker case 'l' : /* Literal/raw */
170*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption("raw", "true", num_options, &options);
171*5e7646d2SAndroid Build Coastguard Worker break;
172*5e7646d2SAndroid Build Coastguard Worker
173*5e7646d2SAndroid Build Coastguard Worker case 'p' : /* Prettyprint */
174*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption("prettyprint", "true", num_options, &options);
175*5e7646d2SAndroid Build Coastguard Worker break;
176*5e7646d2SAndroid Build Coastguard Worker
177*5e7646d2SAndroid Build Coastguard Worker case 'h' : /* Suppress burst page */
178*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption("job-sheets", "none", num_options, &options);
179*5e7646d2SAndroid Build Coastguard Worker break;
180*5e7646d2SAndroid Build Coastguard Worker
181*5e7646d2SAndroid Build Coastguard Worker case 's' : /* Don't use symlinks */
182*5e7646d2SAndroid Build Coastguard Worker break;
183*5e7646d2SAndroid Build Coastguard Worker
184*5e7646d2SAndroid Build Coastguard Worker case 'm' : /* Mail on completion */
185*5e7646d2SAndroid Build Coastguard Worker {
186*5e7646d2SAndroid Build Coastguard Worker char email[1024]; /* EMail address */
187*5e7646d2SAndroid Build Coastguard Worker
188*5e7646d2SAndroid Build Coastguard Worker snprintf(email, sizeof(email), "mailto:%s@%s", cupsUser(), httpGetHostname(NULL, buffer, sizeof(buffer)));
189*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption("notify-recipient-uri", email, num_options, &options);
190*5e7646d2SAndroid Build Coastguard Worker }
191*5e7646d2SAndroid Build Coastguard Worker break;
192*5e7646d2SAndroid Build Coastguard Worker
193*5e7646d2SAndroid Build Coastguard Worker case 'q' : /* Queue file but don't print */
194*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption("job-hold-until", "indefinite", num_options, &options);
195*5e7646d2SAndroid Build Coastguard Worker break;
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker case 'r' : /* Remove file after printing */
198*5e7646d2SAndroid Build Coastguard Worker deletefile = 1;
199*5e7646d2SAndroid Build Coastguard Worker break;
200*5e7646d2SAndroid Build Coastguard Worker
201*5e7646d2SAndroid Build Coastguard Worker case 'P' : /* Destination printer or class */
202*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
203*5e7646d2SAndroid Build Coastguard Worker {
204*5e7646d2SAndroid Build Coastguard Worker printer = opt + 1;
205*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
206*5e7646d2SAndroid Build Coastguard Worker }
207*5e7646d2SAndroid Build Coastguard Worker else
208*5e7646d2SAndroid Build Coastguard Worker {
209*5e7646d2SAndroid Build Coastguard Worker i ++;
210*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
211*5e7646d2SAndroid Build Coastguard Worker {
212*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - expected destination after \"-P\" option."), argv[0]);
213*5e7646d2SAndroid Build Coastguard Worker usage();
214*5e7646d2SAndroid Build Coastguard Worker }
215*5e7646d2SAndroid Build Coastguard Worker
216*5e7646d2SAndroid Build Coastguard Worker printer = argv[i];
217*5e7646d2SAndroid Build Coastguard Worker }
218*5e7646d2SAndroid Build Coastguard Worker
219*5e7646d2SAndroid Build Coastguard Worker if ((instance = strrchr(printer, '/')) != NULL)
220*5e7646d2SAndroid Build Coastguard Worker *instance++ = '\0';
221*5e7646d2SAndroid Build Coastguard Worker
222*5e7646d2SAndroid Build Coastguard Worker if ((dest = cupsGetNamedDest(NULL, printer, instance)) != NULL)
223*5e7646d2SAndroid Build Coastguard Worker {
224*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < dest->num_options; j ++)
225*5e7646d2SAndroid Build Coastguard Worker if (cupsGetOption(dest->options[j].name, num_options,
226*5e7646d2SAndroid Build Coastguard Worker options) == NULL)
227*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(dest->options[j].name,
228*5e7646d2SAndroid Build Coastguard Worker dest->options[j].value,
229*5e7646d2SAndroid Build Coastguard Worker num_options, &options);
230*5e7646d2SAndroid Build Coastguard Worker }
231*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
232*5e7646d2SAndroid Build Coastguard Worker cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
233*5e7646d2SAndroid Build Coastguard Worker {
234*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - add '/version=1.1' to server name."), argv[0]);
235*5e7646d2SAndroid Build Coastguard Worker return (1);
236*5e7646d2SAndroid Build Coastguard Worker }
237*5e7646d2SAndroid Build Coastguard Worker break;
238*5e7646d2SAndroid Build Coastguard Worker
239*5e7646d2SAndroid Build Coastguard Worker case '#' : /* Number of copies */
240*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
241*5e7646d2SAndroid Build Coastguard Worker {
242*5e7646d2SAndroid Build Coastguard Worker num_copies = atoi(opt + 1);
243*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
244*5e7646d2SAndroid Build Coastguard Worker }
245*5e7646d2SAndroid Build Coastguard Worker else
246*5e7646d2SAndroid Build Coastguard Worker {
247*5e7646d2SAndroid Build Coastguard Worker i ++;
248*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
249*5e7646d2SAndroid Build Coastguard Worker {
250*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - expected copies after \"-#\" option."), argv[0]);
251*5e7646d2SAndroid Build Coastguard Worker usage();
252*5e7646d2SAndroid Build Coastguard Worker }
253*5e7646d2SAndroid Build Coastguard Worker
254*5e7646d2SAndroid Build Coastguard Worker num_copies = atoi(argv[i]);
255*5e7646d2SAndroid Build Coastguard Worker }
256*5e7646d2SAndroid Build Coastguard Worker
257*5e7646d2SAndroid Build Coastguard Worker if (num_copies < 1)
258*5e7646d2SAndroid Build Coastguard Worker {
259*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - copies must be 1 or more."), argv[0]);
260*5e7646d2SAndroid Build Coastguard Worker return (1);
261*5e7646d2SAndroid Build Coastguard Worker }
262*5e7646d2SAndroid Build Coastguard Worker
263*5e7646d2SAndroid Build Coastguard Worker sprintf(buffer, "%d", num_copies);
264*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption("copies", buffer, num_options, &options);
265*5e7646d2SAndroid Build Coastguard Worker break;
266*5e7646d2SAndroid Build Coastguard Worker
267*5e7646d2SAndroid Build Coastguard Worker case 'C' : /* Class */
268*5e7646d2SAndroid Build Coastguard Worker case 'J' : /* Job name */
269*5e7646d2SAndroid Build Coastguard Worker case 'T' : /* Title */
270*5e7646d2SAndroid Build Coastguard Worker if (opt[1] != '\0')
271*5e7646d2SAndroid Build Coastguard Worker {
272*5e7646d2SAndroid Build Coastguard Worker title = opt + 1;
273*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
274*5e7646d2SAndroid Build Coastguard Worker }
275*5e7646d2SAndroid Build Coastguard Worker else
276*5e7646d2SAndroid Build Coastguard Worker {
277*5e7646d2SAndroid Build Coastguard Worker i ++;
278*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
279*5e7646d2SAndroid Build Coastguard Worker {
280*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - expected name after \"-%c\" option."), argv[0], ch);
281*5e7646d2SAndroid Build Coastguard Worker usage();
282*5e7646d2SAndroid Build Coastguard Worker }
283*5e7646d2SAndroid Build Coastguard Worker
284*5e7646d2SAndroid Build Coastguard Worker title = argv[i];
285*5e7646d2SAndroid Build Coastguard Worker }
286*5e7646d2SAndroid Build Coastguard Worker break;
287*5e7646d2SAndroid Build Coastguard Worker
288*5e7646d2SAndroid Build Coastguard Worker default :
289*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - unknown option \"%c\"."), argv[0], *opt);
290*5e7646d2SAndroid Build Coastguard Worker return (1);
291*5e7646d2SAndroid Build Coastguard Worker }
292*5e7646d2SAndroid Build Coastguard Worker }
293*5e7646d2SAndroid Build Coastguard Worker }
294*5e7646d2SAndroid Build Coastguard Worker else if (num_files < 1000)
295*5e7646d2SAndroid Build Coastguard Worker {
296*5e7646d2SAndroid Build Coastguard Worker /*
297*5e7646d2SAndroid Build Coastguard Worker * Print a file...
298*5e7646d2SAndroid Build Coastguard Worker */
299*5e7646d2SAndroid Build Coastguard Worker
300*5e7646d2SAndroid Build Coastguard Worker if (access(argv[i], R_OK) != 0)
301*5e7646d2SAndroid Build Coastguard Worker {
302*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
303*5e7646d2SAndroid Build Coastguard Worker _("%s: Error - unable to access \"%s\" - %s"),
304*5e7646d2SAndroid Build Coastguard Worker argv[0], argv[i], strerror(errno));
305*5e7646d2SAndroid Build Coastguard Worker return (1);
306*5e7646d2SAndroid Build Coastguard Worker }
307*5e7646d2SAndroid Build Coastguard Worker
308*5e7646d2SAndroid Build Coastguard Worker files[num_files] = argv[i];
309*5e7646d2SAndroid Build Coastguard Worker num_files ++;
310*5e7646d2SAndroid Build Coastguard Worker
311*5e7646d2SAndroid Build Coastguard Worker if (title == NULL)
312*5e7646d2SAndroid Build Coastguard Worker {
313*5e7646d2SAndroid Build Coastguard Worker if ((title = strrchr(argv[i], '/')) != NULL)
314*5e7646d2SAndroid Build Coastguard Worker title ++;
315*5e7646d2SAndroid Build Coastguard Worker else
316*5e7646d2SAndroid Build Coastguard Worker title = argv[i];
317*5e7646d2SAndroid Build Coastguard Worker }
318*5e7646d2SAndroid Build Coastguard Worker }
319*5e7646d2SAndroid Build Coastguard Worker else
320*5e7646d2SAndroid Build Coastguard Worker {
321*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - too many files - \"%s\"."), argv[0], argv[i]);
322*5e7646d2SAndroid Build Coastguard Worker }
323*5e7646d2SAndroid Build Coastguard Worker }
324*5e7646d2SAndroid Build Coastguard Worker
325*5e7646d2SAndroid Build Coastguard Worker /*
326*5e7646d2SAndroid Build Coastguard Worker * See if we have any files to print; if not, print from stdin...
327*5e7646d2SAndroid Build Coastguard Worker */
328*5e7646d2SAndroid Build Coastguard Worker
329*5e7646d2SAndroid Build Coastguard Worker if (printer == NULL)
330*5e7646d2SAndroid Build Coastguard Worker {
331*5e7646d2SAndroid Build Coastguard Worker if ((dest = cupsGetNamedDest(NULL, NULL, NULL)) != NULL)
332*5e7646d2SAndroid Build Coastguard Worker {
333*5e7646d2SAndroid Build Coastguard Worker printer = dest->name;
334*5e7646d2SAndroid Build Coastguard Worker
335*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < dest->num_options; j ++)
336*5e7646d2SAndroid Build Coastguard Worker if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
337*5e7646d2SAndroid Build Coastguard Worker num_options = cupsAddOption(dest->options[j].name,
338*5e7646d2SAndroid Build Coastguard Worker dest->options[j].value,
339*5e7646d2SAndroid Build Coastguard Worker num_options, &options);
340*5e7646d2SAndroid Build Coastguard Worker }
341*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
342*5e7646d2SAndroid Build Coastguard Worker cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
343*5e7646d2SAndroid Build Coastguard Worker {
344*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
345*5e7646d2SAndroid Build Coastguard Worker _("%s: Error - add '/version=1.1' to server "
346*5e7646d2SAndroid Build Coastguard Worker "name."), argv[0]);
347*5e7646d2SAndroid Build Coastguard Worker return (1);
348*5e7646d2SAndroid Build Coastguard Worker }
349*5e7646d2SAndroid Build Coastguard Worker }
350*5e7646d2SAndroid Build Coastguard Worker
351*5e7646d2SAndroid Build Coastguard Worker if (printer == NULL)
352*5e7646d2SAndroid Build Coastguard Worker {
353*5e7646d2SAndroid Build Coastguard Worker if (!cupsGetNamedDest(NULL, NULL, NULL) && cupsLastError() == IPP_STATUS_ERROR_NOT_FOUND)
354*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - %s"), argv[0], cupsLastErrorString());
355*5e7646d2SAndroid Build Coastguard Worker else
356*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - scheduler not responding."), argv[0]);
357*5e7646d2SAndroid Build Coastguard Worker
358*5e7646d2SAndroid Build Coastguard Worker return (1);
359*5e7646d2SAndroid Build Coastguard Worker }
360*5e7646d2SAndroid Build Coastguard Worker
361*5e7646d2SAndroid Build Coastguard Worker if (num_files > 0)
362*5e7646d2SAndroid Build Coastguard Worker {
363*5e7646d2SAndroid Build Coastguard Worker job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options);
364*5e7646d2SAndroid Build Coastguard Worker
365*5e7646d2SAndroid Build Coastguard Worker if (deletefile && job_id > 0)
366*5e7646d2SAndroid Build Coastguard Worker {
367*5e7646d2SAndroid Build Coastguard Worker /*
368*5e7646d2SAndroid Build Coastguard Worker * Delete print files after printing...
369*5e7646d2SAndroid Build Coastguard Worker */
370*5e7646d2SAndroid Build Coastguard Worker
371*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_files; i ++)
372*5e7646d2SAndroid Build Coastguard Worker unlink(files[i]);
373*5e7646d2SAndroid Build Coastguard Worker }
374*5e7646d2SAndroid Build Coastguard Worker }
375*5e7646d2SAndroid Build Coastguard Worker else if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer,
376*5e7646d2SAndroid Build Coastguard Worker title ? title : "(stdin)",
377*5e7646d2SAndroid Build Coastguard Worker num_options, options)) > 0)
378*5e7646d2SAndroid Build Coastguard Worker {
379*5e7646d2SAndroid Build Coastguard Worker http_status_t status; /* Write status */
380*5e7646d2SAndroid Build Coastguard Worker const char *format; /* Document format */
381*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Bytes read */
382*5e7646d2SAndroid Build Coastguard Worker
383*5e7646d2SAndroid Build Coastguard Worker if (cupsGetOption("raw", num_options, options))
384*5e7646d2SAndroid Build Coastguard Worker format = CUPS_FORMAT_RAW;
385*5e7646d2SAndroid Build Coastguard Worker else if ((format = cupsGetOption("document-format", num_options,
386*5e7646d2SAndroid Build Coastguard Worker options)) == NULL)
387*5e7646d2SAndroid Build Coastguard Worker format = CUPS_FORMAT_AUTO;
388*5e7646d2SAndroid Build Coastguard Worker
389*5e7646d2SAndroid Build Coastguard Worker status = cupsStartDocument(CUPS_HTTP_DEFAULT, printer, job_id, NULL,
390*5e7646d2SAndroid Build Coastguard Worker format, 1);
391*5e7646d2SAndroid Build Coastguard Worker
392*5e7646d2SAndroid Build Coastguard Worker while (status == HTTP_CONTINUE &&
393*5e7646d2SAndroid Build Coastguard Worker (bytes = read(0, buffer, sizeof(buffer))) > 0)
394*5e7646d2SAndroid Build Coastguard Worker status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, (size_t)bytes);
395*5e7646d2SAndroid Build Coastguard Worker
396*5e7646d2SAndroid Build Coastguard Worker if (status != HTTP_CONTINUE)
397*5e7646d2SAndroid Build Coastguard Worker {
398*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("%s: Error - unable to queue from stdin - %s."),
399*5e7646d2SAndroid Build Coastguard Worker argv[0], httpStatus(status));
400*5e7646d2SAndroid Build Coastguard Worker cupsFinishDocument(CUPS_HTTP_DEFAULT, printer);
401*5e7646d2SAndroid Build Coastguard Worker cupsCancelJob2(CUPS_HTTP_DEFAULT, printer, job_id, 0);
402*5e7646d2SAndroid Build Coastguard Worker return (1);
403*5e7646d2SAndroid Build Coastguard Worker }
404*5e7646d2SAndroid Build Coastguard Worker
405*5e7646d2SAndroid Build Coastguard Worker if (cupsFinishDocument(CUPS_HTTP_DEFAULT, printer) != IPP_OK)
406*5e7646d2SAndroid Build Coastguard Worker {
407*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, "%s: %s", argv[0], cupsLastErrorString());
408*5e7646d2SAndroid Build Coastguard Worker cupsCancelJob2(CUPS_HTTP_DEFAULT, printer, job_id, 0);
409*5e7646d2SAndroid Build Coastguard Worker return (1);
410*5e7646d2SAndroid Build Coastguard Worker }
411*5e7646d2SAndroid Build Coastguard Worker }
412*5e7646d2SAndroid Build Coastguard Worker
413*5e7646d2SAndroid Build Coastguard Worker if (job_id < 1)
414*5e7646d2SAndroid Build Coastguard Worker {
415*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, "%s: %s", argv[0], cupsLastErrorString());
416*5e7646d2SAndroid Build Coastguard Worker return (1);
417*5e7646d2SAndroid Build Coastguard Worker }
418*5e7646d2SAndroid Build Coastguard Worker
419*5e7646d2SAndroid Build Coastguard Worker return (0);
420*5e7646d2SAndroid Build Coastguard Worker }
421*5e7646d2SAndroid Build Coastguard Worker
422*5e7646d2SAndroid Build Coastguard Worker
423*5e7646d2SAndroid Build Coastguard Worker /*
424*5e7646d2SAndroid Build Coastguard Worker * 'usage()' - Show program usage and exit.
425*5e7646d2SAndroid Build Coastguard Worker */
426*5e7646d2SAndroid Build Coastguard Worker
427*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)428*5e7646d2SAndroid Build Coastguard Worker usage(void)
429*5e7646d2SAndroid Build Coastguard Worker {
430*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("Usage: lpr [options] [file(s)]"));
431*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("Options:"));
432*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-# num-copies Specify the number of copies to print"));
433*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-E Encrypt the connection to the server"));
434*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-H server[:port] Connect to the named server and port"));
435*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-m Send an email notification when the job completes"));
436*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-o option[=value] Specify a printer-specific option"));
437*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-o job-sheets=standard Print a banner page with the job"));
438*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-o media=size Specify the media size to use"));
439*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-o number-up=N Specify that input pages should be printed N-up (1, 2, 4, 6, 9, and 16 are supported)"));
440*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-o orientation-requested=N\n"
441*5e7646d2SAndroid Build Coastguard Worker " Specify portrait (3) or landscape (4) orientation"));
442*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-o print-quality=N Specify the print quality - draft (3), normal (4), or best (5)"));
443*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-o sides=one-sided Specify 1-sided printing"));
444*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-o sides=two-sided-long-edge\n"
445*5e7646d2SAndroid Build Coastguard Worker " Specify 2-sided portrait printing"));
446*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-o sides=two-sided-short-edge\n"
447*5e7646d2SAndroid Build Coastguard Worker " Specify 2-sided landscape printing"));
448*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-P destination Specify the destination"));
449*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-q Specify the job should be held for printing"));
450*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-r Remove the file(s) after submission"));
451*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-T title Specify the job title"));
452*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("-U username Specify the username to use for authentication"));
453*5e7646d2SAndroid Build Coastguard Worker
454*5e7646d2SAndroid Build Coastguard Worker exit(1);
455*5e7646d2SAndroid Build Coastguard Worker }
456