Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}