|
|
1.1 ! root 1: #include <sys/types.h> ! 2: #include <sys/filio.h> ! 3: #include <ipc.h> ! 4: #include "defs.h" ! 5: ! 6: /* imports */ ! 7: extern int conn_ld; ! 8: extern struct passwd *pwsearch(); ! 9: extern char *strncpy(); ! 10: ! 11: /* global to this file */ ! 12: #define ROOTUID 0 ! 13: ! 14: /* ! 15: * Attach to a name space. If the path is a single element, ! 16: * just mount into the file system. Otherwise, pass the request ! 17: * to a network dialer. ! 18: */ ! 19: int ! 20: ipccreat(name, param) ! 21: char *name; /* name being dialed */ ! 22: char *param; /* parameters for creation */ ! 23: { ! 24: int pfd[2]; ! 25: char *path=name; ! 26: ipcinfo info; ! 27: int nfd; ! 28: ! 29: if (path==NULL) ! 30: return ABORT(EINVAL, "name too long", (ipcinfo*)NULL); ! 31: ! 32: /* ! 33: * if a path is specified, pass the request through a dialer ! 34: */ ! 35: if (strchr(path, '!')!=NULL) { ! 36: info.rfd = info.cfd = -1; ! 37: info.myname = info.user = info.machine = NULL; ! 38: info.uid = info.gid = -1; ! 39: info.name = name; ! 40: info.param = param; ! 41: info.flags = IPC_CREAT; ! 42: return ipcdial(&info); ! 43: } ! 44: ! 45: /* ! 46: * Try creating a file to mount on ! 47: */ ! 48: if(access(path, 0) < 0){ ! 49: nfd = creat(path, 0666); ! 50: if(nfd < 0) ! 51: return ABORT(errno, "can't mount", (ipcinfo*)NULL); ! 52: close(nfd); ! 53: } ! 54: ! 55: /* ! 56: * make a pipe to mount into the file system and push the ! 57: * connection line discipline. Conn_ld ensures that all ! 58: * opens of the pipe will spawn a unique connection. ! 59: */ ! 60: if (pipe(pfd) < 0) ! 61: return ABORT(errno, "out of pipes", (ipcinfo*)NULL); ! 62: if (ioctl(pfd[1], FIOPUSHLD, &conn_ld) < 0) { ! 63: close(pfd[0]); ! 64: close(pfd[1]); ! 65: return ABORT(errno, "pushing line discipline", (ipcinfo*)NULL); ! 66: } ! 67: ! 68: /* mount */ ! 69: if (fmount(3, pfd[1], path, 0) < 0) { ! 70: close(pfd[0]); ! 71: close(pfd[1]); ! 72: return ABORT(errno, "can't mount", (ipcinfo*)NULL); ! 73: } ! 74: close(pfd[1]); ! 75: return pfd[0]; ! 76: } ! 77: ! 78: /* ! 79: * listen for a connection ! 80: */ ! 81: ipcinfo * ! 82: ipclisten(fd) ! 83: int fd; ! 84: { ! 85: struct passfd pass; ! 86: int pfd[2]; ! 87: static ipcinfo info; ! 88: static char user[32]; ! 89: int fd1=-1, fd2=-1; ! 90: ! 91: /* ! 92: * Get a unique stream to a caller, or reuse this one if none is passed. ! 93: * The reuse is typical of the arpa! gateway. ! 94: */ ! 95: if(_fd_read(fd, &pass) < 0) { ! 96: if(errno==EINTR) ! 97: return NULL; ! 98: info.uid = -1; ! 99: info.gid = -1; ! 100: info.rfd = dup(fd); ! 101: close(fd); ! 102: } else { ! 103: info.uid = pass.uid; ! 104: info.gid = pass.gid; ! 105: info.rfd = pass.fd; ! 106: } ! 107: strncpy(user, pass.logname, sizeof(pass.logname)); ! 108: user[sizeof(pass.logname)] = '\0'; ! 109: info.user = user; ! 110: (void)ioctl(info.rfd, FIOACCEPT, &pass); ! 111: ! 112: /* ! 113: * Get possible passed fds. Up to two can be passed, i.e. ! 114: * the fd to reply to and the one to use for communication. ! 115: */ ! 116: if (_fd_read(info.rfd, &pass)>=0) { ! 117: fd1 = pass.fd; ! 118: if (_fd_read(info.rfd, &pass)>=0) { ! 119: fd2 = pass.fd; ! 120: } else if(errno==EINTR){ ! 121: close(info.rfd); ! 122: close(fd1); ! 123: return NULL; ! 124: } ! 125: } else if(errno==EINTR){ ! 126: close(info.rfd); ! 127: return NULL; ! 128: } ! 129: ! 130: /* ! 131: * get the request ! 132: */ ! 133: if (_info_read(info.rfd, &info)<0) { ! 134: /* requestor gave up */ ! 135: close(info.rfd); ! 136: if(fd1>=0) ! 137: close(fd1); ! 138: if(fd2>=0) ! 139: close(fd2); ! 140: return NULL; ! 141: } ! 142: ! 143: if (info.flags & IPC_HANDOFF) { ! 144: /* ! 145: * This is a call passed to us ! 146: * by someone else. ! 147: */ ! 148: close(info.rfd); ! 149: info.rfd = fd1; ! 150: info.cfd = fd2; ! 151: info.flags &= ~IPC_HANDOFF; ! 152: } else { ! 153: /* ! 154: * By default the fd on which the ! 155: * request was received will be used ! 156: * both for replies and communication ! 157: */ ! 158: info.cfd = fd1; ! 159: if (fd2>=0) ! 160: close(fd2); ! 161: } ! 162: return &info; ! 163: } ! 164: ! 165: /* ! 166: * Accept a connection. ! 167: * Close all fd's except ip->cfd. ! 168: */ ! 169: int ! 170: ipcaccept(ip) ! 171: ipcinfo *ip; ! 172: { ! 173: return ipcdaccept(ip, -1, "who_cares"); ! 174: } ! 175: ! 176: /* ! 177: * Accept a connection, and supply a source address and communications fd ! 178: */ ! 179: int ! 180: ipcdaccept(ip, commfd, source) ! 181: ipcinfo *ip; ! 182: int commfd; ! 183: char *source; ! 184: { ! 185: if (commfd >= 0) { ! 186: /* ! 187: * supply our own channel for communications ! 188: */ ! 189: if (_fd_write(ip->rfd, commfd) < 0) { ! 190: close(commfd); ! 191: return ABORT(errno, "can't pass conection", ip); ! 192: } ! 193: _reply_write(ip->rfd, 0, source); ! 194: ABORT(0, "", ip); ! 195: ip->cfd = commfd; ! 196: } else if (ip->cfd >= 0) { ! 197: /* ! 198: * use client supplied channel for communications ! 199: */ ! 200: _reply_write(ip->rfd, 0, ""); ! 201: close(ip->rfd); ! 202: ip->rfd = -1; ! 203: } else { ! 204: /* ! 205: * use reply channel for communications ! 206: */ ! 207: _reply_write(ip->rfd, 0, ""); ! 208: ip->cfd = ip->rfd; ! 209: ip->rfd = -1; ! 210: } ! 211: return(ip->cfd); ! 212: } ! 213: ! 214: /* ! 215: * Reject a connection. ! 216: */ ! 217: int ! 218: ipcreject(ip, no, str) ! 219: ipcinfo *ip; ! 220: int no; /* error number */ ! 221: char *str; /* error string */ ! 222: { ! 223: _reply_write(ip->rfd, no, str); ! 224: ABORT(no, str, ip); ! 225: return 0; ! 226: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.