changes for new printer daemon.
[unix-history] / usr / src / usr.sbin / lpr / filters / lpf.c
CommitLineData
dfc1084e 1/* lpf.c 4.10 83/04/29
8f85bfee
RC
2 * filter which reads the output of nroff and converts lines
3 * with ^H's to overwritten lines. Thus this works like 'ul'
4 * but is much better: it can handle more than 2 overwrites
5 * and it is written with some style.
6 * modified by kls to use register references instead of arrays
7 * to try to gain a little speed.
3f5fc8d0 8 */
3f5fc8d0
BJ
9#include <stdio.h>
10#include <signal.h>
11
8f85bfee
RC
12#define MAXWIDTH 132
13#define MAXREP 10
3f5fc8d0 14
8f85bfee
RC
15char buf[MAXREP][MAXWIDTH];
16int maxcol[MAXREP] = {-1};
aaf17c3e
RC
17int lineno;
18int width = 132; /* default line length */
19int length = 66; /* page length */
20int npages = 1;
21int literal; /* print control characters */
22char *name; /* user's login name */
23char *host; /* user's machine name */
24char *acctfile; /* accounting information file */
3f5fc8d0 25
5af70e5e
RC
26onintr()
27{
28 signal(SIGTERM, SIG_IGN);
29 exit(1);
30}
31
32main(argc, argv)
33 int argc;
34 char *argv[];
3f5fc8d0 35{
8f85bfee
RC
36 register FILE *p = stdin, *o = stdout;
37 register int i, col;
38 register char *cp;
39 int done, linedone, maxrep;
40 char ch, *limit;
41
5af70e5e
RC
42 signal(SIGHUP, SIG_IGN);
43 signal(SIGINT, SIG_IGN);
44 signal(SIGQUIT, SIG_IGN);
45 signal(SIGTERM, onintr);
46
aaf17c3e
RC
47 while (--argc) {
48 if (*(cp = *++argv) == '-') {
49 switch (cp[1]) {
50 case 'n':
51 argc--;
52 name = *++argv;
53 break;
54
55 case 'h':
56 argc--;
57 host = *++argv;
58 break;
59
60 case 'w':
61 if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH)
62 width = i;
63 break;
64
65 case 'l':
66 length = atoi(&cp[2]);
67 break;
68
69 case 'c': /* Print control chars */
70 literal++;
71 break;
72 }
73 } else
74 acctfile = cp;
75 }
76
8f85bfee
RC
77 for (cp = buf[0], limit = buf[MAXREP]; cp < limit; *cp++ = ' ');
78 done = 0;
79
80 while (!done) {
81 col = 0;
3e2fb2e5 82 maxrep = -1;
8f85bfee
RC
83 linedone = 0;
84 while (!linedone) {
85 switch (ch = getc(p)) {
86 case EOF:
87 linedone = done = 1;
88 ch = '\n';
89 break;
90
8f85bfee 91 case '\f':
aaf17c3e 92 lineno = length;
8f85bfee 93 case '\n':
3e2fb2e5
RC
94 if (maxrep < 0)
95 maxrep = 0;
8f85bfee
RC
96 linedone = 1;
97 break;
98
99 case '\b':
100 if (col-- < 0)
101 col = 0;
102 break;
103
104 case '\r':
105 col = 0;
106 break;
107
108 case '\t':
109 col = (col | 07) + 1;
110 break;
111
09d5163a
RC
112 case '\031':
113 /*
114 * lpd needs to use a different filter to
115 * print data so stop what we are doing and
116 * wait for lpd to restart us.
117 */
118 if ((ch = getchar()) == '\1') {
119 fflush(stdout);
120 kill(getpid(), SIGSTOP);
121 break;
122 } else {
123 ungetc(ch, stdin);
124 ch = '\031';
125 }
09d5163a 126
8f85bfee 127 default:
aaf17c3e 128 if (col >= width || !literal && ch < ' ')
8f85bfee
RC
129 break;
130 cp = &buf[0][col];
131 for (i = 0; i < MAXREP; i++) {
132 if (i > maxrep)
133 maxrep = i;
134 if (*cp == ' ') {
135 *cp = ch;
136 if (col > maxcol[i])
137 maxcol[i] = col;
138 break;
139 }
140 cp += MAXWIDTH;
141 }
142 col++;
143 break;
3f5fc8d0
BJ
144 }
145 }
3f5fc8d0 146
8f85bfee
RC
147 /* print out lines */
148 for (i = 0; i <= maxrep; i++) {
149 for (cp = buf[i], limit = cp+maxcol[i]; cp <= limit;) {
150 putc(*cp, o);
151 *cp++ = ' ';
152 }
153 if (i < maxrep)
154 putc('\r', o);
155 else
156 putc(ch, o);
3e2fb2e5
RC
157 if (++lineno >= length) {
158 npages++;
159 lineno = 0;
160 }
8f85bfee 161 maxcol[i] = -1;
fdaeefb7 162 }
3f5fc8d0 163 }
aaf17c3e
RC
164 if (lineno) { /* be sure to end on a page boundary */
165 putchar('\f');
166 npages++;
167 }
168 if (name && acctfile && access(acctfile, 02) >= 0 &&
169 freopen(acctfile, "a", stdout) != NULL) {
170 printf("%7.2f\t%s:%s\n", (float)npages, host, name);
171 }
172 exit(0);
3f5fc8d0 173}