Have partial_dir_fname() also check if the dir is excluded
[rsync/rsync.git] / options.c
... / ...
CommitLineData
1/* -*- c-file-style: "linux" -*-
2 *
3 * Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
4 * Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "rsync.h"
22#include "popt.h"
23
24extern int module_id;
25extern int sanitize_paths;
26extern int select_timeout;
27extern struct filter_list_struct filter_list;
28extern struct filter_list_struct server_filter_list;
29
30int make_backups = 0;
31
32/**
33 * If 1, send the whole file as literal data rather than trying to
34 * create an incremental diff.
35 *
36 * If -1, then look at whether we're local or remote and go by that.
37 *
38 * @sa disable_deltas_p()
39 **/
40int whole_file = -1;
41
42int archive_mode = 0;
43int keep_dirlinks = 0;
44int copy_links = 0;
45int preserve_links = 0;
46int preserve_hard_links = 0;
47int preserve_perms = 0;
48int preserve_devices = 0;
49int preserve_uid = 0;
50int preserve_gid = 0;
51int preserve_times = 0;
52int omit_dir_times = 0;
53int update_only = 0;
54int cvs_exclude = 0;
55int dry_run = 0;
56int ignore_times = 0;
57int delete_mode = 0;
58int delete_during = 0;
59int delete_before = 0;
60int delete_after = 0;
61int delete_excluded = 0;
62int one_file_system = 0;
63int protocol_version = PROTOCOL_VERSION;
64int sparse_files = 0;
65int do_compression = 0;
66int am_root = 0;
67int orig_umask = 0;
68int relative_paths = -1;
69int implied_dirs = 1;
70int numeric_ids = 0;
71int force_delete = 0;
72int io_timeout = 0;
73int am_server = 0;
74int am_sender = -1;
75int am_generator = 0;
76char *files_from = NULL;
77int filesfrom_fd = -1;
78char *remote_filesfrom_file = NULL;
79int eol_nulls = 0;
80int recurse = 0;
81int xfer_dirs = 0;
82int am_daemon = 0;
83int daemon_over_rsh = 0;
84int do_stats = 0;
85int do_progress = 0;
86int keep_partial = 0;
87int safe_symlinks = 0;
88int copy_unsafe_links = 0;
89int size_only = 0;
90int daemon_bwlimit = 0;
91int bwlimit = 0;
92size_t bwlimit_writemax = 0;
93int only_existing = 0;
94int opt_ignore_existing = 0;
95int max_delete = 0;
96OFF_T max_size = 0;
97int ignore_errors = 0;
98int modify_window = 0;
99int blocking_io = -1;
100int checksum_seed = 0;
101int inplace = 0;
102int delay_updates = 0;
103long block_size = 0; /* "long" because popt can't set an int32. */
104
105
106/** Network address family. **/
107#if INET6
108int default_af_hint = 0; /* Any protocol */
109#else
110int default_af_hint = AF_INET; /* Must use IPv4 */
111#endif
112
113/** Do not go into the background when run as --daemon. Good
114 * for debugging and required for running as a service on W32,
115 * or under Unix process-monitors. **/
116int no_detach = 0;
117
118int write_batch = 0;
119int read_batch = 0;
120int backup_dir_len = 0;
121int backup_suffix_len;
122unsigned int backup_dir_remainder;
123
124char *backup_suffix = NULL;
125char *tmpdir = NULL;
126char *partial_dir = NULL;
127char *basis_dir[MAX_BASIS_DIRS+1];
128char *config_file = NULL;
129char *shell_cmd = NULL;
130char *log_format = NULL;
131char *password_file = NULL;
132char *rsync_path = RSYNC_PATH;
133char *backup_dir = NULL;
134char backup_dir_buf[MAXPATHLEN];
135int rsync_port = 0;
136int compare_dest = 0;
137int copy_dest = 0;
138int link_dest = 0;
139int basis_dir_cnt = 0;
140
141int verbose = 0;
142int quiet = 0;
143int always_checksum = 0;
144int list_only = 0;
145
146#define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
147char *batch_name = NULL;
148
149static int daemon_opt; /* sets am_daemon after option error-reporting */
150static int F_option_cnt = 0;
151static int modify_window_set;
152static char *dest_option = NULL;
153static char *max_size_arg;
154
155/** Local address to bind. As a character string because it's
156 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
157 * address, or a hostname. **/
158char *bind_address;
159
160
161static void print_rsync_version(enum logcode f)
162{
163 char const *got_socketpair = "no ";
164 char const *have_inplace = "no ";
165 char const *hardlinks = "no ";
166 char const *links = "no ";
167 char const *ipv6 = "no ";
168 STRUCT_STAT *dumstat;
169
170#if HAVE_SOCKETPAIR
171 got_socketpair = "";
172#endif
173
174#if HAVE_FTRUNCATE
175 have_inplace = "";
176#endif
177
178#if SUPPORT_HARD_LINKS
179 hardlinks = "";
180#endif
181
182#if SUPPORT_LINKS
183 links = "";
184#endif
185
186#if INET6
187 ipv6 = "";
188#endif
189
190 rprintf(f, "%s version %s protocol version %d\n",
191 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
192 rprintf(f,
193 "Copyright (C) 1996-2005 by Andrew Tridgell and others\n");
194 rprintf(f, "<http://rsync.samba.org/>\n");
195 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
196 "%shard links, %ssymlinks, batchfiles, \n",
197 (int) (sizeof (OFF_T) * 8),
198 got_socketpair, hardlinks, links);
199
200 /* Note that this field may not have type ino_t. It depends
201 * on the complicated interaction between largefile feature
202 * macros. */
203 rprintf(f, " %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
204 have_inplace, ipv6,
205 (int) (sizeof dumstat->st_ino * 8),
206 (int) (sizeof (int64) * 8));
207#ifdef MAINTAINER_MODE
208 rprintf(f, " panic action: \"%s\"\n",
209 get_panic_action());
210#endif
211
212#if SIZEOF_INT64 < 8
213 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
214#endif
215 if (sizeof (int64) != SIZEOF_INT64) {
216 rprintf(f,
217 "WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
218 (int) SIZEOF_INT64, (int) sizeof (int64));
219 }
220
221 rprintf(f,
222"\n"
223"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
224"are welcome to redistribute it under certain conditions. See the GNU\n"
225"General Public Licence for details.\n"
226 );
227}
228
229
230void usage(enum logcode F)
231{
232 print_rsync_version(F);
233
234 rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
235
236 rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
237 rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
238 rprintf(F," or rsync [OPTION]... SRC [SRC]... DEST\n");
239 rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
240 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
241 rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
242 rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
243 rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
244 rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
245 rprintf(F," sources separated by space as long as they have same top-level\n");
246 rprintf(F,"\nOptions\n");
247 rprintf(F," -v, --verbose increase verbosity\n");
248 rprintf(F," -q, --quiet suppress non-error messages\n");
249 rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n");
250 rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H)\n");
251 rprintf(F," -r, --recursive recurse into directories\n");
252 rprintf(F," -R, --relative use relative path names\n");
253 rprintf(F," --no-relative turn off --relative\n");
254 rprintf(F," --no-implied-dirs don't send implied dirs with -R\n");
255 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
256 rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
257 rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
258 rprintf(F," -u, --update skip files that are newer on the receiver\n");
259 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
260 rprintf(F," -d, --dirs transfer directories without recursing\n");
261 rprintf(F," -l, --links copy symlinks as symlinks\n");
262 rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
263 rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n");
264 rprintf(F," --safe-links ignore symlinks that point outside the source tree\n");
265 rprintf(F," -H, --hard-links preserve hard links\n");
266 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
267 rprintf(F," -p, --perms preserve permissions\n");
268 rprintf(F," -o, --owner preserve owner (root only)\n");
269 rprintf(F," -g, --group preserve group\n");
270 rprintf(F," -D, --devices preserve devices (root only)\n");
271 rprintf(F," -t, --times preserve times\n");
272 rprintf(F," -O, --omit-dir-times omit directories when preserving times\n");
273 rprintf(F," -S, --sparse handle sparse files efficiently\n");
274 rprintf(F," -n, --dry-run show what would have been transferred\n");
275 rprintf(F," -W, --whole-file copy files whole\n");
276 rprintf(F," --no-whole-file always use incremental rsync algorithm\n");
277 rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
278 rprintf(F," -B, --block-size=SIZE force a fixed checksum block-size\n");
279 rprintf(F," -e, --rsh=COMMAND specify the remote shell to use\n");
280 rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
281 rprintf(F," --existing only update files that already exist on receiver\n");
282 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
283 rprintf(F," --del an alias for --delete-during\n");
284 rprintf(F," --delete delete files that don't exist on the sending side\n");
285 rprintf(F," --delete-before receiver deletes before transfer (default)\n");
286 rprintf(F," --delete-during receiver deletes during transfer, not before\n");
287 rprintf(F," --delete-after receiver deletes after transfer, not before\n");
288 rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
289 rprintf(F," --ignore-errors delete even if there are I/O errors\n");
290 rprintf(F," --force force deletion of directories even if not empty\n");
291 rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
292 rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n");
293 rprintf(F," --partial keep partially transferred files\n");
294 rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
295 rprintf(F," --delay-updates put all updated files into place at transfer's end\n");
296 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
297 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
298 rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
299 rprintf(F," --size-only skip files that match in size\n");
300 rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
301 rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
302 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
303 rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
304 rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
305 rprintf(F," -z, --compress compress file data\n");
306 rprintf(F," -C, --cvs-exclude auto-ignore files the same way CVS does\n");
307 rprintf(F," -f, --filter=RULE add a file-filtering RULE\n");
308 rprintf(F," -F same as --filter=': /.rsync-filter'\n");
309 rprintf(F," repeated: --filter='- .rsync-filter'\n");
310 rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
311 rprintf(F," --exclude-from=FILE read exclude patterns from FILE\n");
312 rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
313 rprintf(F," --include-from=FILE read include patterns from FILE\n");
314 rprintf(F," --files-from=FILE read list of source-file names from FILE\n");
315 rprintf(F," -0, --from0 all *-from file lists are delimited by nulls\n");
316 rprintf(F," --version print version number\n");
317 rprintf(F," --port=PORT specify double-colon alternate port number\n");
318 rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
319 rprintf(F," --no-blocking-io turn off blocking I/O when it is the default\n");
320 rprintf(F," --stats give some file-transfer stats\n");
321 rprintf(F," --progress show progress during transfer\n");
322 rprintf(F," -P same as --partial --progress\n");
323 rprintf(F," --log-format=FORMAT log file-transfers using specified format\n");
324 rprintf(F," --password-file=FILE read password from FILE\n");
325 rprintf(F," --list-only list the files instead of copying them\n");
326 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
327 rprintf(F," --write-batch=FILE write a batched update to FILE\n");
328 rprintf(F," --read-batch=FILE read a batched update from FILE\n");
329#if INET6
330 rprintf(F," -4, --ipv4 prefer IPv4\n");
331 rprintf(F," -6, --ipv6 prefer IPv6\n");
332#endif
333 rprintf(F," -h, --help show this help screen\n");
334
335 rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
336 rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
337 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
338}
339
340enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
341 OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
342 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
343 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
344 OPT_REFUSED_BASE = 9000};
345
346static struct poptOption long_options[] = {
347 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
348 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
349 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
350 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
351 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
352 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
353 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
354 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
355 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
356 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
357 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
358 {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
359 {"delete-before", 0, POPT_ARG_VAL, &delete_before, 2, 0, 0 },
360 {"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
361 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
362 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
363 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
364 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
365 {"filter", 'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
366 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
367 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
368 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
369 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
370 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
371 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
372 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
373 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
374 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
375 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
376 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
377 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
378 {"dirs", 'd', POPT_ARG_VAL, &xfer_dirs, 2, 0, 0 },
379 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
380 {"copy-links", 'L', POPT_ARG_NONE, &copy_links, 0, 0, 0 },
381 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
382 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
383 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
384 {"copy-unsafe-links", 0, POPT_ARG_NONE, &copy_unsafe_links, 0, 0, 0 },
385 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
386 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
387 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
388 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
389 {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
390 {"omit-dir-times", 'O', POPT_ARG_NONE, &omit_dir_times, 0, 0, 0 },
391 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
392 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
393 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
394 {"archive", 'a', POPT_ARG_NONE, &archive_mode, 0, 0, 0 },
395 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
396 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
397 {"recursive", 'r', POPT_ARG_VAL, &recurse, -1, 0, 0 },
398 {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
399 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
400 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
401 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
402 {"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
403 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
404 {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
405 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
406 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
407 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
408 {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
409 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
410 /* TODO: Should this take an optional int giving the compression level? */
411 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
412 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
413 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
414 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
415 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
416 {"delay-updates", 0, POPT_ARG_NONE, &delay_updates, 0, 0, 0 },
417 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
418 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
419 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
420 {0, 'F', POPT_ARG_NONE, 0, 'F', 0, 0 },
421 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
422 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
423 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
424 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
425 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
426 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
427 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
428 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
429 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
430 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
431 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
432 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
433 {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
434#if INET6
435 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
436 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
437#endif
438 /* All these options switch us into daemon-mode option-parsing. */
439 {"address", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
440 {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
441 {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
442 {"no-detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
443 {0,0,0,0, 0, 0, 0}
444};
445
446static void daemon_usage(enum logcode F)
447{
448 print_rsync_version(F);
449
450 rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
451 rprintf(F," --address=ADDRESS bind to the specified address\n");
452 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
453 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
454 rprintf(F," --no-detach do not detach from the parent\n");
455 rprintf(F," --port=PORT listen on alternate port number\n");
456 rprintf(F," -v, --verbose increase verbosity\n");
457#if INET6
458 rprintf(F," -4, --ipv4 prefer IPv4\n");
459 rprintf(F," -6, --ipv6 prefer IPv6\n");
460#endif
461 rprintf(F," -h, --help show this help screen\n");
462
463 rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
464 rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
465}
466
467static struct poptOption long_daemon_options[] = {
468 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
469 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
470 {"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
471 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
472 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
473#if INET6
474 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
475 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
476#endif
477 {"no-detach", 0, POPT_ARG_NONE, &no_detach, 0, 0, 0 },
478 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
479 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
480 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
481 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
482 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
483 {0,0,0,0, 0, 0, 0}
484};
485
486
487static char err_buf[200];
488
489
490/**
491 * Store the option error message, if any, so that we can log the
492 * connection attempt (which requires parsing the options), and then
493 * show the error later on.
494 **/
495void option_error(void)
496{
497 if (!err_buf[0]) {
498 strcpy(err_buf, "Error parsing options: "
499 "option may be supported on client but not on server?\n");
500 }
501
502 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
503}
504
505
506/**
507 * Tweak the option table to disable all options that the rsyncd.conf
508 * file has told us to refuse.
509 **/
510static void set_refuse_options(char *bp)
511{
512 struct poptOption *op;
513 char *cp, shortname[2];
514 int is_wild, found_match;
515
516 shortname[1] = '\0';
517
518 while (1) {
519 while (*bp == ' ') bp++;
520 if (!*bp)
521 break;
522 if ((cp = strchr(bp, ' ')) != NULL)
523 *cp= '\0';
524 /* If they specify "delete", reject all delete options. */
525 if (strcmp(bp, "delete") == 0)
526 bp = "delete*";
527 is_wild = strpbrk(bp, "*?[") != NULL;
528 found_match = 0;
529 for (op = long_options; ; op++) {
530 *shortname = op->shortName;
531 if (!op->longName && !*shortname)
532 break;
533 if ((op->longName && wildmatch(bp, op->longName))
534 || (*shortname && wildmatch(bp, shortname))) {
535 if (op->argInfo == POPT_ARG_VAL)
536 op->argInfo = POPT_ARG_NONE;
537 op->val = (op - long_options) + OPT_REFUSED_BASE;
538 found_match = 1;
539 if (!is_wild)
540 break;
541 }
542 }
543 if (!found_match) {
544 rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
545 bp);
546 }
547 if (!cp)
548 break;
549 *cp = ' ';
550 bp = cp + 1;
551 }
552}
553
554
555static int count_args(const char **argv)
556{
557 int i = 0;
558
559 if (argv) {
560 while (argv[i] != NULL)
561 i++;
562 }
563
564 return i;
565}
566
567
568/**
569 * Process command line arguments. Called on both local and remote.
570 *
571 * @retval 1 if all options are OK; with globals set to appropriate
572 * values
573 *
574 * @retval 0 on error, with err_buf containing an explanation
575 **/
576int parse_arguments(int *argc, const char ***argv, int frommain)
577{
578 int opt;
579 char *ref = lp_refuse_options(module_id);
580 const char *arg;
581 poptContext pc;
582
583 if (ref && *ref)
584 set_refuse_options(ref);
585
586 /* TODO: Call poptReadDefaultConfig; handle errors. */
587
588 /* The context leaks in case of an error, but if there's a
589 * problem we always exit anyhow. */
590 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
591 {
592 struct poptAlias my_alias;
593 char **argv = new_array(char *, 1);
594 argv[0] = strdup("--delete-during");
595 my_alias.longName = "del", my_alias.shortName = '\0';
596 my_alias.argc = 1;
597 my_alias.argv = (const char **)argv;
598 if (argv && argv[0])
599 poptAddAlias(pc, my_alias, 0);
600 }
601 poptReadDefaultConfig(pc, 0);
602
603 while ((opt = poptGetNextOpt(pc)) != -1) {
604 /* most options are handled automatically by popt;
605 * only special cases are returned and listed here. */
606
607 switch (opt) {
608 case OPT_VERSION:
609 print_rsync_version(FINFO);
610 exit_cleanup(0);
611
612 case OPT_DAEMON:
613 if (am_daemon) {
614 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
615 return 0;
616 }
617 poptFreeContext(pc);
618 pc = poptGetContext(RSYNC_NAME, *argc, *argv,
619 long_daemon_options, 0);
620 while ((opt = poptGetNextOpt(pc)) != -1) {
621 switch (opt) {
622 case 'h':
623 daemon_usage(FINFO);
624 exit_cleanup(0);
625
626 case 'v':
627 verbose++;
628 break;
629
630 default:
631 rprintf(FERROR,
632 "rsync: %s: %s (in daemon mode)\n",
633 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
634 poptStrerror(opt));
635 goto daemon_error;
636 }
637 }
638 if (!daemon_opt) {
639 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
640 daemon_error:
641 rprintf(FERROR,
642 "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
643 exit_cleanup(RERR_SYNTAX);
644 }
645 *argv = poptGetArgs(pc);
646 *argc = count_args(*argv);
647 daemon_opt = 0;
648 am_daemon = 1;
649 return 1;
650
651 case OPT_MODIFY_WINDOW:
652 /* The value has already been set by popt, but
653 * we need to remember that we're using a
654 * non-default setting. */
655 modify_window_set = 1;
656 break;
657
658 case OPT_FILTER:
659 parse_rule(&filter_list, poptGetOptArg(pc), 0, 0);
660 break;
661
662 case OPT_EXCLUDE:
663 parse_rule(&filter_list, poptGetOptArg(pc),
664 0, XFLG_OLD_PREFIXES);
665 break;
666
667 case OPT_INCLUDE:
668 parse_rule(&filter_list, poptGetOptArg(pc),
669 MATCHFLG_INCLUDE, XFLG_OLD_PREFIXES);
670 break;
671
672 case OPT_EXCLUDE_FROM:
673 case OPT_INCLUDE_FROM:
674 arg = poptGetOptArg(pc);
675 if (sanitize_paths)
676 arg = sanitize_path(NULL, arg, NULL, 0);
677 if (server_filter_list.head) {
678 char *cp = (char *)arg;
679 clean_fname(cp, 1);
680 if (check_filter(&server_filter_list, cp, 0) < 0)
681 goto options_rejected;
682 }
683 parse_filter_file(&filter_list, arg,
684 opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
685 XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
686 break;
687
688 case 'h':
689 usage(FINFO);
690 exit_cleanup(0);
691
692 case 'v':
693 verbose++;
694 break;
695
696 case 'q':
697 if (frommain)
698 quiet++;
699 break;
700
701 case OPT_SENDER:
702 if (!am_server) {
703 usage(FERROR);
704 exit_cleanup(RERR_SYNTAX);
705 }
706 am_sender = 1;
707 break;
708
709 case 'F':
710 switch (++F_option_cnt) {
711 case 1:
712 parse_rule(&filter_list,": /.rsync-filter",0,0);
713 break;
714 case 2:
715 parse_rule(&filter_list,"- .rsync-filter",0,0);
716 break;
717 }
718 break;
719
720 case 'P':
721 do_progress = 1;
722 keep_partial = 1;
723 break;
724
725 case OPT_WRITE_BATCH:
726 /* batch_name is already set */
727 write_batch = 1;
728 break;
729
730 case OPT_READ_BATCH:
731 /* batch_name is already set */
732 read_batch = 1;
733 break;
734
735 case OPT_MAX_SIZE:
736 for (arg = max_size_arg; isdigit(*(uchar*)arg); arg++) {}
737 if (*arg == '.')
738 for (arg++; isdigit(*(uchar*)arg); arg++) {}
739 switch (*arg) {
740 case 'k': case 'K':
741 max_size = atof(max_size_arg) * 1024;
742 break;
743 case 'm': case 'M':
744 max_size = atof(max_size_arg) * 1024*1024;
745 break;
746 case 'g': case 'G':
747 max_size = atof(max_size_arg) * 1024*1024*1024;
748 break;
749 case '\0':
750 max_size = atof(max_size_arg);
751 break;
752 default:
753 max_size = 0;
754 break;
755 }
756 if (max_size <= 0) {
757 snprintf(err_buf, sizeof err_buf,
758 "--max-size value is invalid: %s\n",
759 max_size_arg);
760 return 0;
761 }
762 break;
763
764 case OPT_TIMEOUT:
765 if (io_timeout && io_timeout < select_timeout)
766 select_timeout = io_timeout;
767 break;
768
769 case OPT_LINK_DEST:
770#if HAVE_LINK
771 link_dest = 1;
772 dest_option = "--link-dest";
773 goto set_dest_dir;
774#else
775 snprintf(err_buf, sizeof err_buf,
776 "hard links are not supported on this %s\n",
777 am_server ? "server" : "client");
778 return 0;
779#endif
780
781 case OPT_COPY_DEST:
782 copy_dest = 1;
783 dest_option = "--copy-dest";
784 goto set_dest_dir;
785
786 case OPT_COMPARE_DEST:
787 compare_dest = 1;
788 dest_option = "--compare-dest";
789 set_dest_dir:
790 if (basis_dir_cnt >= MAX_BASIS_DIRS) {
791 snprintf(err_buf, sizeof err_buf,
792 "ERROR: at most %d %s args may be specified\n",
793 MAX_BASIS_DIRS, dest_option);
794 return 0;
795 }
796 arg = poptGetOptArg(pc);
797 if (sanitize_paths)
798 arg = sanitize_path(NULL, arg, NULL, 0);
799 basis_dir[basis_dir_cnt++] = (char *)arg;
800 break;
801
802 default:
803 /* A large opt value means that set_refuse_options()
804 * turned this option off (opt-BASE is its index). */
805 if (opt >= OPT_REFUSED_BASE) {
806 struct poptOption *op =
807 &long_options[opt-OPT_REFUSED_BASE];
808 int n = snprintf(err_buf, sizeof err_buf,
809 "The server is configured to refuse --%s\n",
810 op->longName) - 1;
811 if (op->shortName) {
812 snprintf(err_buf+n, sizeof err_buf-n,
813 " (-%c)\n", op->shortName);
814 }
815 } else {
816 snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
817 am_server ? "on remote machine: " : "",
818 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
819 poptStrerror(opt));
820 }
821 return 0;
822 }
823 }
824
825 if (am_sender < 0)
826 am_sender = 0;
827
828#if !SUPPORT_LINKS
829 if (preserve_links && !am_sender) {
830 snprintf(err_buf, sizeof err_buf,
831 "symlinks are not supported on this %s\n",
832 am_server ? "server" : "client");
833 return 0;
834 }
835#endif
836
837#if !SUPPORT_HARD_LINKS
838 if (preserve_hard_links) {
839 snprintf(err_buf, sizeof err_buf,
840 "hard links are not supported on this %s\n",
841 am_server ? "server" : "client");
842 return 0;
843 }
844#endif
845
846 if (write_batch && read_batch) {
847 snprintf(err_buf, sizeof err_buf,
848 "--write-batch and --read-batch can not be used together\n");
849 return 0;
850 }
851 if (write_batch || read_batch) {
852 if (dry_run) {
853 snprintf(err_buf, sizeof err_buf,
854 "--%s-batch cannot be used with --dry_run (-n)\n",
855 write_batch ? "write" : "read");
856 return 0;
857 }
858 if (am_server) {
859 rprintf(FINFO,
860 "ignoring --%s-batch option sent to server\n",
861 write_batch ? "write" : "read");
862 /* We don't actually exit_cleanup(), so that we can
863 * still service older version clients that still send
864 * batch args to server. */
865 read_batch = write_batch = 0;
866 batch_name = NULL;
867 }
868 }
869 if (read_batch && files_from) {
870 snprintf(err_buf, sizeof err_buf,
871 "--read-batch cannot be used with --files-from\n");
872 return 0;
873 }
874 if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
875 snprintf(err_buf, sizeof err_buf,
876 "the batch-file name must be %d characters or less.\n",
877 MAX_BATCH_NAME_LEN);
878 return 0;
879 }
880
881 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
882 snprintf(err_buf, sizeof err_buf,
883 "the --temp-dir path is WAY too long.\n");
884 return 0;
885 }
886
887 if (compare_dest + copy_dest + link_dest > 1) {
888 snprintf(err_buf, sizeof err_buf,
889 "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
890 return 0;
891 }
892
893 if (archive_mode) {
894 if (!files_from)
895 recurse = -1; /* infinite recursion */
896#if SUPPORT_LINKS
897 preserve_links = 1;
898#endif
899 preserve_perms = 1;
900 preserve_times = 1;
901 preserve_gid = 1;
902 preserve_uid = 1;
903 preserve_devices = 1;
904 }
905
906 if (recurse || list_only || files_from)
907 xfer_dirs |= 1;
908
909 if (relative_paths < 0)
910 relative_paths = files_from? 1 : 0;
911
912 if (!!delete_before + delete_during + delete_after > 1) {
913 snprintf(err_buf, sizeof err_buf,
914 "You may not combine multiple --delete-WHEN options.\n");
915 return 0;
916 }
917 if (!recurse) {
918 delete_before = delete_during = delete_after = 0;
919 delete_mode = delete_excluded = 0;
920 } else if (delete_before || delete_during || delete_after)
921 delete_mode = 1;
922 else if (delete_mode || delete_excluded)
923 delete_mode = delete_before = 1;
924
925 *argv = poptGetArgs(pc);
926 *argc = count_args(*argv);
927
928 if (sanitize_paths) {
929 int i;
930 for (i = *argc; i-- > 0; )
931 (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
932 if (tmpdir)
933 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
934 if (partial_dir)
935 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
936 if (backup_dir)
937 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
938 if (files_from)
939 files_from = sanitize_path(NULL, files_from, NULL, 0);
940 }
941 if (server_filter_list.head && !am_sender) {
942 struct filter_list_struct *elp = &server_filter_list;
943 int i;
944 if (tmpdir) {
945 clean_fname(tmpdir, 1);
946 if (check_filter(elp, tmpdir, 1) < 0)
947 goto options_rejected;
948 }
949 if (partial_dir) {
950 clean_fname(partial_dir, 1);
951 if (check_filter(elp, partial_dir, 1) < 0)
952 goto options_rejected;
953 }
954 for (i = 0; i < basis_dir_cnt; i++) {
955 clean_fname(basis_dir[i], 1);
956 if (check_filter(elp, basis_dir[i], 1) < 0)
957 goto options_rejected;
958 }
959 if (backup_dir) {
960 clean_fname(backup_dir, 1);
961 if (check_filter(elp, backup_dir, 1) < 0)
962 goto options_rejected;
963 }
964 }
965 if (server_filter_list.head && files_from) {
966 clean_fname(files_from, 1);
967 if (check_filter(&server_filter_list, files_from, 0) < 0) {
968 options_rejected:
969 snprintf(err_buf, sizeof err_buf,
970 "Your options have been rejected by the server.\n");
971 return 0;
972 }
973 }
974
975 if (!backup_suffix)
976 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
977 backup_suffix_len = strlen(backup_suffix);
978 if (strchr(backup_suffix, '/') != NULL) {
979 snprintf(err_buf, sizeof err_buf,
980 "--suffix cannot contain slashes: %s\n",
981 backup_suffix);
982 return 0;
983 }
984 if (backup_dir) {
985 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
986 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
987 if (backup_dir_remainder < 32) {
988 snprintf(err_buf, sizeof err_buf,
989 "the --backup-dir path is WAY too long.\n");
990 return 0;
991 }
992 if (backup_dir_buf[backup_dir_len - 1] != '/') {
993 backup_dir_buf[backup_dir_len++] = '/';
994 backup_dir_buf[backup_dir_len] = '\0';
995 }
996 if (verbose > 1 && !am_sender) {
997 rprintf(FINFO, "backup_dir is %s\n",
998 safe_fname(backup_dir_buf));
999 }
1000 } else if (!backup_suffix_len && (!am_server || !am_sender)) {
1001 snprintf(err_buf, sizeof err_buf,
1002 "--suffix cannot be a null string without --backup-dir\n");
1003 return 0;
1004 }
1005
1006 if (do_progress && !verbose)
1007 verbose = 1;
1008
1009 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1010 bwlimit = daemon_bwlimit;
1011 if (bwlimit) {
1012 bwlimit_writemax = (size_t)bwlimit * 128;
1013 if (bwlimit_writemax < 512)
1014 bwlimit_writemax = 512;
1015 }
1016
1017 if (delay_updates && !partial_dir)
1018 partial_dir = ".~tmp~";
1019
1020 if (inplace) {
1021#if HAVE_FTRUNCATE
1022 if (partial_dir) {
1023 snprintf(err_buf, sizeof err_buf,
1024 "--inplace cannot be used with --%s\n",
1025 delay_updates ? "delay-updates" : "partial-dir");
1026 return 0;
1027 }
1028 keep_partial = 0;
1029#else
1030 snprintf(err_buf, sizeof err_buf,
1031 "--inplace is not supported on this %s\n",
1032 am_server ? "server" : "client");
1033 return 0;
1034#endif
1035 } else {
1036 if (keep_partial && !partial_dir)
1037 partial_dir = getenv("RSYNC_PARTIAL_DIR");
1038 if (partial_dir) {
1039 if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1040 partial_dir = NULL;
1041 else if (*partial_dir != '/') {
1042 parse_rule(&filter_list, partial_dir,
1043 MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
1044 }
1045 keep_partial = 1;
1046 }
1047 }
1048
1049 if (files_from) {
1050 char *colon;
1051 if (*argc > 2 || (!am_daemon && *argc == 1)) {
1052 usage(FERROR);
1053 exit_cleanup(RERR_SYNTAX);
1054 }
1055 if (strcmp(files_from, "-") == 0) {
1056 filesfrom_fd = 0;
1057 if (am_server)
1058 remote_filesfrom_file = "-";
1059 }
1060 else if ((colon = find_colon(files_from)) != 0) {
1061 if (am_server) {
1062 usage(FERROR);
1063 exit_cleanup(RERR_SYNTAX);
1064 }
1065 remote_filesfrom_file = colon+1 + (colon[1] == ':');
1066 if (strcmp(remote_filesfrom_file, "-") == 0) {
1067 snprintf(err_buf, sizeof err_buf,
1068 "Invalid --files-from remote filename\n");
1069 return 0;
1070 }
1071 } else {
1072 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1073 if (filesfrom_fd < 0) {
1074 snprintf(err_buf, sizeof err_buf,
1075 "failed to open files-from file %s: %s\n",
1076 files_from, strerror(errno));
1077 return 0;
1078 }
1079 }
1080 }
1081
1082 return 1;
1083}
1084
1085
1086/**
1087 * Construct a filtered list of options to pass through from the
1088 * client to the server.
1089 *
1090 * This involves setting options that will tell the server how to
1091 * behave, and also filtering out options that are processed only
1092 * locally.
1093 **/
1094void server_options(char **args,int *argc)
1095{
1096 static char argstr[50+MAX_BASIS_DIRS*2];
1097 int ac = *argc;
1098 char *arg;
1099
1100 int i, x;
1101
1102 if (blocking_io == -1)
1103 blocking_io = 0;
1104
1105 args[ac++] = "--server";
1106
1107 if (daemon_over_rsh) {
1108 args[ac++] = "--daemon";
1109 *argc = ac;
1110 /* if we're passing --daemon, we're done */
1111 return;
1112 }
1113
1114 if (!am_sender)
1115 args[ac++] = "--sender";
1116
1117 x = 1;
1118 argstr[0] = '-';
1119 for (i = 0; i < verbose; i++)
1120 argstr[x++] = 'v';
1121
1122 /* the -q option is intentionally left out */
1123 if (make_backups)
1124 argstr[x++] = 'b';
1125 if (update_only)
1126 argstr[x++] = 'u';
1127 if (dry_run)
1128 argstr[x++] = 'n';
1129 if (preserve_links)
1130 argstr[x++] = 'l';
1131 if (copy_links)
1132 argstr[x++] = 'L';
1133 if (xfer_dirs > 1)
1134 argstr[x++] = 'd';
1135 if (keep_dirlinks && am_sender)
1136 argstr[x++] = 'K';
1137
1138 if (whole_file > 0)
1139 argstr[x++] = 'W';
1140 /* We don't need to send --no-whole-file, because it's the
1141 * default for remote transfers, and in any case old versions
1142 * of rsync will not understand it. */
1143
1144 if (preserve_hard_links)
1145 argstr[x++] = 'H';
1146 if (preserve_uid)
1147 argstr[x++] = 'o';
1148 if (preserve_gid)
1149 argstr[x++] = 'g';
1150 if (preserve_devices)
1151 argstr[x++] = 'D';
1152 if (preserve_times)
1153 argstr[x++] = 't';
1154 if (omit_dir_times && am_sender)
1155 argstr[x++] = 'O';
1156 if (preserve_perms)
1157 argstr[x++] = 'p';
1158 if (recurse < 0)
1159 argstr[x++] = 'r';
1160 if (always_checksum)
1161 argstr[x++] = 'c';
1162 if (cvs_exclude)
1163 argstr[x++] = 'C';
1164 if (ignore_times)
1165 argstr[x++] = 'I';
1166 if (relative_paths)
1167 argstr[x++] = 'R';
1168 if (one_file_system)
1169 argstr[x++] = 'x';
1170 if (sparse_files)
1171 argstr[x++] = 'S';
1172 if (do_compression)
1173 argstr[x++] = 'z';
1174
1175 /* This is a complete hack - blame Rusty. FIXME!
1176 * This hack is only needed for older rsync versions that
1177 * don't understand the --list-only option. */
1178 if (list_only == 1 && recurse >= 0)
1179 argstr[x++] = 'r';
1180
1181 argstr[x] = 0;
1182
1183 if (x != 1)
1184 args[ac++] = argstr;
1185
1186 if (list_only > 1)
1187 args[ac++] = "--list-only";
1188
1189 if (block_size) {
1190 if (asprintf(&arg, "-B%lu", block_size) < 0)
1191 goto oom;
1192 args[ac++] = arg;
1193 }
1194
1195 if (max_delete && am_sender) {
1196 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1197 goto oom;
1198 args[ac++] = arg;
1199 }
1200
1201 if (max_size && am_sender) {
1202 args[ac++] = "--max-size";
1203 args[ac++] = max_size_arg;
1204 }
1205
1206 if (io_timeout) {
1207 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1208 goto oom;
1209 args[ac++] = arg;
1210 }
1211
1212 if (bwlimit) {
1213 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1214 goto oom;
1215 args[ac++] = arg;
1216 }
1217
1218 if (backup_dir) {
1219 args[ac++] = "--backup-dir";
1220 args[ac++] = backup_dir;
1221 }
1222
1223 /* Only send --suffix if it specifies a non-default value. */
1224 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1225 /* We use the following syntax to avoid weirdness with '~'. */
1226 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1227 goto oom;
1228 args[ac++] = arg;
1229 }
1230
1231 if (am_sender) {
1232 if (delete_excluded)
1233 args[ac++] = "--delete-excluded";
1234 else if (delete_before == 1 || delete_after)
1235 args[ac++] = "--delete";
1236 if (delete_before > 1)
1237 args[ac++] = "--delete-before";
1238 if (delete_during)
1239 args[ac++] = "--delete-during";
1240 if (delete_after)
1241 args[ac++] = "--delete-after";
1242 if (force_delete)
1243 args[ac++] = "--force";
1244 }
1245
1246 if (size_only)
1247 args[ac++] = "--size-only";
1248
1249 if (modify_window_set) {
1250 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1251 goto oom;
1252 args[ac++] = arg;
1253 }
1254
1255 if (checksum_seed) {
1256 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1257 goto oom;
1258 args[ac++] = arg;
1259 }
1260
1261 if (partial_dir && am_sender) {
1262 args[ac++] = "--partial-dir";
1263 args[ac++] = partial_dir;
1264 if (delay_updates)
1265 args[ac++] = "--delay-updates";
1266 } else if (keep_partial)
1267 args[ac++] = "--partial";
1268
1269 if (ignore_errors)
1270 args[ac++] = "--ignore-errors";
1271
1272 if (copy_unsafe_links)
1273 args[ac++] = "--copy-unsafe-links";
1274
1275 if (safe_symlinks)
1276 args[ac++] = "--safe-links";
1277
1278 if (numeric_ids)
1279 args[ac++] = "--numeric-ids";
1280
1281 if (only_existing && am_sender)
1282 args[ac++] = "--existing";
1283
1284 if (opt_ignore_existing && am_sender)
1285 args[ac++] = "--ignore-existing";
1286
1287 if (inplace)
1288 args[ac++] = "--inplace";
1289
1290 if (tmpdir) {
1291 args[ac++] = "--temp-dir";
1292 args[ac++] = tmpdir;
1293 }
1294
1295 if (basis_dir[0] && am_sender) {
1296 /* the server only needs this option if it is not the sender,
1297 * and it may be an older version that doesn't know this
1298 * option, so don't send it if client is the sender.
1299 */
1300 int i;
1301 for (i = 0; i < basis_dir_cnt; i++) {
1302 args[ac++] = dest_option;
1303 args[ac++] = basis_dir[i];
1304 }
1305 }
1306
1307 if (files_from && (!am_sender || remote_filesfrom_file)) {
1308 if (remote_filesfrom_file) {
1309 args[ac++] = "--files-from";
1310 args[ac++] = remote_filesfrom_file;
1311 if (eol_nulls)
1312 args[ac++] = "--from0";
1313 } else {
1314 args[ac++] = "--files-from=-";
1315 args[ac++] = "--from0";
1316 }
1317 if (!relative_paths)
1318 args[ac++] = "--no-relative";
1319 }
1320 if (!implied_dirs && !am_sender)
1321 args[ac++] = "--no-implied-dirs";
1322
1323 *argc = ac;
1324 return;
1325
1326 oom:
1327 out_of_memory("server_options");
1328}
1329
1330/**
1331 * Return the position of a ':' IF it is not part of a filename (i.e. as
1332 * long as it doesn't occur after a slash.
1333 */
1334char *find_colon(char *s)
1335{
1336 char *p, *p2;
1337
1338 p = strchr(s,':');
1339 if (!p)
1340 return NULL;
1341
1342 /* now check to see if there is a / in the string before the : - if there is then
1343 discard the colon on the assumption that the : is part of a filename */
1344 p2 = strchr(s,'/');
1345 if (p2 && p2 < p)
1346 return NULL;
1347
1348 return p;
1349}