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