|
|
1.1 root 1: #include "ipc.h"
2: #include "mgr.h"
3: #include <errno.h>
4: #include <sys/types.h>
5: #include <sys/filio.h>
6:
7: /* buffer definition */
8: #define BUFLEN 512
9:
10: /* our name */
11: char *ipcname;
12:
13: /*
14: * timeout routine
15: */
16: static int
17: dingaling()
18: {
19: signal(SIGALRM, dingaling);
20: }
21:
22: /*
23: * gate a call to the arpanet
24: */
25: main()
26: {
27: int caller, callee;
28: ipcinfo info;
29: ipcinfo *ip;
30: fd_set fds;
31: char newname[BUFLEN];
32: int (*oldsig)();
33:
34: /*
35: * get the original request
36: */
37: info.uid = info.gid = 0;
38: info.user="root";
39: if (_info_read(caller, &info)<0)
40: return -1;
41:
42: /*
43: * dial the number
44: */
45: sprintf(newname, "%s!%s", "/cs/tcp", info.name);
46: info.name = newname;
47: info.rfd = info.cfd = -1;
48: oldsig=signal(SIGALRM, dingaling);
49: alarm(30);
50: callee = ipcdial(&info);
51: alarm(0);
52: signal(SIGALRM, oldsig);
53:
54: /*
55: * return status
56: */
57: if (callee<0) {
58: _reply_write(caller, errno, errstr);
59: close(caller);
60: return -1;
61: }
62: if (_reply_write(caller, 0, ipcname)<0) {
63: close(caller);
64: close(callee);
65: return -1;
66: }
67:
68: /*
69: * For creat's, we accept only one call per creat. This
70: * makes life a lot simpler though less general.
71: */
72: if(info.flags & IPC_CREAT) {
73: int nfd;
74:
75: if((ip = ipclisten(callee)) == NULL)
76: exit(0);
77: if(_info_write(caller, ip) < 0)
78: exit(0);
79: if(_reply_read(caller) < 0)
80: exit(0);
81: if(errno) {
82: ipcreject(ip, errno, errstr);
83: exit(0);
84: } else {
85: nfd = ipcdaccept(ip, -1, ipcname);
86: close(callee);
87: callee = nfd;
88: }
89: }
90:
91: /*
92: * shuttle bytes back and forth
93: */
94: FD_ZERO(fds);
95: for(;;) {
96: FD_SET(caller, fds);
97: FD_SET(callee, fds);
98: switch(select(NOFILE, &fds, (struct fd_set *)0, 1000)) {
99: case -1:
100: return -1;
101: case 0:
102: continue;
103: }
104: if (FD_ISSET(caller, fds))
105: if (pass(caller, callee)<0)
106: exit(0);
107: if (FD_ISSET(callee, fds))
108: if (pass(callee, caller)<0)
109: exit(0);
110: }
111: }
112:
113: pass(from, to)
114: int from, to;
115: {
116: char buf[4096];
117: int n;
118:
119: if ((n=read(from, buf, sizeof(buf)))<=0)
120: return -1;
121: if (write(to, buf, n)!=n)
122: return -1;
123: return 0;
124: }
125:
126: /*
127: * Send the connection info.
128: */
129: int
130: _info_write(fd, ip)
131: int fd;
132: ipcinfo *ip;
133: {
134: char b[BUFLEN];
135: int n;
136:
137: if (ip->name==NULL)
138: ip->name = "";
139: if (ip->param==NULL)
140: ip->param = "";
141: if (ip->machine==NULL)
142: ip->machine = "";
143: if (ip->user==NULL)
144: ip->user = "";
145: if (ip->myname==NULL)
146: ip->myname = "";
147: sprintf(b, "%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n", ip->myname, ip->name,
148: ip->param, ip->machine, ip->user, ip->flags, ip->uid, ip->gid);
149: n = strlen(b);
150: if (write(fd, b, n)!=n)
151: return ABORT(errno, "can't send request", NULLINFO);
152: return 0;
153: }
154:
155:
156: /* dial a number or plug into the name space */
157: ipcdial(ip)
158: ipcinfo *ip;
159: {
160: /*
161: * decode the call
162: */
163: if(
164: if (ip->flags && IPC_CREAT){
165: /* plug into the name space */
166: } else {
167: }
168: }
169:
170: /* listen for a connection */
171: ipcinfo *
172: ipclisten(fd)
173: int fd;
174: {
175: static ipcinfo info;
176: static char buf[BUFSIZE];
177: static char user[32];
178:
179: /* accept only one connection */
180: info.rfd = fd;
181: close(fd);
182:
183: /* get the request */
184: if (_info_read(info.rfd, &info)<0) {
185: /* requestor gave up */
186: close(info.rfd);
187: return NULL;
188: }
189:
190: return &info;
191: }
192:
193: /*
194: * Accept a connection. Close all except ip->cfd.
195: */
196: int
197: ipcaccept(ip)
198: ipcinfo *ip;
199: {
200: ipcdaccept(ip, -1, "who_cares");
201: }
202:
203: /*
204: * Accept a connection, and supply a source address and communications fd
205: */
206: int
207: ipcdaccept(ip, commfd, source)
208: ipcinfo *ip;
209: int commfd;
210: char *source;
211: {
212: if (commfd >= 0) {
213:
214: /* supply our own channel for communications */
215: if (_fd_write(ip->rfd, commfd) < 0) {
216: close(commfd);
217: return ABORT(errno, "can't pass conection", ip);
218: }
219: _reply_write(ip->rfd, 0, source);
220: ABORT(0, "", ip);
221: ip->cfd = commfd;
222: } else if (ip->cfd >= 0) {
223:
224: /* use client supplied channel for communications */
225: _reply_write(ip->rfd, 0, "");
226: close(ip->rfd);
227: ip->rfd = -1;
228: } else {
229:
230: /* use reply channel for communications */
231: _reply_write(ip->rfd, 0, "");
232: ip->cfd = ip->rfd;
233: ip->rfd = -1;
234: }
235: return(ip->cfd);
236: }
237:
238: /* Reject a connection.
239: */
240: int
241: ipcreject(ip, no, str)
242: ipcinfo *ip;
243: int no; /* error number */
244: char *str; /* error string */
245: {
246: _reply_write(ip->rfd, no, str);
247: ABORT(no, str, ip);
248: return 0;
249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.