|
|
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.