]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/exportfs/pattern.c
exportfs/import: cleanup
[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 = 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", p);
84         for(re = include; *re != nil; re++){
85                 if(regexec(*re, p, nil, 0) != 1){
86                         DEBUG(DFD, "excluded+ %s\n", p);
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", p);
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 }