summaryrefslogtreecommitdiff
path: root/sys/src/cmd/fossil/flfmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/src/cmd/fossil/flfmt.c')
-rw-r--r--sys/src/cmd/fossil/flfmt.c572
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;
-}