diff options
Diffstat (limited to 'sys/src/cmd/fossil/flfmt.c')
-rw-r--r-- | sys/src/cmd/fossil/flfmt.c | 572 |
1 files changed, 0 insertions, 572 deletions
diff --git a/sys/src/cmd/fossil/flfmt.c b/sys/src/cmd/fossil/flfmt.c deleted file mode 100644 index b843388a0..000000000 --- a/sys/src/cmd/fossil/flfmt.c +++ /dev/null @@ -1,572 +0,0 @@ -#include "stdinc.h" -#include "dat.h" -#include "fns.h" -#include "flfmt9660.h" - -#define blockWrite _blockWrite /* hack */ - -static void usage(void); -static u64int fdsize(int fd); -static void partition(int fd, int bsize, Header *h); -static void writeBlock(int fd, uchar *buf, int bsize, ulong bn); -static u64int unittoull(char *s); -static u32int blockAlloc(int type, u32int tag); -static void blockRead(int part, u32int addr); -static void blockWrite(int part, u32int addr); -static void superInit(char *label, u32int root, uchar[VtScoreSize]); -static void rootMetaInit(Entry *e); -static u32int rootInit(Entry *e); -static void topLevel(char *name); -static int parseScore(uchar[VtScoreSize], char*); -static u32int ventiRoot(char*, char*); -static VtSession *z; - -#define TWID64 ((u64int)~(u64int)0) - -Disk *disk; -Fs *fs; -uchar *buf; -int bsize = 8*1024; -u64int qid = 1; -int iso9660off; -char *iso9660file; - -int -confirm(char *msg) -{ - char buf[100]; - int n; - - fprint(2, "%s [y/n]: ", msg); - n = read(0, buf, sizeof buf - 1); - if(n <= 0) - return 0; - if(buf[0] == 'y') - return 1; - return 0; -} - -void -main(int argc, char *argv[]) -{ - int fd, force; - Header h; - ulong bn; - Entry e; - char *label = "vfs"; - char *host = nil; - char *score = nil; - u32int root; - Dir *d; - - force = 0; - ARGBEGIN{ - default: - usage(); - case 'b': - bsize = unittoull(EARGF(usage())); - if(bsize == ~0) - usage(); - break; - case 'h': - host = EARGF(usage()); - break; - case 'i': - iso9660file = EARGF(usage()); - iso9660off = atoi(EARGF(usage())); - break; - case 'l': - label = EARGF(usage()); - break; - case 'v': - score = EARGF(usage()); - break; - - /* - * This is -y instead of -f because flchk has a - * (frequently used) -f option. I type flfmt instead - * of flchk all the time, and want to make it hard - * to reformat my file system accidentally. - */ - case 'y': - force = 1; - break; - }ARGEND - - if(argc != 1) - usage(); - - if(iso9660file && score) - vtFatal("cannot use -i with -v"); - - vtAttach(); - - fmtinstall('V', scoreFmt); - fmtinstall('R', vtErrFmt); - fmtinstall('L', labelFmt); - - fd = open(argv[0], ORDWR); - if(fd < 0) - vtFatal("could not open file: %s: %r", argv[0]); - - buf = vtMemAllocZ(bsize); - if(pread(fd, buf, bsize, HeaderOffset) != bsize) - vtFatal("could not read fs header block: %r"); - - if(headerUnpack(&h, buf) && !force - && !confirm("fs header block already exists; are you sure?")) - goto Out; - - if((d = dirfstat(fd)) == nil) - vtFatal("dirfstat: %r"); - - if(d->type == 'M' && !force - && !confirm("fs file is mounted via devmnt (is not a kernel device); are you sure?")) - goto Out; - - partition(fd, bsize, &h); - headerPack(&h, buf); - if(pwrite(fd, buf, bsize, HeaderOffset) < bsize) - vtFatal("could not write fs header: %r"); - - disk = diskAlloc(fd); - if(disk == nil) - vtFatal("could not open disk: %r"); - - if(iso9660file) - iso9660init(fd, &h, iso9660file, iso9660off); - - /* zero labels */ - memset(buf, 0, bsize); - for(bn = 0; bn < diskSize(disk, PartLabel); bn++) - blockWrite(PartLabel, bn); - - if(iso9660file) - iso9660labels(disk, buf, blockWrite); - - if(score) - root = ventiRoot(host, score); - else{ - rootMetaInit(&e); - root = rootInit(&e); - } - - superInit(label, root, vtZeroScore); - diskFree(disk); - - if(score == nil) - topLevel(argv[0]); - -Out: - vtDetach(); - exits(0); -} - -static u64int -fdsize(int fd) -{ - Dir *dir; - u64int size; - - dir = dirfstat(fd); - if(dir == nil) - vtFatal("could not stat file: %r"); - size = dir->length; - free(dir); - return size; -} - -static void -usage(void) -{ - fprint(2, "usage: %s [-b blocksize] [-h host] [-i file offset] " - "[-l label] [-v score] [-y] file\n", argv0); - exits("usage"); -} - -static void -partition(int fd, int bsize, Header *h) -{ - ulong nblock, ndata, nlabel; - ulong lpb; - - if(bsize % 512 != 0) - sysfatal("block size must be a multiple of 512 bytes"); - if(bsize > VtMaxLumpSize) - sysfatal("block size must be less than %d", VtMaxLumpSize); - - memset(h, 0, sizeof(*h)); - h->blockSize = bsize; - - lpb = bsize/LabelSize; - - nblock = fdsize(fd)/bsize; - - /* sanity check */ - if(nblock < (HeaderOffset*10)/bsize) - vtFatal("file too small"); - - h->super = (HeaderOffset + 2*bsize)/bsize; - h->label = h->super + 1; - ndata = ((u64int)lpb)*(nblock - h->label)/(lpb+1); - nlabel = (ndata + lpb - 1)/lpb; - h->data = h->label + nlabel; - h->end = h->data + ndata; - -} - -static u32int -tagGen(void) -{ - u32int tag; - - for(;;){ - tag = lrand(); - if(tag > RootTag) - break; - } - return tag; -} - -static void -entryInit(Entry *e) -{ - e->gen = 0; - e->dsize = bsize; - e->psize = bsize/VtEntrySize*VtEntrySize; - e->flags = VtEntryActive; - e->depth = 0; - e->size = 0; - memmove(e->score, vtZeroScore, VtScoreSize); - e->tag = tagGen(); - e->snap = 0; - e->archive = 0; -} - -static void -rootMetaInit(Entry *e) -{ - u32int addr; - u32int tag; - DirEntry de; - MetaBlock mb; - MetaEntry me; - - memset(&de, 0, sizeof(de)); - de.elem = vtStrDup("root"); - de.entry = 0; - de.gen = 0; - de.mentry = 1; - de.mgen = 0; - de.size = 0; - de.qid = qid++; - de.uid = vtStrDup("adm"); - de.gid = vtStrDup("adm"); - de.mid = vtStrDup("adm"); - de.mtime = time(0); - de.mcount = 0; - de.ctime = time(0); - de.atime = time(0); - de.mode = ModeDir | 0555; - - tag = tagGen(); - addr = blockAlloc(BtData, tag); - - /* build up meta block */ - memset(buf, 0, bsize); - mbInit(&mb, buf, bsize, bsize/100); - me.size = deSize(&de); - me.p = mbAlloc(&mb, me.size); - assert(me.p != nil); - dePack(&de, &me); - mbInsert(&mb, 0, &me); - mbPack(&mb); - blockWrite(PartData, addr); - deCleanup(&de); - - /* build up entry for meta block */ - entryInit(e); - e->flags |= VtEntryLocal; - e->size = bsize; - e->tag = tag; - localToGlobal(addr, e->score); -} - -static u32int -rootInit(Entry *e) -{ - ulong addr; - u32int tag; - - tag = tagGen(); - - addr = blockAlloc(BtDir, tag); - memset(buf, 0, bsize); - - /* root meta data is in the third entry */ - entryPack(e, buf, 2); - - entryInit(e); - e->flags |= VtEntryDir; - entryPack(e, buf, 0); - - entryInit(e); - entryPack(e, buf, 1); - - blockWrite(PartData, addr); - - entryInit(e); - e->flags |= VtEntryLocal|VtEntryDir; - e->size = VtEntrySize*3; - e->tag = tag; - localToGlobal(addr, e->score); - - addr = blockAlloc(BtDir, RootTag); - memset(buf, 0, bsize); - entryPack(e, buf, 0); - - blockWrite(PartData, addr); - - return addr; -} - - -static u32int -blockAlloc(int type, u32int tag) -{ - static u32int addr; - Label l; - int lpb; - - lpb = bsize/LabelSize; - - blockRead(PartLabel, addr/lpb); - if(!labelUnpack(&l, buf, addr % lpb)) - vtFatal("bad label: %r"); - if(l.state != BsFree) - vtFatal("want to allocate block already in use"); - l.epoch = 1; - l.epochClose = ~(u32int)0; - l.type = type; - l.state = BsAlloc; - l.tag = tag; - labelPack(&l, buf, addr % lpb); - blockWrite(PartLabel, addr/lpb); - return addr++; -} - -static void -superInit(char *label, u32int root, uchar score[VtScoreSize]) -{ - Super s; - - memset(buf, 0, bsize); - memset(&s, 0, sizeof(s)); - s.version = SuperVersion; - s.epochLow = 1; - s.epochHigh = 1; - s.qid = qid; - s.active = root; - s.next = NilBlock; - s.current = NilBlock; - strecpy(s.name, s.name+sizeof(s.name), label); - memmove(s.last, score, VtScoreSize); - - superPack(&s, buf); - blockWrite(PartSuper, 0); -} - -static u64int -unittoull(char *s) -{ - char *es; - u64int n; - - if(s == nil) - return TWID64; - n = strtoul(s, &es, 0); - if(*es == 'k' || *es == 'K'){ - n *= 1024; - es++; - }else if(*es == 'm' || *es == 'M'){ - n *= 1024*1024; - es++; - }else if(*es == 'g' || *es == 'G'){ - n *= 1024*1024*1024; - es++; - } - if(*es != '\0') - return TWID64; - return n; -} - -static void -blockRead(int part, u32int addr) -{ - if(!diskReadRaw(disk, part, addr, buf)) - vtFatal("read failed: %r"); -} - -static void -blockWrite(int part, u32int addr) -{ - if(!diskWriteRaw(disk, part, addr, buf)) - vtFatal("write failed: %r"); -} - -static void -addFile(File *root, char *name, uint mode) -{ - File *f; - - f = fileCreate(root, name, mode | ModeDir, "adm"); - if(f == nil) - vtFatal("could not create file: %s: %r", name); - fileDecRef(f); -} - -static void -topLevel(char *name) -{ - Fs *fs; - File *root; - - /* ok, now we can open as a fs */ - fs = fsOpen(name, z, 100, OReadWrite); - if(fs == nil) - vtFatal("could not open file system: %r"); - vtRLock(fs->elk); - root = fsGetRoot(fs); - if(root == nil) - vtFatal("could not open root: %r"); - addFile(root, "active", 0555); - addFile(root, "archive", 0555); - addFile(root, "snapshot", 0555); - fileDecRef(root); - if(iso9660file) - iso9660copy(fs); - vtRUnlock(fs->elk); - fsClose(fs); -} - -static int -ventiRead(uchar score[VtScoreSize], int type) -{ - int n; - - n = vtRead(z, score, type, buf, bsize); - if(n < 0) - vtFatal("ventiRead %V (%d) failed: %R", score, type); - vtZeroExtend(type, buf, n, bsize); - return n; -} - -static u32int -ventiRoot(char *host, char *s) -{ - int i, n; - uchar score[VtScoreSize]; - u32int addr, tag; - DirEntry de; - MetaBlock mb; - MetaEntry me; - Entry e; - VtRoot root; - - if(!parseScore(score, s)) - vtFatal("bad score '%s'", s); - - if((z = vtDial(host, 0)) == nil - || !vtConnect(z, nil)) - vtFatal("connect to venti: %R"); - - tag = tagGen(); - addr = blockAlloc(BtDir, tag); - - ventiRead(score, VtRootType); - if(!vtRootUnpack(&root, buf)) - vtFatal("corrupted root: vtRootUnpack"); - n = ventiRead(root.score, VtDirType); - - /* - * Fossil's vac archives start with an extra layer of source, - * but vac's don't. - */ - if(n <= 2*VtEntrySize){ - if(!entryUnpack(&e, buf, 0)) - vtFatal("bad root: top entry"); - n = ventiRead(e.score, VtDirType); - } - - /* - * There should be three root sources (and nothing else) here. - */ - for(i=0; i<3; i++){ - if(!entryUnpack(&e, buf, i) - || !(e.flags&VtEntryActive) - || e.psize < 256 - || e.dsize < 256) - vtFatal("bad root: entry %d", i); - fprint(2, "%V\n", e.score); - } - if(n > 3*VtEntrySize) - vtFatal("bad root: entry count"); - - blockWrite(PartData, addr); - - /* - * Maximum qid is recorded in root's msource, entry #2 (conveniently in e). - */ - ventiRead(e.score, VtDataType); - if(!mbUnpack(&mb, buf, bsize)) - vtFatal("bad root: mbUnpack"); - meUnpack(&me, &mb, 0); - if(!deUnpack(&de, &me)) - vtFatal("bad root: dirUnpack"); - if(!de.qidSpace) - vtFatal("bad root: no qidSpace"); - qid = de.qidMax; - - /* - * Recreate the top layer of source. - */ - entryInit(&e); - e.flags |= VtEntryLocal|VtEntryDir; - e.size = VtEntrySize*3; - e.tag = tag; - localToGlobal(addr, e.score); - - addr = blockAlloc(BtDir, RootTag); - memset(buf, 0, bsize); - entryPack(&e, buf, 0); - blockWrite(PartData, addr); - - return addr; -} - -static int -parseScore(uchar *score, char *buf) -{ - int i, c; - - memset(score, 0, VtScoreSize); - - if(strlen(buf) < VtScoreSize*2) - return 0; - for(i=0; i<VtScoreSize*2; i++){ - if(buf[i] >= '0' && buf[i] <= '9') - c = buf[i] - '0'; - else if(buf[i] >= 'a' && buf[i] <= 'f') - c = buf[i] - 'a' + 10; - else if(buf[i] >= 'A' && buf[i] <= 'F') - c = buf[i] - 'A' + 10; - else - return 0; - - if((i & 1) == 0) - c <<= 4; - - score[i>>1] |= c; - } - return 1; -} |