BSD 4_3_Tahoe release
[unix-history] / usr / src / old / vpr / vpd.c
CommitLineData
0d2cd677
BJ
1#define CONSOLE "/dev/console"
2#define dprcons if (debug) prcons
3/*
ca67e7b4 4 * vpd.c updated 11/4/87
0d2cd677
BJ
5 * Varian or Versatec printer daemon
6 */
ca67e7b4 7char vpdSCCSid[] = "@(#)vpd.c 1.5\t11/4/87";
4916dcc2 8
0d2cd677 9#include <stdio.h>
fef7eb28 10#include <sys/param.h>
2afc3750 11#include <sys/dir.h>
0d2cd677 12#include <signal.h>
2afc3750 13#include <sys/stat.h>
0d2cd677
BJ
14#include <sgtty.h>
15#include <errno.h>
16#include <sys/vcmd.h>
2afc3750 17#include <sys/wait.h>
0d2cd677
BJ
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;
0d2cd677
BJ
51int onalrm ();
52char tmplock[] = "lockXXXXXX";
53char 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
60main(argc, argv)
4742deda
KM
61 int argc;
62 char **argv;
0d2cd677 63{
fef7eb28 64 char n;
0d2cd677
BJ
65 register char *p1, *p2;
66 register int df;
fef7eb28
KM
67 register struct direct *dirp;
68 DIR *dp;
0d2cd677
BJ
69 struct stat stb;
70 int offline = 0;
71 int i, okreque = 1;
72
4742deda
KM
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());
0d2cd677
BJ
89 signal(SIGHUP, SIG_IGN);
90 signal(SIGINT, SIG_IGN);
91 signal(SIGQUIT, SIG_IGN);
92 signal(SIGTERM, SIG_IGN);
93begin:
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);
114floop:
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);
123reopen:
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 }
fef7eb28 147 dp = opendir(".");
0d2cd677
BJ
148search:
149 dprcons("search\n");
150 if (okreque == 1) {
fef7eb28 151 rewinddir(dp);
0d2cd677 152 do {
fef7eb28
KM
153 dirp = readdir(dp);
154 if (dirp == NULL) {
0d2cd677
BJ
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);
fef7eb28 166 closedir(dp);
0d2cd677
BJ
167 sleep(30);
168 goto begin;
169 }
fef7eb28
KM
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);
0d2cd677
BJ
173 }
174 dprcons("trying %s\n", dfname);
175 printflag = 1;
176 if (okreque == 0)
177 feedpage();
178 if (trysend(dfname, okreque)) {
179 okreque = 0;
fef7eb28 180 closedir(dp);
0d2cd677
BJ
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
190trysend(file, okreque)
191char *file;
192int 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 }
4916dcc2
DH
205 banner[0] = '\0';
206 for(*banbuf= plot= 0; getline();) switch(line[0]) {
0d2cd677
BJ
207
208 case 'L':
209 strcpy(banbuf, line + 1);
210 continue;
211
4916dcc2
DH
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
0d2cd677
BJ
221 case '1':
222 case '2':
223 case '3':
224 case '4':
225 strcpy(fonts[line[0]-'1'], line + 1);
226 continue;
227
4916dcc2
DH
228 case 'C': /* called by cifplot */
229 case 'V': /* called by vplot */
0d2cd677
BJ
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 }
280remret:
281 fclose(dfb);
282 unlink(file);
283 return (0);
284}
285
286static 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
293resfonts()
294{
295 int i;
296 for (i = 0; i < 4; i++)
297 strcpy(fonts[i], ifonts[i]);
298}
299
300sendmail(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
327getline()
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
351int pid;
352
353send (c)
354char 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;
4916dcc2
DH
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;
0d2cd677
BJ
466 }
467 exit(2); /* execl failed or not one of above cases. */
468}
469
470onalrm()
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 */
483lastpage()
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
497feedpage()
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
509prcons(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}