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