]>
git.ipfire.org Git - thirdparty/cups.git/blob - berkeley/lpr.c
dc92fd882c025742f2938b8ca066af32715fea2f
4 * "lpr" command for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2006 by Easy Software Products.
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
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * main() - Parse options and send files for printing.
27 * sighandler() - Signal catcher for when we print from stdin...
31 * Include necessary headers...
38 #include <cups/string.h>
39 #include <cups/cups.h>
40 #include <cups/i18n.h>
59 char tempfile
[1024]; /* Temporary file for printing from stdin */
63 * 'main()' - Parse options and send files for printing.
67 main(int argc
, /* I - Number of command-line arguments */
68 char *argv
[]) /* I - Command-line arguments */
70 int i
, j
; /* Looping var */
71 int job_id
; /* Job ID */
72 char ch
; /* Option character */
73 char *printer
, /* Destination printer or class */
74 *instance
; /* Instance */
75 const char *title
, /* Job title */
76 *val
; /* Environment variable name */
77 int num_copies
; /* Number of copies per file */
78 int num_files
; /* Number of files to print */
79 const char *files
[1000]; /* Files to print */
80 int num_dests
; /* Number of destinations */
81 cups_dest_t
*dests
, /* Destinations */
82 *dest
; /* Selected destination */
83 int num_options
; /* Number of options */
84 cups_option_t
*options
; /* Options */
85 int deletefile
; /* Delete file after print? */
86 char buffer
[8192]; /* Copy buffer */
87 ssize_t bytes
; /* Bytes copied */
88 off_t filesize
; /* Size of temp file */
89 int temp
; /* Temporary file descriptor */
90 cups_lang_t
*language
; /* Language information */
91 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
92 struct sigaction action
; /* Signal action */
93 struct sigaction oldaction
; /* Old signal action */
94 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
105 language
= cupsLangDefault();
107 for (i
= 1; i
< argc
; i
++)
108 if (argv
[i
][0] == '-')
109 switch (ch
= argv
[i
][1])
111 case 'E' : /* Encrypt */
113 cupsSetEncryption(HTTP_ENCRYPT_REQUIRED
);
115 _cupsLangPrintf(stderr
,
116 _("%s: Sorry, no encryption support compiled in!\n"),
118 #endif /* HAVE_SSL */
121 case 'U' : /* Username */
122 if (argv
[i
][2] != '\0')
123 cupsSetUser(argv
[i
] + 2);
129 _cupsLangPrintf(stderr
,
130 _("%s: Error - expected username after "
136 cupsSetUser(argv
[i
]);
140 case 'H' : /* Connect to host */
141 if (argv
[i
][2] != '\0')
142 cupsSetServer(argv
[i
] + 2);
149 _cupsLangPrintf(stderr
,
150 _("%s: Error - expected hostname after "
156 cupsSetServer(argv
[i
]);
160 case '1' : /* TROFF font set 1 */
161 case '2' : /* TROFF font set 2 */
162 case '3' : /* TROFF font set 3 */
163 case '4' : /* TROFF font set 4 */
164 case 'i' : /* indent */
165 case 'w' : /* width */
166 if (argv
[i
][2] == '\0')
172 _cupsLangPrintf(stderr
,
173 _("%s: Error - expected value after \'-%c\' "
174 "option!\n"), argv
[0], ch
);
179 case 'c' : /* CIFPLOT */
181 case 'f' : /* FORTRAN */
182 case 'g' : /* plot */
183 case 'n' : /* Ditroff */
184 case 't' : /* Troff */
185 case 'v' : /* Raster image */
186 _cupsLangPrintf(stderr
,
187 _("%s: Warning - \'%c\' format modifier not "
188 "supported - output may not be correct!\n"),
192 case 'o' : /* Option */
193 if (argv
[i
][2] != '\0')
194 num_options
= cupsParseOptions(argv
[i
] + 2, num_options
, &options
);
200 _cupsLangPrintf(stderr
,
201 _("%s: error - expected option=value after "
207 num_options
= cupsParseOptions(argv
[i
], num_options
, &options
);
211 case 'l' : /* Literal/raw */
212 num_options
= cupsAddOption("raw", "", num_options
, &options
);
215 case 'p' : /* Prettyprint */
216 num_options
= cupsAddOption("prettyprint", "", num_options
,
220 case 'h' : /* Suppress burst page */
221 num_options
= cupsAddOption("job-sheets", "none", num_options
,
225 case 's' : /* Don't use symlinks */
228 case 'm' : /* Mail on completion */
230 char email
[1024]; /* EMail address */
233 snprintf(email
, sizeof(email
), "mailto:%s@%s", cupsUser(),
234 httpGetHostname(NULL
, buffer
, sizeof(buffer
)));
235 num_options
= cupsAddOption("notify-recipient", email
,
236 num_options
, &options
);
240 case 'q' : /* Queue file but don't print */
241 num_options
= cupsAddOption("job-hold-until", "indefinite",
242 num_options
, &options
);
245 case 'r' : /* Remove file after printing */
249 case 'P' : /* Destination printer or class */
250 if (argv
[i
][2] != '\0')
251 printer
= argv
[i
] + 2;
257 _cupsLangPrintf(stderr
,
258 _("%s: Error - expected destination after "
267 if ((instance
= strrchr(printer
, '/')) != NULL
)
271 num_dests
= cupsGetDests(&dests
);
273 if ((dest
= cupsGetDest(printer
, instance
, num_dests
, dests
)) != NULL
)
275 for (j
= 0; j
< dest
->num_options
; j
++)
276 if (cupsGetOption(dest
->options
[j
].name
, num_options
,
278 num_options
= cupsAddOption(dest
->options
[j
].name
,
279 dest
->options
[j
].value
,
280 num_options
, &options
);
284 case '#' : /* Number of copies */
285 if (argv
[i
][2] != '\0')
286 num_copies
= atoi(argv
[i
] + 2);
292 _cupsLangPrintf(stderr
,
293 _("%s: Error - expected copy count after "
299 num_copies
= atoi(argv
[i
]);
302 sprintf(buffer
, "%d", num_copies
);
303 num_options
= cupsAddOption("copies", buffer
, num_options
, &options
);
306 case 'C' : /* Class */
307 case 'J' : /* Job name */
308 case 'T' : /* Title */
309 if (argv
[i
][2] != '\0')
316 _cupsLangPrintf(stderr
,
317 _("%s: Error - expected name after \'-%c\' "
318 "option!\n"), argv
[0], ch
);
327 _cupsLangPrintf(stderr
,
328 _("%s: Error - unknown option \'%c\'!\n"),
329 argv
[0], argv
[i
][1]);
332 else if (num_files
< 1000)
338 if (access(argv
[i
], R_OK
) != 0)
340 _cupsLangPrintf(stderr
,
341 _("%s: Error - unable to access \"%s\" - %s\n"),
342 argv
[0], argv
[i
], strerror(errno
));
346 files
[num_files
] = argv
[i
];
351 if ((title
= strrchr(argv
[i
], '/')) != NULL
)
358 _cupsLangPrintf(stderr
,
359 _("%s: Error - too many files - \"%s\"\n"),
362 * See if we have any files to print; if not, print from stdin...
368 num_dests
= cupsGetDests(&dests
);
370 if ((dest
= cupsGetDest(NULL
, NULL
, num_dests
, dests
)) != NULL
)
372 printer
= dest
->name
;
374 for (j
= 0; j
< dest
->num_options
; j
++)
375 if (cupsGetOption(dest
->options
[j
].name
, num_options
, options
) == NULL
)
376 num_options
= cupsAddOption(dest
->options
[j
].name
,
377 dest
->options
[j
].value
,
378 num_options
, &options
);
386 if ((printer
= getenv("LPDEST")) == NULL
)
388 if ((printer
= getenv("PRINTER")) != NULL
)
390 if (!strcmp(printer
, "lp"))
399 if (printer
&& !cupsGetDest(printer
, NULL
, num_dests
, dests
))
400 _cupsLangPrintf(stderr
,
401 _("%s: Error - %s environment variable names "
402 "non-existent destination \"%s\"!\n"),
403 argv
[0], val
, printer
);
404 else if (cupsLastError() == IPP_NOT_FOUND
)
405 _cupsLangPrintf(stderr
,
406 _("%s: Error - no default destination available.\n"),
409 _cupsLangPrintf(stderr
,
410 _("%s: Error - scheduler not responding!\n"),
418 job_id
= cupsPrintFiles(printer
, num_files
, files
, title
, num_options
, options
);
420 if (deletefile
&& job_id
> 0)
423 * Delete print files after printing...
426 for (i
= 0; i
< num_files
; i
++)
435 # if defined(HAVE_SIGSET)
436 sigset(SIGHUP
, sighandler
);
437 if (sigset(SIGINT
, sighandler
) == SIG_IGN
)
438 sigset(SIGINT
, SIG_IGN
);
439 sigset(SIGTERM
, sighandler
);
440 # elif defined(HAVE_SIGACTION)
441 memset(&action
, 0, sizeof(action
));
442 action
.sa_handler
= sighandler
;
444 sigaction(SIGHUP
, &action
, NULL
);
445 sigaction(SIGINT
, NULL
, &oldaction
);
446 if (oldaction
.sa_handler
!= SIG_IGN
)
447 sigaction(SIGINT
, &action
, NULL
);
448 sigaction(SIGTERM
, &action
, NULL
);
450 signal(SIGHUP
, sighandler
);
451 if (signal(SIGINT
, sighandler
) == SIG_IGN
)
452 signal(SIGINT
, SIG_IGN
);
453 signal(SIGTERM
, sighandler
);
457 if ((temp
= cupsTempFd(tempfile
, sizeof(tempfile
))) < 0)
459 _cupsLangPrintf(stderr
,
460 _("%s: Error - unable to create temporary file "
462 argv
[0], tempfile
, strerror(errno
));
466 while ((bytes
= read(0, buffer
, sizeof(buffer
))) > 0)
467 if (write(temp
, buffer
, bytes
) < 0)
469 _cupsLangPrintf(stderr
,
470 _("%s: Error - unable to write to temporary file "
472 argv
[0], tempfile
, strerror(errno
));
478 filesize
= lseek(temp
, 0, SEEK_CUR
);
483 _cupsLangPrintf(stderr
,
484 _("%s: Error - stdin is empty, so no job has been sent.\n"),
491 job_id
= cupsPrintFile(printer
, tempfile
, title
, num_options
, options
);
493 job_id
= cupsPrintFile(printer
, tempfile
, "(stdin)", num_options
, options
);
500 _cupsLangPrintf(stderr
, "%s: %s\n", argv
[0], cupsLastErrorString());
510 * 'sighandler()' - Signal catcher for when we print from stdin...
514 sighandler(int s
) /* I - Signal number */
517 * Remove the temporary file we're using to print from stdin...