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