1 #ifndef lint 2 static char sccsid[] = "@(#)vpf.c 4.7 (Berkeley) 07/16/83"; 3 #endif 4 5 /* 6 * Varian/Versatec printer filter 7 */ 8 9 #include <signal.h> 10 #include <stdio.h> 11 #include <sys/vcmd.h> 12 13 #define LINELN 440 14 15 int pltmode[] = {VPLOT}; 16 int prtmode[] = {VPRINT}; 17 char linebuf[LINELN+1]; 18 char ovbuf[LINELN]; 19 int ov; 20 int lineno; 21 int varian = 1; /* default is the varian */ 22 int width = 132; /* default line length */ 23 int length = 58; /* 80 for 11" long paper */ 24 int npages = 1; 25 int literal; 26 char *name; /* user's login name */ 27 char *host; /* user's machine name */ 28 char *acctfile; /* accounting information file */ 29 30 main(argc, argv) 31 int argc; 32 char *argv[]; 33 { 34 register int i; 35 36 if (argv[0][strlen(argv[0])-1] == 'W') { /* Wide: the versatec. */ 37 varian = 0; 38 width = 440; 39 length = 66; 40 } 41 42 while (--argc) { 43 if (*(*++argv) == '-') { 44 switch (argv[0][1]) { 45 case 'n': 46 argc--; 47 name = *++argv; 48 break; 49 50 case 'h': 51 argc--; 52 host = *++argv; 53 break; 54 55 case 'w': 56 if ((i = atoi(&argv[0][2])) > 0 && i < LINELN) 57 width = i; 58 break; 59 60 case 'l': 61 length = atoi(&argv[0][2]); 62 break; 63 64 case 'c': /* Print input without throwing away 65 control chars and without putting 66 in page breaks. */ 67 literal++; 68 break; 69 } 70 } else 71 acctfile = *argv; 72 } 73 /* 74 * device should be open on file descriptor 1. 75 */ 76 ioctl(1, VSETSTATE, prtmode); 77 send(); 78 if (name && acctfile && access(acctfile, 02) >= 0 && 79 freopen(acctfile, "a", stdout) != NULL) { 80 printf("%7.2f\t%s:%s\n", (float)npages, host, name); 81 } 82 exit(0); 83 } 84 85 send() 86 { 87 lineno = 0; 88 while (getline()) { 89 if (varian && !literal && lineno >= length) { 90 putline(1); 91 lineno = 0; 92 } else 93 putline(0); 94 } 95 if (varian && lineno) { 96 putchar('\f'); /* be sure to end on a page boundary */ 97 npages++; 98 } 99 /* 100 * Put out an extra null to ensure varian will get an even 101 * number of good characters. 102 */ 103 putchar('\0'); 104 } 105 106 getline() 107 { 108 register col, maxcol, c; 109 110 ov = 0; 111 for (col = 0; col < width; col++) { 112 linebuf[col] = ' '; 113 ovbuf[col] = 0; 114 } 115 col = 0; 116 maxcol = 0; 117 for (;;) switch (c = getchar()) { 118 119 case EOF: 120 return(0); 121 122 case '\031': 123 /* 124 * lpd needs to use a different filter to print data so 125 * stop what we are doing and wait for lpd to restart us. 126 */ 127 if ((c = getchar()) == '\1') { 128 putchar('\0'); /* make sure even # sent */ 129 fflush(stdout); 130 kill(getpid(), SIGSTOP); 131 ioctl(1, VSETSTATE, prtmode); 132 continue; 133 } 134 ungetc(c, stdin); 135 c = '\031'; 136 /* fall through if not stop sequence */ 137 default: 138 if (c >= ' ' || literal) { 139 if (col < width) { 140 if (linebuf[col] == '_') { 141 ovbuf[col] = 0377; 142 ov++; 143 } 144 linebuf[col++] = c; 145 if (col > maxcol) 146 maxcol = col; 147 } else 148 col++; 149 } 150 continue; 151 152 case ' ': 153 col++; 154 continue; 155 156 case '\t': 157 col = (col|07) + 1; 158 continue; 159 160 case '\r': 161 col = 0; 162 continue; 163 164 case '_': 165 if (col < width) { 166 if (linebuf[col] != ' ') { 167 ovbuf[col] = 0377; 168 ov++; 169 } else 170 linebuf[col] = c; 171 col++; 172 if (col > maxcol) 173 maxcol = col; 174 } else 175 col++; 176 continue; 177 178 case '\f': 179 /* Fall through, treating a ff as a line break, too... */ 180 lineno = length - 1; 181 case '\n': 182 if (maxcol > width) 183 maxcol = width; 184 linebuf[maxcol] = '\0'; 185 if (++lineno % length == 0) 186 npages++; 187 return(1); 188 189 case '\b': 190 if (col > 0) 191 col--; 192 continue; 193 } 194 } 195 196 putline(ff) 197 int ff; 198 { 199 register char *lp; 200 register c, i; 201 202 lp = linebuf; 203 while (c = *lp++) 204 putchar(c); 205 if (ov) { 206 putchar('\n'); 207 putchar('\0'); 208 fflush(stdout); 209 ioctl(1, VSETSTATE, pltmode); 210 for (lp = ovbuf, i = ov; ov--; ) { 211 putchar(*lp & 0377); 212 putchar(*lp++ & 0377); 213 } 214 if (ov & 1) 215 putchar('\0'); 216 fflush(stdout); 217 ioctl(1, VSETSTATE, prtmode); 218 } 219 if (ff) 220 putchar('\f'); 221 else if (ov == 0) 222 putchar('\n'); 223 if (ferror(stdout)) 224 exit(1); 225 } 226