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

Landscape PDF prints incorrectly with orientation-requested=4 #2881

Closed
michaelrsweet opened this issue Jul 18, 2008 · 22 comments
Closed

Landscape PDF prints incorrectly with orientation-requested=4 #2881

michaelrsweet opened this issue Jul 18, 2008 · 22 comments
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

@michaelrsweet michaelrsweet commented Jul 18, 2008

Version: 1.3-current
CUPS.org User: twaugh.redhat

The fix for STR #2850 is incorrect. The PDF file:
http://cups.org/strfiles/2850/landscape.pdf
still prints incorrectly when the option 'orientation-requested=4' is given, even when the patch http://cups.org/strfiles/2850/str2850.patch is applied.

Representation of original PDF:
+------+
|ABCDEF|
|ABCDEF|
+------+

I have scanned in the printed output resulting from this command:
lp -oorientation-requested=4 landscape.pdf

on two different printers:

  1. Epson Stylus D78, using a foomatic driver for gutenprint-ijs
    +------+
    | ABCD|
    | ABCD|
    +------+
  2. HP LaserJet 6MP, using the manufacturer's "HP LaserJet 6P/6MP - PostScript" PPD
    +----+
    |ABCD|
    |ABCD|
    | |
    +----+

Printing the file using 'lp landscape.pdf' works correctly -- the problem only occurs when the orientation-requested=4 option is given.

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Jul 18, 2008

CUPS.org User: h.blischke

May it be that both the pdftops and the pstops filter deal with that attribute and thus fight ageinst one another????

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Jul 18, 2008

CUPS.org User: mike

No, the change specifically forces pdftops to think the page size is rotated so that it won't apply its own rotation.

More than likely the setpagedevice call is causing the problem. Unfortunately, there is no easy way to disable it aside from modifying the PSOutputDevice class, which I'd like to avoid since we'll need the same fix for CUPS 1.4's pdftops...

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Nov 21, 2008

CUPS.org User: jgc

The fix put in for STR #2850 got us up and running again as soon as we updated from v1.3.7 to 1.3.8 - broke again with the 1.3.9 update, so we've had to revert. We have Mac OS X client machines printing to Kyocera FS-1030D printers, and to use twaugh's PDF representation:

+------+
|ABCDEF|
|ABCDEF|
+------+

Gives us this output:

+----+
| |
|CDEF|
|CDEF|
+----+

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Dec 2, 2008

CUPS.org User: jschwender

Is this the same thing?
https://bugs.launchpad.net/ubuntu/+source/cups/+bug/300312

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Dec 19, 2008

CUPS.org User: allianne

In a mixed environment, I have similar problems.

With cups 1.3.8, Windows users printing with cups+samba cannot print in duplex or use staple and punch features. However, Mac users can print landscape documents with 1.3.8.

With 1.3.9, cups+samba works properly, but OS X users cannot print landscape properly.

Additionally, with 1.3.9, it is the first page ONLY that prints rotated and cropped with OS 10.5 clients. Subsequent pages print properly landscaped.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Jan 14, 2009

CUPS.org User: torriem

Is there likely to be any movement on this bug? I get the impression the changes require a bit of reengineering which developers want to wait for 1.4 to do. Is this likely to be soon? We have a RHEL5 server with cups and none of our linux clients are affected by this, but all of our Mac users are affected when they print.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Feb 5, 2009

CUPS.org User: allianne

I can understand having other priorities, but this bug is a show-stopper for us. Can someone point me in the direction of a solution, or give an update on the status of this bug? Thanks in advance.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Feb 16, 2009

CUPS.org User: mike

All: at this point I am not sure what we'll be able to do with this; the PDF filter has always been largely third-party code, and the landscape handling (and specifically the auto-rotation code that is in Xpdf) has caused us grief for a while.

While we will continue looking for a solution, ultimately this will have to get fixed upstream in Xpdf and poppler.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Feb 20, 2009

CUPS.org User: mike

I'm currently looking at wrapping the local pdf-to-postscript filter and pstops so that we allow that filter to handle the auto-rotation of output and not pass landscape or orientation-requested to the pstops filter. That may fix things, but like all workarounds I don't know yet whether it will fix all things.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Feb 20, 2009

CUPS.org User: mike

Also, pushing this to CUPS 1.4, as the changes to run pstops will not be compatible with the CUPS 1.3 code.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Mar 12, 2009

CUPS.org User: mike

Back to CUPS 1.3, since we now have put the new pdftops in CUPS 1.3 as well (STR #3129)...

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Mar 19, 2009

CUPS.org User: torriem

No go. I just tried the new pdftops filter from the svn 1.3.x head. My system is RHEL 5.3 stock, and I assume the underlying transform filter is poppler. The new pdftops code from 1.3.x now does this for all my Macs and from any Linux machine where -o orientation-requested=4 is used:

+----+
| |
|CDEF|
|CDEF|
+----+

In other words the printout is not rotated and all I see is the lower right-hand part of the page.

Maybe this is progress. I dunno. Every fix I've tried over the last year and a half (various subversion versions of pdftops) has resulted in slightly different incorrect printouts.

Is this a poppler bug now? Is poppler guessing at the page orientation only to be (again) second-guessed by the pdftops filter in cups?

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Mar 19, 2009

CUPS.org User: twaugh.redhat

I'm not even sure if submitting a landscape orientation PDF and giving the orientation-requested=4 option is really supposed to work. It seems like asking the print server to rotate the document again, when that is not required.

Is this really a Mac OS X bug?

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Mar 19, 2009

CUPS.org User: torriem

Even more fun. I verified that I am indeed using poppler (I don't think RHEL 5.x by default uses poppler, but rather the older xpdf... I compiled it myself), and even tried the latest version 0.10. Still get the printout I described above.

I rebuild pdftops in cups-1.3.x without pdftops support, forcing it to use gs. This doesn't work either. With gs I get:

+----+
| |
|ABCD|
|ABCE|
+----+

This is very interesting indeed. I'm going to try to hack on the pdftops filter some more.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Mar 19, 2009

CUPS.org User: torriem

You could be right about this, Rick. I originally did open this bug with Apple and they of course said it was RH's fault.

Yes it does seem daft to have a rotated page already and then request landscape. That's definitely what OS X requests though. Very odd indeed. Sadly it's easier to get an open source project to change to accommodate bad behavior that it is to get Apple to fix this on their end. I wonder if OS X printing to another OS X-hosts queue has this problem.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Mar 19, 2009

CUPS.org User: mike

Current 1.3.x does not have the change in place yet, it just has the backported wrapper from trunk without the changes. The changes are coming...

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Mar 19, 2009

CUPS.org User: mike

Michael: This problem does not happen on Mac OS X since the cgpdftops filter does not rotate its output.

The problem is that Xpdf (and poppler) both rotate PDF's to portrait orientation, and then pstops also rotates the output to portrait orientation, resulting in double rotation.

The fix (that I'm still working on) is to run pstops from the wrapper program so that pdftops actually produces application/vnd.cups-postscript instead of application/postscript.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Mar 19, 2009

CUPS.org User: torriem

Okay. Thanks for the clarification. I did hack on pdftops and found that the code that checks the "orientation-requested" thing isn't even executing. Basically the if(size && fit) check is never true. Not sure if this is part that is yet to come or what.

Thanks for your work in this. Appreciate it very much.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented Mar 20, 2009

CUPS.org User: mike

Tim: No, it isn't a Mac OS X bug, but just a side-effect of how the various pdftops filters work - namely, they try to set the page size and do things that the pstops filter normally does.

Since we're trying to get away from hacking the Xpdf pdftops in the CUPS sources, I'm focusing on removing the orientation-requested and landscape options from the arguments passed to pstops.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented May 22, 2009

CUPS.org User: mike

Fixed in Subversion repository.

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented May 22, 2009

"str2881.patch":

Index: conf/mime.convs.in

--- conf/mime.convs.in (revision 8671)
+++ conf/mime.convs.in (working copy)
@@ -7,7 +7,7 @@

MIME converts file for the Common UNIX Printing System (CUPS).

-# Copyright 2007-2008 by Apple Inc.
+# Copyright 2007-2009 by Apple Inc.

Copyright 1997-2007 by Easy Software Products.

These coded instructions, statements, and computer programs are the

@@ -38,7 +38,7 @@

PostScript filters

-application/pdf application/postscript 33 pdftops
+application/pdf application/vnd.cups-postscript 66 pdftops
application/postscript application/vnd.cups-postscript 66 pstops
application/vnd.hp-HPGL application/postscript 66 hpgltops
application/x-cshell application/postscript 33 texttops

Index: filter/pdftops.c

--- filter/pdftops.c (revision 8671)
+++ filter/pdftops.c (working copy)
@@ -65,13 +65,23 @@
fit; /* Fit output to default page size? /
ppd_file_t *ppd; /
PPD file /
ppd_size_t *size; /
Current page size */

  • int pdfpid, /* Process ID for pdftops */
  •   pdfwaitpid,     /\* Process ID from wait() */
    
  •   pdfstatus,      /\* Status from pdftops */
    
  •   pdfargc;        /\* Number of args for pdftops */
    
  • char pdfargv[100], / Arguments for pdftops/gs */
  •   pdfwidth[255],      /\* Paper width */
    
  •   pdfheight[255];     /\* Paper height */
    
  • int pdf_pid, /* Process ID for pdftops */
  •   pdf_argc,       /\* Number of args for pdftops */
    
  •   pstops_pid,     /\* Process ID of pstops filter */
    
  •   pstops_pipe[2],     /\* Pipe to pstops filter */
    
  •   wait_children,      /\* Number of child processes left */
    
  •   wait_pid,       /\* Process ID from wait() */
    
  •   wait_status,        /\* Status from child */
    
  •   exit_status = 0;    /\* Exit status */
    
  • char pdf_argv[100], / Arguments for pdftops/gs */
  •   pdf_width[255],     /\* Paper width */
    
  •   pdf_height[255],    /\* Paper height */
    
  •   pstops_path[1024],  /\* Path to pstops program */
    
  •   _pstops_argv[7],    /_ Arguments for pstops filter */
    
  •   _pstops_options,    /_ Options for pstops filter */
    
  •   _pstops_start,      /_ Start of pstops filter option */
    
  •   _pstops_end;        /_ End of pstops filter option */
    
  • const char cups_serverbin; / CUPS_SERVERBIN environment variable /
    #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
    struct sigaction action; /
    Actions for POSIX signals /
    #endif /
    HAVE_SIGACTION && !HAVE_SIGSET */
    @@ -158,21 +168,111 @@
    cupsMarkOptions(ppd, num_options, options);

/*

  • * Build the pstops command-line...
  • */
  • if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
  • cups_serverbin = CUPS_SERVERBIN;
  • snprintf(pstops_path, sizeof(pstops_path), "%s/filter/pstops",
  •       cups_serverbin);
    
  • pstops_options = strdup(argv[5]);
  • if ((pstops_start = strstr(pstops_options, "fitplot")) != NULL &&
  •  (!pstops_start[7] || isspace(pstops_start[7] & 255)))
    
  • {
  • /*
  • * Strip [no]fitplot option...
  • */
  • pstops_end = pstops_start + 7;
  • if ((pstops_start - pstops_options) >= 2 &&
  •    !strncmp(pstops_start - 2, "no", 2))
    
  •  pstops_start -= 2;
    
  • while (_pstops_end && isspace(_pstops_end & 255))
  •  pstops_end ++;
    
  • _cups_strcpy(pstops_start, pstops_end);
  • }
  • if ((pstops_start = strstr(pstops_options, "fit-to-page")) != NULL &&
  •  (!pstops_start[11] || isspace(pstops_start[11] & 255)))
    
  • {
  • /*
  • * Strip [no]fit-to-page option...
  • */
  • pstops_end = pstops_start + 11;
  • if ((pstops_start - pstops_options) >= 2 &&
  •    !strncmp(pstops_start - 2, "no", 2))
    
  •  pstops_start -= 2;
    
  • while (_pstops_end && isspace(_pstops_end & 255))
  •  pstops_end ++;
    
  • _cups_strcpy(pstops_start, pstops_end);
  • }
  • if ((pstops_start = strstr(pstops_options, "landscape")) != NULL &&
  •  (!pstops_start[9] || isspace(pstops_start[9] & 255)))
    
  • {
  • /*
  • * Strip [no]landscape option...
  • */
  • pstops_end = pstops_start + 9;
  • if ((pstops_start - pstops_options) >= 2 &&
  •    !strncmp(pstops_start - 2, "no", 2))
    
  •  pstops_start -= 2;
    
  • while (_pstops_end && isspace(_pstops_end & 255))
  •  pstops_end ++;
    
  • _cups_strcpy(pstops_start, pstops_end);
  • }
  • if ((pstops_start = strstr(pstops_options, "orientation-requested=")) != NULL)
  • {
  • /*
  • * Strip [no]fitplot option...
  • */
  • pstops_end = pstops_start + 22;
  • while (_pstops_end && !isspace(_pstops_end & 255))
  •  pstops_end ++;
    
  • _cups_strcpy(pstops_start, pstops_end);
  • }
  • pstops_argv[0] = argv[0]; /* Printer */
  • pstops_argv[1] = argv[1]; /* Job */
  • pstops_argv[2] = argv[2]; /* User */
  • pstops_argv[3] = argv[3]; /* Title */
  • pstops_argv[4] = argv[4]; /* Copies */
  • pstops_argv[5] = pstops_options; /* Options */
  • pstops_argv[6] = NULL;
  • /*

    • Build the command-line for the pdftops or gs filter...
      */

    #ifdef HAVE_PDFTOPS

  • pdfargv[0] = (char *)"pdftops";

  • pdfargc = 1;

  • pdf_argv[0] = (char *)"pdftops";

  • pdf_argc = 1;
    #else

  • pdfargv[0] = (char *)"gs";

  • pdfargv[1] = (char *)"-q";

  • pdfargv[2] = (char *)"-dNOPAUSE";

  • pdfargv[3] = (char *)"-dBATCH";

  • pdfargv[4] = (char *)"-dSAFER";

  • pdfargv[5] = (char *)"-sDEVICE=pswrite";

  • pdfargv[6] = (char *)"-sOUTPUTFILE=%stdout";

  • pdfargc = 7;

  • pdf_argv[0] = (char *)"gs";

  • pdf_argv[1] = (char *)"-q";

  • pdf_argv[2] = (char *)"-dNOPAUSE";

  • pdf_argv[3] = (char *)"-dBATCH";

  • pdf_argv[4] = (char *)"-dSAFER";

  • pdf_argv[5] = (char *)"-sDEVICE=pswrite";

  • pdf_argv[6] = (char *)"-sOUTPUTFILE=%stdout";

  • pdf_argc = 7;
    #endif /* HAVE_PDFTOPS */

    if (ppd)
    @@ -184,27 +284,27 @@
    if (ppd->language_level == 1)
    {
    #ifdef HAVE_PDFTOPS

  •  pdfargv[pdfargc++] = (char *)"-level1";
    
  •  pdfargv[pdfargc++] = (char *)"-noembtt";
    
  •  pdf_argv[pdf_argc++] = (char *)"-level1";
    
  •  pdf_argv[pdf_argc++] = (char *)"-noembtt";
    

    #else

  •  pdfargv[pdfargc++] = (char *)"-dLanguageLevel=1";
    
  •  pdf_argv[pdf_argc++] = (char _)"-dLanguageLevel=1";
    

    #endif /_ HAVE_PDFTOPS */
    }
    else if (ppd->language_level == 2)
    {
    #ifdef HAVE_PDFTOPS

  •  pdfargv[pdfargc++] = (char *)"-level2";
    
  •  pdf_argv[pdf_argc++] = (char *)"-level2";
    

    if (!ppd->ttrasterizer)

  • pdfargv[pdfargc++] = (char *)"-noembtt";

  • pdf_argv[pdf_argc++] = (char *)"-noembtt";
    #else

  •  pdfargv[pdfargc++] = (char *)"-dLanguageLevel=2";
    
  •  pdf_argv[pdf_argc++] = (char _)"-dLanguageLevel=2";
    

    #endif /_ HAVE_PDFTOPS */
    }
    else
    #ifdef HAVE_PDFTOPS

  •  pdfargv[pdfargc++] = (char *)"-level3";
    
  •  pdf_argv[pdf_argc++] = (char *)"-level3";
    

    #else

  •  pdfargv[pdfargc++] = (char *)"-dLanguageLevel=3";
    
  •  pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=3";
    

    #endif /* HAVE_PDFTOPS */

    if ((val = cupsGetOption("fitplot", num_options, options)) == NULL)
    @@ -254,72 +354,88 @@
    #ifdef HAVE_PDFTOPS
    if (orientation & 1)
    {

  • snprintf(pdfwidth, sizeof(pdfwidth), "%.0f", size->length);

  • snprintf(pdfheight, sizeof(pdfheight), "%.0f", size->width);

  • snprintf(pdf_width, sizeof(pdf_width), "%.0f", size->length);

  • snprintf(pdf_height, sizeof(pdf_height), "%.0f", size->width);
    }
    else
    {

  • snprintf(pdfwidth, sizeof(pdfwidth), "%.0f", size->width);

  • snprintf(pdfheight, sizeof(pdfheight), "%.0f", size->length);

  • snprintf(pdf_width, sizeof(pdf_width), "%.0f", size->width);

  • snprintf(pdf_height, sizeof(pdf_height), "%.0f", size->length);
    }

  •  pdfargv[pdfargc++] = (char *)"-paperw";
    
  •  pdfargv[pdfargc++] = pdfwidth;
    
  •  pdfargv[pdfargc++] = (char *)"-paperh";
    
  •  pdfargv[pdfargc++] = pdfheight;
    
  •  pdfargv[pdfargc++] = (char *)"-expand";
    
  •  pdf_argv[pdf_argc++] = (char *)"-paperw";
    
  •  pdf_argv[pdf_argc++] = pdf_width;
    
  •  pdf_argv[pdf_argc++] = (char *)"-paperh";
    
  •  pdf_argv[pdf_argc++] = pdf_height;
    
  •  pdf_argv[pdf_argc++] = (char *)"-expand";
    

    #else
    if (orientation & 1)
    {

  • snprintf(pdfwidth, sizeof(pdfwidth), "-dDEVICEWIDTHPOINTS=%.0f",

  • snprintf(pdf_width, sizeof(pdf_width), "-dDEVICEWIDTHPOINTS=%.0f",
    size->length);

  • snprintf(pdfheight, sizeof(pdfheight), "-dDEVICEHEIGHTPOINTS=%.0f",

  • snprintf(pdf_height, sizeof(pdf_height), "-dDEVICEHEIGHTPOINTS=%.0f",
    size->width);
    }
    else
    {

  • snprintf(pdfwidth, sizeof(pdfwidth), "-dDEVICEWIDTHPOINTS=%.0f",

  • snprintf(pdf_width, sizeof(pdf_width), "-dDEVICEWIDTHPOINTS=%.0f",
    size->width);

  • snprintf(pdfheight, sizeof(pdfheight), "-dDEVICEHEIGHTPOINTS=%.0f",

  • snprintf(pdf_height, sizeof(pdf_height), "-dDEVICEHEIGHTPOINTS=%.0f",
    size->length);
    }

  •  pdfargv[pdfargc++] = pdfwidth;
    
  •  pdfargv[pdfargc++] = pdfheight;
    
  •  pdf_argv[pdf_argc++] = pdf_width;
    
  •  pdf_argv[pdf_argc++] = pdf_height;
    

    #endif /* HAVE_PDFTOPS */
    }
    }

    #ifdef HAVE_PDFTOPS

  • pdfargv[pdfargc++] = filename;

  • pdfargv[pdfargc++] = (char *)"-";

  • pdf_argv[pdf_argc++] = filename;

  • pdf_argv[pdf_argc++] = (char *)"-";
    #else

  • pdfargv[pdfargc++] = (char *)"-c";

  • pdfargv[pdfargc++] = (char *)"save pop";

  • pdfargv[pdfargc++] = (char *)"-f";

  • pdfargv[pdfargc++] = filename;

  • pdf_argv[pdf_argc++] = (char *)"-c";

  • pdf_argv[pdf_argc++] = (char *)"save pop";

  • pdf_argv[pdf_argc++] = (char *)"-f";

  • pdf_argv[pdf_argc++] = filename;
    #endif /* HAVE_PDFTOPS */

  • pdfargv[pdfargc] = NULL;

  • pdf_argv[pdf_argc] = NULL;

  • if ((pdfpid = fork()) == 0)

  • /*

  • * Execute "pdftops/gs | pstops"...

  • */

  • if (pipe(pstops_pipe))
    {
  • cupsLangPrintError(("ERROR: Unable to create pipe"));
  • exit_status = 1;
  • goto error;
  • }
  • if ((pdf_pid = fork()) == 0)
  • {
    /*
  • Child comes here...
    */
  • dup2(pstops_pipe[1], 1);
  • close(pstops_pipe[0]);
  • close(pstops_pipe[1]);

#ifdef HAVE_PDFTOPS

  • execv(CUPS_PDFTOPS, pdfargv);

  • execv(CUPS_PDFTOPS, pdf_argv);
    cupsLangPrintError(("ERROR: Unable to execute pdftops program"));
    #else

  • execv(CUPS_GHOSTSCRIPT, pdfargv);

  • execv(CUPS_GHOSTSCRIPT, pdf_argv);
    cupsLangPrintError(("ERROR: Unable to execute gs program"));
    #endif /* HAVE_PDFTOPS */

    exit(1);
    }

  • else if (pdfpid < 0)

  • else if (pdf_pid < 0)
    {
    /*

  • Unable to fork!
    @@ -331,56 +447,137 @@
    cupsLangPrintError(("ERROR: Unable to execute gs program"));
    #endif /* HAVE_PDFTOPS */

  • pdfstatus = 1;

  • exit_status = 1;

  • goto error;
    }

  • else

  • fprintf(stderr, "DEBUG: Started filter %s (PID %d)\n", pdf_argv[0], pdf_pid);
  • if ((pstops_pid = fork()) == 0)
    {
    /*
  • * Parent comes here...
    • Child comes here...
      */
  • while ((pdfwaitpid = wait(&pdfstatus)) != pdfpid && errno == EINTR)
  • dup2(pstops_pipe[0], 0);
  • close(pstops_pipe[0]);
  • close(pstops_pipe[1]);
  • execv(pstops_path, pstops_argv);
  • cupsLangPrintError(("ERROR: Unable to execute pstops program"));
  • exit(1);
  • }
  • else if (pstops_pid < 0)
  • {
  • /*
  • * Unable to fork!
  • */
  • cupsLangPrintError(("ERROR: Unable to execute pstops program"));
  • exit_status = 1;
  • goto error;
  • }
  • fprintf(stderr, "DEBUG: Started filter pstops (PID %d)\n", pstops_pid);
  • close(pstops_pipe[0]);
  • close(pstops_pipe[1]);
  • /*
  • * Wait for the child processes to exit...
  • */
  • wait_children = 2;
  • while (wait_children > 0)
  • {
  • /*
  • * Wait until we get a valid process ID or the job is canceled...
  • */
  • while ((wait_pid = wait(&wait_status)) < 0 && errno == EINTR)
    {
  • /*
    
  •  \* Wait until we get a valid process ID or the job is canceled...
    

- */

   if (job_canceled)
   {
  •    kill(pdfpid, SIGTERM);
    
  • kill(pdf_pid, SIGTERM);
  • kill(pstops_pid, SIGTERM);

job_canceled = 0;
}
}

  • if (pdfstatus)
  • if (wait_pid < 0)
  •  break;
    
  • wait_children --;
  • /*
  • * Report child status...
  • */
  • if (wait_status)
    {
  •  if (WIFEXITED(pdfstatus))
    
  •  if (WIFEXITED(wait_status))
    
    {
  • pdfstatus = WEXITSTATUS(pdfstatus);
  • exit_status = WEXITSTATUS(wait_status);
  • _cupsLangPrintf(stderr,
  •       _("ERROR: pdftops filter exited with status %d!\n"),
    
  •       pdfstatus);
    
  •    fprintf(stderr, "DEBUG: PID %d (%s) stopped with status %d!\n",
    
  •       wait_pid,  
    
    +#ifdef HAVE_PDFTOPS
  •            wait_pid == pdf_pid ? "pdftops" : "pstops",
    
    +#else
  •            wait_pid == pdf_pid ? "gs" : "pstops",
    
    +#endif /* HAVE_PDFTOPS */
  •   exit_status);
    
    }
  •  else if (WTERMSIG(wait_status) == SIGTERM)
    
  •  {
    
  •    fprintf(stderr,
    
  •       "DEBUG: PID %d (%s) was terminated normally with signal %d!\n",
    
  •       wait_pid,  
    
    +#ifdef HAVE_PDFTOPS
  •            wait_pid == pdf_pid ? "pdftops" : "pstops",
    
    +#else
  •            wait_pid == pdf_pid ? "gs" : "pstops",
    
    +#endif /* HAVE_PDFTOPS */
  •   exit_status);
    
  •  }
    
    else
    {
  • pdfstatus = WTERMSIG(pdfstatus);
  • exit_status = WTERMSIG(wait_status);
  • _cupsLangPrintf(stderr,
  •       _("ERROR: pdftops filter crashed on signal %d!\n"),
    
  •       pdfstatus);
    
  •    fprintf(stderr, "DEBUG: PID %d (%s) crashed on signal %d!\n", wait_pid,  
    
    +#ifdef HAVE_PDFTOPS
  •            wait_pid == pdf_pid ? "pdftops" : "pstops",
    
    +#else
  •            wait_pid == pdf_pid ? "gs" : "pstops",
    
    +#endif /* HAVE_PDFTOPS */
  •   exit_status);
    
    }
    }
  • else
  • {
  •  fprintf(stderr, "DEBUG: PID %d (%s) exited with no errors.\n", wait_pid,  
    
    +#ifdef HAVE_PDFTOPS
  •     wait_pid == pdf_pid ? "pdftops" : "pstops");
    
    +#else
  •     wait_pid == pdf_pid ? "gs" : "pstops");
    
    +#endif /* HAVE_PDFTOPS */
  • }
    }

/*

  • Cleanup and exit...
    */
  • error:

if (tempfile[0])
unlink(tempfile);

  • return (pdfstatus);
  • return (exit_status);
    }

Loading

@michaelrsweet
Copy link
Collaborator Author

@michaelrsweet michaelrsweet commented May 22, 2009

"str2881-1.3.patch":

Index: conf/mime.convs.in

--- conf/mime.convs.in (revision 8674)
+++ conf/mime.convs.in (working copy)
@@ -7,7 +7,7 @@

MIME converts file for the Common UNIX Printing System (CUPS).

-# Copyright 2007 by Apple Inc.
+# Copyright 2007-2009 by Apple Inc.

Copyright 1997-2007 by Easy Software Products.

These coded instructions, statements, and computer programs are the

@@ -38,7 +38,7 @@

PostScript filters

-application/pdf application/postscript 33 pdftops
+application/pdf application/vnd.cups-postscript 66 pdftops
application/postscript application/vnd.cups-postscript 66 pstops
application/vnd.hp-HPGL application/postscript 66 hpgltops
application/x-cshell application/postscript 33 texttops

Index: filter/pdftops.c

--- filter/pdftops.c (revision 8674)
+++ filter/pdftops.c (working copy)
@@ -65,13 +65,23 @@
fit; /* Fit output to default page size? /
ppd_file_t *ppd; /
PPD file /
ppd_size_t *size; /
Current page size */

  • int pdfpid, /* Process ID for pdftops */
  •   pdfwaitpid,     /\* Process ID from wait() */
    
  •   pdfstatus,      /\* Status from pdftops */
    
  •   pdfargc;        /\* Number of args for pdftops */
    
  • char pdfargv[100], / Arguments for pdftops/gs */
  •   pdfwidth[255],      /\* Paper width */
    
  •   pdfheight[255];     /\* Paper height */
    
  • int pdf_pid, /* Process ID for pdftops */
  •   pdf_argc,       /\* Number of args for pdftops */
    
  •   pstops_pid,     /\* Process ID of pstops filter */
    
  •   pstops_pipe[2],     /\* Pipe to pstops filter */
    
  •   wait_children,      /\* Number of child processes left */
    
  •   wait_pid,       /\* Process ID from wait() */
    
  •   wait_status,        /\* Status from child */
    
  •   exit_status = 0;    /\* Exit status */
    
  • char pdf_argv[100], / Arguments for pdftops/gs */
  •   pdf_width[255],     /\* Paper width */
    
  •   pdf_height[255],    /\* Paper height */
    
  •   pstops_path[1024],  /\* Path to pstops program */
    
  •   _pstops_argv[7],    /_ Arguments for pstops filter */
    
  •   _pstops_options,    /_ Options for pstops filter */
    
  •   _pstops_start,      /_ Start of pstops filter option */
    
  •   _pstops_end;        /_ End of pstops filter option */
    
  • const char cups_serverbin; / CUPS_SERVERBIN environment variable /
    #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
    struct sigaction action; /
    Actions for POSIX signals /
    #endif /
    HAVE_SIGACTION && !HAVE_SIGSET */
    @@ -159,21 +169,111 @@
    cupsMarkOptions(ppd, num_options, options);

/*

  • * Build the pstops command-line...
  • */
  • if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
  • cups_serverbin = CUPS_SERVERBIN;
  • snprintf(pstops_path, sizeof(pstops_path), "%s/filter/pstops",
  •       cups_serverbin);
    
  • pstops_options = strdup(argv[5]);
  • if ((pstops_start = strstr(pstops_options, "fitplot")) != NULL &&
  •  (!pstops_start[7] || isspace(pstops_start[7] & 255)))
    
  • {
  • /*
  • * Strip [no]fitplot option...
  • */
  • pstops_end = pstops_start + 7;
  • if ((pstops_start - pstops_options) >= 2 &&
  •    !strncmp(pstops_start - 2, "no", 2))
    
  •  pstops_start -= 2;
    
  • while (_pstops_end && isspace(_pstops_end & 255))
  •  pstops_end ++;
    
  • _cups_strcpy(pstops_start, pstops_end);
  • }
  • if ((pstops_start = strstr(pstops_options, "fit-to-page")) != NULL &&
  •  (!pstops_start[11] || isspace(pstops_start[11] & 255)))
    
  • {
  • /*
  • * Strip [no]fit-to-page option...
  • */
  • pstops_end = pstops_start + 11;
  • if ((pstops_start - pstops_options) >= 2 &&
  •    !strncmp(pstops_start - 2, "no", 2))
    
  •  pstops_start -= 2;
    
  • while (_pstops_end && isspace(_pstops_end & 255))
  •  pstops_end ++;
    
  • _cups_strcpy(pstops_start, pstops_end);
  • }
  • if ((pstops_start = strstr(pstops_options, "landscape")) != NULL &&
  •  (!pstops_start[9] || isspace(pstops_start[9] & 255)))
    
  • {
  • /*
  • * Strip [no]landscape option...
  • */
  • pstops_end = pstops_start + 9;
  • if ((pstops_start - pstops_options) >= 2 &&
  •    !strncmp(pstops_start - 2, "no", 2))
    
  •  pstops_start -= 2;
    
  • while (_pstops_end && isspace(_pstops_end & 255))
  •  pstops_end ++;
    
  • _cups_strcpy(pstops_start, pstops_end);
  • }
  • if ((pstops_start = strstr(pstops_options, "orientation-requested=")) != NULL)
  • {
  • /*
  • * Strip [no]fitplot option...
  • */
  • pstops_end = pstops_start + 22;
  • while (_pstops_end && !isspace(_pstops_end & 255))
  •  pstops_end ++;
    
  • _cups_strcpy(pstops_start, pstops_end);
  • }
  • pstops_argv[0] = argv[0]; /* Printer */
  • pstops_argv[1] = argv[1]; /* Job */
  • pstops_argv[2] = argv[2]; /* User */
  • pstops_argv[3] = argv[3]; /* Title */
  • pstops_argv[4] = argv[4]; /* Copies */
  • pstops_argv[5] = pstops_options; /* Options */
  • pstops_argv[6] = NULL;
  • /*

    • Build the command-line for the pdftops or gs filter...
      */

    #ifdef HAVE_PDFTOPS

  • pdfargv[0] = (char *)"pdftops";

  • pdfargc = 1;

  • pdf_argv[0] = (char *)"pdftops";

  • pdf_argc = 1;
    #else

  • pdfargv[0] = (char *)"gs";

  • pdfargv[1] = (char *)"-q";

  • pdfargv[2] = (char *)"-dNOPAUSE";

  • pdfargv[3] = (char *)"-dBATCH";

  • pdfargv[4] = (char *)"-dSAFER";

  • pdfargv[5] = (char *)"-sDEVICE=pswrite";

  • pdfargv[6] = (char *)"-sOUTPUTFILE=%stdout";

  • pdfargc = 7;

  • pdf_argv[0] = (char *)"gs";

  • pdf_argv[1] = (char *)"-q";

  • pdf_argv[2] = (char *)"-dNOPAUSE";

  • pdf_argv[3] = (char *)"-dBATCH";

  • pdf_argv[4] = (char *)"-dSAFER";

  • pdf_argv[5] = (char *)"-sDEVICE=pswrite";

  • pdf_argv[6] = (char *)"-sOUTPUTFILE=%stdout";

  • pdf_argc = 7;
    #endif /* HAVE_PDFTOPS */

    if (ppd)
    @@ -185,27 +285,27 @@
    if (ppd->language_level == 1)
    {
    #ifdef HAVE_PDFTOPS

  •  pdfargv[pdfargc++] = (char *)"-level1";
    
  •  pdfargv[pdfargc++] = (char *)"-noembtt";
    
  •  pdf_argv[pdf_argc++] = (char *)"-level1";
    
  •  pdf_argv[pdf_argc++] = (char *)"-noembtt";
    

    #else

  •  pdfargv[pdfargc++] = (char *)"-dLanguageLevel=1";
    
  •  pdf_argv[pdf_argc++] = (char _)"-dLanguageLevel=1";
    

    #endif /_ HAVE_PDFTOPS */
    }
    else if (ppd->language_level == 2)
    {
    #ifdef HAVE_PDFTOPS

  •  pdfargv[pdfargc++] = (char *)"-level2";
    
  •  pdf_argv[pdf_argc++] = (char *)"-level2";
    

    if (!ppd->ttrasterizer)

  • pdfargv[pdfargc++] = (char *)"-noembtt";

  • pdf_argv[pdf_argc++] = (char *)"-noembtt";
    #else

  •  pdfargv[pdfargc++] = (char *)"-dLanguageLevel=2";
    
  •  pdf_argv[pdf_argc++] = (char _)"-dLanguageLevel=2";
    

    #endif /_ HAVE_PDFTOPS */
    }
    else
    #ifdef HAVE_PDFTOPS

  •  pdfargv[pdfargc++] = (char *)"-level3";
    
  •  pdf_argv[pdf_argc++] = (char *)"-level3";
    

    #else

  •  pdfargv[pdfargc++] = (char *)"-dLanguageLevel=3";
    
  •  pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=3";
    

    #endif /* HAVE_PDFTOPS */

    if ((val = cupsGetOption("fitplot", num_options, options)) == NULL)
    @@ -255,74 +355,91 @@
    #ifdef HAVE_PDFTOPS
    if (orientation & 1)
    {

  • snprintf(pdfwidth, sizeof(pdfwidth), "%.0f", size->length);

  • snprintf(pdfheight, sizeof(pdfheight), "%.0f", size->width);

  • snprintf(pdf_width, sizeof(pdf_width), "%.0f", size->length);

  • snprintf(pdf_height, sizeof(pdf_height), "%.0f", size->width);
    }
    else
    {

  • snprintf(pdfwidth, sizeof(pdfwidth), "%.0f", size->width);

  • snprintf(pdfheight, sizeof(pdfheight), "%.0f", size->length);

  • snprintf(pdf_width, sizeof(pdf_width), "%.0f", size->width);

  • snprintf(pdf_height, sizeof(pdf_height), "%.0f", size->length);
    }

  •  pdfargv[pdfargc++] = (char *)"-paperw";
    
  •  pdfargv[pdfargc++] = pdfwidth;
    
  •  pdfargv[pdfargc++] = (char *)"-paperh";
    
  •  pdfargv[pdfargc++] = pdfheight;
    
  •  pdfargv[pdfargc++] = (char *)"-expand";
    
  •  pdf_argv[pdf_argc++] = (char *)"-paperw";
    
  •  pdf_argv[pdf_argc++] = pdf_width;
    
  •  pdf_argv[pdf_argc++] = (char *)"-paperh";
    
  •  pdf_argv[pdf_argc++] = pdf_height;
    
  •  pdf_argv[pdf_argc++] = (char *)"-expand";
    

    #else
    if (orientation & 1)
    {

  • snprintf(pdfwidth, sizeof(pdfwidth), "-dDEVICEWIDTHPOINTS=%.0f",

  • snprintf(pdf_width, sizeof(pdf_width), "-dDEVICEWIDTHPOINTS=%.0f",
    size->length);

  • snprintf(pdfheight, sizeof(pdfheight), "-dDEVICEHEIGHTPOINTS=%.0f",

  • snprintf(pdf_height, sizeof(pdf_height), "-dDEVICEHEIGHTPOINTS=%.0f",
    size->width);
    }
    else
    {

  • snprintf(pdfwidth, sizeof(pdfwidth), "-dDEVICEWIDTHPOINTS=%.0f",

  • snprintf(pdf_width, sizeof(pdf_width), "-dDEVICEWIDTHPOINTS=%.0f",
    size->width);

  • snprintf(pdfheight, sizeof(pdfheight), "-dDEVICEHEIGHTPOINTS=%.0f",

  • snprintf(pdf_height, sizeof(pdf_height), "-dDEVICEHEIGHTPOINTS=%.0f",
    size->length);
    }

  •  pdfargv[pdfargc++] = pdfwidth;
    
  •  pdfargv[pdfargc++] = pdfheight;
    
  •  pdf_argv[pdf_argc++] = pdf_width;
    
  •  pdf_argv[pdf_argc++] = pdf_height;
    

    #endif /* HAVE_PDFTOPS */
    }
    }

    #ifdef HAVE_PDFTOPS

  • pdfargv[pdfargc++] = filename;

  • pdfargv[pdfargc++] = (char *)"-";

  • pdf_argv[pdf_argc++] = filename;

  • pdf_argv[pdf_argc++] = (char *)"-";
    #else

  • pdfargv[pdfargc++] = (char *)"-c";

  • pdfargv[pdfargc++] = (char *)"save pop";

  • pdfargv[pdfargc++] = (char *)"-f";

  • pdfargv[pdfargc++] = filename;

  • pdf_argv[pdf_argc++] = (char *)"-c";

  • pdf_argv[pdf_argc++] = (char *)"save pop";

  • pdf_argv[pdf_argc++] = (char *)"-f";

  • pdf_argv[pdf_argc++] = filename;
    #endif /* HAVE_PDFTOPS */

  • pdfargv[pdfargc] = NULL;

  • pdf_argv[pdf_argc] = NULL;

  • if ((pdfpid = fork()) == 0)

  • /*

  • * Execute "pdftops/gs | pstops"...

  • */

  • if (pipe(pstops_pipe))
    {
  • _cupsLangPrintf(stderr, _("ERROR: Unable to create pipe: %s\n"),
  •                strerror(errno));
    
  • exit_status = 1;
  • goto error;
  • }
  • if ((pdf_pid = fork()) == 0)
  • {
    /*
  • Child comes here...
    */
  • dup2(pstops_pipe[1], 1);
  • close(pstops_pipe[0]);
  • close(pstops_pipe[1]);

#ifdef HAVE_PDFTOPS

  • execv(CUPS_PDFTOPS, pdfargv);

  • execv(CUPS_PDFTOPS, pdf_argv);
    _cupsLangPrintf(stderr, _("ERROR: Unable to execute pdftops program: %s\n"),
    strerror(errno));
    #else

  • execv(CUPS_GHOSTSCRIPT, pdfargv);

  • execv(CUPS_GHOSTSCRIPT, pdf_argv);
    _cupsLangPrintf(stderr, _("ERROR: Unable to execute gs program: %s\n"),
    strerror(errno));
    #endif /* HAVE_PDFTOPS */

    exit(1);
    }

  • else if (pdfpid < 0)

  • else if (pdf_pid < 0)
    {
    /*

  • Unable to fork!
    @@ -336,56 +453,139 @@
    strerror(errno));
    #endif /* HAVE_PDFTOPS */

  • pdfstatus = 1;

  • exit_status = 1;

  • goto error;
    }

  • else

  • fprintf(stderr, "DEBUG: Started filter %s (PID %d)\n", pdf_argv[0], pdf_pid);
  • if ((pstops_pid = fork()) == 0)
    {
    /*
  • * Parent comes here...
    • Child comes here...
      */
  • while ((pdfwaitpid = wait(&pdfstatus)) != pdfpid && errno == EINTR)
  • dup2(pstops_pipe[0], 0);
  • close(pstops_pipe[0]);
  • close(pstops_pipe[1]);
  • execv(pstops_path, pstops_argv);
  • _cupsLangPrintf(stderr, _("ERROR: Unable to execute pstops program: %s\n"),
  •                strerror(errno));
    
  • exit(1);
  • }
  • else if (pstops_pid < 0)
  • {
  • /*
  • * Unable to fork!
  • */
  • _cupsLangPrintf(stderr, _("ERROR: Unable to execute pstops program: %s\n"),
  •                strerror(errno));
    
  • exit_status = 1;
  • goto error;
  • }
  • fprintf(stderr, "DEBUG: Started filter pstops (PID %d)\n", pstops_pid);
  • close(pstops_pipe[0]);
  • close(pstops_pipe[1]);
  • /*
  • * Wait for the child processes to exit...
  • */
  • wait_children = 2;
  • while (wait_children > 0)
  • {
  • /*
  • * Wait until we get a valid process ID or the job is canceled...
  • */
  • while ((wait_pid = wait(&wait_status)) < 0 && errno == EINTR)
    {
  • /*
    
  •  \* Wait until we get a valid process ID or the job is canceled...
    

- */

   if (job_canceled)
   {
  •    kill(pdfpid, SIGTERM);
    
  • kill(pdf_pid, SIGTERM);
  • kill(pstops_pid, SIGTERM);

job_canceled = 0;
}
}

  • if (pdfstatus)
  • if (wait_pid < 0)
  •  break;
    
  • wait_children --;
  • /*
  • * Report child status...
  • */
  • if (wait_status)
    {
  •  if (WIFEXITED(pdfstatus))
    
  •  if (WIFEXITED(wait_status))
    
    {
  • pdfstatus = WEXITSTATUS(pdfstatus);
  • exit_status = WEXITSTATUS(wait_status);
  • _cupsLangPrintf(stderr,
  •       _("ERROR: pdftops filter exited with status %d!\n"),
    
  •       pdfstatus);
    
  •    fprintf(stderr, "DEBUG: PID %d (%s) stopped with status %d!\n",
    
  •       wait_pid,  
    
    +#ifdef HAVE_PDFTOPS
  •            wait_pid == pdf_pid ? "pdftops" : "pstops",
    
    +#else
  •            wait_pid == pdf_pid ? "gs" : "pstops",
    
    +#endif /* HAVE_PDFTOPS */
  •   exit_status);
    
    }
  •  else if (WTERMSIG(wait_status) == SIGTERM)
    
  •  {
    
  •    fprintf(stderr,
    
  •       "DEBUG: PID %d (%s) was terminated normally with signal %d!\n",
    
  •       wait_pid,  
    
    +#ifdef HAVE_PDFTOPS
  •            wait_pid == pdf_pid ? "pdftops" : "pstops",
    
    +#else
  •            wait_pid == pdf_pid ? "gs" : "pstops",
    
    +#endif /* HAVE_PDFTOPS */
  •   exit_status);
    
  •  }
    
    else
    {
  • pdfstatus = WTERMSIG(pdfstatus);
  • exit_status = WTERMSIG(wait_status);
  • _cupsLangPrintf(stderr,
  •       _("ERROR: pdftops filter crashed on signal %d!\n"),
    
  •       pdfstatus);
    
  •    fprintf(stderr, "DEBUG: PID %d (%s) crashed on signal %d!\n", wait_pid,  
    
    +#ifdef HAVE_PDFTOPS
  •            wait_pid == pdf_pid ? "pdftops" : "pstops",
    
    +#else
  •            wait_pid == pdf_pid ? "gs" : "pstops",
    
    +#endif /* HAVE_PDFTOPS */
  •   exit_status);
    
    }
    }
  • else
  • {
  •  fprintf(stderr, "DEBUG: PID %d (%s) exited with no errors.\n", wait_pid,  
    
    +#ifdef HAVE_PDFTOPS
  •     wait_pid == pdf_pid ? "pdftops" : "pstops");
    
    +#else
  •     wait_pid == pdf_pid ? "gs" : "pstops");
    
    +#endif /* HAVE_PDFTOPS */
  • }
    }

/*

  • Cleanup and exit...
    */
  • error:

if (tempfile[0])
unlink(tempfile);

  • return (pdfstatus);
  • return (exit_status);
    }

Loading

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