133295Skarels #ifndef lint
233295Skarels static char Notice[] = "Copyright (c) 1985 Adobe Systems Incorporated";
3*40201Skarels static char *RCSID = "$Header: enscript.c,v 1.7 89/03/12 01:31:55 van Exp $";
4*40201Skarels 
533295Skarels #endif
6*40201Skarels /*
7*40201Skarels  * enscript.c
833295Skarels  *
9*40201Skarels  * Copyright (c) 1985 Adobe Systems Incorporated
1033295Skarels  *
11*40201Skarels  * inspired by Gosling's cz there have been major overhauls, but the input
12*40201Skarels  * language is the same: new widths format generate PostScript (much easier
13*40201Skarels  * than Press) new and renamed switches (to match 4.2bsd lpr spooler) obeys
14*40201Skarels  * PostScript comment conventions doesn't worry so much about fonts
15*40201Skarels  * (everything is scalable and rotatable, use PS font names, no face
16*40201Skarels  * properties)
1733295Skarels  *
18*40201Skarels  * enscript generates POSTSCRIPT print files of a special kind the coordinate
19*40201Skarels  * system is in 20ths of a point. (1440 per inch)
2033295Skarels  *
21*40201Skarels  * Edit History: Andrew Shore: Mon Nov 18 14:05:05 1985 End Edit History.
2233295Skarels  *
23*40201Skarels  * RCSLOG: $Log:	enscript.c,v $
24*40201Skarels  * Revision 1.7  89/03/12  01:31:55  van
25*40201Skarels  * we have to escape special chars in title strings.
2633295Skarels  *
27*40201Skarels  * Revision 1.6  89/03/10  00:30:39  van
28*40201Skarels  * might as well let the user change everything.
2933295Skarels  *
30*40201Skarels  * Revision 1.5  89/03/09  23:19:17  van
31*40201Skarels  * gcc lint.
3233295Skarels  *
33*40201Skarels  * Revision 1.4  89/03/09  23:08:50  van
34*40201Skarels  * let user set the fonts used in 'gaudy' mode
35*40201Skarels  *
36*40201Skarels  * Revision 1.3  88/03/06  17:23:58  leres
37*40201Skarels  * Fix logic bug; only spool output if that's want we want.
38*40201Skarels  *
39*40201Skarels  * Revision 1.2  86/07/03  00:06:31  van
40*40201Skarels  * reformatted.  removed SYSV ifdefs.
41*40201Skarels  *  Revision 1.1  86/07/03  00:03:12  van Initial
42*40201Skarels  * revision
4333295Skarels  *
44*40201Skarels  * Revision 2.1  85/11/24  11:48:55  shore Product Release 2.0
45*40201Skarels  *
46*40201Skarels  * Revision 1.3  85/11/20  00:10:01  shore Added System V support (input options
47*40201Skarels  * and spooling) margins/linecount reworked (Dataproducts) incompatible
48*40201Skarels  * options changes, getopt! Guy Riddle's Gaudy mode and other changes output
49*40201Skarels  * spooling messages, pages, copies
50*40201Skarels  *
51*40201Skarels  * Revision 1.2  85/05/14  11:22:14  shore *** empty log message ***
52*40201Skarels  *
53*40201Skarels  *
5433295Skarels  */
5533295Skarels 
5633295Skarels #define POSTSCRIPTPRINTER "PostScript"
5733295Skarels 
5833295Skarels #define BODYROMAN "Courier"
5933295Skarels #define HEADFONT "Courier-Bold"
60*40201Skarels #define SHEADFONT "Times-Bold"
61*40201Skarels #define PGNUMFONT "Helvetica-Bold"
62*40201Skarels #define DATEFONT "Times-Bold"
6333295Skarels 
6433295Skarels #ifdef DEBUG
6533295Skarels #define debugp(x) {fprintf x ; VOIDC fflush(stderr);}
6633295Skarels #else
6733295Skarels #define debugp(x)
6833295Skarels #endif
6933295Skarels 
7033295Skarels #define UperInch (1440L)
7133295Skarels #define PtsPerInch 72
7233295Skarels #define UperPt 20
7333295Skarels 
7433295Skarels /* virtual page is 8 x 10.5 inches (for Toshiba compat) */
7533295Skarels #define PageWidth ((long) UperInch*8)
7633295Skarels #define PageLength ((long)((UperInch*21)/2))
7733295Skarels 
78*40201Skarels /* #define PageLength ((long) ((long) (UperInch*(8*11-3)))/8) */
79*40201Skarels /* #define PageWidth  ((long) ((long) (UperInch*(8*17-3)))/8) */
8033295Skarels 
8133295Skarels /* true page is 8.5 x 11 inches */
8233295Skarels #define TruePageWidth  (UperInch*17/2)
8333295Skarels #define TruePageLength ((long)(UperInch*11))
8433295Skarels 
8533295Skarels #include <stdio.h>
8633295Skarels #include <ctype.h>
8733295Skarels #include <pwd.h>
8833295Skarels #include <strings.h>
8933295Skarels #include <sys/time.h>
9033295Skarels #include <signal.h>
9133295Skarels #include <sys/types.h>
9233295Skarels #include <sys/stat.h>
9333295Skarels #include "transcript.h"
9433295Skarels 
9533295Skarels #define LPR "lpr"
9633295Skarels 
97*40201Skarels #define MAXBAD 20		/* number of bad chars to pass before
98*40201Skarels 				 * complaint */
9933295Skarels 
10033295Skarels private struct stat S;
10133295Skarels 
102*40201Skarels extern double atof();
10333295Skarels extern char *optarg;		/* getopt current opt char */
10433295Skarels extern int optind;		/* getopt argv index */
10533295Skarels 
106*40201Skarels private VOID int1 ();
107*40201Skarels private FlushShow();
10833295Skarels 
10933295Skarels #define FSIZEMAX 256		/* number of chars per font */
11033295Skarels 
11133295Skarels /* the layout of a font information block */
11233295Skarels private struct font {
113*40201Skarels 	char    name[100];	/* PostScript font name */
114*40201Skarels 	int     dsize;		/* size */
115*40201Skarels 	int     Xwid[FSIZEMAX];	/* X widths for each character */
11633295Skarels };
11733295Skarels 
118*40201Skarels private struct font fonts[16];	/* 16 possible fonts at one time */
119*40201Skarels private int nf = 0;		/* number of fonts known about */
12033295Skarels 
12133295Skarels private int TabWidth = TruePageWidth / 10;	/* width of a tab */
122*40201Skarels private int BSWidth;		/* width of a backspace */
12333295Skarels 
12433295Skarels private long UperLine = UperInch / 7;
12533295Skarels private long UperHLine = UperInch / 7;
12633295Skarels 
12733295Skarels private char *prog;		/* program name argv[0] */
12833295Skarels private char *libdir;		/* place for prolog and widths files */
12933295Skarels private char *tempdir;		/* place for temp file */
13033295Skarels private char TempName[100];	/* name of temporary PostScript file */
13133295Skarels private char OutName[256] = "";	/* filename for disk output */
13233295Skarels private int PipeOut = FALSE;	/* output to stdout (-p -) */
13333295Skarels private int ListOmitted = FALSE;/* list omitted chars on the tty */
13433295Skarels private int BeQuiet = TRUE;	/* suppress stderr info messages */
13533295Skarels private int Gaudy = FALSE;	/* pretty bars along the top */
13633295Skarels private int LPTsimulate = FALSE;/* an lpt should be simulated */
13733295Skarels private int Lines = 0;		/* max lines per page */
13833295Skarels private int LinesLeft = 66;	/* lines left on page when in LPT mode */
13933295Skarels private int LineMax = 64;	/* ? */
14033295Skarels private int col;		/* column number on current line */
14133295Skarels private int SeenText = TRUE;	/* true if seen some text on this page */
14233295Skarels private int OutOnly = FALSE;	/* PS file only wanted */
14333295Skarels private int Rotated = FALSE;	/* pages to be rotated landscape */
14433295Skarels private int PreFeed = FALSE;	/* prefeed should be enabled */
14533295Skarels private int TwoColumn = FALSE;	/* two-column mode */
14633295Skarels private int FirstCol = TRUE;	/* we're printing column 1 */
14733295Skarels private int NoTitle = FALSE;	/* title line is suppressed */
14833295Skarels private int Cvted = FALSE;	/* converted a file to PS format */
14933295Skarels 
150*40201Skarels private int IgnoreGarbage = FALSE;	/* garbage should be ignored */
15133295Skarels private int SeenFile = FALSE;	/* a file has been processed */
15233295Skarels private int SeenFont = FALSE;	/* we've seen a font request */
153*40201Skarels private int ScannedFonts = FALSE;	/* we've scanned the font file */
15433295Skarels private char *FileName = 0;	/* name of file currently being PSed */
15533295Skarels private char *FileDate = 0;	/* last mod date of file being PSed */
15633295Skarels private char DateStr[27];	/* thanks, but no thanks ctime! */
157*40201Skarels private int spoolNoBurst = FALSE;	/* no break page flag for spooler */
15833295Skarels 
15933295Skarels #ifdef BSD
16033295Skarels private char *spoolJobClass = NULL;
16133295Skarels private char *spoolJobName = NULL;
162*40201Skarels 
16333295Skarels #endif
16433295Skarels private char *PrinterName = NULL;
16533295Skarels private int spoolNotify = 0;
16633295Skarels private char *spoolCopies = "1";
16733295Skarels 
16833295Skarels private char tempstr[256];	/* various path names */
16933295Skarels 
17033295Skarels private int CurFont;		/* current Font */
171*40201Skarels private int fontindex[26];	/* table of fonts, indexed by font designator
172*40201Skarels 				 * ('a' to 'z') */
173*40201Skarels 
17433295Skarels /* indexes for default fonts */
17533295Skarels 
17633295Skarels #define Roman fontindex['r'-'a']
17733295Skarels #define HeaderFont fontindex['h'-'a']
178*40201Skarels #define SHeaderFont fontindex['i'-'a']
179*40201Skarels #define DateFont fontindex['j'-'a']
180*40201Skarels #define PgNumFont fontindex['k'-'a']
18133295Skarels 
18233295Skarels private long cX, cY;		/* current page positions */
18333295Skarels private long dX, dY;		/* desired page positions */
18433295Skarels private long lX, lY;		/* page positions of the start of the line */
18533295Skarels private long crX, crY;		/* X and Y increments to apply to CR's */
18633295Skarels private long maxX;		/* maximum x coord on line */
18733295Skarels private long minY;		/* minimum y coord on page */
188*40201Skarels private long Xoffset;		/* amount to offset left margin */
18933295Skarels 
19033295Skarels #define None	0
19133295Skarels #define RelX	1
19233295Skarels #define	RelY	2
19333295Skarels #define RelXY	3
19433295Skarels #define AbsX	4
19533295Skarels #define AbsY	8
19633295Skarels #define AbsXY	12
19733295Skarels 
19833295Skarels private int movepending;	/* moveto pending coords on stack */
19933295Skarels private int showpending;	/* number of characters waiting to be shown */
200*40201Skarels private int pagepending;	/* start on next page when have something to
201*40201Skarels 				 * print */
202*40201Skarels private char *UsersHeader = NULL;	/* user specified heading */
20333295Skarels private char *Header = NULL;	/* generated header (usually FileName) */
20433295Skarels private int Page = 0;		/* current page number */
20533295Skarels private int TotalPages = 0;	/* total number of pages printed */
20633295Skarels private int TruncChars = 0;	/* number of characters truncated */
207*40201Skarels private int UndefChars = 0;	/* number of characters skipped because they
208*40201Skarels 				 * weren't defined in some font */
209*40201Skarels private int BadChars = 0;	/* number of bad characters seen so far */
21033295Skarels private FILE *OutFile = NULL;	/* output ps file */
21133295Skarels 
21233295Skarels 
21333295Skarels /* decode a fontname string - e.g. Courier10 Helvetica-Bold12 */
214*40201Skarels private
215*40201Skarels decodefont (name, f)
216*40201Skarels 	register char *name;
217*40201Skarels 	register struct font *f;
218*40201Skarels {
219*40201Skarels 	register char *d, *p;
22033295Skarels 
221*40201Skarels 	SeenFont = TRUE;
222*40201Skarels 	p = name;
223*40201Skarels 	d = f->name;
224*40201Skarels 	f->dsize = 0;
225*40201Skarels 	while (isascii (*p) && (isalpha (*p) || (*p == '-'))) {
226*40201Skarels 		*d++ = *p++;
227*40201Skarels 	}
228*40201Skarels 	*d++ = '\0';
229*40201Skarels 	while (isascii (*p) && isdigit (*p)) {
230*40201Skarels 		f->dsize = f->dsize * 10 + *p++ - '0';
231*40201Skarels 	}
232*40201Skarels 	if (*p || !f->dsize || !f->name[0]) {
233*40201Skarels 		fprintf (stderr, "%s: poorly formed font name & size: \"%s\"\n",
234*40201Skarels 			 prog, name);
235*40201Skarels 		exit (1);
236*40201Skarels 	}
23733295Skarels }
238*40201Skarels 
239*40201Skarels 
24033295Skarels #define NOTDEF 0x8000
24133295Skarels #define ForAllFonts(p) for(p = &fonts[nf-1]; p >= &fonts[0]; p--)
24233295Skarels 
24333295Skarels 
244*40201Skarels /*
245*40201Skarels  * Scan the font metrics directory looking for entries that match the entries
246*40201Skarels  * in ``fonts''.  For entries that are found the data in the font description
247*40201Skarels  * is filled in, if any are missing, it dies horribly.
24833295Skarels  */
249*40201Skarels private VOID ScanFont ()
250*40201Skarels {
251*40201Skarels 	register struct font *f;
252*40201Skarels 	register FILE *FontData;/* afm file */
253*40201Skarels 	char   *c;
254*40201Skarels 	int     ccode, cwidth, inChars;
255*40201Skarels 	char    FontFile[512];	/* afm file name */
256*40201Skarels 	char    afmbuf[BUFSIZ];
25733295Skarels 
25833295Skarels 
259*40201Skarels 	if (!SeenFont) {
260*40201Skarels 		if (Lines == 0)
261*40201Skarels 			Lines = 64;
262*40201Skarels 		if (Rotated && TwoColumn)
263*40201Skarels 			fonts[Roman].dsize = 7;
26433295Skarels 	}
265*40201Skarels 	/* loop through fonts, find and read metric entry in dir */
266*40201Skarels 	ForAllFonts (f) {
267*40201Skarels 		VOIDC   mstrcat (FontFile, libdir, "/", sizeof FontFile);
26833295Skarels 
269*40201Skarels 		VOIDC   mstrcat (FontFile, FontFile, f->name, sizeof FontFile);
270*40201Skarels 
271*40201Skarels 		VOIDC   mstrcat (FontFile, FontFile, ".afm", sizeof FontFile);
272*40201Skarels 
273*40201Skarels 		if ((FontData = fopen (FontFile, "r")) == NULL) {
274*40201Skarels 			fprintf (stderr, "%s: can't open font metrics file %s\n",
275*40201Skarels 				 prog, FontFile);
276*40201Skarels 			exit (1);
27733295Skarels 		}
278*40201Skarels 		/* read the .afm file to get the widths */
279*40201Skarels 		for (ccode = 0; ccode < FSIZEMAX; ccode++)
280*40201Skarels 			f->Xwid[ccode] = NOTDEF;
281*40201Skarels 
282*40201Skarels 		inChars = 0;
283*40201Skarels 		while (fgets (afmbuf, sizeof afmbuf, FontData) != NULL) {
284*40201Skarels 			/* strip off newline */
285*40201Skarels 			if ((c = INDEX (afmbuf, '\n')) == 0) {
286*40201Skarels 				fprintf (stderr, "%s: AFM file %s line too long %s\n",
287*40201Skarels 					 prog, FontFile, afmbuf);
288*40201Skarels 				exit (1);
289*40201Skarels 			}
290*40201Skarels 			*c = '\0';
291*40201Skarels 			if (*afmbuf == '\0')
292*40201Skarels 				continue;
293*40201Skarels 			if (strcmp (afmbuf, "StartCharMetrics") == 0) {
294*40201Skarels 				inChars++;
295*40201Skarels 				continue;
296*40201Skarels 			}
297*40201Skarels 			if (strcmp (afmbuf, "EndCharMetrics") == 0)
298*40201Skarels 				break;
299*40201Skarels 			if (inChars == 1) {
300*40201Skarels 				if (sscanf (afmbuf, "C %d ; WX %d ;", &ccode, &cwidth) != 2) {
301*40201Skarels 					fprintf (stderr, "%s: trouble with AFM file %s\n",
302*40201Skarels 						 prog, FontFile);
303*40201Skarels 					exit (1);
304*40201Skarels 				}
305*40201Skarels 				/* get out once we see an unencoded char */
306*40201Skarels 				if (ccode == -1)
307*40201Skarels 					break;
308*40201Skarels 				if (ccode > 255)
309*40201Skarels 					continue;
310*40201Skarels 				f->Xwid[ccode] =
311*40201Skarels 					(short) (((long) cwidth * (long) f->dsize * (long) UperPt)
312*40201Skarels 						 / 1000L);
313*40201Skarels 				continue;
314*40201Skarels 			}
315*40201Skarels 		}
316*40201Skarels 		VOIDC   fclose (FontData);
31733295Skarels 	}
31833295Skarels 
319*40201Skarels 	TabWidth = fonts[Roman].Xwid['0'] * 8;	/* 8 * figure width */
320*40201Skarels 	BSWidth = fonts[Roman].Xwid[' '];	/* space width */
32133295Skarels 
322*40201Skarels 	UperLine = (fonts[Roman].dsize + 1) * UperPt;
32333295Skarels 
324*40201Skarels 	if (LPTsimulate) {
325*40201Skarels 		UperHLine = UperLine;
326*40201Skarels 		Lines = LineMax = 66;
327*40201Skarels 	} else {
328*40201Skarels 		UperHLine = (fonts[HeaderFont].dsize + 1) * UperPt;
329*40201Skarels 	}
33033295Skarels 
331*40201Skarels 	crX = 0;
332*40201Skarels 	crY = -UperLine;
33333295Skarels 
33433295Skarels }
33533295Skarels 
33633295Skarels 
337*40201Skarels /*
338*40201Skarels  * Return a font number for the font with the indicated name and size.  Adds
339*40201Skarels  * info to the font list for the eventual search.
34033295Skarels  */
341*40201Skarels private int
342*40201Skarels DefineFont (name, size)
343*40201Skarels 	char   *name;
344*40201Skarels {
345*40201Skarels 	register struct font *p;
346*40201Skarels 
347*40201Skarels 	p = &fonts[nf];
348*40201Skarels 	VOIDC   strcpy (p->name, name);
349*40201Skarels 
350*40201Skarels 	p->dsize = size;
351*40201Skarels 	return (nf++);
35233295Skarels }
35333295Skarels 
35433295Skarels 
35533295Skarels /* dump the fonts to the PS file for setup */
356*40201Skarels private VOID
357*40201Skarels DumpFonts ()
358*40201Skarels {
359*40201Skarels 	register struct font *f;
36033295Skarels 
361*40201Skarels 	ForAllFonts (f) {
362*40201Skarels 		fprintf (OutFile, "%d %d /%s\n", f - &fonts[0], f->dsize * UperPt, f->name);
363*40201Skarels 	}
364*40201Skarels 	fprintf (OutFile, "%d SetUpFonts\n", nf);
36533295Skarels }
36633295Skarels 
36733295Skarels /* add a shown character to the PS file */
368*40201Skarels private VOID
369*40201Skarels OUTputc (c)
370*40201Skarels 	register int c;
371*40201Skarels {
372*40201Skarels 	if (!showpending) {
373*40201Skarels 		putc ('(', OutFile);
374*40201Skarels 		showpending = TRUE;
375*40201Skarels 	}
376*40201Skarels 	if (c == '\\' || c == '(' || c == ')')
377*40201Skarels 		putc ('\\', OutFile);
378*40201Skarels 	if ((c > 0176) || (c < 040)) {
379*40201Skarels 		putc ('\\', OutFile);
380*40201Skarels 		putc ((c >> 6) + '0', OutFile);
381*40201Skarels 		putc (((c >> 3) & 07) + '0', OutFile);
382*40201Skarels 		putc ((c & 07) + '0', OutFile);
383*40201Skarels 	} else
384*40201Skarels 		putc (c, OutFile);
38533295Skarels }
38633295Skarels 
387*40201Skarels /* put a correctly escaped string to the PS file */
388*40201Skarels private VOID
389*40201Skarels OUTstr(s)
390*40201Skarels 	register char *s;
391*40201Skarels {
392*40201Skarels 	if (!showpending) {
393*40201Skarels 		putc ('(', OutFile);
394*40201Skarels 		showpending = TRUE;
395*40201Skarels 	}
396*40201Skarels 	while (*s)
397*40201Skarels 		OUTputc(*s++);
398*40201Skarels 
399*40201Skarels 	putc(')', OutFile);
400*40201Skarels 	showpending = FALSE;
401*40201Skarels }
402*40201Skarels 
40333295Skarels /* Set the current font */
404*40201Skarels private VOID
405*40201Skarels SetFont (f)
406*40201Skarels 	int     f;
407*40201Skarels {
408*40201Skarels 	FlushShow ();
409*40201Skarels 	CurFont = f;
410*40201Skarels 	fprintf (OutFile, "%d F\n", f);
41133295Skarels }
41233295Skarels 
413*40201Skarels /*
414*40201Skarels  * put a character onto the page at the desired X and Y positions. If the
415*40201Skarels  * current position doesn't agree with the desired position, put out movement
416*40201Skarels  * directives.  Leave the current position updated to account for the
417*40201Skarels  * character.
41833295Skarels  */
419*40201Skarels private VOID
420*40201Skarels ShowChar (c)
421*40201Skarels 	register int c;
422*40201Skarels {
423*40201Skarels 	register struct font *f;
424*40201Skarels 	register long nX, nY;
425*40201Skarels 	static  level = 0;
42633295Skarels 
427*40201Skarels 	level++;
428*40201Skarels 	f = &fonts[CurFont];
42933295Skarels 
430*40201Skarels 	if (f->Xwid[c] == NOTDEF) {
431*40201Skarels 		UndefChars++;
432*40201Skarels 		if (ListOmitted)
433*40201Skarels 			fprintf (stderr, "%s: \\%03o not found in font %s\n",
434*40201Skarels 				 prog, c, f->name);
435*40201Skarels 		if (level <= 1) {
436*40201Skarels 			ShowChar ('\\');
437*40201Skarels 			ShowChar ((c >> 6) + '0');
438*40201Skarels 			ShowChar (((c >> 3) & 07) + '0');
439*40201Skarels 			ShowChar ((c & 07) + '0');
440*40201Skarels 			col += 3;
441*40201Skarels 		}
442*40201Skarels 		level--;
443*40201Skarels 		return;
44433295Skarels 	}
445*40201Skarels 	nX = dX + f->Xwid[c];	/* resulting position after showing this char */
446*40201Skarels 	nY = dY;
44733295Skarels 
448*40201Skarels 	if (c != ' ' || ((cX == dX) && (cY == dY))) {
449*40201Skarels 		if (nX <= maxX) {
450*40201Skarels 			if (cX != dX) {
451*40201Skarels 				if (cY != dY) {
452*40201Skarels 					FlushShow ();
453*40201Skarels 					/* absolute x, relative y */
454*40201Skarels 					fprintf (OutFile, "%ld %ld", dX, dY);
455*40201Skarels 					movepending = AbsXY;
456*40201Skarels 				} else {
457*40201Skarels 					FlushShow ();
458*40201Skarels 					fprintf (OutFile, "%ld", dX - cX);	/* relative x */
459*40201Skarels 					movepending = RelX;
460*40201Skarels 				}
461*40201Skarels 			} else if (cY != dY) {
462*40201Skarels 				FlushShow ();
463*40201Skarels 				fprintf (OutFile, "%ld", dY - cY);	/* relative y */
464*40201Skarels 				movepending = RelY;
465*40201Skarels 			}
466*40201Skarels 			OUTputc (c);
467*40201Skarels 			showpending = TRUE;
468*40201Skarels 			cX = nX;
469*40201Skarels 			cY = nY;
470*40201Skarels 		} else
471*40201Skarels 			TruncChars++;
47233295Skarels 	}
473*40201Skarels 	dX = nX;
474*40201Skarels 	dY = nY;
47533295Skarels 
476*40201Skarels 	level--;
47733295Skarels }
47833295Skarels 
47933295Skarels /* put out a shown string to the PS file */
480*40201Skarels private VOID
481*40201Skarels ShowStr (s)
482*40201Skarels 	register char *s;
483*40201Skarels {
484*40201Skarels 	while (*s) {
485*40201Skarels 		if (*s >= 040)
486*40201Skarels 			ShowChar (*s);
487*40201Skarels 		s++;
488*40201Skarels 	}
48933295Skarels }
49033295Skarels 
49133295Skarels /* flush pending show */
492*40201Skarels private
493*40201Skarels FlushShow ()
494*40201Skarels {
495*40201Skarels 	if (showpending) {
496*40201Skarels 		putc (')', OutFile);
497*40201Skarels 		switch (movepending) {
498*40201Skarels 		case RelX:
499*40201Skarels 			putc ('X', OutFile);
500*40201Skarels 			break;
501*40201Skarels 		case RelY:
502*40201Skarels 			putc ('Y', OutFile);
503*40201Skarels 			break;
504*40201Skarels 		case AbsXY:
505*40201Skarels 			putc ('B', OutFile);
506*40201Skarels 			break;
507*40201Skarels 		case None:
508*40201Skarels 			putc ('S', OutFile);
509*40201Skarels 			break;
510*40201Skarels 		}
511*40201Skarels 		putc ('\n', OutFile);
512*40201Skarels 		movepending = None;
513*40201Skarels 		showpending = FALSE;
51433295Skarels 	}
51533295Skarels }
51633295Skarels 
51733295Skarels /* put out a page heading to the PS file */
518*40201Skarels private VOID
519*40201Skarels InitPage ()
520*40201Skarels {
521*40201Skarels 	char    header[200];
522*40201Skarels 	register int OldFont = CurFont;
52333295Skarels 
524*40201Skarels 	TotalPages++;
525*40201Skarels 	fprintf (OutFile, "%%%%Page: ? %d\n", TotalPages);
526*40201Skarels 	fprintf (OutFile, "StartPage\n");
527*40201Skarels 	SeenText = FALSE;
528*40201Skarels 	cX = cY = -1;
529*40201Skarels 	showpending = pagepending = FALSE;
530*40201Skarels 	FirstCol = TRUE;
531*40201Skarels 	if (Rotated) {
532*40201Skarels 		fprintf (OutFile, "Landscape\n");
533*40201Skarels 		lX = dX = UperInch / 4 + Xoffset;
534*40201Skarels 		lY = dY = PageLength - (UperHLine * 3) / 2;
535*40201Skarels 		maxX = TruePageLength;
536*40201Skarels 		/* minY = (PageLength - TruePageWidth) + 3*UperLine+480; */
537*40201Skarels 		minY = (TruePageLength - TruePageWidth) + (TruePageWidth - PageWidth) / 2;
538*40201Skarels 	} else {
539*40201Skarels 		lX = dX = Xoffset +
540*40201Skarels 			   (TwoColumn? (UperInch * 0.3) : ((UperInch * 5) / 8));
541*40201Skarels 		lY = dY = PageLength - UperHLine;
542*40201Skarels 		maxX = TruePageWidth;
543*40201Skarels 		minY = (UperInch / 4);	/* 0.25 inches */
544*40201Skarels 	}
545*40201Skarels 	movepending = None;
546*40201Skarels 	cX = dX;
547*40201Skarels 	cY = dY;
54833295Skarels 
549*40201Skarels 	if (!NoTitle) {
550*40201Skarels 		if (Gaudy) {
551*40201Skarels 			OUTstr(UsersHeader);
552*40201Skarels 			OUTstr(Header);
553*40201Skarels 			fprintf (OutFile, "[%s](%d)Gaudy\n", FileDate, ++Page);
554*40201Skarels 			cX = cY = 0;	/* force moveto here */
555*40201Skarels 		} else {
556*40201Skarels 			SetFont (HeaderFont);
557*40201Skarels 			fprintf (OutFile, "%ld %ld ", cX, cY);
558*40201Skarels 			movepending = AbsXY;
559*40201Skarels 			if (UsersHeader) {
560*40201Skarels 				if (*UsersHeader == 0) {
561*40201Skarels 					fprintf (OutFile, "()B\n");
562*40201Skarels 					movepending = None;
563*40201Skarels 					showpending = FALSE;
564*40201Skarels 				} else
565*40201Skarels 					ShowStr (UsersHeader);
566*40201Skarels 			} else {
567*40201Skarels 				VOIDC sprintf (header, "%s        %s        %d",
568*40201Skarels 					       Header? Header : "              ", FileDate, ++Page);
569*40201Skarels 
570*40201Skarels 				ShowStr (header);
571*40201Skarels 			}
572*40201Skarels 			FlushShow ();
57333295Skarels 		}
574*40201Skarels 		dX = lX = lX + crX * 2;
575*40201Skarels 		dY = lY = lY + crY * 2;
576*40201Skarels 	} else {
577*40201Skarels 		/* fake it to force a moveto */
578*40201Skarels 		cX = cY = 0;
57933295Skarels 	}
580*40201Skarels 	if (TwoColumn)
581*40201Skarels 		maxX = maxX / 2 - BSWidth;
582*40201Skarels 	else
583*40201Skarels 		maxX -= ((long) (UperInch * 0.3));
584*40201Skarels 	LineMax = (lY - minY) / (-crY);
585*40201Skarels 	if ((Lines <= 0) || (Lines > LineMax))
586*40201Skarels 		Lines = LinesLeft = LineMax;
587*40201Skarels 	else
588*40201Skarels 		LinesLeft = Lines;
589*40201Skarels 	SetFont (OldFont);
59033295Skarels }
59133295Skarels 
592*40201Skarels private VOID
593*40201Skarels ClosePage ()
594*40201Skarels {
595*40201Skarels 	FlushShow ();
596*40201Skarels 	if (!pagepending)
597*40201Skarels 		fprintf (OutFile, "EndPage\n");
598*40201Skarels 	pagepending = TRUE;
59933295Skarels }
60033295Skarels 
60133295Skarels /* skip to a new page */
602*40201Skarels private VOID
603*40201Skarels PageEject ()
604*40201Skarels {
605*40201Skarels 	if (TwoColumn && FirstCol) {
606*40201Skarels 		FirstCol = FALSE;
607*40201Skarels 		if (Rotated) {
608*40201Skarels 			lY = dY = PageLength - (UperHLine * 3) / 2;
609*40201Skarels 			lX = dX = Xoffset + TruePageLength / 2;
610*40201Skarels 			maxX = TruePageLength - UperInch * 0.3;
611*40201Skarels 		} else {
612*40201Skarels 			lY = dY = PageLength - UperHLine;
613*40201Skarels 			lX = dX = Xoffset + TruePageWidth / 2;
614*40201Skarels 			maxX = TruePageWidth - UperInch * 0.3;
615*40201Skarels 		}
616*40201Skarels 		if (!NoTitle) {
617*40201Skarels 			dX = lX = lX + crX * 2;
618*40201Skarels 			dY = lY = lY + crY * 2;
619*40201Skarels 		}
620*40201Skarels 	} else
621*40201Skarels 		ClosePage ();
622*40201Skarels 	LinesLeft = Lines;
623*40201Skarels 	SeenText = FALSE;
62433295Skarels }
62533295Skarels 
626*40201Skarels private VOID
627*40201Skarels CommentHeader ()
628*40201Skarels {
629*40201Skarels 	long    clock;
630*40201Skarels 	struct passwd *pswd;
631*40201Skarels 	char    hostname[40];
632*40201Skarels 
633*40201Skarels 	/* copy the file, prepending a new comment header */
634*40201Skarels 	fprintf (OutFile, "%%!%s\n", COMMENTVERSION);
635*40201Skarels 	fprintf (OutFile, "%%%%Creator: ");
636*40201Skarels 	pswd = getpwuid ((int) getuid ());
637*40201Skarels 	VOIDC   gethostname (hostname, (int) sizeof hostname);
638*40201Skarels 
639*40201Skarels 	fprintf (OutFile, "%s:%s (%s)\n", hostname, pswd->pw_name, pswd->pw_gecos);
640*40201Skarels 	fprintf (OutFile, "%%%%Title: %s\n", (FileName ? FileName : "stdin"));
641*40201Skarels 	fprintf (OutFile, "%%%%CreationDate: %s", (VOIDC time (&clock), ctime (&clock)));
64233295Skarels }
64333295Skarels 
64433295Skarels /* Copy the standard input file to the PS file */
645*40201Skarels private VOID
646*40201Skarels CopyFile ()
647*40201Skarels {
648*40201Skarels 	register int c;
64933295Skarels 
650*40201Skarels 	col = 1;
651*40201Skarels 	if (OutFile == 0) {
652*40201Skarels 		if (OutOnly) {
653*40201Skarels 			OutFile = PipeOut ? stdout : fopen (OutName, "w");
654*40201Skarels 		} else {
655*40201Skarels 			VOIDC   mktemp (mstrcat (TempName, tempdir,
656*40201Skarels 				            ENSCRIPTTEMP, sizeof TempName));
657*40201Skarels 			VOIDC   strcpy (OutName, TempName);
658*40201Skarels 
659*40201Skarels 			VOIDC   umask (077);
660*40201Skarels 
661*40201Skarels 			OutFile = fopen (TempName, "w");
662*40201Skarels 		}
66333295Skarels 	}
664*40201Skarels 	if (OutFile == NULL) {
665*40201Skarels 		fprintf (stderr, "%s: can't create PS file %s\n", prog, TempName);
666*40201Skarels 		exit (1);
66733295Skarels 	}
668*40201Skarels 	if (!ScannedFonts) {
669*40201Skarels 		ScannedFonts = TRUE;
670*40201Skarels 		ScanFont ();
67133295Skarels 	}
672*40201Skarels 	if (!Cvted) {
673*40201Skarels 		CommentHeader ();
674*40201Skarels 		if (nf) {
675*40201Skarels 			register struct font *f;
676*40201Skarels 
677*40201Skarels 			fprintf (OutFile, "%%%%DocumentFonts:");
678*40201Skarels 			ForAllFonts (f) {
679*40201Skarels 				fprintf (OutFile, " %s", f->name);
680*40201Skarels 			}
681*40201Skarels 			fprintf (OutFile, "\n");
682*40201Skarels 		}
683*40201Skarels 		/* copy in fixed prolog */
684*40201Skarels 		if (copyfile (mstrcat (tempstr, libdir, ENSCRIPTPRO, sizeof tempstr),
685*40201Skarels 			      OutFile)) {
686*40201Skarels 			fprintf (stderr, "%s: trouble copying prolog file\n", prog);
687*40201Skarels 			exit (1);
688*40201Skarels 		}
689*40201Skarels 		fprintf (OutFile, "StartEnscriptDoc %% end fixed prolog\n");
690*40201Skarels 		DumpFonts ();
691*40201Skarels 		if (Gaudy)
692*40201Skarels 			fprintf (OutFile, "%s %s InitGaudy\n",
693*40201Skarels 				 Rotated ? "10.55" : "8.0", TwoColumn ? "true" : "false");
694*40201Skarels 		if (PreFeed) {
695*40201Skarels 			fprintf (OutFile, "true DoPreFeed\n");
696*40201Skarels 		}
697*40201Skarels 		fprintf (OutFile, "%%%%EndProlog\n");
69833295Skarels 	}
699*40201Skarels 	Cvted = TRUE;
70033295Skarels 
701*40201Skarels 	Page = 0;
702*40201Skarels 	BadChars = 0;		/* give each file a clean slate */
703*40201Skarels 	pagepending = TRUE;
704*40201Skarels 	while ((c = getchar ()) != EOF)
705*40201Skarels 		if ((c > 0177 || c < 0) && (!IgnoreGarbage)) {
706*40201Skarels 			if (BadChars++ > MAXBAD) {	/* allow some kruft but
707*40201Skarels 							 * not much */
708*40201Skarels 				fprintf (stderr, "%s: \"%s\" not a text file? Try -g.\n",
709*40201Skarels 				     prog, FileName ? FileName : "(stdin)");
710*40201Skarels 				if (!PipeOut)
711*40201Skarels 					VOIDC   unlink (OutName);
712*40201Skarels 
713*40201Skarels 				exit (1);
714*40201Skarels 			}
715*40201Skarels 		} else if (c >= ' ') {
716*40201Skarels 			if (pagepending)
717*40201Skarels 				InitPage ();
718*40201Skarels 			ShowChar (c);
719*40201Skarels 			col++;
720*40201Skarels 		} else
721*40201Skarels 			switch (c) {
722*40201Skarels 			case 010:	/* backspace */
723*40201Skarels 				dX -= BSWidth;
72433295Skarels 				break;
725*40201Skarels 			case 015:	/* carriage return ^M */
726*40201Skarels 				dY = lY;
727*40201Skarels 				dX = lX;
72833295Skarels 				break;
729*40201Skarels 			case 012:	/* linefeed ^J */
730*40201Skarels 				if (pagepending)
731*40201Skarels 					InitPage ();
732*40201Skarels 				if (dX != lX || dY != lY || !LPTsimulate || SeenText) {
733*40201Skarels 					SeenText = TRUE;
734*40201Skarels 					dY = lY = lY + crY;
735*40201Skarels 					dX = lX = lX + crX;
736*40201Skarels 				} else
737*40201Skarels 					LinesLeft = LineMax;
738*40201Skarels 				if ((dY < minY) || (--LinesLeft <= 0))
739*40201Skarels 					PageEject ();
740*40201Skarels 				col = 1;
741*40201Skarels 				break;
742*40201Skarels 			case 033:	/* escape */
743*40201Skarels 				switch (c = getchar ()) {
744*40201Skarels 				case '7':	/* backup one line */
745*40201Skarels 					dY = lY = lY - crY;
746*40201Skarels 					dX = lX = lX - crX;
747*40201Skarels 					break;
748*40201Skarels 				case '8':	/* backup 1/2 line */
749*40201Skarels 					dY -= crY / 2;
750*40201Skarels 					dX -= crX / 2;
751*40201Skarels 					break;
752*40201Skarels 				case '9':	/* forward 1/2 linefeed */
753*40201Skarels 					dY += crY / 2;
754*40201Skarels 					dX += crX / 2;
755*40201Skarels 					break;
756*40201Skarels 				case 'F':	/* font setting */
757*40201Skarels 					c = getchar ();
758*40201Skarels 					if ('a' <= c && c <= 'z')
759*40201Skarels 						if (fontindex[c - 'a'] >= 0)
760*40201Skarels 							SetFont (fontindex[c - 'a']);
761*40201Skarels 						else {
762*40201Skarels 							fprintf (stderr, "%s: font '%c' not defined\n",
763*40201Skarels 								 prog, c);
764*40201Skarels 							exit (1);
765*40201Skarels 						}
766*40201Skarels 					else {
767*40201Skarels 						fprintf (stderr, "%s: bad font code in file: '%c'\n",
768*40201Skarels 							 prog, c);
769*40201Skarels 						exit (1);
770*40201Skarels 					}
771*40201Skarels 					break;
772*40201Skarels 				case 'D':	/* date string */
773*40201Skarels 					VOIDC fgets (DateStr, sizeof(DateStr), stdin);
774*40201Skarels 					FileDate = DateStr;
775*40201Skarels 					break;
776*40201Skarels 				case 'U':	/* new "user's" heading */
777*40201Skarels 					{
778*40201Skarels 						static char header[100];
779*40201Skarels 						VOIDC   fgets (header, sizeof(header), stdin);
78033295Skarels 
781*40201Skarels 						UsersHeader = header;
782*40201Skarels 						break;
783*40201Skarels 					}
784*40201Skarels 				case 'H':	/* new heading */
785*40201Skarels 					{
786*40201Skarels 						static char header[100];
787*40201Skarels 
788*40201Skarels 						VOIDC   fgets (header, sizeof(header), stdin);
789*40201Skarels 
790*40201Skarels 						ClosePage ();
791*40201Skarels 						Header = header;
792*40201Skarels 						Page = 0;
793*40201Skarels 						break;
794*40201Skarels 					}
795*40201Skarels 				}
79633295Skarels 				break;
797*40201Skarels 			case '%':	/* included PostScript line */
798*40201Skarels 				{
799*40201Skarels 					char    psline[200];
800*40201Skarels 					VOIDC   fgets (psline, sizeof(psline), stdin);
801*40201Skarels 
802*40201Skarels 					fprintf (OutFile, "%s\n", psline);
803*40201Skarels 					break;
804*40201Skarels 				}
805*40201Skarels 			case 014:	/* form feed ^L */
806*40201Skarels 				PageEject ();
807*40201Skarels 				col = 1;
808*40201Skarels 				break;
809*40201Skarels 			case 011:	/* tab ^I */
810*40201Skarels 				if (pagepending)
811*40201Skarels 					InitPage ();
812*40201Skarels 				col = (col - 1) / 8 * 8 + 9;
813*40201Skarels 				dX = lX + (col - 1) / 8 * TabWidth;
814*40201Skarels 				break;
815*40201Skarels 			default:	/* other control character, take your
816*40201Skarels 					 * chances */
817*40201Skarels 				if (pagepending)
818*40201Skarels 					InitPage ();
819*40201Skarels 				ShowChar (c);
820*40201Skarels 				col++;
821*40201Skarels 			}
822*40201Skarels 	ClosePage ();
82333295Skarels }
82433295Skarels 
82533295Skarels 
82633295Skarels /*
827*40201Skarels  * close the PS file
82833295Skarels  */
829*40201Skarels private VOID
830*40201Skarels ClosePS ()
831*40201Skarels {
832*40201Skarels 	fprintf (OutFile, "%%%%Trailer\n");
833*40201Skarels 	if (PreFeed) {
834*40201Skarels 		fprintf (OutFile, "false DoPreFeed\n");
835*40201Skarels 	}
836*40201Skarels 	fprintf (OutFile, "EndEnscriptDoc\nEnscriptJob restore\n");
83733295Skarels }
83833295Skarels 
83933295Skarels 
840*40201Skarels private VOID
841*40201Skarels SetTime (tval)
842*40201Skarels 	long    tval;
843*40201Skarels {
844*40201Skarels 	struct tm *tp;
84533295Skarels 
846*40201Skarels 	if (Gaudy) {
847*40201Skarels 		tp = localtime (&tval);
848*40201Skarels 		VOIDC   sprintf (DateStr, "(%02d/%02d/%02d)(%02d:%02d:%02d)",
849*40201Skarels 			           tp->tm_year, tp->tm_mon + 1, tp->tm_mday,
850*40201Skarels 			               tp->tm_hour, tp->tm_min, tp->tm_sec);
851*40201Skarels 	} else {
852*40201Skarels 		VOIDC   strcpy (DateStr, ctime (&tval));
85333295Skarels 
854*40201Skarels 		DateStr[24] = '\0';	/* get rid of newline */
855*40201Skarels 	}
856*40201Skarels 
857*40201Skarels 	FileDate = DateStr;
85833295Skarels }
85933295Skarels 
86033295Skarels 
86133295Skarels 
86233295Skarels 
863*40201Skarels #define ARGS "12gGBlL:oqrRkKf:F:b:p:J:C:P:#:mhO:"
86433295Skarels 
865*40201Skarels private VOID ParseArgs (ac, av)
866*40201Skarels 	int     ac;
867*40201Skarels 	char  **av;
868*40201Skarels {
869*40201Skarels 	int     argp;
870*40201Skarels 
871*40201Skarels 	while ((argp = getopt (ac, av, ARGS)) != EOF) {
872*40201Skarels 		debugp ((stderr, "option: %c\n", argp));
873*40201Skarels 		switch (argp) {
874*40201Skarels 		case '1':
875*40201Skarels 			TwoColumn = FALSE;
876*40201Skarels 			break;
877*40201Skarels 		case '2':
878*40201Skarels 			TwoColumn = TRUE;
879*40201Skarels 			break;
880*40201Skarels 		case 'G':
881*40201Skarels 			Gaudy = TRUE;
882*40201Skarels 			if (UsersHeader == NULL)
883*40201Skarels 				UsersHeader = "";
884*40201Skarels 			if (Header == NULL)
885*40201Skarels 				Header = "";
886*40201Skarels 			SHeaderFont = DefineFont(SHEADFONT, 12);
887*40201Skarels 			DateFont = DefineFont(DATEFONT, 12);
888*40201Skarels 			PgNumFont = DefineFont(PGNUMFONT, 24);
889*40201Skarels 			break;
890*40201Skarels 		case 'g':
891*40201Skarels 			IgnoreGarbage = TRUE;
892*40201Skarels 			break;
893*40201Skarels 		case 'B':
894*40201Skarels 			NoTitle = TRUE;
895*40201Skarels 			break;
896*40201Skarels 		case 'l':
897*40201Skarels 			LPTsimulate = TRUE;
898*40201Skarels 			NoTitle = TRUE;
899*40201Skarels 			Lines = 66;
900*40201Skarels 			break;
901*40201Skarels 		case 'L':
902*40201Skarels 			Lines = atoi (optarg);
903*40201Skarels 			break;
904*40201Skarels 		case 'o':
905*40201Skarels 			ListOmitted = TRUE;
906*40201Skarels 			break;
907*40201Skarels 		case 'q':
908*40201Skarels 			BeQuiet = TRUE;
909*40201Skarels 			break;
910*40201Skarels 		case 'r':
911*40201Skarels 			Rotated = TRUE;
912*40201Skarels 			break;
913*40201Skarels 		case 'R':
914*40201Skarels 			Rotated = FALSE;
915*40201Skarels 			break;
916*40201Skarels 		case 'k':
917*40201Skarels 			PreFeed = TRUE;
918*40201Skarels 			break;
919*40201Skarels 		case 'K':
920*40201Skarels 			PreFeed = FALSE;
921*40201Skarels 			break;
922*40201Skarels 		case 'f':{
923*40201Skarels 				register char font = 'r';
924*40201Skarels 				int    *whichfont;
925*40201Skarels 
926*40201Skarels 				if (*optarg == '-') {
927*40201Skarels 					font = *++optarg;
928*40201Skarels 					optarg++;
929*40201Skarels 				}
930*40201Skarels 				if ((font < 'a') || ('z' < font)) {
931*40201Skarels 					fprintf (stderr,
932*40201Skarels 						 "%s: '%c' isn't a valid font designator.\n",
933*40201Skarels 						 prog, font);
934*40201Skarels 					exit (1);
935*40201Skarels 				}
936*40201Skarels 				whichfont = &fontindex[font - 'a'];
937*40201Skarels 				if (*whichfont < 0)
938*40201Skarels 					*whichfont = nf++;
939*40201Skarels 				decodefont (optarg, &fonts[*whichfont]);
940*40201Skarels 			}
941*40201Skarels 			break;
942*40201Skarels 		case 'F':
943*40201Skarels 			decodefont (optarg, &fonts[HeaderFont]);
944*40201Skarels 			break;
945*40201Skarels 		case 'b':
946*40201Skarels 			UsersHeader = optarg;
947*40201Skarels 			break;
948*40201Skarels 		case 'p':
949*40201Skarels 			OutOnly = TRUE;
950*40201Skarels 			VOIDC   strcpy (OutName, optarg);
951*40201Skarels 
952*40201Skarels 			if (strcmp (OutName, "-") == 0)
953*40201Skarels 				PipeOut = TRUE;
954*40201Skarels 			break;
955*40201Skarels 		case 'h':
956*40201Skarels 			spoolNoBurst = TRUE;
957*40201Skarels 			break;
958*40201Skarels 			/* BSD lpr options processing */
959*40201Skarels 		case 'm':
960*40201Skarels 			spoolNotify = argp;
961*40201Skarels 			break;
962*40201Skarels 		case '#':
963*40201Skarels 			spoolCopies = optarg;
964*40201Skarels 			break;
965*40201Skarels 		case 'C':
966*40201Skarels 			spoolJobClass = optarg;
967*40201Skarels 			break;
968*40201Skarels 		case 'J':
969*40201Skarels 			spoolJobName = optarg;
970*40201Skarels 			break;
971*40201Skarels 		case 'P':
972*40201Skarels 			PrinterName = optarg;
973*40201Skarels 			break;
974*40201Skarels 		case '?':
975*40201Skarels 			/* bad option */
976*40201Skarels 			break;
977*40201Skarels 		case 'O':
978*40201Skarels 			Xoffset = atof(optarg) * (double)UperInch;
979*40201Skarels 			if (Xoffset < 0)
980*40201Skarels 				Xoffset = 0;
981*40201Skarels 			break;
982*40201Skarels 		default:
983*40201Skarels 			break;
98433295Skarels 		}
98533295Skarels 	}
98633295Skarels }
98733295Skarels 
98833295Skarels 
98933295Skarels /* addarg is used to construct an argv for the spooler */
990*40201Skarels private VOID
991*40201Skarels addarg (argv, argstr, argc)
992*40201Skarels 	char  **argv;
993*40201Skarels 	char   *argstr;
994*40201Skarels 	register int *argc;
995*40201Skarels {
996*40201Skarels 	register char *p = (char *) malloc ((unsigned) (strlen (argstr) + 1));
997*40201Skarels 	VOIDC   strcpy (p, argstr);
998*40201Skarels 
999*40201Skarels 	argv[(*argc)++] = p;
1000*40201Skarels 	argv[*argc] = '\0';
100133295Skarels }
100233295Skarels 
100333295Skarels 
1004*40201Skarels private VOID
1005*40201Skarels SpoolIt ()
1006*40201Skarels {
1007*40201Skarels 	char    temparg[200];
1008*40201Skarels 	char   *argstr[200];
1009*40201Skarels 	int     nargs = 0;
101033295Skarels 
101133295Skarels 
1012*40201Skarels 	addarg (argstr, LPR, &nargs);
1013*40201Skarels 	/* BSD spooler */
1014*40201Skarels 	if (atoi (spoolCopies) > 1) {
1015*40201Skarels 		VOIDC   sprintf (temparg, "-#%s", spoolCopies);
101633295Skarels 
1017*40201Skarels 		addarg (argstr, temparg, &nargs);
1018*40201Skarels 	}
1019*40201Skarels 	if ((PrinterName == NULL) && ((PrinterName = envget ("PRINTER")) == NULL)) {
1020*40201Skarels 		PrinterName = POSTSCRIPTPRINTER;
1021*40201Skarels 	}
1022*40201Skarels 	VOIDC   sprintf (temparg, "-P%s", PrinterName);
102333295Skarels 
1024*40201Skarels 	addarg (argstr, temparg, &nargs);
1025*40201Skarels 	if (!BeQuiet)
1026*40201Skarels 		fprintf (stderr, "spooled to %s\n", PrinterName);
102733295Skarels 
1028*40201Skarels 	if (spoolJobClass) {
1029*40201Skarels 		addarg (argstr, "-C", &nargs);
1030*40201Skarels 		addarg (argstr, spoolJobClass, &nargs);
1031*40201Skarels 	}
1032*40201Skarels 	addarg (argstr, "-J", &nargs);
1033*40201Skarels 	if (spoolJobName) {
1034*40201Skarels 		addarg (argstr, spoolJobName, &nargs);
1035*40201Skarels 	} else {
1036*40201Skarels 		if (!FileName)
1037*40201Skarels 			addarg (argstr, "stdin", &nargs);
1038*40201Skarels 		else
1039*40201Skarels 			addarg (argstr, FileName, &nargs);
1040*40201Skarels 	}
1041*40201Skarels 	if (spoolNotify) {
1042*40201Skarels 		addarg (argstr, "-m", &nargs);
1043*40201Skarels 	}
1044*40201Skarels 	if (spoolNoBurst) {
1045*40201Skarels 		addarg (argstr, "-h", &nargs);
1046*40201Skarels 	}
1047*40201Skarels 	/* remove the temporary file after spooling */
1048*40201Skarels 	addarg (argstr, "-r", &nargs);	/* should we use a symbolic link too? */
1049*40201Skarels 	addarg (argstr, TempName, &nargs);
105033295Skarels 
105133295Skarels #ifdef DEBUG
1052*40201Skarels 	{
1053*40201Skarels 		int     i;
1054*40201Skarels 
1055*40201Skarels 		fprintf (stderr, "called spooler with: ");
1056*40201Skarels 		for (i = 0; i < nargs; i++)
1057*40201Skarels 			fprintf (stderr, "(%s)", argstr[i]);
1058*40201Skarels 		fprintf (stderr, "\n");
1059*40201Skarels 	}
106033295Skarels #endif
106133295Skarels 
1062*40201Skarels 	execvp (LPR, argstr);
1063*40201Skarels 	pexit2 (prog, "can't exec spooler", 1);
106433295Skarels }
106533295Skarels 
106633295Skarels 
106733295Skarels private char *eargv[60];
106833295Skarels private int eargc = 1;
106933295Skarels 
107033295Skarels 
1071*40201Skarels main (argc, argv)
1072*40201Skarels 	int     argc;
1073*40201Skarels 	char  **argv;
1074*40201Skarels {
1075*40201Skarels 	register char *p;	/* pointer to "ENSCRIPT" in env */
107633295Skarels 
1077*40201Skarels 	prog = *argv;		/* argv[0] is program name */
107833295Skarels 
1079*40201Skarels 	debugp ((stderr, "PL %ld PW %ld TPL %ld TPW %ld\n", PageLength, PageWidth, TruePageLength, TruePageWidth));
108033295Skarels 
1081*40201Skarels 	if (signal (SIGINT, int1) == SIG_IGN) {
1082*40201Skarels 		VOIDC   signal (SIGINT, SIG_IGN);
1083*40201Skarels 		VOIDC   signal (SIGQUIT, SIG_IGN);
1084*40201Skarels 		VOIDC   signal (SIGHUP, SIG_IGN);
1085*40201Skarels 		VOIDC   signal (SIGTERM, SIG_IGN);
1086*40201Skarels 	} else {
1087*40201Skarels 		VOIDC   signal (SIGQUIT, int1);
1088*40201Skarels 		VOIDC   signal (SIGHUP, int1);
1089*40201Skarels 		VOIDC   signal (SIGTERM, int1);
1090*40201Skarels 	}
109133295Skarels 
1092*40201Skarels 	{
1093*40201Skarels 		register int i;
109433295Skarels 
1095*40201Skarels 		for (i = 0; i < 26; i++)
1096*40201Skarels 			fontindex[i] = -1;
1097*40201Skarels 	}
109833295Skarels 
1099*40201Skarels 	if ((libdir = envget ("PSLIBDIR")) == NULL)
1100*40201Skarels 		libdir = LibDir;
1101*40201Skarels 	if ((tempdir = envget ("PSTEMPDIR")) == NULL)
1102*40201Skarels 		tempdir = TempDir;
110333295Skarels 
1104*40201Skarels 	Roman = CurFont = DefineFont (BODYROMAN, 10);
1105*40201Skarels 	HeaderFont = DefineFont (HEADFONT, 10);
1106*40201Skarels 
1107*40201Skarels 	/* process args in environment variable ENSCRIPT */
1108*40201Skarels 	if (p = envget ("ENSCRIPT")) {
1109*40201Skarels 		while (1) {
1110*40201Skarels 			register char quote = ' ';
1111*40201Skarels 
1112*40201Skarels 			while (*p == ' ')
1113*40201Skarels 				p++;
1114*40201Skarels 			if ((*p == '"') || (*p == '\''))
1115*40201Skarels 				quote = *p++;
1116*40201Skarels 			eargv[eargc++] = p;
1117*40201Skarels 			while ((*p != quote) && (*p != '\0'))
1118*40201Skarels 				p++;
1119*40201Skarels 			if (*p == '\0')
1120*40201Skarels 				break;
1121*40201Skarels 			*p++ = '\0';
1122*40201Skarels 		}
1123*40201Skarels 		ParseArgs (eargc, eargv);
1124*40201Skarels 		if (eargc != optind) {
1125*40201Skarels 			fprintf (stderr, "%s: bad environment variable ENSCRIPT \"%s\"\n",
1126*40201Skarels 				 prog, envget ("ENSCRIPT"));
1127*40201Skarels 			exit (1);
1128*40201Skarels 		}
112933295Skarels 	}
1130*40201Skarels 	/* process the command line arguments */
1131*40201Skarels 	optind = 1;		/* reset getopt global */
1132*40201Skarels 	ParseArgs (argc, argv);
113333295Skarels 
1134*40201Skarels 	/* process non-option args */
1135*40201Skarels 	for (; optind < argc; optind++) {
1136*40201Skarels 		FileName = Header = argv[optind];
1137*40201Skarels 		if (freopen (FileName, "r", stdin) == NULL) {
1138*40201Skarels 			fprintf (stderr, "%s: can't open %s\n", prog, FileName);
1139*40201Skarels 			exit (1);
1140*40201Skarels 		}
1141*40201Skarels 		VOIDC   fstat (fileno (stdin), &S);
114233295Skarels 
1143*40201Skarels 		SetTime (S.st_mtime);
1144*40201Skarels 		CopyFile ();
1145*40201Skarels 		VOIDC   fclose (stdin);
1146*40201Skarels 
1147*40201Skarels 		SeenFile = TRUE;
114833295Skarels 	}
1149*40201Skarels 	if (!SeenFile) {
1150*40201Skarels 		FileName = Header = Gaudy ? "" : 0;
1151*40201Skarels 		VOIDC   fstat (fileno (stdin), &S);
115233295Skarels 
1153*40201Skarels 		if ((S.st_mode & S_IFMT) == S_IFREG)
1154*40201Skarels 			SetTime (S.st_mtime);
1155*40201Skarels 		else
1156*40201Skarels 			SetTime (time ((long *) 0));
1157*40201Skarels 		CopyFile ();
1158*40201Skarels 	}
1159*40201Skarels 	if (Cvted) {
1160*40201Skarels 		ClosePS ();
1161*40201Skarels 		VOIDC   fclose (OutFile);
116233295Skarels 
1163*40201Skarels 		OutFile = 0;
116433295Skarels 	}
1165*40201Skarels 	if (TruncChars && !BeQuiet)
1166*40201Skarels 		fprintf (stderr, "%s: %d characters omitted because of long lines.\n",
1167*40201Skarels 			 prog, TruncChars);
1168*40201Skarels 	if (UndefChars && !BeQuiet)
1169*40201Skarels 		fprintf (stderr, "%s: %d characters omitted because of incomplete fonts.\n",
1170*40201Skarels 			 prog, UndefChars);
1171*40201Skarels 	if (!BeQuiet && (TotalPages > 0)) {
1172*40201Skarels 		fprintf (stderr, "[ %d page%s * %s cop%s ] ",
1173*40201Skarels 			 TotalPages, TotalPages > 1 ? "s" : "",
1174*40201Skarels 			 spoolCopies, atoi (spoolCopies) > 1 ? "ies" : "y");
117533295Skarels 	}
1176*40201Skarels 	if (Cvted) {
1177*40201Skarels 		if (!BeQuiet) {
1178*40201Skarels 			fprintf (stderr, "left in %s\n", OutName);
1179*40201Skarels 		}
1180*40201Skarels 		if (!OutOnly) {
1181*40201Skarels 			SpoolIt ();	/* does an exec */
1182*40201Skarels 		}
1183*40201Skarels 	}
118433295Skarels }
118533295Skarels 
118633295Skarels 
118733295Skarels /* signal catcher */
1188*40201Skarels private VOID
1189*40201Skarels int1 ()
1190*40201Skarels {
1191*40201Skarels 	if ((!PipeOut) && (OutName != NULL) && (*OutName != '\0')) {
1192*40201Skarels 		VOIDC   unlink (OutName);
1193*40201Skarels 	}
1194*40201Skarels 	exit (1);
119533295Skarels }
1196