1*a960ed1cSDavid du Colombier #include <u.h> 2*a960ed1cSDavid du Colombier #include <libc.h> 3*a960ed1cSDavid du Colombier #include <fcall.h> 4*a960ed1cSDavid du Colombier #include <bio.h> 5*a960ed1cSDavid du Colombier #include <regexp.h> 6*a960ed1cSDavid du Colombier #define Extern 7*a960ed1cSDavid du Colombier #include "exportfs.h" 8*a960ed1cSDavid du Colombier 9*a960ed1cSDavid du Colombier Reprog **exclude, **include; 10*a960ed1cSDavid du Colombier char *patternfile; 11*a960ed1cSDavid du Colombier 12*a960ed1cSDavid du Colombier void 13*a960ed1cSDavid du Colombier exclusions(void) 14*a960ed1cSDavid du Colombier { 15*a960ed1cSDavid du Colombier Biobuf *f; 16*a960ed1cSDavid du Colombier int ni, nmaxi, ne, nmaxe; 17*a960ed1cSDavid du Colombier char *line; 18*a960ed1cSDavid du Colombier 19*a960ed1cSDavid du Colombier if(patternfile == nil) 20*a960ed1cSDavid du Colombier return; 21*a960ed1cSDavid du Colombier 22*a960ed1cSDavid du Colombier f = Bopen(patternfile, OREAD); 23*a960ed1cSDavid du Colombier if(f == nil) 24*a960ed1cSDavid du Colombier fatal("cannot open patternfile"); 25*a960ed1cSDavid du Colombier ni = 0; 26*a960ed1cSDavid du Colombier nmaxi = 100; 27*a960ed1cSDavid du Colombier include = malloc(nmaxi*sizeof(*include)); 28*a960ed1cSDavid du Colombier if(include == nil) 29*a960ed1cSDavid du Colombier fatal("out of memory"); 30*a960ed1cSDavid du Colombier include[0] = nil; 31*a960ed1cSDavid du Colombier ne = 0; 32*a960ed1cSDavid du Colombier nmaxe = 100; 33*a960ed1cSDavid du Colombier exclude = malloc(nmaxe*sizeof(*exclude)); 34*a960ed1cSDavid du Colombier if(exclude == nil) 35*a960ed1cSDavid du Colombier fatal("out of memory"); 36*a960ed1cSDavid du Colombier exclude[0] = nil; 37*a960ed1cSDavid du Colombier while(line = Brdline(f, '\n')){ 38*a960ed1cSDavid du Colombier line[Blinelen(f) - 1] = 0; 39*a960ed1cSDavid du Colombier if(strlen(line) < 2 || line[1] != ' ') 40*a960ed1cSDavid du Colombier continue; 41*a960ed1cSDavid du Colombier switch(line[0]){ 42*a960ed1cSDavid du Colombier case '+': 43*a960ed1cSDavid du Colombier if(ni+1 >= nmaxi){ 44*a960ed1cSDavid du Colombier nmaxi = 2*nmaxi; 45*a960ed1cSDavid du Colombier include = realloc(include, nmaxi*sizeof(*include)); 46*a960ed1cSDavid du Colombier if(include == nil) 47*a960ed1cSDavid du Colombier fatal("out of memory"); 48*a960ed1cSDavid du Colombier } 49*a960ed1cSDavid du Colombier DEBUG(DFD, "\tinclude %s\n", line+2); 50*a960ed1cSDavid du Colombier include[ni] = regcomp(line+2); 51*a960ed1cSDavid du Colombier include[++ni] = nil; 52*a960ed1cSDavid du Colombier break; 53*a960ed1cSDavid du Colombier case '-': 54*a960ed1cSDavid du Colombier if(ne+1 >= nmaxe){ 55*a960ed1cSDavid du Colombier nmaxe = 2*nmaxe; 56*a960ed1cSDavid du Colombier exclude = realloc(exclude, nmaxe*sizeof(*exclude)); 57*a960ed1cSDavid du Colombier if(exclude == nil) 58*a960ed1cSDavid du Colombier fatal("out of memory"); 59*a960ed1cSDavid du Colombier } 60*a960ed1cSDavid du Colombier DEBUG(DFD, "\texclude %s\n", line+2); 61*a960ed1cSDavid du Colombier exclude[ne] = regcomp(line+2); 62*a960ed1cSDavid du Colombier exclude[++ne] = nil; 63*a960ed1cSDavid du Colombier break; 64*a960ed1cSDavid du Colombier default: 65*a960ed1cSDavid du Colombier DEBUG(DFD, "ignoring pattern %s\n", line); 66*a960ed1cSDavid du Colombier break; 67*a960ed1cSDavid du Colombier } 68*a960ed1cSDavid du Colombier } 69*a960ed1cSDavid du Colombier Bterm(f); 70*a960ed1cSDavid du Colombier } 71*a960ed1cSDavid du Colombier 72*a960ed1cSDavid du Colombier int 73*a960ed1cSDavid du Colombier excludefile(char *path) 74*a960ed1cSDavid du Colombier { 75*a960ed1cSDavid du Colombier Reprog **re; 76*a960ed1cSDavid du Colombier char *p; 77*a960ed1cSDavid du Colombier 78*a960ed1cSDavid du Colombier if(*(path+1) == 0) 79*a960ed1cSDavid du Colombier p = "/"; 80*a960ed1cSDavid du Colombier else 81*a960ed1cSDavid du Colombier p = path+1; 82*a960ed1cSDavid du Colombier 83*a960ed1cSDavid du Colombier DEBUG(DFD, "checking %s\n", path); 84*a960ed1cSDavid du Colombier for(re = include; *re != nil; re++){ 85*a960ed1cSDavid du Colombier if(regexec(*re, p, nil, 0) != 1){ 86*a960ed1cSDavid du Colombier DEBUG(DFD, "excluded+ %s\n", path); 87*a960ed1cSDavid du Colombier return -1; 88*a960ed1cSDavid du Colombier } 89*a960ed1cSDavid du Colombier } 90*a960ed1cSDavid du Colombier for(re = exclude; *re != nil; re++){ 91*a960ed1cSDavid du Colombier if(regexec(*re, p, nil, 0) == 1){ 92*a960ed1cSDavid du Colombier DEBUG(DFD, "excluded- %s\n", path); 93*a960ed1cSDavid du Colombier return -1; 94*a960ed1cSDavid du Colombier } 95*a960ed1cSDavid du Colombier } 96*a960ed1cSDavid du Colombier return 0; 97*a960ed1cSDavid du Colombier } 98*a960ed1cSDavid du Colombier 99*a960ed1cSDavid du Colombier int 100*a960ed1cSDavid du Colombier preaddir(Fid *f, uchar *data, int n, vlong offset) 101*a960ed1cSDavid du Colombier { 102*a960ed1cSDavid du Colombier int r = 0, m; 103*a960ed1cSDavid du Colombier Dir *d; 104*a960ed1cSDavid du Colombier 105*a960ed1cSDavid du Colombier DEBUG(DFD, "\tpreaddir n=%d wo=%lld fo=%lld\n", n, offset, f->offset); 106*a960ed1cSDavid du Colombier if(offset == 0 && f->offset != 0){ 107*a960ed1cSDavid du Colombier if(seek(f->fid, 0, 0) != 0) 108*a960ed1cSDavid du Colombier return -1; 109*a960ed1cSDavid du Colombier f->offset = f->cdir = f->ndir = 0; 110*a960ed1cSDavid du Colombier free(f->dir); 111*a960ed1cSDavid du Colombier f->dir = nil; 112*a960ed1cSDavid du Colombier }else if(offset != f->offset){ 113*a960ed1cSDavid du Colombier werrstr("can't seek dir %lld to %lld", f->offset, offset); 114*a960ed1cSDavid du Colombier return -1; 115*a960ed1cSDavid du Colombier } 116*a960ed1cSDavid du Colombier 117*a960ed1cSDavid du Colombier while(n > 0){ 118*a960ed1cSDavid du Colombier if(f->dir == nil){ 119*a960ed1cSDavid du Colombier f->ndir = dirread(f->fid, &f->dir); 120*a960ed1cSDavid du Colombier if(f->ndir < 0) 121*a960ed1cSDavid du Colombier return f->ndir; 122*a960ed1cSDavid du Colombier if(f->ndir == 0) 123*a960ed1cSDavid du Colombier return r; 124*a960ed1cSDavid du Colombier } 125*a960ed1cSDavid du Colombier d = &f->dir[f->cdir++]; 126*a960ed1cSDavid du Colombier if(exclude){ 127*a960ed1cSDavid du Colombier char *p = makepath(f->f, d->name); 128*a960ed1cSDavid du Colombier if(excludefile(p)){ 129*a960ed1cSDavid du Colombier free(p); 130*a960ed1cSDavid du Colombier goto skipentry; 131*a960ed1cSDavid du Colombier } 132*a960ed1cSDavid du Colombier free(p); 133*a960ed1cSDavid du Colombier } 134*a960ed1cSDavid du Colombier m = convD2M(d, data, n); 135*a960ed1cSDavid du Colombier DEBUG(DFD, "\t\tconvD2M %d\n", m); 136*a960ed1cSDavid du Colombier if(m <= BIT16SZ){ 137*a960ed1cSDavid du Colombier DEBUG(DFD, "\t\t\tneeded %d\n", GBIT16(data)); 138*a960ed1cSDavid du Colombier /* not enough room for full entry; leave for next time */ 139*a960ed1cSDavid du Colombier f->cdir--; 140*a960ed1cSDavid du Colombier return r; 141*a960ed1cSDavid du Colombier }else{ 142*a960ed1cSDavid du Colombier data += m; 143*a960ed1cSDavid du Colombier n -= m; 144*a960ed1cSDavid du Colombier r += m; 145*a960ed1cSDavid du Colombier f->offset += m; 146*a960ed1cSDavid du Colombier } 147*a960ed1cSDavid du Colombier skipentry: if(f->cdir >= f->ndir){ 148*a960ed1cSDavid du Colombier f->cdir = f->ndir = 0; 149*a960ed1cSDavid du Colombier free(f->dir); 150*a960ed1cSDavid du Colombier f->dir = nil; 151*a960ed1cSDavid du Colombier } 152*a960ed1cSDavid du Colombier } 153*a960ed1cSDavid du Colombier return r; 154*a960ed1cSDavid du Colombier } 155