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