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