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