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