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