|
|
1.1 ! root 1: #include "mgr.h" ! 2: #include "defs.h" ! 3: #include <errno.h> ! 4: #include <sys/param.h> ! 5: #include <sys/filio.h> ! 6: #include <signal.h> ! 7: ! 8: static int ! 9: dingaling() ! 10: { ! 11: signal(SIGALRM, dingaling); ! 12: } ! 13: ! 14: /* ! 15: * Dial out to a gateway. Return -1 if no more gates are to be tried. ! 16: * Return 0 if more gates are to be tried. ! 17: */ ! 18: gateout(rp, ap) ! 19: Request *rp; ! 20: Action *ap; ! 21: { ! 22: int fd; ! 23: char *cp; ! 24: static stretch newipcname; ! 25: extern int rmesg_ld; ! 26: ! 27: if (rp->i->cfd>=0) { ! 28: ipcreject(rp->i, EINVAL, "gate-through disallowed"); ! 29: return -1; ! 30: } ! 31: ! 32: /* call `gateway' */ ! 33: fd = ipcopen(ap->arg, rp->i->param); ! 34: ! 35: /* send original request */ ! 36: if (fd<0 || _info_write(fd, rp->i)<0) { ! 37: /* if there are any more gateout's, keep trying */ ! 38: if (ap->next==NULL) ! 39: ipcreject(rp->i, errno, errstr); ! 40: close(fd); ! 41: return 0; ! 42: } ! 43: ! 44: /* see if the gateway could place the call */ ! 45: if (_reply_read(fd)<0 || errno!=0) { ! 46: /* call was rejected, don't try any more gateouts */ ! 47: ipcreject(rp->i, errno, errstr); ! 48: close(fd); ! 49: return -1; ! 50: } ! 51: ! 52: /* see if we can push the rmesg ld */ ! 53: /* ! 54: if (ioctl(fd, FIOPUSHLD, &rmesg_ld)<0) { ! 55: ipcreject(rp->i, errno, "can't push rmesg_ld"); ! 56: close(fd); ! 57: return -1; ! 58: } ! 59: */ ! 60: ! 61: /* gateway and call were accepted -- pass back a corrected ipcname */ ! 62: cp = strchr(ipcname, '!'); ! 63: _strcat(&newipcname, rp->i->myname, "!", cp); ! 64: ipcdaccept(rp->i, fd, newipcname.ptr); ! 65: return -1; ! 66: } ! 67: ! 68: /* ! 69: * Acccept a gateway call ! 70: */ ! 71: gateway(rp, ap) ! 72: Request *rp; ! 73: Action *ap; ! 74: { ! 75: int caller, callee; ! 76: ipcinfo info; ! 77: ipcinfo *ip; ! 78: fd_set fds; ! 79: char newname[ARB]; ! 80: extern int mesg_ld; ! 81: char *mapuser(); ! 82: int (*oldsig)(); ! 83: ! 84: /* see if we gateway for this requestor */ ! 85: if (mapuser(rp->s->name, rp->i->machine, rp->i->user)==NULL) { ! 86: ipcreject(rp->i, EACCES, "gateway disallowed"); ! 87: return -1; ! 88: } ! 89: if ((caller=ipcaccept(rp->i))<0) ! 90: return -1; ! 91: ! 92: /* the next info_read would destroy these fields */ ! 93: rp->i->machine = strdup(rp->i->machine); ! 94: rp->i->user = strdup(rp->i->user); ! 95: ! 96: /* get the original request */ ! 97: info.uid = info.gid = 0; ! 98: info.user=""; ! 99: if (_info_read(caller, &info)<0) ! 100: return -1; ! 101: ! 102: /* dial the number */ ! 103: sprintf(newname, "%s!%s", ap->arg, info.name); ! 104: info.name = newname; ! 105: info.rfd = info.cfd = -1; ! 106: oldsig=signal(SIGALRM, dingaling); ! 107: alarm(30); ! 108: callee = ipcdial(&info); ! 109: alarm(0); ! 110: signal(SIGALRM, oldsig); ! 111: ! 112: /* log it */ ! 113: rp->i->name = info.name; ! 114: rp->i->myname = info.myname; ! 115: logstatus("gate", rp->i); ! 116: if (callee<0) { ! 117: _reply_write(caller, errno, errstr); ! 118: close(caller); ! 119: return -1; ! 120: } ! 121: ! 122: /* try to push mesg ld */ ! 123: /* ! 124: if(ioctl(callee, FIOPUSHLD, &mesg_ld)<0){ ! 125: _reply_write(caller, errno, "can't push mesg ld"); ! 126: close(caller); ! 127: close(callee); ! 128: return -1; ! 129: } ! 130: */ ! 131: ! 132: /* tell gateout that it worked */ ! 133: if (_reply_write(caller, 0, ipcname)<0) { ! 134: close(caller); ! 135: close(callee); ! 136: return -1; ! 137: } ! 138: ! 139: /* ! 140: * For creat's, we accept only one call per creat. This ! 141: * makes life a lot simpler since we can use the current ! 142: * connection to the other end. ! 143: */ ! 144: if(info.flags & IPC_CREAT) { ! 145: int nfd; ! 146: struct fd_set fds; ! 147: ! 148: /* wait for call or hangup */ ! 149: FD_ZERO(fds); ! 150: FD_SET(callee, fds); ! 151: FD_SET(caller, fds); ! 152: switch(select(NOFILE, &fds, (struct fd_set *)0, 10000000)){ ! 153: case 0: ! 154: case -1: ! 155: exit(0); ! 156: } ! 157: if(FD_ISSET(caller, fds)) ! 158: exit(0); ! 159: ! 160: /* get call info */ ! 161: if((ip = ipclisten(callee)) == NULL) ! 162: exit(0); ! 163: ! 164: /* pass it creator */ ! 165: if(_info_write(caller, ip) < 0) ! 166: exit(0); ! 167: if(_reply_read(caller) < 0) ! 168: exit(0); ! 169: if(errno) { ! 170: ipcreject(ip, errno, errstr); ! 171: exit(0); ! 172: } else { ! 173: nfd = ipcdaccept(ip, -1, ipcname); ! 174: close(callee); ! 175: callee = nfd; ! 176: } ! 177: } ! 178: ! 179: /* shuttle bytes back and forth */ ! 180: FD_ZERO(fds); ! 181: for(;;) { ! 182: FD_SET(caller, fds); ! 183: FD_SET(callee, fds); ! 184: switch(select(NOFILE, &fds, (struct fd_set *)0, 1000)) { ! 185: case -1: ! 186: return -1; ! 187: case 0: ! 188: continue; ! 189: } ! 190: if (FD_ISSET(caller, fds)) ! 191: if (pass(caller, callee)<0) ! 192: exit(0); ! 193: if (FD_ISSET(callee, fds)) ! 194: if (pass(callee, caller)<0) ! 195: exit(0); ! 196: } ! 197: } ! 198: ! 199: pass(from, to) ! 200: int from, to; ! 201: { ! 202: char buf[4096]; ! 203: int n; ! 204: ! 205: if ((n=read(from, buf, sizeof(buf)))<=0) ! 206: return -1; ! 207: if (write(to, buf, n)!=n) ! 208: return -1; ! 209: return 0; ! 210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.