1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied, modified
8    or distributed except as expressly authorized under the terms of that
9    license.  Refer to licensing information at http://www.artifex.com/
10    or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11    San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 
14 /* $Id: gp_iwatc.c 8250 2007-09-25 13:31:24Z giles $ */
15 /* Intel processor, Watcom C-specific routines for Ghostscript */
16 #include "dos_.h"
17 #include <fcntl.h>
18 #include <signal.h>
19 #include <stdlib.h>
20 #include "stat_.h"
21 #include "string_.h"
22 #include "gx.h"
23 #include "gp.h"
24 #include "gpmisc.h"
25 
26 /* Library routines not declared in a standard header */
27 extern char *mktemp(char *);	/* in gp_mktmp.c */
28 
29 /* Define a substitute for stdprn (see below). */
30 static FILE *gs_stdprn;
31 
32 /* Forward declarations */
33 static void handle_FPE(int);
34 
35 /* Do platform-dependent initialization. */
36 void
gp_init(void)37 gp_init(void)
38 {
39     gs_stdprn = 0;
40     /* Set up the handler for numeric exceptions. */
41     signal(SIGFPE, handle_FPE);
42 }
43 
44 /* Trap numeric exceptions.  Someday we will do something */
45 /* more appropriate with these. */
46 static void
handle_FPE(int sig)47 handle_FPE(int sig)
48 {
49     eprintf("Numeric exception:\n");
50     exit(1);
51 }
52 
53 /* Do platform-dependent cleanup. */
54 void
gp_exit(int exit_status,int code)55 gp_exit(int exit_status, int code)
56 {
57 }
58 
59 /* Exit the program. */
60 void
gp_do_exit(int exit_status)61 gp_do_exit(int exit_status)
62 {
63     exit(exit_status);
64 }
65 
66 /* ------ Persistent data cache ------*/
67 
68 /* insert a buffer under a (type, key) pair */
gp_cache_insert(int type,byte * key,int keylen,void * buffer,int buflen)69 int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen)
70 {
71     /* not yet implemented */
72     return 0;
73 }
74 
75 /* look up a (type, key) in the cache */
gp_cache_query(int type,byte * key,int keylen,void ** buffer,gp_cache_alloc alloc,void * userdata)76 int gp_cache_query(int type, byte* key, int keylen, void **buffer,
77     gp_cache_alloc alloc, void *userdata)
78 {
79     /* not yet implemented */
80     return -1;
81 }
82 
83 /* ------ Printer accessing ------ */
84 
85 /* Open a connection to a printer.  A null file name means use the */
86 /* standard printer connected to the machine, if any. */
87 /* Return NULL if the connection could not be opened. */
88 extern void gp_set_file_binary(int, int);
89 FILE *
gp_open_printer(char fname[gp_file_name_sizeof],int binary_mode)90 gp_open_printer(char fname[gp_file_name_sizeof], int binary_mode)
91 {
92     FILE *pfile;
93 
94     if (strlen(fname) == 0 || !strcmp(fname, "PRN")) {
95 #ifdef stdprn
96 	if (!binary_mode)
97 	    return stdprn;
98 	if (gs_stdprn == 0) {
99 	    /* We have to effectively reopen the printer, */
100 	    /* because the Watcom library does \n -> \r\n */
101 	    /* substitution on the stdprn stream. */
102 	    int fno = dup(fileno(stdprn));
103 
104 	    setmode(fno, O_BINARY);
105 	    gs_stdprn = fdopen(fno, "wb");
106 	}
107 	pfile = gs_stdprn;
108 #else	/* WATCOM doesn't know about stdprn device */
109 	pfile = fopen("PRN", (binary_mode ? "wb" : "w"));
110 	if (pfile == NULL)
111 	    return NULL;
112 #endif	/* defined(stdprn) */
113     } else {
114 	pfile = fopen(fname, (binary_mode ? "wb" : "w"));
115 	if (pfile == NULL)
116 	    return NULL;
117     }
118     gp_set_file_binary(fileno(pfile), binary_mode);
119     return pfile;
120 }
121 
122 /* Close the connection to the printer. */
123 void
gp_close_printer(FILE * pfile,const char * fname)124 gp_close_printer(FILE * pfile, const char *fname)
125 {
126 #ifdef stdprn
127     if (pfile != stdprn)
128 #endif	/* defined(stdprn) */
129 	fclose(pfile);
130     if (pfile == gs_stdprn)
131 	gs_stdprn = 0;
132 }
133 
134 /* ------ File naming and accessing ------ */
135 
136 /* Create and open a scratch file with a given name prefix. */
137 /* Write the actual file name at fname. */
138 FILE *
gp_open_scratch_file(const char * prefix,char * fname,const char * mode)139 gp_open_scratch_file(const char *prefix, char *fname, const char *mode)
140 {	      /* The -7 is for XXXXXXX */
141     int prefix_length = strlen(prefix);
142     int len = gp_file_name_sizeof - prefix_length - 7;
143     FILE *f;
144 
145     if (gp_file_name_is_absolute(prefix, prefix_length) ||
146 	gp_gettmpdir(fname, &len) != 0
147 	)
148 	*fname = 0;
149     else {
150 	char *temp;
151 
152 	/* Prevent X's in path from being converted by mktemp. */
153 	for (temp = fname; *temp; temp++)
154 	    *temp = tolower(*temp);
155 	if (strlen(fname) && (fname[strlen(fname) - 1] != '\\'))
156 	    strcat(fname, "\\");
157     }
158     if (strlen(fname) + prefix_length + 7 >= gp_file_name_sizeof)
159 	return 0;		/* file name too long */
160     strcat(fname, prefix);
161     strcat(fname, "XXXXXX");
162     mktemp(fname);
163     f = gp_fopentemp(fname, mode);
164     if (f == NULL)
165 	eprintf1("**** Could not open temporary file %s\n", fname);
166     return f;
167 }
168 
169 
170 /* Open a file with the given name, as a stream of uninterpreted bytes. */
171 FILE *
gp_fopen(const char * fname,const char * mode)172 gp_fopen(const char *fname, const char *mode)
173 {
174     return fopen(fname, mode);
175 }
176 
177 /* ------ Font enumeration ------ */
178 
179  /* This is used to query the native os for a list of font names and
180   * corresponding paths. The general idea is to save the hassle of
181   * building a custom fontmap file.
182   */
183 
gp_enumerate_fonts_init(gs_memory_t * mem)184 void *gp_enumerate_fonts_init(gs_memory_t *mem)
185 {
186     return NULL;
187 }
188 
gp_enumerate_fonts_next(void * enum_state,char ** fontname,char ** path)189 int gp_enumerate_fonts_next(void *enum_state, char **fontname, char **path)
190 {
191     return 0;
192 }
193 
gp_enumerate_fonts_free(void * enum_state)194 void gp_enumerate_fonts_free(void *enum_state)
195 {
196 }
197 
198 /* --------- 64 bit file access ----------- */
199 /* fixme: Not implemented yet.
200  * Currently we stub it with 32 bits access.
201  */
202 
gp_fopen_64(const char * filename,const char * mode)203 FILE *gp_fopen_64(const char *filename, const char *mode)
204 {
205     return fopen(filename, mode);
206 }
207 
gp_open_scratch_file_64(const char * prefix,char fname[gp_file_name_sizeof],const char * mode)208 FILE *gp_open_scratch_file_64(const char *prefix,
209 			   char fname[gp_file_name_sizeof],
210 			   const char *mode)
211 {
212     return gp_open_scratch_file(prefix, fname, mode);
213 }
214 
gp_open_printer_64(char fname[gp_file_name_sizeof],int binary_mode)215 FILE *gp_open_printer_64(char fname[gp_file_name_sizeof], int binary_mode)
216 {
217     return gp_open_printer(fname, binary_mode);
218 }
219 
gp_ftell_64(FILE * strm)220 int64_t gp_ftell_64(FILE *strm)
221 {
222     return ftell(strm);
223 }
224 
gp_fseek_64(FILE * strm,int64_t offset,int origin)225 int gp_fseek_64(FILE *strm, int64_t offset, int origin)
226 {
227     long offset1 = (long)offset;
228 
229     if (offset != offset1)
230 	return -1;
231     return fseek(strm, offset1, origin);
232 }
233