Commit | Line | Data |
---|---|---|
66b47d42 WD |
1 | This patch adds two modifiers to the filter rule prefixes that allow a |
2 | rule to be marked as sender-side (s), receiver-side (r), or both ("sr" | |
3 | or omitted). Sender-side rules prevent files from being transferred, | |
4 | while receiver-side rules prevent files from being deleted. The default | |
5 | for an unmodified include/exclude rule is to affect both sides, but a | |
6 | rule that is explicitly marked as affecting both sides will remain | |
7 | unaffected by the --delete-excluded option (that option changes any | |
8 | unmodified rules into server-side only rules). | |
9 | ||
10 | See the updated manpage for the details. | |
11 | ||
12 | --- orig/compat.c 2005-02-01 10:39:22 | |
13 | +++ compat.c 2005-02-05 05:31:06 | |
14 | @@ -31,6 +31,7 @@ extern int verbose; | |
15 | extern int am_server; | |
16 | extern int am_sender; | |
17 | extern int read_batch; | |
18 | +extern int delete_excluded; | |
19 | extern int checksum_seed; | |
20 | extern int protocol_version; | |
21 | ||
22 | @@ -74,6 +75,12 @@ void setup_protocol(int f_out,int f_in) | |
23 | exit_cleanup(RERR_PROTOCOL); | |
24 | } | |
25 | ||
26 | + /* In newer protocols, --delete-excluded does not avoid the exclude- | |
27 | + * list transfer to the receiver, so mark a modern --delete-excluded | |
28 | + * conversation with a 2 instead of a 1. */ | |
29 | + if (protocol_version >= 29 && delete_excluded) | |
30 | + delete_excluded = 2; | |
31 | + | |
32 | if (am_server) { | |
33 | if (!checksum_seed) | |
34 | checksum_seed = time(NULL); | |
85f55536 | 35 | --- orig/exclude.c 2005-02-11 10:53:14 |
8d30d1c3 | 36 | +++ exclude.c 2005-02-11 22:39:37 |
66b47d42 WD |
37 | @@ -53,7 +53,8 @@ struct filter_list_struct server_filter_ |
38 | #define MAX_RULE_PREFIX (16) | |
39 | ||
40 | #define MODIFIERS_MERGE_FILE "-+Cenw" | |
41 | -#define MODIFIERS_INCL_EXCL "/!C" | |
42 | +#define MODIFIERS_INCL_EXCL "/!Crs" | |
43 | +#define MODIFIERS_HIDE_PROTECT "/!" | |
44 | ||
45 | /* The dirbuf is set by push_local_filters() to the current subdirectory | |
46 | * relative to curr_dir that is being processed. The path always has a | |
92172906 | 47 | @@ -678,6 +679,10 @@ static const char *parse_rule_tok(const |
85f55536 | 48 | if ((s = RULE_STRCMP(s, "exclude")) != NULL) |
92172906 WD |
49 | ch = '-'; |
50 | break; | |
51 | + case 'h': | |
85f55536 | 52 | + if ((s = RULE_STRCMP(s, "hide")) != NULL) |
92172906 WD |
53 | + ch = 'H'; |
54 | + break; | |
55 | case 'i': | |
85f55536 | 56 | if ((s = RULE_STRCMP(s, "include")) != NULL) |
92172906 WD |
57 | ch = '+'; |
58 | @@ -686,6 +691,19 @@ static const char *parse_rule_tok(const | |
85f55536 | 59 | if ((s = RULE_STRCMP(s, "merge")) != NULL) |
92172906 WD |
60 | ch = '.'; |
61 | break; | |
62 | + case 'p': | |
85f55536 | 63 | + if ((s = RULE_STRCMP(s, "protect")) != NULL) |
92172906 WD |
64 | + ch = 'P'; |
65 | + break; | |
8d30d1c3 WD |
66 | + case 'r': |
67 | + if ((s = RULE_STRCMP(s, "risk")) != NULL) | |
68 | + ch = 'R'; | |
69 | + break; | |
92172906 | 70 | + case 's': |
8d30d1c3 | 71 | + if ((s = RULE_STRCMP(s, "show")) != NULL) |
92172906 WD |
72 | + ch = 'S'; |
73 | + break; | |
92172906 WD |
74 | + |
75 | default: | |
76 | ch = *s; | |
77 | if (s[1] == ',') | |
78 | @@ -707,6 +725,20 @@ static const char *parse_rule_tok(const | |
66b47d42 WD |
79 | case '-': |
80 | mods = MODIFIERS_INCL_EXCL; | |
81 | break; | |
92172906 WD |
82 | + case 'S': |
83 | + new_mflags |= MATCHFLG_INCLUDE; | |
84 | + /* FALL THROUGH */ | |
66b47d42 WD |
85 | + case 'H': |
86 | + new_mflags |= MATCHFLG_SENDER_SIDE; | |
87 | + mods = MODIFIERS_HIDE_PROTECT; | |
88 | + break; | |
8d30d1c3 | 89 | + case 'R': |
92172906 WD |
90 | + new_mflags |= MATCHFLG_INCLUDE; |
91 | + /* FALL THROUGH */ | |
66b47d42 WD |
92 | + case 'P': |
93 | + new_mflags |= MATCHFLG_RECEIVER_SIDE; | |
94 | + mods = MODIFIERS_HIDE_PROTECT; | |
95 | + break; | |
96 | case '!': | |
97 | new_mflags |= MATCHFLG_CLEAR_LIST; | |
98 | mods = NULL; | |
92172906 | 99 | @@ -759,6 +791,12 @@ static const char *parse_rule_tok(const |
66b47d42 WD |
100 | case 'n': |
101 | new_mflags |= MATCHFLG_NO_INHERIT; | |
102 | break; | |
103 | + case 'r': | |
104 | + new_mflags |= MATCHFLG_RECEIVER_SIDE; | |
105 | + break; | |
106 | + case 's': | |
107 | + new_mflags |= MATCHFLG_SENDER_SIDE; | |
108 | + break; | |
109 | case 'w': | |
110 | new_mflags |= MATCHFLG_WORD_SPLIT; | |
111 | break; | |
92172906 | 112 | @@ -1013,6 +1051,11 @@ char *get_rule_prefix(int match_flags, c |
66b47d42 WD |
113 | } |
114 | if (match_flags & MATCHFLG_EXCLUDE_SELF) | |
115 | *op++ = 'e'; | |
116 | + if (match_flags & MATCHFLG_SENDER_SIDE && !for_xfer) | |
117 | + *op++ = 's'; | |
118 | + if (match_flags & MATCHFLG_RECEIVER_SIDE | |
afc5ee90 | 119 | + && (!for_xfer || (delete_excluded && am_sender))) |
66b47d42 WD |
120 | + *op++ = 'r'; |
121 | if (legal_len) | |
122 | *op++ = ' '; | |
123 | if (op - buf > legal_len) | |
92172906 | 124 | @@ -1025,19 +1068,37 @@ char *get_rule_prefix(int match_flags, c |
66b47d42 WD |
125 | |
126 | static void send_rules(int f_out, struct filter_list_struct *flp) | |
127 | { | |
128 | - struct filter_struct *ent; | |
129 | + struct filter_struct *ent, *prev = NULL; | |
130 | ||
131 | for (ent = flp->head; ent; ent = ent->next) { | |
132 | unsigned int len, plen, dlen; | |
133 | + int elide = 0; | |
134 | char *p; | |
135 | ||
136 | + if (ent->match_flags & MATCHFLG_SENDER_SIDE) | |
137 | + elide = am_sender ? 1 : -1; | |
138 | + if (ent->match_flags & MATCHFLG_RECEIVER_SIDE) | |
139 | + elide = elide ? 0 : am_sender ? -1 : 1; | |
140 | + else if (delete_excluded) | |
141 | + elide = am_sender ? 1 : -1; | |
142 | + if (elide < 0) { | |
143 | + if (prev) | |
144 | + prev->next = ent->next; | |
145 | + else | |
146 | + flp->head = ent->next; | |
147 | + } else | |
148 | + prev = ent; | |
149 | + if (elide > 0) | |
150 | + continue; | |
151 | if (ent->match_flags & MATCHFLG_CVS_IGNORE | |
152 | && !(ent->match_flags & MATCHFLG_MERGE_FILE)) { | |
153 | - if (am_sender || protocol_version < 29) { | |
154 | - send_rules(f_out, &cvs_filter_list); | |
155 | + int f = am_sender || protocol_version < 29 ? f_out : -1; | |
156 | + send_rules(f, &cvs_filter_list); | |
157 | + if (f >= 0) | |
158 | continue; | |
159 | - } | |
160 | } | |
161 | + if (f_out < 0) | |
162 | + continue; | |
163 | p = get_rule_prefix(ent->match_flags, ent->pattern, 1, &plen); | |
164 | if (!p) { | |
165 | rprintf(FERROR, | |
92172906 | 166 | @@ -1055,12 +1116,13 @@ static void send_rules(int f_out, struct |
66b47d42 WD |
167 | if (dlen) |
168 | write_byte(f_out, '/'); | |
169 | } | |
170 | + flp->tail = prev; | |
171 | } | |
172 | ||
173 | /* This is only called by the client. */ | |
174 | void send_filter_list(int f_out) | |
175 | { | |
176 | - int receiver_wants_list = delete_mode && !delete_excluded; | |
177 | + int receiver_wants_list = delete_mode && delete_excluded != 1; | |
178 | ||
179 | if (local_server || (am_sender && !receiver_wants_list)) | |
180 | f_out = -1; | |
92172906 | 181 | @@ -1075,10 +1137,10 @@ void send_filter_list(int f_out) |
66b47d42 WD |
182 | if (list_only == 1 && !recurse) |
183 | parse_rule(&filter_list, "/*/*", MATCHFLG_NO_PREFIXES, 0); | |
184 | ||
185 | - if (f_out >= 0) { | |
186 | - send_rules(f_out, &filter_list); | |
187 | + send_rules(f_out, &filter_list); | |
188 | + | |
189 | + if (f_out >= 0) | |
190 | write_int(f_out, 0); | |
191 | - } | |
192 | ||
193 | if (cvs_exclude) { | |
194 | if (!am_sender || protocol_version < 29) | |
92172906 | 195 | @@ -1094,7 +1156,7 @@ void recv_filter_list(int f_in) |
66b47d42 WD |
196 | char line[MAXPATHLEN+MAX_RULE_PREFIX+1]; /* +1 for trailing slash. */ |
197 | int xflags = protocol_version >= 29 ? 0 : XFLG_OLD_PREFIXES; | |
198 | unsigned int len; | |
199 | - int receiver_wants_list = delete_mode && !delete_excluded; | |
200 | + int receiver_wants_list = delete_mode && delete_excluded != 1; | |
201 | ||
202 | if (!local_server && (am_sender || receiver_wants_list)) { | |
203 | while ((len = read_int(f_in)) != 0) { | |
92172906 | 204 | @@ -1111,4 +1173,7 @@ void recv_filter_list(int f_in) |
66b47d42 WD |
205 | if (local_server || am_sender) |
206 | parse_rule(&filter_list, "-C", 0, 0); | |
207 | } | |
208 | + | |
209 | + if (local_server) /* filter out any rules that aren't for us. */ | |
210 | + send_rules(-1, &filter_list); | |
211 | } | |
afc5ee90 | 212 | --- orig/flist.c 2005-02-09 02:37:15 |
66b47d42 | 213 | +++ flist.c 2005-02-05 05:31:09 |
afc5ee90 | 214 | @@ -978,7 +978,7 @@ void send_file_name(int f, struct file_l |
66b47d42 WD |
215 | |
216 | /* f is set to -1 when calculating deletion file list */ | |
217 | file = make_file(fname, flist, | |
218 | - f == -1 && delete_excluded? SERVER_FILTERS : ALL_FILTERS); | |
219 | + f == -1 && delete_excluded == 1 ? SERVER_FILTERS : ALL_FILTERS); | |
220 | ||
221 | if (!file) | |
222 | return; | |
92172906 | 223 | --- orig/rsync.h 2005-02-07 20:41:57 |
66b47d42 WD |
224 | +++ rsync.h 2005-02-05 05:31:10 |
225 | @@ -565,9 +565,12 @@ struct map_struct { | |
226 | #define MATCHFLG_FINISH_SETUP (1<<13)/* per-dir merge file needs setup */ | |
227 | #define MATCHFLG_NEGATE (1<<14)/* rule matches when pattern does not */ | |
228 | #define MATCHFLG_CVS_IGNORE (1<<15)/* rule was -C or :C */ | |
85f55536 WD |
229 | +#define MATCHFLG_SENDER_SIDE (1<<16)/* rule applies to the sending side */ |
230 | +#define MATCHFLG_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */ | |
66b47d42 WD |
231 | |
232 | #define MATCHFLGS_FROM_CONTAINER (MATCHFLG_ABS_PATH | MATCHFLG_INCLUDE \ | |
233 | - | MATCHFLG_DIRECTORY | MATCHFLG_NEGATE) | |
234 | + | MATCHFLG_DIRECTORY | MATCHFLG_SENDER_SIDE \ | |
235 | + | MATCHFLG_NEGATE | MATCHFLG_RECEIVER_SIDE) | |
236 | ||
237 | struct filter_struct { | |
238 | struct filter_struct *next; | |
85f55536 | 239 | --- orig/rsync.yo 2005-02-11 10:53:15 |
8d30d1c3 | 240 | +++ rsync.yo 2005-02-11 22:40:50 |
85f55536 | 241 | @@ -679,7 +679,9 @@ send the whole directory (e.g. "dir" or |
66b47d42 WD |
242 | for the directory's contents (e.g. "dir/*") since the wildcard is expanded |
243 | by the shell and rsync thus gets a request to transfer individual files, not | |
244 | the files' parent directory. Files that are excluded from transfer are | |
245 | -excluded from being deleted unless you use bf(--delete-excluded). | |
246 | +also excluded from being deleted unless you use the bf(--delete-excluded) | |
247 | +option or mark the rules as only matching on the sending side (see the | |
248 | +include/exclude modifiers in the FILTER RULES section). | |
249 | ||
250 | This option has no effect unless directory recursion is enabled. | |
251 | ||
85f55536 | 252 | @@ -726,6 +728,9 @@ See bf(--delete) (which is implied) for |
66b47d42 WD |
253 | dit(bf(--delete-excluded)) In addition to deleting the files on the |
254 | receiving side that are not on the sending side, this tells rsync to also | |
255 | delete any files on the receiving side that are excluded (see bf(--exclude)). | |
256 | +See the FILTER RULES section for a way to make individual exclusions behave | |
257 | +this way on the receiver, and for a way to protect files from | |
258 | +bf(--delete-excluded). | |
259 | See bf(--delete) (which is implied) for more details on file-deletion. | |
260 | ||
261 | dit(bf(--ignore-errors)) Tells bf(--delete) to go ahead and delete files | |
85f55536 | 262 | @@ -1255,6 +1260,10 @@ bf(exclude, -) specifies an exclude patt |
92172906 WD |
263 | bf(include, +) specifies an include pattern. nl() |
264 | bf(merge, .) specifies a merge-file to read for more rules. nl() | |
265 | bf(dir-merge, :) specifies a per-directory merge-file. nl() | |
266 | +bf(hide, H) specifies a pattern for hiding files from the transfer. nl() | |
8d30d1c3 | 267 | +bf(show, S) files that match the pattern are not hidden. nl() |
92172906 | 268 | +bf(protect, P) specifies a pattern for protecting files from deletion. nl() |
8d30d1c3 | 269 | +bf(risk, R) files that match the pattern are not protected. nl() |
92172906 | 270 | bf(clear, !) clears the current include/exclude list (takes no arg) nl() |
66b47d42 WD |
271 | ) |
272 | ||
85f55536 | 273 | @@ -1279,8 +1288,8 @@ the bf(--include-from)/bf(--exclude-from |
66b47d42 WD |
274 | |
275 | manpagesection(INCLUDE/EXCLUDE PATTERN RULES) | |
276 | ||
277 | -You can include and exclude files by specifying patterns using the "+" and | |
34ec332e | 278 | -"-" filter rules (as introduced in the FILTER RULES section above). |
66b47d42 | 279 | +You can include and exclude files by specifying patterns using the "+", |
92172906 | 280 | +"-", etc. filter rules (as introduced in the FILTER RULES section above). |
34ec332e WD |
281 | The include/exclude rules each specify a pattern that is matched against |
282 | the names of the files that are going to be transferred. These patterns | |
92172906 | 283 | can take several forms: |
85f55536 | 284 | @@ -1419,7 +1428,9 @@ itemize( |
92172906 WD |
285 | it() You may also specify any of the modifiers for the "+" or "-" rules |
286 | (below) in order to have the rules that are read-in from the file | |
287 | default to having that modifier set. For instance, "merge,-/_.excl" would | |
288 | - treat the contents of .excl as absolute-path excludes. | |
289 | + treat the contents of .excl as absolute-path excludes, | |
290 | + while "dir-merge,s_.filt" and ":sC" would each make all their | |
291 | + per-directory rules apply only on the server side. | |
66b47d42 WD |
292 | ) |
293 | ||
294 | The following modifiers are accepted after a "+" or "-": | |
85f55536 | 295 | @@ -1435,7 +1446,18 @@ itemize( |
66b47d42 WD |
296 | it() A bf(C) is used to indicate that all the global CVS-exclude rules |
297 | should be inserted as excludes in place of the "-C". No arg should | |
298 | follow. | |
85f55536 | 299 | - ) |
66b47d42 | 300 | + it() An bf(s) is used to indicate that the rule applies to the sending |
85f55536 | 301 | + side. When a rule affects the sending side, it prevents files from |
66b47d42 WD |
302 | + being transferred. The default is for a rule to affect both sides |
303 | + unless bf(--delete-excluded) was specified, in which case default rules | |
85f55536 WD |
304 | + become sender-side only. See also the hide (H) and show (S) rules, |
305 | + which are an alternate way to specify server-side includes/excludes. | |
66b47d42 | 306 | + it() An bf(r) is used to indicate that the rule applies to the receiving |
85f55536 WD |
307 | + side. When a rule affects the receiving side, it prevents files from |
308 | + being deleted. See the bf(s) modifier for more info. See also the | |
8d30d1c3 | 309 | + protect (P) and risk (R) rules, which are an alternate way to |
85f55536 WD |
310 | + specify receiver-side includes/excludes. |
311 | +) | |
66b47d42 WD |
312 | |
313 | Per-directory rules are inherited in all subdirectories of the directory | |
85f55536 | 314 | where the merge-file was found unless the 'n' modifier was used. Each |