xref: /csrg-svn/old/vpr/vpd.c (revision 32589)
11849Sroot #define	CONSOLE		"/dev/console"
21849Sroot #define	dprcons		if (debug) prcons
31849Sroot /*
4*32589Sbostic  * vpd.c						updated 11/04/87
51849Sroot  * Varian or Versatec printer daemon
61849Sroot  */
7*32589Sbostic char vpdSCCSid[] = "@(#)vpd.c	1.5\t11/04/87";
82414Shalbert 
91849Sroot #include <stdio.h>
107661Smckusick #include <sys/param.h>
11*32589Sbostic #include <sys/dir.h>
121849Sroot #include <signal.h>
13*32589Sbostic #include <sys/stat.h>
141849Sroot #include <sgtty.h>
151849Sroot #include <errno.h>
161849Sroot #include <sys/vcmd.h>
17*32589Sbostic #include <sys/wait.h>
181849Sroot 
191849Sroot int	debug;
201849Sroot extern	int errno;
211849Sroot 
221849Sroot #define VRAST		"/usr/local/lib/vrast"
232414Shalbert #define VDMP		"/usr/lib/vdmp"
242414Shalbert #define VPLTDMP		"/usr/lib/vpltdmp"
251849Sroot 
261849Sroot #ifdef VARIAN
271849Sroot #define DEVICE		"/dev/va0"
281849Sroot #define DFNAME		"/usr/spool/vad/"
291849Sroot #define SPOOLDIR	"/usr/spool/vad"
301849Sroot #define NAME		"Varian"
311849Sroot #endif
321849Sroot 
331849Sroot #ifdef VERSATEC
341849Sroot #define DEVICE		"/dev/vp0"
351849Sroot #define DFNAME		"/usr/spool/vpd/"
361849Sroot #define SPOOLDIR	"/usr/spool/vpd"
371849Sroot #define NAME		"Versatec"
381849Sroot #endif
391849Sroot 
401849Sroot int	prtmode[] =	{VPRINT, 0, 0};
411849Sroot 
421849Sroot char	line[128];
431849Sroot char    linep[127];
441849Sroot char	banbuf[64];
452414Shalbert char	banner[512];
461849Sroot char	printflag;
471849Sroot int	linel;
481849Sroot FILE	*dfb;
491849Sroot char	dfname[33] = DFNAME;
501849Sroot int	waittm = 6;
511849Sroot int	onalrm ();
521849Sroot char	tmplock[] = "lockXXXXXX";
531849Sroot char	fonts[4][50] = {
541849Sroot 	"/usr/lib/vfont/R",
551849Sroot 	"/usr/lib/vfont/I",
561849Sroot 	"/usr/lib/vfont/B",
571849Sroot 	"/usr/lib/vfont/S"
581849Sroot };
591849Sroot 
main(argc,argv)601849Sroot main(argc, argv)
619300Smckusick 	int argc;
629300Smckusick 	char **argv;
631849Sroot {
647661Smckusick 	char n;
651849Sroot 	register char *p1, *p2;
661849Sroot 	register int df;
677661Smckusick 	register struct direct *dirp;
687661Smckusick 	DIR *dp;
691849Sroot 	struct stat stb;
701849Sroot 	int offline = 0;
711849Sroot 	int i, okreque = 1;
721849Sroot 
739300Smckusick 	while (argc > 1) {
749300Smckusick 		argc--;
759300Smckusick 		argv++;
769300Smckusick 		if (argv[0][0] != '-')
779300Smckusick 			continue;
789300Smckusick 		switch (argv[0][1]) {
799300Smckusick 		case 'n':
809300Smckusick 			if (argc < 2)
819300Smckusick 				break;
829300Smckusick 			argv++;
839300Smckusick 			argc--;
849300Smckusick 			nice(atol(argv[0]));
859300Smckusick 			break;
869300Smckusick 		}
879300Smckusick 	}
889300Smckusick 	setuid(getuid());
891849Sroot 	signal(SIGHUP, SIG_IGN);
901849Sroot 	signal(SIGINT, SIG_IGN);
911849Sroot 	signal(SIGQUIT, SIG_IGN);
921849Sroot 	signal(SIGTERM, SIG_IGN);
931849Sroot begin:
941849Sroot /*
951849Sroot  * Close all files, open root as 0, 1, 2
961849Sroot  * to assure standard environment
971849Sroot  */
981849Sroot 	for (df = 0; df <= 15; df++)
991849Sroot 		close(df);
1001849Sroot 	open("/", 0);
1011849Sroot 	dup(0);
1021849Sroot 	dup(0);
1031849Sroot 	if (chdir(SPOOLDIR) < 0 || (df = creat(mktemp(tmplock), 0)) < 0) {
1041849Sroot 		close(1);
1051849Sroot 		prcons("%s: error accessing %s\n", NAME, SPOOLDIR);
1061849Sroot 		exit(1);
1071849Sroot 	}
1081849Sroot 	if (link(tmplock, "lock") < 0) {
1091849Sroot 		unlink(tmplock);
1101849Sroot 		exit(0);
1111849Sroot 	}
1121849Sroot 	unlink(tmplock);
1131849Sroot 	close(df);
1141849Sroot floop:
1151849Sroot 	dprcons("floop\n");
1161849Sroot 	i = fork();
1171849Sroot 	if (i < 0) {
1181849Sroot 		sleep(5);
1191849Sroot 		goto floop;
1201849Sroot 	}
1211849Sroot 	if (i != 0)
1221849Sroot 		exit(0);
1231849Sroot reopen:
1241849Sroot 	dprcons("reopen\n");
1251849Sroot 	for (;;) {
1261849Sroot 		if (open(DEVICE, 1) == 3)
1271849Sroot 			break;
1281849Sroot 		if (errno != EIO) {
1291849Sroot 			extern char *sys_errlist[];
1301849Sroot 			prcons("%s: %s: %s\n", NAME, DEVICE, sys_errlist[errno]);
1311849Sroot 			unlink("lock");
1321849Sroot 			exit(1);
1331849Sroot 		}
1341849Sroot 		if (offline == 0) {
1351849Sroot 			int f = open("/dev/tty", 1);
1361849Sroot 
1371849Sroot 			offline++;
1381849Sroot 			if (f > 0) {
1391849Sroot 				write(f, NAME, strlen(NAME));
1401849Sroot 				write(f, " is offline\n", 12);
1411849Sroot 				close(f);
1421849Sroot 			}
1431849Sroot 			dprcons("offline\n");
1441849Sroot 		}
1451849Sroot 		sleep(10);
1461849Sroot 	}
1477661Smckusick 	dp = opendir(".");
1481849Sroot search:
1491849Sroot 	dprcons("search\n");
1501849Sroot 	if (okreque == 1) {
1517661Smckusick 		rewinddir(dp);
1521849Sroot 		do {
1537661Smckusick 			dirp = readdir(dp);
1547661Smckusick 			if (dirp == NULL) {
1551849Sroot 				if (printflag)
1561849Sroot 					lastpage();
1571849Sroot 				unlink("lock");
1581849Sroot 				dprcons("nomore\n");
1591849Sroot 				if (printflag==0) {
1601849Sroot 					dprcons("bye\n");
1611849Sroot 					exit(0);
1621849Sroot 				}
1631849Sroot 				dprcons("one last time\n");
1641849Sroot 				printflag = 0;
1651849Sroot 				close(3);
1667661Smckusick 				closedir(dp);
1671849Sroot 				sleep(30);
1681849Sroot 				goto begin;
1691849Sroot 			}
1707661Smckusick 		} while (dirp->d_name[0] != 'd' || dirp->d_name[1] != 'f');
1717661Smckusick 		strcpy(&dfname[15], dirp->d_name);
1727661Smckusick 		dprcons("found %s\n", dirp->d_name);
1731849Sroot 	}
1741849Sroot 	dprcons("trying %s\n", dfname);
1751849Sroot 	printflag = 1;
1761849Sroot 	if (okreque == 0)
1771849Sroot 		feedpage();
1781849Sroot 	if (trysend(dfname, okreque)) {
1791849Sroot 		okreque = 0;
1807661Smckusick 		closedir(dp);
1811849Sroot 		printf("reque %s\n", dfname);
1821849Sroot 		close(3);
1831849Sroot 		goto reopen;
1841849Sroot 	}
1851849Sroot 	dprcons("ok\n");
1861849Sroot 	okreque = 1;
1871849Sroot 	goto search;
1881849Sroot }
1891849Sroot 
trysend(file,okreque)1901849Sroot trysend(file, okreque)
1911849Sroot char *file;
1921849Sroot int okreque;
1931849Sroot {
1941849Sroot 	register int i;
1951849Sroot 	char plot;
1961849Sroot 	union wait status;
1971849Sroot 	int bomb = 0;
1981849Sroot 
1991849Sroot 	resfonts();
2001849Sroot 	dfb = fopen(file, "r");
2011849Sroot 	if (dfb == NULL) {
2021849Sroot 		unlink(file);
2031849Sroot 		return (0);
2041849Sroot 	}
2052414Shalbert 	banner[0] = '\0';
2062414Shalbert 	for(*banbuf= plot= 0; getline();) switch(line[0]) {
2071849Sroot 
2081849Sroot 	case 'L':
2091849Sroot 		strcpy(banbuf, line + 1);
2101849Sroot 		continue;
2111849Sroot 
2122414Shalbert 	case 'B':	/* banner */
2132414Shalbert 		if(banner[0] == '\0')
2142414Shalbert 		    strcat(banner, line + 1);
2152414Shalbert 		  else {
2162414Shalbert 		    strcat(banner,"\n");
2172414Shalbert 		    strcat(banner, line+1);
2182414Shalbert 		    }
2192414Shalbert 		continue;
2202414Shalbert 
2211849Sroot 	case '1':
2221849Sroot 	case '2':
2231849Sroot 	case '3':
2241849Sroot 	case '4':
2251849Sroot 		strcpy(fonts[line[0]-'1'], line + 1);
2261849Sroot 		continue;
2271849Sroot 
2282414Shalbert 	case 'C':	/* called by cifplot */
2292414Shalbert 	case 'V':	/* called by vplot */
2301849Sroot 	case 'F':
2311849Sroot 	case 'G':	/* Like f, but invoke vpf with -l flag. */
2321849Sroot 	case 'T':
2331849Sroot 		status.w_status = send(line[0]);
2341849Sroot 		break;
2351849Sroot 
2361849Sroot 	case 'P':
2371849Sroot 		if (plot) {
2381849Sroot 			plot = 0;
2391849Sroot 			status.w_status = send(line[0]);
2401849Sroot 			break;
2411849Sroot 		}
2421849Sroot 		strcpy(linep, line + 1);
2431849Sroot 		plot++;
2441849Sroot 		continue;
2451849Sroot 
2461849Sroot 	case 'U':
2471849Sroot 		continue;
2481849Sroot 
2491849Sroot 	case 'M':
2501849Sroot 		continue;
2511849Sroot 	}
2521849Sroot 	/*
2531849Sroot 	 * If the process that did the work did an exit(1),
2541849Sroot 	 * we should requeue the file.
2551849Sroot 	 */
2561849Sroot 	if (!WIFEXITED(status) || status.w_retcode > 1) {
2571849Sroot 		ioctl(3, VSETSTATE, prtmode);
2581849Sroot 		write(3, "\nDAEMON MALFUNCTION\n", 20);
2591849Sroot 		feedpage();
2601849Sroot 		bomb++;
2611849Sroot 	} else if (status.w_retcode == 1 && okreque)
2621849Sroot 		return (1);
2631849Sroot 	/*
2641849Sroot 	 * All done, for better or for worse.
2651849Sroot 	 */
2661849Sroot 	fseek(dfb, 0, 0);
2671849Sroot 	while (getline()) switch (*line) {
2681849Sroot 
2691849Sroot 	default:
2701849Sroot 		continue;
2711849Sroot 
2721849Sroot 	case 'U':
2731849Sroot 		unlink(line + 1);
2741849Sroot 		continue;
2751849Sroot 
2761849Sroot 	case 'M':
2771849Sroot 		sendmail(bomb);
2781849Sroot 		continue;
2791849Sroot 	}
2801849Sroot remret:
2811849Sroot 	fclose(dfb);
2821849Sroot 	unlink(file);
2831849Sroot 	return (0);
2841849Sroot }
2851849Sroot 
2861849Sroot static char ifonts[4][50] = {
2871849Sroot 	"/usr/lib/vfont/R",
2881849Sroot 	"/usr/lib/vfont/I",
2891849Sroot 	"/usr/lib/vfont/B",
2901849Sroot 	"/usr/lib/vfont/S"
2911849Sroot };
2921849Sroot 
resfonts()2931849Sroot resfonts()
2941849Sroot {
2951849Sroot 	int i;
2961849Sroot 	for (i = 0; i < 4; i++)
2971849Sroot 		strcpy(fonts[i], ifonts[i]);
2981849Sroot }
2991849Sroot 
sendmail(bomb)3001849Sroot sendmail(bomb)
3011849Sroot 	int bomb;
3021849Sroot {
3031849Sroot 	static int p[2];
3041849Sroot 	register i;
3051849Sroot 	int stat;
3061849Sroot 
3071849Sroot 	pipe(p);
3081849Sroot 	if (fork() == 0) {
3091849Sroot 		alarm(0);
3101849Sroot 		close(0);
3111849Sroot 		dup(p[0]);
3121849Sroot 		for (i = 3; i <= 15; i++)
3131849Sroot 			close(i);
3141849Sroot 		execl("/bin/mail", "mail", &line[1], 0);
3151849Sroot 		exit(0);
3161849Sroot 	}
3171849Sroot 	close(1);
3181849Sroot 	dup(p[1]);
3191849Sroot 	printf("Your %s job %s\n", NAME, bomb ? "screwed up" : "is done");
3201849Sroot 	close(1);
3211849Sroot 	close(p[0]);
3221849Sroot 	close(p[1]);
3231849Sroot 	open("/", 0);
3241849Sroot 	wait(&stat);
3251849Sroot }
3261849Sroot 
getline()3271849Sroot getline()
3281849Sroot {
3291849Sroot 	register char *lp;
3301849Sroot 	register int c;
3311849Sroot 
3321849Sroot 	lp = line;
3331849Sroot 	linel = 0;
3341849Sroot 	while ((c = getc (dfb)) != '\n') {
3351849Sroot 		if (c < 0)
3361849Sroot 			return (0);
3371849Sroot 		if (c == '\t') {
3381849Sroot 			do {
3391849Sroot 				*lp++ = ' ';
3401849Sroot 				linel++;
3411849Sroot 			} while ((linel & 07) != 0);
3421849Sroot 			continue;
3431849Sroot 		}
3441849Sroot 		*lp++ = c;
3451849Sroot 		linel++;
3461849Sroot 	}
3471849Sroot 	*lp++ = 0;
3481849Sroot 	return (1);
3491849Sroot }
3501849Sroot 
3511849Sroot int	pid;
3521849Sroot 
send(c)3531849Sroot send (c)
3541849Sroot char c;
3551849Sroot {
3561849Sroot 	int p, i, rm;
3571849Sroot 
3581849Sroot 	if (pid = fork ()) {
3591849Sroot 		if (pid == -1)
3601849Sroot 			return (1);
3611849Sroot 		setexit();
3621849Sroot 		signal(SIGALRM, onalrm);
3631849Sroot 		alarm(30);
3641849Sroot 		wait(&p);
3651849Sroot 		alarm(0);
3661849Sroot 		return(p);
3671849Sroot 	}
3681849Sroot 	ioctl (3, VSETSTATE, prtmode);
3691849Sroot 	switch (c) {
3701849Sroot 
3711849Sroot 	case 'F':
3721849Sroot 		if (banbuf[0]) {
3731849Sroot 			execl ("/usr/lib/vpf", "vpf",
3741849Sroot #ifdef VERSATEC
3751849Sroot 				"-W",
3761849Sroot #endif
3771849Sroot 				"-b", banbuf, line+1, 0);
3781849Sroot 			break;
3791849Sroot 		}
3801849Sroot 		execl ("/usr/lib/vpf", "vpf",
3811849Sroot #ifdef VERSATEC
3821849Sroot 			"-W",
3831849Sroot #endif
3841849Sroot 			line, 0);
3851849Sroot 		break;
3861849Sroot 
3871849Sroot 	case 'G':	/* Like F (vpf), but passes through -l
3881849Sroot 			   flag to vpf (print control chars). */
3891849Sroot 		if (banbuf[0]) {
3901849Sroot 			execl ("/usr/lib/vpf", "vpf", "-l",
3911849Sroot #ifdef VERSATEC
3921849Sroot 				"-W",
3931849Sroot #endif
3941849Sroot 				"-b", banbuf, line+1, 0);
3951849Sroot 			break;
3961849Sroot 		}
3971849Sroot 		execl ("/usr/lib/vpf", "vpf", "-l",
3981849Sroot #ifdef VERSATEC
3991849Sroot 			"-W",
4001849Sroot #endif
4011849Sroot 			line, 0);
4021849Sroot 		break;
4031849Sroot 
4041849Sroot 	case 'T':
4051849Sroot 		unlink(".railmag");
4061849Sroot 		rm = creat(".railmag", 0666);
4071849Sroot 		for (i = 0; i < 4; i++) {
4081849Sroot 			if (fonts[i][0] != '/')
4091849Sroot 				write(rm, "/usr/lib/vfont/", 15);
4101849Sroot 			write(rm, fonts[i], strlen (fonts[i]));
4111849Sroot 			write(rm, "\n", 1);
4121849Sroot 		}
4131849Sroot 		close(rm);
4141849Sroot 		if (banbuf[0]) {
4151849Sroot #ifdef VARIAN
4161849Sroot 			execl("/usr/lib/rvcat", "rvcat",
4171849Sroot #endif
4181849Sroot #ifdef VERSATEC
4191849Sroot 			execl("/usr/lib/vcat", "rvcat",
4201849Sroot 				"-W",
4211849Sroot #endif
4221849Sroot 				"-3", "-b", banbuf, line+1, 0);
4231849Sroot 			break;
4241849Sroot 		}
4251849Sroot #ifdef VARIAN
4261849Sroot 		execl("/usr/lib/rvcat", "rvcat",
4271849Sroot #endif
4281849Sroot #ifdef VERSATEC
4291849Sroot 		execl("/usr/lib/vcat", "rvcat",
4301849Sroot 			"-W",
4311849Sroot #endif
4321849Sroot 			"-3", line+1, 0);
4331849Sroot 		break;
4341849Sroot 
4351849Sroot 	case 'P':
4361849Sroot 		close(1);
4371849Sroot 		dup(3);
4381849Sroot 		if (banbuf[0]) {
4391849Sroot 			execl(VRAST, "vrast",
4401849Sroot #ifdef VERSATEC
4411849Sroot 				"-W",
4421849Sroot #endif
4431849Sroot 				"-v", "-b", banbuf, line+1, linep, 0);
4441849Sroot 			break;
4451849Sroot 		}
4461849Sroot 		execl(VRAST, "vrast",
4471849Sroot #ifdef VERSATEC
4481849Sroot 			"-W",
4491849Sroot #endif
4501849Sroot 			"-v", line+1, linep, 0);
4511849Sroot 		break;
4522414Shalbert 	case 'C':
4532414Shalbert 		execl(VDMP,"vdmp","-n",banbuf,"-b",banner,
4542414Shalbert #ifdef VERSATEC
4552414Shalbert 			"-W",
4562414Shalbert #endif
4572414Shalbert 			line+1,0);
4582414Shalbert 		break;
4592414Shalbert 	case 'V':
4602414Shalbert 		execl(VPLTDMP,"vpltdmp","-n",banbuf,"-b",banner,
4612414Shalbert #ifdef VERSATEC
4622414Shalbert 			"-W",
4632414Shalbert #endif
4642414Shalbert 			line+1,0);
4652414Shalbert 		break;
4661849Sroot 	}
4671849Sroot 	exit(2);	/* execl failed or not one of above cases. */
4681849Sroot }
4691849Sroot 
4701849Sroot onalrm()
4711849Sroot {
4721849Sroot 	struct stat stb;
4731849Sroot 
4741849Sroot 	signal(SIGALRM, onalrm);
4751849Sroot 	if (stat(dfname, &stb) < 0)
4761849Sroot 		kill(pid, SIGEMT);
4771849Sroot 	reset();
4781849Sroot }
4791849Sroot 
4801849Sroot /*
4811849Sroot  * skip 16 inches or do two formfeeds.
4821849Sroot  */
4831849Sroot lastpage()
4841849Sroot {
4851849Sroot 	register int i;
4861849Sroot 
4871849Sroot 	ioctl(3, VSETSTATE, prtmode);
4881849Sroot #ifdef VARIAN
4891849Sroot 	write(3, "\014\014", 2);
4901849Sroot #endif
4911849Sroot #ifdef VERSATEC
4921849Sroot 	for (i = 0; i < 18; i++)
4931849Sroot 		write(3, "\n\n\n\n\n\n\n\n", 8);
4941849Sroot #endif
4951849Sroot }
4961849Sroot 
4971849Sroot feedpage()
4981849Sroot {
4991849Sroot 
5001849Sroot 	ioctl(3, VSETSTATE, prtmode);
5011849Sroot #ifdef VARIAN
5021849Sroot 	write(3, "\014\0", 2);
5031849Sroot #endif
5041849Sroot #ifdef VERSATEC
5051849Sroot 	write(3, "\n\n\n", 8);
5061849Sroot #endif
5071849Sroot }
5081849Sroot 
5091849Sroot prcons(cp, a1, a2, a3, a4, a5)
5101849Sroot 	char *cp;
5111849Sroot {
5121849Sroot 	char buf[BUFSIZ];
5131849Sroot 	int f = open(CONSOLE, 1);
5141849Sroot 
5151849Sroot 	sprintf(buf, cp, a1, a2, a3, a4, a5);
5161849Sroot 	write(f, buf, strlen(buf));
5171849Sroot 	close(f);
5181849Sroot }
519