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