Annotation of researchv9/ipc/src/bin/nrx.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <errno.h>
        !             3: #include <dk.h>
        !             4: #include <sys/types.h>
        !             5: #include <sys/stat.h>
        !             6: #include <sys/filio.h>
        !             7: #include <sys/ttyio.h>
        !             8: #include <sys/stream.h>
        !             9: #include <signal.h>
        !            10: #include <ipc.h>
        !            11: #include <libc.h>
        !            12: 
        !            13: /*
        !            14:  * program to run a command
        !            15:  * on another cpu on Datakit w/ transparent ioctls,
        !            16:  * sometimes.
        !            17:  */
        !            18: 
        !            19: #define        msglen(mp)      ((mp)->losize + ((mp)->hisize<<8))
        !            20: 
        !            21: int     rem;            /* remote file descriptor */
        !            22: extern int mesg_ld;
        !            23: int    nomesg;
        !            24: 
        !            25: #define MAXCHARS 8192
        !            26: char args[MAXCHARS];
        !            27: 
        !            28: char *bldargs(argv)
        !            29:        register char *argv[];
        !            30: {
        !            31:        register char *s=args, *t;
        !            32:        while(t= *argv++){      /* assignment = */
        !            33:                while(*s = *t++)
        !            34:                        if(s++ >= &args[MAXCHARS-1]){
        !            35:                                fprintf(stderr, "rx: arg list too long\n");
        !            36:                                exit(1);
        !            37:                        }
        !            38:                *s++=' ';
        !            39:        }
        !            40:        s[-1]='\0';
        !            41:        return(args);
        !            42: }
        !            43: 
        !            44: char *
        !            45: basename(s)
        !            46:        register char *s;
        !            47: {
        !            48:        register char *t;
        !            49:        extern char *strrchr();
        !            50:        t=strrchr(s, '/');
        !            51:        return(t? t+1 : s);
        !            52: }
        !            53: 
        !            54: setmsgl(mp, n)
        !            55: register struct mesg *mp;
        !            56: int n;
        !            57: {
        !            58:        mp->losize = n;
        !            59:        mp->hisize = n >> 8;
        !            60: }
        !            61: 
        !            62: finish()
        !            63: {
        !            64: 
        !            65:        if(ioctl(0, FIOLOOKLD, 0) == mesg_ld) {
        !            66:                ioctl(0, FIOPOPLD, 0);
        !            67:                ioctl(0, TIOCFLUSH, 0);
        !            68:        }
        !            69:        exit(0);
        !            70: }
        !            71: 
        !            72: main(argc, argv)
        !            73: char **argv;
        !            74: {
        !            75:        char *host, *cmd;
        !            76: 
        !            77: #ifdef LINT
        !            78:        printf("", argc);
        !            79: #endif LINT
        !            80:         host = cmd = basename(argv[0]);
        !            81:        if(strcmp(host, "rx")==0 || strcmp(host, "rexec")==0
        !            82:           || strcmp(host, "nrx")==0){
        !            83:                host=argv[1];
        !            84:                argv++;
        !            85:        }
        !            86:        if(host==0){
        !            87:                fprintf(stderr, "usage: %s host [command]\n", cmd);
        !            88:                exit(1);
        !            89:        }
        !            90:        if(argv[1]==0){
        !            91:                execl("/usr/ipc/bin/ndcon", argv[1], argv[1], (char *)0);
        !            92:                perror("ndcon");
        !            93:                exit(1);
        !            94:        }
        !            95:         rem = ipcmesgexec(host, "heavy", bldargs(&argv[1]));
        !            96:         if (rem<0) {
        !            97:                fprintf(stderr, "%s: call to %s failed: %s\n", cmd , host, errstr);
        !            98:                 exit(1);
        !            99:        }
        !           100:        setmesg();
        !           101:        signal(SIGHUP, finish);
        !           102:        signal(SIGPIPE, SIG_IGN);
        !           103:        go(rem);
        !           104:        finish();
        !           105:        /* NOTREACHED */
        !           106: }
        !           107: 
        !           108: /*
        !           109:  * if standard input and output are the same,
        !           110:  * try to push the message line discipline
        !           111:  * otherwise we're in a pipeline and it's not safe
        !           112:  */
        !           113: setmesg()
        !           114: {
        !           115:        struct stat st0, st1;
        !           116: 
        !           117:        if (fstat(0, &st0) < 0 || fstat(1, &st1) < 0
        !           118:        ||  st0.st_dev != st1.st_dev || st0.st_ino != st1.st_ino) {
        !           119:                nomesg = 1;
        !           120:                return;
        !           121:        }
        !           122:        if(ioctl(0, FIOPUSHLD, &mesg_ld) < 0)
        !           123:                nomesg = 1;
        !           124: }
        !           125: 
        !           126: /*
        !           127:  * hack:
        !           128:  * until some message comes back from the remote,
        !           129:  * ignore local data
        !           130:  */
        !           131: go(fd)
        !           132: {
        !           133:        int rbits, wbits, srbits;
        !           134:        int n;
        !           135:        char buf[4096+MSGHLEN];
        !           136:        struct mesg *mp;
        !           137: 
        !           138:        mp = (struct mesg *) buf;
        !           139:        wbits = 0;
        !           140:        srbits = (1<<0)|(1<<fd);
        !           141:        while(1){
        !           142:                rbits = srbits;
        !           143:                if(select(20, (struct fd_set*)&rbits, (struct fd_set*)&wbits, 20000) < 0){
        !           144:                        if(errno != EINTR)
        !           145:                                return;
        !           146:                        continue;
        !           147:                }
        !           148:                if(rbits & 1){
        !           149:                        n = rdmesg(0, buf, sizeof(buf));
        !           150:                        if(n <= 0) {
        !           151:                                srbits &=~ 1;
        !           152:                                continue;
        !           153:                        }
        !           154:                        mp->magic = MSGMAGIC;   /* temporary safety */
        !           155:                        if(write(fd, buf, n) != n)
        !           156:                                return;
        !           157:                        if(mp->type == M_FLUSH)
        !           158:                                remflush();
        !           159:                }
        !           160:                if(rbits & (1<<fd)){
        !           161:                        n = read(fd, buf, sizeof(buf));
        !           162:                        if(n <= 0)
        !           163:                                return;
        !           164:                        if(mp->type == M_HANGUP)
        !           165:                                return;
        !           166:                        if(mp->type == M_IOCTL){
        !           167:                                doioctl(buf, n);
        !           168:                        } else {
        !           169:                                mp->magic = MSGMAGIC;   /* temp safety */
        !           170:                                if(wrmesg(1, buf, n) != n)
        !           171:                                        return;
        !           172:                        }
        !           173:                }
        !           174:        }
        !           175: }
        !           176: 
        !           177: #define        MAXEOF  10
        !           178: 
        !           179: rdmesg(f, buf, n)
        !           180: char *buf;
        !           181: {
        !           182:        register struct mesg *mp;
        !           183:        static int eof = 0;
        !           184: 
        !           185:        if (nomesg == 0)
        !           186:                return (read(f, buf, n));
        !           187:        if (eof > MAXEOF)
        !           188:                return (0);
        !           189:        n = read(f, buf + MSGHLEN, n - (2 * MSGHLEN));
        !           190:        if (n < 0)
        !           191:                return (n);
        !           192:        mp = (struct mesg *)buf;
        !           193:        if (n == 0) {
        !           194:                eof++;
        !           195:                mp->type = M_DELIM;
        !           196:                mp->magic = MSGMAGIC;
        !           197:                setmsgl(mp, 0);
        !           198:                return (MSGHLEN);
        !           199:        }
        !           200:        eof = 0;
        !           201:        setmsgl((struct mesg *)buf, n);
        !           202:        mp->type = M_DATA;
        !           203:        mp->magic = MSGMAGIC;
        !           204:        mp = (struct mesg *)(buf + MSGHLEN + n);
        !           205:        mp->type = M_DELIM;
        !           206:        mp->magic = MSGMAGIC;
        !           207:        setmsgl((struct mesg *)buf, 0);
        !           208:        return (n + 2*MSGHLEN);
        !           209: }
        !           210: 
        !           211: wrmesg(f, buf, n)
        !           212: char *buf;
        !           213: {
        !           214:        if (nomesg == 0)
        !           215:                return (write(f, buf, n));
        !           216:        if (((struct mesg *)buf)->type != M_DATA)
        !           217:                return (n);     /* toss it */
        !           218:        if (write(f, buf + MSGHLEN, n - MSGHLEN) != n - MSGHLEN)
        !           219:                return (-1);
        !           220:        return (n);
        !           221: }
        !           222: 
        !           223: doioctl(buf, n)
        !           224: char *buf;
        !           225: {
        !           226:        struct mesg *mp;
        !           227:        struct iofoo{
        !           228:                int cmd;
        !           229:                union{
        !           230:                        int i;
        !           231:                        char errno;
        !           232:                        struct insld insld;
        !           233:                } u;
        !           234:        } *iop;
        !           235:        int cmd, ld;
        !           236: 
        !           237:        iop = (struct iofoo *)(buf + MSGHLEN);
        !           238:        mp = (struct mesg *) buf;
        !           239:        if (nomesg) {
        !           240:                errno = ENOTTY;
        !           241:                goto bad;
        !           242:        }
        !           243:        cmd = iop->cmd;
        !           244:        n -= MSGHLEN;
        !           245:        n -= sizeof(iop->cmd);
        !           246:        switch(cmd){
        !           247:        case FIOLOOKLD:
        !           248:                if(n > 0)
        !           249:                        ld = iop->u.i;
        !           250:                else
        !           251:                        ld = 0;
        !           252:                ld++;
        !           253:                if(ioctl(1, FIOLOOKLD, &ld) < 0)
        !           254:                        goto bad;
        !           255:                iop->cmd = ld;
        !           256:                n = sizeof(iop->cmd);
        !           257:                break;
        !           258: 
        !           259:        case FIOPOPLD:
        !           260:                if(n > 0)
        !           261:                        ld = iop->u.i;
        !           262:                else
        !           263:                        ld = 0;
        !           264:                ld++;
        !           265:                if(ioctl(1, FIOPOPLD, &ld) < 0)
        !           266:                        goto bad;
        !           267:                n = 0;
        !           268:                break;
        !           269: 
        !           270:        case FIOPUSHLD:
        !           271:                iop->u.insld.level = 0;
        !           272:                /* fall through... */
        !           273:        case FIOINSLD:
        !           274:                iop->u.insld.level++;
        !           275:                if(ioctl(1, FIOINSLD, &(iop->u.insld)) < 0)
        !           276:                        goto bad;
        !           277:                n = 0;
        !           278:                break;
        !           279: 
        !           280:        default:
        !           281:                mp->magic = MSGMAGIC;   /* safety */
        !           282:                write(1, buf, MSGHLEN + msglen(mp));
        !           283:                return;
        !           284:        }
        !           285:        /* locally successful */
        !           286:        mp->type = M_IOCACK;
        !           287:        mp->magic = MSGMAGIC;
        !           288:        setmsgl(mp, n);
        !           289:        write(rem, buf, MSGHLEN + msglen(mp));
        !           290:        return;
        !           291: bad:
        !           292:        mp->type = M_IOCNAK;
        !           293:        mp->magic = MSGMAGIC;
        !           294:        setmsgl(mp, sizeof(struct iofoo));
        !           295:        iop->u.errno = errno;
        !           296:        write(rem, buf, MSGHLEN + msglen(mp));
        !           297: }
        !           298: 
        !           299: remflush()
        !           300: {
        !           301:        char buf[5000];
        !           302:        struct mesg *mp;
        !           303: 
        !           304:        mp = (struct mesg *) buf;
        !           305:        mp->type = M_IOCTL;
        !           306:        mp->magic = MSGMAGIC;
        !           307:        setmsgl(mp, sizeof(int));
        !           308:        write(rem, buf, MSGHLEN + msglen(mp));
        !           309: 
        !           310:        while(read(rem, buf, sizeof(buf)) > 0){
        !           311:                if(mp->type == M_IOCNAK || mp->type == M_IOCACK){
        !           312:                        return;
        !           313:                }
        !           314:        }
        !           315: }

unix.superglobalmegacorp.com

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