Annotation of researchv8dc/netfs/setup.c, revision 1.1

1.1     ! root        1: #include "stdio.h"
        !             2: #include "sys/param.h"
        !             3: #include "sys/stat.h"
        !             4: #include "sys/neta.h"
        !             5: #include "errno.h"
        !             6: #include "sys/ioctl.h"
        !             7: #include "signal.h"
        !             8: #include "setjmp.h"
        !             9: 
        !            10: #define RMFSTYP 1      /* file system type for remote file system */
        !            11: 
        !            12: struct friend {
        !            13:        char *who;
        !            14:        char *mount;
        !            15:        int dev;
        !            16:        int silent;
        !            17:        int status;
        !            18:        int chan;
        !            19: } friends[NOFILE];
        !            20: int nfriends;
        !            21: #define DEAD   0
        !            22: #define OK     1
        !            23: #define PROBE  2
        !            24: #define KILL   3
        !            25: 
        !            26: char *states[] = { "dead", "ok", "probe", "kill", "?"};
        !            27: 
        !            28: struct senda x;
        !            29: struct rcva y;
        !            30: extern int errno;
        !            31: extern char *ctime();
        !            32: extern char *malloc();
        !            33: struct stat stb;
        !            34: long looked;
        !            35: jmp_buf jmpbuf;
        !            36: 
        !            37: main()
        !            38: {      int i;
        !            39: /* any signal but SIGALRM (14) will start it over.  SIGALRM is used to
        !            40:  * interrupt hung reads.  SIGCHLD is ignored too */
        !            41:        sigalrm(0);
        !            42:        if(setjmp(jmpbuf) == 1)
        !            43:                rdfile();
        !            44:        else
        !            45:                sigcatch();
        !            46:        probe();
        !            47: }
        !            48: sigalrm(n)
        !            49: {
        !            50:        fprintf(stderr, "sigalrm %d\n", n);
        !            51:        fflush(stderr);
        !            52:        if(n == SIGALRM || n == 0)      /* otherwise might get SIGCHLD in sleep */
        !            53:                signal(SIGALRM, sigalrm);
        !            54:        signal(SIGCHLD, sigalrm);
        !            55: }
        !            56: sigcatch(n)
        !            57: {      int i;
        !            58:        for(i = 1; i < NSIG; i++)
        !            59:                if(i != SIGALRM && i != SIGCHLD)        /* alarm and tdkdial */
        !            60:                        (void) signal(i, sigcatch);
        !            61:        fprintf(stderr, "sigcatch %d\n", n);
        !            62:        fflush(stderr);
        !            63:        switch(i) {
        !            64:        case SIGILL: case SIGBUS: case SIGSEGV:
        !            65:                restart();
        !            66:        }
        !            67:        longjmp(jmpbuf, 1);
        !            68: }
        !            69: restart()
        !            70: {
        !            71:        fprintf(stderr, "execing\n");
        !            72:        fflush(stderr);
        !            73:        execl("/etc/net/setup", "setup", 0);
        !            74:        execl("/usr/net/setup", "setup", 0);
        !            75:        /* if that doesn't work */
        !            76:        fprintf(stderr, "oops, calling main\n");
        !            77:        fflush(stderr);
        !            78:        main();         /* ho ho */
        !            79: }
        !            80: probe()
        !            81: {      int i;
        !            82:        static int lastdone;
        !            83:        long now;
        !            84: loop:
        !            85:        if(lastdone >= nfriends) {
        !            86:                lastdone = 0;
        !            87:                sleep(30);
        !            88:                if(stat("/etc/net/friends", &stb) == 0 && stb.st_mtime > looked)
        !            89:                        rdfile();
        !            90:                if(stat("/usr/net/friends", &stb) == 0 && stb.st_mtime > looked)
        !            91:                        rdfile();
        !            92:                if(time((long *)0) > looked + 1200)
        !            93:                        rdfile();
        !            94:        }
        !            95:        i = lastdone++;
        !            96:        switch(friends[i].status) {
        !            97:        default:
        !            98:                break;
        !            99:        case PROBE:
        !           100:        case OK:
        !           101:                friends[i].status++;
        !           102:                doprobe(friends + i);
        !           103:                if(friends[i].status != OK) {
        !           104:                        now = time(0);
        !           105:                        fprintf(stderr, "hmm %s %s %s\n", friends[i].who,
        !           106:                                states[friends[i].status], ctime(&now));
        !           107:                }
        !           108:                break;
        !           109:        case KILL:      /* over the limit */
        !           110:                now = time(0);
        !           111:                fprintf(stderr, "%s timed out %s 0x%x %s", friends[i].who,
        !           112:                        states[friends[i].status], friends[i].chan, ctime(&now));
        !           113:                errno = 0;
        !           114:                gmount(RMFSTYP, friends[i].dev, 1, 0, 0);
        !           115:                if(errno == 0 || errno == EINVAL) {
        !           116:                        friends[i].status = DEAD;
        !           117:                        fprintf(stderr, "dead now\n");
        !           118:                }
        !           119:                else
        !           120:                        perror("xmount");
        !           121:                break;
        !           122:        }
        !           123:        goto loop;
        !           124: }      
        !           125: doprobe(x)
        !           126: struct friend *x;
        !           127: {      struct stat stb;
        !           128:        if(stat(x->mount, &stb) == 0 && stb.st_dev == x->dev)
        !           129:                x->status = OK;
        !           130: }
        !           131: startup(p)
        !           132: struct friend *p;
        !           133: {      int fd, i;
        !           134:        char version;
        !           135:        fd = callfs(p->who);
        !           136:        if(fd < 0) {
        !           137:                fprintf(stderr, "callfs %s failed\n", p->who);
        !           138:                return;
        !           139:        }
        !           140:        (void) fstat(fd, &stb);
        !           141:        fprintf(stderr, "starting %s (0x%x)", p->who, stb.st_rdev);
        !           142:        gmount(RMFSTYP, p->dev, 1, 0, 0);       /* just in case */
        !           143:        perror("xunmount");
        !           144:        x.trannum = 0;
        !           145:        version = x.version = NETVERSION;
        !           146:        x.cmd = NSTART;
        !           147:        x.uid = p->silent;
        !           148:        x.dev = p->dev;
        !           149:        alarm(30);
        !           150:        x.ta = time(0);
        !           151:        if((write(fd, &version, 1) != 1) || write(fd, (char *)&x, sizeof(x))
        !           152:                != sizeof(x)) {
        !           153:                        perror("write in setup");
        !           154:                        fprintf(stderr, "%s\n", p->who);
        !           155:                        close(fd);
        !           156:                        alarm(0);
        !           157:                        return;
        !           158:        }
        !           159:        if((i = read(fd, (char *)&y, sizeof(y))) != sizeof(y)) {
        !           160:                if(y.trannum == -1)
        !           161:                        fprintf(stderr, "version mismatch %s\n", p->who);
        !           162:                else {
        !           163:                        fprintf(stderr, "read %d chars for %s\n", i, p->who);
        !           164:                        perror((char *)&y);
        !           165:                }
        !           166:                close(fd);
        !           167:                return;
        !           168:        }
        !           169:        alarm(0);
        !           170:        if(y.errno != 0) {
        !           171:                errno = y.errno;
        !           172:                perror("nak in setup");
        !           173:                close(fd);
        !           174:                return;
        !           175:        }
        !           176:        if(gmount(RMFSTYP, p->dev, 0, fd, p->mount) != 0) {
        !           177:                perror("xmount");
        !           178:                fprintf(stderr, "unmounting it\n");     /* garbage collection*/
        !           179:                gmount(RMFSTYP, p->dev, 1, 0, 0);
        !           180:                perror("xunmount");
        !           181:                close(fd);
        !           182:                /* and try again later */
        !           183:                return;
        !           184:        }
        !           185:        p->status = OK;
        !           186:        fprintf(stderr, "started %s on %s dev %d silent %d chan 0x%x\n", p->who,
        !           187:                p->mount, p->dev/256, p->silent, p->chan = stb.st_rdev);
        !           188:        close(fd);
        !           189: }
        !           190: 
        !           191: #define skip for(; *p == ' ' || *p == '\t'; p++)
        !           192: #define note for(s = p; *p != ' ' && *p != '\t' && *p != '\n'; p++)
        !           193: struct friend *
        !           194: cnvt(s)
        !           195: char *s;
        !           196: {      static struct friend x;
        !           197:        char *p;
        !           198:        s[strlen(s)] = '\n';
        !           199:        p = s;
        !           200:        skip;
        !           201:        if(*p == '\n') {
        !           202:                x.who = "#";
        !           203:                return(&x);
        !           204:        }
        !           205:        note;
        !           206:        if(*p == '\n')
        !           207:                return(0);
        !           208:        *p++ = 0;
        !           209:        x.who = malloc(strlen(s) + 1);
        !           210:        strcpy(x.who, s);
        !           211:        s = p;
        !           212:        skip;
        !           213:        note;
        !           214:        if(*p == '\n')
        !           215:                return(0);
        !           216:        *p++ = 0;
        !           217:        x.mount = malloc(strlen(s) + 1);
        !           218:        strcpy(x.mount, s);
        !           219:        s = p;
        !           220:        skip;
        !           221:        note;
        !           222:        if(*p == '\n')
        !           223:                return(0);
        !           224:        *p++ = 0;
        !           225:        x.dev = 256 * atoi(s);
        !           226:        s = p;
        !           227:        skip;
        !           228:        note;
        !           229:        *p++ = 0;
        !           230:        x.silent = atoi(s);
        !           231:        x.status = DEAD;
        !           232:        return(&x);
        !           233: }
        !           234: 
        !           235: rdfile()
        !           236: {      FILE *fd;
        !           237:        int i;
        !           238:        char line[128];
        !           239:        struct friend *p;
        !           240:        alarm(0);               /* disable the sleep in probe */
        !           241:        fd = fopen("/etc/net/friends", "r");
        !           242:        if(fd == NULL) {
        !           243:                fd = fopen("/usr/net/friends","r");
        !           244:                if(fd == NULL) {
        !           245:                        perror("friends");
        !           246:                        exit(1);
        !           247:                }
        !           248:        }
        !           249:        for(;;) {
        !           250: onward:
        !           251:                (void) fgets(line, sizeof(line), fd);
        !           252:                if(feof(fd))
        !           253:                        break;
        !           254:                p = cnvt(line);
        !           255:                if(p == 0) {
        !           256:                        fprintf(stderr, "weird friends line %s\n", line);
        !           257:                        continue;
        !           258:                }
        !           259:                if(p->who[0] == '#')
        !           260:                        continue;
        !           261:                for(i = 0; i < nfriends; i++) {
        !           262:                        if(strcmp(p->who, friends[i].who))
        !           263:                                continue;
        !           264:                        if(friends[i].status != OK) {
        !           265:                                looked = time(0);
        !           266:                                fprintf(stderr, "\nrdfile %s (%s) %s",
        !           267:                                        states[friends[i].status],
        !           268:                                        friends[i].who, ctime(&looked));
        !           269:                                /* off the mother */
        !           270:                                if(friends[i].status != DEAD) {
        !           271:                                        friends[i].status = KILL;
        !           272:                                        fprintf(stderr, "bye %s\n", friends[i].who);
        !           273:                                }
        !           274:                        }
        !           275:                        if(friends[i].status != DEAD)
        !           276:                                goto onward;
        !           277:                        /* one could free the space */
        !           278:                        fprintf(stderr, "new friend %s\n", p->who);
        !           279:                        friends[i] = *p;
        !           280:                        startup(friends + i);
        !           281:                        goto onward;
        !           282:                }
        !           283:                for(i = 0; i < nfriends; i++)
        !           284:                        if(friends[i].status == DEAD) {
        !           285:                                friends[i] = *p;
        !           286:                                fprintf(stderr, "new friend %s\n", p->who);
        !           287:                                startup(friends + i);
        !           288:                                goto onward;
        !           289:                        }
        !           290:                if(i < nfriends)
        !           291:                        continue;
        !           292:                if(nfriends >= NOFILE) {
        !           293:                        fprintf(stderr, "friends overflow\n");
        !           294:                        abort();
        !           295:                }
        !           296:                fprintf(stderr, "new friend %s\n", p->who);
        !           297:                friends[nfriends++] = *p;
        !           298:                startup(friends + nfriends - 1);
        !           299:        }
        !           300:        fclose(fd);
        !           301:        looked = time(0);
        !           302:        fprintf(stderr, "ok %s", ctime(&looked));
        !           303: }
        !           304: 
        !           305: callfs(srvr)
        !           306: char *srvr;
        !           307: {
        !           308:        int rem, v;
        !           309:        extern int pk_ld, dkp_ld;
        !           310:        long x;
        !           311: 
        !           312:        alarm(30);
        !           313:        x = time(0);
        !           314:        fprintf(stderr, "%d tdkdial %s %s", getpid(), srvr, ctime(&x));
        !           315:        fflush(stderr);
        !           316:        rem = _tdkdial(3, 2, srvr);
        !           317:        x = time(0);
        !           318:        alarm(0);
        !           319:        if (rem < 0) {
        !           320:                fprintf(stderr, " %d can't rexec err = %d\n", getpid(), errno);
        !           321:                fflush(stderr);
        !           322:                return(-1);
        !           323:        }
        !           324:        else
        !           325:                fprintf(stderr, "tdkdial ok %s", ctime(&x));
        !           326:        /* v = ioctl(rem, FIOPUSHLD, &dkp_ld);  /* should be dkproto */
        !           327:        v = dkproto(rem, dkp_ld);
        !           328:        x = time(0);
        !           329:        if (v < 0) {
        !           330:                perror("can't start protocol");
        !           331:                fprintf(stderr, "\t%s", ctime(&x));
        !           332:                close(rem);
        !           333:                return(-1);
        !           334:        }
        !           335:        else
        !           336:                fprintf(stderr, "protocol started\n");
        !           337:        return(rem);
        !           338: }

unix.superglobalmegacorp.com

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