#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <cups/string.h>
#include <cups/cups.h>
#include <cups/i18n.h>
#ifndef WIN32
# include <unistd.h>
# include <signal.h>
void sighandler(int);
#endif
char tempfile[1024];
int
main(int argc,
char *argv[])
{
int i, j;
int job_id;
char ch;
char *printer,
*instance;
const char *title,
*val;
int num_copies;
int num_files;
const char *files[1000];
int num_dests;
cups_dest_t *dests,
*dest;
int num_options;
cups_option_t *options;
int deletefile;
char buffer[8192];
ssize_t bytes;
off_t filesize;
int temp;
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action;
struct sigaction oldaction;
#endif
_cupsSetLocale(argv);
deletefile = 0;
printer = NULL;
num_dests = 0;
dests = NULL;
num_options = 0;
options = NULL;
num_files = 0;
title = NULL;
for (i = 1; i < argc; i ++)
if (argv[i][0] == '-')
switch (ch = argv[i][1])
{
case 'E' :
#ifdef HAVE_SSL
cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
#else
_cupsLangPrintf(stderr,
_("%s: Sorry, no encryption support compiled in!\n"),
argv[0]);
#endif
break;
case 'U' :
if (argv[i][2] != '\0')
cupsSetUser(argv[i] + 2);
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr,
_("%s: Error - expected username after "
"\'-U\' option!\n"),
argv[0]);
return (1);
}
cupsSetUser(argv[i]);
}
break;
case 'H' :
if (argv[i][2] != '\0')
cupsSetServer(argv[i] + 2);
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr,
_("%s: Error - expected hostname after "
"\'-H\' option!\n"),
argv[0]);
return (1);
}
else
cupsSetServer(argv[i]);
}
break;
case '1' :
case '2' :
case '3' :
case '4' :
case 'i' :
case 'w' :
if (argv[i][2] == '\0')
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr,
_("%s: Error - expected value after \'-%c\' "
"option!\n"), argv[0], ch);
return (1);
}
}
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!\n"),
argv[0], ch);
break;
case 'o' :
if (argv[i][2] != '\0')
num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr,
_("%s: error - expected option=value after "
"\'-o\' option!\n"),
argv[0]);
return (1);
}
num_options = cupsParseOptions(argv[i], num_options, &options);
}
break;
case 'l' :
num_options = cupsAddOption("raw", "", num_options, &options);
break;
case 'p' :
num_options = cupsAddOption("prettyprint", "", 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 (argv[i][2] != '\0')
printer = argv[i] + 2;
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr,
_("%s: Error - expected destination after "
"\'-P\' option!\n"),
argv[0]);
return (1);
}
printer = argv[i];
}
if ((instance = strrchr(printer, '/')) != NULL)
*instance++ = '\0';
if (num_dests == 0)
num_dests = cupsGetDests(&dests);
if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != 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);
}
break;
case '#' :
if (argv[i][2] != '\0')
num_copies = atoi(argv[i] + 2);
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr,
_("%s: Error - expected copy count after "
"\'-#\' option!\n"),
argv[0]);
return (1);
}
num_copies = atoi(argv[i]);
}
sprintf(buffer, "%d", num_copies);
num_options = cupsAddOption("copies", buffer, num_options, &options);
break;
case 'C' :
case 'J' :
case 'T' :
if (argv[i][2] != '\0')
title = argv[i] + 2;
else
{
i ++;
if (i >= argc)
{
_cupsLangPrintf(stderr,
_("%s: Error - expected name after \'-%c\' "
"option!\n"), argv[0], ch);
return (1);
}
title = argv[i];
}
break;
default :
_cupsLangPrintf(stderr,
_("%s: Error - unknown option \'%c\'!\n"),
argv[0], argv[i][1]);
return (1);
}
else if (num_files < 1000)
{
if (access(argv[i], R_OK) != 0)
{
_cupsLangPrintf(stderr,
_("%s: Error - unable to access \"%s\" - %s\n"),
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\"\n"),
argv[0], argv[i]);
if (printer == NULL)
{
if (num_dests == 0)
num_dests = cupsGetDests(&dests);
if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != 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);
}
}
if (printer == NULL)
{
val = NULL;
if ((printer = getenv("LPDEST")) == NULL)
{
if ((printer = getenv("PRINTER")) != NULL)
{
if (!strcmp(printer, "lp"))
printer = NULL;
else
val = "PRINTER";
}
}
else
val = "LPDEST";
if (printer && !cupsGetDest(printer, NULL, num_dests, dests))
_cupsLangPrintf(stderr,
_("%s: Error - %s environment variable names "
"non-existent destination \"%s\"!\n"),
argv[0], val, printer);
else if (cupsLastError() == IPP_NOT_FOUND)
_cupsLangPrintf(stderr,
_("%s: Error - no default destination available.\n"),
argv[0]);
else
_cupsLangPrintf(stderr,
_("%s: Error - scheduler not responding!\n"),
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
{
num_files = 1;
#ifndef WIN32
# if defined(HAVE_SIGSET)
sigset(SIGHUP, sighandler);
if (sigset(SIGINT, sighandler) == SIG_IGN)
sigset(SIGINT, SIG_IGN);
sigset(SIGTERM, sighandler);
# elif defined(HAVE_SIGACTION)
memset(&action, 0, sizeof(action));
action.sa_handler = sighandler;
sigaction(SIGHUP, &action, NULL);
sigaction(SIGINT, NULL, &oldaction);
if (oldaction.sa_handler != SIG_IGN)
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
# else
signal(SIGHUP, sighandler);
if (signal(SIGINT, sighandler) == SIG_IGN)
signal(SIGINT, SIG_IGN);
signal(SIGTERM, sighandler);
# endif
#endif
if ((temp = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
{
_cupsLangPrintf(stderr,
_("%s: Error - unable to create temporary file "
"\"%s\" - %s\n"),
argv[0], tempfile, strerror(errno));
return (1);
}
while ((bytes = read(0, buffer, sizeof(buffer))) > 0)
if (write(temp, buffer, bytes) < 0)
{
_cupsLangPrintf(stderr,
_("%s: Error - unable to write to temporary file "
"\"%s\" - %s\n"),
argv[0], tempfile, strerror(errno));
close(temp);
unlink(tempfile);
return (1);
}
filesize = lseek(temp, 0, SEEK_CUR);
close(temp);
if (filesize <= 0)
{
_cupsLangPrintf(stderr,
_("%s: Error - stdin is empty, so no job has been sent.\n"),
argv[0]);
unlink(tempfile);
return (1);
}
if (title)
job_id = cupsPrintFile(printer, tempfile, title, num_options, options);
else
job_id = cupsPrintFile(printer, tempfile, "(stdin)", num_options, options);
unlink(tempfile);
}
if (job_id < 1)
{
_cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString());
return (1);
}
return (0);
}
#ifndef WIN32
void
sighandler(int s)
{
unlink(tempfile);
exit(s);
}
#endif