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