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