|
|
1.1 ! root 1: #include "fserv.h" ! 2: #include "errno.h" ! 3: #include "sys/neta.h" ! 4: ! 5: extern char *realloc(); ! 6: /* temporary static alloc of devtab */ ! 7: ! 8: struct tdev devtab[NDEV]; ! 9: struct stat rootstat; ! 10: int ndev, dev; ! 11: extern int alive; ! 12: char *cmdnames[] = {"0?", "stat", "wrt", "read", "free", "trunc", "updat", ! 13: "get", "nami", "put", "10?"}; ! 14: char *buf, *nbuf; ! 15: int buflen, nbuflen; ! 16: ! 17: #define NF 100 ! 18: /* temporary static alloc of netftab */ ! 19: netf netftab[NF]; ! 20: int nnetf; ! 21: ! 22: #define MASK 0x0 ! 23: ! 24: ourdev(n) ! 25: { int i; ! 26: for(i = 0; i < ndev; i++) ! 27: if(devtab[i].his == n) ! 28: return(devtab[i].ours); ! 29: return(-1); ! 30: } ! 31: ! 32: hisdev(n) ! 33: { int i; ! 34: for(i = 0; i < ndev; i++) ! 35: if(devtab[i].ours == n) ! 36: return(devtab[i].his); ! 37: return(-1); ! 38: } ! 39: ! 40: newdev(n) ! 41: { struct tdev *p; ! 42: p = devtab + ndev++; ! 43: p->ours = n; ! 44: p->his = dev++; ! 45: debug1("\tnewdev %d %d", p->ours, p->his); ! 46: } ! 47: ! 48: netf * ! 49: gettag(n) ! 50: long n; ! 51: { int i; ! 52: for(i = 0; i < nnetf; i++) ! 53: if(netftab[i].tag == n) ! 54: return(netftab + i); ! 55: errno = ENOENT; ! 56: return(0); ! 57: } ! 58: ! 59: netf * ! 60: getnetf(d, i) /* either root of netfs, or in the table */ ! 61: { int j; ! 62: netf *p; ! 63: if(i == 0) { ! 64: errno = ENOENT; ! 65: return(0); ! 66: } ! 67: for(j = 0; j < nnetf; j++) ! 68: if(netftab[j].ino == i && netftab[j].dev == d) ! 69: return(netftab + j); ! 70: debug2("\tgetnetf(%d,%d)", d, i); ! 71: for(p = netftab, j = 0; j < nnetf; j++, p++) { ! 72: debug2("\t%d %d %d %s", p->tag, p->dev, p->ino, p->name?p->name:""); ! 73: } ! 74: return(0); ! 75: } ! 76: netf * ! 77: oldnetf(s) /* special case for nami/NDEL */ ! 78: char *s; ! 79: { netf *p; ! 80: struct stat stb; ! 81: if(xstat(s, &stb) < 0) ! 82: return(0); ! 83: if(p = getnetf(hisdev(stb.st_dev), stb.st_ino)) { ! 84: p->statb = stb; ! 85: return(p); ! 86: } ! 87: return(0); ! 88: } ! 89: ! 90: netf * ! 91: newnetf(s, fd, how) ! 92: char *s; ! 93: { int i; ! 94: netf *p; ! 95: struct stat stb; ! 96: if(xstat(s, &stb) < 0) ! 97: return(0); ! 98: if(p = getnetf(hisdev(stb.st_dev), stb.st_ino)) { ! 99: p->statb = stb; ! 100: return(p); ! 101: } ! 102: for(i = 0; i < nnetf; i++) ! 103: if(netftab[i].ino == 0) ! 104: goto found; ! 105: i = nnetf++; ! 106: if(nnetf > NF) { ! 107: errno = ENOMEM; ! 108: return(0); ! 109: } ! 110: found: ! 111: alive++; ! 112: p = netftab + i; ! 113: p->name = malloc(strlen(s) + 1); ! 114: strcpy(p->name, s); ! 115: p->statb = stb; ! 116: if(fd < 0) { ! 117: if(ftype(p) != S_IFLNK && ftype(p) != S_IFCHR && ftype(p) != S_IFBLK) ! 118: p->fd = open(p->name, 0); /* this better work */ ! 119: else ! 120: p->fd = -1; ! 121: p->how = 0; ! 122: } ! 123: else { ! 124: p->fd = fd; ! 125: p->how = how; ! 126: } ! 127: p->dev = hisdev(p->statb.st_dev); ! 128: if(p->dev == -1) { ! 129: newdev(p->statb.st_dev); ! 130: p->dev = hisdev(p->statb.st_dev); ! 131: } ! 132: p->ino = p->statb.st_ino; ! 133: p->tag = (p->dev << 16) ^ p->ino ^ MASK; ! 134: debug2("\tnew %d %d %s", p->dev, p->ino, p->name); ! 135: debug2("\tnew 0%o %d %d", p->statb.st_mode, p->statb.st_uid, p->statb.st_gid); ! 136: debug2("\tnew %d", nnetf); ! 137: return(p); ! 138: } ! 139: ! 140: clrnetf(n) ! 141: { netf *p; ! 142: p = gettag(n); ! 143: if(p == 0) { ! 144: debug("\tclr net got 0 (x%x)", n); ! 145: dumpstate(); ! 146: leave(8); /* shut it down */ ! 147: return; ! 148: } ! 149: if(p->ino == 2 && p->dev == devtab[0].his) ! 150: return; /* hold on to the root */ ! 151: if(p->tag != n) { ! 152: debug("\tclr weird %d %d", n, p->tag); ! 153: errno = EIO; ! 154: dumpstate(); ! 155: return; ! 156: } ! 157: debug1("\tclear %d %s", p->tag, p->name); ! 158: if(p->fd != -1) { ! 159: close(p->fd); ! 160: p->fd = -1; ! 161: p->how = 0; ! 162: } ! 163: p->tag = p->dev = p->ino = 0; ! 164: if(p->name) ! 165: free(p->name); ! 166: p->name = 0; ! 167: alive--; ! 168: } ! 169: ! 170: opennf(p, fl) /* fl: 0-read, 1-write, 2-trunc */ ! 171: netf *p; ! 172: { int i; ! 173: if(p->fd != -1 && p->how == fl) ! 174: return(0); ! 175: if(fl == 2) { ! 176: errno = EPERM; ! 177: return(1); ! 178: } ! 179: i = open(p->name, fl); ! 180: if(p->fd != -1) ! 181: close(p->fd); ! 182: p->fd = i; ! 183: debug1("\topennf %s %d", p->name, p->fd); ! 184: if(p->fd == -1) ! 185: return(1); ! 186: p->how = fl; ! 187: return(0); ! 188: } ! 189: ! 190: truncnf(n) ! 191: long n; ! 192: { netf *p; ! 193: int fd; ! 194: p = gettag(n); ! 195: if(p == 0) { ! 196: debug("\ttrunc %d", n); ! 197: errno = EIO; ! 198: dumpstate(); ! 199: return; ! 200: } ! 201: if(p->fd != -1) ! 202: close(p->fd); ! 203: fd = creat(p->name, 0); ! 204: p->fd = fd; ! 205: p->how = 1; ! 206: } ! 207: ! 208: isroot(p) ! 209: netf *p; ! 210: { ! 211: debug2("\tisroot(dev=%d ino=%d), ourde=%d", p->dev, p->ino, ourdev(p->dev)); ! 212: return(p->ino == rootstat.st_ino && ourdev(p->dev) == rootstat.st_dev); ! 213: } ! 214: ! 215: prcmd(x) ! 216: struct senda *x; ! 217: { ! 218: debug1("got %s %d %d %d", cmdnames[x->cmd], major(x->dev), minor(x->dev), x->ino); ! 219: } ! 220: ! 221: getbuf(n) ! 222: { ! 223: if(n < buflen) ! 224: return; ! 225: if(buflen == 0) ! 226: buf = malloc(buflen = n); ! 227: else ! 228: buf = realloc(buf, buflen = n); ! 229: if(buf) ! 230: return; ! 231: debug("getbuf failed"); ! 232: leave(6); ! 233: } ! 234: ! 235: getnbuf(n) ! 236: long n; ! 237: { ! 238: if(n < nbuflen) ! 239: return; ! 240: if(nbuflen == 0) ! 241: nbuf = malloc(nbuflen = n); ! 242: else ! 243: nbuf = realloc(nbuf, nbuflen = n); ! 244: if(nbuf) ! 245: return; ! 246: debug("nbuf failed"); ! 247: leave(7); ! 248: } ! 249: /* the current name is a full path name, buf contains another component */ ! 250: fixnbuf(name, count, buf, flag) ! 251: char *name, *buf; ! 252: { int i, n; ! 253: for(i = 0; i < count && buf[i]; i++) ! 254: ; ! 255: count = i; ! 256: n = strlen(name); ! 257: getnbuf(n + count + 2); ! 258: strcpy(nbuf, name); ! 259: if(count > 2 || flag == NLINK || flag == NDEL) { ! 260: ok: ! 261: nbuf[n++] = '/'; ! 262: for(i = 0; i < count; i++) ! 263: nbuf[n++] = *buf++; ! 264: nbuf[n] = 0; ! 265: return; ! 266: } ! 267: if(count == 0) ! 268: return; ! 269: if(count == 1) ! 270: if(buf[0] == '.') ! 271: return; /* do we know that name is a directory? */ ! 272: else ! 273: goto ok; ! 274: if(buf[0] != '.' || buf[1] != '.') ! 275: goto ok; ! 276: while(n > 0 && nbuf[n] != '/') ! 277: n--; ! 278: nbuf[n] = 0; ! 279: if(nbuf[0] != '/') ! 280: strcpy(nbuf, "/.."); ! 281: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.