11849Sroot #define CONSOLE "/dev/console" 21849Sroot #define dprcons if (debug) prcons 31849Sroot /* 4*9300Smckusick * vpd.c updated 11/18/82 51849Sroot * Varian or Versatec printer daemon 61849Sroot */ 7*9300Smckusick char vpdSCCSid[] = "@(#)vpd.c 1.4\t11/18/82"; 82414Shalbert 91849Sroot #include <stdio.h> 107661Smckusick #include <sys/param.h> 111849Sroot #include <dir.h> 121849Sroot #include <signal.h> 131849Sroot #include <stat.h> 141849Sroot #include <sgtty.h> 151849Sroot #include <errno.h> 161849Sroot #include <sys/vcmd.h> 171849Sroot #include <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 601849Sroot main(argc, argv) 61*9300Smckusick int argc; 62*9300Smckusick 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 73*9300Smckusick while (argc > 1) { 74*9300Smckusick argc--; 75*9300Smckusick argv++; 76*9300Smckusick if (argv[0][0] != '-') 77*9300Smckusick continue; 78*9300Smckusick switch (argv[0][1]) { 79*9300Smckusick case 'n': 80*9300Smckusick if (argc < 2) 81*9300Smckusick break; 82*9300Smckusick argv++; 83*9300Smckusick argc--; 84*9300Smckusick nice(atol(argv[0])); 85*9300Smckusick break; 86*9300Smckusick } 87*9300Smckusick } 88*9300Smckusick 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 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 2931849Sroot resfonts() 2941849Sroot { 2951849Sroot int i; 2961849Sroot for (i = 0; i < 4; i++) 2971849Sroot strcpy(fonts[i], ifonts[i]); 2981849Sroot } 2991849Sroot 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 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 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