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