|
|
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: /* find the next different one */ ! 79: while(strcmp(from->name.o+namebase, to->name.o+namebase) == 0){ ! 80: if(to->block < from->block) ! 81: *to = *from; /* want the last one */ ! 82: if(++from >= inext) ! 83: goto done; ! 84: } ! 85: *++to = *from; ! 86: } ! 87: done: ! 88: inext = to; ! 89: j = inext-inodebase; ! 90: sprint(buf, "/usr/worm/tmp/%s", s.vol_id); ! 91: if((fd = creat(buf, 0666)) < 0){ ! 92: perror(buf); ! 93: exit(1); ! 94: } ! 95: ni = j; ! 96: nc = cnext-namebase; ! 97: write(fd, (char *)&s.ctime, 4); ! 98: write(fd, (char *)&ni, 4); ! 99: write(fd, (char *)inodebase, (int)ni*sizeof(Inode)); ! 100: write(fd, (char *)&nc, 4); ! 101: write(fd, namebase, (int)nc); ! 102: exit(0); ! 103: } ! 104: ! 105: usage() ! 106: { ! 107: fprint(2, "Usage: worm tmpdir [-fdevice] vol_id\n"); ! 108: exit(2); ! 109: } ! 110: ! 111: cmp(a, b) ! 112: Inode *a, *b; ! 113: { ! 114: return(strcmp(namebase+a->name.o, namebase+b->name.o)); ! 115: } ! 116: ! 117: char * ! 118: vlk(s) ! 119: register Superblock *s; ! 120: { ! 121: register Inode *i; ! 122: short fd = s->fd; ! 123: register long j; ! 124: long blk = -1; /* shouldn't be accessed first time through */ ! 125: char *b; ! 126: long nb; ! 127: Inode *iend; ! 128: static char buf[64]; ! 129: ! 130: if((b = malloc(s->blocksize)) == 0){ ! 131: sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize); ! 132: return(buf); ! 133: } ! 134: for(;;){ ! 135: if(s->magic != SMAGIC){ ! 136: fprint(2, "bad Superblock at %ld\n", blk); ! 137: exit(1); ! 138: } ! 139: if(s->ninodes){ ! 140: nb = (s->ninodes+IPERB-1)/IPERB; ! 141: Seek(s, s->binodes); ! 142: if(Read(s, (char *)inext, nb)) ! 143: goto skip; ! 144: j = cnext-namebase; ! 145: for(i = inext, iend = i+s->ninodes; i < iend; i++) ! 146: i->name.o += j; ! 147: inext += s->ninodes; ! 148: nb = (s->ninochars+s->blocksize-1)/s->blocksize; ! 149: if(Read(s, cnext, nb)) ! 150: goto skip; ! 151: cnext += (s->ninochars+1)&~1; ! 152: } ! 153: skip: ! 154: blk = s->nextsb; ! 155: Seek(s, blk); ! 156: if(Read(s, b, 1L)) ! 157: break; ! 158: *s = *((Superblock *)b); ! 159: s->fd = fd; ! 160: if(s->myblock == 0) ! 161: s->myblock = blk; ! 162: } ! 163: free(b); ! 164: return((char *)0); ! 165: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.