in scheduler/cupsfilter.c [57:519]
static void add_printer_filter(const char *command, mime_t *mime,
mime_type_t *printer_type,
const char *filter);
static mime_type_t *add_printer_filters(const char *command,
mime_t *mime, const char *printer,
const char *ppdfile,
mime_type_t **prefilter_type);
static void check_cb(void *context, _cups_fc_result_t result,
const char *message);
static int compare_pids(mime_filter_t *a, mime_filter_t *b);
static char *escape_options(int num_options, cups_option_t *options);
static int exec_filter(const char *filter, char **argv,
char **envp, int infd, int outfd);
static int exec_filters(mime_type_t *srctype,
cups_array_t *filters, const char *infile,
const char *outfile, const char *ppdfile,
const char *printer, const char *user,
const char *title, int num_options,
cups_option_t *options);
static void get_job_file(const char *job);
static int open_pipe(int *fds);
static int read_cups_files_conf(const char *filename);
static void set_string(char **s, const char *val);
static void sighandler(int sig);
static void usage(const char *opt) _CUPS_NORETURN;
/*
* 'main()' - Main entry for the test program.
*/
int /* O - Exit status */
main(int argc, /* I - Number of command-line args */
char *argv[]) /* I - Command-line arguments */
{
int i, /* Looping vars */
list_filters = 0; /* Just list the filters? */
const char *command, /* Command name */
*opt, /* Current option */
*printer; /* Printer name */
mime_type_t *printer_type, /* Printer MIME type */
*prefilter_type; /* Printer prefilter MIME type */
char *srctype, /* Source type */
*dsttype, /* Destination type */
super[MIME_MAX_SUPER], /* Super-type name */
type[MIME_MAX_TYPE]; /* Type name */
int compression; /* Compression of file */
int cost; /* Cost of filters */
mime_t *mime; /* MIME database */
char mimedir[1024]; /* MIME directory */
char *infile, /* File to filter */
*outfile; /* File to create */
char cupsfilesconf[1024]; /* cups-files.conf file */
const char *server_root; /* CUPS_SERVERROOT environment variable */
mime_type_t *src, /* Source type */
*dst; /* Destination type */
cups_array_t *filters; /* Filters for the file */
int num_options; /* Number of options */
cups_option_t *options; /* Options */
const char *ppdfile; /* PPD file */
const char *title, /* Title string */
*user; /* Username */
int all_filters, /* Use all filters */
removeppd, /* Remove PPD file */
removeinfile; /* Remove input file */
int status; /* Execution status */
/*
* Setup defaults...
*/
if ((command = strrchr(argv[0], '/')) != NULL)
command ++;
else
command = argv[0];
printer = !strcmp(command, "convert") ? "tofile" : "cupsfilter";
mime = NULL;
srctype = NULL;
compression = 0;
dsttype = "application/pdf";
infile = NULL;
outfile = NULL;
num_options = 0;
options = NULL;
ppdfile = NULL;
title = NULL;
user = cupsUser();
all_filters = 0;
removeppd = 0;
removeinfile = 0;
if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
server_root = CUPS_SERVERROOT;
snprintf(cupsfilesconf, sizeof(cupsfilesconf), "%s/cups-files.conf", server_root);
/*
* Process command-line arguments...
*/
_cupsSetLocale(argv);
for (i = 1; i < argc; i ++)
{
if (argv[i][0] == '-')
{
if (!strcmp(argv[i], "--list-filters"))
{
list_filters = 1;
}
else if (!strcmp(argv[i], "--"))
{
i ++;
if (i < argc && !infile)
infile = argv[i];
else
usage(NULL);
}
else
{
for (opt = argv[i] + 1; *opt; opt ++)
{
switch (*opt)
{
case 'a' : /* Specify option... */
i ++;
if (i < argc)
num_options = cupsParseOptions(argv[i], num_options, &options);
else
usage(opt);
break;
case 'c' : /* Specify cups-files.conf file location... */
i ++;
if (i < argc)
{
if (!strcmp(command, "convert"))
num_options = cupsAddOption("copies", argv[i], num_options, &options);
else
strlcpy(cupsfilesconf, argv[i], sizeof(cupsfilesconf));
}
else
usage(opt);
break;
case 'd' : /* Specify the real printer name */
i ++;
if (i < argc)
printer = argv[i];
else
usage(opt);
break;
case 'D' : /* Delete input file after conversion */
removeinfile = 1;
break;
case 'e' : /* Use every filter from the PPD file */
all_filters = 1;
break;
case 'f' : /* Specify input file... */
i ++;
if (i < argc && !infile)
infile = argv[i];
else
usage(opt);
break;
case 'i' : /* Specify source MIME type... */
i ++;
if (i < argc)
{
if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2)
usage(opt);
srctype = argv[i];
}
else
usage(opt);
break;
case 'j' : /* Get job file or specify destination MIME type... */
if (strcmp(command, "convert"))
{
i ++;
if (i < argc)
{
get_job_file(argv[i]);
infile = TempFile;
}
else
usage(opt);
break;
}
case 'm' : /* Specify destination MIME type... */
i ++;
if (i < argc)
{
if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2)
usage(opt);
dsttype = argv[i];
}
else
usage(opt);
break;
case 'n' : /* Specify number of copies... */
i ++;
if (i < argc)
num_options = cupsAddOption("copies", argv[i], num_options, &options);
else
usage(opt);
break;
case 'o' : /* Specify option(s) or output filename */
i ++;
if (i < argc)
{
if (!strcmp(command, "convert"))
{
if (outfile)
usage(NULL);
else
outfile = argv[i];
}
else
num_options = cupsParseOptions(argv[i], num_options, &options);
}
else
usage(opt);
break;
case 'p' : /* Specify PPD file... */
case 'P' : /* Specify PPD file... */
i ++;
if (i < argc)
ppdfile = argv[i];
else
usage(opt);
break;
case 't' : /* Specify title... */
case 'J' : /* Specify title... */
i ++;
if (i < argc)
title = argv[i];
else
usage(opt);
break;
case 'u' : /* Delete PPD file after conversion */
removeppd = 1;
break;
case 'U' : /* Specify username... */
i ++;
if (i < argc)
user = argv[i];
else
usage(opt);
break;
default : /* Something we don't understand... */
usage(opt);
break;
}
}
}
}
else if (!infile)
{
if (strcmp(command, "convert"))
infile = argv[i];
else
usage(NULL);
}
else
{
_cupsLangPuts(stderr,
_("cupsfilter: Only one filename can be specified."));
usage(NULL);
}
}
if (!infile && !srctype)
usage(NULL);
if (!title)
{
if (!infile)
title = "(stdin)";
else if ((title = strrchr(infile, '/')) != NULL)
title ++;
else
title = infile;
}
/*
* Load the cups-files.conf file and create the MIME database...
*/
if (read_cups_files_conf(cupsfilesconf))
return (1);
snprintf(mimedir, sizeof(mimedir), "%s/mime", DataDir);
mime = mimeLoadTypes(NULL, mimedir);
mime = mimeLoadTypes(mime, ServerRoot);
mime = mimeLoadFilters(mime, mimedir, Path);
mime = mimeLoadFilters(mime, ServerRoot, Path);
if (!mime)
{
_cupsLangPrintf(stderr,
_("%s: Unable to read MIME database from \"%s\" or "
"\"%s\"."),
command, mimedir, ServerRoot);
return (1);
}
prefilter_type = NULL;
if (all_filters)
printer_type = add_printer_filters(command, mime, printer, ppdfile,
&prefilter_type);
else
printer_type = mimeType(mime, "application", "vnd.cups-postscript");
/*
* Get the source and destination types...
*/
if (srctype)
{
/* sscanf return value already checked above */
sscanf(srctype, "%15[^/]/%255s", super, type);
if ((src = mimeType(mime, super, type)) == NULL)
{
_cupsLangPrintf(stderr,
_("%s: Unknown source MIME type %s/%s."),
command, super, type);
return (1);
}
}
else if ((src = mimeFileType(mime, infile, infile, &compression)) == NULL)
{
_cupsLangPrintf(stderr,
_("%s: Unable to determine MIME type of \"%s\"."),
command, infile);
return (1);
}
/* sscanf return value already checked above */
sscanf(dsttype, "%15[^/]/%255s", super, type);
if (!_cups_strcasecmp(super, "printer"))
dst = printer_type;
else if ((dst = mimeType(mime, super, type)) == NULL)
{
_cupsLangPrintf(stderr,
_("%s: Unknown destination MIME type %s/%s."),
command, super, type);
return (1);
}
/*
* Figure out how to filter the file...
*/
if (src == dst)
{
/*
* Special case - no filtering needed...
*/
filters = cupsArrayNew(NULL, NULL);
cupsArrayAdd(filters, &GZIPFilter);
GZIPFilter.src = src;
GZIPFilter.dst = dst;
}
else if ((filters = mimeFilter(mime, src, dst, &cost)) == NULL)
{
_cupsLangPrintf(stderr,
_("%s: No filter to convert from %s/%s to %s/%s."),
command, src->super, src->type, dst->super, dst->type);
return (1);
}
else if (compression)
cupsArrayInsert(filters, &GZIPFilter);
if (prefilter_type)
{
/*
* Add pre-filters...
*/
mime_filter_t *filter, /* Current filter */
*prefilter; /* Current pre-filter */
cups_array_t *prefilters = cupsArrayNew(NULL, NULL);
/* New filters array */
for (filter = (mime_filter_t *)cupsArrayFirst(filters);
filter;
filter = (mime_filter_t *)cupsArrayNext(filters))
{
if ((prefilter = mimeFilterLookup(mime, filter->src,
prefilter_type)) != NULL)
cupsArrayAdd(prefilters, prefilter);
cupsArrayAdd(prefilters, filter);
}
cupsArrayDelete(filters);
filters = prefilters;
}
if (list_filters)
{
/*
* List filters...
*/
mime_filter_t *filter; /* Current filter */
for (filter = (mime_filter_t *)cupsArrayFirst(filters);
filter;
filter = (mime_filter_t *)cupsArrayNext(filters))
if (strcmp(filter->filter, "-"))
_cupsLangPuts(stdout, filter->filter);
status = 0;
}
else
{
/*
* Run filters...
*/
status = exec_filters(src, filters, infile, outfile, ppdfile, printer, user,
title, num_options, options);
}
/*
* Remove files as needed, then exit...
*/
if (TempFile[0])
unlink(TempFile);
if (removeppd && ppdfile)
unlink(ppdfile);
if (removeinfile && infile)
unlink(infile);
return (status);
}