Fixed a failing hunk.
[rsync/rsync-patches.git] / sender-receiver-excludes.diff
CommitLineData
66b47d42
WD
1This patch adds two modifiers to the filter rule prefixes that allow a
2rule to be marked as sender-side (s), receiver-side (r), or both ("sr"
3or omitted). Sender-side rules prevent files from being transferred,
4while receiver-side rules prevent files from being deleted. The default
5for an unmodified include/exclude rule is to affect both sides, but a
6rule that is explicitly marked as affecting both sides will remain
7unaffected by the --delete-excluded option (that option changes any
8unmodified rules into server-side only rules).
9
10See 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