Annotation of researchv10no/ipc/bin/nrx.c, revision 1.1.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.