diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /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-x | sys/src/cmd/exportfs/pattern.c | 154 |
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; +} |