Annotation of researchv10no/ipc/mgrs/ndkmgr/dkctlchan.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 <stdio.h>
                      5: #include <errno.h>
                      6: #include <sys/dkio.h>
                      7: 
                      8: extern int errno;
                      9: extern int uxp_ld;
                     10: extern int dkp_ld;
                     11: extern char *netfiles; /* /dev/dk/dk by default */
                     12: 
                     13: static char *cnames[] = {
                     14:        "%sctl0",
                     15:        "%sctl",
                     16:        "%sctl2",
                     17:        0
                     18: };
                     19: static char *names[] = {
                     20:        "%s0%c%c",
                     21:        "%s%c%c",
                     22:        "%s2%c%c",
                     23:        0
                     24: };
                     25: 
                     26: static char alph[] = "0123456789abcdefghijklmnopqrstuvwxyz";
                     27: 
                     28: static int high[] = {256, 256};
                     29: static int low[] = {1, 1};
                     30: 
                     31: /*
                     32:  *     figure out which set of dk channels to use
                     33:  */
                     34: static
                     35: dkindex(traffic, unit)
                     36:        int traffic;
                     37:        int unit;
                     38: {
                     39:        switch(unit) {
                     40:        case '0':
                     41:                return 0;
                     42:        case '2':
                     43:                return 2;
                     44:        case 'b':
                     45:                return traffic;
                     46:        default:
                     47:                return 1;
                     48:        }
                     49: }
                     50: 
                     51: /*
                     52:  *     Open a free dk channel and remember the `type' in namefmt.
                     53:  *     If one device doesn't work, try another.
                     54:  */
                     55: static int
                     56: dkchan2(traffic, unit, chanp, ctlfdp)
                     57:        int traffic;
                     58:        int unit;
                     59:        int *chanp;
                     60:        int *ctlfdp;
                     61: {
                     62:        int missing=0;
                     63:        char outname[64];
                     64:        register i,j;
                     65:        int k;
                     66:        int fd;
                     67:        int ai;
                     68:        int nfd;
                     69: 
                     70:        /*
                     71:         *  get the control channel and ask for a suggested channel
                     72:         */
                     73:        *ctlfdp = dkctlchan(traffic, unit);
                     74:        if(*ctlfdp<0)
                     75:                return -1;
                     76:        k = 0;
                     77:        if(ioctl(*ctlfdp, DIOCCHAN, &k)>0 && k>0)
                     78:                low[0] = high[1] = k;
                     79: 
                     80:        /*
                     81:         *  starting with the suggested channel, loop through all
                     82:         *  channels looking for one not in use
                     83:         */
                     84:        ai=dkindex(traffic, unit);
                     85:        for (j=0; j<2; j++) {
                     86:                for (i=low[j]; i<high[j]; i++) {
                     87:                        sprintf(outname, names[ai], netfiles, alph[i/10], alph[i%10]);
                     88:                        if ((fd = open(outname, 2)) >= 0){
                     89:                                if ((nfd = open(outname, 2)) >= 0) {
                     90:                                        close(nfd);
                     91:                                        close(fd);
                     92:                                        continue;       /* already in use */
                     93:                                }
                     94:                                flabclr(fd);    /* for secure unix */
                     95:                                break;
                     96:                        }
                     97:                        if (errno==ENOENT) 
                     98:                                if (++missing>5)
                     99:                                        break;
                    100:                }
                    101:                if (fd>=0)
                    102:                        break;
                    103:        }
                    104:        if (fd < 0)
                    105:                return -1;
                    106:        low[0] = high[1] = i+1;
                    107:        *chanp = i;
                    108:        return fd;
                    109: }
                    110: int
                    111: dkchan(trafp, unit, chanp, ctlfdp)
                    112:        int *trafp;
                    113:        int unit;
                    114:        int *chanp;
                    115:        int *ctlfdp;
                    116: {
                    117:        int fd;
                    118: 
                    119:        fd = dkchan2(*trafp, unit, chanp, ctlfdp);
                    120:        if(fd >= 0)
                    121:                return fd;
                    122:        if (*trafp == 0)
                    123:                *trafp = 2;
                    124:        else
                    125:                *trafp = 0;
                    126:        return dkchan2(*trafp, unit, chanp, ctlfdp);
                    127: }
                    128: 
                    129: /*
                    130:  * open common control channel
                    131:  */
                    132: dkctlchan(traffic, unit)
                    133: {
                    134:        register i ;
                    135:        char dkctlfile[32];
                    136:        int ai;
                    137: 
                    138:        ai=dkindex(traffic, unit);
                    139:        sprintf(dkctlfile, cnames[ai], netfiles);
                    140:        i = open(dkctlfile, 2);
                    141:        if (i < 0)
                    142:                return -1;
                    143:        ioctl(i, DIOCNXCL, 0);
                    144:        if (ioctl(i, FIOLOOKLD, 0) != uxp_ld) {
                    145:                if (dkproto(i, dkp_ld) < 0) {
                    146:                        fprintf(stderr, "can't push dkp_ld on %s\n", dkctlfile) ;
                    147:                        close(i) ;
                    148:                        return -1;
                    149:                }
                    150:                if (ioctl(i, FIOPUSHLD, &uxp_ld) < 0) {
                    151:                        fprintf(stderr, "can't push unixp_ld on %s\n", dkctlfile) ;
                    152:                        close(i) ;
                    153:                        return -1;
                    154:                }
                    155:                if (ioctl(i, DIOCLHN, (char *)0) < 0) {
                    156:                        fprintf(stderr, "can't be manager on %s\n", dkctlfile) ;
                    157:                        close(i);
                    158:                        return -1;
                    159:                }
                    160:        }
                    161:        return i;
                    162: }
                    163: 
                    164: /*
                    165:  * find the file name corresponding to a given channel.
                    166:  * assumes dkctlchan has been called.
                    167:  * Used for incoming calls.
                    168:  */
                    169: char *
                    170: dkfilename(traffic, unit, chan)
                    171: {
                    172:        static char name[64];
                    173: 
                    174:        sprintf(name, names[dkindex(traffic, unit)], netfiles, alph[chan/10], alph[chan%10]);
                    175:        return(name);
                    176: }
                    177: 
                    178: /*
                    179:  * Make sure that URP protocol is enabled on a datakit file.
                    180:  */
                    181: int
                    182: dkproto(file, linedis)
                    183: {
                    184:        if (ioctl(file, KIOCISURP, (char *)0) < 0)
                    185:                return(ioctl(file, FIOPUSHLD, &linedis));
                    186:        ioctl(file, KIOCINIT, (char *)0);
                    187:        return(0);
                    188: }
                    189: 
                    190: /*
                    191:  * find the traffic type and channel number corresponding to an fd.
                    192:  * Used for redial.
                    193:  */
                    194: int
                    195: dkid(fd, unit, trafficp, chanp, ctlfdp)
                    196:        int fd;
                    197:        int unit;
                    198:        int *trafficp;
                    199:        int *chanp;
                    200:        int *ctlfdp;
                    201: {
                    202:        struct stat s;
                    203:        struct stat s2;
                    204: 
                    205:        /*
                    206:         *  find major minor
                    207:         */
                    208:        if(fstat(fd, &s)<0)
                    209:                return -1;
                    210: 
                    211:        /*
                    212:         *  compare major/minor of fd against that of device 3
                    213:         */
                    214:        if(stat(dkfilename(0, unit, 3), &s2)>=0){
                    215:                if(major(s.st_rdev)==major(s2.st_rdev)){
                    216:                        if(minor(s.st_rdev)>minor(s2.st_rdev)-3){
                    217:                                *trafficp = 0;
                    218:                                *chanp = minor(s.st_rdev)-minor(s2.st_rdev)+3;
                    219:                                *ctlfdp = dkctlchan(*trafficp, unit);
                    220:                                if(*ctlfdp < 0)
                    221:                                        return -1;
                    222:                                return 0;
                    223:                        }
                    224:                }
                    225:        }
                    226:        if(stat(dkfilename(2, unit, 3), &s2)>=0){
                    227:                if(major(s.st_rdev)==major(s2.st_rdev)){
                    228:                        if(minor(s.st_rdev)>minor(s2.st_rdev)-3){
                    229:                                *trafficp = 2;
                    230:                                *chanp = minor(s.st_rdev)-minor(s2.st_rdev)+3;
                    231:                                *ctlfdp = dkctlchan(*trafficp, unit);
                    232:                                if(*ctlfdp < 0)
                    233:                                        return -1;
                    234:                                return 0;
                    235:                        }
                    236:                }
                    237:        }
                    238:        return -1;
                    239: }

unix.superglobalmegacorp.com

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