|
|
1.1 root 1: #include <sys/types.h>
2: #include <sys/ioctl.h>
3: #include <stdio.h>
4: #include <ipc.h>
5: #include "defs.h"
6:
7: /* imports */
8: extern int conn_ld;
9: extern struct passwd *pwsearch();
10: extern char *strncpy();
11:
12: /* global to this file */
13: #define ROOTUID 0
14:
15: /* plug into the name space */
16: int
17: ipccreat(name, param)
18: char *name; /* name being dialed */
19: char *param; /* parameters for creation */
20: {
21: int pfd[2];
22: char *path=name;
23: ipcinfo info;
24:
25: if (path==NULL)
26: return ABORT(EINVAL, "name too long", (ipcinfo*)NULL);
27:
28: /* make a node to mount onto */
29: if (strchr(path, '!')!=NULL || (access(path,0)<0 && creat(path, 0666)<0)) {
30: /* remote creat */
31: info.rfd = info.cfd = -1;
32: info.myname = info.user = info.machine = NULL;
33: info.uid = info.gid = -1;
34: info.name = name;
35: info.param = param;
36: info.flags = IPC_CREAT;
37: return ipcdial(&info);
38: }
39:
40: /* get the stream to mount */
41: if (pipe(pfd) < 0)
42: return ABORT(errno, "out of pipes", (ipcinfo*)NULL);
43: if (ioctl(pfd[1], FIOPUSHLD, &conn_ld) < 0) {
44: close(pfd[0]);
45: close(pfd[1]);
46: return ABORT(errno, "pushing line discipline", (ipcinfo*)NULL);
47: }
48:
49: /* mount */
50: if (fmount(3, pfd[1], path, 0) < 0) {
51: close(pfd[0]);
52: close(pfd[1]);
53: return ABORT(errno, "can't mount", (ipcinfo*)NULL);
54: }
55: close(pfd[1]);
56: return pfd[0];
57: }
58:
59: /* listen for a connection */
60: ipcinfo *
61: ipclisten(fd)
62: int fd;
63: {
64: struct passfd pass;
65: int pfd[2];
66: static ipcinfo info;
67: static char buf[BUFSIZE];
68: static char user[32];
69: int fd1= -1, fd2= -1;
70:
71: /* get a unique stream to the caller */
72: restart:
73: if (_fd_read(fd, &pass)<0) {
74: close(fd);
75: return NULL; /* nothing there */
76: }
77: info.uid = pass.uid;
78: info.gid = pass.gid;
79: info.rfd = pass.fd;
80: strncpy(user, pass.logname, sizeof(pass.logname));
81: user[sizeof(pass.logname)] = '\0';
82: info.user = user;
83: (void)ioctl(info.rfd, FIOACCEPT, &pass);
84:
85: /* get possible passed fds */
86: if (_fd_read(info.rfd, &pass)>=0) {
87: fd1 = pass.fd;
88: if (_fd_read(info.rfd, &pass)>=0)
89: fd2 = pass.fd;
90: }
91:
92: /* get the request */
93: if (_info_read(info.rfd, &info)<0) {
94: /* requestor gave up */
95: close(info.rfd);
96: if(fd1>=0)
97: close(fd1);
98: if(fd2>=0)
99: close(fd2);
100: goto restart;
101: }
102:
103: /* decode the request */
104: if (info.flags & IPC_HANDOFF) {
105: close(info.rfd);
106: info.rfd = fd1;
107: info.cfd = fd2;
108: info.flags &= ~IPC_HANDOFF;
109: } else {
110: info.cfd = fd1;
111: if (fd2>=0)
112: close(fd2);
113: }
114: return &info;
115: }
116:
117: /*
118: * Accept a connection. Close all except ip->cfd.
119: */
120: int
121: ipcaccept(ip)
122: ipcinfo *ip;
123: {
124: ipcdaccept(ip, -1, "who_cares");
125: }
126: /*
127: * Accept a connection, and supply a source address and communications fd
128: */
129: int
130: ipcdaccept(ip, commfd, source)
131: ipcinfo *ip;
132: int commfd;
133: char *source;
134: {
135: if (commfd >= 0) {
136:
137: /* supply our own channel for communications */
138: if (_fd_write(ip->rfd, commfd) < 0) {
139: close(commfd);
140: return ABORT(errno, "can't pass conection", ip);
141: }
142: _reply_write(ip->rfd, 0, source);
143: ABORT(0, "", ip);
144: ip->cfd = commfd;
145: } else if (ip->cfd >= 0) {
146:
147: /* use client supplied channel for communications */
148: _reply_write(ip->rfd, 0, "");
149: close(ip->rfd);
150: ip->rfd = -1;
151: } else {
152:
153: /* use reply channel for communications */
154: _reply_write(ip->rfd, 0, "");
155: ip->cfd = ip->rfd;
156: ip->rfd = -1;
157: }
158: return(ip->cfd);
159: }
160:
161: /* Reject a connection.
162: */
163: int
164: ipcreject(ip, no, str)
165: ipcinfo *ip;
166: int no; /* error number */
167: char *str; /* error string */
168: {
169: _reply_write(ip->rfd, no, str);
170: ABORT(no, str, ip);
171: return 0;
172: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.