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