Annotation of researchv10no/ipc/mgrs/common/dialout.c, revision 1.1.1.1

1.1       root        1: #include <sys/param.h>
                      2: #include <stdio.h>
                      3: #include <sys/filio.h>
                      4: #include <signal.h>
                      5: #include <ipc.h>
                      6: #include <libc.h>
                      7: #include <wait.h>
                      8: #include "defs.h"
                      9: 
                     10: /* preeclared */
                     11: void dodialout();
                     12: void dodialin();
                     13: void doopen();
                     14: void docreat();
                     15: void doredial();
                     16: 
                     17: /* global */
                     18: int pid;
                     19: int debug;
                     20: int zombie;
                     21: int children;
                     22: 
                     23: /* imported */
                     24: extern char *av0;
                     25: extern int net_dial();
                     26: extern int net_redial();
                     27: extern int net_announce();
                     28: extern void net_accept();
                     29: extern void net_reject();
                     30: extern ipcinfo *net_listen();
                     31: extern char *getlogin();
                     32: 
                     33: static
                     34: deadbaby()
                     35: {
                     36:        zombie = 1;
                     37: }
                     38: 
                     39: static
                     40: ding()
                     41: {
                     42: }
                     43: 
                     44: /* loop on calls out of the CPU */
                     45: void
                     46: dodialout(mtpt)
                     47:        char *mtpt;
                     48: {
                     49:        int fd;
                     50:        long next;
                     51:        long last, now;
                     52:        int status;
                     53:        int npid;
                     54: 
                     55:        signal(SIGPIPE, SIG_IGN);
                     56:        pid = getpid();
                     57: 
                     58:        /*
                     59:         *  plug into local name space.  Perform exponential backoff for
                     60:         *  reporting failure.  Console paper is finite.
                     61:         */
                     62:        last = time((long *)0);
                     63:        next = 30;
                     64:        for(;;){
                     65:                fd = ipccreat(mtpt, "");
                     66:                if (fd>=0)
                     67:                        break;
                     68:                now = time((long *)0);
                     69:                if(now-last >= next){
                     70:                        logconsole("%s: can't announce as %s (%s)\n", av0, mtpt, errstr);
                     71:                        next = 2*next;
                     72:                }
                     73:                sleep(30);
                     74:        }
                     75:        chmod(mtpt, 0666);
                     76:        logconsole("%s: announced to fs as %s\n", av0, mtpt);
                     77:        fflush(stdout);
                     78: 
                     79:        /*
                     80:         *  loop on outgoing requests
                     81:         */
                     82:        for(;;) {
                     83:                ipcinfo *ip;
                     84:                int errs;
                     85: 
                     86:                /*
                     87:                 *  eat zombies
                     88:                 */
                     89:                if (zombie) {
                     90:                        zombie = 0;
                     91:                        while(children){
                     92:                                signal(SIGALRM, ding);
                     93:                                alarm(2);
                     94:                                npid = wait(&status);
                     95:                                signal(SIGCHLD, deadbaby);
                     96:                                alarm(0);
                     97:                                if(npid<0)
                     98:                                        break;
                     99:                                children--;
                    100:                        }
                    101:                }
                    102: 
                    103:                /*
                    104:                 *  wait for a request, continue on interrupts
                    105:                 */
                    106:                errs = 0;
                    107:                while((ip = ipclisten(fd))==NULL){
                    108:                        if(errno!=EINTR && errs++>5) {
                    109:                                logevent("dialout: out broken listen\n");
                    110:                                close(fd);
                    111:                                return;
                    112:                        }
                    113:                }
                    114:                if(debug)
                    115:                        logevent("dialout: rcved\n");
                    116: 
                    117:                /*
                    118:                 *  create new process for request
                    119:                 */
                    120:                signal(SIGCHLD, deadbaby);
                    121:                switch(fork()) {
                    122:                case -1:                /* whoops */
                    123:                        ipcreject(ip, errno, "no more processes");
                    124:                        logstatus("out", ip);
                    125:                        continue;
                    126:                case 0:
                    127:                        close(fd);
                    128:                        break;
                    129:                default:
                    130:                        children++;
                    131:                        (void)ABORT(0, "", ip);
                    132:                        continue;
                    133:                }
                    134:                if(debug)
                    135:                        logevent("dialout: forked\n");
                    136: 
                    137:                /*
                    138:                 *  perform request
                    139:                 */
                    140:                if (ip->flags & IPC_CREAT)
                    141:                        docreat(ip, mtpt);
                    142:                else if (ip->flags & IPC_REDIAL)
                    143:                        doredial(ip, mtpt);
                    144:                else
                    145:                        doopen(ip, mtpt);
                    146:                if(debug)
                    147:                        logevent("dialout: done\n");
                    148:                exit(0);
                    149:        }
                    150: }
                    151: 
                    152: /* establish a connection to a net name */
                    153: void
                    154: doopen(ip, mtpt)
                    155:        ipcinfo *ip;
                    156:        char *mtpt;
                    157: {
                    158:        int fd;
                    159:        static stretch myname;
                    160: 
                    161:        *av0 = 'D';
                    162: 
                    163:        /*
                    164:         *  dial out over the network
                    165:         */
                    166:        fd = net_dial(ip);
                    167:        if (fd < 0) {
                    168:                ipcreject(ip, errno, errstr);
                    169:                logstatus("out", ip);
                    170:                return;
                    171:        }
                    172: 
                    173:        /*
                    174:         *  accept the request, passing back the network file descriptor
                    175:         *  and our local name in the form "network!machine!service".
                    176:         */
                    177:        _strcat(&myname, mtpt, "!", ipcname);
                    178:        ipcdaccept(ip, fd, myname.ptr);
                    179: 
                    180:        errno = 0; errstr = "";
                    181:        logstatus("out", ip);
                    182:        close(fd);
                    183: }
                    184: 
                    185: /* announce a new netname */
                    186: void
                    187: docreat(ip, mtpt)
                    188:        ipcinfo *ip;
                    189:        char *mtpt;
                    190: {
                    191:        ipcinfo *netip;
                    192:        int listenfd;
                    193:        int toclient;
                    194:        int pfd[2];
                    195:        fd_set fds;
                    196:        static stretch myname;
                    197: 
                    198:        /*
                    199:         *  no invisible gatewaying, it must be subject to authentication
                    200:         */
                    201:        if (ip->cfd >= 0) {
                    202:                ipcreject(ip, EIO, "can't do remote ipccreat");
                    203:                logstatus("out", ip);
                    204:                return;
                    205:        }
                    206: 
                    207:        *av0 = 'L';
                    208: 
                    209:        /*
                    210:         *  create a unique channel 
                    211:         *  for communications with requestor
                    212:         */
                    213:        if (pipe(pfd) < 0) {
                    214:                ipcreject(ip, errno, "can't create local channel");
                    215:                logstatus("out", ip);
                    216:                return;
                    217:        }
                    218:        toclient = pfd[1];
                    219: 
                    220:        /*
                    221:         *  dial out on network
                    222:         */
                    223:        listenfd = net_announce(ip);
                    224:        if (listenfd < 0) {
                    225:                close(pfd[0]);
                    226:                close(pfd[1]);
                    227:                ipcreject(ip, errno, errstr);
                    228:                logstatus("out", ip);
                    229:                return;
                    230:        }
                    231: 
                    232:        /*
                    233:         *  accept the announce request.  Return our address, if we have
                    234:         *  one in the form "network!machine!service"
                    235:         */
                    236:        _strcat(&myname, mtpt, "!", ipcname);
                    237:        if (ipcdaccept(ip, pfd[0], myname.ptr) < 0)
                    238:                return;
                    239:        close(pfd[0]);
                    240:        errno = 0; errstr = "";
                    241:        logstatus("out", ip);
                    242: 
                    243:        /* loop waiting for in calls */
                    244:        FD_ZERO(fds);
                    245:        FD_SET(listenfd, fds);
                    246:        FD_SET(toclient, fds);
                    247:        while(1) {
                    248:                fd_set rfds;
                    249:                int rv;
                    250: 
                    251:                /* check for input or hang-up */
                    252:                rfds = fds;
                    253:                rv = select(NOFILE, &rfds, (fd_set*)0, 10000);
                    254:                if (rv == 0)
                    255:                        continue;
                    256:                else if (rv < 0)
                    257:                        break;
                    258:                else if (FD_ISSET(toclient, rfds))
                    259:                        break;
                    260: 
                    261:                /* get request */
                    262:                netip = net_listen(listenfd);
                    263:                if (netip == NULL) {
                    264:                        logevent("net_listen error %d %s\n", errno, errstr);
                    265:                        ABORT(errno, errstr, ip);
                    266:                        break;
                    267:                }
                    268: 
                    269:                /*
                    270:                 *  make a new channel to the listener, and pass him
                    271:                 *  one end.
                    272:                 */
                    273:                if (pipe(pfd)<0) {
                    274:                        net_reject(netip, errno, "no more pipes");
                    275:                        logstatus("in", netip);
                    276:                        continue;
                    277:                }
                    278:                if (ioctl(toclient, FIOSNDFD, &(pfd[0]))<0) {
                    279:                        net_reject(netip, errno, "protocol botch");
                    280:                        logstatus("in", netip);
                    281:                        break;
                    282:                }
                    283:                close(pfd[0]);
                    284: 
                    285:                /*
                    286:                 *  pass the request over the new channel.  include name
                    287:                 *  used to make the call.
                    288:                 */
                    289:                if (ioctl(pfd[1], FIOSNDFD, &(netip->rfd))<0) {
                    290:                        net_reject(netip, errno, "protocol botch");
                    291:                        close(pfd[1]);
                    292:                        logstatus("in", netip);
                    293:                        continue;
                    294:                }
                    295:                close(netip->rfd);
                    296:                netip->rfd = -1;
                    297:                _strcat(&myname, mtpt, "!", ip->myname);
                    298:                ip->myname = myname.ptr;
                    299:                if (_info_write(pfd[1], netip) < 0) {
                    300:                        net_reject(netip, errno, "protocol botch");
                    301:                        close(pfd[1]);
                    302:                        logstatus("in", netip);
                    303:                        continue;
                    304:                }
                    305: 
                    306:                /*
                    307:                 *  get the client's reply and pass it on to the net
                    308:                 */
                    309:                if (_reply_read(pfd[1]) < 0) {
                    310:                        /*  didn't work, drop call */
                    311:                        net_reject(netip, errno, "protocol botch");
                    312:                } else if(errno<0) {
                    313:                        /*  client will handle the accept/reject */
                    314:                        close(netip->cfd);
                    315:                } else if (errno) {
                    316:                        net_reject(netip, errno, errstr);
                    317:                } else
                    318:                        net_accept(netip);
                    319:                logstatus("in", netip);
                    320:                close(pfd[1]);
                    321:        }
                    322:        return;
                    323: }
                    324: 
                    325: /* redial a call */
                    326: void
                    327: doredial(ip, mtpt)
                    328:        ipcinfo *ip;
                    329:        char *mtpt;
                    330: {
                    331:        *av0 = 'R';
                    332: 
                    333:        /*
                    334:         *  redial over the network
                    335:         */
                    336:        net_redial(ip);
                    337:        ipcaccept(ip);
                    338:        ABORT(0, (char *)0, ip);
                    339:        logstatus("redial", ip);
                    340: }

unix.superglobalmegacorp.com

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