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