|
|
1.1 ! root 1: #include <sys/types.h> ! 2: #include <stdio.h> ! 3: #include <sys/ioctl.h> ! 4: #include <ipc.h> ! 5: #include <libc.h> ! 6: #include <wait.h> ! 7: #include "defs.h" ! 8: ! 9: /* preeclared */ ! 10: void dodialout(); ! 11: void dodialin(); ! 12: void doopen(); ! 13: void docreat(); ! 14: ! 15: /* global */ ! 16: int pid; ! 17: ! 18: /* imported */ ! 19: extern char *av0; ! 20: extern int net_dial(); ! 21: extern int net_announce(); ! 22: extern void net_accept(); ! 23: extern void net_reject(); ! 24: extern ipcinfo *net_listen(); ! 25: extern char *getlogin(); ! 26: ! 27: static ! 28: deadbaby() ! 29: { ! 30: while(wait3(NULL, WNOHANG, NULL)>0) ! 31: ; ! 32: signal(SIGCHLD, deadbaby); ! 33: } ! 34: ! 35: /* loop on calls out of the CPU */ ! 36: void ! 37: dodialout(mtpt) ! 38: char *mtpt; ! 39: { ! 40: int fd; ! 41: int st; ! 42: ! 43: pid = getpid(); ! 44: ! 45: /* plug into local name space */ ! 46: for(st=1;;st=st>60?st:(st<<1)){ ! 47: fd = ipccreat(mtpt, ""); ! 48: if (fd>=0) ! 49: break; ! 50: logconsole("%s: can't announce as %s (%s)\n", av0, mtpt, errstr); ! 51: sleep(st); ! 52: } ! 53: chmod(mtpt, 0666); ! 54: logconsole("%s: announced to fs as %s\n", av0, mtpt); ! 55: fflush(stdout); ! 56: ! 57: /* loop on requests */ ! 58: for(;;) { ! 59: ipcinfo *ip; ! 60: ! 61: ip = ipclisten(fd); ! 62: if (ip == NULL) { ! 63: fprintf(stderr,"out broken listen\n"); ! 64: break; ! 65: } ! 66: ! 67: /* run request as separate process */ ! 68: signal(SIGCHLD, deadbaby); ! 69: switch(fork()) { ! 70: case -1: /* whoops */ ! 71: ipcreject(ip, errno, "no more processes"); ! 72: logstatus(ip); ! 73: continue; ! 74: case 0: ! 75: close(fd); ! 76: break; ! 77: default: ! 78: (void)ABORT(0, "", ip); ! 79: continue; ! 80: } ! 81: ! 82: logcall("callout", ip); ! 83: if (ip->flags & IPC_CREAT) ! 84: docreat(ip); ! 85: else ! 86: doopen(ip, mtpt); ! 87: exit(0); ! 88: } ! 89: close(fd); ! 90: } ! 91: ! 92: /* establish a connection to a net name */ ! 93: void ! 94: doopen(ip, mtpt) ! 95: ipcinfo *ip; ! 96: char *mtpt; ! 97: { ! 98: int fd; ! 99: static stretch myname; ! 100: ! 101: *av0 = 'D'; ! 102: ! 103: fd = net_dial(ip); ! 104: if (fd < 0) { ! 105: ipcreject(ip, errno, errstr); ! 106: logstatus(ip); ! 107: return; ! 108: } ! 109: errno = 0; errstr = ""; ! 110: _strcat(&myname, mtpt, "!", ip->myname); ! 111: ipcdaccept(ip, fd, myname.ptr); ! 112: close(fd); ! 113: logstatus(ip); ! 114: } ! 115: ! 116: /* announce a new netname */ ! 117: void ! 118: docreat(ip) ! 119: ipcinfo *ip; ! 120: { ! 121: ipcinfo *netip; ! 122: int listenfd; ! 123: int toclient; ! 124: int pfd[2]; ! 125: fd_set fds; ! 126: ! 127: if (ip->cfd >= 0) { ! 128: ipcreject(ip, EIO, "can't do remote ipccreat"); ! 129: logstatus(ip); ! 130: return; ! 131: } ! 132: ! 133: *av0 = 'L'; ! 134: ! 135: /* for communications with requestor */ ! 136: if (pipe(pfd) < 0) { ! 137: ipcreject(ip, errno, "can't create local channel"); ! 138: logstatus(ip); ! 139: return; ! 140: } ! 141: toclient = pfd[1]; ! 142: ! 143: /* dial out on device */ ! 144: listenfd = net_announce(ip); ! 145: if (listenfd < 0) { ! 146: close(pfd[0]); ! 147: close(pfd[1]); ! 148: ipcreject(ip, errno, errstr); ! 149: logstatus(ip); ! 150: return; ! 151: } ! 152: ! 153: /* accept the announce request */ ! 154: if (ipcdaccept(ip, pfd[0], "who_knows") < 0) ! 155: return; ! 156: close(pfd[0]); ! 157: errno = 0; errstr = ""; ! 158: logstatus(ip); ! 159: ! 160: /* loop waiting for in calls */ ! 161: FD_ZERO(fds); ! 162: FD_SET(listenfd, fds); ! 163: FD_SET(toclient, fds); ! 164: while(1) { ! 165: fd_set rfds; ! 166: int rv; ! 167: ! 168: /* check for input or hang-up */ ! 169: rfds = fds; ! 170: rv = select(NOFILE, &rfds, (fd_set*)0, 10000); ! 171: if (rv == 0) ! 172: continue; ! 173: else if (rv < 0) ! 174: break; ! 175: else if (FD_ISSET(toclient, rfds)) ! 176: break; ! 177: ! 178: /* get request */ ! 179: netip = net_listen(listenfd); ! 180: if (netip == NULL) { ! 181: ABORT(errno, errstr, ip); ! 182: break; ! 183: } ! 184: logcall(ip->name, netip); ! 185: ! 186: /* make a new channel to the listener */ ! 187: if (pipe(pfd)<0) { ! 188: net_reject(netip, errno, "no more pipes"); ! 189: logstatus(ip); ! 190: continue; ! 191: } ! 192: if (ioctl(toclient, FIOSNDFD, &(pfd[0]))<0) { ! 193: net_reject(netip, errno, "protocol botch"); ! 194: logstatus(ip); ! 195: break; ! 196: } ! 197: close(pfd[0]); ! 198: ! 199: /* pass the request over the new channel */ ! 200: if (ioctl(pfd[1], FIOSNDFD, &(netip->rfd))<0) { ! 201: net_reject(netip, errno, "protocol botch"); ! 202: close(pfd[1]); ! 203: logstatus(ip); ! 204: continue; ! 205: } ! 206: close(netip->rfd); ! 207: netip->rfd = -1; ! 208: if (_info_write(pfd[1], netip) < 0) { ! 209: net_reject(netip, errno, "protocol botch"); ! 210: close(pfd[1]); ! 211: logstatus(ip); ! 212: continue; ! 213: } ! 214: if (_reply_read(pfd[1]) < 0) ! 215: net_reject(netip, errno, "protocol botch"); ! 216: else ! 217: net_accept(netip); ! 218: logstatus(ip); ! 219: close(pfd[1]); ! 220: } ! 221: return; ! 222: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.