Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"cupsfilter" command should also support the printer driver filter specified in the PPD #2562

Closed
michaelrsweet opened this issue Oct 17, 2007 · 2 comments
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

@michaelrsweet michaelrsweet commented Oct 17, 2007

Version: 1.4-feature
CUPS.org User: till.kamppeter

The new "cupsfilter" utility seems to be a nice tool to develop and debug filter processes for CUPS, but one thing can be made better in it:

I want to run this command for debugging the filter process of a fax driver for an HP multi-function device doing a call like ("-m" option intentionally left out):

cupsfilter -p /etc/cups/ppd/HP_LaserJet_3390_fax.ppd ~/printers.txt

The PPD file is the one which HP provides with HPLIP. It contains a cupsFilter line:

*cupsFilter: "application/vnd.cups-postscript 0 foomatic-rip"

This means that the input file has to be converted to application/vnd.cups-postscript and then to be fed into the CUPS filter foomatic-rip.

So I would like that with above command line the following filters get called

texttops -> pstops -> foomatic-rip

with the environment variable PPD set to /etc/cups/ppd/HP_LaserJet_3390_fax.ppd

resulting in a Fax file for my HP as output.

Unfortunately, running the filter specified by the PPD file is not supported by the current version of the tool so that I get


till@till-laptop:~/ubuntu/cups-pdf/cups-pdf-2.4.6$ cupsfilter -p /etc/cups/ppd/HP_LaserJet_3390_fax.ppd ~/printers.txt
cupsfilter: No filter to convert from text/plain to application/pdf!

till@till-laptop:~/ubuntu/cups-pdf/cups-pdf-2.4.6$

which is not very useful.

I appreciate if support for the filter specified in the PPD file (printer driver) gets added.

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Sep 11, 2008

CUPS.org User: mike

Fixed in Subversion repository.

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Sep 11, 2008

"str2562.patch":

Index: man/cupsfilter.man

--- man/cupsfilter.man (revision 7934)
+++ man/cupsfilter.man (working copy)
@@ -3,7 +3,7 @@
."
." cupsfilter man page for the Common UNIX Printing System (CUPS).
."
-." Copyright 2007 by Apple Inc.
+." Copyright 2007-2008 by Apple Inc.
."
." These coded instructions, statements, and computer programs are the
." property of Apple Inc. and are protected by Federal copyright
@@ -11,7 +11,7 @@
." which should have been included with this file. If this file is
." file is missing or damaged, see the license at "http://www.cups.org/".
."
-.TH cupsfilter 8 "Common UNIX Printing System" "19 October 2007" "Apple Inc."
+.TH cupsfilter 8 "Common UNIX Printing System" "10 September 2008" "Apple Inc."
.SH NAME
cupsfilter - convert a file to another format using cups filters
.SH SYNOPSIS
@@ -50,6 +50,8 @@
-m mime/type
.br
Specifies the destination file type. The default file type is application/pdf.
+Use printer/foo to convert to the printer format defined by the filters in the
+PPD file.
.TP 5
-n copies
.br
@@ -74,7 +76,7 @@
.br
http://localhost:631/help
.SH COPYRIGHT
-Copyright 2007 by Apple Inc.
+Copyright 2007-2008 by Apple Inc.
."
." End of "$Id$".
."

Index: scheduler/cupsfilter.c

--- scheduler/cupsfilter.c (revision 7934)
+++ scheduler/cupsfilter.c (working copy)
@@ -75,21 +75,28 @@

  • 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 @@
    {
    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 @@
    else
    command = argv[0];

  • printer = !strcmp(command, "convert") ? "tofile" : "cupsfilter";
    mime = NULL;
    srctype = NULL;
    compression = 0;
    @@ -369,6 +380,8 @@
    return (1);
    }

  • add_printer_filters(command, mime, printer, ppdfile, &prefilter_type);

/*

  • Get the source and destination types...
    */
    @@ -393,7 +406,9 @@
    }

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 +439,38 @@
    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 +490,131 @@

    /*

  • * '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...
    */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant