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