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