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

unix.superglobalmegacorp.com

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