|
|
1.1 ! root 1: * Remote dialer routine. ! 2: */ ! 3: #include <sys/types.h> ! 4: #include <stdio.h> ! 5: #include <libc.h> ! 6: #include <sys/utsname.h> ! 7: #include <errno.h> ! 8: #include <sys/filio.h> ! 9: #include <ipc.h> ! 10: #include "defs.h" ! 11: ! 12: /* export */ ! 13: char *av0; ! 14: char *param; ! 15: int debug; ! 16: ! 17: /* cheap foiegn imports */ ! 18: extern void dodialout(), dodialin(); ! 19: ! 20: usage(name) ! 21: char *name; ! 22: { ! 23: fprintf(stderr, "usage: %s [-m mount-pt] [-n netname] gate1 [gate2 ...]\n", name); ! 24: exit(1); ! 25: } ! 26: ! 27: /* ! 28: * Gate calls to/from a remote network. ! 29: */ ! 30: main(ac, av) ! 31: int ac; ! 32: char *av[]; ! 33: { ! 34: char *netname=NULL, *mtpt="rem", *cp; ! 35: int ai; ! 36: ! 37: av0 = av[0]; ! 38: chdir("/cs"); ! 39: ! 40: /* get args */ ! 41: for (ai=1; ai<ac; ai++) { ! 42: if (av[ai][0] == '-') ! 43: for (cp=&av[ai][1]; *cp; cp++) { ! 44: switch(*cp) { ! 45: case 'm': ! 46: if (ai+1>=ac) ! 47: usage(av[0]); ! 48: mtpt = av[++ai]; ! 49: break; ! 50: case 'n': ! 51: if (ai+1>=ac) ! 52: usage(av[0]); ! 53: netname = av[++ai]; ! 54: break; ! 55: case 'd': ! 56: debug = 1; ! 57: break; ! 58: default: ! 59: usage(av0); ! 60: } ! 61: } ! 62: else ! 63: break; ! 64: } ! 65: ! 66: /* get gateways */ ! 67: if(ai>=ac) ! 68: usage(av0); ! 69: ! 70: /* detach from process group, terminal, etc. */ ! 71: if (!debug) ! 72: detach(mtpt); ! 73: ! 74: /* get defaults */ ! 75: if (netname==NULL) { ! 76: struct utsname name; ! 77: ! 78: uname(&name); ! 79: netname = name.nodename; ! 80: } ! 81: ! 82: /* create dialer and listener */ ! 83: switch (fork()) { ! 84: case -1: ! 85: perror(av0); ! 86: exit(1); ! 87: case 0: ! 88: for(;;) ! 89: dodialout(mtpt); ! 90: default: ! 91: for(;;) ! 92: dodialin(mtpt, netname, "heavy"); ! 93: } ! 94: } ! 95: ! 96: static int ! 97: dingaling() ! 98: { ! 99: signal(SIGALRM, dingaling); ! 100: } ! 101: ! 102: /* ! 103: * Dial out to a gateway. Return -1 if no more gates are to be tried. ! 104: * Return 0 if more gates are to be tried. ! 105: */ ! 106: gateout(rp, ap) ! 107: Request *rp; ! 108: Action *ap; ! 109: { ! 110: int fd; ! 111: extern int rmesg_ld; ! 112: char netname[ARB]; ! 113: char *cp; ! 114: ! 115: if (rp->i->cfd>=0) { ! 116: ipcreject(rp->i, EINVAL, "gate-through disallowed"); ! 117: return -1; ! 118: } ! 119: ! 120: /* call `gateway' */ ! 121: fd = ipcopen(ap->arg, rp->i->param); ! 122: ! 123: /* send original request */ ! 124: if (fd<0 || _info_write(fd, rp->i)<0) { ! 125: /* if there are any more gateout's, keep trying */ ! 126: if (ap->next==NULL) ! 127: ipcreject(rp->i, errno, errstr); ! 128: close(fd); ! 129: return 0; ! 130: } ! 131: ! 132: /* see if the gateway could place the call */ ! 133: if (_reply_read(fd)<0 || errno!=0) { ! 134: /* call was rejected, don't try any more gateouts */ ! 135: ipcreject(rp->i, errno, errstr); ! 136: close(fd); ! 137: return -1; ! 138: } ! 139: ! 140: /* gateway and call were accepted */ ! 141: if(rp->i->flags == IPC_CREAT){ ! 142: /* for remote announcements, this process becomes a mux */ ! 143: lfd = ipcaccept(rp->i); ! 144: localmux(fd, lfd); ! 145: return -1; ! 146: } else { ! 147: /* for remote dials, just pass the net fd back to the process */ ! 148: ipcdaccept(rp->i, fd, ipcname); ! 149: return -1; ! 150: } ! 151: } ! 152: ! 153: /* ! 154: * Acccept a gateway call ! 155: */ ! 156: gateway(rp, ap) ! 157: Request *rp; ! 158: Action *ap; ! 159: { ! 160: int caller, callee; ! 161: ipcinfo info; ! 162: fd_set fds; ! 163: char newname[ARB]; ! 164: extern int mesg_ld; ! 165: char *mapuser(); ! 166: int (*oldsig)(); ! 167: ! 168: /* see if we gateway for this requestor */ ! 169: if (mapuser(rp->s->name, rp->i->machine, rp->i->user)==NULL) { ! 170: ipcreject(rp->i, EACCES, "gateway disallowed"); ! 171: return -1; ! 172: } ! 173: if ((caller=ipcaccept(rp->i))<0) ! 174: return -1; ! 175: ! 176: /* get the original request */ ! 177: info.uid = info.gid = 0; ! 178: info.user=""; ! 179: if (_info_read(caller, &info)<0) ! 180: return -1; ! 181: ! 182: /* make the call */ ! 183: if(rp->i->flags == IPC_CREAT){ ! 184: /* for remote announcements, this process becomes a mux */ ! 185: lfd = ipcaccept(rp->i); ! 186: localmux(fd, lfd); ! 187: return -1; ! 188: } else { ! 189: /* for remote dials, just shuttle bytes back and forth */ ! 190: ipcdaccept(rp->i, fd, "who_cares"); ! 191: return -1; ! 192: } ! 193: ! 194: /* dial the number */ ! 195: sprintf(newname, "%s!%s", ap->arg, info.name); ! 196: info.name = newname; ! 197: info.rfd = info.cfd = -1; ! 198: info.flags = IPC_OPEN; ! 199: oldsig=signal(SIGALRM, dingaling); ! 200: alarm(30); ! 201: callee = ipcdial(&info); ! 202: alarm(0); ! 203: signal(SIGALRM, oldsig); ! 204: if (callee<0) { ! 205: _reply_write(caller, errno, errstr); ! 206: close(caller); ! 207: return -1; ! 208: } ! 209: ! 210: /* tell gateout that it worked */ ! 211: if (_reply_write(caller, 0, "")<0) { ! 212: close(caller); ! 213: close(callee); ! 214: return -1; ! 215: } ! 216: ! 217: /* shuttle bytes back and forth */ ! 218: FD_ZERO(fds); ! 219: for(;;) { ! 220: FD_SET(caller, fds); ! 221: FD_SET(callee, fds); ! 222: switch(select(NOFILE, &fds, (struct fd_set *)0, 1000)) { ! 223: case -1: ! 224: return -1; ! 225: case 0: ! 226: continue; ! 227: } ! 228: if (FD_ISSET(caller, fds)) ! 229: if (pass(caller, callee)<0) ! 230: return -1; ! 231: if (FD_ISSET(callee, fds)) ! 232: if (pass(callee, caller)<0) ! 233: return -1; ! 234: } ! 235: } ! 236: ! 237: pass(from, to) ! 238: int from, to; ! 239: { ! 240: char buf[4096]; ! 241: int n; ! 242: ! 243: if ((n=read(from, buf, sizeof(buf)))<=0) ! 244: return -1; ! 245: if (write(to, buf, n)!=n) ! 246: return -1; ! 247: return 0; ! 248: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.