|
|
1.1 root 1: #include <sys/types.h>
2: #include <stdio.h>
3: #include <sys/ioctl.h>
4: #include <ipc.h>
5: #include <libc.h>
6: #include <wait.h>
7: #include "defs.h"
8:
9: /* preeclared */
10: void dodialout();
11: void dodialin();
12: void doopen();
13: void docreat();
14:
15: /* global */
16: int pid;
17:
18: /* imported */
19: extern char *av0;
20: extern int net_dial();
21: extern int net_announce();
22: extern void net_accept();
23: extern void net_reject();
24: extern ipcinfo *net_listen();
25: extern char *getlogin();
26:
27: static
28: deadbaby()
29: {
30: while(wait3(NULL, WNOHANG, NULL)>0)
31: ;
32: signal(SIGCHLD, deadbaby);
33: }
34:
35: /* loop on calls out of the CPU */
36: void
37: dodialout(mtpt)
38: char *mtpt;
39: {
40: int fd;
41: int st;
42:
43: pid = getpid();
44:
45: /* plug into local name space */
46: for(st=1;;st=st>60?st:(st<<1)){
47: fd = ipccreat(mtpt, "");
48: if (fd>=0)
49: break;
50: logconsole("%s: can't announce as %s (%s)\n", av0, mtpt, errstr);
51: sleep(st);
52: }
53: chmod(mtpt, 0666);
54: logconsole("%s: announced to fs as %s\n", av0, mtpt);
55: fflush(stdout);
56:
57: /* loop on requests */
58: for(;;) {
59: ipcinfo *ip;
60:
61: ip = ipclisten(fd);
62: if (ip == NULL) {
63: fprintf(stderr,"out broken listen\n");
64: break;
65: }
66:
67: /* run request as separate process */
68: signal(SIGCHLD, deadbaby);
69: switch(fork()) {
70: case -1: /* whoops */
71: ipcreject(ip, errno, "no more processes");
72: logstatus(ip);
73: continue;
74: case 0:
75: close(fd);
76: break;
77: default:
78: (void)ABORT(0, "", ip);
79: continue;
80: }
81:
82: logcall("callout", ip);
83: if (ip->flags & IPC_CREAT)
84: docreat(ip);
85: else
86: doopen(ip, mtpt);
87: exit(0);
88: }
89: close(fd);
90: }
91:
92: /* establish a connection to a net name */
93: void
94: doopen(ip, mtpt)
95: ipcinfo *ip;
96: char *mtpt;
97: {
98: int fd;
99: static stretch myname;
100:
101: *av0 = 'D';
102:
103: fd = net_dial(ip);
104: if (fd < 0) {
105: ipcreject(ip, errno, errstr);
106: logstatus(ip);
107: return;
108: }
109: errno = 0; errstr = "";
110: _strcat(&myname, mtpt, "!", ip->myname);
111: ipcdaccept(ip, fd, myname.ptr);
112: close(fd);
113: logstatus(ip);
114: }
115:
116: /* announce a new netname */
117: void
118: docreat(ip)
119: ipcinfo *ip;
120: {
121: ipcinfo *netip;
122: int listenfd;
123: int toclient;
124: int pfd[2];
125: fd_set fds;
126:
127: if (ip->cfd >= 0) {
128: ipcreject(ip, EIO, "can't do remote ipccreat");
129: logstatus(ip);
130: return;
131: }
132:
133: *av0 = 'L';
134:
135: /* for communications with requestor */
136: if (pipe(pfd) < 0) {
137: ipcreject(ip, errno, "can't create local channel");
138: logstatus(ip);
139: return;
140: }
141: toclient = pfd[1];
142:
143: /* dial out on device */
144: listenfd = net_announce(ip);
145: if (listenfd < 0) {
146: close(pfd[0]);
147: close(pfd[1]);
148: ipcreject(ip, errno, errstr);
149: logstatus(ip);
150: return;
151: }
152:
153: /* accept the announce request */
154: if (ipcdaccept(ip, pfd[0], "who_knows") < 0)
155: return;
156: close(pfd[0]);
157: errno = 0; errstr = "";
158: logstatus(ip);
159:
160: /* loop waiting for in calls */
161: FD_ZERO(fds);
162: FD_SET(listenfd, fds);
163: FD_SET(toclient, fds);
164: while(1) {
165: fd_set rfds;
166: int rv;
167:
168: /* check for input or hang-up */
169: rfds = fds;
170: rv = select(NOFILE, &rfds, (fd_set*)0, 10000);
171: if (rv == 0)
172: continue;
173: else if (rv < 0)
174: break;
175: else if (FD_ISSET(toclient, rfds))
176: break;
177:
178: /* get request */
179: netip = net_listen(listenfd);
180: if (netip == NULL) {
181: ABORT(errno, errstr, ip);
182: break;
183: }
184: logcall(ip->name, netip);
185:
186: /* make a new channel to the listener */
187: if (pipe(pfd)<0) {
188: net_reject(netip, errno, "no more pipes");
189: logstatus(ip);
190: continue;
191: }
192: if (ioctl(toclient, FIOSNDFD, &(pfd[0]))<0) {
193: net_reject(netip, errno, "protocol botch");
194: logstatus(ip);
195: break;
196: }
197: close(pfd[0]);
198:
199: /* pass the request over the new channel */
200: if (ioctl(pfd[1], FIOSNDFD, &(netip->rfd))<0) {
201: net_reject(netip, errno, "protocol botch");
202: close(pfd[1]);
203: logstatus(ip);
204: continue;
205: }
206: close(netip->rfd);
207: netip->rfd = -1;
208: if (_info_write(pfd[1], netip) < 0) {
209: net_reject(netip, errno, "protocol botch");
210: close(pfd[1]);
211: logstatus(ip);
212: continue;
213: }
214: if (_reply_read(pfd[1]) < 0)
215: net_reject(netip, errno, "protocol botch");
216: else
217: net_accept(netip);
218: logstatus(ip);
219: close(pfd[1]);
220: }
221: return;
222: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.