Annotation of researchv10no/ipc/mgrs/svcmgr/ngate.c, revision 1.1.1.1

1.1       root        1:  *     Remote dialer routine.
                      2:  */
                      3: #include <sys/types.h>
                      4: #include <stdio.h>
                      5: #include <libc.h>
                      6: #include <sys/utsname.h>
                      7: #include <errno.h>
                      8: #include <sys/filio.h>
                      9: #include <ipc.h>
                     10: #include "defs.h"
                     11: 
                     12: /* export */
                     13: char *av0;
                     14: char *param;
                     15: int debug;
                     16: 
                     17: /* cheap foiegn imports */
                     18: extern void dodialout(), dodialin();
                     19: 
                     20: usage(name)
                     21:        char *name;
                     22: {
                     23:        fprintf(stderr, "usage: %s [-m mount-pt] [-n netname] gate1 [gate2 ...]\n", name);
                     24:        exit(1);
                     25: }
                     26: 
                     27: /*
                     28:  *  Gate calls to/from a remote network.
                     29:  */
                     30: main(ac, av)
                     31:        int ac;
                     32:        char *av[];
                     33: {
                     34:        char *netname=NULL, *mtpt="rem", *cp;
                     35:        int ai;
                     36: 
                     37:        av0 = av[0];
                     38:        chdir("/cs");
                     39: 
                     40:        /* get args */
                     41:        for (ai=1; ai<ac; ai++) {
                     42:                if (av[ai][0] == '-')
                     43:                        for (cp=&av[ai][1]; *cp; cp++) {
                     44:                                switch(*cp) {
                     45:                                case 'm':
                     46:                                        if (ai+1>=ac)
                     47:                                                usage(av[0]);
                     48:                                        mtpt = av[++ai];
                     49:                                        break;
                     50:                                case 'n':
                     51:                                        if (ai+1>=ac)
                     52:                                                usage(av[0]);
                     53:                                        netname = av[++ai];
                     54:                                        break;
                     55:                                case 'd':
                     56:                                        debug = 1;
                     57:                                        break;
                     58:                                default:
                     59:                                        usage(av0);
                     60:                                }
                     61:                        }
                     62:                else
                     63:                        break;
                     64:        }
                     65: 
                     66:        /* get gateways */
                     67:        if(ai>=ac)
                     68:                usage(av0);
                     69: 
                     70:        /* detach from process group, terminal, etc. */
                     71:        if (!debug)
                     72:                detach(mtpt);
                     73: 
                     74:        /* get defaults */
                     75:        if (netname==NULL) {
                     76:                struct utsname name;
                     77: 
                     78:                uname(&name);
                     79:                netname = name.nodename;
                     80:        }
                     81: 
                     82:        /* create dialer and listener */
                     83:        switch (fork()) {
                     84:        case -1:
                     85:                perror(av0);
                     86:                exit(1);
                     87:        case 0:
                     88:                for(;;)
                     89:                        dodialout(mtpt);
                     90:        default:
                     91:                for(;;)
                     92:                        dodialin(mtpt, netname, "heavy");
                     93:        }
                     94: }
                     95: 
                     96: static int
                     97: dingaling()
                     98: {
                     99:        signal(SIGALRM, dingaling);
                    100: }
                    101: 
                    102: /*
                    103:  *  Dial out to a gateway.  Return -1 if no more gates are to be tried.
                    104:  *  Return 0 if more gates are to be tried.
                    105:  */
                    106: gateout(rp, ap)
                    107:        Request *rp;
                    108:        Action *ap;
                    109: {
                    110:        int fd;
                    111:        extern int rmesg_ld;
                    112:        char netname[ARB];
                    113:        char *cp;
                    114: 
                    115:        if (rp->i->cfd>=0) {
                    116:                ipcreject(rp->i, EINVAL, "gate-through disallowed");
                    117:                return -1;
                    118:        }
                    119: 
                    120:        /* call `gateway' */
                    121:        fd = ipcopen(ap->arg, rp->i->param);
                    122: 
                    123:        /* send original request */
                    124:        if (fd<0 || _info_write(fd, rp->i)<0) {
                    125:                /* if there are any more gateout's, keep trying */
                    126:                if (ap->next==NULL)
                    127:                        ipcreject(rp->i, errno, errstr);
                    128:                close(fd);
                    129:                return 0;
                    130:        }
                    131: 
                    132:        /* see if the gateway could place the call */
                    133:        if (_reply_read(fd)<0 || errno!=0) {
                    134:                /* call was rejected, don't try any more gateouts */
                    135:                ipcreject(rp->i, errno, errstr);
                    136:                close(fd);
                    137:                return -1;
                    138:        }
                    139: 
                    140:        /* gateway and call were accepted */
                    141:        if(rp->i->flags == IPC_CREAT){
                    142:                /* for remote announcements, this process becomes a mux */
                    143:                lfd = ipcaccept(rp->i);
                    144:                localmux(fd, lfd);
                    145:                return -1;
                    146:        } else {
                    147:                /* for remote dials, just pass the net fd back to the process */
                    148:                ipcdaccept(rp->i, fd, ipcname);
                    149:                return -1;
                    150:        }
                    151: }
                    152: 
                    153: /*
                    154:  *  Acccept a gateway call
                    155:  */
                    156: gateway(rp, ap)
                    157:        Request *rp;
                    158:        Action *ap;
                    159: {
                    160:        int caller, callee;
                    161:        ipcinfo info;
                    162:        fd_set fds;
                    163:        char newname[ARB];
                    164:        extern int mesg_ld;
                    165:        char *mapuser();
                    166:        int (*oldsig)();
                    167: 
                    168:        /* see if we gateway for this requestor */
                    169:        if (mapuser(rp->s->name, rp->i->machine, rp->i->user)==NULL) {
                    170:                ipcreject(rp->i, EACCES, "gateway disallowed");
                    171:                return -1;
                    172:        }
                    173:        if ((caller=ipcaccept(rp->i))<0)
                    174:                return -1;
                    175: 
                    176:        /* get the original request */
                    177:        info.uid = info.gid = 0;
                    178:        info.user="";
                    179:        if (_info_read(caller, &info)<0)
                    180:                return -1;
                    181: 
                    182:        /* make the call */
                    183:        if(rp->i->flags == IPC_CREAT){
                    184:                /* for remote announcements, this process becomes a mux */
                    185:                lfd = ipcaccept(rp->i);
                    186:                localmux(fd, lfd);
                    187:                return -1;
                    188:        } else {
                    189:                /* for remote dials, just shuttle bytes back and forth */
                    190:                ipcdaccept(rp->i, fd, "who_cares");
                    191:                return -1;
                    192:        }
                    193: 
                    194:        /* dial the number */
                    195:        sprintf(newname, "%s!%s", ap->arg, info.name);
                    196:        info.name = newname;
                    197:        info.rfd = info.cfd = -1;
                    198:        info.flags = IPC_OPEN;
                    199:        oldsig=signal(SIGALRM, dingaling);
                    200:        alarm(30);
                    201:        callee = ipcdial(&info);
                    202:        alarm(0);
                    203:        signal(SIGALRM, oldsig);
                    204:        if (callee<0) {
                    205:                _reply_write(caller, errno, errstr);
                    206:                close(caller);
                    207:                return -1;
                    208:        }
                    209: 
                    210:        /* tell gateout that it worked */
                    211:        if (_reply_write(caller, 0, "")<0) {
                    212:                close(caller);
                    213:                close(callee);
                    214:                return -1;
                    215:        }
                    216: 
                    217:        /* shuttle bytes back and forth */
                    218:        FD_ZERO(fds);
                    219:        for(;;) {
                    220:                FD_SET(caller, fds);
                    221:                FD_SET(callee, fds);
                    222:                switch(select(NOFILE, &fds, (struct fd_set *)0, 1000)) {
                    223:                case -1:
                    224:                        return -1;
                    225:                case 0:
                    226:                        continue;
                    227:                }
                    228:                if (FD_ISSET(caller, fds))
                    229:                        if (pass(caller, callee)<0)
                    230:                                return -1;
                    231:                if (FD_ISSET(callee, fds))
                    232:                        if (pass(callee, caller)<0)
                    233:                                return -1;
                    234:        }
                    235: }
                    236: 
                    237: pass(from, to)
                    238:        int from, to;
                    239: {
                    240:        char buf[4096];
                    241:        int n;
                    242: 
                    243:        if ((n=read(from, buf, sizeof(buf)))<=0)
                    244:                return -1;
                    245:        if (write(to, buf, n)!=n)
                    246:                return -1;
                    247:        return 0;
                    248: }

unix.superglobalmegacorp.com

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