Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/cmd/gs/src/gp_os2.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999, 2000 Aladdin Enterprises.  All rights reserved.
2
 
3
  This software is provided AS-IS with no warranty, either express or
4
  implied.
5
 
6
  This software is distributed under license and may not be copied,
7
  modified or distributed except as expressly authorized under the terms
8
  of the license contained in the file LICENSE in this distribution.
9
 
10
  For more information about licensing, please refer to
11
  http://www.ghostscript.com/licensing/. For information on
12
  commercial licensing, go to http://www.artifex.com/licensing/ or
13
  contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
  San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
*/
16
 
17
/* $Id: gp_os2.c,v 1.32 2004/09/27 21:14:00 ghostgum Exp $ */
18
/* Common platform-specific routines for OS/2 and MS-DOS */
19
/* compiled with GCC/EMX */
20
 
21
#define INCL_DOS
22
#define INCL_SPL
23
#define INCL_SPLDOSPRINT
24
#define INCL_SPLERRORS
25
#define INCL_BASE
26
#define INCL_ERRORS
27
#define INCL_WIN
28
#include <os2.h>
29
 
30
#include "pipe_.h"
31
#include "stdio_.h"
32
#include "string_.h"
33
#include <fcntl.h>
34
 
35
#ifdef __IBMC__
36
#define popen fopen		/* doesn't support popen */
37
#define pclose fclose		/* doesn't support pclose */
38
#else
39
#include <dos.h>
40
#endif
41
/* Define the regs union tag for short registers. */
42
#  define rshort x
43
#define intdos(a,b) _int86(0x21, a, b)
44
 
45
#include "memory_.h"
46
#include "string_.h"
47
#include "gx.h"
48
#include "gsexit.h"
49
#include "gsmemory.h"
50
#include "gsstruct.h"
51
#include "gp.h"
52
#include "gpmisc.h"
53
#include "gsutil.h"
54
#include "stdlib.h"		/* need _osmode, exit */
55
#include "time_.h"
56
#include <time.h>		/* should this be in time_.h? */
57
#include "gp_os2.h"
58
#include "gdevpm.h"
59
#ifdef __EMX__
60
#include <sys/emxload.h>
61
#endif
62
 
63
#if defined(__DLL__) && defined( __EMX__)
64
/* This isn't provided in any of the libraries */
65
/* We set this to the process environment in gp_init */
66
char *fake_environ[3] =
67
{"", NULL, NULL};
68
char **environ = fake_environ;
69
char **_environ = fake_environ;
70
HWND hwndtext = (HWND) NULL;
71
 
72
#endif
73
 
74
#ifdef __DLL__
75
/* use longjmp instead of exit when using DLL */
76
#include <setjmp.h>
77
extern jmp_buf gsdll_env;
78
 
79
#endif
80
 
81
#ifdef __DLL__
82
#define isos2 TRUE
83
#else
84
#define isos2 (_osmode == OS2_MODE)
85
#endif
86
char pm_prntmp[256];		/* filename of printer spool temporary file */
87
 
88
 
89
/* ------ Miscellaneous ------ */
90
 
91
/* Get the string corresponding to an OS error number. */
92
/* All reasonable compilers support it. */
93
const char *
94
gp_strerror(int errnum)
95
{
96
    return strerror(errnum);
97
}
98
 
99
/* use Unix version for date and time */
100
/* ------ Date and time ------ */
101
 
102
/* Read the current time (in seconds since Jan. 1, 1970) */
103
/* and fraction (in nanoseconds since midnight). */
104
void
105
gp_get_realtime(long *pdt)
106
{
107
    struct timeval tp;
108
    struct timezone tzp;
109
 
110
    if (gettimeofday(&tp, &tzp) == -1) {
111
	lprintf("Ghostscript: gettimeofday failed!\n");
112
	tp.tv_sec = tp.tv_usec = 0;
113
    }
114
    /* tp.tv_sec is #secs since Jan 1, 1970 */
115
    pdt[0] = tp.tv_sec;
116
    pdt[1] = tp.tv_usec * 1000;
117
 
118
#ifdef DEBUG_CLOCK
119
    printf("tp.tv_sec = %d  tp.tv_usec = %d  pdt[0] = %ld  pdt[1] = %ld\n",
120
	   tp.tv_sec, tp.tv_usec, pdt[0], pdt[1]);
121
#endif
122
}
123
 
124
/* Read the current user CPU time (in seconds) */
125
/* and fraction (in nanoseconds).  */
126
void
127
gp_get_usertime(long *pdt)
128
{
129
    gp_get_realtime(pdt);	/* Use an approximation for now.  */
130
}
131
 
132
 
133
/* ------ Console management ------ */
134
 
135
/* Answer whether a given file is the console (input or output). */
136
/* This is not a standard gp procedure, */
137
/* but the MS Windows configuration needs it, */
138
/* and other MS-DOS configurations might need it someday. */
139
/* Don't know if it is needed for OS/2. */
140
bool
141
gp_file_is_console(FILE * f)
142
{
143
#ifndef __DLL__
144
    if (!isos2) {
145
	union REGS regs;
146
 
147
	if (f == NULL)
148
	    return false;
149
	regs.h.ah = 0x44;	/* ioctl */
150
	regs.h.al = 0;		/* get device info */
151
	regs.rshort.bx = fileno(f);
152
	intdos(&regs, &regs);
153
	return ((regs.h.dl & 0x80) != 0 && (regs.h.dl & 3) != 0);
154
    }
155
#endif
156
    if (fileno(f) <= 2)
157
	return true;
158
    return false;
159
}
160
 
161
/* ------ Persistent data cache ------*/
162
 
163
/* insert a buffer under a (type, key) pair */
164
int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen)
165
{ 
166
    /* not yet implemented */
167
    return 0;
168
} 
169
 
170
/* look up a (type, key) in the cache */
171
int gp_cache_query(int type, byte* key, int keylen, void **buffer,
172
    gp_cache_alloc alloc, void *userdata)
173
{
174
    /* not yet implemented */
175
    return -1;
176
}
177
 
178
/* ------ File naming and accessing ------ */
179
 
180
/* Define the character used for separating file names in a list. */
181
const char gp_file_name_list_separator = ';';
182
 
183
/* Define the default scratch file name prefix. */
184
const char gp_scratch_file_name_prefix[] = "gs";
185
 
186
/* Define the name of the null output file. */
187
const char gp_null_file_name[] = "nul";
188
 
189
/* Define the name that designates the current directory. */
190
const char gp_current_directory_name[] = ".";
191
 
192
/* Define the string to be concatenated with the file mode */
193
/* for opening files without end-of-line conversion. */
194
const char gp_fmode_binary_suffix[] = "b";
195
 
196
/* Define the file modes for binary reading or writing. */
197
const char gp_fmode_rb[] = "rb";
198
const char gp_fmode_wb[] = "wb";
199
 
200
/* ------ File enumeration ------ */
201
 
202
 
203
struct file_enum_s {
204
    FILEFINDBUF3 findbuf;
205
    HDIR hdir;
206
    char *pattern;
207
    int patlen;			/* orig pattern length */
208
    int pat_size;		/* allocate space for pattern */
209
    int head_size;		/* pattern length through last */
210
    /* :, / or \ */
211
    int first_time;
212
    gs_memory_t *memory;
213
};
214
gs_private_st_ptrs1(st_file_enum, struct file_enum_s, "file_enum",
215
		    file_enum_enum_ptrs, file_enum_reloc_ptrs, pattern);
216
 
217
/* Initialize an enumeration.  may NEED WORK ON HANDLING * ? \. */
218
file_enum *
219
gp_enumerate_files_init(const char *pat, uint patlen, gs_memory_t * mem)
220
{
221
    file_enum *pfen = gs_alloc_struct(mem, file_enum, &st_file_enum, "gp_enumerate_files");
222
    int pat_size = 2 * patlen + 1;
223
    char *pattern;
224
    int hsize = 0;
225
    int i;
226
 
227
    if (pfen == 0)
228
	return 0;
229
 
230
    /* pattern could be allocated as a string, */
231
    /* but it's simpler for GC and freeing to allocate it as bytes. */
232
 
233
    pattern = (char *)gs_alloc_bytes(mem, pat_size,
234
				     "gp_enumerate_files(pattern)");
235
    if (pattern == 0)
236
	return 0;
237
    memcpy(pattern, pat, patlen);
238
    /* find directory name = header */
239
    for (i = 0; i < patlen; i++) {
240
	switch (pat[i]) {
241
	    case '\\':
242
		if (i + 1 < patlen && pat[i + 1] == '\\')
243
		    i++;
244
		/* falls through */
245
	    case ':':
246
	    case '/':
247
		hsize = i + 1;
248
	}
249
    }
250
    pattern[patlen] = 0;
251
    pfen->pattern = pattern;
252
    pfen->patlen = patlen;
253
    pfen->pat_size = pat_size;
254
    pfen->head_size = hsize;
255
    pfen->memory = mem;
256
    pfen->first_time = 1;
257
    pfen->hdir = HDIR_CREATE;
258
    return pfen;
259
}
260
 
261
/* Enumerate the next file. */
262
uint
263
gp_enumerate_files_next(file_enum * pfen, char *ptr, uint maxlen)
264
{
265
    APIRET rc;
266
    ULONG cFilenames = 1;
267
 
268
    if (!isos2) {
269
	/* CAN'T DO IT SO JUST RETURN THE PATTERN. */
270
	if (pfen->first_time) {
271
	    char *pattern = pfen->pattern;
272
	    uint len = strlen(pattern);
273
 
274
	    pfen->first_time = 0;
275
	    if (len > maxlen)
276
		return maxlen + 1;
277
	    strcpy(ptr, pattern);
278
	    return len;
279
	}
280
	return -1;
281
    }
282
    /* else OS/2 */
283
    if (pfen->first_time) {
284
	rc = DosFindFirst(pfen->pattern, &pfen->hdir, FILE_NORMAL,
285
			  &pfen->findbuf, sizeof(pfen->findbuf),
286
			  &cFilenames, FIL_STANDARD);
287
	pfen->first_time = 0;
288
    } else {
289
	rc = DosFindNext(pfen->hdir, &pfen->findbuf, sizeof(pfen->findbuf),
290
			 &cFilenames);
291
    }
292
    if (rc)
293
	return -1;
294
 
295
    if (pfen->head_size + pfen->findbuf.cchName < maxlen) {
296
	memcpy(ptr, pfen->pattern, pfen->head_size);
297
	strcpy(ptr + pfen->head_size, pfen->findbuf.achName);
298
	return pfen->head_size + pfen->findbuf.cchName;
299
    }
300
    if (pfen->head_size >= maxlen)
301
	return 0;		/* no hope at all */
302
 
303
    memcpy(ptr, pfen->pattern, pfen->head_size);
304
    strncpy(ptr + pfen->head_size, pfen->findbuf.achName,
305
	    maxlen - pfen->head_size - 1);
306
    return maxlen;
307
}
308
 
309
/* Clean up the file enumeration. */
310
void
311
gp_enumerate_files_close(file_enum * pfen)
312
{
313
    gs_memory_t *mem = pfen->memory;
314
 
315
    if (isos2)
316
	DosFindClose(pfen->hdir);
317
    gs_free_object(mem, pfen->pattern,
318
		   "gp_enumerate_files_close(pattern)");
319
    gs_free_object(mem, pfen, "gp_enumerate_files_close");
320
}
321
 
322
/*************************************************************/
323
/* from gp_iwatc.c and gp_itbc.c */
324
 
325
/* Intel processor, EMX/GCC specific routines for Ghostscript */
326
#include <signal.h>
327
#include "stat_.h"
328
#include "string_.h"
329
 
330
/* Library routines not declared in a standard header */
331
/* extern char *getenv(const char *); */
332
 
333
/* Forward declarations */
334
private void handle_FPE(int);
335
 
336
/* Do platform-dependent initialization. */
337
void
338
gp_init(void)
339
{
340
#if defined(__DLL__) && defined(__EMX__)
341
    PTIB pptib;
342
    PPIB pppib;
343
    int i;
344
    char *p;
345
 
346
    /* get environment of EXE */
347
    DosGetInfoBlocks(&pptib, &pppib);
348
    for (i = 0, p = pppib->pib_pchenv; *p; p += strlen(p) + 1)
349
	i++;
350
    _environ = environ = (char **)malloc((i + 2) * sizeof(char *));
351
 
352
    for (i = 0, p = pppib->pib_pchenv; *p; p += strlen(p) + 1) {
353
	environ[i] = p;
354
	i++;
355
    }
356
    environ[i] = p;
357
    i++;
358
    environ[i] = NULL;
359
#endif
360
 
361
    /* keep gsos2.exe in memory for number of minutes specified in */
362
    /* environment variable GS_LOAD */
363
#ifdef __EMX__
364
    _emxload_env("GS_LOAD");
365
#endif
366
 
367
    /* Set up the handler for numeric exceptions. */
368
    signal(SIGFPE, handle_FPE);
369
}
370
 
371
 
372
/* Trap numeric exceptions.  Someday we will do something */
373
/* more appropriate with these. */
374
private void
375
handle_FPE(int sig)
376
{
377
    eprintf("Numeric exception:\n");
378
    exit(1);
379
}
380
 
381
/* Do platform-dependent cleanup. */
382
void
383
gp_exit(int exit_status, int code)
384
{
385
#if defined(__DLL__) && defined(__EMX__)
386
    if (environ != fake_environ) {
387
	free(environ);
388
	environ = _environ = fake_environ;
389
    }
390
#endif
391
}
392
 
393
/* Exit the program. */
394
void
395
gp_do_exit(int exit_status)
396
{
397
    exit(exit_status);
398
}
399
 
400
/* ------ Printer accessing ------ */
401
private int is_os2_spool(const char *queue);
402
 
403
/* Put a printer file (which might be stdout) into binary or text mode. */
404
/* This is not a standard gp procedure, */
405
/* but all MS-DOS configurations need it. */
406
void
407
gp_set_file_binary(int prnfno, int binary)
408
{
409
#ifndef __IBMC__
410
    union REGS regs;
411
 
412
    regs.h.ah = 0x44;		/* ioctl */
413
    regs.h.al = 0;		/* get device info */
414
    regs.rshort.bx = prnfno;
415
    intdos(&regs, &regs);
416
    if (((regs.rshort.flags) & 1) != 0 || !(regs.h.dl & 0x80))
417
	return;			/* error, or not a device */
418
    if (binary)
419
	regs.h.dl |= 0x20;	/* binary (no ^Z intervention) */
420
    else
421
	regs.h.dl &= ~0x20;	/* text */
422
    regs.h.dh = 0;
423
    regs.h.ah = 0x44;		/* ioctl */
424
    regs.h.al = 1;		/* set device info */
425
    intdos(&regs, &regs);
426
#endif
427
}
428
 
429
/* Open a connection to a printer.  A null file name means use the */
430
/* standard printer connected to the machine, if any. */
431
/* Return NULL if the connection could not be opened. */
432
/* filename can be one of the following values
433
 *   ""                Spool in default queue
434
 *   "\\spool\queue"   Spool in "queue"
435
 *   "|command"        open an output pipe using popen()
436
 *   "filename"        open filename using fopen()
437
 *   "port"            open port using fopen()
438
 */
439
FILE *
440
gp_open_printer(char fname[gp_file_name_sizeof], int binary_mode)
441
{
442
    FILE *pfile;
443
 
444
    if ((strlen(fname) == 0) || is_os2_spool(fname)) {
445
	if (isos2) {
446
	    /* default or spool */
447
	    if (pm_spool(NULL, fname))	/* check if spool queue valid */
448
		return NULL;
449
	    pfile = gp_open_scratch_file(gp_scratch_file_name_prefix,
450
				     pm_prntmp, (binary_mode ? "wb" : "w"));
451
	} else
452
	    pfile = fopen("PRN", (binary_mode ? "wb" : "w"));
453
    } else if ((isos2) && (fname[0] == '|'))
454
	/* pipe */
455
	pfile = popen(fname + 1, (binary_mode ? "wb" : "w"));
456
    else
457
	/* normal file or port */
458
	pfile = fopen(fname, (binary_mode ? "wb" : "w"));
459
 
460
    if (pfile == (FILE *) NULL)
461
	return (FILE *) NULL;
462
    if (!isos2)
463
	gp_set_file_binary(fileno(pfile), binary_mode);
464
    return pfile;
465
}
466
 
467
/* Close the connection to the printer. */
468
void
469
gp_close_printer(FILE * pfile, const char *fname)
470
{
471
    if (isos2 && (fname[0] == '|'))
472
	pclose(pfile);
473
    else
474
	fclose(pfile);
475
 
476
    if ((strlen(fname) == 0) || is_os2_spool(fname)) {
477
	/* spool temporary file */
478
	pm_spool(pm_prntmp, fname);
479
	unlink(pm_prntmp);
480
    }
481
}
482
 
483
/* ------ File accessing -------- */
484
 
485
/* Set a file into binary or text mode. */
486
int
487
gp_setmode_binary(FILE * pfile, bool binary)
488
{
489
    gp_set_file_binary(fileno(pfile), binary);
490
    return 0;
491
}
492
 
493
/* ------ Printer Spooling ------ */
494
#ifndef NERR_BufTooSmall
495
#define NERR_BufTooSmall 2123	/* For SplEnumQueue */
496
#endif
497
 
498
/* If queue_name is NULL, list available queues */
499
/* If strlen(queue_name)==0, return default queue and driver name */
500
/* If queue_name supplied, return driver_name */
501
/* returns 0 if OK, non-zero for error */
502
int
503
pm_find_queue(char *queue_name, char *driver_name)
504
{
505
    SPLERR splerr;
506
    USHORT jobCount;
507
    ULONG cbBuf;
508
    ULONG cTotal;
509
    ULONG cReturned;
510
    ULONG cbNeeded;
511
    ULONG ulLevel;
512
    ULONG i;
513
    PSZ pszComputerName;
514
    PBYTE pBuf;
515
    PPRQINFO3 prq;
516
 
517
    ulLevel = 3L;
518
    pszComputerName = (PSZ) NULL;
519
    splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, 0L,	/* cbBuf */
520
			  &cReturned, &cTotal,
521
			  &cbNeeded, NULL);
522
    if (splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall) {
523
	if (!DosAllocMem((PVOID) & pBuf, cbNeeded,
524
			 PAG_READ | PAG_WRITE | PAG_COMMIT)) {
525
	    cbBuf = cbNeeded;
526
	    splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, cbBuf,
527
				  &cReturned, &cTotal,
528
				  &cbNeeded, NULL);
529
	    if (splerr == NO_ERROR) {
530
		/* Set pointer to point to the beginning of the buffer.           */
531
		prq = (PPRQINFO3) pBuf;
532
 
533
		/* cReturned has the count of the number of PRQINFO3 structures.  */
534
		for (i = 0; i < cReturned; i++) {
535
		    if (queue_name) {
536
			/* find queue name and return driver name */
537
			if (strlen(queue_name) == 0) {	/* use default queue */
538
			    if (prq->fsType & PRQ3_TYPE_APPDEFAULT)
539
				strcpy(queue_name, prq->pszName);
540
			}
541
			if (strcmp(prq->pszName, queue_name) == 0) {
542
			    char *p;
543
 
544
			    for (p = prq->pszDriverName; *p && (*p != '.'); p++)
545
				/* do nothing */ ;
546
			    *p = '\0';	/* truncate at '.' */
547
			    if (driver_name != NULL)
548
				strcpy(driver_name, prq->pszDriverName);
549
			    DosFreeMem((PVOID) pBuf);
550
			    return 0;
551
			}
552
		    } else {
553
			/* list queue details */
554
			if (prq->fsType & PRQ3_TYPE_APPDEFAULT)
555
			    eprintf1("  \042%s\042  (DEFAULT)\n", prq->pszName);
556
			else
557
			    eprintf1("  \042%s\042\n", prq->pszName);
558
		    }
559
		    prq++;
560
		}		/*endfor cReturned */
561
	    }
562
	    DosFreeMem((PVOID) pBuf);
563
	}
564
    }
565
    /* end if Q level given */ 
566
    else {
567
	/* If we are here we had a bad error code. Print it and some other info. */
568
	eprintf4("SplEnumQueue Error=%ld, Total=%ld, Returned=%ld, Needed=%ld\n",
569
		splerr, cTotal, cReturned, cbNeeded);
570
    }
571
    if (splerr)
572
	return splerr;
573
    if (queue_name)
574
	return -1;
575
    return 0;
576
}
577
 
578
 
579
/* return TRUE if queue looks like a valid OS/2 queue name */
580
private int
581
is_os2_spool(const char *queue)
582
{
583
    char *prefix = "\\\\spool\\";	/* 8 characters long */
584
    int i;
585
 
586
    for (i = 0; i < 8; i++) {
587
	if (prefix[i] == '\\') {
588
	    if ((*queue != '\\') && (*queue != '/'))
589
		return FALSE;
590
	} else if (tolower(*queue) != prefix[i])
591
	    return FALSE;
592
	queue++;
593
    }
594
    return TRUE;
595
}
596
 
597
#define PRINT_BUF_SIZE 16384
598
 
599
/* Spool file to queue */
600
/* return 0 if successful, non-zero if error */
601
/* if filename is NULL, return 0 if spool queue is valid, non-zero if error */
602
int
603
pm_spool(char *filename, const char *queue)
604
{
605
    HSPL hspl;
606
    PDEVOPENSTRUC pdata;
607
    PSZ pszToken = "*";
608
    ULONG jobid;
609
    BOOL rc;
610
    char queue_name[256];
611
    char driver_name[256];
612
    char *buffer;
613
    FILE *f;
614
    int count;
615
 
616
    if (strlen(queue) != 0) {
617
	/* queue specified */
618
	strcpy(queue_name, queue + 8);	/* skip over \\spool\ */
619
    } else {
620
	/* get default queue */
621
	queue_name[0] = '\0';
622
    }
623
    if (pm_find_queue(queue_name, driver_name)) {
624
	/* error, list valid queue names */
625
	eprintf("Invalid queue name.  Use one of:\n");
626
	pm_find_queue(NULL, NULL);
627
	return 1;
628
    }
629
    if (!filename)
630
	return 0;		/* we were only asked to check the queue */
631
 
632
 
633
    if ((buffer = malloc(PRINT_BUF_SIZE)) == (char *)NULL) {
634
	eprintf("Out of memory in pm_spool\n");
635
	return 1;
636
    }
637
    if ((f = fopen(filename, "rb")) == (FILE *) NULL) {
638
	free(buffer);
639
	eprintf1("Can't open temporary file %s\n", filename);
640
	return 1;
641
    }
642
    /* Allocate memory for pdata */
643
    if (!DosAllocMem((PVOID) & pdata, sizeof(DEVOPENSTRUC),
644
		     (PAG_READ | PAG_WRITE | PAG_COMMIT))) {
645
	/* Initialize elements of pdata */
646
	pdata->pszLogAddress = queue_name;
647
	pdata->pszDriverName = driver_name;
648
	pdata->pdriv = NULL;
649
	pdata->pszDataType = "PM_Q_RAW";
650
	pdata->pszComment = "Ghostscript";
651
	pdata->pszQueueProcName = NULL;
652
	pdata->pszQueueProcParams = NULL;
653
	pdata->pszSpoolerParams = NULL;
654
	pdata->pszNetworkParams = NULL;
655
 
656
	hspl = SplQmOpen(pszToken, 4L, (PQMOPENDATA) pdata);
657
	if (hspl == SPL_ERROR) {
658
	    eprintf("SplQmOpen failed.\n");
659
	    DosFreeMem((PVOID) pdata);
660
	    free(buffer);
661
	    fclose(f);
662
	    return 1;		/* failed */
663
	}
664
	rc = SplQmStartDoc(hspl, "Ghostscript");
665
	if (!rc) {
666
	    eprintf("SplQmStartDoc failed.\n");
667
	    DosFreeMem((PVOID) pdata);
668
	    free(buffer);
669
	    fclose(f);
670
	    return 1;
671
	}
672
	/* loop, copying file to queue */
673
	while (rc && (count = fread(buffer, 1, PRINT_BUF_SIZE, f)) != 0) {
674
	    rc = SplQmWrite(hspl, count, buffer);
675
	    if (!rc)
676
		eprintf("SplQmWrite failed.\n");
677
	}
678
	free(buffer);
679
	fclose(f);
680
 
681
	if (!rc) {
682
	    eprintf("Aborting Spooling.\n");
683
	    SplQmAbort(hspl);
684
	} else {
685
	    SplQmEndDoc(hspl);
686
	    rc = SplQmClose(hspl);
687
	    if (!rc)
688
		eprintf("SplQmClose failed.\n");
689
	}
690
    } else
691
	rc = 0;			/* no memory */
692
    return !rc;
693
}
694
 
695
/* ------ File naming and accessing ------ */
696
 
697
/* Create and open a scratch file with a given name prefix. */
698
/* Write the actual file name at fname. */
699
FILE *
700
gp_open_scratch_file(const char *prefix, char fname[gp_file_name_sizeof],
701
		     const char *mode)
702
{
703
    FILE *f;
704
#ifdef __IBMC__
705
    char *temp = 0;
706
    char *tname;
707
    int prefix_length = strlen(prefix);
708
 
709
    if (!gp_file_name_is_absolute(prefix, prefix_length)) {
710
	temp = getenv("TMPDIR");
711
	if (temp == 0)
712
	    temp = getenv("TEMP");
713
    }
714
    *fname = 0;
715
    tname = _tempnam(temp, (char *)prefix);
716
    if (tname) {
717
	if (strlen(tname) > gp_file_name_sizeof - 1) {
718
	    free(tname);
719
	    return 0;		/* file name too long */
720
	}
721
	strcpy(fname, tname);
722
	free(tname);
723
    }
724
#else
725
    /* The -7 is for XXXXXX plus a possible final \. */
726
    int prefix_length = strlen(prefix);
727
    int len = gp_file_name_sizeof - prefix_length - 7;
728
 
729
    if (gp_file_name_is_absolute(prefix, prefix_length) ||
730
	gp_gettmpdir(fname, &len) != 0)
731
	*fname = 0;
732
    else {
733
	char last = '\\';
734
	char *temp;
735
 
736
	/* Prevent X's in path from being converted by mktemp. */
737
	for (temp = fname; *temp; temp++)
738
	    *temp = last = tolower(*temp);
739
	switch (last) {
740
	default:
741
	    strcat(fname, "\\");
742
	case ':':
743
	case '\\':
744
	    ;
745
	}
746
    }
747
    if (strlen(fname) + prefix_length + 7 >= gp_file_name_sizeof)
748
	return 0;		/* file name too long */
749
    strcat(fname, prefix);
750
    strcat(fname, "XXXXXX");
751
    mktemp(fname);
752
#endif
753
    f = gp_fopentemp(fname, mode);
754
    if (f == NULL)
755
	eprintf1("**** Could not open temporary file %s\n", fname);
756
    return f;
757
}
758
 
759
/* Open a file with the given name, as a stream of uninterpreted bytes. */
760
FILE *
761
gp_fopen(const char *fname, const char *mode)
762
{
763
    return fopen(fname, mode);
764
}
765
 
766
/* -------------- Helpers for gp_file_name_combine_generic ------------- */
767
 
768
uint gp_file_name_root(const char *fname, uint len)
769
{   int i = 0;
770
 
771
    if (len == 0)
772
	return 0;
773
    if (len > 1 && fname[0] == '\\' && fname[1] == '\\') {
774
	/* A network path: "\\server\share\" */
775
	int k = 0;
776
 
777
	for (i = 2; i < len; i++)
778
	    if (fname[i] == '\\' || fname[i] == '/')
779
		if (k++) {
780
		    i++;
781
		    break;
782
		}
783
    } else if (fname[0] == '/' || fname[0] == '\\') {
784
	/* Absolute with no drive. */
785
	i = 1;
786
    } else if (len > 1 && fname[1] == ':') {
787
	/* Absolute with a drive. */
788
	i = (len > 2 && (fname[2] == '/' || fname[2] == '\\') ? 3 : 2);
789
    }
790
    return i;
791
}
792
 
793
uint gs_file_name_check_separator(const char *fname, int len, const char *item)
794
{   if (len > 0) {
795
	if (fname[0] == '/' || fname[0] == '\\')
796
	    return 1;
797
    } else if (len < 0) {
798
	if (fname[-1] == '/' || fname[-1] == '\\')
799
	    return 1;
800
    }
801
    return 0;
802
}
803
 
804
bool gp_file_name_is_parent(const char *fname, uint len)
805
{   return len == 2 && fname[0] == '.' && fname[1] == '.';
806
}
807
 
808
bool gp_file_name_is_current(const char *fname, uint len)
809
{   return len == 1 && fname[0] == '.';
810
}
811
 
812
const char *gp_file_name_separator(void)
813
{   return "/";
814
}
815
 
816
const char *gp_file_name_directory_separator(void)
817
{   return "/";
818
}
819
 
820
const char *gp_file_name_parent(void)
821
{   return "..";
822
}
823
 
824
const char *gp_file_name_current(void)
825
{   return ".";
826
}
827
 
828
bool gp_file_name_is_partent_allowed(void)
829
{   return true;
830
}
831
 
832
bool gp_file_name_is_empty_item_meanful(void)
833
{   return false;
834
}
835
 
836
gp_file_name_combine_result
837
gp_file_name_combine(const char *prefix, uint plen, const char *fname, uint flen, 
838
		    bool no_sibling, char *buffer, uint *blen)
839
{
840
    return gp_file_name_combine_generic(prefix, plen, 
841
	    fname, flen, no_sibling, buffer, blen);
842
}
843
 
844
/* ------ Font enumeration ------ */
845
 
846
 /* This is used to query the native os for a list of font names and
847
  * corresponding paths. The general idea is to save the hassle of
848
  * building a custom fontmap file.
849
  */
850
 
851
void *gp_enumerate_fonts_init(gs_memory_t *mem)
852
{
853
    return NULL;
854
}
855
 
856
int gp_enumerate_fonts_next(void *enum_state, char **fontname, char **path)
857
{
858
    return 0;
859
}
860
 
861
void gp_enumerate_fonts_free(void *enum_state)
862
{
863
}