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