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