]> git.ipfire.org Git - thirdparty/cups.git/blame - berkeley/lpr.c
Update cups-lpd man page for "-o" option.
[thirdparty/cups.git] / berkeley / lpr.c
CommitLineData
bd0b97ff 1/*
a8131f99 2 * "$Id: lpr.c,v 1.19 2001/02/13 15:16:52 mike Exp $"
bd0b97ff 3 *
4 * "lpr" command for the Common UNIX Printing System (CUPS).
5 *
d2935a0f 6 * Copyright 1997-2001 by Easy Software Products.
bd0b97ff 7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
8dbf3e6a 26 * main() - Parse options and send files for printing.
27 * sighandler() - Signal catcher for when we print from stdin...
bd0b97ff 28 */
29
30/*
31 * Include necessary headers...
32 */
33
34#include <stdio.h>
35#include <stdlib.h>
1c9e0181 36
37#include <config.h>
bd0b97ff 38#include <cups/cups.h>
39
40
8dbf3e6a 41#ifndef WIN32
42# include <signal.h>
43
44
45/*
46 * Local functions.
47 */
48
977acbd3 49void sighandler(int);
8dbf3e6a 50#endif /* !WIN32 */
51
52
53/*
54 * Globals...
55 */
56
57char tempfile[1024]; /* Temporary file for printing from stdin */
58
59
bd0b97ff 60/*
61 * 'main()' - Parse options and send files for printing.
62 */
63
64int
65main(int argc, /* I - Number of command-line arguments */
66 char *argv[]) /* I - Command-line arguments */
67{
caa7d083 68 int i, j; /* Looping var */
bd0b97ff 69 int job_id; /* Job ID */
caa7d083 70 char *printer, /* Destination printer or class */
71 *instance; /* Instance */
bf56a667 72 const char *title; /* Job title */
bd0b97ff 73 int num_copies; /* Number of copies per file */
caa7d083 74 int num_files; /* Number of files to print */
75 const char *files[1000]; /* Files to print */
76 int num_dests; /* Number of destinations */
77 cups_dest_t *dests, /* Destinations */
78 *dest; /* Selected destination */
bd0b97ff 79 int num_options; /* Number of options */
80 cups_option_t *options; /* Options */
8a2c2126 81 int deletefile; /* Delete file after print? */
bd0b97ff 82 char buffer[8192]; /* Copy buffer */
1b5bf964 83 int temp; /* Temporary file descriptor */
977acbd3 84#ifdef HAVE_SIGACTION
85 struct sigaction action; /* Signal action */
86#endif /* HAVE_SIGACTION */
bd0b97ff 87
88
7dd958a9 89 deletefile = 0;
caa7d083 90 printer = NULL;
91 num_dests = 0;
92 dests = NULL;
bd0b97ff 93 num_options = 0;
94 options = NULL;
95 num_files = 0;
96 title = NULL;
97
98 for (i = 1; i < argc; i ++)
99 if (argv[i][0] == '-')
100 switch (argv[i][1])
101 {
1c9e0181 102 case 'E' : /* Encrypt */
103#ifdef HAVE_LIBSSL
104 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
105#else
106 fprintf(stderr, "%s: Sorry, no encryption support compiled in!\n",
107 argv[0]);
108#endif /* HAVE_LIBSSL */
109 break;
110
a8131f99 111 case '1' : /* TROFF font set 1 */
112 case '2' : /* TROFF font set 2 */
113 case '3' : /* TROFF font set 3 */
114 case '4' : /* TROFF font set 4 */
bd0b97ff 115 case 'i' : /* indent */
116 case 'w' : /* width */
117 if (argv[i][2] == '\0')
118 i ++;
119 case 'c' : /* CIFPLOT */
120 case 'd' : /* DVI */
121 case 'f' : /* FORTRAN */
122 case 'g' : /* plot */
123 case 'n' : /* Ditroff */
124 case 't' : /* Troff */
125 case 'v' : /* Raster image */
126 fprintf(stderr, "Warning: \'%c\' format modifier not supported - output may not be correct!\n",
127 argv[i][1]);
128 break;
129
5b187d9c 130 case 'o' : /* Option */
131 if (argv[i][2] != '\0')
132 num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
133 else
134 {
135 i ++;
136 num_options = cupsParseOptions(argv[i], num_options, &options);
137 }
138 break;
139
bd0b97ff 140 case 'l' : /* Literal/raw */
20178dbb 141 num_options = cupsAddOption("raw", "", num_options, &options);
bd0b97ff 142 break;
143
144 case 'p' : /* Prettyprint */
20178dbb 145 num_options = cupsAddOption("prettyprint", "", num_options, &options);
bd0b97ff 146 break;
147
148 case 'h' : /* Suppress burst page */
20178dbb 149 num_options = cupsAddOption("job-sheets", "none", num_options, &options);
150 break;
151
bd0b97ff 152 case 's' : /* Don't use symlinks */
153 break;
154
7dd958a9 155 case 'm' : /* Mail on completion */
bd0b97ff 156 fputs("Warning: email notification is not supported!\n", stderr);
157 break;
158
7dd958a9 159 case 'r' : /* Remove file after printing */
160 deletefile = 1;
161 break;
162
bd0b97ff 163 case 'P' : /* Destination printer or class */
164 if (argv[i][2] != '\0')
caa7d083 165 printer = argv[i] + 2;
bd0b97ff 166 else
167 {
168 i ++;
caa7d083 169 printer = argv[i];
170 }
171
172 if ((instance = strrchr(printer, '/')) != NULL)
173 *instance++ = '\0';
174
175 if (num_dests == 0)
176 num_dests = cupsGetDests(&dests);
177
178 if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL)
179 {
180 for (j = 0; j < dest->num_options; j ++)
e8973392 181 if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
182 num_options = cupsAddOption(dest->options[j].name,
183 dest->options[j].value,
184 num_options, &options);
bd0b97ff 185 }
186 break;
187
188 case '#' : /* Number of copies */
189 if (argv[i][2] != '\0')
190 num_copies = atoi(argv[i] + 2);
191 else
192 {
193 i ++;
194 num_copies = atoi(argv[i]);
195 }
196
197 if (num_copies < 1 || num_copies > 100)
198 {
199 fputs("lpr: Number copies must be between 1 and 100.\n", stderr);
200 return (1);
201 }
202
203 sprintf(buffer, "%d", num_copies);
204 num_options = cupsAddOption("copies", buffer, num_options, &options);
205 break;
206
207 case 'C' : /* Class */
208 case 'J' : /* Job name */
209 case 'T' : /* Title */
210 if (argv[i][2] != '\0')
211 title = argv[i] + 2;
212 else
213 {
214 i ++;
215 title = argv[i];
216 }
217 break;
218
219 default :
220 fprintf(stderr, "lpr: Unknown option \'%c\'!\n", argv[i][1]);
221 return (1);
222 }
caa7d083 223 else if (num_files < 1000)
bd0b97ff 224 {
225 /*
226 * Print a file...
227 */
228
caa7d083 229 files[num_files] = argv[i];
bd0b97ff 230 num_files ++;
bd0b97ff 231
caa7d083 232 if (title == NULL)
233 {
234 if ((title = strrchr(argv[i], '/')) != NULL)
235 title ++;
bd0b97ff 236 else
caa7d083 237 title = argv[i];
bd0b97ff 238 }
caa7d083 239 }
240 else
241 fprintf(stderr, "lpr: Too many files - \"%s\"\n", argv[i]);
242 /*
243 * See if we have any files to print; if not, print from stdin...
244 */
245
246 if (printer == NULL)
247 {
248 if (num_dests == 0)
249 num_dests = cupsGetDests(&dests);
bd0b97ff 250
caa7d083 251 for (j = 0, dest = dests; j < num_dests; j ++, dest ++)
252 if (dest->is_default)
bd0b97ff 253 {
caa7d083 254 printer = dests[j].name;
255
256 for (j = 0; j < dest->num_options; j ++)
e8973392 257 if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
258 num_options = cupsAddOption(dest->options[j].name,
259 dest->options[j].value,
260 num_options, &options);
caa7d083 261 break;
bd0b97ff 262 }
caa7d083 263 }
bd0b97ff 264
caa7d083 265 if (printer == NULL)
266 {
267 fputs("lpr: error - no default destination available.\n", stderr);
268 return (1);
269 }
bd0b97ff 270
caa7d083 271 if (num_files > 0)
bd0b97ff 272 {
caa7d083 273 job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options);
274
275 if (deletefile)
bd0b97ff 276 {
caa7d083 277 /*
278 * Delete print files after printing...
279 */
280
281 for (i = 0; i < num_files; i ++)
282 unlink(files[i]);
bd0b97ff 283 }
caa7d083 284 }
285 else
286 {
287 num_files = 1;
bd0b97ff 288
8dbf3e6a 289#ifndef WIN32
977acbd3 290# if defined(HAVE_SIGSET)
291 sigset(SIGHUP, sighandler);
292 sigset(SIGINT, sighandler);
293 sigset(SIGTERM, sighandler);
294# elif defined(HAVE_SIGACTION)
295 memset(&action, 0, sizeof(action));
296 action.sa_handler = sighandler;
297
298 sigaction(SIGHUP, &action, NULL);
299 sigaction(SIGINT, &action, NULL);
300 sigaction(SIGTERM, &action, NULL);
301# else
302 signal(SIGHUP, sighandler);
303 signal(SIGINT, sighandler);
8dbf3e6a 304 signal(SIGTERM, sighandler);
977acbd3 305# endif
8dbf3e6a 306#endif /* !WIN32 */
307
1b5bf964 308 if ((temp = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
bd0b97ff 309 {
310 fputs("lpr: unable to create temporary file.\n", stderr);
311 return (1);
312 }
313
314 while ((i = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
1b5bf964 315 write(temp, buffer, i);
bd0b97ff 316
1b5bf964 317 i = lseek(temp, 0, SEEK_CUR);
318 close(temp);
bd0b97ff 319
320 if (i == 0)
321 {
caa7d083 322 fputs("lpr: stdin is empty, so no job has been sent.\n", stderr);
bd0b97ff 323 return (1);
324 }
325
326 if (title)
caa7d083 327 job_id = cupsPrintFile(printer, tempfile, title, num_options, options);
bd0b97ff 328 else
caa7d083 329 job_id = cupsPrintFile(printer, tempfile, "(stdin)", num_options, options);
bd0b97ff 330
68ea7095 331 unlink(tempfile);
caa7d083 332 }
68ea7095 333
caa7d083 334 if (job_id < 1)
335 {
336 fprintf(stderr, "lpr: unable to print file: %s\n",
337 ippErrorString(cupsLastError()));
338 return (1);
bd0b97ff 339 }
340
341 return (0);
342}
343
344
8dbf3e6a 345#ifndef WIN32
346/*
347 * 'sighandler()' - Signal catcher for when we print from stdin...
348 */
349
350void
977acbd3 351sighandler(int s) /* I - Signal number */
8dbf3e6a 352{
353 /*
354 * Remove the temporary file we're using to print from stdin...
355 */
356
357 unlink(tempfile);
977acbd3 358
359 /*
360 * Exit...
361 */
362
363 exit(s);
8dbf3e6a 364}
365#endif /* !WIN32 */
366
367
bd0b97ff 368/*
a8131f99 369 * End of "$Id: lpr.c,v 1.19 2001/02/13 15:16:52 mike Exp $".
bd0b97ff 370 */