|
|
1.1 ! root 1: #include <sys/types.h> ! 2: #include <sys/ioctl.h> ! 3: #include <sys/stat.h> ! 4: #include <ipc.h> ! 5: #include "defs.h" ! 6: ! 7: /* exported */ ! 8: char *errstr; ! 9: ! 10: /* imports */ ! 11: extern int atoi(); ! 12: extern char *memchr(); ! 13: ! 14: /* dial a name and return an fd to the connection */ ! 15: int ! 16: ipcopen(name, param) ! 17: char *name; /* name being dialed */ ! 18: char *param; /* parameters for dialer */ ! 19: { ! 20: ipcinfo info; ! 21: ! 22: info.rfd = info.cfd = -1; ! 23: info.myname = info.user = info.machine = NULL; ! 24: info.uid = info.gid = -1; ! 25: info.name = name; ! 26: info.param = param; ! 27: info.flags = IPC_OPEN; ! 28: return ipcdial(&info); ! 29: } ! 30: ! 31: /* ! 32: * Open a mounted steam. ip->name points to a string of the form ! 33: * path!address. Path must be a file system path to a mounted stream. ! 34: */ ! 35: _ipcopen(ip) ! 36: ipcinfo *ip; ! 37: { ! 38: static stretch path; ! 39: char *np; ! 40: int fd; ! 41: struct stat sbuf; ! 42: ! 43: /* split into path and network address */ ! 44: _strcat(&path, ip->name, (char *)NULL, (char *)NULL); ! 45: np = strchr(path.ptr, '!'); ! 46: if (np) { ! 47: *np = '\0'; ! 48: ip->name += np - path.ptr + 1; ! 49: } ! 50: if (ip->flags&IPC_CAREFUL) { ! 51: if (stat(path.ptr, &sbuf)<0) ! 52: return ABORT(ENOENT, "destination nonexistent", NULLINFO); ! 53: if (sbuf.st_mode&6 != 6) ! 54: return ABORT(EACCES, "permission denied", NULLINFO); ! 55: } ! 56: if ((fd = open(path.ptr, 2))<0) { ! 57: if (errno==EACCES){ ! 58: if (*(ip->name)) ! 59: return ABORT(EACCES, "can't access dialer", NULLINFO); ! 60: else ! 61: return ABORT(EACCES, "permission denied", NULLINFO); ! 62: } else ! 63: return ABORT(ENOENT, "destination nonexistent", NULLINFO); ! 64: } ! 65: ! 66: /* update the translated part of the name */ ! 67: if(ip->myname) ! 68: _strcat(&path, ip->myname, "!", path.ptr); ! 69: ip->myname = path.ptr; ! 70: return fd; ! 71: } ! 72: ! 73: /* dial a name and return an fd to the connection */ ! 74: int ! 75: ipcdial(ip) ! 76: ipcinfo *ip; ! 77: { ! 78: struct passfd pass; ! 79: int fd; ! 80: ! 81: if ((fd = _ipcopen(ip))<0) ! 82: return -1; ! 83: ! 84: /* pass reply channel */ ! 85: if (ip->rfd >= 0) { ! 86: if (_fd_write(fd, ip->rfd)<0) { ! 87: close(fd); ! 88: return ABORT(EIO, "protocol botch", ip); ! 89: } ! 90: close(ip->rfd); ! 91: ip->rfd = -1; ! 92: } ! 93: ! 94: /* pass communications channel (if not same as reply channel) */ ! 95: if (ip->cfd >= 0) { ! 96: if (_fd_write(fd, ip->cfd)<0) { ! 97: close(fd); ! 98: return ABORT(EIO, "protocol botch", ip); ! 99: } ! 100: close(ip->cfd); ! 101: ip->cfd = -1; ! 102: } ! 103: ! 104: /* pass the info on */ ! 105: if (_info_write(fd, ip) < 0) { ! 106: close(fd); ! 107: return ABORT(errno, errstr, ip); ! 108: } ! 109: if (ip->flags&IPC_HANDOFF) ! 110: return fd; ! 111: ! 112: /* get the reply */ ! 113: if (_fd_read(fd, &pass)>=0) { ! 114: _reply_read(fd); ! 115: if (errno != 0) { ! 116: close(fd); ! 117: close(pass.fd); ! 118: return ABORT(errno, errstr, NULLINFO); ! 119: } ! 120: return pass.fd; ! 121: } else { ! 122: _reply_read(fd); ! 123: if (errno != 0) { ! 124: close(fd); ! 125: return ABORT(errno, errstr, NULLINFO); ! 126: } ! 127: return fd; ! 128: } ! 129: } ! 130: ! 131: /* ! 132: * Pass a request to someone else to handle. ! 133: */ ! 134: ipcpass(ip) ! 135: ipcinfo *ip; ! 136: { ! 137: ip->flags |= IPC_HANDOFF; ! 138: return ipcdial(ip); ! 139: } ! 140: ! 141: /* set error number and string and return -1 */ ! 142: int ! 143: _ipcabort(no, err, ip) ! 144: int no; ! 145: char *err; ! 146: ipcinfo *ip; ! 147: { ! 148: if (ip!=NULLINFO) { ! 149: if (ip->cfd>0) { ! 150: close(ip->cfd); ! 151: ip->cfd = -1; ! 152: } ! 153: if (ip->rfd>0) { ! 154: close(ip->rfd); ! 155: ip->rfd = -1; ! 156: } ! 157: } ! 158: errstr = err; ! 159: errno = no; ! 160: return -1; ! 161: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.