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