xref: /csrg-svn/old/vfilters/vpsf/vpsf.c (revision 11582)
1 /*	vpsf.c	4.2	83/03/17	*/
2 /*
3  * Versatec printer filter
4  * 	make wide listings by placing pages side by side
5  */
6 
7 #include <signal.h>
8 #include <stdio.h>
9 #include <sys/vcmd.h>
10 
11 #define	LINELN 440
12 #define	PAGELN	86
13 #define	LMARG	10
14 
15 int	pltmode[] = {VPLOT, 0, 0};
16 int	prtmode[] = {VPRINT, 0, 0};
17 
18 char	screen[PAGELN][LINELN];
19 char	ul[PAGELN][LINELN];
20 char	anyul[PAGELN];
21 int	origin;
22 int	outline;
23 int	outcol;
24 int	npages;
25 int	width = 106;	/* page width */
26 int	length = 86;	/* page length */
27 
28 int	literal;
29 char	*name;		/* user's login name */
30 char	*host;		/* user's machine name */
31 char	*acctfile;	/* accounting information file */
32 
33 onintr()
34 {
35 	signal(SIGTERM, SIG_IGN);
36 	exit(1);
37 }
38 
39 main(argc, argv)
40 	int argc;
41 	char *argv[];
42 {
43 	register int i;
44 
45 	signal(SIGHUP, SIG_IGN);
46 	signal(SIGINT, SIG_IGN);
47 	signal(SIGQUIT, SIG_IGN);
48 	signal(SIGTERM, onintr);
49 
50 	while (--argc) {
51 		if (*(*++argv) == '-') {
52 			switch (argv[0][1]) {
53 			case 'n':
54 				argc--;
55 				name = *++argv;
56 				break;
57 
58 			case 'h':
59 				argc--;
60 				host = *++argv;
61 				break;
62 
63 			case 'w':
64 				if ((i = atoi(&argv[0][2])) > 0 && i <= LINELN)
65 					width = i;
66 				break;
67 
68 			case 'l':
69 				if ((i = atoi(&argv[0][2])) > 0 && i <= PAGELN)
70 					length = i;
71 				break;
72 
73 			case 'c':	/* Print input without throwing away
74 					   control chars and without putting
75 					   in page breaks. */
76 				literal++;
77 				break;
78 			}
79 		} else
80 			acctfile = *argv;
81 	}
82 
83 	/*
84 	 * input file is open on file descriptor 0.
85 	 * vp should be open on file descriptor 1.
86 	 * The error log file is open on file descriptor 2.
87 	 */
88 	ioctl(1, VSETSTATE, prtmode);
89 	process();
90 
91 	/*
92 	 * Put out an extra null to ensure versatec will get an even
93 	 * number of good characters.
94 	 */
95 	putchar('\0');
96 
97 	if (ferror(stdout))
98 		exit(1);
99 	if (name && acctfile && access(acctfile, 02) >= 0 &&
100 	    freopen(acctfile, "a", stdout) != NULL) {
101 		if (host)
102 			printf("%7.2f\t%s:%s\n", (float)npages, host, name);
103 		else
104 			printf("%7.2f\t%s\n", (float)npages, name);
105 	}
106 	exit(0);
107 }
108 
109 process()
110 {
111 	register int c;
112 
113 	clear(screen, sizeof(screen));
114 	origin = LMARG;
115 	outcol = LMARG;
116 	cutmark(LMARG);
117 
118 	while ((c = getchar()) != EOF)
119 		switch (c) {
120 		case ' ':
121 			outcol++;
122 			break;
123 
124 		case '\t':
125 			outcol = ((outcol - origin) | 07) + origin + 1;
126 			break;
127 
128 		case '\b':
129 			if (outcol > origin)
130 				outcol--;
131 			break;
132 
133 		case '\r':
134 			outcol = origin;
135 			break;
136 
137 		case '\f':
138 			outline = length;
139 			/* fall into ... */
140 
141 		case '\n':
142 			if (++outline >= length) {
143 				origin += width;
144 				if (origin + width > LINELN) {
145 					cutmark(origin);
146 					oflush();
147 					break;
148 				}
149 				outline = 0;
150 				cutmark(origin);
151 			}
152 			outcol = origin;
153 			break;
154 
155 		default:
156 			outchar(c);
157 			break;
158 		}
159 
160 	if (outline || origin != LMARG) {
161 		cutmark(origin + width);
162 		oflush();
163 	}
164 	printf("\n\n\n\n\n");
165 }
166 
167 outchar(c)
168 	register int c;
169 {
170 	register char *cp;
171 	register int d;
172 
173 	if (!literal && (c < 040 || c >= 0177))
174 		return;
175 	if (outcol >= LINELN) {
176 		outcol++;
177 		return;
178 	}
179 	cp = &screen[outline][outcol];
180 	d = *cp;
181 	if (d != ' ') {
182 		if (d == '_' || c == '_') {
183 			if (c == d) {
184 				outcol++;
185 				return;
186 			}
187 			if (anyul[outline] == 0)
188 				clear(ul[outline], LINELN);
189 			anyul[outline] = 1;
190 			ul[outline][outcol] = 0377;
191 			if (c == '_')
192 				c = d;
193 		}
194 	}
195 	*cp = c;
196 	outcol++;
197 }
198 
199 oflush()
200 {
201 	register char *cp, *dp;
202 	register int i, j, oc, dc, c;
203 
204 	npages++;
205 	putchar('\n');
206 	for (i = 0; i < length; i++)
207 		putline(i);
208 	for (i = 0; i < LINELN; i++)
209 		putchar('_');
210 	putchar('\n');
211 	clear(screen, sizeof(screen));
212 	outline = 0;
213 	outcol = LMARG;
214 	origin = LMARG;
215 	cutmark(LMARG);
216 }
217 
218 clear(cp, i)
219 	register char *cp;
220 	register int i;
221 {
222 	if (i > 0)
223 		do
224 			*cp++ = ' ';
225 		while (--i);
226 }
227 
228 cutmark(o)
229 	register int o;
230 {
231 	register int i;
232 
233 	screen[0][o - LMARG] = '|';
234 	screen[1][o - LMARG] = '|';
235 	screen[length - 1][o - LMARG] = '|';
236 	screen[length - 2][o - LMARG] = '|';
237 }
238 
239 putline(n)
240 	register int n;
241 {
242 	register char *cp;
243 	register int j;
244 
245 	fwrite(screen[n], sizeof(char), sizeof(screen[0]), stdout);
246 	if (anyul[n]) {
247 		putchar('\n');
248 		putchar('\0');
249 		fflush(stdout);
250 		ioctl(1, VSETSTATE, pltmode);
251 		cp = ul[n];
252 		j = LINELN;
253 		do {
254 			putchar(*cp & 0377);
255 			putchar(*cp++ & 0377);
256 		} while (--j);
257 		fflush(stdout);
258 		ioctl(1, VSETSTATE, prtmode);
259 	} else
260 		putchar('\n');
261 	if (ferror(stdout))
262 		exit(1);
263 }
264