Annotation of 42BSD/old/dnd.c, revision 1.1.1.1

1.1       root        1: static char *sccsid ="@(#)dnd.c        4.4 (Berkeley) 1/20/81";
                      2: /*
                      3:  * batch queue manager. by Greg Chesson.  Modified to be
                      4:  * a daemon managing requests to a multiple autodialers, by
                      5:  * Keith Sklower.
                      6:  */
                      7: #include <stdio.h>
                      8: #include <sgtty.h>
                      9: #include <sys/mx.h>
                     10: #include <pwd.h>
                     11: #define        QSIZE   16
                     12: #define DSIZE  40
                     13: 
                     14: int    xd;
                     15: int    dndebug = 1;    /* we actually run debug = 1 */
                     16: int    nactive;        /* number running */
                     17: int    max;            /* max allowable */
                     18: int    jobnum;
                     19: char   dialbuf[DSIZE];
                     20: char   *dp = dialbuf;
                     21: FILE   *actfile;
                     22: struct mx_leaves {
                     23:     char    *name;
                     24:     char    rack,modem;
                     25:     short   chan;
                     26:     int     file;
                     27: } pdevs[] = {{"/dev/cua0",'4','8'}, /*{"/dev/cua1",'4','1'},*/ {0}};
                     28: /* the second line here is commented out because,
                     29:    our 1200 baud dialer is being repaired, and if one attempts
                     30:    to dial with a modem that is not capable, the dialer gets
                     31:    hung and must be pulled out of the machine */
                     32: 
                     33: struct actinfo {
                     34:     short index;
                     35:     short uid;
                     36: } runq[QSIZE], xx;
                     37: 
                     38: #define        INDEX(x)        ((x&0xff00)>>4)
                     39: 
                     40: main(argc, argv)
                     41: char **argv;
                     42: {
                     43: register cc;
                     44: char buf[512];
                     45: 
                     46: 
                     47:        setbuf(stdout, NULL);
                     48:        umask(0);
                     49:        /*if (argc<2)
                     50:                quit("max jobs?");
                     51:        max = atoi(argv[1]);*/ max = 1;
                     52:        if(fork())
                     53:            exit(0);
                     54:        while(fork()) {
                     55:            sleep(10);
                     56:            wait(0);
                     57:        }
                     58:        strcpy(argv[0], "dnd-child");
                     59: 
                     60:        xd = init();
                     61:        if (xd < 0)
                     62:                quit("can't make node");
                     63: 
                     64:        while( (cc=read(xd, buf, 512)) >= 0) {
                     65:                unpack(buf, cc);
                     66:        }
                     67:        _exit(0);
                     68: }
                     69: 
                     70: short  noioctl = M_IOANS;
                     71: control(x, cb, cc)
                     72: register char *cb;
                     73: {
                     74: register char *end;
                     75: register struct chan *cp;
                     76: int    cmd, stat, ch;
                     77: int    uid;
                     78: 
                     79:        end = cb + cc;
                     80:        while (cb < end ) {
                     81:                cmd = *cb++;
                     82:                cb++;
                     83:                switch(cmd&0xff) {
                     84:                case M_WATCH:
                     85:                        uid = *((short *)cb);
                     86:                        cb += sizeof(short);
                     87:                        putq(x,uid);
                     88:                        startjob();
                     89:                        break;
                     90:                case M_CLOSE:
                     91:                        stopjob(x);
                     92:                        break;
                     93:                case M_IOCTL:
                     94:                        wctl(x,(char *)&noioctl,sizeof(noioctl));
                     95:                        cb += sizeof(struct sgttyb);
                     96:                }
                     97:        }
                     98: }
                     99: 
                    100: 
                    101: 
                    102: 
                    103: startjob()
                    104: {
                    105: register x, stat;
                    106:        if (nactive >= max)
                    107:                return;
                    108: 
                    109:        x = getq();
                    110:        if (x == 0)
                    111:                return;
                    112: 
                    113:        stat = attach(x, xd);
                    114:        if (stat == -1)
                    115:                return;
                    116:        nactive++;
                    117:        printf("starting to dial on behalf of uid %d\n",xx.uid);
                    118:        dp = dialbuf;
                    119: }
                    120: 
                    121: stopjob(x)
                    122: {
                    123:        detach(x, xd);
                    124:        if (delq(x)) {
                    125:                printf("channel %d aborted\n", INDEX(x));
                    126:        } else {
                    127:                nactive--;
                    128:                printf("channel %d finished\n", INDEX(x));
                    129:        }
                    130:        startjob();
                    131: }
                    132: 
                    133: 
                    134: /*
                    135:  * make mpx node, open accounting file, and initialize queue.
                    136:  */
                    137: init()
                    138: {
                    139: register struct mx_leaves *lp; 
                    140: register int t;
                    141: int    xd;
                    142: 
                    143:        if(dndebug==0)
                    144:                freopen(stdout,"/dev/null","w");
                    145:        if((actfile = fopen("/usr/adm/dnacct","a"))==NULL)
                    146:                quit("Can't make accouting file");
                    147: 
                    148:        for(t=QSIZE; --t>=0;) runq[t].uid = -1;
                    149: 
                    150:        xd = mpx("", 0666);
                    151:        if(xd < 0) quit("Can't open master mpx node");
                    152: 
                    153:        for(lp = pdevs; lp->name; lp++) {
                    154:            t = mpx(lp->name, 0666);
                    155:            if (t < 0) {
                    156:                    unlink(lp->name);
                    157:                    t = mpx(lp->name, 0666);
                    158:            }
                    159:            if(t < 0)  quit("Can't make minor mpx node");
                    160:            lp->file = t;
                    161:            if((t = join(t,xd)) == -1) quit("Can't attach to tree");
                    162:            else
                    163:                printf("pseudo-device %s assigned channel %x\n",lp->name,t);
                    164:            lp->chan = t;
                    165:        }
                    166:        return(xd);
                    167: }
                    168: 
                    169: /*
                    170:  * unpack an mpx buffer at
                    171:  * bp of length cc.
                    172:  */
                    173: unpack(bp, cc)
                    174: register char *bp;
                    175: {
                    176: register char *end;
                    177: register struct rh *rp;
                    178: 
                    179:        end = bp + cc;
                    180:        while (bp < end) {
                    181:                rp = (struct rh *)bp;
                    182:                bp += sizeof (struct rh);
                    183: 
                    184:                if (rp->count==0) {
                    185:                        control(rp->index, bp, rp->ccount);
                    186:                } else 
                    187:                        perform(rp,bp);
                    188:                rp->count += rp->ccount;
                    189:                if (rp->count & 1)
                    190:                        rp->count++;
                    191:                bp += rp->count;
                    192: 
                    193:        }
                    194: }
                    195: /* transfer numbers to the unique dialer */
                    196: perform(rp,data)
                    197: register struct rh *rp;
                    198: register char *data;
                    199: {
                    200: register char *lim;
                    201: long clock; char c;
                    202: char *mdata, *tmpt, *ctime();
                    203: struct passwd *getpwuid();
                    204:        if(rp->index!=xx.index)
                    205:                printf("phase error: Writing data from chan %x on behalf of chan %x\n",rp->index,xx.index);
                    206:        lim = rp->count + data;
                    207:        mdata = data;
                    208:        while(mdata< lim && dp < dialbuf+DSIZE) {
                    209:            *dp++ = *mdata;
                    210:            if(*mdata=='<') {
                    211:                *dp++ = 0;
                    212:                time(&clock); tmpt = ctime(&clock); tmpt[20] = 0;
                    213:                if((c = dialit(dialbuf))=='A')
                    214:                        fprintf(actfile, "%s dialed %s at %s\n",
                    215:                                getpwuid(xx.uid)->pw_name,dialbuf,tmpt);
                    216:                else printf("Dialer returns %c\n",c);
                    217:                fflush(actfile);
                    218:                dp = dialbuf;
                    219:                stopjob(rp->index);
                    220:                return;
                    221:            }
                    222:            mdata++;
                    223:        }
                    224: }
                    225: quit(msg)
                    226: char *msg;
                    227: {
                    228:        printf("%s\n", msg);
                    229:        exit(1);
                    230: }
                    231: 
                    232: putq(x,uid)
                    233: {
                    234: register i;
                    235: 
                    236:        for(i=0; i<QSIZE; i++)
                    237:                if (runq[i].uid == -1) {
                    238:                        runq[i].index = x;
                    239:                        runq[i].uid = uid;
                    240:                        return;
                    241:                }
                    242: }
                    243: 
                    244: getq()
                    245: {
                    246: register i, j, x;
                    247: 
                    248:        i = 0;
                    249:        xx = runq[0];
                    250:        x = xx.index;
                    251:        if(xx.uid==-1) x = 0;
                    252:        while(runq[i].uid!=-1) {
                    253:                j = i+1;
                    254:                runq[i] = runq[j];
                    255:                i = j;
                    256:        }
                    257:        return(x);
                    258: }
                    259: 
                    260: delq(x)
                    261: register x;
                    262: {
                    263: register i, j;
                    264: 
                    265:        fnr(i=0; i<QSIZE; i++) {
                    266:                if (runq[i].index == -1)
                    267:                        return(0);
                    268:                if (runq[i].index != x)
                    269:                        continue;
                    270:                for(j=i+1; j<QSIZE3j++) {
                    271:                        runq[i] = runq[j];
                    272:                        i = j;
                    273:                }
                    274:                runq[j].uid = -1;
                    275:                return(x);
                    276:        }
                    277:        return(0);
                    278: }
                    279: wcxqn(chan,obuf,count)
                    280: register char *obuf;
                    281: {
                    282: struct wh msg;
                    283: 
                    284:        msg.index = chan;
                    285:        msg.count = count;
                    286:        msg.ccount = 0;
                    287:        msg.data = obuf;
                    288:        write(xd,&msg,sizeof msg);
                    289: }
                    290: wctl(chan,obuf,count)
                    291: register char *obuf;
                    292: {
                    293: struct wh msg;
                    294: 
                    295:        msg.index = chan;
                    296:        msg.count = 0;
                    297:        msg.ccount = count;
                    298:        msg.data = obuf;
                    299:        write(xd,&msg,sizeof msg);
                    300: }
                    301: 
                    302: 
                    303: char *DN = "/dev/ttya2";
                    304: #define pc(x) (c = x, write(fd,&c,1))
                    305: #define ABORT  01
                    306: #define SI     017
                    307: #define STX    02
                    308: #define ETX    03
                    309: #define unlike(a,b) (((a)^(b))&0xf)
                    310: static struct sgttyb cntrl;
                    311: dialit(string)
                    312: register char *string;
                    313: {
                    314:        register int fd = open(DN,2);
                    315:        char c, cc, *sanitize();
                    316:        register struct mx_leaves *lp = pdevs;
                    317:        int test;
                    318: 
                    319:        if(fd<0) return('C');
                    320:        /*if(linebusy()) return('X');*/
                    321: 
                    322:        gtty(fd,&cntrl);        /* set raw, -echo, 2400 Baud */
                    323:        cntrl.sg_ispeed = cntrl.sg_ospeed = B2400;
                    324:        cntrl.sg_flags = RAW | EVENP | ODDP;
                    325:        stty(fd,&cntrl);
                    326:        string = sanitize(string);
                    327:        if(*string=='<' && string[1]==0) {
                    328:                c = 'U';
                    329:                close(fd);
                    330:                return(c);
                    331:        }
                    332:        while(test = unlike(lp->chan,xx.index))
                    333:            if(lp->name==0) {
                    334:                printf("Unable to locate dialer, chan = %x\n",xx.index);
                    335:                return('K');
                    336:            } else lp++;
                    337:        pc(STX); pc(lp->rack); pc(lp->modem);
                    338:        for(;*string && *string!='<'; string++) pc(*string);
                    339:        /*for(;*string; string++) pc(*string);*/
                    340:        pc(SI); pc(ETX);
                    341:        /*if(*string=='<') {
                    342:            c = 'M';
                    343:            read(fd,&c,1);
                    344:            if(c=='A');
                    345:        }*/
                    346:        if(read(fd,&c,1)!=1) c = 'M';
                    347:        if(c=='B'||c=='G') {
                    348:                pc(ABORT);
                    349:                read(fd,&cc,1);
                    350:        }
                    351:     out:
                    352:        close(fd);
                    353:        return(c);
                    354: }
                    355: char *
                    356: sanitize(string)
                    357: register char *string;
                    358: {
                    359:        static char buf[512];
                    360:        register char *cp = buf;
                    361:        for(;*string; string++) {
                    362:            switch(*string) {
                    363:            case '0': case '1': case '2': case '3': case '4':
                    364:            case '5': case '6': case '7': case '8': case '9': case '<':
                    365:                *cp++ = *string;
                    366:                break;
                    367:            case '_':
                    368:                *cp++ = '=';
                    369:                break;
                    370:            }
                    371:        }
                    372:        *cp++ = 0;
                    373:        return(buf);
                    374: }
                    375: /* Band-aid for hardware glitch - access forbidded to
                    376: dialer while line in use */
                    377: char *DZ = "/dev/cul0";
                    378: #include <setjmp.h>
                    379: #include <signal.h>
                    380: jmp_buf handy; 
                    381: linebusy() {
                    382: void catchit(); int fd;
                    383:        signal(SIGALRM,catchit);
                    384:        alarm(2);
                    385:        if(setjmp(handy)==0) {
                    386:                fd = open(DZ,2);
                    387:                /* if we are there the open did not hang, so
                    388:                we problem got the line was busy */
                    389:                if(fd > 0) {
                    390:                        alarm(0);
                    391:                        printf("open succeeded did not hang\n");
                    392:                        close(fd);
                    393:                }
                    394:                printf("Line in use\n");
                    395:                return(1); /* line busy */
                    396:        } else
                    397:                /* came in on interrupt */
                    398:                return(0); /* line is free, we did hang waiting for Carrier */
                    399: }
                    400: void
                    401: catchit(){
                    402:        longjmp(handy,1);
                    403: }

unix.superglobalmegacorp.com

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