133295Skarels #ifndef lint 233295Skarels static char Notice[] = "Copyright (c) 1985 Adobe Systems Incorporated"; 3*45782Skarels static char sccsid[] = "@(#)enscript.c 1.7 (Berkeley) 12/14/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 */ 120*45782Skarels 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 SeenText = TRUE; /* true if seen some text on this page */ 15033295Skarels private int OutOnly = FALSE; /* PS file only wanted */ 15133295Skarels private int Rotated = FALSE; /* pages to be rotated landscape */ 15233295Skarels private int PreFeed = FALSE; /* prefeed should be enabled */ 15333295Skarels private int TwoColumn = FALSE; /* two-column mode */ 15433295Skarels private int FirstCol = TRUE; /* we're printing column 1 */ 15533295Skarels private int NoTitle = FALSE; /* title line is suppressed */ 15633295Skarels private int Cvted = FALSE; /* converted a file to PS format */ 15733295Skarels 15840201Skarels private int IgnoreGarbage = FALSE; /* garbage should be ignored */ 15940521Skarels private int SeenFont = FALSE; /* we've seen a font request */ 16033295Skarels private int SeenFile = FALSE; /* a file has been processed */ 16140201Skarels private int ScannedFonts = FALSE; /* we've scanned the font file */ 16233295Skarels private char *FileName = 0; /* name of file currently being PSed */ 16333295Skarels private char *FileDate = 0; /* last mod date of file being PSed */ 16433295Skarels private char DateStr[27]; /* thanks, but no thanks ctime! */ 16540201Skarels private int spoolNoBurst = FALSE; /* no break page flag for spooler */ 16633295Skarels 16733295Skarels #ifdef BSD 16833295Skarels private char *spoolJobClass = NULL; 16933295Skarels private char *spoolJobName = NULL; 17040201Skarels 17133295Skarels #endif 17233295Skarels private char *PrinterName = NULL; 17333295Skarels private int spoolNotify = 0; 17433295Skarels private char *spoolCopies = "1"; 17533295Skarels 17633295Skarels private char tempstr[256]; /* various path names */ 17733295Skarels 17833295Skarels private int CurFont; /* current Font */ 17940201Skarels private int fontindex[26]; /* table of fonts, indexed by font designator 18040201Skarels * ('a' to 'z') */ 18140201Skarels 18233295Skarels /* indexes for default fonts */ 18333295Skarels 18433295Skarels #define Roman fontindex['r'-'a'] 18533295Skarels #define HeaderFont fontindex['h'-'a'] 18640201Skarels #define SHeaderFont fontindex['i'-'a'] 18740201Skarels #define DateFont fontindex['j'-'a'] 18840201Skarels #define PgNumFont fontindex['k'-'a'] 18933295Skarels 19033295Skarels private long cX, cY; /* current page positions */ 19133295Skarels private long dX, dY; /* desired page positions */ 19233295Skarels private long lX, lY; /* page positions of the start of the line */ 19333295Skarels private long crX, crY; /* X and Y increments to apply to CR's */ 19433295Skarels private long maxX; /* maximum x coord on line */ 19533295Skarels private long minY; /* minimum y coord on page */ 19640201Skarels private long Xoffset; /* amount to offset left margin */ 19733295Skarels 19833295Skarels #define None 0 19933295Skarels #define RelX 1 20033295Skarels #define RelY 2 20133295Skarels #define RelXY 3 20233295Skarels #define AbsX 4 20333295Skarels #define AbsY 8 20433295Skarels #define AbsXY 12 20533295Skarels 20633295Skarels private int movepending; /* moveto pending coords on stack */ 20733295Skarels private int showpending; /* number of characters waiting to be shown */ 20840201Skarels private int pagepending; /* start on next page when have something to 20940201Skarels * print */ 21040201Skarels private char *UsersHeader = NULL; /* user specified heading */ 21133295Skarels private char *Header = NULL; /* generated header (usually FileName) */ 21240521Skarels private char *Header2 = NULL; /* second header line for Gaudy */ 21333295Skarels private int Page = 0; /* current page number */ 21433295Skarels private int TotalPages = 0; /* total number of pages printed */ 21533295Skarels private int TruncChars = 0; /* number of characters truncated */ 21640201Skarels private int UndefChars = 0; /* number of characters skipped because they 21740201Skarels * weren't defined in some font */ 21840201Skarels private int BadChars = 0; /* number of bad characters seen so far */ 21933295Skarels private FILE *OutFile = NULL; /* output ps file */ 22033295Skarels 22133295Skarels 22233295Skarels /* decode a fontname string - e.g. Courier10 Helvetica-Bold12 */ 22340201Skarels private 22440201Skarels decodefont (name, f) 22540201Skarels register char *name; 22640201Skarels register struct font *f; 22740201Skarels { 22840201Skarels register char *d, *p; 22933295Skarels 23040201Skarels p = name; 23140201Skarels d = f->name; 23240201Skarels f->dsize = 0; 23340201Skarels while (isascii (*p) && (isalpha (*p) || (*p == '-'))) { 23440201Skarels *d++ = *p++; 23540201Skarels } 23640201Skarels *d++ = '\0'; 23740201Skarels while (isascii (*p) && isdigit (*p)) { 23840201Skarels f->dsize = f->dsize * 10 + *p++ - '0'; 23940201Skarels } 24040201Skarels if (*p || !f->dsize || !f->name[0]) { 24140201Skarels fprintf (stderr, "%s: poorly formed font name & size: \"%s\"\n", 24240201Skarels prog, name); 24340201Skarels exit (1); 24440201Skarels } 24533295Skarels } 24640201Skarels 24740201Skarels 24833295Skarels #define NOTDEF 0x8000 24933295Skarels #define ForAllFonts(p) for(p = &fonts[nf-1]; p >= &fonts[0]; p--) 25033295Skarels 25133295Skarels 25240201Skarels /* 25340201Skarels * Scan the font metrics directory looking for entries that match the entries 25440201Skarels * in ``fonts''. For entries that are found the data in the font description 25540201Skarels * is filled in, if any are missing, it dies horribly. 25633295Skarels */ 25740201Skarels private VOID ScanFont () 25840201Skarels { 25940201Skarels register struct font *f; 26040201Skarels register FILE *FontData;/* afm file */ 26140201Skarels char *c; 26240201Skarels int ccode, cwidth, inChars; 26340201Skarels char FontFile[512]; /* afm file name */ 26440201Skarels char afmbuf[BUFSIZ]; 26533295Skarels 26633295Skarels 26740201Skarels if (!SeenFont) { 26840201Skarels if (Lines == 0) 26940201Skarels Lines = 64; 27040201Skarels if (Rotated && TwoColumn) 27140201Skarels fonts[Roman].dsize = 7; 27233295Skarels } 27340201Skarels /* loop through fonts, find and read metric entry in dir */ 27440201Skarels ForAllFonts (f) { 27540201Skarels VOIDC mstrcat (FontFile, libdir, "/", sizeof FontFile); 27633295Skarels 27740201Skarels VOIDC mstrcat (FontFile, FontFile, f->name, sizeof FontFile); 27840201Skarels 27940201Skarels VOIDC mstrcat (FontFile, FontFile, ".afm", sizeof FontFile); 28040201Skarels 28140201Skarels if ((FontData = fopen (FontFile, "r")) == NULL) { 28240201Skarels fprintf (stderr, "%s: can't open font metrics file %s\n", 28340201Skarels prog, FontFile); 28440201Skarels exit (1); 28533295Skarels } 28640201Skarels /* read the .afm file to get the widths */ 28740201Skarels for (ccode = 0; ccode < FSIZEMAX; ccode++) 28840201Skarels f->Xwid[ccode] = NOTDEF; 28940201Skarels 29040201Skarels inChars = 0; 29140201Skarels while (fgets (afmbuf, sizeof afmbuf, FontData) != NULL) { 29240201Skarels /* strip off newline */ 29340201Skarels if ((c = INDEX (afmbuf, '\n')) == 0) { 29440201Skarels fprintf (stderr, "%s: AFM file %s line too long %s\n", 29540201Skarels prog, FontFile, afmbuf); 29640201Skarels exit (1); 29740201Skarels } 29840201Skarels *c = '\0'; 29940201Skarels if (*afmbuf == '\0') 30040201Skarels continue; 30140201Skarels if (strcmp (afmbuf, "StartCharMetrics") == 0) { 30240201Skarels inChars++; 30340201Skarels continue; 30440201Skarels } 30540201Skarels if (strcmp (afmbuf, "EndCharMetrics") == 0) 30640201Skarels break; 30740201Skarels if (inChars == 1) { 30840201Skarels if (sscanf (afmbuf, "C %d ; WX %d ;", &ccode, &cwidth) != 2) { 30940201Skarels fprintf (stderr, "%s: trouble with AFM file %s\n", 31040201Skarels prog, FontFile); 31140201Skarels exit (1); 31240201Skarels } 31340201Skarels /* get out once we see an unencoded char */ 31440201Skarels if (ccode == -1) 31540201Skarels break; 31640201Skarels if (ccode > 255) 31740201Skarels continue; 31840201Skarels f->Xwid[ccode] = 31940201Skarels (short) (((long) cwidth * (long) f->dsize * (long) UperPt) 32040201Skarels / 1000L); 32140201Skarels continue; 32240201Skarels } 32340201Skarels } 32440201Skarels VOIDC fclose (FontData); 32533295Skarels } 32633295Skarels 327*45782Skarels /* 328*45782Skarels * Tab width is problematical for proportionally-spaced fonts. 329*45782Skarels * Attempt to make tabs wide enough that things hand-tabulated 330*45782Skarels * for monospaced fonts still fit in columns. 331*45782Skarels */ 332*45782Skarels if (fonts[Roman].Xwid['0'] == fonts[Roman].Xwid['M']) 333*45782Skarels TabWidth = fonts[Roman].Xwid['0'] * 8; /* 8 * figure width */ 334*45782Skarels else 335*45782Skarels TabWidth = fonts[Roman].Xwid['0'] * 10; /* 10 * figure width */ 33640201Skarels BSWidth = fonts[Roman].Xwid[' ']; /* space width */ 33733295Skarels 33840201Skarels UperLine = (fonts[Roman].dsize + 1) * UperPt; 33933295Skarels 34040201Skarels if (LPTsimulate) { 34140201Skarels UperHLine = UperLine; 34240201Skarels Lines = LineMax = 66; 34340201Skarels } else { 34440201Skarels UperHLine = (fonts[HeaderFont].dsize + 1) * UperPt; 34540201Skarels } 34633295Skarels 34740201Skarels crX = 0; 34840201Skarels crY = -UperLine; 34933295Skarels 35033295Skarels } 35133295Skarels 35233295Skarels 35340201Skarels /* 35440201Skarels * Return a font number for the font with the indicated name and size. Adds 35540201Skarels * info to the font list for the eventual search. 35633295Skarels */ 35740201Skarels private int 35840201Skarels DefineFont (name, size) 35940201Skarels char *name; 36040201Skarels { 36140201Skarels register struct font *p; 36240201Skarels 36340201Skarels p = &fonts[nf]; 36440201Skarels VOIDC strcpy (p->name, name); 36540201Skarels 36640201Skarels p->dsize = size; 36740201Skarels return (nf++); 36833295Skarels } 36933295Skarels 37040538Skarels ResetFont(indx, name, size) 37140538Skarels char *name; 37240538Skarels { 37340538Skarels register struct font *p; 37433295Skarels 37540538Skarels p = &fonts[indx]; 37640538Skarels VOIDC strcpy (p->name, name); 37740538Skarels p->dsize = size; 37840538Skarels } 37940538Skarels 38033295Skarels /* dump the fonts to the PS file for setup */ 38140201Skarels private VOID 38240201Skarels DumpFonts () 38340201Skarels { 38440201Skarels register struct font *f; 38533295Skarels 38640201Skarels ForAllFonts (f) { 38740201Skarels fprintf (OutFile, "%d %d /%s\n", f - &fonts[0], f->dsize * UperPt, f->name); 38840201Skarels } 38940201Skarels fprintf (OutFile, "%d SetUpFonts\n", nf); 39033295Skarels } 39133295Skarels 39233295Skarels /* add a shown character to the PS file */ 39340201Skarels private VOID 39440201Skarels OUTputc (c) 39540201Skarels register int c; 39640201Skarels { 39740201Skarels if (!showpending) { 39840201Skarels putc ('(', OutFile); 39940201Skarels showpending = TRUE; 40040201Skarels } 40140201Skarels if (c == '\\' || c == '(' || c == ')') 40240201Skarels putc ('\\', OutFile); 40340201Skarels if ((c > 0176) || (c < 040)) { 40440201Skarels putc ('\\', OutFile); 40540201Skarels putc ((c >> 6) + '0', OutFile); 40640201Skarels putc (((c >> 3) & 07) + '0', OutFile); 40740201Skarels putc ((c & 07) + '0', OutFile); 40840201Skarels } else 40940201Skarels putc (c, OutFile); 41033295Skarels } 41133295Skarels 41240201Skarels /* put a correctly escaped string to the PS file */ 41340201Skarels private VOID 41440201Skarels OUTstr(s) 41540201Skarels register char *s; 41640201Skarels { 41740201Skarels if (!showpending) { 41840201Skarels putc ('(', OutFile); 41940201Skarels showpending = TRUE; 42040201Skarels } 42140201Skarels while (*s) 42240201Skarels OUTputc(*s++); 42340201Skarels 42440201Skarels putc(')', OutFile); 42540201Skarels showpending = FALSE; 42640201Skarels } 42740201Skarels 42833295Skarels /* Set the current font */ 42940201Skarels private VOID 43040201Skarels SetFont (f) 43140201Skarels int f; 43240201Skarels { 43340201Skarels FlushShow (); 43440201Skarels CurFont = f; 43540201Skarels fprintf (OutFile, "%d F\n", f); 43633295Skarels } 43733295Skarels 43840201Skarels /* 43940201Skarels * put a character onto the page at the desired X and Y positions. If the 44040201Skarels * current position doesn't agree with the desired position, put out movement 44140201Skarels * directives. Leave the current position updated to account for the 44240201Skarels * character. 44333295Skarels */ 44440201Skarels private VOID 44540201Skarels ShowChar (c) 44640201Skarels register int c; 44740201Skarels { 44840201Skarels register struct font *f; 44940201Skarels register long nX, nY; 45040201Skarels static level = 0; 45140564Skarels VOID PageEject(), InitPage(); 45233295Skarels 45340201Skarels level++; 45440201Skarels f = &fonts[CurFont]; 45533295Skarels 45640201Skarels if (f->Xwid[c] == NOTDEF) { 45740201Skarels UndefChars++; 45840201Skarels if (ListOmitted) 45940201Skarels fprintf (stderr, "%s: \\%03o not found in font %s\n", 46040201Skarels prog, c, f->name); 46140201Skarels if (level <= 1) { 46240201Skarels ShowChar ('\\'); 46340201Skarels ShowChar ((c >> 6) + '0'); 46440201Skarels ShowChar (((c >> 3) & 07) + '0'); 46540201Skarels ShowChar ((c & 07) + '0'); 46640201Skarels } 46740201Skarels level--; 46840201Skarels return; 46933295Skarels } 47040201Skarels nX = dX + f->Xwid[c]; /* resulting position after showing this char */ 47140201Skarels nY = dY; 47233295Skarels 47340201Skarels if (c != ' ' || ((cX == dX) && (cY == dY))) { 47440521Skarels /* 47540521Skarels * If character doesn't fit on this line 47640521Skarels * (and we're not at left margin), simulate newline 47740521Skarels * and then call ourselves recursively. 47840521Skarels */ 47940521Skarels if (nX > maxX && dX > lX) { 48040521Skarels SeenText = TRUE; 48140521Skarels dY = lY = lY + crY; 48240521Skarels dX = lX = lX + crX; 48340564Skarels if ((dY < minY) || (--LinesLeft <= 0)) { 48440521Skarels PageEject (); 48540564Skarels if (pagepending) 48640564Skarels InitPage (); 48740564Skarels } 48840521Skarels ShowChar(c); 48940521Skarels level--; 49040521Skarels return; 49140521Skarels } 49240521Skarels if (cX != dX) { 49340521Skarels if (cY != dY) { 49440201Skarels FlushShow (); 49540521Skarels /* absolute x, relative y */ 49640521Skarels fprintf (OutFile, "%ld %ld", dX, dY); 49740521Skarels movepending = AbsXY; 49840521Skarels } else { 49940521Skarels FlushShow (); 50040521Skarels fprintf (OutFile, "%ld", dX - cX); /* relative x */ 50140521Skarels movepending = RelX; 50240201Skarels } 50340521Skarels } else if (cY != dY) { 50440521Skarels FlushShow (); 50540521Skarels fprintf (OutFile, "%ld", dY - cY); /* relative y */ 50640521Skarels movepending = RelY; 50740521Skarels } 50840521Skarels OUTputc (c); 50940521Skarels showpending = TRUE; 51040521Skarels cX = nX; 51140521Skarels cY = nY; 51233295Skarels } 51340201Skarels dX = nX; 51440201Skarels dY = nY; 51533295Skarels 51640201Skarels level--; 51733295Skarels } 51833295Skarels 51933295Skarels /* put out a shown string to the PS file */ 52040201Skarels private VOID 52140201Skarels ShowStr (s) 52240201Skarels register char *s; 52340201Skarels { 52440201Skarels while (*s) { 52540201Skarels if (*s >= 040) 52640201Skarels ShowChar (*s); 52740201Skarels s++; 52840201Skarels } 52933295Skarels } 53033295Skarels 53133295Skarels /* flush pending show */ 53240201Skarels private 53340201Skarels FlushShow () 53440201Skarels { 53540201Skarels if (showpending) { 53640201Skarels putc (')', OutFile); 53740201Skarels switch (movepending) { 53840201Skarels case RelX: 53940201Skarels putc ('X', OutFile); 54040201Skarels break; 54140201Skarels case RelY: 54240201Skarels putc ('Y', OutFile); 54340201Skarels break; 54440201Skarels case AbsXY: 54540201Skarels putc ('B', OutFile); 54640201Skarels break; 54740201Skarels case None: 54840201Skarels putc ('S', OutFile); 54940201Skarels break; 55040201Skarels } 55140201Skarels putc ('\n', OutFile); 55240201Skarels movepending = None; 55340201Skarels showpending = FALSE; 55433295Skarels } 55533295Skarels } 55633295Skarels 55733295Skarels /* put out a page heading to the PS file */ 55840201Skarels private VOID 55940201Skarels InitPage () 56040201Skarels { 56140201Skarels char header[200]; 56240201Skarels register int OldFont = CurFont; 56333295Skarels 56440201Skarels TotalPages++; 56540201Skarels fprintf (OutFile, "%%%%Page: ? %d\n", TotalPages); 56640201Skarels fprintf (OutFile, "StartPage\n"); 56740201Skarels SeenText = FALSE; 56840201Skarels cX = cY = -1; 56940201Skarels showpending = pagepending = FALSE; 57040201Skarels FirstCol = TRUE; 57140201Skarels if (Rotated) { 57240201Skarels fprintf (OutFile, "Landscape\n"); 57340201Skarels lX = dX = UperInch / 4 + Xoffset; 57440201Skarels lY = dY = PageLength - (UperHLine * 3) / 2; 57540201Skarels maxX = TruePageLength; 57640201Skarels /* minY = (PageLength - TruePageWidth) + 3*UperLine+480; */ 57740201Skarels minY = (TruePageLength - TruePageWidth) + (TruePageWidth - PageWidth) / 2; 57840201Skarels } else { 57940201Skarels lX = dX = Xoffset + 58040201Skarels (TwoColumn? (UperInch * 0.3) : ((UperInch * 5) / 8)); 58140201Skarels lY = dY = PageLength - UperHLine; 58240201Skarels maxX = TruePageWidth; 58340201Skarels minY = (UperInch / 4); /* 0.25 inches */ 58440201Skarels } 58540201Skarels movepending = None; 58640201Skarels cX = dX; 58740201Skarels cY = dY; 58833295Skarels 58940201Skarels if (!NoTitle) { 59040201Skarels if (Gaudy) { 59140201Skarels OUTstr(UsersHeader); 59240521Skarels if (Header2) 59340521Skarels OUTstr(Header2); 59440521Skarels else 59540521Skarels OUTstr(Header); 59640201Skarels fprintf (OutFile, "[%s](%d)Gaudy\n", FileDate, ++Page); 59740201Skarels cX = cY = 0; /* force moveto here */ 59840201Skarels } else { 59940201Skarels SetFont (HeaderFont); 60040201Skarels fprintf (OutFile, "%ld %ld ", cX, cY); 60140201Skarels movepending = AbsXY; 60240201Skarels if (UsersHeader) { 60340201Skarels if (*UsersHeader == 0) { 60440201Skarels fprintf (OutFile, "()B\n"); 60540201Skarels movepending = None; 60640201Skarels showpending = FALSE; 60740201Skarels } else 60840201Skarels ShowStr (UsersHeader); 60940201Skarels } else { 61040201Skarels VOIDC sprintf (header, "%s %s %d", 61140201Skarels Header? Header : " ", FileDate, ++Page); 61240201Skarels 61340201Skarels ShowStr (header); 61440201Skarels } 61540201Skarels FlushShow (); 61633295Skarels } 61740201Skarels dX = lX = lX + crX * 2; 61840201Skarels dY = lY = lY + crY * 2; 61940201Skarels } else { 62040201Skarels /* fake it to force a moveto */ 62140201Skarels cX = cY = 0; 62233295Skarels } 62340201Skarels if (TwoColumn) 62440201Skarels maxX = maxX / 2 - BSWidth; 62540201Skarels else 62640201Skarels maxX -= ((long) (UperInch * 0.3)); 62740201Skarels LineMax = (lY - minY) / (-crY); 62840201Skarels if ((Lines <= 0) || (Lines > LineMax)) 62940201Skarels Lines = LinesLeft = LineMax; 63040201Skarels else 63140201Skarels LinesLeft = Lines; 63240201Skarels SetFont (OldFont); 63333295Skarels } 63433295Skarels 63540201Skarels private VOID 63640201Skarels ClosePage () 63740201Skarels { 63840201Skarels FlushShow (); 63940201Skarels if (!pagepending) 64040201Skarels fprintf (OutFile, "EndPage\n"); 64140201Skarels pagepending = TRUE; 64233295Skarels } 64333295Skarels 64433295Skarels /* skip to a new page */ 64540201Skarels private VOID 64640201Skarels PageEject () 64740201Skarels { 64840201Skarels if (TwoColumn && FirstCol) { 64940201Skarels FirstCol = FALSE; 65040201Skarels if (Rotated) { 65140201Skarels lY = dY = PageLength - (UperHLine * 3) / 2; 65240201Skarels lX = dX = Xoffset + TruePageLength / 2; 65340201Skarels maxX = TruePageLength - UperInch * 0.3; 65440201Skarels } else { 65540201Skarels lY = dY = PageLength - UperHLine; 65640201Skarels lX = dX = Xoffset + TruePageWidth / 2; 65740201Skarels maxX = TruePageWidth - UperInch * 0.3; 65840201Skarels } 65940201Skarels if (!NoTitle) { 66040201Skarels dX = lX = lX + crX * 2; 66140201Skarels dY = lY = lY + crY * 2; 66240201Skarels } 66340201Skarels } else 66440201Skarels ClosePage (); 66540201Skarels LinesLeft = Lines; 66640201Skarels SeenText = FALSE; 66733295Skarels } 66833295Skarels 66940201Skarels private VOID 67040201Skarels CommentHeader () 67140201Skarels { 67240201Skarels long clock; 67340201Skarels struct passwd *pswd; 67440201Skarels char hostname[40]; 67540201Skarels 67640201Skarels /* copy the file, prepending a new comment header */ 67740201Skarels fprintf (OutFile, "%%!%s\n", COMMENTVERSION); 67840201Skarels fprintf (OutFile, "%%%%Creator: "); 67940201Skarels pswd = getpwuid ((int) getuid ()); 68040201Skarels VOIDC gethostname (hostname, (int) sizeof hostname); 68140201Skarels 68240201Skarels fprintf (OutFile, "%s:%s (%s)\n", hostname, pswd->pw_name, pswd->pw_gecos); 68340201Skarels fprintf (OutFile, "%%%%Title: %s\n", (FileName ? FileName : "stdin")); 68440201Skarels fprintf (OutFile, "%%%%CreationDate: %s", (VOIDC time (&clock), ctime (&clock))); 68533295Skarels } 68633295Skarels 68733295Skarels /* Copy the standard input file to the PS file */ 68840201Skarels private VOID 68940201Skarels CopyFile () 69040201Skarels { 69140201Skarels register int c; 69233295Skarels 69340201Skarels if (OutFile == 0) { 69440201Skarels if (OutOnly) { 69540201Skarels OutFile = PipeOut ? stdout : fopen (OutName, "w"); 69640201Skarels } else { 69740201Skarels VOIDC mktemp (mstrcat (TempName, tempdir, 69840201Skarels ENSCRIPTTEMP, sizeof TempName)); 69940201Skarels VOIDC strcpy (OutName, TempName); 70040201Skarels 70140201Skarels VOIDC umask (077); 70240201Skarels 70340201Skarels OutFile = fopen (TempName, "w"); 70440201Skarels } 70533295Skarels } 70640201Skarels if (OutFile == NULL) { 70740201Skarels fprintf (stderr, "%s: can't create PS file %s\n", prog, TempName); 70840201Skarels exit (1); 70933295Skarels } 71040201Skarels if (!ScannedFonts) { 71140201Skarels ScannedFonts = TRUE; 71240201Skarels ScanFont (); 71333295Skarels } 71440201Skarels if (!Cvted) { 71540201Skarels CommentHeader (); 71640201Skarels if (nf) { 71740201Skarels register struct font *f; 71840201Skarels 71940201Skarels fprintf (OutFile, "%%%%DocumentFonts:"); 72040201Skarels ForAllFonts (f) { 72140201Skarels fprintf (OutFile, " %s", f->name); 72240201Skarels } 72340201Skarels fprintf (OutFile, "\n"); 72440201Skarels } 72540201Skarels /* copy in fixed prolog */ 72640201Skarels if (copyfile (mstrcat (tempstr, libdir, ENSCRIPTPRO, sizeof tempstr), 72740201Skarels OutFile)) { 72840201Skarels fprintf (stderr, "%s: trouble copying prolog file\n", prog); 72940201Skarels exit (1); 73040201Skarels } 73140201Skarels fprintf (OutFile, "StartEnscriptDoc %% end fixed prolog\n"); 73240201Skarels DumpFonts (); 73340201Skarels if (Gaudy) 73440201Skarels fprintf (OutFile, "%s %s InitGaudy\n", 73540201Skarels Rotated ? "10.55" : "8.0", TwoColumn ? "true" : "false"); 73640201Skarels if (PreFeed) { 73740201Skarels fprintf (OutFile, "true DoPreFeed\n"); 73840201Skarels } 73940201Skarels fprintf (OutFile, "%%%%EndProlog\n"); 74033295Skarels } 74140201Skarels Cvted = TRUE; 74233295Skarels 74340201Skarels Page = 0; 74440201Skarels BadChars = 0; /* give each file a clean slate */ 74540201Skarels pagepending = TRUE; 74640201Skarels while ((c = getchar ()) != EOF) 74740201Skarels if ((c > 0177 || c < 0) && (!IgnoreGarbage)) { 74840201Skarels if (BadChars++ > MAXBAD) { /* allow some kruft but 74940201Skarels * not much */ 75040201Skarels fprintf (stderr, "%s: \"%s\" not a text file? Try -g.\n", 75140201Skarels prog, FileName ? FileName : "(stdin)"); 75240201Skarels if (!PipeOut) 75340201Skarels VOIDC unlink (OutName); 75440201Skarels 75540201Skarels exit (1); 75640201Skarels } 75740201Skarels } else if (c >= ' ') { 75840201Skarels if (pagepending) 75940201Skarels InitPage (); 76040201Skarels ShowChar (c); 76140201Skarels } else 76240201Skarels switch (c) { 76340201Skarels case 010: /* backspace */ 76440201Skarels dX -= BSWidth; 76533295Skarels break; 76640201Skarels case 015: /* carriage return ^M */ 76740201Skarels dY = lY; 76840201Skarels dX = lX; 76933295Skarels break; 77040201Skarels case 012: /* linefeed ^J */ 77140201Skarels if (pagepending) 77240201Skarels InitPage (); 77340201Skarels if (dX != lX || dY != lY || !LPTsimulate || SeenText) { 77440201Skarels SeenText = TRUE; 77540201Skarels dY = lY = lY + crY; 77640201Skarels dX = lX = lX + crX; 77740201Skarels } else 77840201Skarels LinesLeft = LineMax; 77940201Skarels if ((dY < minY) || (--LinesLeft <= 0)) 78040201Skarels PageEject (); 78140201Skarels break; 78240201Skarels case 033: /* escape */ 78340201Skarels switch (c = getchar ()) { 78440201Skarels case '7': /* backup one line */ 78540201Skarels dY = lY = lY - crY; 78640201Skarels dX = lX = lX - crX; 78740201Skarels break; 78840201Skarels case '8': /* backup 1/2 line */ 78940201Skarels dY -= crY / 2; 79040201Skarels dX -= crX / 2; 79140201Skarels break; 79240201Skarels case '9': /* forward 1/2 linefeed */ 79340201Skarels dY += crY / 2; 79440201Skarels dX += crX / 2; 79540201Skarels break; 79640201Skarels case 'F': /* font setting */ 79740201Skarels c = getchar (); 79840201Skarels if ('a' <= c && c <= 'z') 79940201Skarels if (fontindex[c - 'a'] >= 0) 80040201Skarels SetFont (fontindex[c - 'a']); 80140201Skarels else { 80240201Skarels fprintf (stderr, "%s: font '%c' not defined\n", 80340201Skarels prog, c); 80440201Skarels exit (1); 80540201Skarels } 80640201Skarels else { 80740201Skarels fprintf (stderr, "%s: bad font code in file: '%c'\n", 80840201Skarels prog, c); 80940201Skarels exit (1); 81040201Skarels } 81140201Skarels break; 81240201Skarels case 'D': /* date string */ 81340201Skarels VOIDC fgets (DateStr, sizeof(DateStr), stdin); 81440201Skarels FileDate = DateStr; 81540201Skarels break; 81640201Skarels case 'U': /* new "user's" heading */ 81740201Skarels { 81840201Skarels static char header[100]; 81940201Skarels VOIDC fgets (header, sizeof(header), stdin); 82033295Skarels 82140201Skarels UsersHeader = header; 82240201Skarels break; 82340201Skarels } 82440201Skarels case 'H': /* new heading */ 82540201Skarels { 82640201Skarels static char header[100]; 82740201Skarels 82840201Skarels VOIDC fgets (header, sizeof(header), stdin); 82940201Skarels 83040201Skarels ClosePage (); 83140521Skarels Header2 = header; 83240201Skarels Page = 0; 83340201Skarels break; 83440201Skarels } 83540201Skarels } 83633295Skarels break; 83740201Skarels case '%': /* included PostScript line */ 83840201Skarels { 83940201Skarels char psline[200]; 84040201Skarels VOIDC fgets (psline, sizeof(psline), stdin); 84140201Skarels 84240201Skarels fprintf (OutFile, "%s\n", psline); 84340201Skarels break; 84440201Skarels } 84540201Skarels case 014: /* form feed ^L */ 84640201Skarels PageEject (); 84740201Skarels break; 84840201Skarels case 011: /* tab ^I */ 84940201Skarels if (pagepending) 85040201Skarels InitPage (); 851*45782Skarels dX += TabWidth - (dX % TabWidth); 85240201Skarels break; 85340201Skarels default: /* other control character, take your 85440201Skarels * chances */ 85540201Skarels if (pagepending) 85640201Skarels InitPage (); 85740201Skarels ShowChar (c); 85840201Skarels } 85940201Skarels ClosePage (); 86033295Skarels } 86133295Skarels 86233295Skarels 86333295Skarels /* 86440201Skarels * close the PS file 86533295Skarels */ 86640201Skarels private VOID 86740201Skarels ClosePS () 86840201Skarels { 86940201Skarels fprintf (OutFile, "%%%%Trailer\n"); 87040201Skarels if (PreFeed) { 87140201Skarels fprintf (OutFile, "false DoPreFeed\n"); 87240201Skarels } 87340201Skarels fprintf (OutFile, "EndEnscriptDoc\nEnscriptJob restore\n"); 87433295Skarels } 87533295Skarels 87633295Skarels 87740201Skarels private VOID 87840201Skarels SetTime (tval) 87940201Skarels long tval; 88040201Skarels { 88140201Skarels struct tm *tp; 88233295Skarels 88340201Skarels if (Gaudy) { 88440201Skarels tp = localtime (&tval); 88540201Skarels VOIDC sprintf (DateStr, "(%02d/%02d/%02d)(%02d:%02d:%02d)", 88640201Skarels tp->tm_year, tp->tm_mon + 1, tp->tm_mday, 88740201Skarels tp->tm_hour, tp->tm_min, tp->tm_sec); 88840201Skarels } else { 88940201Skarels VOIDC strcpy (DateStr, ctime (&tval)); 89033295Skarels 89140201Skarels DateStr[24] = '\0'; /* get rid of newline */ 89240201Skarels } 89340201Skarels 89440201Skarels FileDate = DateStr; 89533295Skarels } 89633295Skarels 89733295Skarels 89833295Skarels 89933295Skarels 90040521Skarels #define ARGS "12gGBlL:oqrRkKf:F:b:p:J:C:P:#:mhO:s:v" 90133295Skarels 90240201Skarels private VOID ParseArgs (ac, av) 90340201Skarels int ac; 90440201Skarels char **av; 90540201Skarels { 90640201Skarels int argp; 90740201Skarels 90840201Skarels while ((argp = getopt (ac, av, ARGS)) != EOF) { 90940201Skarels debugp ((stderr, "option: %c\n", argp)); 91040201Skarels switch (argp) { 91140201Skarels case '1': 91240201Skarels TwoColumn = FALSE; 91340201Skarels break; 91440201Skarels case '2': 91540201Skarels TwoColumn = TRUE; 91640201Skarels break; 91740201Skarels case 'G': 91840201Skarels Gaudy = TRUE; 91940201Skarels if (UsersHeader == NULL) 92040201Skarels UsersHeader = ""; 92140201Skarels if (Header == NULL) 92240201Skarels Header = ""; 92340538Skarels /* warning: fonts must be defined in this order! */ 92440538Skarels ResetFont(HeaderFont, GHEADFONT, GHEADSZ); 92540538Skarels if (SHeaderFont == -1) 92640538Skarels SHeaderFont = DefineFont(SHEADFONT, SHEADSZ); 92740521Skarels DateFont = DefineFont(DATEFONT, DATESZ); 92840521Skarels PgNumFont = DefineFont(PGNUMFONT, PGNUMSZ); 92940201Skarels break; 93040201Skarels case 'g': 93140201Skarels IgnoreGarbage = TRUE; 93240201Skarels break; 93340201Skarels case 'B': 93440201Skarels NoTitle = TRUE; 93540201Skarels break; 93640201Skarels case 'l': 93740201Skarels LPTsimulate = TRUE; 93840201Skarels NoTitle = TRUE; 93940201Skarels Lines = 66; 94040201Skarels break; 94140201Skarels case 'L': 94240201Skarels Lines = atoi (optarg); 94340201Skarels break; 94440201Skarels case 'o': 94540201Skarels ListOmitted = TRUE; 94640201Skarels break; 94740201Skarels case 'q': 94840201Skarels BeQuiet = TRUE; 94940201Skarels break; 95040201Skarels case 'r': 95140201Skarels Rotated = TRUE; 95240201Skarels break; 95340201Skarels case 'R': 95440201Skarels Rotated = FALSE; 95540201Skarels break; 95640201Skarels case 'k': 95740201Skarels PreFeed = TRUE; 95840201Skarels break; 95940201Skarels case 'K': 96040201Skarels PreFeed = FALSE; 96140201Skarels break; 96240201Skarels case 'f':{ 96340201Skarels register char font = 'r'; 96440201Skarels int *whichfont; 96540201Skarels 96640201Skarels if (*optarg == '-') { 96740201Skarels font = *++optarg; 96840201Skarels optarg++; 96940201Skarels } 97040201Skarels if ((font < 'a') || ('z' < font)) { 97140201Skarels fprintf (stderr, 97240201Skarels "%s: '%c' isn't a valid font designator.\n", 97340201Skarels prog, font); 97440201Skarels exit (1); 97540201Skarels } 97640201Skarels whichfont = &fontindex[font - 'a']; 97740201Skarels if (*whichfont < 0) 97840201Skarels *whichfont = nf++; 97940201Skarels decodefont (optarg, &fonts[*whichfont]); 98040521Skarels if (font == 'r') 98140521Skarels SeenFont++; 98240201Skarels } 98340201Skarels break; 98440201Skarels case 'F': 98540521Skarels if (HeaderFont == -1) 98640521Skarels HeaderFont = nf++; 98740201Skarels decodefont (optarg, &fonts[HeaderFont]); 98840201Skarels break; 98940201Skarels case 'b': 99040201Skarels UsersHeader = optarg; 99140201Skarels break; 99240521Skarels case 's': 99340521Skarels Header2 = optarg; 99440521Skarels break; 99540201Skarels case 'p': 99640201Skarels OutOnly = TRUE; 99740201Skarels VOIDC strcpy (OutName, optarg); 99840201Skarels 99940201Skarels if (strcmp (OutName, "-") == 0) 100040201Skarels PipeOut = TRUE; 100140201Skarels break; 100240201Skarels case 'h': 100340201Skarels spoolNoBurst = TRUE; 100440201Skarels break; 100540201Skarels /* BSD lpr options processing */ 100640201Skarels case 'm': 100740201Skarels spoolNotify = argp; 100840201Skarels break; 100940201Skarels case '#': 101040201Skarels spoolCopies = optarg; 101140201Skarels break; 101240201Skarels case 'C': 101340201Skarels spoolJobClass = optarg; 101440201Skarels break; 101540201Skarels case 'J': 101640201Skarels spoolJobName = optarg; 101740201Skarels break; 101840201Skarels case 'P': 101940201Skarels PrinterName = optarg; 102040201Skarels break; 102140201Skarels case '?': 102240201Skarels /* bad option */ 102340201Skarels break; 102440201Skarels case 'O': 102540201Skarels Xoffset = atof(optarg) * (double)UperInch; 102640201Skarels if (Xoffset < 0) 102740201Skarels Xoffset = 0; 102840201Skarels break; 102940521Skarels case 'v': 103040521Skarels Verbose = TRUE; 103140521Skarels break; 103240201Skarels default: 103340201Skarels break; 103433295Skarels } 103533295Skarels } 103633295Skarels } 103733295Skarels 103833295Skarels 103933295Skarels /* addarg is used to construct an argv for the spooler */ 104040201Skarels private VOID 104140201Skarels addarg (argv, argstr, argc) 104240201Skarels char **argv; 104340201Skarels char *argstr; 104440201Skarels register int *argc; 104540201Skarels { 104640201Skarels register char *p = (char *) malloc ((unsigned) (strlen (argstr) + 1)); 104740201Skarels VOIDC strcpy (p, argstr); 104840201Skarels 104940201Skarels argv[(*argc)++] = p; 105040201Skarels argv[*argc] = '\0'; 105133295Skarels } 105233295Skarels 105333295Skarels 105440201Skarels private VOID 105540201Skarels SpoolIt () 105640201Skarels { 105740201Skarels char temparg[200]; 105840201Skarels char *argstr[200]; 105940201Skarels int nargs = 0; 106033295Skarels 106133295Skarels 106240201Skarels addarg (argstr, LPR, &nargs); 106340201Skarels /* BSD spooler */ 106440201Skarels if (atoi (spoolCopies) > 1) { 106540201Skarels VOIDC sprintf (temparg, "-#%s", spoolCopies); 106633295Skarels 106740201Skarels addarg (argstr, temparg, &nargs); 106840201Skarels } 106940201Skarels if ((PrinterName == NULL) && ((PrinterName = envget ("PRINTER")) == NULL)) { 107040201Skarels PrinterName = POSTSCRIPTPRINTER; 107140201Skarels } 107240201Skarels VOIDC sprintf (temparg, "-P%s", PrinterName); 107333295Skarels 107440201Skarels addarg (argstr, temparg, &nargs); 107533295Skarels 107640201Skarels if (spoolJobClass) { 107740201Skarels addarg (argstr, "-C", &nargs); 107840201Skarels addarg (argstr, spoolJobClass, &nargs); 107940201Skarels } 108040201Skarels addarg (argstr, "-J", &nargs); 108140201Skarels if (spoolJobName) { 108240201Skarels addarg (argstr, spoolJobName, &nargs); 108340201Skarels } else { 108440201Skarels if (!FileName) 108540201Skarels addarg (argstr, "stdin", &nargs); 108640201Skarels else 108740201Skarels addarg (argstr, FileName, &nargs); 108840201Skarels } 108940201Skarels if (spoolNotify) { 109040201Skarels addarg (argstr, "-m", &nargs); 109140201Skarels } 109240201Skarels if (spoolNoBurst) { 109340201Skarels addarg (argstr, "-h", &nargs); 109440201Skarels } 109540201Skarels /* remove the temporary file after spooling */ 109640201Skarels addarg (argstr, "-r", &nargs); /* should we use a symbolic link too? */ 109740201Skarels addarg (argstr, TempName, &nargs); 109833295Skarels 109933295Skarels #ifdef DEBUG 110040201Skarels { 110140201Skarels int i; 110240201Skarels 110340201Skarels fprintf (stderr, "called spooler with: "); 110440201Skarels for (i = 0; i < nargs; i++) 110540201Skarels fprintf (stderr, "(%s)", argstr[i]); 110640201Skarels fprintf (stderr, "\n"); 110740201Skarels } 110833295Skarels #endif 110933295Skarels 111040201Skarels execvp (LPR, argstr); 111140201Skarels pexit2 (prog, "can't exec spooler", 1); 111233295Skarels } 111333295Skarels 111433295Skarels 111533295Skarels private char *eargv[60]; 111633295Skarels private int eargc = 1; 111733295Skarels 111833295Skarels 111940201Skarels main (argc, argv) 112040201Skarels int argc; 112140201Skarels char **argv; 112240201Skarels { 112340201Skarels register char *p; /* pointer to "ENSCRIPT" in env */ 112433295Skarels 112540201Skarels prog = *argv; /* argv[0] is program name */ 112633295Skarels 112740201Skarels debugp ((stderr, "PL %ld PW %ld TPL %ld TPW %ld\n", PageLength, PageWidth, TruePageLength, TruePageWidth)); 112833295Skarels 112940201Skarels if (signal (SIGINT, int1) == SIG_IGN) { 113040201Skarels VOIDC signal (SIGINT, SIG_IGN); 113140201Skarels VOIDC signal (SIGQUIT, SIG_IGN); 113240201Skarels VOIDC signal (SIGHUP, SIG_IGN); 113340201Skarels VOIDC signal (SIGTERM, SIG_IGN); 113440201Skarels } else { 113540201Skarels VOIDC signal (SIGQUIT, int1); 113640201Skarels VOIDC signal (SIGHUP, int1); 113740201Skarels VOIDC signal (SIGTERM, int1); 113840201Skarels } 113933295Skarels 114040201Skarels { 114140201Skarels register int i; 114233295Skarels 114340201Skarels for (i = 0; i < 26; i++) 114440201Skarels fontindex[i] = -1; 114540201Skarels } 114633295Skarels 114740201Skarels if ((libdir = envget ("PSLIBDIR")) == NULL) 114840201Skarels libdir = LibDir; 114940201Skarels if ((tempdir = envget ("PSTEMPDIR")) == NULL) 115040201Skarels tempdir = TempDir; 115133295Skarels 115240521Skarels Roman = CurFont = DefineFont (BODYROMAN, BODYSZ); 115340538Skarels HeaderFont = DefineFont (HEADFONT, HEADSZ); 115440201Skarels 115540201Skarels /* process args in environment variable ENSCRIPT */ 115640201Skarels if (p = envget ("ENSCRIPT")) { 115740201Skarels while (1) { 115840201Skarels register char quote = ' '; 115940201Skarels 116040201Skarels while (*p == ' ') 116140201Skarels p++; 116240201Skarels if ((*p == '"') || (*p == '\'')) 116340201Skarels quote = *p++; 116440201Skarels eargv[eargc++] = p; 116540201Skarels while ((*p != quote) && (*p != '\0')) 116640201Skarels p++; 116740201Skarels if (*p == '\0') 116840201Skarels break; 116940201Skarels *p++ = '\0'; 117040201Skarels } 117140201Skarels ParseArgs (eargc, eargv); 117240201Skarels if (eargc != optind) { 117340201Skarels fprintf (stderr, "%s: bad environment variable ENSCRIPT \"%s\"\n", 117440201Skarels prog, envget ("ENSCRIPT")); 117540201Skarels exit (1); 117640201Skarels } 117733295Skarels } 117840201Skarels /* process the command line arguments */ 117940201Skarels optind = 1; /* reset getopt global */ 118040201Skarels ParseArgs (argc, argv); 118133295Skarels 118240201Skarels /* process non-option args */ 118340201Skarels for (; optind < argc; optind++) { 118440201Skarels FileName = Header = argv[optind]; 118540201Skarels if (freopen (FileName, "r", stdin) == NULL) { 118640201Skarels fprintf (stderr, "%s: can't open %s\n", prog, FileName); 118740201Skarels exit (1); 118840201Skarels } 118940201Skarels VOIDC fstat (fileno (stdin), &S); 119033295Skarels 119140201Skarels SetTime (S.st_mtime); 119240201Skarels CopyFile (); 119340201Skarels VOIDC fclose (stdin); 119440201Skarels 119540201Skarels SeenFile = TRUE; 119633295Skarels } 119740201Skarels if (!SeenFile) { 119840201Skarels FileName = Header = Gaudy ? "" : 0; 119940201Skarels VOIDC fstat (fileno (stdin), &S); 120033295Skarels 120140201Skarels if ((S.st_mode & S_IFMT) == S_IFREG) 120240201Skarels SetTime (S.st_mtime); 120340201Skarels else 120440201Skarels SetTime (time ((long *) 0)); 120540201Skarels CopyFile (); 120640201Skarels } 120740201Skarels if (Cvted) { 120840201Skarels ClosePS (); 120940201Skarels VOIDC fclose (OutFile); 121033295Skarels 121140201Skarels OutFile = 0; 121233295Skarels } 121340201Skarels if (TruncChars && !BeQuiet) 121440201Skarels fprintf (stderr, "%s: %d characters omitted because of long lines.\n", 121540201Skarels prog, TruncChars); 121640201Skarels if (UndefChars && !BeQuiet) 121740201Skarels fprintf (stderr, "%s: %d characters omitted because of incomplete fonts.\n", 121840201Skarels prog, UndefChars); 121940521Skarels if (Verbose && (TotalPages > 0)) { 122040521Skarels fprintf(stderr,"[ %d page%s * %s cop%s ]\n", 122140521Skarels TotalPages, TotalPages > 1 ? "s" : "", 122240521Skarels spoolCopies, atoi(spoolCopies) > 1 ? "ies" : "y" ); 122333295Skarels } 122440521Skarels if (Cvted && !OutOnly) { 122540521Skarels SpoolIt (); /* does an exec */ 122640201Skarels } 122733295Skarels } 122833295Skarels 122933295Skarels 123033295Skarels /* signal catcher */ 123140201Skarels private VOID 123240201Skarels int1 () 123340201Skarels { 123440201Skarels if ((!PipeOut) && (OutName != NULL) && (*OutName != '\0')) { 123540201Skarels VOIDC unlink (OutName); 123640201Skarels } 123740201Skarels exit (1); 123833295Skarels } 1239