summaryrefslogtreecommitdiff
path: root/sys/src/cmd/exportfs/pattern.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/exportfs/pattern.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/exportfs/pattern.c')
-rwxr-xr-xsys/src/cmd/exportfs/pattern.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/sys/src/cmd/exportfs/pattern.c b/sys/src/cmd/exportfs/pattern.c
new file mode 100755
index 000000000..0dcbc9380
--- /dev/null
+++ b/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;
+}