|
|
1.1 ! root 1: #include "ipc.h" ! 2: #include "mgr.h" ! 3: #include <errno.h> ! 4: #include <sys/types.h> ! 5: #include <sys/filio.h> ! 6: ! 7: /* buffer definition */ ! 8: #define BUFLEN 512 ! 9: ! 10: /* our name */ ! 11: char *ipcname; ! 12: ! 13: /* ! 14: * timeout routine ! 15: */ ! 16: static int ! 17: dingaling() ! 18: { ! 19: signal(SIGALRM, dingaling); ! 20: } ! 21: ! 22: /* ! 23: * gate a call to the arpanet ! 24: */ ! 25: main() ! 26: { ! 27: int caller, callee; ! 28: ipcinfo info; ! 29: ipcinfo *ip; ! 30: fd_set fds; ! 31: char newname[BUFLEN]; ! 32: int (*oldsig)(); ! 33: ! 34: /* ! 35: * get the original request ! 36: */ ! 37: info.uid = info.gid = 0; ! 38: info.user="root"; ! 39: if (_info_read(caller, &info)<0) ! 40: return -1; ! 41: ! 42: /* ! 43: * dial the number ! 44: */ ! 45: sprintf(newname, "%s!%s", "/cs/tcp", info.name); ! 46: info.name = newname; ! 47: info.rfd = info.cfd = -1; ! 48: oldsig=signal(SIGALRM, dingaling); ! 49: alarm(30); ! 50: callee = ipcdial(&info); ! 51: alarm(0); ! 52: signal(SIGALRM, oldsig); ! 53: ! 54: /* ! 55: * return status ! 56: */ ! 57: if (callee<0) { ! 58: _reply_write(caller, errno, errstr); ! 59: close(caller); ! 60: return -1; ! 61: } ! 62: if (_reply_write(caller, 0, ipcname)<0) { ! 63: close(caller); ! 64: close(callee); ! 65: return -1; ! 66: } ! 67: ! 68: /* ! 69: * For creat's, we accept only one call per creat. This ! 70: * makes life a lot simpler though less general. ! 71: */ ! 72: if(info.flags & IPC_CREAT) { ! 73: int nfd; ! 74: ! 75: if((ip = ipclisten(callee)) == NULL) ! 76: exit(0); ! 77: if(_info_write(caller, ip) < 0) ! 78: exit(0); ! 79: if(_reply_read(caller) < 0) ! 80: exit(0); ! 81: if(errno) { ! 82: ipcreject(ip, errno, errstr); ! 83: exit(0); ! 84: } else { ! 85: nfd = ipcdaccept(ip, -1, ipcname); ! 86: close(callee); ! 87: callee = nfd; ! 88: } ! 89: } ! 90: ! 91: /* ! 92: * shuttle bytes back and forth ! 93: */ ! 94: FD_ZERO(fds); ! 95: for(;;) { ! 96: FD_SET(caller, fds); ! 97: FD_SET(callee, fds); ! 98: switch(select(NOFILE, &fds, (struct fd_set *)0, 1000)) { ! 99: case -1: ! 100: return -1; ! 101: case 0: ! 102: continue; ! 103: } ! 104: if (FD_ISSET(caller, fds)) ! 105: if (pass(caller, callee)<0) ! 106: exit(0); ! 107: if (FD_ISSET(callee, fds)) ! 108: if (pass(callee, caller)<0) ! 109: exit(0); ! 110: } ! 111: } ! 112: ! 113: pass(from, to) ! 114: int from, to; ! 115: { ! 116: char buf[4096]; ! 117: int n; ! 118: ! 119: if ((n=read(from, buf, sizeof(buf)))<=0) ! 120: return -1; ! 121: if (write(to, buf, n)!=n) ! 122: return -1; ! 123: return 0; ! 124: } ! 125: ! 126: /* ! 127: * Send the connection info. ! 128: */ ! 129: int ! 130: _info_write(fd, ip) ! 131: int fd; ! 132: ipcinfo *ip; ! 133: { ! 134: char b[BUFLEN]; ! 135: int n; ! 136: ! 137: if (ip->name==NULL) ! 138: ip->name = ""; ! 139: if (ip->param==NULL) ! 140: ip->param = ""; ! 141: if (ip->machine==NULL) ! 142: ip->machine = ""; ! 143: if (ip->user==NULL) ! 144: ip->user = ""; ! 145: if (ip->myname==NULL) ! 146: ip->myname = ""; ! 147: sprintf(b, "%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n", ip->myname, ip->name, ! 148: ip->param, ip->machine, ip->user, ip->flags, ip->uid, ip->gid); ! 149: n = strlen(b); ! 150: if (write(fd, b, n)!=n) ! 151: return ABORT(errno, "can't send request", NULLINFO); ! 152: return 0; ! 153: } ! 154: ! 155: ! 156: /* dial a number or plug into the name space */ ! 157: ipcdial(ip) ! 158: ipcinfo *ip; ! 159: { ! 160: /* ! 161: * decode the call ! 162: */ ! 163: if( ! 164: if (ip->flags && IPC_CREAT){ ! 165: /* plug into the name space */ ! 166: } else { ! 167: } ! 168: } ! 169: ! 170: /* listen for a connection */ ! 171: ipcinfo * ! 172: ipclisten(fd) ! 173: int fd; ! 174: { ! 175: static ipcinfo info; ! 176: static char buf[BUFSIZE]; ! 177: static char user[32]; ! 178: ! 179: /* accept only one connection */ ! 180: info.rfd = fd; ! 181: close(fd); ! 182: ! 183: /* get the request */ ! 184: if (_info_read(info.rfd, &info)<0) { ! 185: /* requestor gave up */ ! 186: close(info.rfd); ! 187: return NULL; ! 188: } ! 189: ! 190: return &info; ! 191: } ! 192: ! 193: /* ! 194: * Accept a connection. Close all except ip->cfd. ! 195: */ ! 196: int ! 197: ipcaccept(ip) ! 198: ipcinfo *ip; ! 199: { ! 200: ipcdaccept(ip, -1, "who_cares"); ! 201: } ! 202: ! 203: /* ! 204: * Accept a connection, and supply a source address and communications fd ! 205: */ ! 206: int ! 207: ipcdaccept(ip, commfd, source) ! 208: ipcinfo *ip; ! 209: int commfd; ! 210: char *source; ! 211: { ! 212: if (commfd >= 0) { ! 213: ! 214: /* supply our own channel for communications */ ! 215: if (_fd_write(ip->rfd, commfd) < 0) { ! 216: close(commfd); ! 217: return ABORT(errno, "can't pass conection", ip); ! 218: } ! 219: _reply_write(ip->rfd, 0, source); ! 220: ABORT(0, "", ip); ! 221: ip->cfd = commfd; ! 222: } else if (ip->cfd >= 0) { ! 223: ! 224: /* use client supplied channel for communications */ ! 225: _reply_write(ip->rfd, 0, ""); ! 226: close(ip->rfd); ! 227: ip->rfd = -1; ! 228: } else { ! 229: ! 230: /* use reply channel for communications */ ! 231: _reply_write(ip->rfd, 0, ""); ! 232: ip->cfd = ip->rfd; ! 233: ip->rfd = -1; ! 234: } ! 235: return(ip->cfd); ! 236: } ! 237: ! 238: /* Reject a connection. ! 239: */ ! 240: int ! 241: ipcreject(ip, no, str) ! 242: ipcinfo *ip; ! 243: int no; /* error number */ ! 244: char *str; /* error string */ ! 245: { ! 246: _reply_write(ip->rfd, no, str); ! 247: ABORT(no, str, ip); ! 248: return 0; ! 249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.