ref: 4308f6e7e6586e3a27aa46c4d54c434b8533b16d
dir: /sys/src/cmd/exportfs/pattern.c/
#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 = emallocz(nmaxi*sizeof(*include)); include[0] = nil; ne = 0; nmaxe = 100; exclude = emallocz(nmaxe*sizeof(*exclude)); 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", p); for(re = include; *re != nil; re++){ if(regexec(*re, p, nil, 0) != 1){ DEBUG(DFD, "excluded+ %s\n", p); return -1; } } for(re = exclude; *re != nil; re++){ if(regexec(*re, p, nil, 0) == 1){ DEBUG(DFD, "excluded- %s\n", p); 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; }