Annotation of researchv10no/ipc/mgrs/4.3gate/main.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.