Annotation of researchv10no/ipc/mgrs/ndkmgr/dial.c, revision 1.1.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.