]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/exportfs/pattern.c
exportfs: revert e524e8d65a7573c46d7beb49e77bfc2d55a5563d
[plan9front.git] / sys / src / cmd / exportfs / pattern.c
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 }