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