Commit | Line | Data |
---|---|---|
a55d21aa WD |
1 | This patch adds the ability to use ". INSERT" files in excludes and |
2 | includes. If you specify a name without slashes, that filename will be | |
3 | looked for in every directory and its rules will effect that directory | |
4 | and its subdirectories. Insert rules found inside a per-directory | |
5 | include file are always just read in (they don't create any new per-dir | |
6 | include/exclude files). | |
7 | ||
8 | For example: | |
9 | ||
10 | rsync -av --exclude='. .excl' from/ to | |
11 | ||
12 | The above will look for a file named ".excl" in every directory of the | |
13 | sender and will exclude (by default) files based on the rules found | |
14 | therein. If a file contains this: | |
15 | ||
16 | + *.c | |
17 | . another.file | |
18 | - *.o | |
19 | ||
20 | Then the file "another.file" will also be read (from that one dir) and | |
21 | its rules inserted in between the surrounding lines. | |
22 | ||
23 | Additionally, you can affect where the -C option's inclusion of the | |
24 | .cvsignore file gets inserted into your rules by mentioning it as an | |
25 | insertion. For instance, specifying this: | |
26 | ||
27 | rsync -avC --include=foo --exclude='. .cvsignore' --include='*.c' a/ b | |
28 | ||
29 | This will insert all the .cvsignore rules in the middle of your rules | |
30 | rather than at the end. This allows their dir-specific rules to | |
31 | supersede your general rules instead of being subservient to them. | |
32 | ||
33 | ..wayne.. | |
34 | ||
35 | --- exclude.c 22 Apr 2004 22:17:15 -0000 1.71 | |
36 | +++ exclude.c 22 Apr 2004 23:45:51 -0000 | |
37 | @@ -30,31 +30,60 @@ extern int verbose; | |
38 | extern int eol_nulls; | |
39 | extern int list_only; | |
40 | extern int recurse; | |
41 | +extern int io_error; | |
42 | +extern int sanitize_paths; | |
43 | ||
44 | extern char curr_dir[]; | |
45 | ||
46 | -struct exclude_list_struct exclude_list = { 0, 0, "" }; | |
47 | -struct exclude_list_struct local_exclude_list = { 0, 0, "local-cvsignore " }; | |
48 | -struct exclude_list_struct server_exclude_list = { 0, 0, "server " }; | |
49 | +struct exclude_list_struct exclude_list = { 0, 0, 0, 0, "" }; | |
50 | +struct exclude_list_struct server_exclude_list = { 0, 0, 0, 0, "server " }; | |
51 | char *exclude_path_prefix = NULL; | |
52 | ||
53 | +static struct exclude_list_struct *local_exclude_lists; | |
54 | +static int local_exclude_list_cnt; | |
55 | +static char dirbuf[MAXPATHLEN]; | |
56 | +static unsigned int dirbuf_offset = 0; | |
57 | + | |
58 | +static void clear_exclude_list(struct exclude_list_struct *listp, | |
59 | + struct exclude_struct *extra) | |
60 | +{ | |
61 | + listp->head = listp->extra = extra; | |
62 | + listp->tail = NULL; | |
63 | +} | |
64 | + | |
65 | /** Build an exclude structure given a exclude pattern */ | |
66 | static void make_exclude(struct exclude_list_struct *listp, const char *pattern, | |
67 | - int pat_len, int include) | |
68 | + unsigned int pat_len, int mflags) | |
69 | { | |
70 | struct exclude_struct *ret; | |
71 | const char *cp; | |
72 | - int ex_len; | |
73 | + unsigned int ex_len; | |
74 | + | |
75 | + if (mflags & MATCHFLG_INSERT_FILE) { | |
76 | + struct exclude_struct *ex; | |
77 | + /* If the local include file was already mentioned, don't | |
78 | + * insert it again. */ | |
79 | + for (ex = listp->head; ex; ex = ex->next) { | |
80 | + if ((ex->match_flags & MATCHFLG_INSERT_FILE) | |
81 | + && strlen(ex->pattern) == pat_len | |
82 | + && strncmp(ex->pattern, pattern, pat_len) == 0) | |
83 | + return; | |
84 | + } | |
85 | + if (pat_len == 10 && strncmp(pattern, ".cvsignore", 10) == 0) { | |
86 | + mflags |= MATCHFLG_CVSIGNORE; | |
87 | + mflags &= ~MATCHFLG_INCLUDE; | |
88 | + } else | |
89 | + mflags &= ~MATCHFLG_CVSIGNORE; | |
90 | + } | |
91 | ||
92 | ret = new(struct exclude_struct); | |
93 | if (!ret) | |
94 | out_of_memory("make_exclude"); | |
95 | ||
96 | memset(ret, 0, sizeof ret[0]); | |
97 | - ret->include = include; | |
98 | ||
99 | if (exclude_path_prefix) | |
100 | - ret->match_flags |= MATCHFLG_ABS_PATH; | |
101 | + mflags |= MATCHFLG_ABS_PATH; | |
102 | if (exclude_path_prefix && *pattern == '/') | |
103 | ex_len = strlen(exclude_path_prefix); | |
104 | else | |
105 | @@ -68,29 +97,49 @@ static void make_exclude(struct exclude_ | |
106 | pat_len += ex_len; | |
107 | ||
108 | if (strpbrk(ret->pattern, "*[?")) { | |
109 | - ret->match_flags |= MATCHFLG_WILD; | |
110 | + mflags |= MATCHFLG_WILD; | |
111 | if ((cp = strstr(ret->pattern, "**")) != NULL) { | |
112 | - ret->match_flags |= MATCHFLG_WILD2; | |
113 | + mflags |= MATCHFLG_WILD2; | |
114 | /* If the pattern starts with **, note that. */ | |
115 | if (cp == ret->pattern) | |
116 | - ret->match_flags |= MATCHFLG_WILD2_PREFIX; | |
117 | + mflags |= MATCHFLG_WILD2_PREFIX; | |
118 | } | |
119 | } | |
120 | ||
121 | if (pat_len > 1 && ret->pattern[pat_len-1] == '/') { | |
122 | ret->pattern[pat_len-1] = 0; | |
123 | - ret->directory = 1; | |
124 | + mflags |= MATCHFLG_DIRECTORY; | |
125 | } | |
126 | ||
127 | for (cp = ret->pattern; (cp = strchr(cp, '/')) != NULL; cp++) | |
128 | ret->slash_cnt++; | |
129 | ||
130 | + ret->next = listp->extra; | |
131 | + | |
132 | if (!listp->tail) | |
133 | listp->head = listp->tail = ret; | |
134 | else { | |
135 | listp->tail->next = ret; | |
136 | listp->tail = ret; | |
137 | } | |
138 | + | |
139 | + if (mflags & MATCHFLG_INSERT_FILE) { | |
140 | + struct exclude_list_struct *lp; | |
141 | + int ndx = local_exclude_list_cnt++; | |
142 | + local_exclude_lists = realloc_array(local_exclude_lists, | |
143 | + struct exclude_list_struct, local_exclude_list_cnt); | |
144 | + if (!local_exclude_lists) | |
145 | + out_of_memory("make_exclude"); | |
146 | + lp = &local_exclude_lists[ndx]; | |
147 | + clear_exclude_list(lp, NULL); | |
148 | + if (asprintf(&lp->debug_type, "local %s ", | |
149 | + ret->pattern) < 0) | |
150 | + out_of_memory("make_exclude"); | |
151 | + lp->parent = ret; | |
152 | + ret->slash_cnt = ndx; | |
153 | + } | |
154 | + | |
155 | + ret->match_flags = mflags; | |
156 | } | |
157 | ||
158 | static void free_exclude(struct exclude_struct *ex) | |
159 | @@ -99,7 +148,7 @@ static void free_exclude(struct exclude_ | |
160 | free(ex); | |
161 | } | |
162 | ||
163 | -void free_exclude_list(struct exclude_list_struct *listp) | |
164 | +static void free_exclude_list(struct exclude_list_struct *listp) | |
165 | { | |
166 | struct exclude_struct *ent, *next; | |
167 | ||
168 | @@ -108,12 +157,72 @@ void free_exclude_list(struct exclude_li | |
169 | who_am_i(), listp->debug_type); | |
170 | } | |
171 | ||
172 | + if (listp->extra) { | |
173 | + if (listp->tail) | |
174 | + listp->tail->next = NULL; | |
175 | + else | |
176 | + listp->head = NULL; | |
177 | + } | |
178 | + | |
179 | for (ent = listp->head; ent; ent = next) { | |
180 | next = ent->next; | |
181 | free_exclude(ent); | |
182 | } | |
183 | ||
184 | - listp->head = listp->tail = NULL; | |
185 | + clear_exclude_list(listp, NULL); | |
186 | +} | |
187 | + | |
188 | +void *push_local_excludes(char *fname, unsigned int offset) | |
189 | +{ | |
190 | + int i; | |
191 | + struct exclude_list_struct *mem = new_array(struct exclude_list_struct, | |
192 | + local_exclude_list_cnt); | |
193 | + if (!mem) | |
194 | + out_of_memory("push_local_excludes"); | |
195 | + | |
196 | + memcpy(mem, local_exclude_lists, | |
197 | + sizeof (struct exclude_list_struct) * local_exclude_list_cnt); | |
198 | + | |
199 | + memcpy(dirbuf, fname, offset); | |
200 | + dirbuf_offset = offset; | |
201 | + | |
202 | + for (i = 0; i < local_exclude_list_cnt; i++) { | |
203 | + struct exclude_list_struct *listp = &local_exclude_lists[i]; | |
204 | + struct exclude_struct *extra; | |
205 | + char *file = listp->parent->pattern; | |
206 | + int flags; | |
207 | + if (listp->parent->match_flags & MATCHFLG_CVSIGNORE) { | |
208 | + flags = XFLG_WORD_SPLIT | XFLG_NO_PREFIXES; | |
209 | + extra = NULL; | |
210 | + } else { | |
211 | + flags = 0; | |
212 | + extra = listp->head; /* subdirs inherit our rules */ | |
213 | + } | |
214 | + clear_exclude_list(listp, extra); | |
215 | + if (strlcpy(fname + offset, file, MAXPATHLEN - offset) | |
216 | + < MAXPATHLEN - offset) { | |
217 | + add_exclude_file(listp, fname, flags); | |
218 | + } else { | |
219 | + io_error |= IOERR_GENERAL; | |
220 | + rprintf(FINFO, | |
221 | + "cannot add local excludes in long-named directory %s\n", | |
222 | + full_fname(fname)); | |
223 | + } | |
224 | + } | |
225 | + | |
226 | + return (void *) mem; | |
227 | +} | |
228 | + | |
229 | +void pop_local_excludes(void *mem) | |
230 | +{ | |
231 | + int i; | |
232 | + for (i = 0; i < local_exclude_list_cnt; i++) { | |
233 | + struct exclude_list_struct *listp = &local_exclude_lists[i]; | |
234 | + free_exclude_list(listp); | |
235 | + } | |
236 | + memcpy(local_exclude_lists, mem, | |
237 | + sizeof (struct exclude_list_struct) * local_exclude_list_cnt); | |
238 | + free(mem); | |
239 | } | |
240 | ||
241 | static int check_one_exclude(char *name, struct exclude_struct *ex, | |
242 | @@ -139,7 +248,8 @@ static int check_one_exclude(char *name, | |
243 | ||
244 | if (!name[0]) return 0; | |
245 | ||
246 | - if (ex->directory && !name_is_dir) return 0; | |
247 | + if ((ex->match_flags & MATCHFLG_DIRECTORY) && !name_is_dir) | |
248 | + return 0; | |
249 | ||
250 | if (*pattern == '/') { | |
251 | match_start = 1; | |
252 | @@ -206,9 +316,11 @@ static void report_exclude_result(char c | |
253 | ||
254 | if (verbose >= 2) { | |
255 | rprintf(FINFO, "[%s] %scluding %s %s because of %spattern %s%s\n", | |
256 | - who_am_i(), ent->include ? "in" : "ex", | |
257 | + who_am_i(), | |
258 | + ent->match_flags & MATCHFLG_INCLUDE ? "in" : "ex", | |
259 | name_is_dir ? "directory" : "file", name, type, | |
260 | - ent->pattern, ent->directory ? "/" : ""); | |
261 | + ent->pattern, | |
262 | + ent->match_flags & MATCHFLG_DIRECTORY ? "/" : ""); | |
263 | } | |
264 | } | |
265 | ||
266 | @@ -223,10 +335,18 @@ int check_exclude(struct exclude_list_st | |
267 | struct exclude_struct *ent; | |
268 | ||
269 | for (ent = listp->head; ent; ent = ent->next) { | |
270 | + if (ent->match_flags & MATCHFLG_INSERT_FILE) { | |
271 | + struct exclude_list_struct *lp | |
272 | + = &local_exclude_lists[ent->slash_cnt]; | |
273 | + int rc = check_exclude(lp, name, name_is_dir); | |
274 | + if (rc) | |
275 | + return rc; | |
276 | + continue; | |
277 | + } | |
278 | if (check_one_exclude(name, ent, name_is_dir)) { | |
279 | report_exclude_result(name, ent, name_is_dir, | |
280 | listp->debug_type); | |
281 | - return ent->include ? 1 : -1; | |
282 | + return (ent->match_flags & MATCHFLG_INCLUDE) ? 1 : -1; | |
283 | } | |
284 | } | |
285 | ||
286 | @@ -242,11 +362,11 @@ int check_exclude(struct exclude_list_st | |
287 | * *incl_ptr value will be 1 for an include, 0 for an exclude, and -1 for | |
288 | * the list-clearing "!" token. | |
289 | */ | |
290 | -static const char *get_exclude_tok(const char *p, int *len_ptr, int *incl_ptr, | |
291 | +static const char *get_exclude_tok(const char *p, int *len_ptr, int *flag_ptr, | |
292 | int xflags) | |
293 | { | |
294 | const unsigned char *s = (const unsigned char *)p; | |
295 | - int len; | |
296 | + int len, mflags = 0; | |
297 | ||
298 | if (xflags & XFLG_WORD_SPLIT) { | |
299 | /* Skip over any initial whitespace. */ | |
300 | @@ -256,13 +376,19 @@ static const char *get_exclude_tok(const | |
301 | p = (const char *)s; | |
302 | } | |
303 | ||
304 | - /* Is this a '+' or '-' followed by a space (not whitespace)? */ | |
305 | + /* Is this a +/-/. followed by a space (not whitespace)? */ | |
306 | if (!(xflags & XFLG_NO_PREFIXES) | |
307 | - && (*s == '-' || *s == '+') && s[1] == ' ') { | |
308 | - *incl_ptr = *s == '+'; | |
309 | + && (*s == '-' || *s == '+' || *s == '.') && s[1] == ' ') { | |
310 | + if (*s == '+') | |
311 | + mflags |= MATCHFLG_INCLUDE; | |
312 | + else if (*s == '.') { | |
313 | + mflags |= MATCHFLG_INSERT_FILE; | |
314 | + if (xflags & XFLG_DEF_INCLUDE) | |
315 | + mflags |= MATCHFLG_INCLUDE; | |
316 | + } | |
317 | s += 2; | |
318 | - } else | |
319 | - *incl_ptr = xflags & XFLG_DEF_INCLUDE; | |
320 | + } else if (xflags & XFLG_DEF_INCLUDE) | |
321 | + mflags |= MATCHFLG_INCLUDE; | |
322 | ||
323 | if (xflags & XFLG_WORD_SPLIT) { | |
324 | const unsigned char *cp = s; | |
325 | @@ -274,9 +400,10 @@ static const char *get_exclude_tok(const | |
326 | len = strlen(s); | |
327 | ||
328 | if (*p == '!' && len == 1 && !(xflags & XFLG_NO_PREFIXES)) | |
329 | - *incl_ptr = -1; | |
330 | + mflags |= MATCHFLG_CLEAR_LIST; | |
331 | ||
332 | *len_ptr = len; | |
333 | + *flag_ptr = mflags; | |
334 | return (const char *)s; | |
335 | } | |
336 | ||
337 | @@ -284,7 +411,7 @@ static const char *get_exclude_tok(const | |
338 | void add_exclude(struct exclude_list_struct *listp, const char *pattern, | |
339 | int xflags) | |
340 | { | |
341 | - int pat_len, incl; | |
342 | + int pat_len, mflags; | |
343 | const char *cp; | |
344 | ||
345 | if (!pattern) | |
346 | @@ -293,22 +420,44 @@ void add_exclude(struct exclude_list_str | |
347 | cp = pattern; | |
348 | pat_len = 0; | |
349 | while (1) { | |
350 | - cp = get_exclude_tok(cp + pat_len, &pat_len, &incl, xflags); | |
351 | + cp = get_exclude_tok(cp + pat_len, &pat_len, &mflags, xflags); | |
352 | if (!pat_len) | |
353 | break; | |
354 | /* If we got the special "!" token, clear the list. */ | |
355 | - if (incl < 0) | |
356 | + if (mflags & MATCHFLG_CLEAR_LIST) { | |
357 | free_exclude_list(listp); | |
358 | - else { | |
359 | - make_exclude(listp, cp, pat_len, incl); | |
360 | - | |
361 | - if (verbose > 2) { | |
362 | - rprintf(FINFO, "[%s] add_exclude(%.*s, %s%s)\n", | |
363 | - who_am_i(), pat_len, cp, | |
364 | - listp->debug_type, | |
365 | - incl ? "include" : "exclude"); | |
366 | + continue; | |
367 | + } | |
368 | + if (mflags & MATCHFLG_INSERT_FILE) { | |
369 | + char name[MAXPATHLEN]; | |
370 | + if ((unsigned) pat_len >= sizeof name) | |
371 | + continue; // XXX complain? | |
372 | + strlcpy(name, cp, pat_len+1); | |
373 | + if (listp->parent || strchr(name, '/') != NULL) { | |
374 | + if (sanitize_paths) | |
375 | + sanitize_path(name, curr_dir); | |
376 | + if (*name == '/') | |
377 | + cp = name; | |
378 | + else { | |
379 | + if (strlcpy(dirbuf + dirbuf_offset, | |
380 | + name, MAXPATHLEN - dirbuf_offset) | |
381 | + >= MAXPATHLEN - dirbuf_offset) | |
382 | + continue; // XXX complain? | |
383 | + cp = dirbuf; | |
384 | + } | |
385 | + add_exclude_file(listp, cp, | |
386 | + xflags | XFLG_FATAL_ERRORS); | |
387 | + continue; | |
388 | } | |
389 | } | |
390 | + make_exclude(listp, cp, pat_len, mflags); | |
391 | + | |
392 | + if (verbose > 2) { | |
393 | + rprintf(FINFO, "[%s] add_exclude(%.*s, %s%s%sclude)\n", | |
394 | + who_am_i(), pat_len, cp, listp->debug_type, | |
395 | + mflags & MATCHFLG_INSERT_FILE ? "FILE " : "", | |
396 | + mflags & MATCHFLG_INCLUDE ? "in" : "ex"); | |
397 | + } | |
398 | } | |
399 | } | |
400 | ||
401 | @@ -384,15 +533,19 @@ void send_exclude_list(int f) | |
402 | l = strlcpy(p, ent->pattern, sizeof p); | |
403 | if (l == 0 || l >= MAXPATHLEN) | |
404 | continue; | |
405 | - if (ent->directory) { | |
406 | + if (ent->match_flags & MATCHFLG_DIRECTORY) { | |
407 | p[l++] = '/'; | |
408 | p[l] = '\0'; | |
409 | } | |
410 | ||
411 | - if (ent->include) { | |
412 | + if (ent->match_flags & MATCHFLG_INCLUDE) { | |
413 | write_int(f, l + 2); | |
414 | write_buf(f, "+ ", 2); | |
415 | - } else if ((*p == '-' || *p == '+') && p[1] == ' ') { | |
416 | + } else if (ent->match_flags & MATCHFLG_INSERT_FILE) { | |
417 | + write_int(f, l + 2); | |
418 | + write_buf(f, ". ", 2); | |
419 | + } else if ((*p == '-' || *p == '+' || *p == '.') | |
420 | + && p[1] == ' ') { | |
421 | write_int(f, l + 2); | |
422 | write_buf(f, "- ", 2); | |
423 | } else | |
424 | @@ -433,6 +586,7 @@ void add_cvs_excludes(void) | |
425 | char fname[MAXPATHLEN]; | |
426 | char *p; | |
427 | ||
428 | + add_exclude(&exclude_list, ". .cvsignore", 0); | |
429 | add_exclude(&exclude_list, default_cvsignore, | |
430 | XFLG_WORD_SPLIT | XFLG_NO_PREFIXES); | |
431 | ||
432 | --- flist.c 22 Apr 2004 22:17:15 -0000 1.216 | |
433 | +++ flist.c 22 Apr 2004 23:45:51 -0000 | |
434 | @@ -39,8 +39,6 @@ extern int module_id; | |
435 | extern int ignore_errors; | |
436 | extern int numeric_ids; | |
437 | ||
438 | -extern int cvs_exclude; | |
439 | - | |
440 | extern int recurse; | |
441 | extern char curr_dir[MAXPATHLEN]; | |
442 | extern char *files_from; | |
443 | @@ -66,7 +64,6 @@ extern int write_batch; | |
444 | ||
445 | extern struct exclude_list_struct exclude_list; | |
446 | extern struct exclude_list_struct server_exclude_list; | |
447 | -extern struct exclude_list_struct local_exclude_list; | |
448 | ||
449 | int io_error; | |
450 | ||
451 | @@ -211,8 +208,6 @@ int link_stat(const char *path, STRUCT_S | |
452 | */ | |
453 | static int check_exclude_file(char *fname, int is_dir, int exclude_level) | |
454 | { | |
455 | - int rc; | |
456 | - | |
457 | #if 0 /* This currently never happens, so avoid a useless compare. */ | |
458 | if (exclude_level == NO_EXCLUDES) | |
459 | return 0; | |
460 | @@ -234,10 +229,7 @@ static int check_exclude_file(char *fnam | |
461 | if (exclude_level != ALL_EXCLUDES) | |
462 | return 0; | |
463 | if (exclude_list.head | |
464 | - && (rc = check_exclude(&exclude_list, fname, is_dir)) != 0) | |
465 | - return rc < 0; | |
466 | - if (local_exclude_list.head | |
467 | - && check_exclude(&local_exclude_list, fname, is_dir) < 0) | |
468 | + && check_exclude(&exclude_list, fname, is_dir) < 0) | |
469 | return 1; | |
470 | return 0; | |
471 | } | |
472 | @@ -946,11 +938,7 @@ void send_file_name(int f, struct file_l | |
473 | ||
474 | if (recursive && S_ISDIR(file->mode) | |
475 | && !(file->flags & FLAG_MOUNT_POINT)) { | |
476 | - struct exclude_list_struct last_list = local_exclude_list; | |
477 | - local_exclude_list.head = local_exclude_list.tail = NULL; | |
478 | send_directory(f, flist, f_name_to(file, fbuf)); | |
479 | - free_exclude_list(&local_exclude_list); | |
480 | - local_exclude_list = last_list; | |
481 | } | |
482 | } | |
483 | ||
484 | @@ -961,6 +949,7 @@ static void send_directory(int f, struct | |
485 | struct dirent *di; | |
486 | char fname[MAXPATHLEN]; | |
487 | unsigned int offset; | |
488 | + void *save_excludes; | |
489 | char *p; | |
490 | ||
491 | d = opendir(dir); | |
492 | @@ -985,18 +974,7 @@ static void send_directory(int f, struct | |
493 | offset++; | |
494 | } | |
495 | ||
496 | - if (cvs_exclude) { | |
497 | - if (strlcpy(p, ".cvsignore", MAXPATHLEN - offset) | |
498 | - < MAXPATHLEN - offset) { | |
499 | - add_exclude_file(&local_exclude_list, fname, | |
500 | - XFLG_WORD_SPLIT | XFLG_NO_PREFIXES); | |
501 | - } else { | |
502 | - io_error |= IOERR_GENERAL; | |
503 | - rprintf(FINFO, | |
504 | - "cannot cvs-exclude in long-named directory %s\n", | |
505 | - full_fname(fname)); | |
506 | - } | |
507 | - } | |
508 | + save_excludes = push_local_excludes(fname, offset); | |
509 | ||
510 | for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) { | |
511 | char *dname = d_name(di); | |
512 | @@ -1017,6 +995,8 @@ static void send_directory(int f, struct | |
513 | rprintf(FERROR, "readdir(%s): (%d) %s\n", | |
514 | dir, errno, strerror(errno)); | |
515 | } | |
516 | + | |
517 | + pop_local_excludes(save_excludes); | |
518 | ||
519 | closedir(d); | |
520 | } | |
521 | --- proto.h 22 Apr 2004 09:58:09 -0000 1.189 | |
522 | +++ proto.h 22 Apr 2004 23:45:51 -0000 | |
523 | @@ -51,7 +51,8 @@ int start_daemon(int f_in, int f_out); | |
524 | int daemon_main(void); | |
525 | void setup_protocol(int f_out,int f_in); | |
526 | int claim_connection(char *fname,int max_connections); | |
527 | -void free_exclude_list(struct exclude_list_struct *listp); | |
528 | +void *push_local_excludes(char *fname, unsigned int offset); | |
529 | +void pop_local_excludes(void *mem); | |
530 | int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir); | |
531 | void add_exclude(struct exclude_list_struct *listp, const char *pattern, | |
532 | int xflags); | |
533 | --- rsync.h 22 Apr 2004 09:58:24 -0000 1.198 | |
534 | +++ rsync.h 22 Apr 2004 23:45:52 -0000 | |
535 | @@ -490,18 +490,21 @@ struct map_struct { | |
536 | #define MATCHFLG_WILD2 (1<<1) /* pattern has '**' */ | |
537 | #define MATCHFLG_WILD2_PREFIX (1<<2) /* pattern starts with '**' */ | |
538 | #define MATCHFLG_ABS_PATH (1<<3) /* path-match on absolute path */ | |
539 | +#define MATCHFLG_INCLUDE (1<<4) /* this is an include, not an exclude */ | |
540 | +#define MATCHFLG_CLEAR_LIST (1<<5) /* this item is the "!" token */ | |
541 | +#define MATCHFLG_DIRECTORY (1<<6) /* this matches only directories */ | |
542 | +#define MATCHFLG_INSERT_FILE (1<<7) /* specifies a file to insert */ | |
543 | +#define MATCHFLG_CVSIGNORE (1<<8) /* parse this as a .cvsignore file */ | |
544 | struct exclude_struct { | |
545 | struct exclude_struct *next; | |
546 | char *pattern; | |
547 | int match_flags; | |
548 | - int include; | |
549 | - int directory; | |
550 | int slash_cnt; | |
551 | }; | |
552 | ||
553 | struct exclude_list_struct { | |
554 | - struct exclude_struct *head; | |
555 | - struct exclude_struct *tail; | |
556 | + struct exclude_struct *head, *tail; | |
557 | + struct exclude_struct *extra, *parent; | |
558 | char *debug_type; | |
559 | }; | |
560 |