|
|
1.1 root 1: #include "mgr.h"
2: #include "defs.h"
3: #include <errno.h>
4: #include <sys/param.h>
5: #include <sys/filio.h>
6: #include <signal.h>
7:
8: static int
9: dingaling()
10: {
11: signal(SIGALRM, dingaling);
12: }
13:
14: /*
15: * Dial out to a gateway. Return -1 if no more gates are to be tried.
16: * Return 0 if more gates are to be tried.
17: */
18: gateout(rp, ap)
19: Request *rp;
20: Action *ap;
21: {
22: int fd;
23: char *cp;
24: static stretch newipcname;
25: extern int rmesg_ld;
26:
27: if (rp->i->cfd>=0) {
28: ipcreject(rp->i, EINVAL, "gate-through disallowed");
29: return -1;
30: }
31:
32: /* call `gateway' */
33: fd = ipcopen(ap->arg, rp->i->param);
34:
35: /* send original request */
36: if (fd<0 || _info_write(fd, rp->i)<0) {
37: /* if there are any more gateout's, keep trying */
38: if (ap->next==NULL)
39: ipcreject(rp->i, errno, errstr);
40: close(fd);
41: return 0;
42: }
43:
44: /* see if the gateway could place the call */
45: if (_reply_read(fd)<0 || errno!=0) {
46: /* call was rejected, don't try any more gateouts */
47: ipcreject(rp->i, errno, errstr);
48: close(fd);
49: return -1;
50: }
51:
52: /* see if we can push the rmesg ld */
53: /*
54: if (ioctl(fd, FIOPUSHLD, &rmesg_ld)<0) {
55: ipcreject(rp->i, errno, "can't push rmesg_ld");
56: close(fd);
57: return -1;
58: }
59: */
60:
61: /* gateway and call were accepted -- pass back a corrected ipcname */
62: cp = strchr(ipcname, '!');
63: _strcat(&newipcname, rp->i->myname, "!", cp);
64: ipcdaccept(rp->i, fd, newipcname.ptr);
65: return -1;
66: }
67:
68: /*
69: * Acccept a gateway call
70: */
71: gateway(rp, ap)
72: Request *rp;
73: Action *ap;
74: {
75: int caller, callee;
76: ipcinfo info;
77: ipcinfo *ip;
78: fd_set fds;
79: char newname[ARB];
80: extern int mesg_ld;
81: char *mapuser();
82: int (*oldsig)();
83:
84: /* see if we gateway for this requestor */
85: if (mapuser(rp->s->name, rp->i->machine, rp->i->user)==NULL) {
86: ipcreject(rp->i, EACCES, "gateway disallowed");
87: return -1;
88: }
89: if ((caller=ipcaccept(rp->i))<0)
90: return -1;
91:
92: /* the next info_read would destroy these fields */
93: rp->i->machine = strdup(rp->i->machine);
94: rp->i->user = strdup(rp->i->user);
95:
96: /* get the original request */
97: info.uid = info.gid = 0;
98: info.user="";
99: if (_info_read(caller, &info)<0)
100: return -1;
101:
102: /* dial the number */
103: sprintf(newname, "%s!%s", ap->arg, info.name);
104: info.name = newname;
105: info.rfd = info.cfd = -1;
106: oldsig=signal(SIGALRM, dingaling);
107: alarm(30);
108: callee = ipcdial(&info);
109: alarm(0);
110: signal(SIGALRM, oldsig);
111:
112: /* log it */
113: rp->i->name = info.name;
114: rp->i->myname = info.myname;
115: logstatus("gate", rp->i);
116: if (callee<0) {
117: _reply_write(caller, errno, errstr);
118: close(caller);
119: return -1;
120: }
121:
122: /* try to push mesg ld */
123: /*
124: if(ioctl(callee, FIOPUSHLD, &mesg_ld)<0){
125: _reply_write(caller, errno, "can't push mesg ld");
126: close(caller);
127: close(callee);
128: return -1;
129: }
130: */
131:
132: /* tell gateout that it worked */
133: if (_reply_write(caller, 0, ipcname)<0) {
134: close(caller);
135: close(callee);
136: return -1;
137: }
138:
139: /*
140: * For creat's, we accept only one call per creat. This
141: * makes life a lot simpler since we can use the current
142: * connection to the other end.
143: */
144: if(info.flags & IPC_CREAT) {
145: int nfd;
146: struct fd_set fds;
147:
148: /* wait for call or hangup */
149: FD_ZERO(fds);
150: FD_SET(callee, fds);
151: FD_SET(caller, fds);
152: switch(select(NOFILE, &fds, (struct fd_set *)0, 10000000)){
153: case 0:
154: case -1:
155: exit(0);
156: }
157: if(FD_ISSET(caller, fds))
158: exit(0);
159:
160: /* get call info */
161: if((ip = ipclisten(callee)) == NULL)
162: exit(0);
163:
164: /* pass it creator */
165: if(_info_write(caller, ip) < 0)
166: exit(0);
167: if(_reply_read(caller) < 0)
168: exit(0);
169: if(errno) {
170: ipcreject(ip, errno, errstr);
171: exit(0);
172: } else {
173: nfd = ipcdaccept(ip, -1, ipcname);
174: close(callee);
175: callee = nfd;
176: }
177: }
178:
179: /* shuttle bytes back and forth */
180: FD_ZERO(fds);
181: for(;;) {
182: FD_SET(caller, fds);
183: FD_SET(callee, fds);
184: switch(select(NOFILE, &fds, (struct fd_set *)0, 1000)) {
185: case -1:
186: return -1;
187: case 0:
188: continue;
189: }
190: if (FD_ISSET(caller, fds))
191: if (pass(caller, callee)<0)
192: exit(0);
193: if (FD_ISSET(callee, fds))
194: if (pass(callee, caller)<0)
195: exit(0);
196: }
197: }
198:
199: pass(from, to)
200: int from, to;
201: {
202: char buf[4096];
203: int n;
204:
205: if ((n=read(from, buf, sizeof(buf)))<=0)
206: return -1;
207: if (write(to, buf, n)!=n)
208: return -1;
209: return 0;
210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.