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
main(argc,argv)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
send()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
getline()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
putline(ff)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