|
|
1.1 ! root 1: #include <libc.h> ! 2: #include "worm.h" ! 3: #include "sym.h" ! 4: #include <sys/types.h> ! 5: #include <sys/stat.h> ! 6: #include <pwd.h> ! 7: #include <grp.h> ! 8: ! 9: Inode *inodebase, *inext; ! 10: char *namebase, *cnext; ! 11: ! 12: main(argc, argv) ! 13: char **argv; ! 14: { ! 15: Superblock s; ! 16: char *e; ! 17: char *dev = "/dev/worm0"; ! 18: register c, j; ! 19: register Inode *from, *to; ! 20: extern char *optarg; ! 21: extern int optind; ! 22: char *vlk(); ! 23: int cmp(); ! 24: int fd; ! 25: int verbose = 0; ! 26: char buf[512]; ! 27: long ni, nc; ! 28: ! 29: while((c = getopt(argc, argv, "vf:")) != -1) ! 30: switch(c) ! 31: { ! 32: case 'v': verbose = 1; break; ! 33: case 'f': dev = optarg; break; ! 34: case '?': usage(); ! 35: } ! 36: dev = mapdev(dev); ! 37: if((s.fd = open(dev, 0)) < 0){ ! 38: perror(dev); ! 39: exit(1); ! 40: } ! 41: if(e = openinode(&s, SPIN_DOWN)){ ! 42: fprint(2, "%s: %s\n", dev, e); ! 43: exit(1); ! 44: } ! 45: if(s.version != VLINK){ ! 46: fprint(2, "%s: not a vlink disk, no action taken.\n", s.vol_id); ! 47: exit(1); ! 48: } ! 49: if(optind != argc-1) ! 50: usage(); ! 51: if(strcmp(argv[optind], s.vol_id)){ ! 52: fprint(2, "wanted volid '%s'; got '%s'\n", argv[optind], s.vol_id); ! 53: exit(1); ! 54: } ! 55: if(verbose) ! 56: print("%d inodes\n", numinodes); ! 57: if((inodebase = (Inode *)malloc(s.blocksize+(int)numinodes*sizeof(Inode))) == 0){ ! 58: fprint(2, "malloc of %ld inodes failed\n", numinodes); ! 59: exit(2); ! 60: } ! 61: if((namebase = malloc(s.blocksize+(int)numnamechars+(int)numinodes)) == 0){ ! 62: fprint(2, "malloc of %ld chars failed\n", numnamechars); ! 63: exit(2); ! 64: } ! 65: inext = inodebase; ! 66: cnext = namebase; ! 67: s.ninodes = 0; ! 68: s.nextsb = 2; ! 69: if(e = vlk(&s)){ ! 70: fprint(2, "%s: %s\n", dev, e); ! 71: exit(1); ! 72: } ! 73: j = inext-inodebase; ! 74: if(verbose) ! 75: print("%d in base\n", j); ! 76: qsort((char *)inodebase, j, sizeof(*inodebase), cmp); ! 77: for(to = inodebase, from = inodebase+1; from < inext; from++) ! 78: if(strcmp(from->name.o+namebase, from[-1].name.o+namebase)) ! 79: *to++ = from[-1]; ! 80: else { ! 81: while((++from < inext) && (strcmp(from->name.o+namebase, from[-1].name.o+namebase) == 0)) ! 82: ; ! 83: } ! 84: if(from == inext) ! 85: *to++ = from[-1]; ! 86: inext = to; ! 87: j = inext-inodebase; ! 88: sprint(buf, "/usr/worm/tmp/%s", s.vol_id); ! 89: if((fd = creat(buf, 0666)) < 0){ ! 90: perror(buf); ! 91: exit(1); ! 92: } ! 93: /**/ ! 94: for(from = inodebase; from < inext; from++) ! 95: from->block++; ! 96: /**/ ! 97: ni = j; ! 98: nc = cnext-namebase; ! 99: write(fd, (char *)&s.ctime, 4); ! 100: write(fd, (char *)&ni, 4); ! 101: write(fd, (char *)inodebase, (int)ni*sizeof(Inode)); ! 102: write(fd, (char *)&nc, 4); ! 103: write(fd, namebase, (int)nc); ! 104: exit(0); ! 105: } ! 106: ! 107: usage() ! 108: { ! 109: fprint(2, "Usage: worm tmpdir [-fdevice] vol_id\n"); ! 110: exit(2); ! 111: } ! 112: ! 113: cmp(a, b) ! 114: Inode *a, *b; ! 115: { ! 116: return(strcmp(namebase+a->name.o, namebase+b->name.o)); ! 117: } ! 118: ! 119: char * ! 120: vlk(s) ! 121: register Superblock *s; ! 122: { ! 123: register Inode *i; ! 124: short fd = s->fd; ! 125: register long j; ! 126: long blk = -1; /* shouldn't be accessed first time through */ ! 127: char *b; ! 128: long nb; ! 129: Inode *iend; ! 130: static char buf[64]; ! 131: ! 132: if((b = malloc(s->blocksize)) == 0){ ! 133: sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize); ! 134: return(buf); ! 135: } ! 136: for(;;){ ! 137: if(s->magic != SMAGIC){ ! 138: fprint(2, "bad Superblock at %ld\n", blk); ! 139: exit(1); ! 140: } ! 141: if(s->ninodes){ ! 142: nb = (s->ninodes+IPERB-1)/IPERB; ! 143: Seek(s, s->binodes); ! 144: if(Read(s, (char *)inext, nb)) ! 145: goto skip; ! 146: j = cnext-namebase; ! 147: for(i = inext, iend = i+s->ninodes; i < iend; i++) ! 148: i->name.o += j; ! 149: inext += s->ninodes; ! 150: nb = (s->ninochars+s->blocksize-1)/s->blocksize; ! 151: if(Read(s, cnext, nb)) ! 152: goto skip; ! 153: cnext += (s->ninochars+1)&~1; ! 154: } ! 155: skip: ! 156: blk = s->nextsb; ! 157: Seek(s, blk); ! 158: if(Read(s, b, 1L)) ! 159: break; ! 160: *s = *((Superblock *)b); ! 161: s->fd = fd; ! 162: if(s->myblock == 0) ! 163: s->myblock = blk; ! 164: } ! 165: free(b); ! 166: return((char *)0); ! 167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.