|
|
1.1 ! root 1: /* ! 2: * Line-printer daemon ! 3: */ ! 4: ! 5: #include <sys/types.h> ! 6: #include <stdio.h> ! 7: #include <dir.h> ! 8: #include <signal.h> ! 9: #include <stat.h> ! 10: #include <sgtty.h> ! 11: ! 12: char line[128]; ! 13: char banbuf[64]; ! 14: int linel; ! 15: FILE *dfb; ! 16: char dfname[26] = "/usr/spool/lpd/"; ! 17: int waittm = 60; ! 18: struct dir dbuf; ! 19: int onalrm(); ! 20: ! 21: main(argc, argv) ! 22: { ! 23: register char *p1, *p2; ! 24: register int df; ! 25: register FILE *dp; ! 26: struct stat stb; ! 27: ! 28: signal(SIGHUP, SIG_IGN); ! 29: signal(SIGINT, SIG_IGN); ! 30: signal(SIGQUIT, SIG_IGN); ! 31: signal(SIGTERM, SIG_IGN); ! 32: /* ! 33: * Close all files, open root as 0, 1, 2 ! 34: * to assure standard environment ! 35: */ ! 36: for (df=0; df<=15; df++) ! 37: close(df); ! 38: open("/", 0); ! 39: dup(0); ! 40: dup(0); ! 41: if (stat("/usr/spool/lpd/lock", &stb) >= 0) ! 42: exit(0); ! 43: if ((df=creat("/usr/spool/lpd/lock", 0)) < 0) ! 44: exit(0); ! 45: close(df); ! 46: if (fork()) ! 47: exit(0); ! 48: again: ! 49: dp = fopen("/usr/spool/lpd", "r"); ! 50: do { ! 51: if (fread(&dbuf, sizeof dbuf, 1, dp) != 1) { ! 52: feedpage(); ! 53: unlink("/usr/spool/lpd/lock"); ! 54: exit(0); ! 55: } ! 56: } while (dbuf.d_ino==0 || dbuf.d_name[0]!='d' || dbuf.d_name[1]!='f'); ! 57: fclose(dp); ! 58: strcpy(dfname, "/usr/spool/lpd/"); ! 59: strcatn(dfname, dbuf.d_name, DIRSIZ); ! 60: if (trysend(dfname) == 0) ! 61: goto again; ! 62: sleep(waittm); ! 63: goto again; ! 64: } ! 65: ! 66: trysend(file) ! 67: char *file; ! 68: { ! 69: register char *p1, *p2; ! 70: register int i; ! 71: extern int badexit(); ! 72: ! 73: dfb = fopen(file, "r"); ! 74: if (dfb == NULL) ! 75: return(0); ! 76: banbuf[0] = 0; ! 77: while (getline()) switch (line[0]) { ! 78: case 'L': ! 79: p1 = line+1; ! 80: p2 = banbuf; ! 81: while (*p2++ = *p1++); ! 82: continue; ! 83: ! 84: case 'F': ! 85: if (send()) ! 86: return(1); ! 87: continue; ! 88: ! 89: case 'U': ! 90: continue; ! 91: ! 92: case 'M': ! 93: continue; ! 94: } ! 95: /* ! 96: * Second pass. ! 97: * Unlink files and send mail. ! 98: */ ! 99: fseek(dfb, 0L, 0); ! 100: while (getline()) switch (line[0]) { ! 101: ! 102: default: ! 103: continue; ! 104: ! 105: case 'U': ! 106: unlink(&line[1]); ! 107: continue; ! 108: ! 109: case 'M': ! 110: sendmail(); ! 111: continue; ! 112: } ! 113: fclose(dfb); ! 114: unlink(file); ! 115: } ! 116: ! 117: sendmail() ! 118: { ! 119: static int p[2]; ! 120: register i; ! 121: int stat; ! 122: ! 123: pipe(p); ! 124: if (fork()==0) { ! 125: alarm(0); ! 126: if (p[0] != 0) { ! 127: close(0); ! 128: dup(p[0]); ! 129: close(p[0]); ! 130: } ! 131: close(p[1]); ! 132: for (i=3; i<=15; i++) ! 133: close(i); ! 134: execl("/bin/mail", "mail", &line[1], 0); ! 135: exit(0); ! 136: } ! 137: write(p[1], "Your printer job is done\n", 25); ! 138: close(p[0]); ! 139: close(p[1]); ! 140: wait(&stat); ! 141: } ! 142: ! 143: getline() ! 144: { ! 145: register char *lp; ! 146: register int c; ! 147: ! 148: lp = line; ! 149: linel = 0; ! 150: while ((c = getc(dfb)) != '\n') { ! 151: if (c<0) ! 152: return(0); ! 153: if (c=='\t') { ! 154: do { ! 155: *lp++ = ' '; ! 156: linel++; ! 157: } while ((linel & 07) != 0); ! 158: continue; ! 159: } ! 160: *lp++ = c; ! 161: linel++; ! 162: } ! 163: *lp++ = 0; ! 164: return(1); ! 165: } ! 166: ! 167: int pid; ! 168: ! 169: send() ! 170: { ! 171: int p; ! 172: ! 173: if (pid = fork()) { ! 174: if (pid == -1) ! 175: return(1); ! 176: setexit(); ! 177: signal(SIGALRM, onalrm); ! 178: alarm(30); ! 179: wait(&p); ! 180: alarm(0); ! 181: return(p); ! 182: } ! 183: if (banbuf[0]) { ! 184: execl("/usr/lib/lpf", "lpf", "-b", banbuf, line+1, 0); ! 185: return(1); ! 186: } ! 187: execl("/usr/lib/lpf", "lpf", line, 0); ! 188: return(1); ! 189: } ! 190: ! 191: onalrm() ! 192: { ! 193: struct stat stb; ! 194: ! 195: signal(SIGALRM, onalrm); ! 196: if (stat(dfname, &stb) < 0) ! 197: kill(pid, SIGEMT); ! 198: reset(); ! 199: } ! 200: ! 201: struct sgttyb ttyb = { ! 202: B9600, B9600, ! 203: 0, 0, ! 204: XTABS|ANYP|CBREAK ! 205: }; ! 206: ! 207: FILE *out; ! 208: int lpack; ! 209: ! 210: feedpage() ! 211: { ! 212: register int i = 66; ! 213: FILE *lp; ! 214: int retry = 0; ! 215: ! 216: out = fopen("/dev/lp", "w"); ! 217: if (out == NULL) ! 218: return; ! 219: lpack = open("/dev/lp", 0); ! 220: if (lpack < 0) { ! 221: fclose(lp); ! 222: return; ! 223: } ! 224: stty(fileno(out), &ttyb); ! 225: putc(2, out); ! 226: putc('\f', out); ! 227: putc(3, out); ! 228: ack(); ! 229: fclose(out); ! 230: close(lpack); ! 231: } ! 232: ! 233: #define ACK 06 ! 234: #define NAK 025 ! 235: #define STX 2 ! 236: #define ETX 3 ! 237: ! 238: nothing() ! 239: { ! 240: ; ! 241: } ! 242: ! 243: ack() ! 244: { ! 245: char buf[256]; ! 246: ! 247: int i = STX; ! 248: write(fileno(out), &i, 1); ! 249: putc('\r', out); ! 250: putc(ETX, out); ! 251: fflush(out); ! 252: alarm(5); ! 253: signal(SIGALRM, nothing); ! 254: i = read(lpack, buf, 256); ! 255: if (buf[0] == NAK) ! 256: sleep(1); ! 257: return (buf[0] == ACK); ! 258: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.