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); | |
35 | --- orig/exclude.c 2005-02-05 06:48:21 | |
36 | +++ exclude.c 2005-02-05 06:56:47 | |
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 | |
47 | @@ -667,6 +668,14 @@ static const char *parse_rule_tok(const | |
48 | case '-': | |
49 | mods = MODIFIERS_INCL_EXCL; | |
50 | break; | |
51 | + case 'H': | |
52 | + new_mflags |= MATCHFLG_SENDER_SIDE; | |
53 | + mods = MODIFIERS_HIDE_PROTECT; | |
54 | + break; | |
55 | + case 'P': | |
56 | + new_mflags |= MATCHFLG_RECEIVER_SIDE; | |
57 | + mods = MODIFIERS_HIDE_PROTECT; | |
58 | + break; | |
59 | case '!': | |
60 | new_mflags |= MATCHFLG_CLEAR_LIST; | |
61 | mods = NULL; | |
62 | @@ -719,6 +728,12 @@ static const char *parse_rule_tok(const | |
63 | case 'n': | |
64 | new_mflags |= MATCHFLG_NO_INHERIT; | |
65 | break; | |
66 | + case 'r': | |
67 | + new_mflags |= MATCHFLG_RECEIVER_SIDE; | |
68 | + break; | |
69 | + case 's': | |
70 | + new_mflags |= MATCHFLG_SENDER_SIDE; | |
71 | + break; | |
72 | case 'w': | |
73 | new_mflags |= MATCHFLG_WORD_SPLIT; | |
74 | break; | |
75 | @@ -973,6 +988,11 @@ char *get_rule_prefix(int match_flags, c | |
76 | } | |
77 | if (match_flags & MATCHFLG_EXCLUDE_SELF) | |
78 | *op++ = 'e'; | |
79 | + if (match_flags & MATCHFLG_SENDER_SIDE && !for_xfer) | |
80 | + *op++ = 's'; | |
81 | + if (match_flags & MATCHFLG_RECEIVER_SIDE | |
82 | + && (!for_xfer || delete_excluded)) | |
83 | + *op++ = 'r'; | |
84 | if (legal_len) | |
85 | *op++ = ' '; | |
86 | if (op - buf > legal_len) | |
87 | @@ -985,19 +1005,37 @@ char *get_rule_prefix(int match_flags, c | |
88 | ||
89 | static void send_rules(int f_out, struct filter_list_struct *flp) | |
90 | { | |
91 | - struct filter_struct *ent; | |
92 | + struct filter_struct *ent, *prev = NULL; | |
93 | ||
94 | for (ent = flp->head; ent; ent = ent->next) { | |
95 | unsigned int len, plen, dlen; | |
96 | + int elide = 0; | |
97 | char *p; | |
98 | ||
99 | + if (ent->match_flags & MATCHFLG_SENDER_SIDE) | |
100 | + elide = am_sender ? 1 : -1; | |
101 | + if (ent->match_flags & MATCHFLG_RECEIVER_SIDE) | |
102 | + elide = elide ? 0 : am_sender ? -1 : 1; | |
103 | + else if (delete_excluded) | |
104 | + elide = am_sender ? 1 : -1; | |
105 | + if (elide < 0) { | |
106 | + if (prev) | |
107 | + prev->next = ent->next; | |
108 | + else | |
109 | + flp->head = ent->next; | |
110 | + } else | |
111 | + prev = ent; | |
112 | + if (elide > 0) | |
113 | + continue; | |
114 | if (ent->match_flags & MATCHFLG_CVS_IGNORE | |
115 | && !(ent->match_flags & MATCHFLG_MERGE_FILE)) { | |
116 | - if (am_sender || protocol_version < 29) { | |
117 | - send_rules(f_out, &cvs_filter_list); | |
118 | + int f = am_sender || protocol_version < 29 ? f_out : -1; | |
119 | + send_rules(f, &cvs_filter_list); | |
120 | + if (f >= 0) | |
121 | continue; | |
122 | - } | |
123 | } | |
124 | + if (f_out < 0) | |
125 | + continue; | |
126 | p = get_rule_prefix(ent->match_flags, ent->pattern, 1, &plen); | |
127 | if (!p) { | |
128 | rprintf(FERROR, | |
129 | @@ -1015,12 +1053,13 @@ static void send_rules(int f_out, struct | |
130 | if (dlen) | |
131 | write_byte(f_out, '/'); | |
132 | } | |
133 | + flp->tail = prev; | |
134 | } | |
135 | ||
136 | /* This is only called by the client. */ | |
137 | void send_filter_list(int f_out) | |
138 | { | |
139 | - int receiver_wants_list = delete_mode && !delete_excluded; | |
140 | + int receiver_wants_list = delete_mode && delete_excluded != 1; | |
141 | ||
142 | if (local_server || (am_sender && !receiver_wants_list)) | |
143 | f_out = -1; | |
144 | @@ -1035,10 +1074,10 @@ void send_filter_list(int f_out) | |
145 | if (list_only == 1 && !recurse) | |
146 | parse_rule(&filter_list, "/*/*", MATCHFLG_NO_PREFIXES, 0); | |
147 | ||
148 | - if (f_out >= 0) { | |
149 | - send_rules(f_out, &filter_list); | |
150 | + send_rules(f_out, &filter_list); | |
151 | + | |
152 | + if (f_out >= 0) | |
153 | write_int(f_out, 0); | |
154 | - } | |
155 | ||
156 | if (cvs_exclude) { | |
157 | if (!am_sender || protocol_version < 29) | |
158 | @@ -1054,7 +1093,7 @@ void recv_filter_list(int f_in) | |
159 | char line[MAXPATHLEN+MAX_RULE_PREFIX+1]; /* +1 for trailing slash. */ | |
160 | int xflags = protocol_version >= 29 ? 0 : XFLG_OLD_PREFIXES; | |
161 | unsigned int len; | |
162 | - int receiver_wants_list = delete_mode && !delete_excluded; | |
163 | + int receiver_wants_list = delete_mode && delete_excluded != 1; | |
164 | ||
165 | if (!local_server && (am_sender || receiver_wants_list)) { | |
166 | while ((len = read_int(f_in)) != 0) { | |
167 | @@ -1071,4 +1110,7 @@ void recv_filter_list(int f_in) | |
168 | if (local_server || am_sender) | |
169 | parse_rule(&filter_list, "-C", 0, 0); | |
170 | } | |
171 | + | |
172 | + if (local_server) /* filter out any rules that aren't for us. */ | |
173 | + send_rules(-1, &filter_list); | |
174 | } | |
175 | --- orig/flist.c 2005-02-03 19:23:55 | |
176 | +++ flist.c 2005-02-05 05:31:09 | |
177 | @@ -979,7 +979,7 @@ void send_file_name(int f, struct file_l | |
178 | ||
179 | /* f is set to -1 when calculating deletion file list */ | |
180 | file = make_file(fname, flist, | |
181 | - f == -1 && delete_excluded? SERVER_FILTERS : ALL_FILTERS); | |
182 | + f == -1 && delete_excluded == 1 ? SERVER_FILTERS : ALL_FILTERS); | |
183 | ||
184 | if (!file) | |
185 | return; | |
186 | --- orig/rsync.h 2005-02-04 22:28:09 | |
187 | +++ rsync.h 2005-02-05 05:31:10 | |
188 | @@ -565,9 +565,12 @@ struct map_struct { | |
189 | #define MATCHFLG_FINISH_SETUP (1<<13)/* per-dir merge file needs setup */ | |
190 | #define MATCHFLG_NEGATE (1<<14)/* rule matches when pattern does not */ | |
191 | #define MATCHFLG_CVS_IGNORE (1<<15)/* rule was -C or :C */ | |
192 | +#define MATCHFLG_SENDER_SIDE (1<<16)/* rule applies to the sender side */ | |
193 | +#define MATCHFLG_RECEIVER_SIDE (1<<17)/* rule applies to the receiver side */ | |
194 | ||
195 | #define MATCHFLGS_FROM_CONTAINER (MATCHFLG_ABS_PATH | MATCHFLG_INCLUDE \ | |
196 | - | MATCHFLG_DIRECTORY | MATCHFLG_NEGATE) | |
197 | + | MATCHFLG_DIRECTORY | MATCHFLG_SENDER_SIDE \ | |
198 | + | MATCHFLG_NEGATE | MATCHFLG_RECEIVER_SIDE) | |
199 | ||
200 | struct filter_struct { | |
201 | struct filter_struct *next; | |
34ec332e WD |
202 | --- orig/rsync.yo 2005-02-06 07:24:23 |
203 | +++ rsync.yo 2005-02-06 07:21:31 | |
66b47d42 WD |
204 | @@ -678,7 +678,9 @@ send the whole directory (e.g. "dir" or |
205 | for the directory's contents (e.g. "dir/*") since the wildcard is expanded | |
206 | by the shell and rsync thus gets a request to transfer individual files, not | |
207 | the files' parent directory. Files that are excluded from transfer are | |
208 | -excluded from being deleted unless you use bf(--delete-excluded). | |
209 | +also excluded from being deleted unless you use the bf(--delete-excluded) | |
210 | +option or mark the rules as only matching on the sending side (see the | |
211 | +include/exclude modifiers in the FILTER RULES section). | |
212 | ||
213 | This option has no effect unless directory recursion is enabled. | |
214 | ||
215 | @@ -725,6 +727,9 @@ See bf(--delete) (which is implied) for | |
216 | dit(bf(--delete-excluded)) In addition to deleting the files on the | |
217 | receiving side that are not on the sending side, this tells rsync to also | |
218 | delete any files on the receiving side that are excluded (see bf(--exclude)). | |
219 | +See the FILTER RULES section for a way to make individual exclusions behave | |
220 | +this way on the receiver, and for a way to protect files from | |
221 | +bf(--delete-excluded). | |
222 | See bf(--delete) (which is implied) for more details on file-deletion. | |
223 | ||
224 | dit(bf(--ignore-errors)) Tells bf(--delete) to go ahead and delete files | |
225 | @@ -1241,6 +1246,8 @@ bf(-) specifies an exclude pattern. nl() | |
226 | bf(+) specifies an include pattern. nl() | |
227 | bf(.) specifies a merge-file to read for more rules. nl() | |
228 | bf(:) specifies a per-directory merge-file. nl() | |
229 | +bf(H) specifies a pattern for hiding files from the transfer. nl() | |
230 | +bf(P) specifies a pattern for protecting files from deletion. nl() | |
231 | bf(!) clears the current include/exclude list (takes no arg) nl() | |
232 | ) | |
233 | ||
34ec332e | 234 | @@ -1263,8 +1270,13 @@ comment lines that start with a "#". |
66b47d42 WD |
235 | |
236 | manpagesection(INCLUDE/EXCLUDE PATTERN RULES) | |
237 | ||
238 | -You can include and exclude files by specifying patterns using the "+" and | |
34ec332e | 239 | -"-" filter rules (as introduced in the FILTER RULES section above). |
66b47d42 WD |
240 | +You can include and exclude files by specifying patterns using the "+", |
241 | +"-", "H", and "P" filter rules (as introduced in the FILTER RULES section | |
242 | +above). | |
243 | +Note that the "H" (hide) rule is just a more intuitive way to specify a "-" | |
244 | +rule with an "s" modifier (a sender-only exclusion) and "P" (protect) is | |
245 | +just a more intuitive way to specify a "-" rule with an "r" modifier (a | |
246 | +receiver-only exclusion). See the modifiers below for more information. | |
66b47d42 | 247 | |
34ec332e WD |
248 | The include/exclude rules each specify a pattern that is matched against |
249 | the names of the files that are going to be transferred. These patterns | |
250 | @@ -1402,7 +1414,9 @@ itemize( | |
66b47d42 | 251 | specified to turn off the parsing of prefixes). |
34ec332e WD |
252 | it() You may also specify any of the modifiers for "+" or "-" to have the |
253 | rules that are read-in default to having that option set. For instance, | |
254 | - ".-/_.excl" would treat the contents of .excl as absolute-path excludes. | |
255 | + ".-/_.excl" would treat the contents of .excl as absolute-path excludes, | |
256 | + while ":s_.filt" and ":Cs" would each make all their per-directory | |
257 | + rules apply only on the server side. | |
66b47d42 WD |
258 | ) |
259 | ||
260 | The following modifiers are accepted after a "+" or "-": | |
34ec332e | 261 | @@ -1418,6 +1432,16 @@ itemize( |
66b47d42 WD |
262 | it() A bf(C) is used to indicate that all the global CVS-exclude rules |
263 | should be inserted as excludes in place of the "-C". No arg should | |
264 | follow. | |
265 | + it() An bf(s) is used to indicate that the rule applies to the sending | |
266 | + side. When a rule affects the sending side it, prevents files from | |
267 | + being transferred. The default is for a rule to affect both sides | |
268 | + unless bf(--delete-excluded) was specified, in which case default rules | |
269 | + become sender-side only. See also the "H" (hide) rule, which is an | |
270 | + alias for the "-" rule with the "s" modifer. | |
271 | + it() An bf(r) is used to indicate that the rule applies to the receiving | |
272 | + side. When a rule affects the receiving side it, prevents files from | |
273 | + being deleted. See the bf(s) modifier for more info. See also the "P" | |
274 | + (protect) rule, which is an alias for the "-" rule with the "r" modifier. | |
275 | ) | |
276 | ||
277 | Per-directory rules are inherited in all subdirectories of the directory |