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