/* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ #ifndef lint static char sccsid[] = "@(#)vpf.c 5.1 (Berkeley) 5/15/85"; #endif not lint /* * Varian/Versatec printer filter */ #include #include #include #define LINELN 440 int pltmode[] = {VPLOT}; int prtmode[] = {VPRINT}; char linebuf[LINELN+1]; char ovbuf[LINELN]; int ov; int lineno; int varian = 1; /* default is the varian */ int width = 132; /* default line length */ int indent = 0; /* default indent length */ int length = 58; /* 80 for 11" long paper */ int npages = 1; int literal; char *name; /* user's login name */ char *host; /* user's machine name */ char *acctfile; /* accounting information file */ main(argc, argv) int argc; char *argv[]; { register int i; if (argv[0][strlen(argv[0])-1] == 'W') { /* Wide: the versatec. */ varian = 0; width = 440; length = 66; } while (--argc) { if (*(*++argv) == '-') { switch (argv[0][1]) { case 'n': argc--; name = *++argv; break; case 'h': argc--; host = *++argv; break; case 'w': if ((i = atoi(&argv[0][2])) > 0 && i < LINELN) width = i; break; case 'l': length = atoi(&argv[0][2]); break; case 'i': if ((i = atoi(&argv[0][2])) >= 0 && i < LINELN - 1) indent = i; break; case 'c': /* Print input without throwing away control chars and without putting in page breaks. */ literal++; break; } } else acctfile = *argv; } /* * device should be open on file descriptor 1. */ ioctl(1, VSETSTATE, prtmode); send(); if (name && acctfile && access(acctfile, 02) >= 0 && freopen(acctfile, "a", stdout) != NULL) { printf("%7.2f\t%s:%s\n", (float)npages, host, name); } exit(0); } send() { lineno = 0; while (getline()) { if (varian && !literal && lineno >= length) { putline(1); lineno = 0; } else putline(0); } if (varian && lineno) { putchar('\f'); /* be sure to end on a page boundary */ npages++; } /* * Put out an extra null to ensure varian will get an even * number of good characters. */ putchar('\0'); } getline() { register col, maxcol, c; ov = 0; for (col = 0; col < width; col++) { linebuf[col] = ' '; ovbuf[col] = 0; } col = indent; maxcol = 0; for (;;) switch (c = getchar()) { case EOF: return(0); case '\031': /* * lpd needs to use a different filter to print data so * stop what we are doing and wait for lpd to restart us. */ if ((c = getchar()) == '\1') { putchar('\0'); /* make sure even # sent */ fflush(stdout); kill(getpid(), SIGSTOP); ioctl(1, VSETSTATE, prtmode); continue; } ungetc(c, stdin); c = '\031'; /* fall through if not stop sequence */ default: if (c >= ' ' || literal) { if (col < width) { if (linebuf[col] == '_') { ovbuf[col] = 0377; ov++; } linebuf[col++] = c; if (col > maxcol) maxcol = col; } else col++; } continue; case ' ': col++; continue; case '\t': col = (col|07) + 1; continue; case '\r': col = 0; continue; case '_': if (col < width) { if (linebuf[col] != ' ') { ovbuf[col] = 0377; ov++; } else linebuf[col] = c; col++; if (col > maxcol) maxcol = col; } else col++; continue; case '\f': /* Fall through, treating a ff as a line break, too... */ lineno = length - 1; case '\n': if (maxcol > width) maxcol = width; linebuf[maxcol] = '\0'; if (++lineno % length == 0) npages++; return(1); case '\b': if (col > 0) col--; continue; } } putline(ff) int ff; { register char *lp; register c, i; lp = linebuf; while (c = *lp++) putchar(c); if (ov) { putchar('\n'); putchar('\0'); fflush(stdout); ioctl(1, VSETSTATE, pltmode); for (lp = ovbuf, i = ov; ov--; ) { putchar(*lp & 0377); putchar(*lp++ & 0377); } if (ov & 1) putchar('\0'); fflush(stdout); ioctl(1, VSETSTATE, prtmode); } if (ff) putchar('\f'); else if (ov == 0) putchar('\n'); if (ferror(stdout)) exit(1); }