133295Skarels #ifndef lint 233295Skarels static char Notice[] = "Copyright (c) 1985 Adobe Systems Incorporated"; 3*40564Skarels static char sccsid[] = "@(#)enscript.c 1.6 (Berkeley) 03/22/90"; 440201Skarels static char *RCSID = "$Header: enscript.c,v 1.7 89/03/12 01:31:55 van Exp $"; 540201Skarels 633295Skarels #endif 740201Skarels /* 840201Skarels * enscript.c 933295Skarels * 1040201Skarels * Copyright (c) 1985 Adobe Systems Incorporated 1133295Skarels * 1240201Skarels * inspired by Gosling's cz there have been major overhauls, but the input 1340201Skarels * language is the same: new widths format generate PostScript (much easier 1440201Skarels * than Press) new and renamed switches (to match 4.2bsd lpr spooler) obeys 1540201Skarels * PostScript comment conventions doesn't worry so much about fonts 1640201Skarels * (everything is scalable and rotatable, use PS font names, no face 1740201Skarels * properties) 1833295Skarels * 1940201Skarels * enscript generates POSTSCRIPT print files of a special kind the coordinate 2040201Skarels * system is in 20ths of a point. (1440 per inch) 2133295Skarels * 2240201Skarels * Edit History: Andrew Shore: Mon Nov 18 14:05:05 1985 End Edit History. 2333295Skarels * 2440201Skarels * RCSLOG: $Log: enscript.c,v $ 2540201Skarels * Revision 1.7 89/03/12 01:31:55 van 2640201Skarels * we have to escape special chars in title strings. 2733295Skarels * 2840201Skarels * Revision 1.6 89/03/10 00:30:39 van 2940201Skarels * might as well let the user change everything. 3033295Skarels * 3140201Skarels * Revision 1.5 89/03/09 23:19:17 van 3240201Skarels * gcc lint. 3333295Skarels * 3440201Skarels * Revision 1.4 89/03/09 23:08:50 van 3540201Skarels * let user set the fonts used in 'gaudy' mode 3640201Skarels * 3740201Skarels * Revision 1.3 88/03/06 17:23:58 leres 3840201Skarels * Fix logic bug; only spool output if that's want we want. 3940201Skarels * 4040201Skarels * Revision 1.2 86/07/03 00:06:31 van 4140201Skarels * reformatted. removed SYSV ifdefs. 4240201Skarels * Revision 1.1 86/07/03 00:03:12 van Initial 4340201Skarels * revision 4433295Skarels * 4540201Skarels * Revision 2.1 85/11/24 11:48:55 shore Product Release 2.0 4640201Skarels * 4740201Skarels * Revision 1.3 85/11/20 00:10:01 shore Added System V support (input options 4840201Skarels * and spooling) margins/linecount reworked (Dataproducts) incompatible 4940201Skarels * options changes, getopt! Guy Riddle's Gaudy mode and other changes output 5040201Skarels * spooling messages, pages, copies 5140201Skarels * 5240201Skarels * Revision 1.2 85/05/14 11:22:14 shore *** empty log message *** 5340201Skarels * 5440201Skarels * 5533295Skarels */ 5633295Skarels 5733295Skarels #define POSTSCRIPTPRINTER "PostScript" 5833295Skarels 5933295Skarels #define BODYROMAN "Courier" 6040521Skarels #define BODYSZ 10 6140521Skarels #define HEADFONT "Courier-Bold" 6240521Skarels #define HEADSZ 10 6340521Skarels #define GHEADFONT "Helvetica-Bold" 6440521Skarels #define GHEADSZ 14 6540201Skarels #define SHEADFONT "Times-Bold" 6640521Skarels #define SHEADSZ 12 6740201Skarels #define PGNUMFONT "Helvetica-Bold" 6840521Skarels #define PGNUMSZ 24 6940521Skarels #define DATEFONT "Times-Bold" 7040521Skarels #define DATESZ 12 7133295Skarels 7233295Skarels #ifdef DEBUG 7333295Skarels #define debugp(x) {fprintf x ; VOIDC fflush(stderr);} 7433295Skarels #else 7533295Skarels #define debugp(x) 7633295Skarels #endif 7733295Skarels 7833295Skarels #define UperInch (1440L) 7933295Skarels #define PtsPerInch 72 8033295Skarels #define UperPt 20 8133295Skarels 8233295Skarels /* virtual page is 8 x 10.5 inches (for Toshiba compat) */ 8333295Skarels #define PageWidth ((long) UperInch*8) 8433295Skarels #define PageLength ((long)((UperInch*21)/2)) 8533295Skarels 8640201Skarels /* #define PageLength ((long) ((long) (UperInch*(8*11-3)))/8) */ 8740201Skarels /* #define PageWidth ((long) ((long) (UperInch*(8*17-3)))/8) */ 8833295Skarels 8933295Skarels /* true page is 8.5 x 11 inches */ 9033295Skarels #define TruePageWidth (UperInch*17/2) 9133295Skarels #define TruePageLength ((long)(UperInch*11)) 9233295Skarels 9333295Skarels #include <stdio.h> 9433295Skarels #include <ctype.h> 9533295Skarels #include <pwd.h> 9633295Skarels #include <strings.h> 9733295Skarels #include <sys/time.h> 9833295Skarels #include <signal.h> 9933295Skarels #include <sys/types.h> 10033295Skarels #include <sys/stat.h> 10133295Skarels #include "transcript.h" 10233295Skarels 10333295Skarels #define LPR "lpr" 10433295Skarels 10540201Skarels #define MAXBAD 20 /* number of bad chars to pass before 10640201Skarels * complaint */ 10733295Skarels 10833295Skarels private struct stat S; 10933295Skarels 11040201Skarels extern double atof(); 11133295Skarels extern char *optarg; /* getopt current opt char */ 11233295Skarels extern int optind; /* getopt argv index */ 11333295Skarels 11440201Skarels private VOID int1 (); 11540201Skarels private FlushShow(); 11633295Skarels 11733295Skarels #define FSIZEMAX 256 /* number of chars per font */ 11833295Skarels 11933295Skarels /* the layout of a font information block */ 12033295Skarels private struct font { 12140201Skarels char name[100]; /* PostScript font name */ 12240201Skarels int dsize; /* size */ 12340201Skarels int Xwid[FSIZEMAX]; /* X widths for each character */ 12433295Skarels }; 12533295Skarels 12640201Skarels private struct font fonts[16]; /* 16 possible fonts at one time */ 12740201Skarels private int nf = 0; /* number of fonts known about */ 12833295Skarels 12933295Skarels private int TabWidth = TruePageWidth / 10; /* width of a tab */ 13040201Skarels private int BSWidth; /* width of a backspace */ 13133295Skarels 13233295Skarels private long UperLine = UperInch / 7; 13333295Skarels private long UperHLine = UperInch / 7; 13433295Skarels 13533295Skarels private char *prog; /* program name argv[0] */ 13633295Skarels private char *libdir; /* place for prolog and widths files */ 13733295Skarels private char *tempdir; /* place for temp file */ 13833295Skarels private char TempName[100]; /* name of temporary PostScript file */ 13933295Skarels private char OutName[256] = ""; /* filename for disk output */ 14033295Skarels private int PipeOut = FALSE; /* output to stdout (-p -) */ 14133295Skarels private int ListOmitted = FALSE;/* list omitted chars on the tty */ 14240521Skarels private int BeQuiet = FALSE; /* suppress stderr error messages */ 14340521Skarels private int Verbose = FALSE; /* silly informational messages */ 14433295Skarels private int Gaudy = FALSE; /* pretty bars along the top */ 14533295Skarels private int LPTsimulate = FALSE;/* an lpt should be simulated */ 14633295Skarels private int Lines = 0; /* max lines per page */ 14733295Skarels private int LinesLeft = 66; /* lines left on page when in LPT mode */ 14833295Skarels private int LineMax = 64; /* ? */ 14933295Skarels private int col; /* column number on current line */ 15033295Skarels private int SeenText = TRUE; /* true if seen some text on this page */ 15133295Skarels private int OutOnly = FALSE; /* PS file only wanted */ 15233295Skarels private int Rotated = FALSE; /* pages to be rotated landscape */ 15333295Skarels private int PreFeed = FALSE; /* prefeed should be enabled */ 15433295Skarels private int TwoColumn = FALSE; /* two-column mode */ 15533295Skarels private int FirstCol = TRUE; /* we're printing column 1 */ 15633295Skarels private int NoTitle = FALSE; /* title line is suppressed */ 15733295Skarels private int Cvted = FALSE; /* converted a file to PS format */ 15833295Skarels 15940201Skarels private int IgnoreGarbage = FALSE; /* garbage should be ignored */ 16040521Skarels private int SeenFont = FALSE; /* we've seen a font request */ 16133295Skarels private int SeenFile = FALSE; /* a file has been processed */ 16240201Skarels private int ScannedFonts = FALSE; /* we've scanned the font file */ 16333295Skarels private char *FileName = 0; /* name of file currently being PSed */ 16433295Skarels private char *FileDate = 0; /* last mod date of file being PSed */ 16533295Skarels private char DateStr[27]; /* thanks, but no thanks ctime! */ 16640201Skarels private int spoolNoBurst = FALSE; /* no break page flag for spooler */ 16733295Skarels 16833295Skarels #ifdef BSD 16933295Skarels private char *spoolJobClass = NULL; 17033295Skarels private char *spoolJobName = NULL; 17140201Skarels 17233295Skarels #endif 17333295Skarels private char *PrinterName = NULL; 17433295Skarels private int spoolNotify = 0; 17533295Skarels private char *spoolCopies = "1"; 17633295Skarels 17733295Skarels private char tempstr[256]; /* various path names */ 17833295Skarels 17933295Skarels private int CurFont; /* current Font */ 18040201Skarels private int fontindex[26]; /* table of fonts, indexed by font designator 18140201Skarels * ('a' to 'z') */ 18240201Skarels 18333295Skarels /* indexes for default fonts */ 18433295Skarels 18533295Skarels #define Roman fontindex['r'-'a'] 18633295Skarels #define HeaderFont fontindex['h'-'a'] 18740201Skarels #define SHeaderFont fontindex['i'-'a'] 18840201Skarels #define DateFont fontindex['j'-'a'] 18940201Skarels #define PgNumFont fontindex['k'-'a'] 19033295Skarels 19133295Skarels private long cX, cY; /* current page positions */ 19233295Skarels private long dX, dY; /* desired page positions */ 19333295Skarels private long lX, lY; /* page positions of the start of the line */ 19433295Skarels private long crX, crY; /* X and Y increments to apply to CR's */ 19533295Skarels private long maxX; /* maximum x coord on line */ 19633295Skarels private long minY; /* minimum y coord on page */ 19740201Skarels private long Xoffset; /* amount to offset left margin */ 19833295Skarels 19933295Skarels #define None 0 20033295Skarels #define RelX 1 20133295Skarels #define RelY 2 20233295Skarels #define RelXY 3 20333295Skarels #define AbsX 4 20433295Skarels #define AbsY 8 20533295Skarels #define AbsXY 12 20633295Skarels 20733295Skarels private int movepending; /* moveto pending coords on stack */ 20833295Skarels private int showpending; /* number of characters waiting to be shown */ 20940201Skarels private int pagepending; /* start on next page when have something to 21040201Skarels * print */ 21140201Skarels private char *UsersHeader = NULL; /* user specified heading */ 21233295Skarels private char *Header = NULL; /* generated header (usually FileName) */ 21340521Skarels private char *Header2 = NULL; /* second header line for Gaudy */ 21433295Skarels private int Page = 0; /* current page number */ 21533295Skarels private int TotalPages = 0; /* total number of pages printed */ 21633295Skarels private int TruncChars = 0; /* number of characters truncated */ 21740201Skarels private int UndefChars = 0; /* number of characters skipped because they 21840201Skarels * weren't defined in some font */ 21940201Skarels private int BadChars = 0; /* number of bad characters seen so far */ 22033295Skarels private FILE *OutFile = NULL; /* output ps file */ 22133295Skarels 22233295Skarels 22333295Skarels /* decode a fontname string - e.g. Courier10 Helvetica-Bold12 */ 22440201Skarels private 22540201Skarels decodefont (name, f) 22640201Skarels register char *name; 22740201Skarels register struct font *f; 22840201Skarels { 22940201Skarels register char *d, *p; 23033295Skarels 23140201Skarels p = name; 23240201Skarels d = f->name; 23340201Skarels f->dsize = 0; 23440201Skarels while (isascii (*p) && (isalpha (*p) || (*p == '-'))) { 23540201Skarels *d++ = *p++; 23640201Skarels } 23740201Skarels *d++ = '\0'; 23840201Skarels while (isascii (*p) && isdigit (*p)) { 23940201Skarels f->dsize = f->dsize * 10 + *p++ - '0'; 24040201Skarels } 24140201Skarels if (*p || !f->dsize || !f->name[0]) { 24240201Skarels fprintf (stderr, "%s: poorly formed font name & size: \"%s\"\n", 24340201Skarels prog, name); 24440201Skarels exit (1); 24540201Skarels } 24633295Skarels } 24740201Skarels 24840201Skarels 24933295Skarels #define NOTDEF 0x8000 25033295Skarels #define ForAllFonts(p) for(p = &fonts[nf-1]; p >= &fonts[0]; p--) 25133295Skarels 25233295Skarels 25340201Skarels /* 25440201Skarels * Scan the font metrics directory looking for entries that match the entries 25540201Skarels * in ``fonts''. For entries that are found the data in the font description 25640201Skarels * is filled in, if any are missing, it dies horribly. 25733295Skarels */ 25840201Skarels private VOID ScanFont () 25940201Skarels { 26040201Skarels register struct font *f; 26140201Skarels register FILE *FontData;/* afm file */ 26240201Skarels char *c; 26340201Skarels int ccode, cwidth, inChars; 26440201Skarels char FontFile[512]; /* afm file name */ 26540201Skarels char afmbuf[BUFSIZ]; 26633295Skarels 26733295Skarels 26840201Skarels if (!SeenFont) { 26940201Skarels if (Lines == 0) 27040201Skarels Lines = 64; 27140201Skarels if (Rotated && TwoColumn) 27240201Skarels fonts[Roman].dsize = 7; 27333295Skarels } 27440201Skarels /* loop through fonts, find and read metric entry in dir */ 27540201Skarels ForAllFonts (f) { 27640201Skarels VOIDC mstrcat (FontFile, libdir, "/", sizeof FontFile); 27733295Skarels 27840201Skarels VOIDC mstrcat (FontFile, FontFile, f->name, sizeof FontFile); 27940201Skarels 28040201Skarels VOIDC mstrcat (FontFile, FontFile, ".afm", sizeof FontFile); 28140201Skarels 28240201Skarels if ((FontData = fopen (FontFile, "r")) == NULL) { 28340201Skarels fprintf (stderr, "%s: can't open font metrics file %s\n", 28440201Skarels prog, FontFile); 28540201Skarels exit (1); 28633295Skarels } 28740201Skarels /* read the .afm file to get the widths */ 28840201Skarels for (ccode = 0; ccode < FSIZEMAX; ccode++) 28940201Skarels f->Xwid[ccode] = NOTDEF; 29040201Skarels 29140201Skarels inChars = 0; 29240201Skarels while (fgets (afmbuf, sizeof afmbuf, FontData) != NULL) { 29340201Skarels /* strip off newline */ 29440201Skarels if ((c = INDEX (afmbuf, '\n')) == 0) { 29540201Skarels fprintf (stderr, "%s: AFM file %s line too long %s\n", 29640201Skarels prog, FontFile, afmbuf); 29740201Skarels exit (1); 29840201Skarels } 29940201Skarels *c = '\0'; 30040201Skarels if (*afmbuf == '\0') 30140201Skarels continue; 30240201Skarels if (strcmp (afmbuf, "StartCharMetrics") == 0) { 30340201Skarels inChars++; 30440201Skarels continue; 30540201Skarels } 30640201Skarels if (strcmp (afmbuf, "EndCharMetrics") == 0) 30740201Skarels break; 30840201Skarels if (inChars == 1) { 30940201Skarels if (sscanf (afmbuf, "C %d ; WX %d ;", &ccode, &cwidth) != 2) { 31040201Skarels fprintf (stderr, "%s: trouble with AFM file %s\n", 31140201Skarels prog, FontFile); 31240201Skarels exit (1); 31340201Skarels } 31440201Skarels /* get out once we see an unencoded char */ 31540201Skarels if (ccode == -1) 31640201Skarels break; 31740201Skarels if (ccode > 255) 31840201Skarels continue; 31940201Skarels f->Xwid[ccode] = 32040201Skarels (short) (((long) cwidth * (long) f->dsize * (long) UperPt) 32140201Skarels / 1000L); 32240201Skarels continue; 32340201Skarels } 32440201Skarels } 32540201Skarels VOIDC fclose (FontData); 32633295Skarels } 32733295Skarels 32840201Skarels TabWidth = fonts[Roman].Xwid['0'] * 8; /* 8 * figure width */ 32940201Skarels BSWidth = fonts[Roman].Xwid[' ']; /* space width */ 33033295Skarels 33140201Skarels UperLine = (fonts[Roman].dsize + 1) * UperPt; 33233295Skarels 33340201Skarels if (LPTsimulate) { 33440201Skarels UperHLine = UperLine; 33540201Skarels Lines = LineMax = 66; 33640201Skarels } else { 33740201Skarels UperHLine = (fonts[HeaderFont].dsize + 1) * UperPt; 33840201Skarels } 33933295Skarels 34040201Skarels crX = 0; 34140201Skarels crY = -UperLine; 34233295Skarels 34333295Skarels } 34433295Skarels 34533295Skarels 34640201Skarels /* 34740201Skarels * Return a font number for the font with the indicated name and size. Adds 34840201Skarels * info to the font list for the eventual search. 34933295Skarels */ 35040201Skarels private int 35140201Skarels DefineFont (name, size) 35240201Skarels char *name; 35340201Skarels { 35440201Skarels register struct font *p; 35540201Skarels 35640201Skarels p = &fonts[nf]; 35740201Skarels VOIDC strcpy (p->name, name); 35840201Skarels 35940201Skarels p->dsize = size; 36040201Skarels return (nf++); 36133295Skarels } 36233295Skarels 36340538Skarels ResetFont(indx, name, size) 36440538Skarels char *name; 36540538Skarels { 36640538Skarels register struct font *p; 36733295Skarels 36840538Skarels p = &fonts[indx]; 36940538Skarels VOIDC strcpy (p->name, name); 37040538Skarels p->dsize = size; 37140538Skarels } 37240538Skarels 37333295Skarels /* dump the fonts to the PS file for setup */ 37440201Skarels private VOID 37540201Skarels DumpFonts () 37640201Skarels { 37740201Skarels register struct font *f; 37833295Skarels 37940201Skarels ForAllFonts (f) { 38040201Skarels fprintf (OutFile, "%d %d /%s\n", f - &fonts[0], f->dsize * UperPt, f->name); 38140201Skarels } 38240201Skarels fprintf (OutFile, "%d SetUpFonts\n", nf); 38333295Skarels } 38433295Skarels 38533295Skarels /* add a shown character to the PS file */ 38640201Skarels private VOID 38740201Skarels OUTputc (c) 38840201Skarels register int c; 38940201Skarels { 39040201Skarels if (!showpending) { 39140201Skarels putc ('(', OutFile); 39240201Skarels showpending = TRUE; 39340201Skarels } 39440201Skarels if (c == '\\' || c == '(' || c == ')') 39540201Skarels putc ('\\', OutFile); 39640201Skarels if ((c > 0176) || (c < 040)) { 39740201Skarels putc ('\\', OutFile); 39840201Skarels putc ((c >> 6) + '0', OutFile); 39940201Skarels putc (((c >> 3) & 07) + '0', OutFile); 40040201Skarels putc ((c & 07) + '0', OutFile); 40140201Skarels } else 40240201Skarels putc (c, OutFile); 40333295Skarels } 40433295Skarels 40540201Skarels /* put a correctly escaped string to the PS file */ 40640201Skarels private VOID 40740201Skarels OUTstr(s) 40840201Skarels register char *s; 40940201Skarels { 41040201Skarels if (!showpending) { 41140201Skarels putc ('(', OutFile); 41240201Skarels showpending = TRUE; 41340201Skarels } 41440201Skarels while (*s) 41540201Skarels OUTputc(*s++); 41640201Skarels 41740201Skarels putc(')', OutFile); 41840201Skarels showpending = FALSE; 41940201Skarels } 42040201Skarels 42133295Skarels /* Set the current font */ 42240201Skarels private VOID 42340201Skarels SetFont (f) 42440201Skarels int f; 42540201Skarels { 42640201Skarels FlushShow (); 42740201Skarels CurFont = f; 42840201Skarels fprintf (OutFile, "%d F\n", f); 42933295Skarels } 43033295Skarels 43140201Skarels /* 43240201Skarels * put a character onto the page at the desired X and Y positions. If the 43340201Skarels * current position doesn't agree with the desired position, put out movement 43440201Skarels * directives. Leave the current position updated to account for the 43540201Skarels * character. 43633295Skarels */ 43740201Skarels private VOID 43840201Skarels ShowChar (c) 43940201Skarels register int c; 44040201Skarels { 44140201Skarels register struct font *f; 44240201Skarels register long nX, nY; 44340201Skarels static level = 0; 444*40564Skarels VOID PageEject(), InitPage(); 44533295Skarels 44640201Skarels level++; 44740201Skarels f = &fonts[CurFont]; 44833295Skarels 44940201Skarels if (f->Xwid[c] == NOTDEF) { 45040201Skarels UndefChars++; 45140201Skarels if (ListOmitted) 45240201Skarels fprintf (stderr, "%s: \\%03o not found in font %s\n", 45340201Skarels prog, c, f->name); 45440201Skarels if (level <= 1) { 45540201Skarels ShowChar ('\\'); 45640201Skarels ShowChar ((c >> 6) + '0'); 45740201Skarels ShowChar (((c >> 3) & 07) + '0'); 45840201Skarels ShowChar ((c & 07) + '0'); 45940201Skarels col += 3; 46040201Skarels } 46140201Skarels level--; 46240201Skarels return; 46333295Skarels } 46440201Skarels nX = dX + f->Xwid[c]; /* resulting position after showing this char */ 46540201Skarels nY = dY; 46633295Skarels 46740201Skarels if (c != ' ' || ((cX == dX) && (cY == dY))) { 46840521Skarels /* 46940521Skarels * If character doesn't fit on this line 47040521Skarels * (and we're not at left margin), simulate newline 47140521Skarels * and then call ourselves recursively. 47240521Skarels */ 47340521Skarels if (nX > maxX && dX > lX) { 47440521Skarels SeenText = TRUE; 47540521Skarels dY = lY = lY + crY; 47640521Skarels dX = lX = lX + crX; 477*40564Skarels if ((dY < minY) || (--LinesLeft <= 0)) { 47840521Skarels PageEject (); 479*40564Skarels if (pagepending) 480*40564Skarels InitPage (); 481*40564Skarels } 48240521Skarels col = 1; 48340521Skarels ShowChar(c); 484*40564Skarels col++; 48540521Skarels level--; 48640521Skarels return; 48740521Skarels } 48840521Skarels if (cX != dX) { 48940521Skarels if (cY != dY) { 49040201Skarels FlushShow (); 49140521Skarels /* absolute x, relative y */ 49240521Skarels fprintf (OutFile, "%ld %ld", dX, dY); 49340521Skarels movepending = AbsXY; 49440521Skarels } else { 49540521Skarels FlushShow (); 49640521Skarels fprintf (OutFile, "%ld", dX - cX); /* relative x */ 49740521Skarels movepending = RelX; 49840201Skarels } 49940521Skarels } else if (cY != dY) { 50040521Skarels FlushShow (); 50140521Skarels fprintf (OutFile, "%ld", dY - cY); /* relative y */ 50240521Skarels movepending = RelY; 50340521Skarels } 50440521Skarels OUTputc (c); 50540521Skarels showpending = TRUE; 50640521Skarels cX = nX; 50740521Skarels cY = nY; 50833295Skarels } 50940201Skarels dX = nX; 51040201Skarels dY = nY; 51133295Skarels 51240201Skarels level--; 51333295Skarels } 51433295Skarels 51533295Skarels /* put out a shown string to the PS file */ 51640201Skarels private VOID 51740201Skarels ShowStr (s) 51840201Skarels register char *s; 51940201Skarels { 52040201Skarels while (*s) { 52140201Skarels if (*s >= 040) 52240201Skarels ShowChar (*s); 52340201Skarels s++; 52440201Skarels } 52533295Skarels } 52633295Skarels 52733295Skarels /* flush pending show */ 52840201Skarels private 52940201Skarels FlushShow () 53040201Skarels { 53140201Skarels if (showpending) { 53240201Skarels putc (')', OutFile); 53340201Skarels switch (movepending) { 53440201Skarels case RelX: 53540201Skarels putc ('X', OutFile); 53640201Skarels break; 53740201Skarels case RelY: 53840201Skarels putc ('Y', OutFile); 53940201Skarels break; 54040201Skarels case AbsXY: 54140201Skarels putc ('B', OutFile); 54240201Skarels break; 54340201Skarels case None: 54440201Skarels putc ('S', OutFile); 54540201Skarels break; 54640201Skarels } 54740201Skarels putc ('\n', OutFile); 54840201Skarels movepending = None; 54940201Skarels showpending = FALSE; 55033295Skarels } 55133295Skarels } 55233295Skarels 55333295Skarels /* put out a page heading to the PS file */ 55440201Skarels private VOID 55540201Skarels InitPage () 55640201Skarels { 55740201Skarels char header[200]; 55840201Skarels register int OldFont = CurFont; 55933295Skarels 56040201Skarels TotalPages++; 56140201Skarels fprintf (OutFile, "%%%%Page: ? %d\n", TotalPages); 56240201Skarels fprintf (OutFile, "StartPage\n"); 56340201Skarels SeenText = FALSE; 56440201Skarels cX = cY = -1; 56540201Skarels showpending = pagepending = FALSE; 56640201Skarels FirstCol = TRUE; 56740201Skarels if (Rotated) { 56840201Skarels fprintf (OutFile, "Landscape\n"); 56940201Skarels lX = dX = UperInch / 4 + Xoffset; 57040201Skarels lY = dY = PageLength - (UperHLine * 3) / 2; 57140201Skarels maxX = TruePageLength; 57240201Skarels /* minY = (PageLength - TruePageWidth) + 3*UperLine+480; */ 57340201Skarels minY = (TruePageLength - TruePageWidth) + (TruePageWidth - PageWidth) / 2; 57440201Skarels } else { 57540201Skarels lX = dX = Xoffset + 57640201Skarels (TwoColumn? (UperInch * 0.3) : ((UperInch * 5) / 8)); 57740201Skarels lY = dY = PageLength - UperHLine; 57840201Skarels maxX = TruePageWidth; 57940201Skarels minY = (UperInch / 4); /* 0.25 inches */ 58040201Skarels } 58140201Skarels movepending = None; 58240201Skarels cX = dX; 58340201Skarels cY = dY; 58433295Skarels 58540201Skarels if (!NoTitle) { 58640201Skarels if (Gaudy) { 58740201Skarels OUTstr(UsersHeader); 58840521Skarels if (Header2) 58940521Skarels OUTstr(Header2); 59040521Skarels else 59140521Skarels OUTstr(Header); 59240201Skarels fprintf (OutFile, "[%s](%d)Gaudy\n", FileDate, ++Page); 59340201Skarels cX = cY = 0; /* force moveto here */ 59440201Skarels } else { 59540201Skarels SetFont (HeaderFont); 59640201Skarels fprintf (OutFile, "%ld %ld ", cX, cY); 59740201Skarels movepending = AbsXY; 59840201Skarels if (UsersHeader) { 59940201Skarels if (*UsersHeader == 0) { 60040201Skarels fprintf (OutFile, "()B\n"); 60140201Skarels movepending = None; 60240201Skarels showpending = FALSE; 60340201Skarels } else 60440201Skarels ShowStr (UsersHeader); 60540201Skarels } else { 60640201Skarels VOIDC sprintf (header, "%s %s %d", 60740201Skarels Header? Header : " ", FileDate, ++Page); 60840201Skarels 60940201Skarels ShowStr (header); 61040201Skarels } 61140201Skarels FlushShow (); 61233295Skarels } 61340201Skarels dX = lX = lX + crX * 2; 61440201Skarels dY = lY = lY + crY * 2; 61540201Skarels } else { 61640201Skarels /* fake it to force a moveto */ 61740201Skarels cX = cY = 0; 61833295Skarels } 61940201Skarels if (TwoColumn) 62040201Skarels maxX = maxX / 2 - BSWidth; 62140201Skarels else 62240201Skarels maxX -= ((long) (UperInch * 0.3)); 62340201Skarels LineMax = (lY - minY) / (-crY); 62440201Skarels if ((Lines <= 0) || (Lines > LineMax)) 62540201Skarels Lines = LinesLeft = LineMax; 62640201Skarels else 62740201Skarels LinesLeft = Lines; 62840201Skarels SetFont (OldFont); 62933295Skarels } 63033295Skarels 63140201Skarels private VOID 63240201Skarels ClosePage () 63340201Skarels { 63440201Skarels FlushShow (); 63540201Skarels if (!pagepending) 63640201Skarels fprintf (OutFile, "EndPage\n"); 63740201Skarels pagepending = TRUE; 63833295Skarels } 63933295Skarels 64033295Skarels /* skip to a new page */ 64140201Skarels private VOID 64240201Skarels PageEject () 64340201Skarels { 64440201Skarels if (TwoColumn && FirstCol) { 64540201Skarels FirstCol = FALSE; 64640201Skarels if (Rotated) { 64740201Skarels lY = dY = PageLength - (UperHLine * 3) / 2; 64840201Skarels lX = dX = Xoffset + TruePageLength / 2; 64940201Skarels maxX = TruePageLength - UperInch * 0.3; 65040201Skarels } else { 65140201Skarels lY = dY = PageLength - UperHLine; 65240201Skarels lX = dX = Xoffset + TruePageWidth / 2; 65340201Skarels maxX = TruePageWidth - UperInch * 0.3; 65440201Skarels } 65540201Skarels if (!NoTitle) { 65640201Skarels dX = lX = lX + crX * 2; 65740201Skarels dY = lY = lY + crY * 2; 65840201Skarels } 65940201Skarels } else 66040201Skarels ClosePage (); 66140201Skarels LinesLeft = Lines; 66240201Skarels SeenText = FALSE; 66333295Skarels } 66433295Skarels 66540201Skarels private VOID 66640201Skarels CommentHeader () 66740201Skarels { 66840201Skarels long clock; 66940201Skarels struct passwd *pswd; 67040201Skarels char hostname[40]; 67140201Skarels 67240201Skarels /* copy the file, prepending a new comment header */ 67340201Skarels fprintf (OutFile, "%%!%s\n", COMMENTVERSION); 67440201Skarels fprintf (OutFile, "%%%%Creator: "); 67540201Skarels pswd = getpwuid ((int) getuid ()); 67640201Skarels VOIDC gethostname (hostname, (int) sizeof hostname); 67740201Skarels 67840201Skarels fprintf (OutFile, "%s:%s (%s)\n", hostname, pswd->pw_name, pswd->pw_gecos); 67940201Skarels fprintf (OutFile, "%%%%Title: %s\n", (FileName ? FileName : "stdin")); 68040201Skarels fprintf (OutFile, "%%%%CreationDate: %s", (VOIDC time (&clock), ctime (&clock))); 68133295Skarels } 68233295Skarels 68333295Skarels /* Copy the standard input file to the PS file */ 68440201Skarels private VOID 68540201Skarels CopyFile () 68640201Skarels { 68740201Skarels register int c; 68833295Skarels 68940201Skarels col = 1; 69040201Skarels if (OutFile == 0) { 69140201Skarels if (OutOnly) { 69240201Skarels OutFile = PipeOut ? stdout : fopen (OutName, "w"); 69340201Skarels } else { 69440201Skarels VOIDC mktemp (mstrcat (TempName, tempdir, 69540201Skarels ENSCRIPTTEMP, sizeof TempName)); 69640201Skarels VOIDC strcpy (OutName, TempName); 69740201Skarels 69840201Skarels VOIDC umask (077); 69940201Skarels 70040201Skarels OutFile = fopen (TempName, "w"); 70140201Skarels } 70233295Skarels } 70340201Skarels if (OutFile == NULL) { 70440201Skarels fprintf (stderr, "%s: can't create PS file %s\n", prog, TempName); 70540201Skarels exit (1); 70633295Skarels } 70740201Skarels if (!ScannedFonts) { 70840201Skarels ScannedFonts = TRUE; 70940201Skarels ScanFont (); 71033295Skarels } 71140201Skarels if (!Cvted) { 71240201Skarels CommentHeader (); 71340201Skarels if (nf) { 71440201Skarels register struct font *f; 71540201Skarels 71640201Skarels fprintf (OutFile, "%%%%DocumentFonts:"); 71740201Skarels ForAllFonts (f) { 71840201Skarels fprintf (OutFile, " %s", f->name); 71940201Skarels } 72040201Skarels fprintf (OutFile, "\n"); 72140201Skarels } 72240201Skarels /* copy in fixed prolog */ 72340201Skarels if (copyfile (mstrcat (tempstr, libdir, ENSCRIPTPRO, sizeof tempstr), 72440201Skarels OutFile)) { 72540201Skarels fprintf (stderr, "%s: trouble copying prolog file\n", prog); 72640201Skarels exit (1); 72740201Skarels } 72840201Skarels fprintf (OutFile, "StartEnscriptDoc %% end fixed prolog\n"); 72940201Skarels DumpFonts (); 73040201Skarels if (Gaudy) 73140201Skarels fprintf (OutFile, "%s %s InitGaudy\n", 73240201Skarels Rotated ? "10.55" : "8.0", TwoColumn ? "true" : "false"); 73340201Skarels if (PreFeed) { 73440201Skarels fprintf (OutFile, "true DoPreFeed\n"); 73540201Skarels } 73640201Skarels fprintf (OutFile, "%%%%EndProlog\n"); 73733295Skarels } 73840201Skarels Cvted = TRUE; 73933295Skarels 74040201Skarels Page = 0; 74140201Skarels BadChars = 0; /* give each file a clean slate */ 74240201Skarels pagepending = TRUE; 74340201Skarels while ((c = getchar ()) != EOF) 74440201Skarels if ((c > 0177 || c < 0) && (!IgnoreGarbage)) { 74540201Skarels if (BadChars++ > MAXBAD) { /* allow some kruft but 74640201Skarels * not much */ 74740201Skarels fprintf (stderr, "%s: \"%s\" not a text file? Try -g.\n", 74840201Skarels prog, FileName ? FileName : "(stdin)"); 74940201Skarels if (!PipeOut) 75040201Skarels VOIDC unlink (OutName); 75140201Skarels 75240201Skarels exit (1); 75340201Skarels } 75440201Skarels } else if (c >= ' ') { 75540201Skarels if (pagepending) 75640201Skarels InitPage (); 75740201Skarels ShowChar (c); 75840201Skarels col++; 75940201Skarels } else 76040201Skarels switch (c) { 76140201Skarels case 010: /* backspace */ 76240201Skarels dX -= BSWidth; 76333295Skarels break; 76440201Skarels case 015: /* carriage return ^M */ 76540201Skarels dY = lY; 76640201Skarels dX = lX; 76733295Skarels break; 76840201Skarels case 012: /* linefeed ^J */ 76940201Skarels if (pagepending) 77040201Skarels InitPage (); 77140201Skarels if (dX != lX || dY != lY || !LPTsimulate || SeenText) { 77240201Skarels SeenText = TRUE; 77340201Skarels dY = lY = lY + crY; 77440201Skarels dX = lX = lX + crX; 77540201Skarels } else 77640201Skarels LinesLeft = LineMax; 77740201Skarels if ((dY < minY) || (--LinesLeft <= 0)) 77840201Skarels PageEject (); 77940201Skarels col = 1; 78040201Skarels break; 78140201Skarels case 033: /* escape */ 78240201Skarels switch (c = getchar ()) { 78340201Skarels case '7': /* backup one line */ 78440201Skarels dY = lY = lY - crY; 78540201Skarels dX = lX = lX - crX; 78640201Skarels break; 78740201Skarels case '8': /* backup 1/2 line */ 78840201Skarels dY -= crY / 2; 78940201Skarels dX -= crX / 2; 79040201Skarels break; 79140201Skarels case '9': /* forward 1/2 linefeed */ 79240201Skarels dY += crY / 2; 79340201Skarels dX += crX / 2; 79440201Skarels break; 79540201Skarels case 'F': /* font setting */ 79640201Skarels c = getchar (); 79740201Skarels if ('a' <= c && c <= 'z') 79840201Skarels if (fontindex[c - 'a'] >= 0) 79940201Skarels SetFont (fontindex[c - 'a']); 80040201Skarels else { 80140201Skarels fprintf (stderr, "%s: font '%c' not defined\n", 80240201Skarels prog, c); 80340201Skarels exit (1); 80440201Skarels } 80540201Skarels else { 80640201Skarels fprintf (stderr, "%s: bad font code in file: '%c'\n", 80740201Skarels prog, c); 80840201Skarels exit (1); 80940201Skarels } 81040201Skarels break; 81140201Skarels case 'D': /* date string */ 81240201Skarels VOIDC fgets (DateStr, sizeof(DateStr), stdin); 81340201Skarels FileDate = DateStr; 81440201Skarels break; 81540201Skarels case 'U': /* new "user's" heading */ 81640201Skarels { 81740201Skarels static char header[100]; 81840201Skarels VOIDC fgets (header, sizeof(header), stdin); 81933295Skarels 82040201Skarels UsersHeader = header; 82140201Skarels break; 82240201Skarels } 82340201Skarels case 'H': /* new heading */ 82440201Skarels { 82540201Skarels static char header[100]; 82640201Skarels 82740201Skarels VOIDC fgets (header, sizeof(header), stdin); 82840201Skarels 82940201Skarels ClosePage (); 83040521Skarels Header2 = header; 83140201Skarels Page = 0; 83240201Skarels break; 83340201Skarels } 83440201Skarels } 83533295Skarels break; 83640201Skarels case '%': /* included PostScript line */ 83740201Skarels { 83840201Skarels char psline[200]; 83940201Skarels VOIDC fgets (psline, sizeof(psline), stdin); 84040201Skarels 84140201Skarels fprintf (OutFile, "%s\n", psline); 84240201Skarels break; 84340201Skarels } 84440201Skarels case 014: /* form feed ^L */ 84540201Skarels PageEject (); 84640201Skarels col = 1; 84740201Skarels break; 84840201Skarels case 011: /* tab ^I */ 84940201Skarels if (pagepending) 85040201Skarels InitPage (); 85140201Skarels col = (col - 1) / 8 * 8 + 9; 85240201Skarels dX = lX + (col - 1) / 8 * TabWidth; 85340201Skarels break; 85440201Skarels default: /* other control character, take your 85540201Skarels * chances */ 85640201Skarels if (pagepending) 85740201Skarels InitPage (); 85840201Skarels ShowChar (c); 85940201Skarels col++; 86040201Skarels } 86140201Skarels ClosePage (); 86233295Skarels } 86333295Skarels 86433295Skarels 86533295Skarels /* 86640201Skarels * close the PS file 86733295Skarels */ 86840201Skarels private VOID 86940201Skarels ClosePS () 87040201Skarels { 87140201Skarels fprintf (OutFile, "%%%%Trailer\n"); 87240201Skarels if (PreFeed) { 87340201Skarels fprintf (OutFile, "false DoPreFeed\n"); 87440201Skarels } 87540201Skarels fprintf (OutFile, "EndEnscriptDoc\nEnscriptJob restore\n"); 87633295Skarels } 87733295Skarels 87833295Skarels 87940201Skarels private VOID 88040201Skarels SetTime (tval) 88140201Skarels long tval; 88240201Skarels { 88340201Skarels struct tm *tp; 88433295Skarels 88540201Skarels if (Gaudy) { 88640201Skarels tp = localtime (&tval); 88740201Skarels VOIDC sprintf (DateStr, "(%02d/%02d/%02d)(%02d:%02d:%02d)", 88840201Skarels tp->tm_year, tp->tm_mon + 1, tp->tm_mday, 88940201Skarels tp->tm_hour, tp->tm_min, tp->tm_sec); 89040201Skarels } else { 89140201Skarels VOIDC strcpy (DateStr, ctime (&tval)); 89233295Skarels 89340201Skarels DateStr[24] = '\0'; /* get rid of newline */ 89440201Skarels } 89540201Skarels 89640201Skarels FileDate = DateStr; 89733295Skarels } 89833295Skarels 89933295Skarels 90033295Skarels 90133295Skarels 90240521Skarels #define ARGS "12gGBlL:oqrRkKf:F:b:p:J:C:P:#:mhO:s:v" 90333295Skarels 90440201Skarels private VOID ParseArgs (ac, av) 90540201Skarels int ac; 90640201Skarels char **av; 90740201Skarels { 90840201Skarels int argp; 90940201Skarels 91040201Skarels while ((argp = getopt (ac, av, ARGS)) != EOF) { 91140201Skarels debugp ((stderr, "option: %c\n", argp)); 91240201Skarels switch (argp) { 91340201Skarels case '1': 91440201Skarels TwoColumn = FALSE; 91540201Skarels break; 91640201Skarels case '2': 91740201Skarels TwoColumn = TRUE; 91840201Skarels break; 91940201Skarels case 'G': 92040201Skarels Gaudy = TRUE; 92140201Skarels if (UsersHeader == NULL) 92240201Skarels UsersHeader = ""; 92340201Skarels if (Header == NULL) 92440201Skarels Header = ""; 92540538Skarels /* warning: fonts must be defined in this order! */ 92640538Skarels ResetFont(HeaderFont, GHEADFONT, GHEADSZ); 92740538Skarels if (SHeaderFont == -1) 92840538Skarels SHeaderFont = DefineFont(SHEADFONT, SHEADSZ); 92940521Skarels DateFont = DefineFont(DATEFONT, DATESZ); 93040521Skarels PgNumFont = DefineFont(PGNUMFONT, PGNUMSZ); 93140201Skarels break; 93240201Skarels case 'g': 93340201Skarels IgnoreGarbage = TRUE; 93440201Skarels break; 93540201Skarels case 'B': 93640201Skarels NoTitle = TRUE; 93740201Skarels break; 93840201Skarels case 'l': 93940201Skarels LPTsimulate = TRUE; 94040201Skarels NoTitle = TRUE; 94140201Skarels Lines = 66; 94240201Skarels break; 94340201Skarels case 'L': 94440201Skarels Lines = atoi (optarg); 94540201Skarels break; 94640201Skarels case 'o': 94740201Skarels ListOmitted = TRUE; 94840201Skarels break; 94940201Skarels case 'q': 95040201Skarels BeQuiet = TRUE; 95140201Skarels break; 95240201Skarels case 'r': 95340201Skarels Rotated = TRUE; 95440201Skarels break; 95540201Skarels case 'R': 95640201Skarels Rotated = FALSE; 95740201Skarels break; 95840201Skarels case 'k': 95940201Skarels PreFeed = TRUE; 96040201Skarels break; 96140201Skarels case 'K': 96240201Skarels PreFeed = FALSE; 96340201Skarels break; 96440201Skarels case 'f':{ 96540201Skarels register char font = 'r'; 96640201Skarels int *whichfont; 96740201Skarels 96840201Skarels if (*optarg == '-') { 96940201Skarels font = *++optarg; 97040201Skarels optarg++; 97140201Skarels } 97240201Skarels if ((font < 'a') || ('z' < font)) { 97340201Skarels fprintf (stderr, 97440201Skarels "%s: '%c' isn't a valid font designator.\n", 97540201Skarels prog, font); 97640201Skarels exit (1); 97740201Skarels } 97840201Skarels whichfont = &fontindex[font - 'a']; 97940201Skarels if (*whichfont < 0) 98040201Skarels *whichfont = nf++; 98140201Skarels decodefont (optarg, &fonts[*whichfont]); 98240521Skarels if (font == 'r') 98340521Skarels SeenFont++; 98440201Skarels } 98540201Skarels break; 98640201Skarels case 'F': 98740521Skarels if (HeaderFont == -1) 98840521Skarels HeaderFont = nf++; 98940201Skarels decodefont (optarg, &fonts[HeaderFont]); 99040201Skarels break; 99140201Skarels case 'b': 99240201Skarels UsersHeader = optarg; 99340201Skarels break; 99440521Skarels case 's': 99540521Skarels Header2 = optarg; 99640521Skarels break; 99740201Skarels case 'p': 99840201Skarels OutOnly = TRUE; 99940201Skarels VOIDC strcpy (OutName, optarg); 100040201Skarels 100140201Skarels if (strcmp (OutName, "-") == 0) 100240201Skarels PipeOut = TRUE; 100340201Skarels break; 100440201Skarels case 'h': 100540201Skarels spoolNoBurst = TRUE; 100640201Skarels break; 100740201Skarels /* BSD lpr options processing */ 100840201Skarels case 'm': 100940201Skarels spoolNotify = argp; 101040201Skarels break; 101140201Skarels case '#': 101240201Skarels spoolCopies = optarg; 101340201Skarels break; 101440201Skarels case 'C': 101540201Skarels spoolJobClass = optarg; 101640201Skarels break; 101740201Skarels case 'J': 101840201Skarels spoolJobName = optarg; 101940201Skarels break; 102040201Skarels case 'P': 102140201Skarels PrinterName = optarg; 102240201Skarels break; 102340201Skarels case '?': 102440201Skarels /* bad option */ 102540201Skarels break; 102640201Skarels case 'O': 102740201Skarels Xoffset = atof(optarg) * (double)UperInch; 102840201Skarels if (Xoffset < 0) 102940201Skarels Xoffset = 0; 103040201Skarels break; 103140521Skarels case 'v': 103240521Skarels Verbose = TRUE; 103340521Skarels break; 103440201Skarels default: 103540201Skarels break; 103633295Skarels } 103733295Skarels } 103833295Skarels } 103933295Skarels 104033295Skarels 104133295Skarels /* addarg is used to construct an argv for the spooler */ 104240201Skarels private VOID 104340201Skarels addarg (argv, argstr, argc) 104440201Skarels char **argv; 104540201Skarels char *argstr; 104640201Skarels register int *argc; 104740201Skarels { 104840201Skarels register char *p = (char *) malloc ((unsigned) (strlen (argstr) + 1)); 104940201Skarels VOIDC strcpy (p, argstr); 105040201Skarels 105140201Skarels argv[(*argc)++] = p; 105240201Skarels argv[*argc] = '\0'; 105333295Skarels } 105433295Skarels 105533295Skarels 105640201Skarels private VOID 105740201Skarels SpoolIt () 105840201Skarels { 105940201Skarels char temparg[200]; 106040201Skarels char *argstr[200]; 106140201Skarels int nargs = 0; 106233295Skarels 106333295Skarels 106440201Skarels addarg (argstr, LPR, &nargs); 106540201Skarels /* BSD spooler */ 106640201Skarels if (atoi (spoolCopies) > 1) { 106740201Skarels VOIDC sprintf (temparg, "-#%s", spoolCopies); 106833295Skarels 106940201Skarels addarg (argstr, temparg, &nargs); 107040201Skarels } 107140201Skarels if ((PrinterName == NULL) && ((PrinterName = envget ("PRINTER")) == NULL)) { 107240201Skarels PrinterName = POSTSCRIPTPRINTER; 107340201Skarels } 107440201Skarels VOIDC sprintf (temparg, "-P%s", PrinterName); 107533295Skarels 107640201Skarels addarg (argstr, temparg, &nargs); 107733295Skarels 107840201Skarels if (spoolJobClass) { 107940201Skarels addarg (argstr, "-C", &nargs); 108040201Skarels addarg (argstr, spoolJobClass, &nargs); 108140201Skarels } 108240201Skarels addarg (argstr, "-J", &nargs); 108340201Skarels if (spoolJobName) { 108440201Skarels addarg (argstr, spoolJobName, &nargs); 108540201Skarels } else { 108640201Skarels if (!FileName) 108740201Skarels addarg (argstr, "stdin", &nargs); 108840201Skarels else 108940201Skarels addarg (argstr, FileName, &nargs); 109040201Skarels } 109140201Skarels if (spoolNotify) { 109240201Skarels addarg (argstr, "-m", &nargs); 109340201Skarels } 109440201Skarels if (spoolNoBurst) { 109540201Skarels addarg (argstr, "-h", &nargs); 109640201Skarels } 109740201Skarels /* remove the temporary file after spooling */ 109840201Skarels addarg (argstr, "-r", &nargs); /* should we use a symbolic link too? */ 109940201Skarels addarg (argstr, TempName, &nargs); 110033295Skarels 110133295Skarels #ifdef DEBUG 110240201Skarels { 110340201Skarels int i; 110440201Skarels 110540201Skarels fprintf (stderr, "called spooler with: "); 110640201Skarels for (i = 0; i < nargs; i++) 110740201Skarels fprintf (stderr, "(%s)", argstr[i]); 110840201Skarels fprintf (stderr, "\n"); 110940201Skarels } 111033295Skarels #endif 111133295Skarels 111240201Skarels execvp (LPR, argstr); 111340201Skarels pexit2 (prog, "can't exec spooler", 1); 111433295Skarels } 111533295Skarels 111633295Skarels 111733295Skarels private char *eargv[60]; 111833295Skarels private int eargc = 1; 111933295Skarels 112033295Skarels 112140201Skarels main (argc, argv) 112240201Skarels int argc; 112340201Skarels char **argv; 112440201Skarels { 112540201Skarels register char *p; /* pointer to "ENSCRIPT" in env */ 112633295Skarels 112740201Skarels prog = *argv; /* argv[0] is program name */ 112833295Skarels 112940201Skarels debugp ((stderr, "PL %ld PW %ld TPL %ld TPW %ld\n", PageLength, PageWidth, TruePageLength, TruePageWidth)); 113033295Skarels 113140201Skarels if (signal (SIGINT, int1) == SIG_IGN) { 113240201Skarels VOIDC signal (SIGINT, SIG_IGN); 113340201Skarels VOIDC signal (SIGQUIT, SIG_IGN); 113440201Skarels VOIDC signal (SIGHUP, SIG_IGN); 113540201Skarels VOIDC signal (SIGTERM, SIG_IGN); 113640201Skarels } else { 113740201Skarels VOIDC signal (SIGQUIT, int1); 113840201Skarels VOIDC signal (SIGHUP, int1); 113940201Skarels VOIDC signal (SIGTERM, int1); 114040201Skarels } 114133295Skarels 114240201Skarels { 114340201Skarels register int i; 114433295Skarels 114540201Skarels for (i = 0; i < 26; i++) 114640201Skarels fontindex[i] = -1; 114740201Skarels } 114833295Skarels 114940201Skarels if ((libdir = envget ("PSLIBDIR")) == NULL) 115040201Skarels libdir = LibDir; 115140201Skarels if ((tempdir = envget ("PSTEMPDIR")) == NULL) 115240201Skarels tempdir = TempDir; 115333295Skarels 115440521Skarels Roman = CurFont = DefineFont (BODYROMAN, BODYSZ); 115540538Skarels HeaderFont = DefineFont (HEADFONT, HEADSZ); 115640201Skarels 115740201Skarels /* process args in environment variable ENSCRIPT */ 115840201Skarels if (p = envget ("ENSCRIPT")) { 115940201Skarels while (1) { 116040201Skarels register char quote = ' '; 116140201Skarels 116240201Skarels while (*p == ' ') 116340201Skarels p++; 116440201Skarels if ((*p == '"') || (*p == '\'')) 116540201Skarels quote = *p++; 116640201Skarels eargv[eargc++] = p; 116740201Skarels while ((*p != quote) && (*p != '\0')) 116840201Skarels p++; 116940201Skarels if (*p == '\0') 117040201Skarels break; 117140201Skarels *p++ = '\0'; 117240201Skarels } 117340201Skarels ParseArgs (eargc, eargv); 117440201Skarels if (eargc != optind) { 117540201Skarels fprintf (stderr, "%s: bad environment variable ENSCRIPT \"%s\"\n", 117640201Skarels prog, envget ("ENSCRIPT")); 117740201Skarels exit (1); 117840201Skarels } 117933295Skarels } 118040201Skarels /* process the command line arguments */ 118140201Skarels optind = 1; /* reset getopt global */ 118240201Skarels ParseArgs (argc, argv); 118333295Skarels 118440201Skarels /* process non-option args */ 118540201Skarels for (; optind < argc; optind++) { 118640201Skarels FileName = Header = argv[optind]; 118740201Skarels if (freopen (FileName, "r", stdin) == NULL) { 118840201Skarels fprintf (stderr, "%s: can't open %s\n", prog, FileName); 118940201Skarels exit (1); 119040201Skarels } 119140201Skarels VOIDC fstat (fileno (stdin), &S); 119233295Skarels 119340201Skarels SetTime (S.st_mtime); 119440201Skarels CopyFile (); 119540201Skarels VOIDC fclose (stdin); 119640201Skarels 119740201Skarels SeenFile = TRUE; 119833295Skarels } 119940201Skarels if (!SeenFile) { 120040201Skarels FileName = Header = Gaudy ? "" : 0; 120140201Skarels VOIDC fstat (fileno (stdin), &S); 120233295Skarels 120340201Skarels if ((S.st_mode & S_IFMT) == S_IFREG) 120440201Skarels SetTime (S.st_mtime); 120540201Skarels else 120640201Skarels SetTime (time ((long *) 0)); 120740201Skarels CopyFile (); 120840201Skarels } 120940201Skarels if (Cvted) { 121040201Skarels ClosePS (); 121140201Skarels VOIDC fclose (OutFile); 121233295Skarels 121340201Skarels OutFile = 0; 121433295Skarels } 121540201Skarels if (TruncChars && !BeQuiet) 121640201Skarels fprintf (stderr, "%s: %d characters omitted because of long lines.\n", 121740201Skarels prog, TruncChars); 121840201Skarels if (UndefChars && !BeQuiet) 121940201Skarels fprintf (stderr, "%s: %d characters omitted because of incomplete fonts.\n", 122040201Skarels prog, UndefChars); 122140521Skarels if (Verbose && (TotalPages > 0)) { 122240521Skarels fprintf(stderr,"[ %d page%s * %s cop%s ]\n", 122340521Skarels TotalPages, TotalPages > 1 ? "s" : "", 122440521Skarels spoolCopies, atoi(spoolCopies) > 1 ? "ies" : "y" ); 122533295Skarels } 122640521Skarels if (Cvted && !OutOnly) { 122740521Skarels SpoolIt (); /* does an exec */ 122840201Skarels } 122933295Skarels } 123033295Skarels 123133295Skarels 123233295Skarels /* signal catcher */ 123340201Skarels private VOID 123440201Skarels int1 () 123540201Skarels { 123640201Skarels if ((!PipeOut) && (OutName != NULL) && (*OutName != '\0')) { 123740201Skarels VOIDC unlink (OutName); 123840201Skarels } 123940201Skarels exit (1); 124033295Skarels } 1241