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