|
|
1.1 root 1: /*
2: * lpf -- Line printer filter
3: */
4:
5: #include <stdio.h>
6: #include <sgtty.h>
7: #include <signal.h>
8:
9: #define LINELN 132
10: #define EJLINE 63
11:
12: int anydone;
13: char linebuf[LINELN+2];
14: int ov;
15: char ovbuf[LINELN];
16: FILE *in = {stdin};
17: int lpack;
18: FILE *out;
19: char *ban;
20: int npages = 1;
21: char chrtab[][16];
22: int lineno;
23: struct sgttyb ttyb =
24: {
25: B9600,B9600,
26: 0, 0,
27: XTABS|ANYP|CBREAK,
28: };
29: char obuf[BUFSIZ];
30: int onemt();
31:
32: main(argc, argv)
33: char **argv;
34: {
35:
36: if ((out = fopen("/dev/lp", "w")) == NULL) {
37: fprintf(stderr, "Can't open printer\n");
38: exit(1);
39: }
40: setbuf(out, obuf);
41: stty(fileno(out), &ttyb);
42: if ((lpack = open("/dev/lp", 0)) < 0) {
43: fprintf(stderr, "Can't open printer\n");
44: exit(1);
45: }
46: signal(SIGEMT, onemt);
47: if (argc > 2 && argv[1][0]=='-' && argv[1][1]=='b') {
48: argc -= 2;
49: banner(ban = argv[2]);
50: argv += 2;
51: }
52: if (argc<=1) {
53: anydone |= send();
54: if (lineno > 0)
55: feedpage();
56: } else while (argc>1) {
57: if ((in = fopen(argv[1], "r")) == NULL) {
58: fprintf(stderr, "Can't find %s\n", argv[1]);
59: argv++;
60: argc--;
61: anydone |= 01;
62: continue;
63: }
64: anydone |= send();
65: argc--;
66: argv++;
67: fclose(in);
68: feedpage();
69: }
70: fflush(out);
71: stty(fileno(out), &ttyb);
72: if (anydone==0)
73: exit(1);
74: if (ferror(out)) {
75: fprintf(out, "Printer IO error\n");
76: exit(1);
77: }
78: fclose(out);
79: if (ban && access("/usr/adm/lpacct", 02)>=0
80: && (out = fopen("/usr/adm/lpacct", "a"))!=NULL) {
81: fprintf(out, "%4d %s\n", npages, ban);
82: }
83: return(0);
84: }
85:
86: send()
87: {
88: register int nskipped;
89:
90: lineno = 0;
91: nskipped = 0;
92: while (getline()) {
93: if (lineno==0 && linebuf[0]==0 && nskipped<3) {
94: nskipped ++;
95: continue;
96: }
97: if (lineno >= EJLINE) {
98: nskipped = 0;
99: putline(1);
100: lineno = 0;
101: } else {
102: putline(0);
103: lineno++;
104: }
105: }
106: if (lineno>0)
107: npages++;
108: return(1);
109: }
110:
111: getline()
112: {
113: register int col, maxcol, c;
114:
115: ov = 0;
116: for (col=0; col<LINELN; col++) {
117: linebuf[col] = ' ';
118: ovbuf[col] = 0;
119: }
120: col = 0;
121: maxcol = 0;
122: for (;;) switch (c = getc(in)) {
123:
124: case EOF:
125: return(0);
126:
127: default:
128: if (c>=' ') {
129: if (col < LINELN) {
130: if (linebuf[col]=='_') {
131: ov++;
132: ovbuf[col] = '_';
133: }
134: linebuf[col++] = c;
135: if (col > maxcol)
136: maxcol = col;
137: }
138: }
139: continue;
140:
141: case '\f':
142: lineno = EJLINE;
143: continue;
144:
145: case ' ':
146: col++;
147: continue;
148:
149: case '\t':
150: col = (col|07) + 1;
151: if (col>maxcol)
152: maxcol = col;
153: continue;
154:
155: case '\r':
156: col = 0;
157: continue;
158:
159: case '_':
160: if (col>=LINELN) {
161: col++;
162: continue;
163: }
164: if (linebuf[col]!=' ') {
165: ovbuf[col] = '_';
166: ov++;
167: } else
168: linebuf[col] = c;
169: col++;
170: if (col>maxcol)
171: maxcol = col;
172: continue;
173:
174: case '\n':
175: if (maxcol>=LINELN)
176: maxcol = LINELN;
177: linebuf[maxcol] = 0;
178: return(1);
179:
180: case '\b':
181: if (col>0)
182: col--;
183: continue;
184: }
185: }
186:
187: putline(ff)
188: {
189: register char *lp, *ep;
190: register int c;
191: extern errno;
192: int i, j;
193:
194: errno = 0;
195: /*
196: if (ov) do {
197: for (ep= &ovbuf[LINELN-1]; *ep == 0; ep--)
198: continue;
199: for (lp=ovbuf; lp <= ep; lp++)
200: putc(*lp ? *lp : ' ', out);
201: } while (ack() == 0);
202: */
203: again:
204: lp = linebuf;
205: while (c = *lp++)
206: putc(c, out);
207: if (ff) {
208: putc('\014', out);
209: npages++;
210: } else
211: putc('\n', out);
212: if (ack() == 0)
213: goto again;
214: if (ferror(out)) {
215: printf("Printer IO error\n");
216: exit(1);
217: }
218: }
219:
220: banner(s)
221: char *s;
222: {
223: long timeb;
224: register char *sp;
225: int i, j, t;
226:
227: for (i = 0; i < 16; i++)
228: do
229: putc ('\n', out);
230: while (ack() == 0);
231: for (i=0; i<16; i++) {
232: do {
233: fprintf(out, " ");
234: for (sp=s; *sp; sp++) {
235: if (*sp<=' '|| *sp >'}')
236: continue;
237: fprintf(out, " ");
238: t = chrtab[*sp - ' '][i];
239: for (j=7; j>=0; j--)
240: if ((t>>j) & 01)
241: putc('X', out);
242: else
243: putc(' ', out);
244: }
245: putc('\n', out);
246: } while (ack() == 0);
247: }
248: for (i = 0; i < 8; i++) {
249: do
250: putc ('\n', out);
251: while (ack() == 0);
252: }
253: do {
254: fprintf(out, " ");
255: fprintf(out, (time(&timeb), ctime(&timeb)));
256: fprintf(out, "\n");
257: } while (ack() == 0);
258: do {
259: fprintf(out, "\014");
260: } while (ack() == 0);
261: }
262:
263: onemt()
264: {
265:
266: feedpage();
267: exit(0);
268: }
269:
270: #define ACK 06
271: #define NAK 025
272: #define STX 2
273: #define ETX 3
274:
275: nothing()
276: {
277: ;
278: }
279:
280: ack()
281: {
282: char buf[256];
283:
284: int i = STX;
285: write(fileno(out), &i, 1);
286: putc('\r', out);
287: putc(ETX, out);
288: fflush(out);
289: alarm(5);
290: signal(SIGALRM, nothing);
291: i = read(lpack, buf, 256);
292: if (buf[0] == NAK)
293: sleep(1);
294: return (buf[0] == ACK);
295: }
296:
297: feedpage()
298: {
299: int retry = 0;
300:
301: fprintf(out, "\014");
302: ack();
303: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.