Annotation of researchv10no/cmd/face/faced.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * face server, library style
                      3:  */
                      4: #include <rf.h>
                      5: #include <ipc.h>
                      6: #include <signal.h>
                      7: #include "faceproto.h"
                      8: 
                      9: #define        NULL    0
                     10: char *malloc();
                     11: 
                     12: 
                     13: /*
                     14:  * ignore permissions from server for now (who cares?)
                     15:  * uid, gid always RFNOID
                     16:  * permissions always read for everyone
                     17:  */
                     18: #define        FPERM   ((RFPRD<<RFPOWNER)|(RFPRD<<RFPGROUP)|(RFPRD<<RFPOTHER))
                     19: #define        DPERM   (FPERM|(RFPDS<<RFPOWNER)|(RFPDS<<RFPGROUP)|(RFPDS<<RFPOTHER))
                     20: 
                     21: char *server;
                     22: int commfd = -1;
                     23: static int ininit;
                     24: 
                     25: #define        TIMEOUT (2*60)  /* disconnect if idle this long */
                     26: 
                     27: /*
                     28:  * init:
                     29:  * we have to return something,
                     30:  * but the server might not be running when we start
                     31:  * so fake up a root for now
                     32:  */
                     33: 
                     34: Rfile *
                     35: fsinit(argc, argv)
                     36: int argc;
                     37: char **argv;
                     38: {
                     39:        register Rfile *f;
                     40:        int timeout();
                     41: 
                     42:        if (argc <= 1)
                     43:                rfpanic("usage: a.out server\n");
                     44:        server = argv[1];
                     45:        if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL)
                     46:                rfpanic("no mem for root\n");
                     47:        f->fs = "/";
                     48:        f->ino = FROOT;
                     49:        f->dev = 0;
                     50:        f->type = RFTDIR;
                     51:        f->mode = DPERM;
                     52:        f->size = 512;  /* something nonzero */
                     53:        f->nlink = 1;
                     54:        f->ta = f->tm = f->tc = 0;
                     55:        signal(SIGALRM, timeout);
                     56:        ininit = 1;
                     57:        if (fsstat(f) < 0)
                     58:                fserrno = 0;    /* ignore error, use the fake data */
                     59:        ininit = 0;
                     60:        return (f);
                     61: }
                     62: 
                     63: timeout(s)
                     64: int s;
                     65: {
                     66:        signal(s, timeout);
                     67:        if (rfdebug)
                     68:                rflog("timeout\n");
                     69:        callshutdown();
                     70: }
                     71: 
                     72: /*
                     73:  * cheap hack:
                     74:  * if we've already checked the root,
                     75:  * short-circuit namei calls for it,
                     76:  * so status programs (like netb setup) won't make us
                     77:  * keep a circuit open
                     78:  */
                     79: Rfile *
                     80: fswalk(df, name)
                     81: Rfile *df;
                     82: char *name;
                     83: {
                     84:        register Rfile *f;
                     85:        char stbuf[FMAXDATA];
                     86:        long rcode;
                     87:        char *nname;
                     88: 
                     89:        if (df->ino == FROOT
                     90:        &&  (name[0] == 0 || (name[0] == '.' && name[1] == 0)))
                     91:                return (df);
                     92:        if (df->ino == FROOT && strcmp(name, "..") == 0) {
                     93:                fserrno = 0;
                     94:                return (NULL);
                     95:        }
                     96:        if ((nname = malloc(FMAXPATH)) == NULL) {
                     97:                rflog("no mem for name: %s/%s\n", df->fs, name);
                     98:                fserrno = RFEINVAL;
                     99:                return (NULL);
                    100:        }
                    101:        strcpy(nname, df->fs);
                    102:        strcat(nname, "/");
                    103:        strcat(nname, name);
                    104:        if (facecall(nname, DOSTAT, 0L, 0L, stbuf, &rcode) < STLEN) {
                    105:                /* call failed or network botch */
                    106:                fserrno = RFEINVAL;
                    107:                free(nname);
                    108:                return (NULL);
                    109:        }
                    110:        if (rcode < 0) {
                    111:                fserrno = RFENOENT;
                    112:                free(nname);
                    113:                return (NULL);
                    114:        }
                    115:        if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) {
                    116:                rflog("no mem for file: %s\n", nname);
                    117:                fserrno = RFEINVAL;
                    118:                free(nname);
                    119:                return (NULL);
                    120:        }
                    121:        f->fs = nname;
                    122:        stunpack(stbuf, f);
                    123:        return (f);
                    124: }
                    125: 
                    126: int
                    127: fsput(f)
                    128: Rfile *f;
                    129: {
                    130:        free(f->fs);
                    131:        free((char *)f);
                    132:        return (0);
                    133: }
                    134: 
                    135: int
                    136: fsstat(f)
                    137: Rfile *f;
                    138: {
                    139:        char stbuf[FMAXDATA];
                    140:        long rcode;
                    141: 
                    142:        if (f->ino == FROOT && ininit == 0)
                    143:                return (0);     /* and don't call */
                    144:        if (facecall(f->fs, DOSTAT, 0L, 0L, stbuf, &rcode) < STLEN) {
                    145:                fserrno = RFEINVAL;
                    146:                return (-1);
                    147:        }
                    148:        if (rcode < 0) {
                    149:                fserrno = RFEINVAL;
                    150:                return (-1);
                    151:        }
                    152:        stunpack(stbuf, f);
                    153:        return (0);
                    154: }
                    155: 
                    156: /*
                    157:  * read directories
                    158:  */
                    159: int
                    160: fsdirread(f, off, buf, len, noffp)
                    161: Rfile *f;
                    162: long off;
                    163: char *buf;
                    164: int len;
                    165: long *noffp;
                    166: {
                    167:        char dirbuf[FDLEN*32];  /* some even multiple */
                    168:        char onebuf[FDLEN-FD_NAME + 10];        /* enough for one entry */
                    169:        register unsigned char *dp;
                    170:        register int nread, n;
                    171:        register char *bp;
                    172: 
                    173:        if ((off%FDLEN) != 0) {
                    174:                rflog("unaligned fsdirread: off %ld\n", off);
                    175:                fserrno = RFEINVAL;
                    176:                return (-1);
                    177:        }
                    178:        bp = buf;
                    179:        while ((nread = fsread(f, off, dirbuf, sizeof(dirbuf))) > 0) {
                    180:                dp = (unsigned char *)dirbuf;
                    181:                while (nread >= FDLEN) {
                    182:                        /* should check ino==0 here */
                    183:                        sprintf(onebuf, "%d\t%.*s", frfshort(dp, FD_INO),
                    184:                                FDLEN - FD_NAME, dp + FD_NAME);
                    185:                        n = strlen(onebuf)+1;   /* including NUL */
                    186:                        if ((len -= n) < 0)
                    187:                                goto out;
                    188:                        memcpy(bp, onebuf, n);
                    189:                        bp += n;
                    190:                        off += FDLEN;
                    191:                        dp += FDLEN;
                    192:                        nread -= FDLEN;
                    193:                }
                    194:        }
                    195: out:
                    196:        *noffp = off;
                    197:        if (bp != buf)          /* if we read anything, return it */
                    198:                return (bp - buf);
                    199:        if (len < 0) {          /* first entry too large */
                    200:                fserrno = RFENOSPC;
                    201:                return (-1);
                    202:        }
                    203:        return (nread);         /* must be 0 or -1 */
                    204: }
                    205: 
                    206: int
                    207: fsread(f, off, buf, len)
                    208: Rfile *f;
                    209: char *buf;
                    210: int len;
                    211: long off;
                    212: {
                    213:        char data[FMAXDATA];
                    214:        long rcode;
                    215: 
                    216:        if (facecall(f->fs, DOREAD, off, (long)len, data, &rcode) < 0) {
                    217:                fserrno = RFEINVAL;
                    218:                return (-1);
                    219:        }
                    220:        if (rcode < 0) {
                    221:                fserrno = RFEIO;
                    222:                return (-1);
                    223:        }
                    224:        if (rcode > len)
                    225:                rfpanic("fsread wanted %d got %ld\n", len, rcode);
                    226:        if (rcode)
                    227:                memcpy(buf, data, (int)rcode);
                    228:        return (rcode);
                    229: }
                    230: 
                    231: /* need fsdirread too */
                    232: 
                    233: /*
                    234:  * one function call to the server
                    235:  * interface is overly general and underused
                    236:  * there are a filename, a function code, and two long parameters;
                    237:  * some data is returned in result,
                    238:  * and a long status code is returned in *codep
                    239:  * the function return value is the length of the data;
                    240:  * -1 means error
                    241:  */
                    242: int
                    243: facecall(file, func, p1, p2, result, codep)
                    244: char *file;
                    245: int func;
                    246: long p1, p2;
                    247: char *result;
                    248: long *codep;
                    249: {
                    250:        register unsigned char *p;
                    251:        register char msg[F_DATA+FMAXDATA];
                    252:        int len;
                    253: 
                    254:        alarm(0);
                    255:        if (commfd < 0 && callsetup() < 0)
                    256:                return (-1);
                    257:        len = strlen(file) + 1;
                    258:        if (len > FMAXDATA)
                    259:                rfpanic("facecall: name too long\n");
                    260:        p = (unsigned char *)msg;
                    261:        p[F_TYPE] = func;
                    262:        p[F_TYPE+1] = 0;        /* safety for old servers */
                    263:        tofshort(p, F_LEN, len);
                    264:        toflong(p, F_P1, p1);
                    265:        toflong(p, F_P2, p2);
                    266:        memcpy(&p[F_DATA], file, len);
                    267:        if (rfdebug)
                    268:                rflog("facecall: %s: func %d p %ld %ld\n", file, func, p1, p2);
                    269:        if (write(commfd, msg, len+F_DATA) != len+F_DATA) {
                    270:                rflog("net write error\n");
                    271:                callshutdown();
                    272:                return (-1);
                    273:        }
                    274:        if (gread(commfd, msg, F_DATA, F_DATA) != F_DATA) {
                    275:                rflog("net read error\n");
                    276:                callshutdown();
                    277:                return (-1);
                    278:        }
                    279:        len = frfshort(p, F_LEN);
                    280:        if (len < 0 || len > FMAXDATA) {
                    281:                rflog("net ill len %d\n", len);
                    282:                callshutdown();
                    283:                return (-1);
                    284:        }
                    285:        if (len > 0 && gread(commfd, result, len, len) != len) {
                    286:                rflog("net read error (body)\n");
                    287:                callshutdown();
                    288:                return (-1);
                    289:        }
                    290:        *codep = frflong(p, F_P1);
                    291:        if (rfdebug)
                    292:                rflog("... len %d p1 %ld\n", len, *codep);
                    293:        alarm(TIMEOUT);
                    294:        return (len);
                    295: }
                    296: 
                    297: /*
                    298:  * call server
                    299:  */
                    300: callsetup()
                    301: {
                    302:        extern char *errstr;
                    303: 
                    304:        if (rfdebug)
                    305:                rflog("call %s\n", server);
                    306:        if ((commfd = ipcopen(ipcpath(server, "", ""), "")) < 0)
                    307:                rflog("can't call %s: %s\n", server, errstr);
                    308:        return (commfd);
                    309: }
                    310: 
                    311: callshutdown()
                    312: {
                    313:        close(commfd);
                    314:        commfd = -1;
                    315: }
                    316: 
                    317: /*
                    318:  * unpack stat buffer into a file
                    319:  */
                    320: 
                    321: stunpack(buf, f)
                    322: char *buf;
                    323: register Rfile *f;
                    324: {
                    325:        register unsigned char *p;
                    326: 
                    327:        p = (unsigned char *)buf;
                    328:        f->ino = frfshort(p, ST_INO);
                    329:        f->dev = 0;
                    330:        if ((frfshort(p, ST_MODE) & STFMT) == STDIR) {
                    331:                f->type = RFTDIR;
                    332:                f->mode = DPERM;
                    333:        } else {
                    334:                f->type = RFTREG;
                    335:                f->mode = FPERM;
                    336:        }
                    337:        f->nlink = frfshort(p, ST_NLINK);
                    338:        f->uid = RFNOID;
                    339:        f->gid = RFNOID;
                    340:        f->size = frflong(p, ST_SIZE);
                    341:        f->ta = frflong(p, ST_ATIME);
                    342:        f->tm = frflong(p, ST_MTIME);
                    343:        f->tc = frflong(p, ST_CTIME);
                    344: }
                    345: 
                    346: /*
                    347:  * gather data that may come in dribs and drabs:
                    348:  * read size bytes into buf,
                    349:  * but keep looking until at least minsize have arrived
                    350:  */
                    351: 
                    352: int
                    353: gread(fd, buf, size, minsize)
                    354: int fd;
                    355: char *buf;
                    356: int size;
                    357: register int minsize;
                    358: {
                    359:        register int n, tot;
                    360: 
                    361:        tot = 0;
                    362:        while (minsize > 0) {
                    363:                if ((n = read(fd, buf, size)) <= 0)
                    364:                        break;
                    365:                buf += n;
                    366:                size -= n;
                    367:                minsize -= n;
                    368:                tot += n;
                    369:        }
                    370:        if (tot)
                    371:                return (tot);
                    372:        return (n);
                    373: }

unix.superglobalmegacorp.com

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