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