Annotation of 43BSDReno/old/dnd/dnd.c, revision 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.