changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > ventivac / changeset: vacput can now write changes compared to a base archive.

changeset 73: ced42c12c2d2
parent 72: 26d55179d5d0
child 74: f09fa771561e
author: Mechiel Lukkien <mechiel@ueber.net>
date: Tue, 17 Jul 2007 16:34:20 +0200
files: appl/cmd/vacget.b appl/cmd/vacput.b man/1/vacget
description: vacput can now write changes compared to a base archive.

new usage:
-d for debug has been changed to -D for debug
-d tag:score enables comparing to the base archive.

this also works with vacput -r.
a check for qid version should be made as well.
an option -q for writing only the new part of an append-only file is missing as of yet.
     1.1--- a/appl/cmd/vacget.b	Sat Jul 14 13:46:53 2007 +0200
     1.2+++ b/appl/cmd/vacget.b	Tue Jul 17 16:34:20 2007 +0200
     1.3@@ -25,7 +25,7 @@
     1.4 };
     1.5 
     1.6 addr := "net!$venti!venti";
     1.7-dflag := vflag := pflag := tflag := 0;
     1.8+Dflag := vflag := pflag := tflag := 0;
     1.9 session: ref Session;
    1.10 
    1.11 init(nil: ref Draw->Context, args: list of string)
    1.12@@ -42,11 +42,11 @@
    1.13 	vac->init();
    1.14 
    1.15 	arg->init(args);
    1.16-	arg->setusage(sprint("%s [-dptv] [-a addr] [tag:]score", arg->progname()));
    1.17+	arg->setusage(sprint("%s [-Dptv] [-a addr] [tag:]score", arg->progname()));
    1.18 	while((c := arg->opt()) != 0)
    1.19 		case c {
    1.20 		'a' =>	addr = arg->earg();
    1.21-		'd' =>	dflag++;
    1.22+		'D' =>	Dflag++;
    1.23 			vac->dflag++;
    1.24 		'p' =>	pflag++;
    1.25 		't' =>	tflag++;
    1.26@@ -194,6 +194,6 @@
    1.27 
    1.28 say(s: string)
    1.29 {
    1.30-	if(dflag)
    1.31+	if(Dflag)
    1.32 		warn(s);
    1.33 }
     2.1--- a/appl/cmd/vacput.b	Sat Jul 14 13:46:53 2007 +0200
     2.2+++ b/appl/cmd/vacput.b	Tue Jul 17 16:34:20 2007 +0200
     2.3@@ -21,8 +21,8 @@
     2.4 
     2.5 print, sprint, fprint, fildes: import sys;
     2.6 Score, Session: import venti;
     2.7-Roottype, Dirtype, Pointertype0, Datatype: import venti;
     2.8-Root, Entry, Direntry, Metablock, Metaentry, Entrysize, File, Sink, MSink: import vac;
     2.9+Rootversion, Roottype, Dirtype, Pointertype0, Datatype, Rootsize: import venti;
    2.10+Rootversionvar, Root, Entry, Direntry, Metablock, Metaentry, Entrysize, File, Sink, MSink, Vacdir: import vac;
    2.11 Rcfg, Rfile: import rabin;
    2.12 
    2.13 Vacput: module {
    2.14@@ -30,10 +30,12 @@
    2.15 };
    2.16 
    2.17 addr := "net!$venti!venti";
    2.18-dflag, vflag, rflag: int;
    2.19+Dflag, vflag, rflag: int;
    2.20 blocksize := vac->Dsize;
    2.21 session: ref Session;
    2.22 name := "vac";
    2.23+basetag: string;
    2.24+basescore: Score;
    2.25 rcfg: ref Rcfg;
    2.26 blockmin, blockmax: int;
    2.27 
    2.28@@ -62,13 +64,25 @@
    2.29 	blockmax = 32*1024;
    2.30 
    2.31 	arg->init(args);
    2.32-	arg->setusage(sprint("%s [-drv] [-a addr] [-b blocksize] [-n name] path ...", arg->progname()));
    2.33+	arg->setusage(sprint("%s [-Drv] [-d base] [-a addr] [-b blocksize] [-n name] path ...", arg->progname()));
    2.34 	while((c := arg->opt()) != 0)
    2.35 		case c {
    2.36 		'a' =>	addr = arg->earg();
    2.37 		'b' =>	blocksize = int arg->earg();
    2.38 		'n' =>	name = arg->earg();
    2.39-		'd' =>	dflag++;
    2.40+		'd' =>	(tag, scorestr) := str->splitstrr(arg->earg(), ":");
    2.41+			if(tag != nil)
    2.42+				tag = tag[:len tag-1];
    2.43+			if(tag == nil)
    2.44+				tag = "vac";
    2.45+			if(tag != "vac")
    2.46+				error("bad score type: "+tag);
    2.47+			basetag = tag;
    2.48+			ok: int;
    2.49+			(ok, basescore) = Score.parse(scorestr);
    2.50+			if(ok != 0)
    2.51+				error("bad score: "+scorestr);
    2.52+		'D' =>	Dflag++;
    2.53 			vac->dflag++;
    2.54 			rabin->debug++;
    2.55 		'r' =>	rflag++;
    2.56@@ -98,6 +112,21 @@
    2.57 		error(sprint("handshake: %r"));
    2.58 	say("have handshake");
    2.59 
    2.60+	vd: ref Vacdir;
    2.61+	if(basetag != nil) {
    2.62+		err: string;
    2.63+		(vd, nil, err) = vac->vdroot(session, basescore);
    2.64+		if(err != nil)
    2.65+			error("opening base score: "+err);
    2.66+
    2.67+		d := session.read(basescore, Roottype, Rootsize);
    2.68+		if(d == nil)
    2.69+			error("reading base root block: "+err);
    2.70+		r := Root.unpack(d);
    2.71+		if(rflag && r.version != Rootversionvar || !rflag && r.version != Rootversion)
    2.72+			error("old archive not of same type as new archive");
    2.73+	}
    2.74+
    2.75 	topde: ref Direntry;
    2.76 	if(len args == 1 && ((nil, d) := sys->stat(hd args)).t0 == 0 && d.mode&Sys->DMDIR) {
    2.77 		topde = Direntry.mk(d);
    2.78@@ -114,7 +143,7 @@
    2.79 	s := Sink.new(session, blocksize);
    2.80 	ms := MSink.new(session, blocksize);
    2.81 	for(; args != nil; args = tl args)
    2.82-		writepath(hd args, s, ms);
    2.83+		writepath(hd args, s, ms, vd);
    2.84 	say("tree written");
    2.85 
    2.86 	e0 := s.finish();
    2.87@@ -142,7 +171,6 @@
    2.88 	root := Root.new(name, "vac", tscore, blocksize, nil);
    2.89 	if(rflag) {
    2.90 		root.version = Vac->Rootversionvar;
    2.91-		root.rtype = "rvac";
    2.92 		root.blocksize = 0;
    2.93 	}
    2.94 	rd := root.pack();
    2.95@@ -152,12 +180,12 @@
    2.96 	if(rok < 0)
    2.97 		error(sprint("writing root score: %r"));
    2.98 	say("root written, "+rscore.text());
    2.99-	print("vac:%s\n", rscore.text());
   2.100+	print("%s:%s\n", root.rtype, rscore.text());
   2.101 	if(session.sync() < 0)
   2.102 		error(sprint("syncing server: %r"));
   2.103 }
   2.104 
   2.105-writepath(path: string, s: ref Sink, ms: ref MSink)
   2.106+writepath(path: string, s: ref Sink, ms: ref MSink, vd: ref Vacdir)
   2.107 {
   2.108 	if(vflag)
   2.109 		print("%s\n", path);
   2.110@@ -184,6 +212,8 @@
   2.111 say("writepath: file is dir");
   2.112 		ns := Sink.new(session, blocksize);
   2.113 		nms := MSink.new(session, blocksize);
   2.114+
   2.115+		nvd := vdopendir(vd, dir.name);
   2.116 		for(;;) {
   2.117 			(n, dirs) := sys->dirread(fd);
   2.118 			if(n == 0)
   2.119@@ -193,7 +223,7 @@
   2.120 			for(i := 0; i < len dirs; i++) {
   2.121 				d := dirs[i];
   2.122 				npath := path+"/"+d.name;
   2.123-				writepath(npath, ns, nms);
   2.124+				writepath(npath, ns, nms, nvd);
   2.125 			}
   2.126 		}
   2.127 		e = ns.finish();
   2.128@@ -203,10 +233,21 @@
   2.129 		if(me == nil)
   2.130 			error(sprint("error flushing metasink for %s: %r", path));
   2.131 	} else {
   2.132-say("writepath: file is normale file");
   2.133-		e = writefile(path, fd);
   2.134-		if(e == nil)
   2.135-			error(sprint("error flushing filesink for %s: %r", path));
   2.136+say("writepath: file is normal file");
   2.137+		nde: ref Direntry;
   2.138+		if(vd != nil)
   2.139+			nde = vd.walk(dir.name);
   2.140+		if(nde != nil)
   2.141+			(e, nil) = vd.open(nde);
   2.142+		# xxx use qid version
   2.143+		if(e != nil && (nde.mtime != dir.mtime || e.size != dir.length || nde.qid != dir.qid.path))
   2.144+			e = nil;
   2.145+		if(e == nil) {
   2.146+say("writepath: file has changed or is new, writing it");
   2.147+			e = writefile(path, fd);
   2.148+			if(e == nil)
   2.149+				error(sprint("error flushing filesink for %s: %r", path));
   2.150+		}
   2.151 	}
   2.152 say("writepath: wrote path, "+e.score.text());
   2.153 
   2.154@@ -278,6 +319,19 @@
   2.155 	return f.finish();
   2.156 }
   2.157 
   2.158+vdopendir(vd: ref Vacdir, elem: string): ref Vacdir
   2.159+{
   2.160+	if(vd == nil)
   2.161+		return nil;
   2.162+	de := vd.walk(elem);
   2.163+	if(de == nil)
   2.164+		return nil;
   2.165+	(e, me) := vd.open(de);
   2.166+	if(e == nil || me == nil)
   2.167+		return nil;
   2.168+	return Vacdir.new(session, e, me);
   2.169+}
   2.170+
   2.171 user(): string
   2.172 {
   2.173 	if((fd := sys->open("/dev/user", Sys->OREAD)) != nil
   2.174@@ -299,6 +353,6 @@
   2.175 
   2.176 say(s: string)
   2.177 {
   2.178-	if(dflag)
   2.179+	if(Dflag)
   2.180 		warn(s);
   2.181 }
     3.1--- a/man/1/vacget	Sat Jul 14 13:46:53 2007 +0200
     3.2+++ b/man/1/vacget	Tue Jul 17 16:34:20 2007 +0200
     3.3@@ -4,7 +4,7 @@
     3.4 .SH SYNOPSIS
     3.5 .B vacget
     3.6 [
     3.7-.B -vdpt
     3.8+.B -Dvpt
     3.9 ] [
    3.10 .B -a
    3.11 .I addr
    3.12@@ -13,7 +13,7 @@
    3.13 .br
    3.14 .B vacput
    3.15 [
    3.16-.B -vdr
    3.17+.B -Dvr
    3.18 ] [
    3.19 .B -a
    3.20 .I addr
    3.21@@ -21,6 +21,9 @@
    3.22 .B -b
    3.23 .I blocksize
    3.24 ] [
    3.25+.B -d
    3.26+.I tag:score
    3.27+] [
    3.28 .B -n
    3.29 .I name
    3.30 ]
    3.31@@ -34,9 +37,15 @@
    3.32 .I paths
    3.33 are walked recursively and all files and directories written to the archive.  Temporary files, i.e. those with the
    3.34 .B DMTMP
    3.35-bit set, are skipped.  Writing only changed files relative to a previously written archive is not implemented.
    3.36+bit set, are skipped.  With
    3.37+.B -d
    3.38+a base archive can be specified.  Files that have not changed are assumed to be present in venti and included in the new archive without writing their contents to venti.
    3.39 .TP
    3.40-.B -d
    3.41+.BI -d " tag:score"
    3.42+The archive denoted by
    3.43+.I tag:score
    3.44+is used as base archive while writing.  Only the contents of files that have been modified are written to venti before inclusion in the new archive.  Only for vacput.
    3.45+.B -D
    3.46 Print debug messages.
    3.47 .TP
    3.48 .B -p