Commit | Line | Data |
---|---|---|
bd8bf8b1 | 1 | --- exclude.c 22 Apr 2004 22:17:15 -0000 1.71 |
b0aa8860 WD |
2 | +++ exclude.c 22 Apr 2004 10:32:52 -0000 |
3 | @@ -27,15 +27,17 @@ | |
94f29894 WD |
4 | #include "rsync.h" |
5 | ||
6 | extern int verbose; | |
7 | +extern int protocol_version; | |
7b0cee24 WD |
8 | extern int eol_nulls; |
9 | extern int list_only; | |
10 | extern int recurse; | |
b0aa8860 | 11 | |
7b0cee24 | 12 | extern char curr_dir[]; |
94f29894 | 13 | |
b0aa8860 WD |
14 | -struct exclude_list_struct exclude_list = { 0, 0, "" }; |
15 | -struct exclude_list_struct local_exclude_list = { 0, 0, "local-cvsignore " }; | |
16 | -struct exclude_list_struct server_exclude_list = { 0, 0, "server " }; | |
17 | +struct exclude_list_struct exclude_list = { 0, 0, 0, "" }; | |
18 | +struct exclude_list_struct perdir_exclude_list = { 0, 0, 0, "perdir " }; | |
19 | +struct exclude_list_struct local_exclude_list = { 0, 0, 0, "local-cvsignore " }; | |
20 | +struct exclude_list_struct server_exclude_list = { 0, 0, 0, "server " }; | |
94f29894 | 21 | char *exclude_path_prefix = NULL; |
b0aa8860 WD |
22 | |
23 | /** Build an exclude structure given a exclude pattern */ | |
7b0cee24 | 24 | @@ -85,6 +87,8 @@ static void make_exclude(struct exclude_ |
616f340b WD |
25 | for (cp = ret->pattern; (cp = strchr(cp, '/')) != NULL; cp++) |
26 | ret->slash_cnt++; | |
94f29894 | 27 | |
616f340b WD |
28 | + ret->next = listp->extra; |
29 | + | |
30 | if (!listp->tail) | |
31 | listp->head = listp->tail = ret; | |
32 | else { | |
b0aa8860 WD |
33 | @@ -108,12 +112,26 @@ void free_exclude_list(struct exclude_li |
34 | who_am_i(), listp->debug_type); | |
35 | } | |
94f29894 | 36 | |
616f340b WD |
37 | + if (listp->extra) { |
38 | + if (listp->tail) | |
39 | + listp->tail->next = NULL; | |
40 | + else | |
41 | + listp->head = NULL; | |
42 | + } | |
43 | + | |
94f29894 | 44 | for (ent = listp->head; ent; ent = next) { |
94f29894 WD |
45 | next = ent->next; |
46 | free_exclude(ent); | |
b0aa8860 | 47 | } |
4eddff16 | 48 | |
b0aa8860 WD |
49 | - listp->head = listp->tail = NULL; |
50 | + clear_exclude_list(listp, NULL); | |
51 | +} | |
52 | + | |
4eddff16 WD |
53 | +void clear_exclude_list(struct exclude_list_struct *listp, |
54 | + struct exclude_struct *extra) | |
55 | +{ | |
56 | + listp->head = listp->extra = extra; | |
57 | + listp->tail = NULL; | |
b0aa8860 WD |
58 | } |
59 | ||
4eddff16 | 60 | static int check_one_exclude(char *name, struct exclude_struct *ex, |
bd8bf8b1 | 61 | @@ -215,22 +233,25 @@ static void report_exclude_result(char c |
94f29894 WD |
62 | |
63 | /* | |
64 | * Return true if file NAME is defined to be excluded by the specified | |
bd8bf8b1 WD |
65 | - * exclude list. Returns -1 for an exclude, 1 for an include, and 0 if |
66 | - * no match. | |
67 | + * exclude list. Returns -1 for an exclude, 0 for a normal include, or 1 | |
68 | + * for a super include. | |
94f29894 | 69 | */ |
b0aa8860 WD |
70 | -int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir) |
71 | +int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir, | |
72 | + int current_exclusion) | |
94f29894 WD |
73 | { |
74 | struct exclude_struct *ent; | |
75 | ||
76 | for (ent = listp->head; ent; ent = ent->next) { | |
77 | + if (current_exclusion < 0 && ent->include < 2) | |
78 | + continue; | |
79 | if (check_one_exclude(name, ent, name_is_dir)) { | |
b0aa8860 WD |
80 | report_exclude_result(name, ent, name_is_dir, |
81 | listp->debug_type); | |
bd8bf8b1 | 82 | - return ent->include ? 1 : -1; |
94f29894 WD |
83 | + return ent->include - 1; |
84 | } | |
85 | } | |
86 | ||
87 | - return 0; | |
88 | + return current_exclusion; | |
89 | } | |
90 | ||
91 | ||
bd8bf8b1 | 92 | @@ -256,10 +277,10 @@ static const char *get_exclude_tok(const |
94f29894 WD |
93 | p = (const char *)s; |
94 | } | |
95 | ||
96 | - /* Is this a '+' or '-' followed by a space (not whitespace)? */ | |
97 | + /* Is this a +/-/& followed by a space (not whitespace)? */ | |
98 | if (!(xflags & XFLG_NO_PREFIXES) | |
99 | - && (*s == '-' || *s == '+') && s[1] == ' ') { | |
100 | - *incl_ptr = *s == '+'; | |
101 | + && (*s == '-' || *s == '+' || *s == '&') && s[1] == ' ') { | |
102 | + *incl_ptr = *s == '+' ? 1 : *s == '&' ? 2 : 0; | |
103 | s += 2; | |
104 | } else | |
105 | *incl_ptr = xflags & XFLG_DEF_INCLUDE; | |
bd8bf8b1 | 106 | @@ -391,8 +412,12 @@ void send_exclude_list(int f) |
94f29894 WD |
107 | |
108 | if (ent->include) { | |
109 | write_int(f, l + 2); | |
110 | - write_buf(f, "+ ", 2); | |
111 | - } else if ((*p == '-' || *p == '+') && p[1] == ' ') { | |
112 | + if (ent->include > 1 && protocol_version >= 28) | |
113 | + write_buf(f, "& ", 2); | |
114 | + else | |
115 | + write_buf(f, "+ ", 2); | |
116 | + } else if ((*p == '-' || *p == '+' || *p == '&') | |
117 | + && p[1] == ' ') { | |
118 | write_int(f, l + 2); | |
119 | write_buf(f, "- ", 2); | |
120 | } else | |
bd8bf8b1 | 121 | --- flist.c 22 Apr 2004 22:17:15 -0000 1.216 |
b0aa8860 | 122 | +++ flist.c 22 Apr 2004 10:32:52 -0000 |
94f29894 WD |
123 | @@ -40,6 +40,7 @@ extern int ignore_errors; |
124 | extern int numeric_ids; | |
125 | ||
126 | extern int cvs_exclude; | |
7b0cee24 | 127 | +extern const char *perdir_exclude_from; |
94f29894 WD |
128 | |
129 | extern int recurse; | |
130 | extern char curr_dir[MAXPATHLEN]; | |
616f340b | 131 | @@ -66,6 +67,7 @@ extern int write_batch; |
94f29894 WD |
132 | |
133 | extern struct exclude_list_struct exclude_list; | |
134 | extern struct exclude_list_struct server_exclude_list; | |
7b0cee24 | 135 | +extern struct exclude_list_struct perdir_exclude_list; |
94f29894 | 136 | extern struct exclude_list_struct local_exclude_list; |
94f29894 WD |
137 | |
138 | int io_error; | |
bd8bf8b1 | 139 | @@ -211,7 +213,9 @@ int link_stat(const char *path, STRUCT_S |
94f29894 WD |
140 | */ |
141 | static int check_exclude_file(char *fname, int is_dir, int exclude_level) | |
142 | { | |
bd8bf8b1 | 143 | - int rc; |
616f340b | 144 | + static struct exclude_list_struct *elist[] = { |
7b0cee24 | 145 | + &exclude_list, &perdir_exclude_list, &local_exclude_list, NULL }; |
616f340b | 146 | + int i, rc; |
bd8bf8b1 | 147 | |
94f29894 WD |
148 | #if 0 /* This currently never happens, so avoid a useless compare. */ |
149 | if (exclude_level == NO_EXCLUDES) | |
bd8bf8b1 | 150 | @@ -229,17 +233,18 @@ static int check_exclude_file(char *fnam |
b0aa8860 | 151 | } |
94f29894 WD |
152 | } |
153 | if (server_exclude_list.head | |
bd8bf8b1 WD |
154 | - && check_exclude(&server_exclude_list, fname, is_dir) < 0) |
155 | + && check_exclude(&server_exclude_list, fname, is_dir, 0) < 0) | |
94f29894 WD |
156 | return 1; |
157 | if (exclude_level != ALL_EXCLUDES) | |
158 | return 0; | |
bd8bf8b1 WD |
159 | - if (exclude_list.head |
160 | - && (rc = check_exclude(&exclude_list, fname, is_dir)) != 0) | |
161 | - return rc < 0; | |
94f29894 | 162 | - if (local_exclude_list.head |
bd8bf8b1 | 163 | - && check_exclude(&local_exclude_list, fname, is_dir) < 0) |
94f29894 WD |
164 | - return 1; |
165 | - return 0; | |
166 | + for (i = 0, rc = 0; elist[i]; i++) { | |
167 | + if (!elist[i]->head) | |
168 | + continue; | |
b0aa8860 | 169 | + rc = check_exclude(elist[i], fname, is_dir, rc); |
94f29894 WD |
170 | + if (rc > 0) |
171 | + return 0; | |
172 | + } | |
173 | + return rc < 0; | |
174 | } | |
175 | ||
176 | /* used by the one_file_system code */ | |
bd8bf8b1 | 177 | @@ -947,8 +952,12 @@ void send_file_name(int f, struct file_l |
94f29894 WD |
178 | if (recursive && S_ISDIR(file->mode) |
179 | && !(file->flags & FLAG_MOUNT_POINT)) { | |
180 | struct exclude_list_struct last_list = local_exclude_list; | |
b0aa8860 | 181 | - local_exclude_list.head = local_exclude_list.tail = NULL; |
7b0cee24 | 182 | + struct exclude_list_struct sub_list = perdir_exclude_list; |
4eddff16 | 183 | + clear_exclude_list(&local_exclude_list, NULL); |
7b0cee24 | 184 | + clear_exclude_list(&perdir_exclude_list, sub_list.head); |
94f29894 | 185 | send_directory(f, flist, f_name_to(file, fbuf)); |
7b0cee24 WD |
186 | + free_exclude_list(&perdir_exclude_list); |
187 | + perdir_exclude_list = sub_list; | |
94f29894 WD |
188 | free_exclude_list(&local_exclude_list); |
189 | local_exclude_list = last_list; | |
190 | } | |
bd8bf8b1 | 191 | @@ -994,6 +1003,18 @@ static void send_directory(int f, struct |
94f29894 WD |
192 | io_error |= IOERR_GENERAL; |
193 | rprintf(FINFO, | |
194 | "cannot cvs-exclude in long-named directory %s\n", | |
195 | + full_fname(fname)); | |
196 | + } | |
197 | + } | |
198 | + | |
7b0cee24 WD |
199 | + if (perdir_exclude_from) { |
200 | + if (strlcpy(p, perdir_exclude_from, MAXPATHLEN - offset) | |
616f340b | 201 | + < MAXPATHLEN - offset) |
7b0cee24 | 202 | + add_exclude_file(&perdir_exclude_list, fname, 0); |
616f340b | 203 | + else { |
94f29894 WD |
204 | + io_error |= IOERR_GENERAL; |
205 | + rprintf(FINFO, | |
7b0cee24 | 206 | + "cannot perdir-exclude in long-named directory %s\n", |
94f29894 WD |
207 | full_fname(fname)); |
208 | } | |
209 | } | |
7b0cee24 | 210 | --- options.c 17 Apr 2004 17:07:23 -0000 1.147 |
b0aa8860 | 211 | +++ options.c 22 Apr 2004 10:32:53 -0000 |
94f29894 WD |
212 | @@ -70,6 +70,7 @@ int am_server = 0; |
213 | int am_sender = 0; | |
214 | int am_generator = 0; | |
215 | char *files_from = NULL; | |
7b0cee24 | 216 | +char *perdir_exclude_from = NULL; |
94f29894 WD |
217 | int filesfrom_fd = -1; |
218 | char *remote_filesfrom_file = NULL; | |
219 | int eol_nulls = 0; | |
220 | @@ -273,6 +274,7 @@ void usage(enum logcode F) | |
221 | rprintf(F," --exclude-from=FILE exclude patterns listed in FILE\n"); | |
222 | rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n"); | |
223 | rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n"); | |
7b0cee24 | 224 | + rprintf(F," --perdir-exclude-from=F look in each dir for exclude-file F\n"); |
94f29894 WD |
225 | rprintf(F," --files-from=FILE read FILE for list of source-file names\n"); |
226 | rprintf(F," -0 --from0 all *-from file lists are delimited by nulls\n"); | |
227 | rprintf(F," --version print version number\n"); | |
228 | @@ -335,6 +337,7 @@ static struct poptOption long_options[] | |
229 | {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 }, | |
230 | {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 }, | |
231 | {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 }, | |
7b0cee24 | 232 | + {"perdir-exclude-from",0,POPT_ARG_STRING, &perdir_exclude_from, 0, 0, 0 }, |
94f29894 WD |
233 | {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 }, |
234 | {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 }, | |
235 | {"copy-links", 'L', POPT_ARG_NONE, ©_links, 0, 0, 0 }, | |
b0aa8860 WD |
236 | --- proto.h 22 Apr 2004 09:58:09 -0000 1.189 |
237 | +++ proto.h 22 Apr 2004 10:32:53 -0000 | |
238 | @@ -52,7 +52,10 @@ int daemon_main(void); | |
4eddff16 | 239 | void setup_protocol(int f_out,int f_in); |
94f29894 WD |
240 | int claim_connection(char *fname,int max_connections); |
241 | void free_exclude_list(struct exclude_list_struct *listp); | |
b0aa8860 | 242 | -int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir); |
4eddff16 WD |
243 | +void clear_exclude_list(struct exclude_list_struct *listp, |
244 | + struct exclude_struct *extra); | |
b0aa8860 WD |
245 | +int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir, |
246 | + int current_exclusion); | |
94f29894 WD |
247 | void add_exclude(struct exclude_list_struct *listp, const char *pattern, |
248 | int xflags); | |
249 | void add_exclude_file(struct exclude_list_struct *listp, const char *fname, | |
b0aa8860 WD |
250 | --- rsync.h 22 Apr 2004 09:58:24 -0000 1.198 |
251 | +++ rsync.h 22 Apr 2004 10:32:53 -0000 | |
b896fd56 | 252 | @@ -502,6 +502,7 @@ struct exclude_struct { |
616f340b WD |
253 | struct exclude_list_struct { |
254 | struct exclude_struct *head; | |
255 | struct exclude_struct *tail; | |
256 | + struct exclude_struct *extra; | |
b0aa8860 | 257 | char *debug_type; |
616f340b WD |
258 | }; |
259 | ||
bd8bf8b1 | 260 | --- rsync.yo 22 Apr 2004 21:35:45 -0000 1.161 |
b0aa8860 | 261 | +++ rsync.yo 22 Apr 2004 10:32:54 -0000 |
94f29894 WD |
262 | @@ -331,6 +331,7 @@ verb( |
263 | --exclude-from=FILE exclude patterns listed in FILE | |
264 | --include=PATTERN don't exclude files matching PATTERN | |
265 | --include-from=FILE don't exclude patterns listed in FILE | |
7b0cee24 | 266 | + --perdir-exclude-from=F look in each dir for exclude file F |
94f29894 WD |
267 | --files-from=FILE read FILE for list of source-file names |
268 | -0 --from0 all file lists are delimited by nulls | |
269 | --version print version number | |
bd8bf8b1 | 270 | @@ -675,6 +676,15 @@ dit(bf(--include-from=FILE)) This specif |
7b0cee24 WD |
271 | from a file. |
272 | If em(FILE) is bf(-) the list will be read from standard input. | |
94f29894 | 273 | |
7b0cee24 WD |
274 | +dit(bf(--perdir-exclude-from=FILE)) In any given directory, patterns |
275 | +listed in FILE (one per line) are excluded from the file lists | |
276 | +associated with that directory and all of its subdirectories. Rules | |
277 | +specified in a subdir take precedence over rules evaluated in a parent | |
278 | +dir (think of each file's rules being prefixed to the prior rules). If | |
279 | +you don't want to inherit the parent-dir rules, start the FILE with a | |
280 | +single exclamation mark ! to clear them out. You may prefix names with | |
281 | +an explicit exclude, include, or super-include prefix (see below). | |
94f29894 | 282 | + |
7b0cee24 WD |
283 | dit(bf(--files-from=FILE)) Using this option allows you to specify the |
284 | exact list of files to transfer (as read from the specified FILE or "-" | |
285 | for stdin). It also tweaks the default behavior of rsync to make | |
bd8bf8b1 | 286 | @@ -714,7 +724,8 @@ was located on the remote "src" host. |
7b0cee24 WD |
287 | |
288 | dit(bf(-0, --from0)) This tells rsync that the filenames it reads from a | |
289 | file are terminated by a null ('\0') character, not a NL, CR, or CR+LF. | |
290 | -This affects --exclude-from, --include-from, and --files-from. | |
291 | +This affects --exclude-from, --include-from, --perdir-exclude-from, | |
292 | +and --files-from. | |
293 | It does not affect --cvs-exclude (since all names read from a .cvsignore | |
294 | file are split on whitespace). | |
94f29894 | 295 | |
bd8bf8b1 | 296 | @@ -1001,6 +1012,12 @@ itemize( |
94f29894 WD |
297 | it() if the pattern starts with "- " (a minus followed by a space) |
298 | then it is always considered an exclude pattern, even if specified as | |
ce17e35e | 299 | part of an include option. The prefix is discarded before matching. |
94f29894 WD |
300 | + |
301 | + it() if the pattern starts with "& " (an ampersand followed by a space) | |
302 | + then it is considered a super-include pattern. A super-include will | |
303 | + override an exclude from another exclude list (a normal include only | |
304 | + overrides an exclusion from further down in the same list). The | |
305 | + prefix is discarded before matching. | |
306 | ||
307 | it() if the pattern is a single exclamation mark ! then the current | |
308 | include/exclude list is reset, removing all previously defined patterns. | |
b0aa8860 WD |
309 | --- t_stub.c 22 Apr 2004 09:58:11 -0000 1.7 |
310 | +++ t_stub.c 22 Apr 2004 10:32:54 -0000 | |
311 | @@ -46,7 +46,7 @@ struct exclude_list_struct server_exclud | |
312 | } | |
313 | ||
314 | int check_exclude(UNUSED(struct exclude_list_struct *listp), UNUSED(char *name), | |
315 | - UNUSED(int name_is_dir)) | |
316 | + UNUSED(int name_is_dir), UNUSED(int current_exclusion)) | |
317 | { | |
318 | /* This function doesn't really get called in this test context, so | |
319 | * just return 0. */ | |
bd8bf8b1 | 320 | --- util.c 22 Apr 2004 22:17:15 -0000 1.138 |
b0aa8860 WD |
321 | +++ util.c 22 Apr 2004 10:32:54 -0000 |
322 | @@ -476,7 +476,7 @@ static int exclude_server_path(char *arg | |
323 | if (server_exclude_list.head) { | |
94f29894 WD |
324 | for (s = arg; (s = strchr(s, '/')) != NULL; ) { |
325 | *s = '\0'; | |
bd8bf8b1 | 326 | - if (check_exclude(&server_exclude_list, arg, 1) < 0) { |
b0aa8860 | 327 | + if (check_exclude(&server_exclude_list, arg, 1, 0) < 0) { |
94f29894 WD |
328 | /* We must leave arg truncated! */ |
329 | return 1; | |
330 | } |