|
|
1.1 root 1: #include "mgr.h"
2: #include <errno.h>
3: #include <sys/types.h>
4: #include <sys/filio.h>
5:
6: /*
7: * Dial out to a gateway. Return -1 if no more gates are to be tried.
8: * Return 0 if more gates are to be tried.
9: */
10: gateout(rp, ap)
11: Request *rp;
12: Action *ap;
13: {
14: int fd;
15: extern int rmesg_ld;
16:
17: if (rp->i->cfd>=0) {
18: ipcreject(rp->i, EINVAL, "gate-through disallowed");
19: return -1;
20: }
21:
22: /* call `gateway' */
23: fd = ipcopen(ap->arg, rp->i->param);
24:
25: /* send original request */
26: if (fd<0 || _info_write(fd, rp->i)<0) {
27: /* if there are any more gateout's, keep trying */
28: if (ap->next==NULL)
29: ipcreject(rp->i, errno, errstr);
30: close(fd);
31: return 0;
32: }
33:
34: /* see if the gateway could place the call */
35: if (_reply_read(fd)<0 || errno!=0 || ioctl(fd, FIOPUSHLD, &rmesg_ld)<0) {
36: /* call was rejected, don't try any more gateouts */
37: ipcreject(rp->i, errno, errstr);
38: close(fd);
39: return -1;
40: }
41:
42: /* gateway and call were accepted -- go for it */
43: ipcdaccept(rp->i, fd, "who_cares");
44: return -1;
45: }
46:
47: /*
48: * Acccept a gateway call
49: */
50: gateway(rp, ap)
51: Request *rp;
52: Action *ap;
53: {
54: int caller, callee;
55: ipcinfo info;
56: fd_set fds;
57: char newname[ARB];
58: extern int mesg_ld;
59: char *mapuser();
60:
61: /* see if we gateway for this requestor */
62: if (mapuser(rp->s->name, rp->i->machine, rp->i->user)==NULL) {
63: ipcreject(rp->i, EACCES, "gateway disallowed");
64: return -1;
65: }
66: if ((caller=ipcaccept(rp->i))<0)
67: return -1;
68:
69: /* get the original request */
70: info.uid = info.gid = 0;
71: if (_info_read(caller, &info)<0)
72: return -1;
73:
74: /* dial the number */
75: sprintf(newname, "%s!%s", ap->arg, info.name);
76: info.name = newname;
77: info.rfd = info.cfd = -1;
78: info.flags = IPC_OPEN;
79: callee = ipcdial(&info);
80: if (callee<0 || ioctl(callee, FIOPUSHLD, &rmesg_ld)<0) {
81: _reply_write(caller, errno, errstr);
82: close(caller);
83: return -1;
84: }
85:
86: /* tell gateout that it worked */
87: if (_reply_write(caller, 0, "")<0) {
88: close(callee);
89: return -1;
90: }
91:
92: /* shuttle bytes back and forth */
93: FD_ZERO(fds);
94: for(;;) {
95: FD_SET(caller, fds);
96: FD_SET(callee, fds);
97: switch(select(NOFILE, &fds, (struct fd_set *)0, 1000)) {
98: case -1:
99: return -1;
100: case 0:
101: continue;
102: }
103: if (FD_ISSET(caller, fds))
104: if (pass(caller, callee)<0)
105: return -1;
106: if (FD_ISSET(callee, fds))
107: if (pass(callee, caller)<0)
108: return -1;
109: }
110: }
111:
112: pass(from, to)
113: int from, to;
114: {
115: char buf[ARB];
116: int n;
117:
118: if ((n=read(from, buf, ARB))<=0)
119: return -1;
120: if (write(to, buf, n)!=n)
121: return -1;
122: return 0;
123: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.