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
exclusions(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
excludefile(char * path)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
preaddir(Fid * f,uchar * data,int n,vlong offset)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