Annotation of researchv10no/ipc/mgrs/svcmgr/gate.c, revision 1.1.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.