summaryrefslogtreecommitdiff
path: root/scheduler/cupsfilter.c
diff options
context:
space:
mode:
Diffstat (limited to 'scheduler/cupsfilter.c')
-rw-r--r--scheduler/cupsfilter.c210
1 files changed, 188 insertions, 22 deletions
diff --git a/scheduler/cupsfilter.c b/scheduler/cupsfilter.c
index d387ecf7c..6974e47c6 100644
--- a/scheduler/cupsfilter.c
+++ b/scheduler/cupsfilter.c
@@ -1,5 +1,5 @@
/*
- * "$Id: cupsfilter.c 7694 2008-06-26 00:23:20Z mike $"
+ * "$Id: cupsfilter.c 7952 2008-09-17 00:56:20Z mike $"
*
* CUPS filtering program for the Common UNIX Printing System (CUPS).
*
@@ -75,21 +75,28 @@ static char TempFile[1024] = "";
* Local functions...
*/
-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(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_cupsd_conf(const char *filename);
-static void set_string(char **s, const char *val);
-static void sighandler(int sig);
-static void usage(const char *command, const char *opt);
+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 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(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_cupsd_conf(const char *filename);
+static void set_string(char **s, const char *val);
+static void sighandler(int sig);
+static void usage(const char *command, const char *opt);
/*
@@ -102,7 +109,10 @@ main(int argc, /* I - Number of command-line args */
{
int i; /* Looping vars */
const char *command, /* Command name */
- *opt; /* Current option */
+ *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 */
@@ -137,6 +147,7 @@ main(int argc, /* I - Number of command-line args */
else
command = argv[0];
+ printer = !strcmp(command, "convert") ? "tofile" : "cupsfilter";
mime = NULL;
srctype = NULL;
compression = 0;
@@ -369,6 +380,9 @@ main(int argc, /* I - Number of command-line args */
return (1);
}
+ printer_type = add_printer_filters(command, mime, printer, ppdfile,
+ &prefilter_type);
+
/*
* Get the source and destination types...
*/
@@ -393,7 +407,9 @@ main(int argc, /* I - Number of command-line args */
}
sscanf(dsttype, "%15[^/]/%255s", super, type);
- if ((dst = mimeType(mime, super, type)) == NULL)
+ if (!strcasecmp(super, "printer"))
+ dst = printer_type;
+ else if ((dst = mimeType(mime, super, type)) == NULL)
{
_cupsLangPrintf(stderr,
_("%s: Unknown destination MIME type %s/%s!\n"),
@@ -424,13 +440,38 @@ main(int argc, /* I - Number of command-line args */
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)))
+ cupsArrayAdd(prefilters, prefilter);
+
+ cupsArrayAdd(prefilters, filter);
+ }
+
+ cupsArrayDelete(filters);
+ filters = prefilters;
+ }
+
/*
* Do it!
*/
- status = exec_filters(filters, infile, outfile, ppdfile,
- !strcmp(command, "convert") ? "tofile" : "cupsfilter",
- user, title, num_options, options);
+ status = exec_filters(filters, infile, outfile, ppdfile, printer, user,
+ title, num_options, options);
/*
* Remove files as needed, then exit...
@@ -450,6 +491,131 @@ main(int argc, /* I - Number of command-line args */
/*
+ * 'add_printer_filter()' - Add a single filters from a PPD file.
+ */
+
+static void
+add_printer_filter(
+ const char *command, /* I - Command name */
+ mime_t *mime, /* I - MIME database */
+ mime_type_t *filtertype, /* I - Printer or prefilter MIME type */
+ const char *filter) /* I - Filter to add */
+{
+ char super[MIME_MAX_SUPER], /* Super-type for filter */
+ type[MIME_MAX_TYPE], /* Type for filter */
+ program[1024]; /* Program/filter name */
+ int cost; /* Cost of filter */
+ mime_type_t *temptype; /* MIME type looping var */
+ char filename[1024]; /* Full filter filename */
+
+
+ /*
+ * Parse the filter string; it should be in the following format:
+ *
+ * super/type cost program
+ */
+
+ if (sscanf(filter, "%15[^/]/%31s%d%*[ \t]%1023[^\n]", super, type, &cost,
+ program) != 4)
+ {
+ _cupsLangPrintf(stderr, _("%s: Invalid filter string \"%s\"\n"), command,
+ filter);
+ return;
+ }
+
+ /*
+ * See if the filter program exists; if not, stop the printer and flag
+ * the error!
+ */
+
+ if (strcmp(program, "-"))
+ {
+ if (program[0] == '/')
+ strlcpy(filename, program, sizeof(filename));
+ else
+ snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin, program);
+
+ if (access(filename, X_OK))
+ {
+ _cupsLangPrintf(stderr, _("%s: Filter \"%s\" not available: %s\n"),
+ command, program, strerror(errno));
+ return;
+ }
+ }
+
+ /*
+ * Add the filter to the MIME database, supporting wildcards as needed...
+ */
+
+ for (temptype = mimeFirstType(mime);
+ temptype;
+ temptype = mimeNextType(mime))
+ if (((super[0] == '*' && strcasecmp(temptype->super, "printer")) ||
+ !strcasecmp(temptype->super, super)) &&
+ (type[0] == '*' || !strcasecmp(temptype->type, type)))
+ mimeAddFilter(mime, temptype, filtertype, cost, program);
+}
+
+
+/*
+ * 'add_printer_filters()' - Add filters from a PPD file.
+ */
+
+static mime_type_t * /* O - Printer type or NULL on error */
+add_printer_filters(
+ const char *command, /* I - Command name */
+ mime_t *mime, /* I - MIME database */
+ const char *printer, /* I - Printer name */
+ const char *ppdfile, /* I - PPD file */
+ mime_type_t **prefilter_type) /* O - Prefilter type */
+{
+ int i; /* Looping var */
+ mime_type_t *printer_type; /* Printer MIME type */
+ ppd_file_t *ppd; /* PPD file data */
+ ppd_attr_t *ppdattr; /* Current prefilter */
+
+
+ if ((ppd = ppdOpenFile(ppdfile)) == NULL)
+ {
+ ppd_status_t status; /* PPD load status */
+
+ status = ppdLastError(&i);
+ _cupsLangPrintf(stderr, _("%s: Unable to open PPD file: %s on line %d\n"),
+ command, ppdErrorString(status), i);
+ return (NULL);
+ }
+
+ printer_type = mimeAddType(mime, "printer", printer);
+
+ if (ppd->num_filters > 0)
+ {
+ for (i = 0; i < ppd->num_filters; i ++)
+ add_printer_filter(command, mime, printer_type, ppd->filters[i]);
+ }
+ else
+ {
+ add_printer_filter(command, mime, printer_type,
+ "application/vnd.cups-command 0 commandtops");
+ add_printer_filter(command, mime, printer_type,
+ "application/vnd.cups-postscript 0 -");
+ }
+
+ if ((ppdattr = ppdFindAttr(ppd, "cupsPreFilter", NULL)) != NULL)
+ {
+ *prefilter_type = mimeAddType(mime, "prefilter", printer);
+
+ for (; ppdattr; ppdattr = ppdFindNextAttr(ppd, "cupsPreFilter", NULL))
+ if (ppdattr->value)
+ add_printer_filter(command, mime, *prefilter_type, ppdattr->value);
+ }
+ else
+ *prefilter_type = NULL;
+
+ return (printer_type);
+}
+
+
+/*
* 'compare_pids()' - Compare two filter PIDs...
*/
@@ -1144,5 +1310,5 @@ usage(const char *command, /* I - Command name */
/*
- * End of "$Id: cupsfilter.c 7694 2008-06-26 00:23:20Z mike $".
+ * End of "$Id: cupsfilter.c 7952 2008-09-17 00:56:20Z mike $".
*/