#include <cups/cups-private.h>
static void usage(void) _CUPS_NORETURN;
int
main(int argc,
char *argv[])
{
int i, j;
int job_id;
char ch;
char *printer,
*instance,
*opt;
const char *title;
int num_copies;
int num_files;
const char *files[1000];
cups_dest_t *dest;
int num_options;
cups_option_t *options;
int deletefile;
char buffer[8192];
_cupsSetLocale(argv);
deletefile = 0;
printer = NULL;
dest = NULL;
num_options = 0;
options = NULL;
num_files = 0;
title = NULL;
for (i = 1; i < argc; i ++)
{
if (!strcmp(argv[i], "--help"))
usage();
else if (argv[i][0] == '-')
{
for (opt = argv[i] + 1; *opt; opt ++)
{
switch (ch = *opt)
{
case 'E' :
#ifdef HAVE_TLS
cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
#else
_cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
#endif
break;
case 'U' :
if (opt[1] != '\0')
{
cupsSetUser(opt + 1);
opt += strlen(opt) - 1;
}
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr, _("%s: Error - expected username after \"-U\" option."), argv[0]);
usage();
}
cupsSetUser(argv[i]);
}
break;
case 'H' :
if (opt[1] != '\0')
{
cupsSetServer(opt + 1);
opt += strlen(opt) - 1;
}
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr, _("%s: Error - expected hostname after \"-H\" option."), argv[0]);
usage();
}
else
cupsSetServer(argv[i]);
}
break;
case '1' :
case '2' :
case '3' :
case '4' :
case 'i' :
case 'w' :
if (opt[1] != '\0')
{
opt += strlen(opt) - 1;
}
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr,
_("%s: Error - expected value after \"-%c\" "
"option."), argv[0], ch);
usage();
}
}
case 'c' :
case 'd' :
case 'f' :
case 'g' :
case 'n' :
case 't' :
case 'v' :
_cupsLangPrintf(stderr, _("%s: Warning - \"%c\" format modifier not supported - output may not be correct."), argv[0], ch);
break;
case 'o' :
if (opt[1] != '\0')
{
num_options = cupsParseOptions(opt + 1, num_options, &options);
opt += strlen(opt) - 1;
}
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr, _("%s: Error - expected option=value after \"-o\" option."), argv[0]);
usage();
}
num_options = cupsParseOptions(argv[i], num_options, &options);
}
break;
case 'l' :
num_options = cupsAddOption("raw", "true", num_options, &options);
break;
case 'p' :
num_options = cupsAddOption("prettyprint", "true", num_options, &options);
break;
case 'h' :
num_options = cupsAddOption("job-sheets", "none", num_options, &options);
break;
case 's' :
break;
case 'm' :
{
char email[1024];
snprintf(email, sizeof(email), "mailto:%s@%s", cupsUser(), httpGetHostname(NULL, buffer, sizeof(buffer)));
num_options = cupsAddOption("notify-recipient-uri", email, num_options, &options);
}
break;
case 'q' :
num_options = cupsAddOption("job-hold-until", "indefinite", num_options, &options);
break;
case 'r' :
deletefile = 1;
break;
case 'P' :
if (opt[1] != '\0')
{
printer = opt + 1;
opt += strlen(opt) - 1;
}
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr, _("%s: Error - expected destination after \"-P\" option."), argv[0]);
usage();
}
printer = argv[i];
}
if ((instance = strrchr(printer, '/')) != NULL)
*instance++ = '\0';
if ((dest = cupsGetNamedDest(NULL, printer, instance)) != NULL)
{
for (j = 0; j < dest->num_options; j ++)
if (cupsGetOption(dest->options[j].name, num_options,
options) == NULL)
num_options = cupsAddOption(dest->options[j].name,
dest->options[j].value,
num_options, &options);
}
else if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
{
_cupsLangPrintf(stderr, _("%s: Error - add '/version=1.1' to server name."), argv[0]);
return (1);
}
else if (cupsLastError() == IPP_STATUS_ERROR_NOT_FOUND)
{
_cupsLangPrintf(stderr,
_("%s: Error - The printer or class does not exist."), argv[0]);
return (1);
}
break;
case '#' :
if (opt[1] != '\0')
{
num_copies = atoi(opt + 1);
opt += strlen(opt) - 1;
}
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr, _("%s: Error - expected copies after \"-#\" option."), argv[0]);
usage();
}
num_copies = atoi(argv[i]);
}
if (num_copies < 1)
{
_cupsLangPrintf(stderr, _("%s: Error - copies must be 1 or more."), argv[0]);
return (1);
}
num_options = cupsAddIntegerOption("copies", num_copies, num_options, &options);
break;
case 'C' :
case 'J' :
case 'T' :
if (opt[1] != '\0')
{
title = opt + 1;
opt += strlen(opt) - 1;
}
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr, _("%s: Error - expected name after \"-%c\" option."), argv[0], ch);
usage();
}
title = argv[i];
}
break;
default :
_cupsLangPrintf(stderr, _("%s: Error - unknown option \"%c\"."), argv[0], *opt);
return (1);
}
}
}
else if (num_files < 1000)
{
if (access(argv[i], R_OK) != 0)
{
_cupsLangPrintf(stderr,
_("%s: Error - unable to access \"%s\" - %s"),
argv[0], argv[i], strerror(errno));
return (1);
}
files[num_files] = argv[i];
num_files ++;
if (title == NULL)
{
if ((title = strrchr(argv[i], '/')) != NULL)
title ++;
else
title = argv[i];
}
}
else
{
_cupsLangPrintf(stderr, _("%s: Error - too many files - \"%s\"."), argv[0], argv[i]);
}
}
if (printer == NULL)
{
if ((dest = cupsGetNamedDest(NULL, NULL, NULL)) != NULL)
{
printer = dest->name;
for (j = 0; j < dest->num_options; j ++)
if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
num_options = cupsAddOption(dest->options[j].name,
dest->options[j].value,
num_options, &options);
}
else if (cupsLastError() == IPP_STATUS_ERROR_BAD_REQUEST ||
cupsLastError() == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED)
{
_cupsLangPrintf(stderr,
_("%s: Error - add '/version=1.1' to server "
"name."), argv[0]);
return (1);
}
}
if (printer == NULL)
{
if (!cupsGetNamedDest(NULL, NULL, NULL) && cupsLastError() == IPP_STATUS_ERROR_NOT_FOUND)
_cupsLangPrintf(stderr, _("%s: Error - %s"), argv[0], cupsLastErrorString());
else
_cupsLangPrintf(stderr, _("%s: Error - scheduler not responding."), argv[0]);
return (1);
}
if (num_files > 0)
{
job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options);
if (deletefile && job_id > 0)
{
for (i = 0; i < num_files; i ++)
unlink(files[i]);
}
}
else if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer,
title ? title : "(stdin)",
num_options, options)) > 0)
{
http_status_t status;
const char *format;
ssize_t bytes;
if (cupsGetOption("raw", num_options, options))
format = CUPS_FORMAT_RAW;
else if ((format = cupsGetOption("document-format", num_options,
options)) == NULL)
format = CUPS_FORMAT_AUTO;
status = cupsStartDocument(CUPS_HTTP_DEFAULT, printer, job_id, NULL,
format, 1);
while (status == HTTP_CONTINUE &&
(bytes = read(0, buffer, sizeof(buffer))) > 0)
status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, (size_t)bytes);
if (status != HTTP_CONTINUE)
{
_cupsLangPrintf(stderr, _("%s: Error - unable to queue from stdin - %s."),
argv[0], httpStatus(status));
cupsFinishDocument(CUPS_HTTP_DEFAULT, printer);
cupsCancelJob2(CUPS_HTTP_DEFAULT, printer, job_id, 0);
return (1);
}
if (cupsFinishDocument(CUPS_HTTP_DEFAULT, printer) != IPP_OK)
{
_cupsLangPrintf(stderr, "%s: %s", argv[0], cupsLastErrorString());
cupsCancelJob2(CUPS_HTTP_DEFAULT, printer, job_id, 0);
return (1);
}
}
if (job_id < 1)
{
_cupsLangPrintf(stderr, "%s: %s", argv[0], cupsLastErrorString());
return (1);
}
return (0);
}
static void
usage(void)
{
_cupsLangPuts(stdout, _("Usage: lpr [options] [file(s)]"));
_cupsLangPuts(stdout, _("Options:"));
_cupsLangPuts(stdout, _("-# num-copies Specify the number of copies to print"));
_cupsLangPuts(stdout, _("-E Encrypt the connection to the server"));
_cupsLangPuts(stdout, _("-H server[:port] Connect to the named server and port"));
_cupsLangPuts(stdout, _("-m Send an email notification when the job completes"));
_cupsLangPuts(stdout, _("-o option[=value] Specify a printer-specific option"));
_cupsLangPuts(stdout, _("-o job-sheets=standard Print a banner page with the job"));
_cupsLangPuts(stdout, _("-o media=size Specify the media size to use"));
_cupsLangPuts(stdout, _("-o number-up=N Specify that input pages should be printed N-up (1, 2, 4, 6, 9, and 16 are supported)"));
_cupsLangPuts(stdout, _("-o orientation-requested=N\n"
" Specify portrait (3) or landscape (4) orientation"));
_cupsLangPuts(stdout, _("-o print-quality=N Specify the print quality - draft (3), normal (4), or best (5)"));
_cupsLangPuts(stdout, _("-o sides=one-sided Specify 1-sided printing"));
_cupsLangPuts(stdout, _("-o sides=two-sided-long-edge\n"
" Specify 2-sided portrait printing"));
_cupsLangPuts(stdout, _("-o sides=two-sided-short-edge\n"
" Specify 2-sided landscape printing"));
_cupsLangPuts(stdout, _("-P destination Specify the destination"));
_cupsLangPuts(stdout, _("-q Specify the job should be held for printing"));
_cupsLangPuts(stdout, _("-r Remove the file(s) after submission"));
_cupsLangPuts(stdout, _("-T title Specify the job title"));
_cupsLangPuts(stdout, _("-U username Specify the username to use for authentication"));
exit(1);
}