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