Commit | Line | Data |
---|---|---|
15e5cd83 BJ |
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|ECHO | |
205 | }; | |
206 | ||
207 | feedpage() | |
208 | { | |
209 | register int i = 66; | |
210 | FILE *lp; | |
211 | ||
212 | lp = fopen("/dev/lp", "w"); | |
213 | if (lp == NULL) | |
214 | return; | |
215 | stty(fileno(lp), &ttyb); | |
216 | while (i > 0) | |
217 | fprintf(lp, "\n"), i--; | |
218 | fclose(lp); | |
219 | } |