Annotation of researchv10no/ipc/mgrs/svcmgr/gate.c, revision 1.1

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

unix.superglobalmegacorp.com

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