|
|
1.1 root 1: * Remote dialer routine.
2: */
3: #include <sys/types.h>
4: #include <stdio.h>
5: #include <libc.h>
6: #include <sys/utsname.h>
7: #include <errno.h>
8: #include <sys/filio.h>
9: #include <ipc.h>
10: #include "defs.h"
11:
12: /* export */
13: char *av0;
14: char *param;
15: int debug;
16:
17: /* cheap foiegn imports */
18: extern void dodialout(), dodialin();
19:
20: usage(name)
21: char *name;
22: {
23: fprintf(stderr, "usage: %s [-m mount-pt] [-n netname] gate1 [gate2 ...]\n", name);
24: exit(1);
25: }
26:
27: /*
28: * Gate calls to/from a remote network.
29: */
30: main(ac, av)
31: int ac;
32: char *av[];
33: {
34: char *netname=NULL, *mtpt="rem", *cp;
35: int ai;
36:
37: av0 = av[0];
38: chdir("/cs");
39:
40: /* get args */
41: for (ai=1; ai<ac; ai++) {
42: if (av[ai][0] == '-')
43: for (cp=&av[ai][1]; *cp; cp++) {
44: switch(*cp) {
45: case 'm':
46: if (ai+1>=ac)
47: usage(av[0]);
48: mtpt = av[++ai];
49: break;
50: case 'n':
51: if (ai+1>=ac)
52: usage(av[0]);
53: netname = av[++ai];
54: break;
55: case 'd':
56: debug = 1;
57: break;
58: default:
59: usage(av0);
60: }
61: }
62: else
63: break;
64: }
65:
66: /* get gateways */
67: if(ai>=ac)
68: usage(av0);
69:
70: /* detach from process group, terminal, etc. */
71: if (!debug)
72: detach(mtpt);
73:
74: /* get defaults */
75: if (netname==NULL) {
76: struct utsname name;
77:
78: uname(&name);
79: netname = name.nodename;
80: }
81:
82: /* create dialer and listener */
83: switch (fork()) {
84: case -1:
85: perror(av0);
86: exit(1);
87: case 0:
88: for(;;)
89: dodialout(mtpt);
90: default:
91: for(;;)
92: dodialin(mtpt, netname, "heavy");
93: }
94: }
95:
96: static int
97: dingaling()
98: {
99: signal(SIGALRM, dingaling);
100: }
101:
102: /*
103: * Dial out to a gateway. Return -1 if no more gates are to be tried.
104: * Return 0 if more gates are to be tried.
105: */
106: gateout(rp, ap)
107: Request *rp;
108: Action *ap;
109: {
110: int fd;
111: extern int rmesg_ld;
112: char netname[ARB];
113: char *cp;
114:
115: if (rp->i->cfd>=0) {
116: ipcreject(rp->i, EINVAL, "gate-through disallowed");
117: return -1;
118: }
119:
120: /* call `gateway' */
121: fd = ipcopen(ap->arg, rp->i->param);
122:
123: /* send original request */
124: if (fd<0 || _info_write(fd, rp->i)<0) {
125: /* if there are any more gateout's, keep trying */
126: if (ap->next==NULL)
127: ipcreject(rp->i, errno, errstr);
128: close(fd);
129: return 0;
130: }
131:
132: /* see if the gateway could place the call */
133: if (_reply_read(fd)<0 || errno!=0) {
134: /* call was rejected, don't try any more gateouts */
135: ipcreject(rp->i, errno, errstr);
136: close(fd);
137: return -1;
138: }
139:
140: /* gateway and call were accepted */
141: if(rp->i->flags == IPC_CREAT){
142: /* for remote announcements, this process becomes a mux */
143: lfd = ipcaccept(rp->i);
144: localmux(fd, lfd);
145: return -1;
146: } else {
147: /* for remote dials, just pass the net fd back to the process */
148: ipcdaccept(rp->i, fd, ipcname);
149: return -1;
150: }
151: }
152:
153: /*
154: * Acccept a gateway call
155: */
156: gateway(rp, ap)
157: Request *rp;
158: Action *ap;
159: {
160: int caller, callee;
161: ipcinfo info;
162: fd_set fds;
163: char newname[ARB];
164: extern int mesg_ld;
165: char *mapuser();
166: int (*oldsig)();
167:
168: /* see if we gateway for this requestor */
169: if (mapuser(rp->s->name, rp->i->machine, rp->i->user)==NULL) {
170: ipcreject(rp->i, EACCES, "gateway disallowed");
171: return -1;
172: }
173: if ((caller=ipcaccept(rp->i))<0)
174: return -1;
175:
176: /* get the original request */
177: info.uid = info.gid = 0;
178: info.user="";
179: if (_info_read(caller, &info)<0)
180: return -1;
181:
182: /* make the call */
183: if(rp->i->flags == IPC_CREAT){
184: /* for remote announcements, this process becomes a mux */
185: lfd = ipcaccept(rp->i);
186: localmux(fd, lfd);
187: return -1;
188: } else {
189: /* for remote dials, just shuttle bytes back and forth */
190: ipcdaccept(rp->i, fd, "who_cares");
191: return -1;
192: }
193:
194: /* dial the number */
195: sprintf(newname, "%s!%s", ap->arg, info.name);
196: info.name = newname;
197: info.rfd = info.cfd = -1;
198: info.flags = IPC_OPEN;
199: oldsig=signal(SIGALRM, dingaling);
200: alarm(30);
201: callee = ipcdial(&info);
202: alarm(0);
203: signal(SIGALRM, oldsig);
204: if (callee<0) {
205: _reply_write(caller, errno, errstr);
206: close(caller);
207: return -1;
208: }
209:
210: /* tell gateout that it worked */
211: if (_reply_write(caller, 0, "")<0) {
212: close(caller);
213: close(callee);
214: return -1;
215: }
216:
217: /* shuttle bytes back and forth */
218: FD_ZERO(fds);
219: for(;;) {
220: FD_SET(caller, fds);
221: FD_SET(callee, fds);
222: switch(select(NOFILE, &fds, (struct fd_set *)0, 1000)) {
223: case -1:
224: return -1;
225: case 0:
226: continue;
227: }
228: if (FD_ISSET(caller, fds))
229: if (pass(caller, callee)<0)
230: return -1;
231: if (FD_ISSET(callee, fds))
232: if (pass(callee, caller)<0)
233: return -1;
234: }
235: }
236:
237: pass(from, to)
238: int from, to;
239: {
240: char buf[4096];
241: int n;
242:
243: if ((n=read(from, buf, sizeof(buf)))<=0)
244: return -1;
245: if (write(to, buf, n)!=n)
246: return -1;
247: return 0;
248: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.