Commit | Line | Data |
---|---|---|
0d2cd677 BJ |
1 | #define CONSOLE "/dev/console" |
2 | #define dprcons if (debug) prcons | |
3 | /* | |
4916dcc2 | 4 | * vpd.c updated %G% |
0d2cd677 BJ |
5 | * Varian or Versatec printer daemon |
6 | */ | |
fef7eb28 | 7 | char vpdSCCSid[] = "@(#)vpd.c 1.3\t%G%"; |
4916dcc2 | 8 | |
0d2cd677 | 9 | #include <stdio.h> |
fef7eb28 | 10 | #include <sys/param.h> |
0d2cd677 BJ |
11 | #include <dir.h> |
12 | #include <signal.h> | |
13 | #include <stat.h> | |
14 | #include <sgtty.h> | |
15 | #include <errno.h> | |
16 | #include <sys/vcmd.h> | |
17 | #include <wait.h> | |
18 | ||
19 | int debug; | |
20 | extern int errno; | |
21 | ||
22 | #define VRAST "/usr/local/lib/vrast" | |
4916dcc2 DH |
23 | #define VDMP "/usr/lib/vdmp" |
24 | #define VPLTDMP "/usr/lib/vpltdmp" | |
0d2cd677 BJ |
25 | |
26 | #ifdef VARIAN | |
27 | #define DEVICE "/dev/va0" | |
28 | #define DFNAME "/usr/spool/vad/" | |
29 | #define SPOOLDIR "/usr/spool/vad" | |
30 | #define NAME "Varian" | |
31 | #endif | |
32 | ||
33 | #ifdef VERSATEC | |
34 | #define DEVICE "/dev/vp0" | |
35 | #define DFNAME "/usr/spool/vpd/" | |
36 | #define SPOOLDIR "/usr/spool/vpd" | |
37 | #define NAME "Versatec" | |
38 | #endif | |
39 | ||
40 | int prtmode[] = {VPRINT, 0, 0}; | |
41 | ||
42 | char line[128]; | |
43 | char linep[127]; | |
44 | char banbuf[64]; | |
4916dcc2 | 45 | char banner[512]; |
0d2cd677 BJ |
46 | char printflag; |
47 | int linel; | |
48 | FILE *dfb; | |
49 | char dfname[33] = DFNAME; | |
50 | int waittm = 6; | |
0d2cd677 BJ |
51 | int onalrm (); |
52 | char tmplock[] = "lockXXXXXX"; | |
53 | char fonts[4][50] = { | |
54 | "/usr/lib/vfont/R", | |
55 | "/usr/lib/vfont/I", | |
56 | "/usr/lib/vfont/B", | |
57 | "/usr/lib/vfont/S" | |
58 | }; | |
59 | ||
60 | main(argc, argv) | |
61 | { | |
fef7eb28 | 62 | char n; |
0d2cd677 BJ |
63 | register char *p1, *p2; |
64 | register int df; | |
fef7eb28 KM |
65 | register struct direct *dirp; |
66 | DIR *dp; | |
0d2cd677 BJ |
67 | struct stat stb; |
68 | int offline = 0; | |
69 | int i, okreque = 1; | |
70 | ||
71 | signal(SIGHUP, SIG_IGN); | |
72 | signal(SIGINT, SIG_IGN); | |
73 | signal(SIGQUIT, SIG_IGN); | |
74 | signal(SIGTERM, SIG_IGN); | |
75 | begin: | |
76 | /* | |
77 | * Close all files, open root as 0, 1, 2 | |
78 | * to assure standard environment | |
79 | */ | |
80 | for (df = 0; df <= 15; df++) | |
81 | close(df); | |
82 | open("/", 0); | |
83 | dup(0); | |
84 | dup(0); | |
85 | if (chdir(SPOOLDIR) < 0 || (df = creat(mktemp(tmplock), 0)) < 0) { | |
86 | close(1); | |
87 | prcons("%s: error accessing %s\n", NAME, SPOOLDIR); | |
88 | exit(1); | |
89 | } | |
90 | if (link(tmplock, "lock") < 0) { | |
91 | unlink(tmplock); | |
92 | exit(0); | |
93 | } | |
94 | unlink(tmplock); | |
95 | close(df); | |
96 | floop: | |
97 | dprcons("floop\n"); | |
98 | i = fork(); | |
99 | if (i < 0) { | |
100 | sleep(5); | |
101 | goto floop; | |
102 | } | |
103 | if (i != 0) | |
104 | exit(0); | |
105 | reopen: | |
106 | dprcons("reopen\n"); | |
107 | for (;;) { | |
108 | if (open(DEVICE, 1) == 3) | |
109 | break; | |
110 | if (errno != EIO) { | |
111 | extern char *sys_errlist[]; | |
112 | prcons("%s: %s: %s\n", NAME, DEVICE, sys_errlist[errno]); | |
113 | unlink("lock"); | |
114 | exit(1); | |
115 | } | |
116 | if (offline == 0) { | |
117 | int f = open("/dev/tty", 1); | |
118 | ||
119 | offline++; | |
120 | if (f > 0) { | |
121 | write(f, NAME, strlen(NAME)); | |
122 | write(f, " is offline\n", 12); | |
123 | close(f); | |
124 | } | |
125 | dprcons("offline\n"); | |
126 | } | |
127 | sleep(10); | |
128 | } | |
fef7eb28 | 129 | dp = opendir("."); |
0d2cd677 BJ |
130 | search: |
131 | dprcons("search\n"); | |
132 | if (okreque == 1) { | |
fef7eb28 | 133 | rewinddir(dp); |
0d2cd677 | 134 | do { |
fef7eb28 KM |
135 | dirp = readdir(dp); |
136 | if (dirp == NULL) { | |
0d2cd677 BJ |
137 | if (printflag) |
138 | lastpage(); | |
139 | unlink("lock"); | |
140 | dprcons("nomore\n"); | |
141 | if (printflag==0) { | |
142 | dprcons("bye\n"); | |
143 | exit(0); | |
144 | } | |
145 | dprcons("one last time\n"); | |
146 | printflag = 0; | |
147 | close(3); | |
fef7eb28 | 148 | closedir(dp); |
0d2cd677 BJ |
149 | sleep(30); |
150 | goto begin; | |
151 | } | |
fef7eb28 KM |
152 | } while (dirp->d_name[0] != 'd' || dirp->d_name[1] != 'f'); |
153 | strcpy(&dfname[15], dirp->d_name); | |
154 | dprcons("found %s\n", dirp->d_name); | |
0d2cd677 BJ |
155 | } |
156 | dprcons("trying %s\n", dfname); | |
157 | printflag = 1; | |
158 | if (okreque == 0) | |
159 | feedpage(); | |
160 | if (trysend(dfname, okreque)) { | |
161 | okreque = 0; | |
fef7eb28 | 162 | closedir(dp); |
0d2cd677 BJ |
163 | printf("reque %s\n", dfname); |
164 | close(3); | |
165 | goto reopen; | |
166 | } | |
167 | dprcons("ok\n"); | |
168 | okreque = 1; | |
169 | goto search; | |
170 | } | |
171 | ||
172 | trysend(file, okreque) | |
173 | char *file; | |
174 | int okreque; | |
175 | { | |
176 | register int i; | |
177 | char plot; | |
178 | union wait status; | |
179 | int bomb = 0; | |
180 | ||
181 | resfonts(); | |
182 | dfb = fopen(file, "r"); | |
183 | if (dfb == NULL) { | |
184 | unlink(file); | |
185 | return (0); | |
186 | } | |
4916dcc2 DH |
187 | banner[0] = '\0'; |
188 | for(*banbuf= plot= 0; getline();) switch(line[0]) { | |
0d2cd677 BJ |
189 | |
190 | case 'L': | |
191 | strcpy(banbuf, line + 1); | |
192 | continue; | |
193 | ||
4916dcc2 DH |
194 | case 'B': /* banner */ |
195 | if(banner[0] == '\0') | |
196 | strcat(banner, line + 1); | |
197 | else { | |
198 | strcat(banner,"\n"); | |
199 | strcat(banner, line+1); | |
200 | } | |
201 | continue; | |
202 | ||
0d2cd677 BJ |
203 | case '1': |
204 | case '2': | |
205 | case '3': | |
206 | case '4': | |
207 | strcpy(fonts[line[0]-'1'], line + 1); | |
208 | continue; | |
209 | ||
4916dcc2 DH |
210 | case 'C': /* called by cifplot */ |
211 | case 'V': /* called by vplot */ | |
0d2cd677 BJ |
212 | case 'F': |
213 | case 'G': /* Like f, but invoke vpf with -l flag. */ | |
214 | case 'T': | |
215 | status.w_status = send(line[0]); | |
216 | break; | |
217 | ||
218 | case 'P': | |
219 | if (plot) { | |
220 | plot = 0; | |
221 | status.w_status = send(line[0]); | |
222 | break; | |
223 | } | |
224 | strcpy(linep, line + 1); | |
225 | plot++; | |
226 | continue; | |
227 | ||
228 | case 'U': | |
229 | continue; | |
230 | ||
231 | case 'M': | |
232 | continue; | |
233 | } | |
234 | /* | |
235 | * If the process that did the work did an exit(1), | |
236 | * we should requeue the file. | |
237 | */ | |
238 | if (!WIFEXITED(status) || status.w_retcode > 1) { | |
239 | ioctl(3, VSETSTATE, prtmode); | |
240 | write(3, "\nDAEMON MALFUNCTION\n", 20); | |
241 | feedpage(); | |
242 | bomb++; | |
243 | } else if (status.w_retcode == 1 && okreque) | |
244 | return (1); | |
245 | /* | |
246 | * All done, for better or for worse. | |
247 | */ | |
248 | fseek(dfb, 0, 0); | |
249 | while (getline()) switch (*line) { | |
250 | ||
251 | default: | |
252 | continue; | |
253 | ||
254 | case 'U': | |
255 | unlink(line + 1); | |
256 | continue; | |
257 | ||
258 | case 'M': | |
259 | sendmail(bomb); | |
260 | continue; | |
261 | } | |
262 | remret: | |
263 | fclose(dfb); | |
264 | unlink(file); | |
265 | return (0); | |
266 | } | |
267 | ||
268 | static char ifonts[4][50] = { | |
269 | "/usr/lib/vfont/R", | |
270 | "/usr/lib/vfont/I", | |
271 | "/usr/lib/vfont/B", | |
272 | "/usr/lib/vfont/S" | |
273 | }; | |
274 | ||
275 | resfonts() | |
276 | { | |
277 | int i; | |
278 | for (i = 0; i < 4; i++) | |
279 | strcpy(fonts[i], ifonts[i]); | |
280 | } | |
281 | ||
282 | sendmail(bomb) | |
283 | int bomb; | |
284 | { | |
285 | static int p[2]; | |
286 | register i; | |
287 | int stat; | |
288 | ||
289 | pipe(p); | |
290 | if (fork() == 0) { | |
291 | alarm(0); | |
292 | close(0); | |
293 | dup(p[0]); | |
294 | for (i = 3; i <= 15; i++) | |
295 | close(i); | |
296 | execl("/bin/mail", "mail", &line[1], 0); | |
297 | exit(0); | |
298 | } | |
299 | close(1); | |
300 | dup(p[1]); | |
301 | printf("Your %s job %s\n", NAME, bomb ? "screwed up" : "is done"); | |
302 | close(1); | |
303 | close(p[0]); | |
304 | close(p[1]); | |
305 | open("/", 0); | |
306 | wait(&stat); | |
307 | } | |
308 | ||
309 | getline() | |
310 | { | |
311 | register char *lp; | |
312 | register int c; | |
313 | ||
314 | lp = line; | |
315 | linel = 0; | |
316 | while ((c = getc (dfb)) != '\n') { | |
317 | if (c < 0) | |
318 | return (0); | |
319 | if (c == '\t') { | |
320 | do { | |
321 | *lp++ = ' '; | |
322 | linel++; | |
323 | } while ((linel & 07) != 0); | |
324 | continue; | |
325 | } | |
326 | *lp++ = c; | |
327 | linel++; | |
328 | } | |
329 | *lp++ = 0; | |
330 | return (1); | |
331 | } | |
332 | ||
333 | int pid; | |
334 | ||
335 | send (c) | |
336 | char c; | |
337 | { | |
338 | int p, i, rm; | |
339 | ||
340 | if (pid = fork ()) { | |
341 | if (pid == -1) | |
342 | return (1); | |
343 | setexit(); | |
344 | signal(SIGALRM, onalrm); | |
345 | alarm(30); | |
346 | wait(&p); | |
347 | alarm(0); | |
348 | return(p); | |
349 | } | |
350 | ioctl (3, VSETSTATE, prtmode); | |
351 | switch (c) { | |
352 | ||
353 | case 'F': | |
354 | if (banbuf[0]) { | |
355 | execl ("/usr/lib/vpf", "vpf", | |
356 | #ifdef VERSATEC | |
357 | "-W", | |
358 | #endif | |
359 | "-b", banbuf, line+1, 0); | |
360 | break; | |
361 | } | |
362 | execl ("/usr/lib/vpf", "vpf", | |
363 | #ifdef VERSATEC | |
364 | "-W", | |
365 | #endif | |
366 | line, 0); | |
367 | break; | |
368 | ||
369 | case 'G': /* Like F (vpf), but passes through -l | |
370 | flag to vpf (print control chars). */ | |
371 | if (banbuf[0]) { | |
372 | execl ("/usr/lib/vpf", "vpf", "-l", | |
373 | #ifdef VERSATEC | |
374 | "-W", | |
375 | #endif | |
376 | "-b", banbuf, line+1, 0); | |
377 | break; | |
378 | } | |
379 | execl ("/usr/lib/vpf", "vpf", "-l", | |
380 | #ifdef VERSATEC | |
381 | "-W", | |
382 | #endif | |
383 | line, 0); | |
384 | break; | |
385 | ||
386 | case 'T': | |
387 | unlink(".railmag"); | |
388 | rm = creat(".railmag", 0666); | |
389 | for (i = 0; i < 4; i++) { | |
390 | if (fonts[i][0] != '/') | |
391 | write(rm, "/usr/lib/vfont/", 15); | |
392 | write(rm, fonts[i], strlen (fonts[i])); | |
393 | write(rm, "\n", 1); | |
394 | } | |
395 | close(rm); | |
396 | if (banbuf[0]) { | |
397 | #ifdef VARIAN | |
398 | execl("/usr/lib/rvcat", "rvcat", | |
399 | #endif | |
400 | #ifdef VERSATEC | |
401 | execl("/usr/lib/vcat", "rvcat", | |
402 | "-W", | |
403 | #endif | |
404 | "-3", "-b", banbuf, line+1, 0); | |
405 | break; | |
406 | } | |
407 | #ifdef VARIAN | |
408 | execl("/usr/lib/rvcat", "rvcat", | |
409 | #endif | |
410 | #ifdef VERSATEC | |
411 | execl("/usr/lib/vcat", "rvcat", | |
412 | "-W", | |
413 | #endif | |
414 | "-3", line+1, 0); | |
415 | break; | |
416 | ||
417 | case 'P': | |
418 | close(1); | |
419 | dup(3); | |
420 | if (banbuf[0]) { | |
421 | execl(VRAST, "vrast", | |
422 | #ifdef VERSATEC | |
423 | "-W", | |
424 | #endif | |
425 | "-v", "-b", banbuf, line+1, linep, 0); | |
426 | break; | |
427 | } | |
428 | execl(VRAST, "vrast", | |
429 | #ifdef VERSATEC | |
430 | "-W", | |
431 | #endif | |
432 | "-v", line+1, linep, 0); | |
433 | break; | |
4916dcc2 DH |
434 | case 'C': |
435 | execl(VDMP,"vdmp","-n",banbuf,"-b",banner, | |
436 | #ifdef VERSATEC | |
437 | "-W", | |
438 | #endif | |
439 | line+1,0); | |
440 | break; | |
441 | case 'V': | |
442 | execl(VPLTDMP,"vpltdmp","-n",banbuf,"-b",banner, | |
443 | #ifdef VERSATEC | |
444 | "-W", | |
445 | #endif | |
446 | line+1,0); | |
447 | break; | |
0d2cd677 BJ |
448 | } |
449 | exit(2); /* execl failed or not one of above cases. */ | |
450 | } | |
451 | ||
452 | onalrm() | |
453 | { | |
454 | struct stat stb; | |
455 | ||
456 | signal(SIGALRM, onalrm); | |
457 | if (stat(dfname, &stb) < 0) | |
458 | kill(pid, SIGEMT); | |
459 | reset(); | |
460 | } | |
461 | ||
462 | /* | |
463 | * skip 16 inches or do two formfeeds. | |
464 | */ | |
465 | lastpage() | |
466 | { | |
467 | register int i; | |
468 | ||
469 | ioctl(3, VSETSTATE, prtmode); | |
470 | #ifdef VARIAN | |
471 | write(3, "\014\014", 2); | |
472 | #endif | |
473 | #ifdef VERSATEC | |
474 | for (i = 0; i < 18; i++) | |
475 | write(3, "\n\n\n\n\n\n\n\n", 8); | |
476 | #endif | |
477 | } | |
478 | ||
479 | feedpage() | |
480 | { | |
481 | ||
482 | ioctl(3, VSETSTATE, prtmode); | |
483 | #ifdef VARIAN | |
484 | write(3, "\014\0", 2); | |
485 | #endif | |
486 | #ifdef VERSATEC | |
487 | write(3, "\n\n\n", 8); | |
488 | #endif | |
489 | } | |
490 | ||
491 | prcons(cp, a1, a2, a3, a4, a5) | |
492 | char *cp; | |
493 | { | |
494 | char buf[BUFSIZ]; | |
495 | int f = open(CONSOLE, 1); | |
496 | ||
497 | sprintf(buf, cp, a1, a2, a3, a4, a5); | |
498 | write(f, buf, strlen(buf)); | |
499 | close(f); | |
500 | } |