When an option defined with POPT_ARG_VAL is being refused, we must
[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;
3a90ea0a 81int keep_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");
51d48398 254 rprintf(F," -k, --keep-dirs transfer a directory without recursing\n");
716e73d4 255 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
13e29995 256 rprintf(F," -l, --links copy symlinks as symlinks\n");
06d76beb
WD
257 rprintf(F," -L, --copy-links copy the referent of all symlinks\n");
258 rprintf(F," --copy-unsafe-links copy the referent of \"unsafe\" symlinks\n");
259 rprintf(F," --safe-links ignore \"unsafe\" symlinks\n");
704f908e
AT
260 rprintf(F," -H, --hard-links preserve hard links\n");
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");
ef5d23eb 311 rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
9b3318b0
WD
312 rprintf(F," --write-batch=FILE write a batch to FILE\n");
313 rprintf(F," --read-batch=FILE read a batch from FILE\n");
06963d0f 314#ifdef INET6
4db88e5b
WD
315 rprintf(F," -4, --ipv4 prefer IPv4\n");
316 rprintf(F," -6, --ipv6 prefer IPv6\n");
06963d0f 317#endif
3dd22903 318 rprintf(F," -h, --help show this help screen\n");
7a6421fa 319
3ac7f5d4
WD
320 rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
321 rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
2855f61f 322 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
7a6421fa
AT
323}
324
3ac7f5d4 325enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
e012f858 326 OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
1f3d6cdd 327 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
7d5acf1d 328 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
c67d1386 329 OPT_REFUSED_BASE = 9000};
7a6421fa 330
2855f61f
MP
331static struct poptOption long_options[] = {
332 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
8db7cc2c 333 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
d175d7e1 334 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
3dd22903
WD
335 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
336 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
afb6e945
WD
337 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
338 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
8b54f004 339 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
afb6e945 340 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
afb6e945
WD
341 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
342 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
51d48398
WD
343 {"delete", 0, POPT_ARG_NONE, &delete_before, 0, 0, 0 },
344 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
345 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
afb6e945
WD
346 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
347 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
8db7cc2c
WD
348 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
349 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
350 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
351 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
afb6e945 352 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
8db7cc2c 353 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
afb6e945
WD
354 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
355 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
356 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
357 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
358 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
a3221d2a 359 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
51d48398 360 {"keep-dirs", 'k', POPT_ARG_VAL, &keep_dirs, 2, 0, 0 },
716e73d4 361 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 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 },
364 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
365 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
366 {"copy-unsafe-links", 0, POPT_ARG_NONE, &copy_unsafe_links, 0, 0, 0 },
367 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
368 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
369 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
370 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
371 {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
372 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
8db7cc2c
WD
373 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
374 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
dfa32483 375 {"archive", 'a', POPT_ARG_NONE, &archive_mode, 0, 0, 0 },
afb6e945 376 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
8db7cc2c 377 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
51d48398
WD
378 {"recursive", 'r', POPT_ARG_VAL, &recurse, -1, 0, 0 },
379 {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
ea5164d1
WD
380 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
381 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
afb6e945 382 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
a06b419d 383 {"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
afb6e945 384 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
7d5acf1d 385 {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
99218d82 386 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
afb6e945 387 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
e012f858
WD
388 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
389 {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
390 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
2855f61f 391 /* TODO: Should this take an optional int giving the compression level? */
afb6e945 392 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
afb6e945
WD
393 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
394 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
395 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
a7260c40 396 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
afb6e945
WD
397 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
398 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
399 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
8db7cc2c 400 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
b4713295 401 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
afb6e945
WD
402 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
403 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
afb6e945
WD
404 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
405 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
8db7cc2c
WD
406 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
407 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
ea5164d1
WD
408 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
409 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
410 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
4f3e9a0f 411 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
c8d895de 412 {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
06963d0f 413#ifdef INET6
3dd22903
WD
414 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
415 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
06963d0f 416#endif
3ac7f5d4
WD
417 /* All these options switch us into daemon-mode option-parsing. */
418 {"address", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
419 {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
420 {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
421 {"no-detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
3ac7f5d4
WD
422 {0,0,0,0, 0, 0, 0}
423};
424
425static void daemon_usage(enum logcode F)
426{
427 print_rsync_version(F);
428
429 rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
430 rprintf(F," --address=ADDRESS bind to the specified address\n");
9fb08441 431 rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
3ac7f5d4
WD
432 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
433 rprintf(F," --no-detach do not detach from the parent\n");
434 rprintf(F," --port=PORT specify alternate rsyncd port number\n");
435#ifdef INET6
436 rprintf(F," -4, --ipv4 prefer IPv4\n");
437 rprintf(F," -6, --ipv6 prefer IPv6\n");
438#endif
439 rprintf(F," -h, --help show this help screen\n");
440
441 rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
442 rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
443}
444
445static struct poptOption long_daemon_options[] = {
446 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
447 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
9fb08441 448 {"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
3ac7f5d4
WD
449 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
450 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
451#ifdef INET6
452 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
453 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
454#endif
455 {"no-detach", 0, POPT_ARG_NONE, &no_detach, 0, 0, 0 },
456 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
457 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
458 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
459 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
ad715008 460 {0,0,0,0, 0, 0, 0}
2855f61f 461};
7a6421fa 462
06963d0f 463
e51094b7 464static char err_buf[200];
cd8185f2 465
2855f61f 466
dafe63ca
MP
467/**
468 * Store the option error message, if any, so that we can log the
469 * connection attempt (which requires parsing the options), and then
470 * show the error later on.
471 **/
cd8185f2
AT
472void option_error(void)
473{
e51094b7
WD
474 if (!err_buf[0]) {
475 strcpy(err_buf, "Error parsing options: "
476 "option may be supported on client but not on server?\n");
cd8185f2 477 }
e51094b7 478
e51094b7 479 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
cd8185f2
AT
480}
481
dafe63ca
MP
482
483/**
27ed20f7
WD
484 * Tweak the option table to disable all options that the rsyncd.conf
485 * file has told us to refuse.
dafe63ca 486 **/
27ed20f7 487static void set_refuse_options(char *bp)
cd8185f2 488{
27ed20f7 489 struct poptOption *op;
093e816c 490 char *cp, shortname[2];
d73e7f6e 491 int is_wild, found_match;
093e816c
WD
492
493 shortname[1] = '\0';
27ed20f7
WD
494
495 while (1) {
06a50542
WD
496 while (*bp == ' ') bp++;
497 if (!*bp)
498 break;
27ed20f7
WD
499 if ((cp = strchr(bp, ' ')) != NULL)
500 *cp= '\0';
06a50542
WD
501 /* If they specify "delete", reject all delete options. */
502 if (strcmp(bp, "delete") == 0)
503 bp = "delete*";
093e816c 504 is_wild = strpbrk(bp, "*?[") != NULL;
d73e7f6e 505 found_match = 0;
55afbb52 506 for (op = long_options; ; op++) {
093e816c 507 *shortname = op->shortName;
d73e7f6e
WD
508 if (!op->longName && !*shortname)
509 break;
510 if ((op->longName && wildmatch(bp, op->longName))
511 || (*shortname && wildmatch(bp, shortname))) {
e57211c5
WD
512 if (op->argInfo == POPT_ARG_VAL)
513 op->argInfo = POPT_ARG_NONE;
06a50542 514 op->val = (op - long_options) + OPT_REFUSED_BASE;
d73e7f6e 515 found_match = 1;
06a50542
WD
516 if (!is_wild)
517 break;
27ed20f7 518 }
cd8185f2 519 }
d73e7f6e
WD
520 if (!found_match) {
521 rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
522 bp);
523 }
27ed20f7
WD
524 if (!cp)
525 break;
526 *cp = ' ';
527 bp = cp + 1;
cd8185f2 528 }
cd8185f2
AT
529}
530
531
8db7cc2c 532static int count_args(const char **argv)
2855f61f 533{
dfa32483 534 int i = 0;
2855f61f 535
8db7cc2c
WD
536 if (argv) {
537 while (argv[i] != NULL)
538 i++;
539 }
dfa32483
WD
540
541 return i;
2855f61f
MP
542}
543
544
dafe63ca
MP
545/**
546 * Process command line arguments. Called on both local and remote.
547 *
548 * @retval 1 if all options are OK; with globals set to appropriate
549 * values
550 *
551 * @retval 0 on error, with err_buf containing an explanation
552 **/
2855f61f 553int parse_arguments(int *argc, const char ***argv, int frommain)
7a6421fa 554{
d853783f 555 int opt;
cd8185f2 556 char *ref = lp_refuse_options(module_id);
7be73df4 557 const char *arg;
dfa32483 558 poptContext pc;
d853783f 559
27ed20f7
WD
560 if (ref && *ref)
561 set_refuse_options(ref);
562
dfa32483 563 /* TODO: Call poptReadDefaultConfig; handle errors. */
cd8185f2 564
dfa32483
WD
565 /* The context leaks in case of an error, but if there's a
566 * problem we always exit anyhow. */
567 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
9fb08441 568 poptReadDefaultConfig(pc, 0);
2855f61f
MP
569
570 while ((opt = poptGetNextOpt(pc)) != -1) {
dfa32483
WD
571 /* most options are handled automatically by popt;
572 * only special cases are returned and listed here. */
2855f61f 573
d853783f
AT
574 switch (opt) {
575 case OPT_VERSION:
dfa32483 576 print_rsync_version(FINFO);
d853783f 577 exit_cleanup(0);
dfa32483 578
3ac7f5d4
WD
579 case OPT_DAEMON:
580 if (am_daemon) {
581 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
582 return 0;
583 }
584 poptFreeContext(pc);
585 pc = poptGetContext(RSYNC_NAME, *argc, *argv,
586 long_daemon_options, 0);
587 while ((opt = poptGetNextOpt(pc)) != -1) {
588 switch (opt) {
589 case 'h':
590 daemon_usage(FINFO);
591 exit_cleanup(0);
592
593 default:
594 rprintf(FERROR,
595 "rsync: %s: %s (in daemon mode)\n",
596 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
597 poptStrerror(opt));
598 goto daemon_error;
599 }
600 }
601 if (!daemon_opt) {
602 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
603 daemon_error:
604 rprintf(FERROR,
605 "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
606 exit_cleanup(RERR_SYNTAX);
607 }
608 *argv = poptGetArgs(pc);
609 *argc = count_args(*argv);
610 daemon_opt = 0;
611 am_daemon = 1;
612 return 1;
613
5b56cc19 614 case OPT_MODIFY_WINDOW:
dfa32483
WD
615 /* The value has already been set by popt, but
616 * we need to remember that we're using a
617 * non-default setting. */
5b56cc19
AT
618 modify_window_set = 1;
619 break;
1de50993 620
d853783f 621 case OPT_EXCLUDE:
357406ec 622 add_exclude(&exclude_list, poptGetOptArg(pc), 0);
d853783f
AT
623 break;
624
625 case OPT_INCLUDE:
8645af1d 626 add_exclude(&exclude_list, poptGetOptArg(pc),
357406ec 627 XFLG_DEF_INCLUDE);
d853783f
AT
628 break;
629
630 case OPT_EXCLUDE_FROM:
93695764 631 case OPT_INCLUDE_FROM:
7be73df4 632 arg = poptGetOptArg(pc);
ba3db479
WD
633 if (sanitize_paths)
634 arg = sanitize_path(NULL, arg, NULL, 0);
635 if (server_exclude_list.head) {
636 char *cp = (char *)arg;
637 clean_fname(cp, 1);
638 if (check_exclude(&server_exclude_list, cp, 0) < 0)
639 goto options_rejected;
640 }
641 add_exclude_file(&exclude_list, arg, XFLG_FATAL_ERRORS
642 | (opt == OPT_INCLUDE_FROM
643 ? XFLG_DEF_INCLUDE : 0));
93695764
DD
644 break;
645
d853783f
AT
646 case 'h':
647 usage(FINFO);
648 exit_cleanup(0);
649
d853783f
AT
650 case 'v':
651 verbose++;
652 break;
7a6421fa 653
b86f0cef 654 case 'q':
f98c60bf
WD
655 if (frommain)
656 quiet++;
b86f0cef
DD
657 break;
658
d853783f
AT
659 case OPT_SENDER:
660 if (!am_server) {
661 usage(FERROR);
65417579 662 exit_cleanup(RERR_SYNTAX);
d853783f
AT
663 }
664 am_sender = 1;
665 break;
666
d9fcc198
AT
667 case 'P':
668 do_progress = 1;
669 keep_partial = 1;
670 break;
671
088aac85 672 case OPT_WRITE_BATCH:
9b3318b0 673 /* batch_name is already set */
088aac85
DD
674 write_batch = 1;
675 break;
676
76f79ba7 677 case OPT_READ_BATCH:
9b3318b0 678 /* batch_name is already set */
6902ed17
MP
679 read_batch = 1;
680 break;
ea5164d1 681
7d5acf1d
WD
682 case OPT_MAX_SIZE:
683 for (arg = max_size_arg; isdigit(*arg); arg++) {}
684 if (*arg == '.')
685 for (arg++; isdigit(*arg); arg++) {}
686 switch (*arg) {
687 case 'k': case 'K':
688 max_size = atof(max_size_arg) * 1024;
689 break;
690 case 'm': case 'M':
691 max_size = atof(max_size_arg) * 1024*1024;
692 break;
693 case 'g': case 'G':
694 max_size = atof(max_size_arg) * 1024*1024*1024;
695 break;
696 case '\0':
697 max_size = atof(max_size_arg);
698 break;
699 default:
700 max_size = 0;
701 break;
702 }
703 if (max_size <= 0) {
e012f858 704 snprintf(err_buf, sizeof err_buf,
7d5acf1d
WD
705 "--max-size value is invalid: %s\n",
706 max_size_arg);
e012f858 707 return 0;
7d5acf1d
WD
708 }
709 break;
710
99218d82
WD
711 case OPT_TIMEOUT:
712 if (io_timeout && io_timeout < select_timeout)
713 select_timeout = io_timeout;
714 break;
715
59c95e42
DD
716 case OPT_LINK_DEST:
717#if HAVE_LINK
59c95e42 718 link_dest = 1;
e012f858
WD
719 dest_option = "--link-dest";
720 goto set_dest_dir;
59c95e42 721#else
d175d7e1 722 snprintf(err_buf, sizeof err_buf,
dfa32483 723 "hard links are not supported on this %s\n",
59c95e42 724 am_server ? "server" : "client");
59c95e42
DD
725 return 0;
726#endif
727
e012f858
WD
728 case OPT_COPY_DEST:
729 copy_dest = 1;
730 dest_option = "--copy-dest";
731 goto set_dest_dir;
732
733 case OPT_COMPARE_DEST:
734 compare_dest = 1;
735 dest_option = "--compare-dest";
736 set_dest_dir:
3b26bba0 737 if (basis_dir_cnt >= MAX_BASIS_DIRS) {
e012f858
WD
738 snprintf(err_buf, sizeof err_buf,
739 "ERROR: at most %d %s args may be specified\n",
740 MAX_BASIS_DIRS, dest_option);
741 return 0;
742 }
743 arg = poptGetOptArg(pc);
744 if (sanitize_paths)
745 arg = sanitize_path(NULL, arg, NULL, 0);
746 basis_dir[basis_dir_cnt++] = (char *)arg;
747 break;
748
d853783f 749 default:
55afbb52 750 /* A large opt value means that set_refuse_options()
c67d1386
WD
751 * turned this option off (opt-BASE is its index). */
752 if (opt >= OPT_REFUSED_BASE) {
753 struct poptOption *op =
754 &long_options[opt-OPT_REFUSED_BASE];
27ed20f7 755 int n = snprintf(err_buf, sizeof err_buf,
a2570930 756 "The server is configured to refuse --%s\n",
27ed20f7
WD
757 op->longName) - 1;
758 if (op->shortName) {
759 snprintf(err_buf+n, sizeof err_buf-n,
760 " (-%c)\n", op->shortName);
761 }
762 } else {
8db7cc2c 763 snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
27ed20f7
WD
764 am_server ? "on remote machine: " : "",
765 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
766 poptStrerror(opt));
767 }
dfa32483 768 return 0;
d853783f 769 }
7a6421fa 770 }
2855f61f 771
e1add893 772#if !SUPPORT_LINKS
54e87b4b 773 if (preserve_links && !am_sender) {
e1add893
WD
774 snprintf(err_buf, sizeof err_buf,
775 "symlinks are not supported on this %s\n",
776 am_server ? "server" : "client");
e1add893
WD
777 return 0;
778 }
779#endif
780
781#if !SUPPORT_HARD_LINKS
782 if (preserve_hard_links) {
783 snprintf(err_buf, sizeof err_buf,
784 "hard links are not supported on this %s\n",
785 am_server ? "server" : "client");
e1add893
WD
786 return 0;
787 }
788#endif
789
088aac85 790 if (write_batch && read_batch) {
c3ea0990 791 snprintf(err_buf, sizeof err_buf,
36119893 792 "--write-batch and --read-batch can not be used together\n");
c3ea0990 793 return 0;
088aac85 794 }
94327ff0
WD
795 if (write_batch || read_batch) {
796 if (dry_run) {
c3ea0990 797 snprintf(err_buf, sizeof err_buf,
94327ff0
WD
798 "--%s-batch cannot be used with --dry_run (-n)\n",
799 write_batch ? "write" : "read");
c3ea0990 800 return 0;
94327ff0
WD
801 }
802 if (am_server) {
803 rprintf(FINFO,
804 "ignoring --%s-batch option sent to server\n",
805 write_batch ? "write" : "read");
806 /* We don't actually exit_cleanup(), so that we can
807 * still service older version clients that still send
808 * batch args to server. */
809 read_batch = write_batch = 0;
810 batch_name = NULL;
811 }
b9f592fb 812 }
36119893 813 if (read_batch && files_from) {
c3ea0990 814 snprintf(err_buf, sizeof err_buf,
36119893 815 "--read-batch cannot be used with --files-from\n");
c3ea0990 816 return 0;
36119893 817 }
9b3318b0 818 if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
c3ea0990 819 snprintf(err_buf, sizeof err_buf,
9b3318b0
WD
820 "the batch-file name must be %d characters or less.\n",
821 MAX_BATCH_NAME_LEN);
c3ea0990 822 return 0;
beb93684 823 }
088aac85 824
ce58b1b4 825 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
c3ea0990
WD
826 snprintf(err_buf, sizeof err_buf,
827 "the --temp-dir path is WAY too long.\n");
828 return 0;
ce58b1b4
WD
829 }
830
e012f858
WD
831 if (compare_dest + copy_dest + link_dest > 1) {
832 snprintf(err_buf, sizeof err_buf,
833 "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
834 return 0;
835 }
836
dfa32483 837 if (archive_mode) {
ea5164d1 838 if (!files_from)
51d48398 839 recurse = -1; /* infinite recursion */
dfa32483
WD
840#if SUPPORT_LINKS
841 preserve_links = 1;
842#endif
843 preserve_perms = 1;
844 preserve_times = 1;
845 preserve_gid = 1;
846 preserve_uid = 1;
847 preserve_devices = 1;
848 }
51d48398
WD
849
850 if (recurse || list_only || files_from)
851 keep_dirs |= 1;
dfa32483 852
ea5164d1
WD
853 if (relative_paths < 0)
854 relative_paths = files_from? 1 : 0;
855
51d48398
WD
856 if (delete_before || delete_after)
857 delete_mode = 1;
858 if (delete_excluded && !delete_mode)
859 delete_mode = delete_before = 1;
860
7be73df4 861 *argv = poptGetArgs(pc);
8db7cc2c 862 *argc = count_args(*argv);
7be73df4
WD
863
864 if (sanitize_paths) {
865 int i;
866 for (i = *argc; i-- > 0; )
10796f4b 867 (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
7be73df4 868 if (tmpdir)
10796f4b 869 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
a7260c40 870 if (partial_dir)
10796f4b 871 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
7be73df4 872 if (backup_dir)
10796f4b 873 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
7be73df4 874 if (files_from)
10796f4b 875 files_from = sanitize_path(NULL, files_from, NULL, 0);
7be73df4 876 }
c3ea0990
WD
877 if (server_exclude_list.head && !am_sender) {
878 struct exclude_list_struct *elp = &server_exclude_list;
e012f858 879 int i;
c3ea0990 880 if (tmpdir) {
58b1999e 881 clean_fname(tmpdir, 1);
c3ea0990
WD
882 if (check_exclude(elp, tmpdir, 1) < 0)
883 goto options_rejected;
884 }
885 if (partial_dir) {
58b1999e 886 clean_fname(partial_dir, 1);
c3ea0990
WD
887 if (check_exclude(elp, partial_dir, 1) < 0)
888 goto options_rejected;
889 }
e012f858
WD
890 for (i = 0; i < basis_dir_cnt; i++) {
891 clean_fname(basis_dir[i], 1);
892 if (check_exclude(elp, basis_dir[i], 1) < 0)
c3ea0990
WD
893 goto options_rejected;
894 }
895 if (backup_dir) {
58b1999e 896 clean_fname(backup_dir, 1);
c3ea0990
WD
897 if (check_exclude(elp, backup_dir, 1) < 0)
898 goto options_rejected;
899 }
900 }
901 if (server_exclude_list.head && files_from) {
58b1999e 902 clean_fname(files_from, 1);
c3ea0990
WD
903 if (check_exclude(&server_exclude_list, files_from, 0) < 0) {
904 options_rejected:
905 snprintf(err_buf, sizeof err_buf,
906 "Your options have been rejected by the server.\n");
907 return 0;
908 }
909 }
7be73df4 910
d175d7e1 911 if (!backup_suffix)
e0391f81 912 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
d175d7e1 913 backup_suffix_len = strlen(backup_suffix);
80ddadb7 914 if (strchr(backup_suffix, '/') != NULL) {
c3ea0990
WD
915 snprintf(err_buf, sizeof err_buf,
916 "--suffix cannot contain slashes: %s\n",
80ddadb7 917 backup_suffix);
c3ea0990 918 return 0;
80ddadb7 919 }
e0391f81
WD
920 if (backup_dir) {
921 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
922 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
923 if (backup_dir_remainder < 32) {
c3ea0990
WD
924 snprintf(err_buf, sizeof err_buf,
925 "the --backup-dir path is WAY too long.\n");
926 return 0;
e0391f81
WD
927 }
928 if (backup_dir_buf[backup_dir_len - 1] != '/') {
929 backup_dir_buf[backup_dir_len++] = '/';
930 backup_dir_buf[backup_dir_len] = '\0';
931 }
8dcf9335 932 if (verbose > 1 && !am_sender)
e0391f81 933 rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
8dcf9335 934 } else if (!backup_suffix_len && (!am_server || !am_sender)) {
c3ea0990 935 snprintf(err_buf, sizeof err_buf,
d175d7e1 936 "--suffix cannot be a null string without --backup-dir\n");
c3ea0990 937 return 0;
d175d7e1
WD
938 }
939
e2559dbe
S
940 if (do_progress && !verbose)
941 verbose = 1;
942
9fb08441
WD
943 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
944 bwlimit = daemon_bwlimit;
3c74c3a3
WD
945 if (bwlimit) {
946 bwlimit_writemax = (size_t)bwlimit * 128;
947 if (bwlimit_writemax < 512)
948 bwlimit_writemax = 512;
949 }
950
a3221d2a
WD
951 if (inplace) {
952#if HAVE_FTRUNCATE
a7260c40
WD
953 if (partial_dir) {
954 snprintf(err_buf, sizeof err_buf,
955 "--inplace cannot be used with --partial-dir\n");
956 return 0;
957 }
a3221d2a 958 keep_partial = 0;
ded4daf0
WD
959#else
960 snprintf(err_buf, sizeof err_buf,
961 "--inplace is not supported on this %s\n",
962 am_server ? "server" : "client");
963 return 0;
964#endif
075aa18f
WD
965 } else {
966 if (keep_partial && !partial_dir)
967 partial_dir = getenv("RSYNC_PARTIAL_DIR");
968 if (partial_dir) {
969 if (!*partial_dir || strcmp(partial_dir, ".") == 0)
970 partial_dir = NULL;
13791b1e
WD
971 else if (*partial_dir != '/') {
972 add_exclude(&exclude_list, partial_dir,
973 XFLG_DIRECTORY);
974 }
075aa18f
WD
975 keep_partial = 1;
976 }
a3221d2a
WD
977 }
978
ea5164d1
WD
979 if (files_from) {
980 char *colon;
c3ea0990 981 if (*argc > 2 || (!am_daemon && *argc == 1)) {
ea5164d1
WD
982 usage(FERROR);
983 exit_cleanup(RERR_SYNTAX);
984 }
63596e1c 985 if (strcmp(files_from, "-") == 0) {
ea5164d1 986 filesfrom_fd = 0;
63596e1c
WD
987 if (am_server)
988 remote_filesfrom_file = "-";
989 }
ea5164d1
WD
990 else if ((colon = find_colon(files_from)) != 0) {
991 if (am_server) {
992 usage(FERROR);
993 exit_cleanup(RERR_SYNTAX);
994 }
995 remote_filesfrom_file = colon+1 + (colon[1] == ':');
996 if (strcmp(remote_filesfrom_file, "-") == 0) {
c3ea0990
WD
997 snprintf(err_buf, sizeof err_buf,
998 "Invalid --files-from remote filename\n");
999 return 0;
ea5164d1
WD
1000 }
1001 } else {
ea5164d1
WD
1002 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1003 if (filesfrom_fd < 0) {
c3ea0990
WD
1004 snprintf(err_buf, sizeof err_buf,
1005 "failed to open files-from file %s: %s\n",
1006 files_from, strerror(errno));
1007 return 0;
ea5164d1
WD
1008 }
1009 }
1010 }
1011
b11ed3b1 1012 return 1;
7a6421fa
AT
1013}
1014
1015
dafe63ca
MP
1016/**
1017 * Construct a filtered list of options to pass through from the
1018 * client to the server.
1019 *
1020 * This involves setting options that will tell the server how to
1021 * behave, and also filtering out options that are processed only
1022 * locally.
1023 **/
7a6421fa
AT
1024void server_options(char **args,int *argc)
1025{
e012f858 1026 static char argstr[50+MAX_BASIS_DIRS*2];
d853783f 1027 int ac = *argc;
f98c60bf 1028 char *arg;
ef5d23eb 1029
d853783f
AT
1030 int i, x;
1031
93689aa5
DD
1032 if (blocking_io == -1)
1033 blocking_io = 0;
1034
d853783f
AT
1035 args[ac++] = "--server";
1036
1312d9fc
WD
1037 if (daemon_over_rsh) {
1038 args[ac++] = "--daemon";
1039 *argc = ac;
1040 /* if we're passing --daemon, we're done */
1041 return;
1042 }
1043
d853783f
AT
1044 if (!am_sender)
1045 args[ac++] = "--sender";
1046
1047 x = 1;
1048 argstr[0] = '-';
f98c60bf 1049 for (i = 0; i < verbose; i++)
d853783f 1050 argstr[x++] = 'v';
f0b36a48 1051
b86f0cef 1052 /* the -q option is intentionally left out */
d853783f
AT
1053 if (make_backups)
1054 argstr[x++] = 'b';
1055 if (update_only)
1056 argstr[x++] = 'u';
1057 if (dry_run)
1058 argstr[x++] = 'n';
1059 if (preserve_links)
1060 argstr[x++] = 'l';
1061 if (copy_links)
1062 argstr[x++] = 'L';
51d48398
WD
1063 if (keep_dirs > 1)
1064 argstr[x++] = 'k';
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';
51d48398 1086 if (recurse < 0)
d853783f
AT
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
51d48398
WD
1103 /* This is a complete hack - blame Rusty. FIXME!
1104 * This hack is only needed for older rsync versions that
1105 * don't understand the --list-only option. */
1106 if (list_only == 1 && recurse >= 0)
f0b36a48
AT
1107 argstr[x++] = 'r';
1108
d853783f
AT
1109 argstr[x] = 0;
1110
f98c60bf
WD
1111 if (x != 1)
1112 args[ac++] = argstr;
d853783f 1113
51d48398
WD
1114 if (list_only > 1)
1115 args[ac++] = "--list-only";
1116
195bd906 1117 if (block_size) {
a06b419d 1118 if (asprintf(&arg, "-B%lu", block_size) < 0)
f98c60bf
WD
1119 goto oom;
1120 args[ac++] = arg;
dfa32483 1121 }
d853783f 1122
0b73ca12 1123 if (max_delete && am_sender) {
f98c60bf
WD
1124 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1125 goto oom;
1126 args[ac++] = arg;
dfa32483
WD
1127 }
1128
7d5acf1d
WD
1129 if (max_size && am_sender) {
1130 args[ac++] = "--max-size";
1131 args[ac++] = max_size_arg;
1132 }
1133
d853783f 1134 if (io_timeout) {
f98c60bf
WD
1135 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1136 goto oom;
1137 args[ac++] = arg;
dfa32483 1138 }
d853783f 1139
ef5d23eb 1140 if (bwlimit) {
f98c60bf
WD
1141 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1142 goto oom;
1143 args[ac++] = arg;
ef5d23eb
DD
1144 }
1145
d175d7e1
WD
1146 if (backup_dir) {
1147 args[ac++] = "--backup-dir";
1148 args[ac++] = backup_dir;
1149 }
1150
1151 /* Only send --suffix if it specifies a non-default value. */
f98c60bf 1152 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
191e40da 1153 /* We use the following syntax to avoid weirdness with '~'. */
f98c60bf
WD
1154 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1155 goto oom;
1156 args[ac++] = arg;
d853783f
AT
1157 }
1158
06a50542
WD
1159 if (am_sender) {
1160 if (delete_excluded)
1161 args[ac++] = "--delete-excluded";
51d48398 1162 else if (delete_before || delete_after)
06a50542
WD
1163 args[ac++] = "--delete";
1164
1165 if (delete_after)
1166 args[ac++] = "--delete-after";
1167
1168 if (force_delete)
1169 args[ac++] = "--force";
1170 }
b33b791e 1171
f83f0548
AT
1172 if (size_only)
1173 args[ac++] = "--size-only";
1174
5b56cc19 1175 if (modify_window_set) {
f98c60bf
WD
1176 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1177 goto oom;
1178 args[ac++] = arg;
5b56cc19
AT
1179 }
1180
c8d895de 1181 if (checksum_seed) {
221ddb94 1182 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
c8d895de
WD
1183 goto oom;
1184 args[ac++] = arg;
1185 }
1186
a7260c40
WD
1187 if (partial_dir && am_sender) {
1188 args[ac++] = "--partial-dir";
1189 args[ac++] = partial_dir;
1190 } else if (keep_partial)
d853783f
AT
1191 args[ac++] = "--partial";
1192
ef55c686
AT
1193 if (ignore_errors)
1194 args[ac++] = "--ignore-errors";
1195
b5313607
DD
1196 if (copy_unsafe_links)
1197 args[ac++] = "--copy-unsafe-links";
1198
d853783f
AT
1199 if (safe_symlinks)
1200 args[ac++] = "--safe-links";
1201
1202 if (numeric_ids)
1203 args[ac++] = "--numeric-ids";
1204
0b73ca12 1205 if (only_existing && am_sender)
1347d512
AT
1206 args[ac++] = "--existing";
1207
dfa32483 1208 if (opt_ignore_existing && am_sender)
3d6feada
MP
1209 args[ac++] = "--ignore-existing";
1210
a3221d2a
WD
1211 if (inplace)
1212 args[ac++] = "--inplace";
1213
d853783f
AT
1214 if (tmpdir) {
1215 args[ac++] = "--temp-dir";
1216 args[ac++] = tmpdir;
1217 }
1218
e012f858 1219 if (basis_dir[0] && am_sender) {
375a4556
DD
1220 /* the server only needs this option if it is not the sender,
1221 * and it may be an older version that doesn't know this
1222 * option, so don't send it if client is the sender.
1223 */
e012f858
WD
1224 int i;
1225 for (i = 0; i < basis_dir_cnt; i++) {
1226 args[ac++] = dest_option;
1227 args[ac++] = basis_dir[i];
1228 }
375a4556
DD
1229 }
1230
ea5164d1
WD
1231 if (files_from && (!am_sender || remote_filesfrom_file)) {
1232 if (remote_filesfrom_file) {
1233 args[ac++] = "--files-from";
1234 args[ac++] = remote_filesfrom_file;
1235 if (eol_nulls)
1236 args[ac++] = "--from0";
1237 } else {
1238 args[ac++] = "--files-from=-";
1239 args[ac++] = "--from0";
1240 }
c0ab28d1
WD
1241 if (!relative_paths)
1242 args[ac++] = "--no-relative";
ea5164d1 1243 }
c72f5bd9 1244 if (!implied_dirs && !am_sender)
3a90ea0a 1245 args[ac++] = "--no-implied-dirs";
ea5164d1 1246
d853783f 1247 *argc = ac;
f98c60bf
WD
1248 return;
1249
1250 oom:
1251 out_of_memory("server_options");
7a6421fa
AT
1252}
1253
ea5164d1
WD
1254/**
1255 * Return the position of a ':' IF it is not part of a filename (i.e. as
1256 * long as it doesn't occur after a slash.
1257 */
1258char *find_colon(char *s)
1259{
1260 char *p, *p2;
1261
1262 p = strchr(s,':');
f98c60bf
WD
1263 if (!p)
1264 return NULL;
ea5164d1
WD
1265
1266 /* now check to see if there is a / in the string before the : - if there is then
1267 discard the colon on the assumption that the : is part of a filename */
1268 p2 = strchr(s,'/');
f98c60bf
WD
1269 if (p2 && p2 < p)
1270 return NULL;
ea5164d1
WD
1271
1272 return p;
1273}