|
|
1.1 root 1: /*
2: * Line-printer daemon
3: */
4:
5: #include <sys/types.h>
6: #include <stdio.h>
7: #include <dir.h>
8: #include <signal.h>
9: #include <stat.h>
10: #include <sgtty.h>
11:
12: char line[128];
13: char banbuf[64];
14: int linel;
15: FILE *dfb;
16: char dfname[26] = "/usr/spool/lpd/";
17: int waittm = 60;
18: struct dir dbuf;
19: int onalrm();
20:
21: main(argc, argv)
22: {
23: register char *p1, *p2;
24: register int df;
25: register FILE *dp;
26: struct stat stb;
27:
28: signal(SIGHUP, SIG_IGN);
29: signal(SIGINT, SIG_IGN);
30: signal(SIGQUIT, SIG_IGN);
31: signal(SIGTERM, SIG_IGN);
32: /*
33: * Close all files, open root as 0, 1, 2
34: * to assure standard environment
35: */
36: for (df=0; df<=15; df++)
37: close(df);
38: open("/", 0);
39: dup(0);
40: dup(0);
41: if (stat("/usr/spool/lpd/lock", &stb) >= 0)
42: exit(0);
43: if ((df=creat("/usr/spool/lpd/lock", 0)) < 0)
44: exit(0);
45: close(df);
46: if (fork())
47: exit(0);
48: again:
49: dp = fopen("/usr/spool/lpd", "r");
50: do {
51: if (fread(&dbuf, sizeof dbuf, 1, dp) != 1) {
52: feedpage();
53: unlink("/usr/spool/lpd/lock");
54: exit(0);
55: }
56: } while (dbuf.d_ino==0 || dbuf.d_name[0]!='d' || dbuf.d_name[1]!='f');
57: fclose(dp);
58: strcpy(dfname, "/usr/spool/lpd/");
59: strcatn(dfname, dbuf.d_name, DIRSIZ);
60: if (trysend(dfname) == 0)
61: goto again;
62: sleep(waittm);
63: goto again;
64: }
65:
66: trysend(file)
67: char *file;
68: {
69: register char *p1, *p2;
70: register int i;
71: extern int badexit();
72:
73: dfb = fopen(file, "r");
74: if (dfb == NULL)
75: return(0);
76: banbuf[0] = 0;
77: while (getline()) switch (line[0]) {
78: case 'L':
79: p1 = line+1;
80: p2 = banbuf;
81: while (*p2++ = *p1++);
82: continue;
83:
84: case 'F':
85: if (send())
86: return(1);
87: continue;
88:
89: case 'U':
90: continue;
91:
92: case 'M':
93: continue;
94: }
95: /*
96: * Second pass.
97: * Unlink files and send mail.
98: */
99: fseek(dfb, 0L, 0);
100: while (getline()) switch (line[0]) {
101:
102: default:
103: continue;
104:
105: case 'U':
106: unlink(&line[1]);
107: continue;
108:
109: case 'M':
110: sendmail();
111: continue;
112: }
113: fclose(dfb);
114: unlink(file);
115: }
116:
117: sendmail()
118: {
119: static int p[2];
120: register i;
121: int stat;
122:
123: pipe(p);
124: if (fork()==0) {
125: alarm(0);
126: if (p[0] != 0) {
127: close(0);
128: dup(p[0]);
129: close(p[0]);
130: }
131: close(p[1]);
132: for (i=3; i<=15; i++)
133: close(i);
134: execl("/bin/mail", "mail", &line[1], 0);
135: exit(0);
136: }
137: write(p[1], "Your printer job is done\n", 25);
138: close(p[0]);
139: close(p[1]);
140: wait(&stat);
141: }
142:
143: getline()
144: {
145: register char *lp;
146: register int c;
147:
148: lp = line;
149: linel = 0;
150: while ((c = getc(dfb)) != '\n') {
151: if (c<0)
152: return(0);
153: if (c=='\t') {
154: do {
155: *lp++ = ' ';
156: linel++;
157: } while ((linel & 07) != 0);
158: continue;
159: }
160: *lp++ = c;
161: linel++;
162: }
163: *lp++ = 0;
164: return(1);
165: }
166:
167: int pid;
168:
169: send()
170: {
171: int p;
172:
173: if (pid = fork()) {
174: if (pid == -1)
175: return(1);
176: setexit();
177: signal(SIGALRM, onalrm);
178: alarm(30);
179: wait(&p);
180: alarm(0);
181: return(p);
182: }
183: if (banbuf[0]) {
184: execl("/usr/lib/lpf", "lpf", "-b", banbuf, line+1, 0);
185: return(1);
186: }
187: execl("/usr/lib/lpf", "lpf", line, 0);
188: return(1);
189: }
190:
191: onalrm()
192: {
193: struct stat stb;
194:
195: signal(SIGALRM, onalrm);
196: if (stat(dfname, &stb) < 0)
197: kill(pid, SIGEMT);
198: reset();
199: }
200:
201: struct sgttyb ttyb = {
202: B9600, B9600,
203: 0, 0,
204: XTABS|ANYP|CBREAK
205: };
206:
207: FILE *out;
208: int lpack;
209:
210: feedpage()
211: {
212: register int i = 66;
213: FILE *lp;
214: int retry = 0;
215:
216: out = fopen("/dev/lp", "w");
217: if (out == NULL)
218: return;
219: lpack = open("/dev/lp", 0);
220: if (lpack < 0) {
221: fclose(lp);
222: return;
223: }
224: stty(fileno(out), &ttyb);
225: putc(2, out);
226: putc('\f', out);
227: putc(3, out);
228: ack();
229: fclose(out);
230: close(lpack);
231: }
232:
233: #define ACK 06
234: #define NAK 025
235: #define STX 2
236: #define ETX 3
237:
238: nothing()
239: {
240: ;
241: }
242:
243: ack()
244: {
245: char buf[256];
246:
247: int i = STX;
248: write(fileno(out), &i, 1);
249: putc('\r', out);
250: putc(ETX, out);
251: fflush(out);
252: alarm(5);
253: signal(SIGALRM, nothing);
254: i = read(lpack, buf, 256);
255: if (buf[0] == NAK)
256: sleep(1);
257: return (buf[0] == ACK);
258: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.