Annotation of 41BSD/cmd/lpr/lpd.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.