date and time created 82/10/21 23:58:34 by mckusick
[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 */
fef7eb28 7char 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
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)
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);
75begin:
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);
96floop:
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);
105reopen:
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
130search:
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
172trysend(file, okreque)
173char *file;
174int 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 }
262remret:
263 fclose(dfb);
264 unlink(file);
265 return (0);
266}
267
268static 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
275resfonts()
276{
277 int i;
278 for (i = 0; i < 4; i++)
279 strcpy(fonts[i], ifonts[i]);
280}
281
282sendmail(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
309getline()
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
333int pid;
334
335send (c)
336char 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
452onalrm()
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 */
465lastpage()
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
479feedpage()
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
491prcons(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}