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