Browse Source

Plan 9 from Bell Labs 2003-10-23

David du Colombier 20 years ago
parent
commit
9da0c704f9

+ 9 - 8
dist/replica/plan9.db

@@ -220,7 +220,7 @@
 386/bin/ed - 775 sys sys 1064598133 91839
 386/bin/eqn - 775 sys sys 1048745036 240244
 386/bin/execnet - 775 sys sys 1064598134 173621
-386/bin/exportfs - 775 sys sys 1064598135 146671
+386/bin/exportfs - 775 sys sys 1066823148 161831
 386/bin/ext2srv - 775 sys sys 1064598136 176120
 386/bin/faces - 775 sys sys 1064598137 191011
 386/bin/factor - 775 sys sys 1064598138 59887
@@ -231,7 +231,7 @@
 386/bin/fossil/conf - 775 sys sys 1056364255 1497
 386/bin/fossil/flchk - 775 sys sys 1064598141 232263
 386/bin/fossil/flfmt - 775 sys sys 1064598142 230228
-386/bin/fossil/fossil - 775 sys sys 1066098149 345764
+386/bin/fossil/fossil - 775 sys sys 1066848944 345758
 386/bin/freq - 775 sys sys 1064598145 60197
 386/bin/fs - 20000000775 sys sys 954380769 0
 386/bin/fs/32vfs - 775 sys sys 1064598146 95907
@@ -4849,7 +4849,7 @@ sys/man/4/cfs - 664 sys sys 1015024813 1758
 sys/man/4/consolefs - 664 sys sys 1022112154 3751
 sys/man/4/dossrv - 664 sys sys 1015024813 4176
 sys/man/4/execnet - 664 sys sys 1019866708 1069
-sys/man/4/exportfs - 664 sys sys 1018386776 3746
+sys/man/4/exportfs - 664 sys sys 1066826682 4336
 sys/man/4/ext2srv - 664 sys sys 1055692986 2409
 sys/man/4/factotum - 664 sys sys 1053127875 14460
 sys/man/4/fossil - 664 sys sys 1055701130 9208
@@ -7235,10 +7235,11 @@ sys/src/cmd/execnet/main.c - 664 sys sys 1019861330 657
 sys/src/cmd/execnet/mkfile - 664 sys sys 1032059543 208
 sys/src/cmd/execnet/note.c - 664 sys sys 1019855740 2315
 sys/src/cmd/exportfs - 20000000775 sys sys 988249971 0
-sys/src/cmd/exportfs/exportfs.c - 664 sys sys 1055698967 15466
-sys/src/cmd/exportfs/exportfs.h - 664 sys sys 1017166329 2435
-sys/src/cmd/exportfs/exportsrv.c - 664 sys sys 1036979222 11202
-sys/src/cmd/exportfs/mkfile - 664 sys sys 1036979221 204
+sys/src/cmd/exportfs/exportfs.c - 664 sys sys 1066823092 15669
+sys/src/cmd/exportfs/exportfs.h - 664 sys sys 1066823091 2800
+sys/src/cmd/exportfs/exportsrv.c - 664 sys sys 1066823092 11325
+sys/src/cmd/exportfs/mkfile - 664 sys sys 1066825703 194
+sys/src/cmd/exportfs/pattern.c - 664 sys sys 1066823092 2960
 sys/src/cmd/ext2srv - 20000000775 sys sys 1055687763 0
 sys/src/cmd/ext2srv/chat.c - 664 sys sys 1055687746 827
 sys/src/cmd/ext2srv/dat.h - 664 sys sys 1055687746 5275
@@ -7308,7 +7309,7 @@ sys/src/cmd/fossil/dump.c - 664 sys sys 1042005506 1340
 sys/src/cmd/fossil/epoch.c - 664 sys sys 1045600021 997
 sys/src/cmd/fossil/error.c - 664 sys sys 1042005507 1367
 sys/src/cmd/fossil/error.h - 664 sys sys 1042005507 744
-sys/src/cmd/fossil/file.c - 664 sys sys 1066098099 28004
+sys/src/cmd/fossil/file.c - 664 sys sys 1066848926 28000
 sys/src/cmd/fossil/flchk.c - 664 sys sys 1061530720 14296
 sys/src/cmd/fossil/flfmt.c - 664 sys sys 1061530720 10358
 sys/src/cmd/fossil/flproto - 664 sys sys 1042005508 210

+ 11 - 0
dist/replica/plan9.log

@@ -13917,3 +13917,14 @@
 1066618935 2 c sys/src/9/pc/ether2114x.c - 664 sys sys 1066618082 41227
 1066618935 3 c sys/src/boot/pc/ether2114x.c - 664 sys sys 1066618033 37048
 1066737677 0 c sys/src/9/port/devtls.c - 664 sys sys 1066737478 45222
+1066824077 0 c 386/bin/exportfs - 775 sys sys 1066823148 161831
+1066824077 1 c sys/man/4/exportfs - 664 sys sys 1066823072 4333
+1066824077 2 c sys/src/cmd/exportfs/exportfs.c - 664 sys sys 1066823092 15669
+1066824077 3 c sys/src/cmd/exportfs/exportfs.h - 664 sys sys 1066823091 2800
+1066824077 4 c sys/src/cmd/exportfs/exportsrv.c - 664 sys sys 1066823092 11325
+1066824077 5 c sys/src/cmd/exportfs/mkfile - 664 sys sys 1066823091 194
+1066824077 6 a sys/src/cmd/exportfs/pattern.c - 664 sys sys 1066823092 2960
+1066825879 0 c sys/src/cmd/exportfs/mkfile - 664 sys sys 1066825703 194
+1066827680 0 c sys/man/4/exportfs - 664 sys sys 1066826682 4336
+1066849305 0 c 386/bin/fossil/fossil - 775 sys sys 1066848944 345758
+1066849305 1 c sys/src/cmd/fossil/file.c - 664 sys sys 1066848926 28000

+ 29 - 1
sys/man/4/exportfs

@@ -20,6 +20,10 @@ exportfs, srvfs \- network file server plumbing
 ] [
 .B -A announce
 ]
+[
+.B -p
+.I patternfile
+]
 .PP
 .B srvfs
 [
@@ -31,7 +35,7 @@ exportfs, srvfs \- network file server plumbing
 ]
 [
 .B -p
-.I filter
+.I perm
 ]
 .I name
 .I path
@@ -106,6 +110,21 @@ to log all 9P traffic to
 .BR /tmp/exportdb ).
 .PP
 The
+.BI  -p patternfile
+option restricts the set of exported files.
+.I Patternfile
+contains one regular expression per line,
+to be matched against path names
+relative to the current working directory
+and starting with
+.BR ./ .
+For a file to be exported, all lines with a prefix
+.B +
+must match and all those with prefix
+.B -
+must not match.
+.PP
+The
 .B -e
 option specifies the encryption and authentication algorithms to use for
 encrypting the wire traffic.  The defaults are
@@ -169,6 +188,15 @@ filter specifies an announce string when exportfs is used in combination
 with aan.  The announce string identifies the network and network 
 protocol to use for aan connections.
 .SH EXAMPLES
+To export the archive of one user for one month, except for secrets,
+.IP
+.EX
+cd /n/dump
+echo '+ ^\.(/2003(/10..(/usr(/glenda/?)?)?)?)?' > /tmp/pattern
+echo '- \.(aes|pgp)$' >> /tmp/pattern
+exportfs -p /tmp/pattern
+.EE
+.LP
 Use
 .I srvfs
 to enable mounting of an FTP file system (see

+ 17 - 2
sys/src/cmd/exportfs/exportfs.c

@@ -47,8 +47,9 @@ int	srvfd = -1;
 int	nonone = 1;
 char	*filterp;
 char	*ealgs = "rc4_256 sha1";
-char *aanfilter = "/bin/aan";
-int encproto = Encnone;
+char	*aanfilter = "/bin/aan";
+int	encproto = Encnone;
+
 static void	mksecret(char *, uchar *);
 static int localread9pmsg(int, void *, uint, ulong *);
 static char *anstring  = "tcp!*!0";
@@ -136,6 +137,10 @@ main(int argc, char **argv)
 		srv = "/";
 		break;
 
+	case 'p':
+		patternfile = EARGF(usage());
+		break;
+
 	case 'A':
 		anstring = EARGF(usage());
 		break;
@@ -145,6 +150,8 @@ main(int argc, char **argv)
 	}ARGEND
 	USED(argc, argv);
 
+	exclusions();
+
 	if(dbg) {
 		n = create(dbfile, OWRITE|OTRUNC, 0666);
 		dup(n, DFD);
@@ -417,6 +424,10 @@ freefid(int nr)
 				freefile(f->f);
 				f->f = nil;
 			}
+			if(f->dir){
+				free(f->dir);
+				f->dir = nil;
+			}
 			*l = f->next;
 			f->next = fidfree;
 			fidfree = f;
@@ -539,6 +550,10 @@ file(File *parent, char *name)
 	DEBUG(DFD, "\tfile: 0x%p %s name %s\n", parent, parent->name, name);
 
 	path = makepath(parent, name);
+	if(patternfile != nil && excludefile(path)){
+		free(path);
+		return nil;
+	}
 	dir = dirstat(path);
 	free(path);
 	if(dir == nil)

+ 13 - 2
sys/src/cmd/exportfs/exportfs.h

@@ -30,6 +30,13 @@ struct Fid
 	int	nr;		/* fid number */
 	int	mid;		/* Mount id */
 	Fid	*next;		/* hash link */
+
+	/* for preaddir -- ARRGH! */
+	Dir	*dir;		/* buffer for reading directories */
+	int	ndir;		/* number of entries in dir */
+	int	cdir;		/* number of consumed entries in dir */
+	int	gdir;		/* glue index */
+	vlong	offset;		/* offset in virtual directory */
 };
 
 struct File
@@ -92,7 +99,8 @@ Extern char	psmap[Npsmpt];
 Extern Qidtab	*qidtab[Nqidtab];
 Extern ulong	messagesize;
 Extern char	Enomem[];
-Extern int		srvfd;
+Extern int	srvfd;
+Extern char*	patternfile;
 
 /* File system protocol service procedures */
 void Xattach(Fsrpc*);
@@ -130,4 +138,7 @@ Qidtab* uniqueqid(Dir*);
 void	freeqid(Qidtab*);
 char*	estrdup(char*);
 void*	emallocz(uint);
-int		readmessage(int, char*, int);
+int	readmessage(int, char*, int);
+void	exclusions(void);
+int	excludefile(char*);
+int	preaddir(Fid*, uchar*, int, vlong);

+ 5 - 1
sys/src/cmd/exportfs/exportsrv.c

@@ -592,6 +592,7 @@ slaveopen(Fsrpc *p)
 
 	DEBUG(DFD, "\topen: fd %d\n", f->fid);
 	f->mode = work->mode;
+	f->offset = 0;
 	rhdr.iounit = getiounit(f->fid);
 	rhdr.qid = f->f->qid;
 	reply(work, &rhdr, 0);
@@ -622,7 +623,10 @@ slaveread(Fsrpc *p)
 		fatal(Enomem);
 
 	/* can't just call pread, since directories must update the offset */
-	r = pread(f->fid, data, n, work->offset);
+	if(patternfile != nil && (f->f->qid.type&QTDIR))
+		r = preaddir(f, (uchar*)data, n, work->offset);
+	else
+		r = pread(f->fid, data, n, work->offset);
 	p->canint = 0;
 	if(r < 0) {
 		free(data);

+ 1 - 1
sys/src/cmd/exportfs/mkfile

@@ -4,6 +4,7 @@ TARG=exportfs
 OFILES=\
 	exportfs.$O\
 	exportsrv.$O\
+	pattern.$O\
 
 HFILES=exportfs.h\
 
@@ -13,6 +14,5 @@ UPDATE=\
 	mkfile\
 	$HFILES\
 	${OFILES:%.$O=%.c}\
-	${TARG:%=/386/bin/%}\
 
 </sys/src/cmd/mkone

+ 154 - 0
sys/src/cmd/exportfs/pattern.c

@@ -0,0 +1,154 @@
+#include <u.h>
+#include <libc.h>
+#include <fcall.h>
+#include <bio.h>
+#include <regexp.h>
+#define Extern
+#include "exportfs.h"
+
+Reprog	**exclude, **include;
+char	*patternfile;
+
+void
+exclusions(void)
+{
+	Biobuf *f;
+	int ni, nmaxi, ne, nmaxe;
+	char *line;
+
+	if(patternfile == nil)
+		return;
+
+	f = Bopen(patternfile, OREAD);
+	if(f == nil)
+		fatal("cannot open patternfile");
+	ni = 0;
+	nmaxi = 100;
+	include = malloc(nmaxi*sizeof(*include));
+	if(include == nil)
+		fatal("out of memory");
+	include[0] = nil;
+	ne = 0;
+	nmaxe = 100;
+	exclude = malloc(nmaxe*sizeof(*exclude));
+	if(exclude == nil)
+		fatal("out of memory");
+	exclude[0] = nil;
+	while(line = Brdline(f, '\n')){
+		line[Blinelen(f) - 1] = 0;
+		if(strlen(line) < 2 || line[1] != ' ')
+			continue;
+		switch(line[0]){
+		case '+':
+			if(ni+1 >= nmaxi){
+				nmaxi = 2*nmaxi;
+				include = realloc(include, nmaxi*sizeof(*include));
+				if(include == nil)
+					fatal("out of memory");
+			}
+			DEBUG(DFD, "\tinclude %s\n", line+2);
+			include[ni] = regcomp(line+2);
+			include[++ni] = nil;
+			break;
+		case '-':
+			if(ne+1 >= nmaxe){
+				nmaxe = 2*nmaxe;
+				exclude = realloc(exclude, nmaxe*sizeof(*exclude));
+				if(exclude == nil)
+					fatal("out of memory");
+			}
+			DEBUG(DFD, "\texclude %s\n", line+2);
+			exclude[ne] = regcomp(line+2);
+			exclude[++ne] = nil;
+			break;
+		default:
+			DEBUG(DFD, "ignoring pattern %s\n", line);
+			break;
+		}
+	}
+	Bterm(f);
+}
+
+int
+excludefile(char *path)
+{
+	Reprog **re;
+	char *p;
+
+	if(*(path+1) == 0)
+		p = "/";
+	else
+		p = path+1;
+
+	DEBUG(DFD, "checking %s\n", path);
+	for(re = include; *re != nil; re++){
+		if(regexec(*re, p, nil, 0) != 1){
+			DEBUG(DFD, "excluded+ %s\n", path);
+			return -1;
+		}
+	}
+	for(re = exclude; *re != nil; re++){
+		if(regexec(*re, p, nil, 0) == 1){
+			DEBUG(DFD, "excluded- %s\n", path);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+int
+preaddir(Fid *f, uchar *data, int n, vlong offset)
+{
+	int r = 0, m;
+	Dir *d;
+
+	DEBUG(DFD, "\tpreaddir n=%d wo=%lld fo=%lld\n", n, offset, f->offset);
+	if(offset == 0 && f->offset != 0){
+		if(seek(f->fid, 0, 0) != 0)
+			return -1;
+		f->offset = f->cdir = f->ndir = 0;
+		free(f->dir);
+		f->dir = nil;
+	}else if(offset != f->offset){
+		werrstr("can't seek dir %lld to %lld", f->offset, offset);
+		return -1;
+	}
+
+	while(n > 0){
+		if(f->dir == nil){
+			f->ndir = dirread(f->fid, &f->dir);
+			if(f->ndir < 0)
+				return f->ndir;
+			if(f->ndir == 0)
+				return r;
+		}
+		d = &f->dir[f->cdir++];
+		if(exclude){
+			char *p = makepath(f->f, d->name);
+			if(excludefile(p)){
+				free(p);
+				goto skipentry;
+			}
+			free(p);
+		}
+		m = convD2M(d, data, n);
+		DEBUG(DFD, "\t\tconvD2M %d\n", m);
+		if(m <= BIT16SZ){
+			DEBUG(DFD, "\t\t\tneeded %d\n", GBIT16(data));
+			/* not enough room for full entry; leave for next time */
+			f->cdir--;
+			return r;
+		}else{
+			data += m;
+			n -= m;
+			r += m;
+			f->offset += m;
+		}
+skipentry:	if(f->cdir >= f->ndir){
+			f->cdir = f->ndir = 0;
+			free(f->dir);
+			f->dir = nil;
+		}
+	}
+	return r;
+}

+ 1 - 1
sys/src/cmd/fossil/file.c

@@ -654,7 +654,7 @@ fileTruncate(File *f, char *uid)
 	sourceUnlock(f->source);
 	fileUnlock(f);
 
-	fileWAccess(f->up, uid);
+	fileWAccess(f, uid);
 
 	return 1;
 }