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