|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.