Bug 687542 Print with pswrite gives 'Could not open the file \\spool\yourprinter' (OS/2)

"Russell Lang" <[email protected]> Wed, 07 Jul 2004 19:45:31 +1000
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <40EC52DB.3057.AA64DDF4@localhost>
Log Message:
Fixes bug 687542 Print with pswrite gives 'Could not open the 
file \\spool\yourprinter'. Add a %printer% IODevice for OS/2, 
which opens to a temporary file then later copies it to the
print spooler.  This will need "%printer%yourprinter",
not "\\spool\yourprinter".
This is needed to make pswrite write to a printer queue.

Russell Lang                   [email protected]
Ghostgum Software Pty Ltd      http://www.ghostgum.com.au/

diff -u l:/cvs/gs/src/gp_os2.c src/gp_os2.c
--- l:/cvs/gs/src/gp_os2.c	Fri Jan 30 09:35:59 2004
+++ src/gp_os2.c	Wed Jul 07 09:35:12 2004
@@ -54,6 +54,7 @@
 #include "stdlib.h"		/* need _osmode, exit */
 #include "time_.h"
 #include <time.h>		/* should this be in time_.h? */
+#include "gp_os2.h"
 #include "gdevpm.h"
 #ifdef __EMX__
 #include <sys/emxload.h>
@@ -397,9 +398,7 @@
 }
 
 /* ------ Printer accessing ------ */
-private int pm_find_queue(char *queue_name, char *driver_name);
 private int is_os2_spool(const char *queue);
-private int pm_spool(char *filename, const char *queue);
 
 /* Put a printer file (which might be stdout) into binary or text mode. */
 /* This is not a standard gp procedure, */
@@ -500,7 +499,7 @@
 /* If strlen(queue_name)==0, return default queue and driver name */
 /* If queue_name supplied, return driver_name */
 /* returns 0 if OK, non-zero for error */
-private int
+int
 pm_find_queue(char *queue_name, char *driver_name)
 {
     SPLERR splerr;
@@ -553,9 +552,9 @@
 		    } else {
 			/* list queue details */
 			if (prq->fsType & PRQ3_TYPE_APPDEFAULT)
-			    eprintf1("  %s  (DEFAULT)\n", prq->pszName);
+			    eprintf1("  \042%s\042  (DEFAULT)\n", prq->pszName);
 			else
-			    eprintf1("  %s\n", prq->pszName);
+			    eprintf1("  \042%s\042\n", prq->pszName);
 		    }
 		    prq++;
 		}		/*endfor cReturned */
@@ -600,7 +599,7 @@
 /* Spool file to queue */
 /* return 0 if successful, non-zero if error */
 /* if filename is NULL, return 0 if spool queue is valid, non-zero if error */
-private int
+int
 pm_spool(char *filename, const char *queue)
 {
     HSPL hspl;
diff -u l:/cvs/gs/src/gp_os2.h src/gp_os2.h
--- l:/cvs/gs/src/gp_os2.h	Wed Jul 07 09:33:04 2004
+++ src/gp_os2.h	Wed Jul 07 09:33:28 2004
@@ -0,0 +1,30 @@
+/* Copyright (C) 2004 artocode LLC.  All rights reserved.
+  
+  This software is provided AS-IS with no warranty, either express or
+  implied.
+  
+  This software is distributed under license and may not be copied,
+  modified or distributed except as expressly authorized under the terms
+  of the license contained in the file LICENSE in this distribution.
+  
+  For more information about licensing, please refer to
+  http://www.ghostscript.com/licensing/. For information on
+  commercial licensing, go to http://www.artifex.com/licensing/ or
+  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
+  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
+*/
+
+/* $Id$ */
+/* Common platform-specific routines for OS/2 */
+
+/* If queue_name is NULL, list available queues */
+/* If strlen(queue_name)==0, return default queue and driver name */
+/* If queue_name supplied, return driver_name */
+/* returns 0 if OK, non-zero for error */
+int pm_find_queue(char *queue_name, char *driver_name);
+
+/* Spool file to queue */
+/* Return 0 if successful, non-zero if error. */
+/* If filename is NULL, return 0 if spool queue is valid, non-zero if error */
+int pm_spool(char *filename, const char *queue);
+
diff -u l:/cvs/gs/src/gp_os2pr.c src/gp_os2pr.c
--- l:/cvs/gs/src/gp_os2pr.c	Wed Jul 07 09:32:59 2004
+++ src/gp_os2pr.c	Wed Jul 07 09:33:28 2004
@@ -0,0 +1,129 @@
+/* Copyright (C) 2004 artofcode LLC.  All rights reserved.
+  
+  This software is provided AS-IS with no warranty, either express or
+  implied.
+  
+  This software is distributed under license and may not be copied,
+  modified or distributed except as expressly authorized under the terms
+  of the license contained in the file LICENSE in this distribution.
+  
+  For more information about licensing, please refer to
+  http://www.ghostscript.com/licensing/. For information on
+  commercial licensing, go to http://www.artifex.com/licensing/ or
+  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
+  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
+*/
+
+/* $Id$ */
+/* %printer% IODevice */
+
+#define INCL_DOS
+#define INCL_SPL
+#define INCL_SPLDOSPRINT
+#define INCL_SPLERRORS
+#define INCL_BASE
+#define INCL_ERRORS
+#define INCL_WIN
+#include <os2.h>
+
+#include "errno_.h"
+#include "stdio_.h"
+#include "string_.h"
+#include "gp.h"
+#include "gscdefs.h"
+#include "gserrors.h"
+#include "gserror.h"
+#include "gstypes.h"
+#include "gsmemory.h"		/* for gxiodev.h */
+#include "gxiodev.h"
+
+/* The OS/2 printer IODevice */
+
+/*
+ * This allows an OS/2 printer to be specified as an 
+ * output using
+ *  -sOutputFile="%printer%AppleLas"
+ * where "AppleLas" is the physical name of the queue.
+ *
+ * If you don't supply a printer name you will get
+ *  Error: /undefinedfilename in --.outputpage-- 
+ * If the printer name is invalid you will get
+ *  Error: /invalidfileaccess in --.outputpage-- 
+ *
+ * This is implemented by writing to a temporary file
+ * then copying it to the spooler.
+ *
+ * A better method would be to return a file pointer
+ * to the write end of a pipe, and starting a thread
+ * which reads the pipe and writes to an OS/2 printer.
+ * This method didn't work properly on the second
+ * thread within ghostscript.
+ */
+
+private iodev_proc_init(os2_printer_init);
+private iodev_proc_fopen(os2_printer_fopen);
+private iodev_proc_fclose(os2_printer_fclose);
+const gx_io_device gs_iodev_printer = {
+    "%printer%", "FileSystem",
+    {os2_printer_init, iodev_no_open_device,
+     NULL /*iodev_os_open_file */ , os2_printer_fopen, os2_printer_fclose,
+     iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,
+     iodev_no_enumerate_files, NULL, NULL,
+     iodev_no_get_params, iodev_no_put_params
+    }
+};
+
+typedef struct os2_printer_s {
+    char queue[gp_file_name_sizeof];
+    char filename[gp_file_name_sizeof];
+} os2_printer_t;
+
+/* The file device procedures */
+private int
+os2_printer_init(gx_io_device * iodev, gs_memory_t * mem)
+{
+    /* state -> structure containing thread handle */
+    iodev->state = gs_alloc_bytes(mem, sizeof(os2_printer_t), 
+	"os2_printer_init");
+    if (iodev->state == NULL)
+        return_error(gs_error_VMerror);
+    memset(iodev->state, 0, sizeof(os2_printer_t));
+    return 0;
+}
+
+
+private int
+os2_printer_fopen(gx_io_device * iodev, const char *fname, const char *access,
+	   FILE ** pfile, char *rfname, uint rnamelen)
+{
+    os2_printer_t *pr = (os2_printer_t *)iodev->state;
+    char driver_name[256];
+
+    /* Make sure that printer exists. */
+    if (pm_find_queue(fname, driver_name)) {
+	/* error, list valid queue names */
+	eprintf("Invalid queue name.  Use one of:\n");
+	pm_find_queue(NULL, NULL);
+	return_error(gs_error_undefinedfilename);
+    }
+
+    strncpy(pr->queue, fname, sizeof(pr->queue)-1);
+
+    /* Create a temporary file */
+    *pfile = gp_open_scratch_file("gs", pr->filename, access);
+    if (*pfile == NULL)
+	return_error(gs_fopen_errno_to_code(errno));
+
+    return 0;
+}
+
+private int
+os2_printer_fclose(gx_io_device * iodev, FILE * file)
+{
+    os2_printer_t *pr = (os2_printer_t *)iodev->state;
+    fclose(file);
+    pm_spool(pr->filename, pr->queue); 
+    unlink(pr->filename);
+    return 0;
+}
+
diff -u l:/cvs/gs/src/os2.mak src/os2.mak
--- l:/cvs/gs/src/os2.mak	Thu Jun 24 08:47:40 2004
+++ src/os2.mak	Wed Jul 07 09:33:28 2004
@@ -441,7 +441,7 @@
 # Choose the language feature(s) to include.  See gs.mak for details.
 # Since we have a large address space, we include some optional features.
 
-FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)epsf.dev
+FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)epsf.dev $(PSD)os2print.dev
 
 # Choose whether to compile the .ps initialization files into the executable.
 # See gs.mak for details.
@@ -527,7 +527,7 @@
 $(GLGEN)os2_.dev: $(os2__) $(GLD)nosync.dev
 	$(SETMOD) $(GLGEN)os2_ $(os2__) -include $(GLD)nosync
 
-$(GLOBJ)gp_os2.$(OBJ): $(GLSRC)gp_os2.c\
+$(GLOBJ)gp_os2.$(OBJ): $(GLSRC)gp_os2.c $(GLSRC)gp_os2.h\
  $(dos__h) $(pipe__h) $(string__h) $(time__h)\
  $(gsdll_h) $(gx_h) $(gsexit_h) $(gsutil_h) $(gp_h) $(gpmisc_h)
 	$(GLCC) $(GLO_)gp_os2.$(OBJ) $(C_) $(GLSRC)gp_os2.c
@@ -536,6 +536,19 @@
   $(stdio__h) $(time__h) $(unistd__h) $(gx_h) $(gp_h)
 	$(GLCC) $(GLO_)gp_stdia.$(OBJ) $(C_) $(GLSRC)gp_stdia.c
 
+# Define OS/2 printer (file system) as a separable feature.
+
+os2print_=$(GLOBJ)gp_os2pr.$(OBJ)
+$(GLD)os2print.dev: $(ECHOGS_XE) $(os2print_)
+	$(SETMOD) $(GLD)os2print $(os2print_)
+	$(ADDMOD) $(GLD)os2print -iodev printer
+
+$(GLOBJ)gp_os2pr.$(OBJ): $(GLSRC)gp_os2pr.c $(GLSRC)gp_os2.h $(AK)\
+ $(ctype__h) $(errno__h) $(stdio__h) $(string__h)\
+ $(gserror_h) $(gsmemory_h) $(gstypes_h) $(gxiodev_h)
+	$(GLCC) $(GLO_)gp_os2pr.$(OBJ) $(C_) $(GLSRC)gp_os2pr.c
+
+
 # -------------------------- Auxiliary programs --------------------------- #
 
 #CCAUX=$(COMPDIR)\$(COMP) $(CO)
diff -u l:/cvs/gs/doc/Develop.htm doc/Develop.htm
--- l:/cvs/gs/doc/Develop.htm	Thu Jun 24 08:47:39 2004
+++ doc/Develop.htm	Wed Jul 07 09:39:26 2004
@@ -4164,6 +4164,7 @@
 <a href="../src/gp_mswin.h">src/gp_mswin.h</a>,
 <a href="../src/gp_ntfs.c">src/gp_ntfs.c</a>,
 <a href="../src/gp_os2.c">src/gp_os2.c</a>,
+<a href="../src/gp_os2.h">src/gp_os2.h</a>,
 <a href="../src/gp_os9.c">src/gp_os9.c</a>,
 <a href="../src/gp_stdia.c">src/gp_stdia.c</a>,
 <a href="../src/gp_stdin.c">src/gp_stdin.c</a>,
@@ -4502,6 +4503,7 @@
 <dt>
 OS/2 files:
 <dd>
+<a href="../src/gp_os2pr.c">src/gp_os2pr.c</a>,
 <a href="../src/gsdllos2.h">src/gsdllos2.h</a>.
 
 <dt>

_______________________________________________
gs-code-review mailing list
[email protected]
http://www.ghostscript.com/mailman/listinfo/gs-code-review