Annotation of researchv10no/ipc/mgrs/ndkmgr/dial.c, revision 1.1

1.1     ! root        1: #include <sys/types.h>
        !             2: #include <sys/stat.h>
        !             3: #include <sys/filio.h>
        !             4: #include "dk.h"
        !             5: #include <stdio.h>
        !             6: #include <signal.h>
        !             7: #include <errno.h>
        !             8: #include <ipc.h>
        !             9: #include <libc.h>
        !            10: #include "defs.h"
        !            11: #include <dkwindow.h>
        !            12: #include <sys/dkio.h>
        !            13: 
        !            14: /* imported */
        !            15: extern int     uxp_ld;
        !            16: extern int     dkp_ld;
        !            17: extern         int     errno;
        !            18: extern int unit;
        !            19: 
        !            20: enum { dial, announce, redial };
        !            21: 
        !            22: 
        !            23: static int
        !            24: gettraffic(ip)
        !            25:        ipcinfo *ip;
        !            26: {
        !            27:        char *dp;
        !            28: 
        !            29:        /* get type of request and properties */
        !            30:        for(dp = ip->param; *dp; dp++) {
        !            31:                for(;*dp && *dp==' '; dp++);
        !            32:                if (strncmp(dp, "heavy", 5)==0 && (dp[5]=='\0'||dp[5]==' '))
        !            33:                        return 2;
        !            34:                for(;*dp && *dp!=' '; dp++);
        !            35:        }
        !            36:        return 0;
        !            37: }
        !            38: 
        !            39: int
        !            40: net_dial(ip)
        !            41:        ipcinfo *ip;
        !            42: {
        !            43:        int fd;
        !            44:        int ctlfd;
        !            45:        int traffic;
        !            46:        int chan;
        !            47: 
        !            48:        traffic = gettraffic(ip);
        !            49:        fd = dkchan(&traffic, unit, &chan, &ctlfd);
        !            50:        if (fd < 0)
        !            51:                return ABORT(EBUSY, "out of output channels", NULLINFO);
        !            52:        return dkdial(fd, ctlfd, ip, traffic, chan, dial);
        !            53: }
        !            54: 
        !            55: int
        !            56: net_announce(ip)
        !            57:        ipcinfo *ip;
        !            58: {
        !            59:        int fd;
        !            60:        int ctlfd;
        !            61:        int traffic;
        !            62:        int chan;
        !            63: 
        !            64:        /*
        !            65:         * hack: assertively set unit
        !            66:         *   when announcing, use traffic type to decide on interface to use.
        !            67:         *   otherwise, we could announce on the wrong interface.
        !            68:         *   bug: dkchan tries the other interface, so could still
        !            69:         *   end up on the wrong one if the right one is full
        !            70:         */
        !            71:        traffic = gettraffic(ip);
        !            72:        if (unit == 'b') {
        !            73:                switch(traffic){
        !            74:                case 0:
        !            75:                        unit = '0';
        !            76:                        break;
        !            77:                case 2:
        !            78:                        unit = '2';
        !            79:                        break;
        !            80:                }
        !            81:        }
        !            82:        fd = dkchan(&traffic, unit, &chan, &ctlfd);
        !            83:        if (fd < 0)
        !            84:                return ABORT(EBUSY, "out of output channels", NULLINFO);
        !            85:        return dkdial(fd, ctlfd, ip, traffic, chan, announce);
        !            86: }
        !            87: 
        !            88: int
        !            89: net_redial(ip)
        !            90:        ipcinfo *ip;
        !            91: {
        !            92:        int traffic;
        !            93:        int chan;
        !            94:        int ctlfd;
        !            95: 
        !            96:        /*
        !            97:         *  find unit, traffic, and channel
        !            98:         */
        !            99:        if(dkid(ip->cfd, unit, &traffic, &chan, &ctlfd)<0)
        !           100:                return -1;
        !           101:        return dkdial(ip->cfd, ctlfd, ip, traffic, chan, redial);
        !           102: }
        !           103: 
        !           104: int
        !           105: dkdial(fd, listener, ip, traffic, chan, operation)
        !           106:        ipcinfo *ip;
        !           107: {
        !           108:        int i;
        !           109:        struct dialout d;
        !           110:        char dialstr[128];
        !           111:        char dialtone[2];
        !           112:        register char *dp, *cp;
        !           113:        struct dialout reply;
        !           114:        int al_catch();
        !           115:        long window;
        !           116:        char ws[8];
        !           117: 
        !           118:        /*
        !           119:         *  restart URP on the channel
        !           120:         */
        !           121:        signal(SIGALRM, al_catch);
        !           122:        dkproto(fd, dkp_ld);
        !           123:        ioctl(fd, FIOPUSHLD, &uxp_ld);
        !           124: 
        !           125:        /* set up the parameter block for the initial request */
        !           126:        switch(operation){
        !           127:        case dial:
        !           128:                d.type = T_SRV;
        !           129:                d.srv = D_DIAL;
        !           130:                break;
        !           131:        case announce:
        !           132:                d.type = T_SRV;
        !           133:                d.srv = D_SERV;
        !           134:                break;
        !           135:        case redial:
        !           136:                d.type = T_CHG;
        !           137:                d.srv = D_REDIAL;
        !           138:                break;
        !           139:        }
        !           140:        d.param0l = chan;
        !           141:        d.param0h = chan>>8;
        !           142:        d.param1l = traffic;
        !           143:        d.param1h = traffic>>8;
        !           144:        d.param2l = 0;
        !           145:        d.param2h = 0;
        !           146:        d.param3l = 0;
        !           147:        d.param3h = 0;
        !           148:        d.param4l = ip->uid;
        !           149:        d.param4h = ip->uid>>8;
        !           150: 
        !           151:        /*
        !           152:         *  Make dial string.
        !           153:         *  Convert first two '!'s to '.'s to comply with generic's form
        !           154:         *  of destination.service[.more-things].  Escape any '.'s in the
        !           155:         *  service part with '\'s.
        !           156:         */
        !           157:        for(i=0, cp=ip->name, dp=dialstr; *cp; cp++)
        !           158:                if (i<2 && *cp=='!'){
        !           159:                        *dp++ = '.';
        !           160:                        i++;
        !           161:                } else if (i==1 && *cp=='.') {
        !           162:                        *dp++ = '\\';
        !           163:                        *dp++ = '.';
        !           164:                } else if (*cp=='\n') {
        !           165:                        close(fd);
        !           166:                        return ABORT(EACCES, "illegal dial string", NULLINFO);
        !           167:                } else
        !           168:                        *dp++ = *cp;
        !           169:        *dp = '\0';
        !           170:        switch(operation){
        !           171:        case dial:
        !           172:                strcat(dialstr, "\n");
        !           173:                strcat(dialstr, ip->user);
        !           174:                break;
        !           175:        case redial:
        !           176:                strcat(dialstr, "\n");
        !           177:                strcat(dialstr, ip->user);
        !           178:                strcat(dialstr, "\n");
        !           179:                strcat(dialstr, ip->machine);
        !           180:                break;
        !           181:        }
        !           182: 
        !           183:        /*
        !           184:         *  send request on common signalling channel
        !           185:         */
        !           186:        alarm(15);
        !           187:        i = write(listener, (char *)&d, sizeof(d));
        !           188:        close(listener);
        !           189:        if (i != sizeof(d)) {
        !           190:                alarm(0);
        !           191:                close(fd);
        !           192:                ip->cfd = -1;
        !           193:                return ABORT(EIO, "can't dial out on dk", NULLINFO);
        !           194:        }
        !           195: 
        !           196:        /*
        !           197:         *  wait for dial tone (REDIAL only)
        !           198:         */
        !           199:        if(operation==redial && (read(fd, dialtone, 1)!=1 || *dialtone!='O')) {
        !           200:                alarm(0);
        !           201:                close(fd);
        !           202:                ip->cfd = -1;
        !           203:                return ABORT(EIO, "no dialtone on dk", NULLINFO);
        !           204:        }
        !           205: 
        !           206:        /*
        !           207:         *  dial out
        !           208:         */
        !           209:        alarm(60);
        !           210:        ioctl(fd, DIOCSTOP, 0);         /* hold back user data */
        !           211:        write(fd, dialstr, strlen(dialstr));
        !           212:        if(operation==redial){
        !           213:                alarm(0);
        !           214:                return fd;
        !           215:        }
        !           216: 
        !           217:        /*
        !           218:         *  get reply back (REDIAL never gets here)
        !           219:         */
        !           220:        i = read(fd, (char *)&reply, sizeof reply);
        !           221:        alarm(0);
        !           222:        if (i <= 0) {
        !           223:                close(fd);
        !           224:                return ABORT(EIO,"remote system doesn't respond",
        !           225:                                (ipcinfo *)NULL);
        !           226:        }
        !           227: 
        !           228:        /* 
        !           229:         *  successful reply, analyze it
        !           230:         */
        !           231:        i = (reply.param1h<<8) | reply.param1l;
        !           232:        if (reply.srv!=D_OPEN) {
        !           233:                close(fd);
        !           234:                dktouerr(i&0x7f);
        !           235:                return -1;
        !           236:        }
        !           237:        if (W_VALID(i)){
        !           238:                /*
        !           239:                 *  a 1127 window negotiation
        !           240:                 */
        !           241:                window = W_VALUE(W_DEST(i));
        !           242:        } else if(i>2 && i<31){
        !           243:                /*
        !           244:                 *  a generic window negotiation
        !           245:                 */
        !           246:                window = 1<<i;
        !           247:        } else
        !           248:                window = 0;
        !           249:        logevent("out window(%d)\n", window);
        !           250:        dkproto(fd, dkp_ld);
        !           251:        ioctl(fd, FIOPOPLD, 0);         /* dump rdk */
        !           252:        setwins(fd, window);
        !           253:        ip->myname = "";
        !           254:        ip->machine = "";
        !           255:        return fd;
        !           256: }
        !           257: 
        !           258: al_catch()
        !           259: {
        !           260: }

unix.superglobalmegacorp.com

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