Document the extended parsing of --max-size values.
[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
7bc90b30 24extern int module_id;
7be73df4 25extern int sanitize_paths;
7842418b
WD
26extern struct filter_list_struct filter_list;
27extern struct filter_list_struct server_filter_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
a015788d 41int append_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;
20fb7b91 51int omit_dir_times = 0;
7a6421fa
AT
52int update_only = 0;
53int cvs_exclude = 0;
a5c11139 54int dry_run = 0;
11e758a4 55int do_xfers = 1;
a5c11139
WD
56int ignore_times = 0;
57int delete_mode = 0;
a51b3168 58int delete_during = 0;
51d48398
WD
59int delete_before = 0;
60int delete_after = 0;
a5c11139 61int delete_excluded = 0;
07c6ae7d 62int remove_sent_files = 0;
a5c11139 63int one_file_system = 0;
4f3e9a0f 64int protocol_version = PROTOCOL_VERSION;
a5c11139
WD
65int sparse_files = 0;
66int do_compression = 0;
67int am_root = 0;
7f2a1f65
WD
68int am_server = 0;
69int am_sender = 0;
70int am_generator = 0;
71int am_starting_up = 1;
a5c11139 72int orig_umask = 0;
ea5164d1
WD
73int relative_paths = -1;
74int implied_dirs = 1;
7a6421fa
AT
75int numeric_ids = 0;
76int force_delete = 0;
77int io_timeout = 0;
9ac756c6 78int allowed_lull = 0;
ea5164d1
WD
79char *files_from = NULL;
80int filesfrom_fd = -1;
305666bf 81char *filesfrom_host = NULL;
ea5164d1 82int eol_nulls = 0;
7a6421fa 83int recurse = 0;
b6164938 84int xfer_dirs = -1;
1312d9fc
WD
85int am_daemon = 0;
86int daemon_over_rsh = 0;
a5c11139
WD
87int do_stats = 0;
88int do_progress = 0;
89int keep_partial = 0;
90int safe_symlinks = 0;
91int copy_unsafe_links = 0;
92int size_only = 0;
9fb08441 93int daemon_bwlimit = 0;
a5c11139 94int bwlimit = 0;
c4ed1487 95int fuzzy_basis = 0;
3c74c3a3 96size_t bwlimit_writemax = 0;
e90aab49
WD
97int ignore_existing = 0;
98int ignore_non_existing = 0;
07c6ae7d 99int need_messages_from_generator = 0;
a5c11139 100int max_delete = 0;
7d5acf1d 101OFF_T max_size = 0;
a5c11139
WD
102int ignore_errors = 0;
103int modify_window = 0;
104int blocking_io = -1;
2289bf64 105int checksum_seed = 0;
a3221d2a 106int inplace = 0;
f06e7082 107int delay_updates = 0;
a06b419d 108long block_size = 0; /* "long" because popt can't set an int32. */
7a6421fa 109
b35d0d8e 110
13e29995 111/** Network address family. **/
4f5b0756 112#ifdef INET6
13e29995 113int default_af_hint = 0; /* Any protocol */
6ab6d4bf 114#else
13e29995 115int default_af_hint = AF_INET; /* Must use IPv4 */
6ab6d4bf 116#endif
06963d0f 117
13e29995
MP
118/** Do not go into the background when run as --daemon. Good
119 * for debugging and required for running as a service on W32,
120 * or under Unix process-monitors. **/
1f35babc
WD
121int no_detach
122#if defined _WIN32 || defined __WIN32__
123 = 1;
124#else
125 = 0;
126#endif
13e29995 127
088aac85
DD
128int write_batch = 0;
129int read_batch = 0;
d175d7e1
WD
130int backup_dir_len = 0;
131int backup_suffix_len;
e0391f81 132unsigned int backup_dir_remainder;
6902ed17 133
d175d7e1 134char *backup_suffix = NULL;
7a6421fa 135char *tmpdir = NULL;
a7260c40 136char *partial_dir = NULL;
e012f858 137char *basis_dir[MAX_BASIS_DIRS+1];
30e8c8e1 138char *config_file = NULL;
7a6421fa 139char *shell_cmd = NULL;
b6062654 140char *log_format = NULL;
65575e96 141char *password_file = NULL;
41bd28fe 142char *rsync_path = RSYNC_PATH;
66203a98 143char *backup_dir = NULL;
e0391f81 144char backup_dir_buf[MAXPATHLEN];
0c56b1ad 145int rsync_port = 0;
dfd7d541 146int compare_dest = 0;
1de3e99b 147int copy_dest = 0;
59c95e42 148int link_dest = 0;
ce0b384f 149int basis_dir_cnt = 0;
f9a9f547 150char *dest_option = NULL;
7a6421fa
AT
151
152int verbose = 0;
b86f0cef 153int quiet = 0;
e7651884 154int log_before_transfer = 0;
684d7582 155int log_format_has_i = 0;
5c5e1598 156int log_format_has_o_or_i = 0;
7a6421fa 157int always_checksum = 0;
f7632fc6 158int list_only = 0;
7a6421fa 159
9b3318b0
WD
160#define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
161char *batch_name = NULL;
6902ed17 162
e1add893 163static int daemon_opt; /* sets am_daemon after option error-reporting */
aa4d3b4c 164static int F_option_cnt = 0;
5b56cc19 165static int modify_window_set;
624d6be2 166static int itemize_changes = 0;
702cd15c 167static int refused_delete, refused_archive_part;
3296f91b 168static int refused_partial, refused_progress, refused_delete_before;
a015788d 169static int refused_inplace;
7d5acf1d 170static char *max_size_arg;
3671987f 171static char partialdir_for_delayupdate[] = ".~tmp~";
5b56cc19 172
06963d0f 173/** Local address to bind. As a character string because it's
fdf57ede 174 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
06963d0f
MP
175 * address, or a hostname. **/
176char *bind_address;
5c9730a4 177
7a24c346 178
27a12348 179static void print_rsync_version(enum logcode f)
7a24c346 180{
dfa32483 181 char const *got_socketpair = "no ";
a3221d2a 182 char const *have_inplace = "no ";
dfa32483
WD
183 char const *hardlinks = "no ";
184 char const *links = "no ";
a358449a 185 char const *ipv6 = "no ";
736a6a29 186 STRUCT_STAT *dumstat;
0c80cd8e 187
4f5b0756 188#ifdef HAVE_SOCKETPAIR
dfa32483 189 got_socketpair = "";
0c80cd8e 190#endif
2855f61f 191
4f5b0756 192#ifdef HAVE_FTRUNCATE
a3221d2a
WD
193 have_inplace = "";
194#endif
195
4f5b0756 196#ifdef SUPPORT_HARD_LINKS
dfa32483 197 hardlinks = "";
2855f61f
MP
198#endif
199
4f5b0756 200#ifdef SUPPORT_LINKS
dfa32483 201 links = "";
2855f61f
MP
202#endif
203
4f5b0756 204#ifdef INET6
a358449a 205 ipv6 = "";
dfa32483 206#endif
a358449a 207
dfa32483
WD
208 rprintf(f, "%s version %s protocol version %d\n",
209 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
210 rprintf(f,
72a90c75 211 "Copyright (C) 1996-2005 by Andrew Tridgell and others\n");
3b4b1984 212 rprintf(f, "<http://rsync.samba.org/>\n");
dfa32483
WD
213 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
214 "%shard links, %ssymlinks, batchfiles, \n",
a5c11139 215 (int) (sizeof (OFF_T) * 8),
dfa32483 216 got_socketpair, hardlinks, links);
2855f61f 217
736a6a29
MP
218 /* Note that this field may not have type ino_t. It depends
219 * on the complicated interaction between largefile feature
220 * macros. */
a3221d2a
WD
221 rprintf(f, " %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
222 have_inplace, ipv6,
a5c11139 223 (int) (sizeof dumstat->st_ino * 8),
1490812a 224 (int) (sizeof (int64) * 8));
fc0302cf
MP
225#ifdef MAINTAINER_MODE
226 rprintf(f, " panic action: \"%s\"\n",
227 get_panic_action());
228#endif
736a6a29 229
031fa9ad
WD
230#if SIZEOF_INT64 < 8
231 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
7a24c346 232#endif
c561edaa
WD
233 if (sizeof (int64) != SIZEOF_INT64) {
234 rprintf(f,
235 "WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
236 (int) SIZEOF_INT64, (int) sizeof (int64));
237 }
7b329a2d
MP
238
239 rprintf(f,
240"\n"
241"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
242"are welcome to redistribute it under certain conditions. See the GNU\n"
243"General Public Licence for details.\n"
244 );
7a24c346
MP
245}
246
247
0f3203c3 248void usage(enum logcode F)
7a6421fa 249{
2855f61f 250 print_rsync_version(F);
704f908e 251
3ff984d7 252 rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
704f908e 253
868676dc
WD
254 rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... DEST\n");
255 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
256 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
257 rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
d0e94abb 258 rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC [DEST]\n");
14d43f1f 259 rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
14d43f1f 260 rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
08d82b84
WD
261 rprintf(F,"The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect\n");
262 rprintf(F,"to an rsync daemon, and require SRC or DEST to start with a module name.\n");
704f908e
AT
263 rprintf(F,"\nOptions\n");
264 rprintf(F," -v, --verbose increase verbosity\n");
b3708acf
WD
265 rprintf(F," -q, --quiet suppress non-error messages\n");
266 rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n");
267 rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H)\n");
b6164938 268 rprintf(F," --no-OPTION turn of an implied OPTION (e.g. --no-D)\n");
704f908e
AT
269 rprintf(F," -r, --recursive recurse into directories\n");
270 rprintf(F," -R, --relative use relative path names\n");
11bfaf63 271 rprintf(F," --no-implied-dirs don't send implied dirs with --relative\n");
6839140e 272 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
b3708acf
WD
273 rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
274 rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
275 rprintf(F," -u, --update skip files that are newer on the receiver\n");
4ce838e1 276 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
a015788d 277 rprintf(F," --append append data onto shorter files\n");
65e4cda0 278 rprintf(F," -d, --dirs transfer directories without recursing\n");
13e29995 279 rprintf(F," -l, --links copy symlinks as symlinks\n");
b3708acf
WD
280 rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
281 rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n");
282 rprintf(F," --safe-links ignore symlinks that point outside the source tree\n");
704f908e 283 rprintf(F," -H, --hard-links preserve hard links\n");
65e4cda0 284 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
704f908e
AT
285 rprintf(F," -p, --perms preserve permissions\n");
286 rprintf(F," -o, --owner preserve owner (root only)\n");
287 rprintf(F," -g, --group preserve group\n");
288 rprintf(F," -D, --devices preserve devices (root only)\n");
dfa32483 289 rprintf(F," -t, --times preserve times\n");
20fb7b91 290 rprintf(F," -O, --omit-dir-times omit directories when preserving times\n");
704f908e
AT
291 rprintf(F," -S, --sparse handle sparse files efficiently\n");
292 rprintf(F," -n, --dry-run show what would have been transferred\n");
98bf61c8 293 rprintf(F," -W, --whole-file copy files whole (without rsync algorithm)\n");
704f908e 294 rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
9cd339eb 295 rprintf(F," -B, --block-size=SIZE force a fixed checksum block-size\n");
b3708acf 296 rprintf(F," -e, --rsh=COMMAND specify the remote shell to use\n");
05ee4866 297 rprintf(F," --rsync-path=PROGRAM specify the rsync to run on the remote machine\n");
b3708acf 298 rprintf(F," --existing only update files that already exist on receiver\n");
6839140e 299 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
07c6ae7d 300 rprintf(F," --remove-sent-files sent files/symlinks are removed from sending side\n");
3359acb8 301 rprintf(F," --del an alias for --delete-during\n");
704f908e 302 rprintf(F," --delete delete files that don't exist on the sending side\n");
c6eb7fad 303 rprintf(F," --delete-before receiver deletes before transfer (default)\n");
3359acb8
WD
304 rprintf(F," --delete-during receiver deletes during transfer, not before\n");
305 rprintf(F," --delete-after receiver deletes after transfer, not before\n");
51d48398 306 rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
db2b5cb7 307 rprintf(F," --ignore-errors delete even if there are I/O errors\n");
51d48398 308 rprintf(F," --force force deletion of directories even if not empty\n");
0b73ca12 309 rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
7d5acf1d 310 rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n");
c95da96a 311 rprintf(F," --partial keep partially transferred files\n");
a7260c40 312 rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
b3708acf 313 rprintf(F," --delay-updates put all updated files into place at transfer's end\n");
704f908e 314 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
db2b5cb7 315 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
b3708acf
WD
316 rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
317 rprintf(F," --size-only skip files that match in size\n");
318 rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
4db88e5b 319 rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
c4ed1487 320 rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n");
375a4556 321 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
1de3e99b 322 rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
e012f858 323 rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
f924946e 324 rprintf(F," -z, --compress compress file data during the transfer\n");
b3708acf 325 rprintf(F," -C, --cvs-exclude auto-ignore files the same way CVS does\n");
aa4d3b4c 326 rprintf(F," -f, --filter=RULE add a file-filtering RULE\n");
9c71f56a 327 rprintf(F," -F same as --filter='dir-merge /.rsync-filter'\n");
aa4d3b4c 328 rprintf(F," repeated: --filter='- .rsync-filter'\n");
2acf81eb 329 rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
b3708acf 330 rprintf(F," --exclude-from=FILE read exclude patterns from FILE\n");
2acf81eb 331 rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
b3708acf
WD
332 rprintf(F," --include-from=FILE read include patterns from FILE\n");
333 rprintf(F," --files-from=FILE read list of source-file names from FILE\n");
72316028 334 rprintf(F," -0, --from0 all *-from/filter files are delimited by 0s\n");
b4ef0bca 335 rprintf(F," --address=ADDRESS bind address for outgoing socket to daemon\n");
b4713295 336 rprintf(F," --port=PORT specify double-colon alternate port number\n");
db2b5cb7 337 rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
b3708acf 338 rprintf(F," --stats give some file-transfer stats\n");
dfa32483 339 rprintf(F," --progress show progress during transfer\n");
b3708acf 340 rprintf(F," -P same as --partial --progress\n");
b78296cb 341 rprintf(F," -i, --itemize-changes output a change-summary for all updates\n");
4a34c6f1 342 rprintf(F," --log-format=FORMAT output filenames using the specified format\n");
b3708acf 343 rprintf(F," --password-file=FILE read password from FILE\n");
65e4cda0 344 rprintf(F," --list-only list the files instead of copying them\n");
b3708acf
WD
345 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
346 rprintf(F," --write-batch=FILE write a batched update to FILE\n");
11e758a4 347 rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
b3708acf 348 rprintf(F," --read-batch=FILE read a batched update from FILE\n");
da9f5926 349 rprintf(F," --protocol=NUM force an older protocol version to be used\n");
4f5b0756 350#ifdef INET6
4db88e5b
WD
351 rprintf(F," -4, --ipv4 prefer IPv4\n");
352 rprintf(F," -6, --ipv6 prefer IPv6\n");
06963d0f 353#endif
4a34c6f1 354 rprintf(F," --version print version number\n");
3dd22903 355 rprintf(F," -h, --help show this help screen\n");
7a6421fa 356
3ac7f5d4
WD
357 rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
358 rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
2855f61f 359 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
7a6421fa
AT
360}
361
3ac7f5d4 362enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
1de3e99b 363 OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
1f3d6cdd 364 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
9ac756c6 365 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
c67d1386 366 OPT_REFUSED_BASE = 9000};
7a6421fa 367
2855f61f
MP
368static struct poptOption long_options[] = {
369 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
e86e2fa1 370 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
8db7cc2c 371 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
e86e2fa1 372 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
b6164938 373 {"no-verbose", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
4afcb709 374 {"no-v", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
e86e2fa1
WD
375 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
376 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
377 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
b6164938
WD
378 {"archive", 'a', POPT_ARG_NONE, 0, 'a', 0, 0 },
379 {"recursive", 'r', POPT_ARG_VAL, &recurse, 2, 0, 0 },
380 {"no-recursive", 0, POPT_ARG_VAL, &recurse, 0, 0, 0 },
381 {"no-r", 0, POPT_ARG_VAL, &recurse, 0, 0, 0 },
e86e2fa1 382 {"dirs", 'd', POPT_ARG_VAL, &xfer_dirs, 2, 0, 0 },
b6164938
WD
383 {"no-dirs", 0, POPT_ARG_VAL, &xfer_dirs, 0, 0, 0 },
384 {"no-d", 0, POPT_ARG_VAL, &xfer_dirs, 0, 0, 0 },
385 {"perms", 'p', POPT_ARG_VAL, &preserve_perms, 1, 0, 0 },
386 {"no-perms", 0, POPT_ARG_VAL, &preserve_perms, 0, 0, 0 },
387 {"no-p", 0, POPT_ARG_VAL, &preserve_perms, 0, 0, 0 },
388 {"times", 't', POPT_ARG_VAL, &preserve_times, 1, 0, 0 },
b6164938
WD
389 {"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
390 {"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
38b9170c
WD
391 {"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 2, 0, 0 },
392 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
b6164938
WD
393 {"owner", 'o', POPT_ARG_VAL, &preserve_uid, 1, 0, 0 },
394 {"no-owner", 0, POPT_ARG_VAL, &preserve_uid, 0, 0, 0 },
395 {"no-o", 0, POPT_ARG_VAL, &preserve_uid, 0, 0, 0 },
396 {"group", 'g', POPT_ARG_VAL, &preserve_gid, 1, 0, 0 },
397 {"no-group", 0, POPT_ARG_VAL, &preserve_gid, 0, 0, 0 },
398 {"no-g", 0, POPT_ARG_VAL, &preserve_gid, 0, 0, 0 },
399 {"devices", 'D', POPT_ARG_VAL, &preserve_devices, 1, 0, 0 },
400 {"no-devices", 0, POPT_ARG_VAL, &preserve_devices, 0, 0, 0 },
401 {"no-D", 0, POPT_ARG_VAL, &preserve_devices, 0, 0, 0 },
e86e2fa1 402 {"links", 'l', POPT_ARG_VAL, &preserve_links, 1, 0, 0 },
b6164938
WD
403 {"no-links", 0, POPT_ARG_VAL, &preserve_links, 0, 0, 0 },
404 {"no-l", 0, POPT_ARG_VAL, &preserve_links, 0, 0, 0 },
e86e2fa1
WD
405 {"copy-links", 'L', POPT_ARG_NONE, &copy_links, 0, 0, 0 },
406 {"copy-unsafe-links",0, POPT_ARG_NONE, &copy_unsafe_links, 0, 0, 0 },
407 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
408 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
409 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
410 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
411 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
b6164938 412 {"no-R", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
e86e2fa1 413 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
afb6e945
WD
414 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
415 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
afb6e945 416 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
e86e2fa1 417 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
e90aab49
WD
418 {"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
419 {"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 },
420 {"ignore-non-existing",0,POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
aeb213ea 421 {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
e86e2fa1
WD
422 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
423 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
424 {"append", 0, POPT_ARG_VAL, &append_mode, 1, 0, 0 },
3671987f 425 {"del", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
3359acb8 426 {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
c6eb7fad 427 {"delete-before", 0, POPT_ARG_VAL, &delete_before, 2, 0, 0 },
3359acb8 428 {"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
51d48398
WD
429 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
430 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
07c6ae7d 431 {"remove-sent-files",0, POPT_ARG_NONE, &remove_sent_files, 0, 0, 0 },
afb6e945 432 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
e86e2fa1
WD
433 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
434 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
435 {0, 'F', POPT_ARG_NONE, 0, 'F', 0, 0 },
aa4d3b4c 436 {"filter", 'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
8db7cc2c
WD
437 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
438 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
439 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
440 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
afb6e945 441 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
afb6e945
WD
442 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
443 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
b6164938 444 {"no-W", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
afb6e945 445 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
a06b419d 446 {"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
e012f858 447 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
1de3e99b 448 {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
e012f858 449 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
c4ed1487 450 {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
afb6e945 451 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
11bfaf63 452 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
b6164938
WD
453 {"progress", 0, POPT_ARG_VAL, &do_progress, 1, 0, 0 },
454 {"no-progress", 0, POPT_ARG_VAL, &do_progress, 0, 0, 0 },
455 {"partial", 0, POPT_ARG_VAL, &keep_partial, 1, 0, 0 },
456 {"no-partial", 0, POPT_ARG_VAL, &keep_partial, 0, 0, 0 },
a7260c40 457 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
f06e7082 458 {"delay-updates", 0, POPT_ARG_NONE, &delay_updates, 0, 0, 0 },
afb6e945 459 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
b78296cb 460 {"itemize-changes", 'i', POPT_ARG_NONE, &itemize_changes, 0, 0, 0 },
afb6e945 461 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
11bfaf63 462 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
afb6e945 463 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
e86e2fa1
WD
464 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
465 {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
8db7cc2c
WD
466 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
467 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
11e758a4 468 {"only-write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 },
ea5164d1
WD
469 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
470 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
e86e2fa1
WD
471 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
472 {"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 },
473 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
474 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
475 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
4f5b0756 476#ifdef INET6
3dd22903
WD
477 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
478 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
06963d0f 479#endif
e86e2fa1
WD
480 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
481 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
482 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
483 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
484 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
485 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
486 {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
487 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
488 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
489 /* All the following options switch us into daemon-mode option-parsing. */
3ac7f5d4
WD
490 {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
491 {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
1f35babc 492 {"detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
3ac7f5d4 493 {"no-detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
3ac7f5d4
WD
494 {0,0,0,0, 0, 0, 0}
495};
496
497static void daemon_usage(enum logcode F)
498{
499 print_rsync_version(F);
500
501 rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
502 rprintf(F," --address=ADDRESS bind to the specified address\n");
b3708acf 503 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
3ac7f5d4
WD
504 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
505 rprintf(F," --no-detach do not detach from the parent\n");
b3708acf 506 rprintf(F," --port=PORT listen on alternate port number\n");
1bd9db74 507 rprintf(F," -v, --verbose increase verbosity\n");
4f5b0756 508#ifdef INET6
3ac7f5d4
WD
509 rprintf(F," -4, --ipv4 prefer IPv4\n");
510 rprintf(F," -6, --ipv6 prefer IPv6\n");
511#endif
512 rprintf(F," -h, --help show this help screen\n");
513
514 rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
515 rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
516}
517
518static struct poptOption long_daemon_options[] = {
519 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
520 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
9fb08441 521 {"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
3ac7f5d4
WD
522 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
523 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
4f5b0756 524#ifdef INET6
3ac7f5d4
WD
525 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
526 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
527#endif
1f35babc
WD
528 {"detach", 0, POPT_ARG_VAL, &no_detach, 0, 0, 0 },
529 {"no-detach", 0, POPT_ARG_VAL, &no_detach, 1, 0, 0 },
3ac7f5d4
WD
530 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
531 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
532 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
b8cc3587 533 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
1bd9db74 534 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
b6e22a47
WD
535 {"no-verbose", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
536 {"no-v", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
3ac7f5d4 537 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
ad715008 538 {0,0,0,0, 0, 0, 0}
2855f61f 539};
7a6421fa 540
06963d0f 541
e51094b7 542static char err_buf[200];
cd8185f2 543
2855f61f 544
dafe63ca
MP
545/**
546 * Store the option error message, if any, so that we can log the
547 * connection attempt (which requires parsing the options), and then
548 * show the error later on.
549 **/
cd8185f2
AT
550void option_error(void)
551{
e51094b7
WD
552 if (!err_buf[0]) {
553 strcpy(err_buf, "Error parsing options: "
554 "option may be supported on client but not on server?\n");
cd8185f2 555 }
e51094b7 556
e51094b7 557 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
cd8185f2
AT
558}
559
dafe63ca
MP
560
561/**
27ed20f7
WD
562 * Tweak the option table to disable all options that the rsyncd.conf
563 * file has told us to refuse.
dafe63ca 564 **/
27ed20f7 565static void set_refuse_options(char *bp)
cd8185f2 566{
27ed20f7 567 struct poptOption *op;
093e816c 568 char *cp, shortname[2];
d73e7f6e 569 int is_wild, found_match;
093e816c
WD
570
571 shortname[1] = '\0';
27ed20f7
WD
572
573 while (1) {
06a50542
WD
574 while (*bp == ' ') bp++;
575 if (!*bp)
576 break;
27ed20f7
WD
577 if ((cp = strchr(bp, ' ')) != NULL)
578 *cp= '\0';
093e816c 579 is_wild = strpbrk(bp, "*?[") != NULL;
d73e7f6e 580 found_match = 0;
55afbb52 581 for (op = long_options; ; op++) {
093e816c 582 *shortname = op->shortName;
d73e7f6e
WD
583 if (!op->longName && !*shortname)
584 break;
585 if ((op->longName && wildmatch(bp, op->longName))
684d7582 586 || (*shortname && wildmatch(bp, shortname))) {
e57211c5
WD
587 if (op->argInfo == POPT_ARG_VAL)
588 op->argInfo = POPT_ARG_NONE;
06a50542 589 op->val = (op - long_options) + OPT_REFUSED_BASE;
d73e7f6e 590 found_match = 1;
3671987f
WD
591 /* These flags are set to let us easily check
592 * an implied option later in the code. */
593 switch (*shortname) {
3671987f
WD
594 case 'r': case 'd': case 'l': case 'p':
595 case 't': case 'g': case 'o': case 'D':
596 refused_archive_part = op->val;
597 break;
598 case '\0':
599 if (wildmatch("delete", op->longName))
600 refused_delete = op->val;
3296f91b
WD
601 else if (wildmatch("delete-before", op->longName))
602 refused_delete_before = op->val;
3671987f
WD
603 else if (wildmatch("partial", op->longName))
604 refused_partial = op->val;
605 else if (wildmatch("progress", op->longName))
606 refused_progress = op->val;
a015788d
WD
607 else if (wildmatch("inplace", op->longName))
608 refused_inplace = op->val;
3671987f
WD
609 break;
610 }
06a50542
WD
611 if (!is_wild)
612 break;
27ed20f7 613 }
cd8185f2 614 }
d73e7f6e
WD
615 if (!found_match) {
616 rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
617 bp);
618 }
27ed20f7
WD
619 if (!cp)
620 break;
621 *cp = ' ';
622 bp = cp + 1;
cd8185f2 623 }
684d7582
WD
624
625 for (op = long_options; ; op++) {
626 *shortname = op->shortName;
627 if (!op->longName && !*shortname)
628 break;
629 if (op->val == OPT_DAEMON) {
630 if (op->argInfo == POPT_ARG_VAL)
631 op->argInfo = POPT_ARG_NONE;
632 op->val = (op - long_options) + OPT_REFUSED_BASE;
633 }
634 }
cd8185f2
AT
635}
636
637
8db7cc2c 638static int count_args(const char **argv)
2855f61f 639{
dfa32483 640 int i = 0;
2855f61f 641
8db7cc2c
WD
642 if (argv) {
643 while (argv[i] != NULL)
644 i++;
645 }
dfa32483
WD
646
647 return i;
2855f61f
MP
648}
649
650
aeb213ea 651static OFF_T parse_size_arg(char **size_arg)
95e107db
WD
652{
653 const char *arg;
654 OFF_T size;
aeb213ea 655 int mult, make_compatible = 0;
95e107db 656
aeb213ea 657 for (arg = *size_arg; isdigit(*(uchar*)arg); arg++) {}
95e107db
WD
658 if (*arg == '.')
659 for (arg++; isdigit(*(uchar*)arg); arg++) {}
aeb213ea
WD
660 if (*arg && (arg[1] == 't' || arg[1] == 'T'))
661 mult = 1000, make_compatible = 1;
662 else
663 mult = 1024;
95e107db
WD
664 switch (*arg) {
665 case 'k': case 'K':
aeb213ea 666 size = atof(*size_arg) * mult;
95e107db
WD
667 break;
668 case 'm': case 'M':
aeb213ea 669 size = atof(*size_arg) * mult*mult;
95e107db
WD
670 break;
671 case 'g': case 'G':
aeb213ea 672 size = atof(*size_arg) * mult*mult*mult;
95e107db 673 break;
aeb213ea
WD
674 case '\0': case '+': case '-':
675 size = atof(*size_arg);
95e107db
WD
676 break;
677 default:
aeb213ea 678 size = -1;
95e107db
WD
679 break;
680 }
aeb213ea
WD
681 if (strchr(arg, '+'))
682 size++, make_compatible = 1;
683 else if (strchr(arg, '-'))
684 size--, make_compatible = 1;
685 if (size > 0 && make_compatible) {
686 /* We convert this manually because we many need %lld
687 * precision, and that's not portable. */
688 char buf[128], *s = buf + sizeof buf;
689 OFF_T num = size;
690 *--s = '\0';
691 while (num) {
692 if (s == buf) /* impossible... */
693 out_of_memory("parse_size_arg@buf");
694 *--s = (num % 10) + '0';
695 num /= 10;
696 }
697 if (!(*size_arg = strdup(s)))
698 out_of_memory("parse_size_arg");
699 }
95e107db
WD
700 return size;
701}
702
703
3671987f
WD
704static void create_refuse_error(int which)
705{
706 /* The "which" value is the index + OPT_REFUSED_BASE. */
707 struct poptOption *op = &long_options[which - OPT_REFUSED_BASE];
708 int n = snprintf(err_buf, sizeof err_buf,
709 "The server is configured to refuse --%s\n",
710 op->longName) - 1;
711 if (op->shortName) {
712 snprintf(err_buf + n, sizeof err_buf - n,
713 " (-%c)\n", op->shortName);
714 }
715}
716
717
dafe63ca
MP
718/**
719 * Process command line arguments. Called on both local and remote.
720 *
721 * @retval 1 if all options are OK; with globals set to appropriate
722 * values
723 *
724 * @retval 0 on error, with err_buf containing an explanation
725 **/
2855f61f 726int parse_arguments(int *argc, const char ***argv, int frommain)
7a6421fa 727{
d853783f 728 int opt;
cd8185f2 729 char *ref = lp_refuse_options(module_id);
7be73df4 730 const char *arg;
dfa32483 731 poptContext pc;
d853783f 732
27ed20f7
WD
733 if (ref && *ref)
734 set_refuse_options(ref);
735
dfa32483 736 /* TODO: Call poptReadDefaultConfig; handle errors. */
cd8185f2 737
dfa32483
WD
738 /* The context leaks in case of an error, but if there's a
739 * problem we always exit anyhow. */
740 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
9fb08441 741 poptReadDefaultConfig(pc, 0);
2855f61f
MP
742
743 while ((opt = poptGetNextOpt(pc)) != -1) {
dfa32483
WD
744 /* most options are handled automatically by popt;
745 * only special cases are returned and listed here. */
2855f61f 746
d853783f
AT
747 switch (opt) {
748 case OPT_VERSION:
dfa32483 749 print_rsync_version(FINFO);
d853783f 750 exit_cleanup(0);
dfa32483 751
3ac7f5d4
WD
752 case OPT_DAEMON:
753 if (am_daemon) {
754 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
755 return 0;
756 }
757 poptFreeContext(pc);
758 pc = poptGetContext(RSYNC_NAME, *argc, *argv,
759 long_daemon_options, 0);
760 while ((opt = poptGetNextOpt(pc)) != -1) {
761 switch (opt) {
762 case 'h':
763 daemon_usage(FINFO);
764 exit_cleanup(0);
765
1bd9db74
WD
766 case 'v':
767 verbose++;
768 break;
769
3ac7f5d4
WD
770 default:
771 rprintf(FERROR,
772 "rsync: %s: %s (in daemon mode)\n",
773 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
774 poptStrerror(opt));
775 goto daemon_error;
776 }
777 }
b6e22a47
WD
778
779 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
780 snprintf(err_buf, sizeof err_buf,
781 "the --temp-dir path is WAY too long.\n");
782 return 0;
783 }
784
3ac7f5d4
WD
785 if (!daemon_opt) {
786 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
787 daemon_error:
788 rprintf(FERROR,
789 "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
790 exit_cleanup(RERR_SYNTAX);
791 }
b6e22a47 792
3ac7f5d4
WD
793 *argv = poptGetArgs(pc);
794 *argc = count_args(*argv);
7f2a1f65 795 am_starting_up = 0;
3ac7f5d4
WD
796 daemon_opt = 0;
797 am_daemon = 1;
798 return 1;
799
5b56cc19 800 case OPT_MODIFY_WINDOW:
dfa32483
WD
801 /* The value has already been set by popt, but
802 * we need to remember that we're using a
803 * non-default setting. */
5b56cc19
AT
804 modify_window_set = 1;
805 break;
1de50993 806
aa4d3b4c 807 case OPT_FILTER:
3a5e9224 808 parse_rule(&filter_list, poptGetOptArg(pc), 0, 0);
d853783f
AT
809 break;
810
aa4d3b4c 811 case OPT_EXCLUDE:
3a5e9224 812 parse_rule(&filter_list, poptGetOptArg(pc),
0a68f869 813 0, XFLG_OLD_PREFIXES);
aa4d3b4c
WD
814 break;
815
d853783f 816 case OPT_INCLUDE:
3a5e9224 817 parse_rule(&filter_list, poptGetOptArg(pc),
0a68f869 818 MATCHFLG_INCLUDE, XFLG_OLD_PREFIXES);
d853783f
AT
819 break;
820
821 case OPT_EXCLUDE_FROM:
93695764 822 case OPT_INCLUDE_FROM:
7be73df4 823 arg = poptGetOptArg(pc);
ba3db479
WD
824 if (sanitize_paths)
825 arg = sanitize_path(NULL, arg, NULL, 0);
7842418b 826 if (server_filter_list.head) {
ba3db479 827 char *cp = (char *)arg;
3671987f
WD
828 if (!*cp)
829 goto options_rejected;
ba3db479 830 clean_fname(cp, 1);
7842418b 831 if (check_filter(&server_filter_list, cp, 0) < 0)
ba3db479
WD
832 goto options_rejected;
833 }
3a5e9224
WD
834 parse_filter_file(&filter_list, arg,
835 opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
836 XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
93695764
DD
837 break;
838
b6164938
WD
839 case 'a':
840 if (refused_archive_part) {
841 create_refuse_error(refused_archive_part);
842 return 0;
843 }
844 if (!recurse) /* preserve recurse == 2 */
845 recurse = 1;
846#ifdef SUPPORT_LINKS
847 preserve_links = 1;
848#endif
849 preserve_perms = 1;
850 preserve_times = 1;
851 preserve_gid = 1;
852 preserve_uid = 1;
853 preserve_devices = 1;
854 break;
855
d853783f
AT
856 case 'h':
857 usage(FINFO);
858 exit_cleanup(0);
859
d853783f
AT
860 case 'v':
861 verbose++;
862 break;
7a6421fa 863
b86f0cef 864 case 'q':
f98c60bf
WD
865 if (frommain)
866 quiet++;
b86f0cef
DD
867 break;
868
d853783f
AT
869 case OPT_SENDER:
870 if (!am_server) {
871 usage(FERROR);
65417579 872 exit_cleanup(RERR_SYNTAX);
d853783f
AT
873 }
874 am_sender = 1;
875 break;
876
aa4d3b4c
WD
877 case 'F':
878 switch (++F_option_cnt) {
879 case 1:
3a5e9224 880 parse_rule(&filter_list,": /.rsync-filter",0,0);
aa4d3b4c
WD
881 break;
882 case 2:
3a5e9224 883 parse_rule(&filter_list,"- .rsync-filter",0,0);
aa4d3b4c
WD
884 break;
885 }
886 break;
887
d9fcc198 888 case 'P':
3671987f
WD
889 if (refused_partial || refused_progress) {
890 create_refuse_error(refused_partial
891 ? refused_partial : refused_progress);
892 return 0;
893 }
d9fcc198
AT
894 do_progress = 1;
895 keep_partial = 1;
896 break;
897
088aac85 898 case OPT_WRITE_BATCH:
9b3318b0 899 /* batch_name is already set */
088aac85
DD
900 write_batch = 1;
901 break;
902
11e758a4
WD
903 case OPT_ONLY_WRITE_BATCH:
904 /* batch_name is already set */
905 write_batch = -1;
906 break;
907
76f79ba7 908 case OPT_READ_BATCH:
9b3318b0 909 /* batch_name is already set */
6902ed17
MP
910 read_batch = 1;
911 break;
ea5164d1 912
7d5acf1d 913 case OPT_MAX_SIZE:
aeb213ea 914 if ((max_size = parse_size_arg(&max_size_arg)) <= 0) {
e012f858 915 snprintf(err_buf, sizeof err_buf,
7d5acf1d
WD
916 "--max-size value is invalid: %s\n",
917 max_size_arg);
e012f858 918 return 0;
7d5acf1d
WD
919 }
920 break;
921
59c95e42 922 case OPT_LINK_DEST:
4f5b0756 923#ifdef HAVE_LINK
59c95e42 924 link_dest = 1;
e012f858
WD
925 dest_option = "--link-dest";
926 goto set_dest_dir;
59c95e42 927#else
d175d7e1 928 snprintf(err_buf, sizeof err_buf,
dfa32483 929 "hard links are not supported on this %s\n",
59c95e42 930 am_server ? "server" : "client");
59c95e42
DD
931 return 0;
932#endif
933
1de3e99b
WD
934 case OPT_COPY_DEST:
935 copy_dest = 1;
936 dest_option = "--copy-dest";
937 goto set_dest_dir;
938
e012f858
WD
939 case OPT_COMPARE_DEST:
940 compare_dest = 1;
941 dest_option = "--compare-dest";
942 set_dest_dir:
3b26bba0 943 if (basis_dir_cnt >= MAX_BASIS_DIRS) {
e012f858
WD
944 snprintf(err_buf, sizeof err_buf,
945 "ERROR: at most %d %s args may be specified\n",
946 MAX_BASIS_DIRS, dest_option);
947 return 0;
948 }
949 arg = poptGetOptArg(pc);
950 if (sanitize_paths)
951 arg = sanitize_path(NULL, arg, NULL, 0);
952 basis_dir[basis_dir_cnt++] = (char *)arg;
953 break;
954
d853783f 955 default:
55afbb52 956 /* A large opt value means that set_refuse_options()
3671987f 957 * turned this option off. */
c67d1386 958 if (opt >= OPT_REFUSED_BASE) {
3671987f
WD
959 create_refuse_error(opt);
960 return 0;
27ed20f7 961 }
3671987f
WD
962 snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
963 am_server ? "on remote machine: " : "",
964 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
965 poptStrerror(opt));
dfa32483 966 return 0;
d853783f 967 }
7a6421fa 968 }
2855f61f 969
4f5b0756 970#ifndef SUPPORT_LINKS
54e87b4b 971 if (preserve_links && !am_sender) {
e1add893
WD
972 snprintf(err_buf, sizeof err_buf,
973 "symlinks are not supported on this %s\n",
974 am_server ? "server" : "client");
e1add893
WD
975 return 0;
976 }
977#endif
978
4f5b0756 979#ifndef SUPPORT_HARD_LINKS
e1add893
WD
980 if (preserve_hard_links) {
981 snprintf(err_buf, sizeof err_buf,
982 "hard links are not supported on this %s\n",
983 am_server ? "server" : "client");
e1add893
WD
984 return 0;
985 }
986#endif
987
088aac85 988 if (write_batch && read_batch) {
c3ea0990 989 snprintf(err_buf, sizeof err_buf,
36119893 990 "--write-batch and --read-batch can not be used together\n");
c3ea0990 991 return 0;
088aac85 992 }
11e758a4 993 if (write_batch > 0 || read_batch) {
94327ff0
WD
994 if (am_server) {
995 rprintf(FINFO,
996 "ignoring --%s-batch option sent to server\n",
997 write_batch ? "write" : "read");
998 /* We don't actually exit_cleanup(), so that we can
999 * still service older version clients that still send
1000 * batch args to server. */
1001 read_batch = write_batch = 0;
1002 batch_name = NULL;
254ee3ba
WD
1003 } else if (dry_run)
1004 write_batch = 0;
b9f592fb 1005 }
36119893 1006 if (read_batch && files_from) {
c3ea0990 1007 snprintf(err_buf, sizeof err_buf,
36119893 1008 "--read-batch cannot be used with --files-from\n");
c3ea0990 1009 return 0;
36119893 1010 }
9b3318b0 1011 if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
c3ea0990 1012 snprintf(err_buf, sizeof err_buf,
9b3318b0
WD
1013 "the batch-file name must be %d characters or less.\n",
1014 MAX_BATCH_NAME_LEN);
c3ea0990 1015 return 0;
beb93684 1016 }
088aac85 1017
ce58b1b4 1018 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
c3ea0990
WD
1019 snprintf(err_buf, sizeof err_buf,
1020 "the --temp-dir path is WAY too long.\n");
1021 return 0;
ce58b1b4
WD
1022 }
1023
1de3e99b 1024 if (compare_dest + copy_dest + link_dest > 1) {
e012f858 1025 snprintf(err_buf, sizeof err_buf,
1de3e99b 1026 "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
e012f858
WD
1027 return 0;
1028 }
1029
b6164938
WD
1030 if (files_from) {
1031 if (recurse == 1) /* preserve recurse == 2 */
1032 recurse = 0;
550d4e23 1033 if (xfer_dirs < 0)
b6164938 1034 xfer_dirs = 1;
dfa32483 1035 }
51d48398 1036
b6164938
WD
1037 if (xfer_dirs < 1)
1038 xfer_dirs = recurse || list_only;
dfa32483 1039
ea5164d1
WD
1040 if (relative_paths < 0)
1041 relative_paths = files_from? 1 : 0;
89f2a4c2
WD
1042 if (!relative_paths)
1043 implied_dirs = 0;
ea5164d1 1044
c6eb7fad 1045 if (!!delete_before + delete_during + delete_after > 1) {
3359acb8 1046 snprintf(err_buf, sizeof err_buf,
c6eb7fad 1047 "You may not combine multiple --delete-WHEN options.\n");
3359acb8
WD
1048 return 0;
1049 }
8d6c1c4e 1050 if (!xfer_dirs) {
78fc60cd
WD
1051 delete_before = delete_during = delete_after = 0;
1052 delete_mode = delete_excluded = 0;
1053 } else if (delete_before || delete_during || delete_after)
51d48398 1054 delete_mode = 1;
3296f91b
WD
1055 else if (delete_mode || delete_excluded) {
1056 if (refused_delete_before) {
1057 create_refuse_error(refused_delete_before);
1058 return 0;
1059 }
3359acb8 1060 delete_mode = delete_before = 1;
3296f91b 1061 }
51d48398 1062
3671987f
WD
1063 if (delete_mode && refused_delete) {
1064 create_refuse_error(refused_delete);
1065 return 0;
1066 }
1067
07c6ae7d
WD
1068 if (remove_sent_files) {
1069 /* We only want to infer this refusal of --remove-sent-files
1070 * via the refusal of "delete", not any of the "delete-FOO"
1071 * options. */
1072 if (refused_delete && am_sender) {
1073 create_refuse_error(refused_delete);
1074 return 0;
1075 }
1076 need_messages_from_generator = 1;
1077 }
1078
7be73df4 1079 *argv = poptGetArgs(pc);
8db7cc2c 1080 *argc = count_args(*argv);
7be73df4
WD
1081
1082 if (sanitize_paths) {
1083 int i;
1084 for (i = *argc; i-- > 0; )
10796f4b 1085 (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
7be73df4 1086 if (tmpdir)
10796f4b 1087 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
a7260c40 1088 if (partial_dir)
10796f4b 1089 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
7be73df4 1090 if (backup_dir)
10796f4b 1091 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
7be73df4 1092 }
7842418b
WD
1093 if (server_filter_list.head && !am_sender) {
1094 struct filter_list_struct *elp = &server_filter_list;
e012f858 1095 int i;
c3ea0990 1096 if (tmpdir) {
3671987f
WD
1097 if (!*tmpdir)
1098 goto options_rejected;
58b1999e 1099 clean_fname(tmpdir, 1);
7842418b 1100 if (check_filter(elp, tmpdir, 1) < 0)
c3ea0990
WD
1101 goto options_rejected;
1102 }
3671987f 1103 if (partial_dir && *partial_dir) {
58b1999e 1104 clean_fname(partial_dir, 1);
7842418b 1105 if (check_filter(elp, partial_dir, 1) < 0)
c3ea0990
WD
1106 goto options_rejected;
1107 }
e012f858 1108 for (i = 0; i < basis_dir_cnt; i++) {
3671987f
WD
1109 if (!*basis_dir[i])
1110 goto options_rejected;
e012f858 1111 clean_fname(basis_dir[i], 1);
7842418b 1112 if (check_filter(elp, basis_dir[i], 1) < 0)
c3ea0990
WD
1113 goto options_rejected;
1114 }
1115 if (backup_dir) {
3671987f
WD
1116 if (!*backup_dir)
1117 goto options_rejected;
58b1999e 1118 clean_fname(backup_dir, 1);
305666bf
WD
1119 if (check_filter(elp, backup_dir, 1) < 0) {
1120 options_rejected:
1121 snprintf(err_buf, sizeof err_buf,
1122 "Your options have been rejected by the server.\n");
1123 return 0;
1124 }
c3ea0990
WD
1125 }
1126 }
7be73df4 1127
d175d7e1 1128 if (!backup_suffix)
e0391f81 1129 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
d175d7e1 1130 backup_suffix_len = strlen(backup_suffix);
80ddadb7 1131 if (strchr(backup_suffix, '/') != NULL) {
c3ea0990
WD
1132 snprintf(err_buf, sizeof err_buf,
1133 "--suffix cannot contain slashes: %s\n",
80ddadb7 1134 backup_suffix);
c3ea0990 1135 return 0;
80ddadb7 1136 }
e0391f81
WD
1137 if (backup_dir) {
1138 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
1139 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
1140 if (backup_dir_remainder < 32) {
c3ea0990
WD
1141 snprintf(err_buf, sizeof err_buf,
1142 "the --backup-dir path is WAY too long.\n");
1143 return 0;
e0391f81
WD
1144 }
1145 if (backup_dir_buf[backup_dir_len - 1] != '/') {
1146 backup_dir_buf[backup_dir_len++] = '/';
1147 backup_dir_buf[backup_dir_len] = '\0';
1148 }
4875d6b6
WD
1149 if (verbose > 1 && !am_sender) {
1150 rprintf(FINFO, "backup_dir is %s\n",
1151 safe_fname(backup_dir_buf));
1152 }
8dcf9335 1153 } else if (!backup_suffix_len && (!am_server || !am_sender)) {
c3ea0990 1154 snprintf(err_buf, sizeof err_buf,
d175d7e1 1155 "--suffix cannot be a null string without --backup-dir\n");
c3ea0990 1156 return 0;
d175d7e1 1157 }
d4021b6d
WD
1158 if (make_backups && !backup_dir)
1159 omit_dir_times = 1;
d175d7e1 1160
e7651884 1161 if (log_format) {
624d6be2 1162 if (log_format_has(log_format, 'i'))
684d7582 1163 log_format_has_i = 1;
624d6be2
WD
1164 if (!log_format_has(log_format, 'b')
1165 && !log_format_has(log_format, 'c'))
e7651884
WD
1166 log_before_transfer = !am_server;
1167 } else if (itemize_changes) {
1168 log_format = "%i %n%L";
684d7582 1169 log_format_has_i = 1;
e7651884
WD
1170 log_before_transfer = !am_server;
1171 }
87383697
WD
1172
1173 if ((do_progress || dry_run) && !verbose && !log_before_transfer
702cd15c 1174 && !am_server)
e2559dbe 1175 verbose = 1;
87383697 1176
11e758a4
WD
1177 if (dry_run)
1178 do_xfers = 0;
1179
9ac756c6
WD
1180 set_io_timeout(io_timeout);
1181
87383697
WD
1182 if (verbose && !log_format) {
1183 log_format = "%n%L";
1184 log_before_transfer = !am_server;
3671987f 1185 }
624d6be2 1186 if (log_format_has_i || log_format_has(log_format, 'o'))
5c5e1598 1187 log_format_has_o_or_i = 1;
e2559dbe 1188
9fb08441
WD
1189 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1190 bwlimit = daemon_bwlimit;
3c74c3a3
WD
1191 if (bwlimit) {
1192 bwlimit_writemax = (size_t)bwlimit * 128;
1193 if (bwlimit_writemax < 512)
1194 bwlimit_writemax = 512;
1195 }
1196
cfce9f6d 1197 if (sparse_files && inplace) {
c3851185 1198 /* Note: we don't check for this below, because --append is
cfce9f6d
WD
1199 * OK with --sparse (as long as redos are handled right). */
1200 snprintf(err_buf, sizeof err_buf,
1201 "--sparse cannot be used with --inplace\n");
1202 return 0;
1203 }
1204
a015788d
WD
1205 if (append_mode) {
1206 if (whole_file > 0) {
1207 snprintf(err_buf, sizeof err_buf,
1208 "--append cannot be used with --whole-file\n");
1209 return 0;
1210 }
1211 if (refused_inplace) {
1212 create_refuse_error(refused_inplace);
1213 return 0;
1214 }
1215 inplace = 1;
1216 }
1217
f06e7082 1218 if (delay_updates && !partial_dir)
3671987f 1219 partial_dir = partialdir_for_delayupdate;
f06e7082 1220
a3221d2a 1221 if (inplace) {
4f5b0756 1222#ifdef HAVE_FTRUNCATE
a7260c40
WD
1223 if (partial_dir) {
1224 snprintf(err_buf, sizeof err_buf,
a015788d
WD
1225 "--%s cannot be used with --%s\n",
1226 append_mode ? "append" : "inplace",
f06e7082 1227 delay_updates ? "delay-updates" : "partial-dir");
a7260c40
WD
1228 return 0;
1229 }
3671987f
WD
1230 /* --inplace implies --partial for refusal purposes, but we
1231 * clear the keep_partial flag for internal logic purposes. */
1232 if (refused_partial) {
1233 create_refuse_error(refused_partial);
1234 return 0;
1235 }
a3221d2a 1236 keep_partial = 0;
ded4daf0
WD
1237#else
1238 snprintf(err_buf, sizeof err_buf,
a015788d
WD
1239 "--%s is not supported on this %s\n",
1240 append_mode ? "append" : "inplace",
ded4daf0
WD
1241 am_server ? "server" : "client");
1242 return 0;
1243#endif
075aa18f 1244 } else {
3671987f
WD
1245 if (keep_partial && !partial_dir) {
1246 if ((arg = getenv("RSYNC_PARTIAL_DIR")) != NULL && *arg)
1247 partial_dir = strdup(arg);
1248 }
075aa18f 1249 if (partial_dir) {
3671987f
WD
1250 if (*partial_dir)
1251 clean_fname(partial_dir, 1);
075aa18f
WD
1252 if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1253 partial_dir = NULL;
13791b1e 1254 else if (*partial_dir != '/') {
3a5e9224 1255 parse_rule(&filter_list, partial_dir,
0a68f869 1256 MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
13791b1e 1257 }
3671987f
WD
1258 if (!partial_dir && refused_partial) {
1259 create_refuse_error(refused_partial);
1260 return 0;
1261 }
075aa18f
WD
1262 keep_partial = 1;
1263 }
a3221d2a
WD
1264 }
1265
ea5164d1 1266 if (files_from) {
305666bf
WD
1267 char *h, *p;
1268 int q;
c3ea0990 1269 if (*argc > 2 || (!am_daemon && *argc == 1)) {
ea5164d1
WD
1270 usage(FERROR);
1271 exit_cleanup(RERR_SYNTAX);
1272 }
63596e1c 1273 if (strcmp(files_from, "-") == 0) {
ea5164d1 1274 filesfrom_fd = 0;
63596e1c 1275 if (am_server)
305666bf
WD
1276 filesfrom_host = ""; /* reading from socket */
1277 } else if ((p = check_for_hostspec(files_from, &h, &q)) != 0) {
ea5164d1 1278 if (am_server) {
305666bf
WD
1279 snprintf(err_buf, sizeof err_buf,
1280 "The --files-from sent to the server cannot specify a host.\n");
1281 return 0;
ea5164d1 1282 }
305666bf
WD
1283 files_from = p;
1284 filesfrom_host = h;
1285 if (strcmp(files_from, "-") == 0) {
c3ea0990
WD
1286 snprintf(err_buf, sizeof err_buf,
1287 "Invalid --files-from remote filename\n");
1288 return 0;
ea5164d1
WD
1289 }
1290 } else {
305666bf
WD
1291 if (sanitize_paths)
1292 files_from = sanitize_path(NULL, files_from, NULL, 0);
1293 if (server_filter_list.head) {
1294 if (!*files_from)
1295 goto options_rejected;
1296 clean_fname(files_from, 1);
1297 if (check_filter(&server_filter_list, files_from, 0) < 0)
1298 goto options_rejected;
1299 }
ea5164d1
WD
1300 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1301 if (filesfrom_fd < 0) {
c3ea0990
WD
1302 snprintf(err_buf, sizeof err_buf,
1303 "failed to open files-from file %s: %s\n",
1304 files_from, strerror(errno));
1305 return 0;
ea5164d1
WD
1306 }
1307 }
1308 }
1309
7f2a1f65
WD
1310 am_starting_up = 0;
1311
b11ed3b1 1312 return 1;
7a6421fa
AT
1313}
1314
1315
dafe63ca
MP
1316/**
1317 * Construct a filtered list of options to pass through from the
1318 * client to the server.
1319 *
1320 * This involves setting options that will tell the server how to
1321 * behave, and also filtering out options that are processed only
1322 * locally.
1323 **/
7a6421fa
AT
1324void server_options(char **args,int *argc)
1325{
74ba98a5 1326 static char argstr[64];
d853783f 1327 int ac = *argc;
f98c60bf 1328 char *arg;
ef5d23eb 1329
d853783f
AT
1330 int i, x;
1331
93689aa5
DD
1332 if (blocking_io == -1)
1333 blocking_io = 0;
1334
d853783f
AT
1335 args[ac++] = "--server";
1336
1312d9fc
WD
1337 if (daemon_over_rsh) {
1338 args[ac++] = "--daemon";
1339 *argc = ac;
1340 /* if we're passing --daemon, we're done */
1341 return;
1342 }
1343
d853783f
AT
1344 if (!am_sender)
1345 args[ac++] = "--sender";
1346
1347 x = 1;
1348 argstr[0] = '-';
f98c60bf 1349 for (i = 0; i < verbose; i++)
d853783f 1350 argstr[x++] = 'v';
f0b36a48 1351
b86f0cef 1352 /* the -q option is intentionally left out */
d853783f
AT
1353 if (make_backups)
1354 argstr[x++] = 'b';
1355 if (update_only)
1356 argstr[x++] = 'u';
4a34c6f1 1357 if (!do_xfers) /* NOT "dry_run"! */
d853783f
AT
1358 argstr[x++] = 'n';
1359 if (preserve_links)
1360 argstr[x++] = 'l';
1361 if (copy_links)
1362 argstr[x++] = 'L';
65e4cda0 1363 if (xfer_dirs > 1)
5454d22a 1364 argstr[x++] = 'd';
716e73d4
WD
1365 if (keep_dirlinks && am_sender)
1366 argstr[x++] = 'K';
1bfbf40b 1367
dfa32483 1368 if (whole_file > 0)
d853783f 1369 argstr[x++] = 'W';
bceec82f
MP
1370 /* We don't need to send --no-whole-file, because it's the
1371 * default for remote transfers, and in any case old versions
1372 * of rsync will not understand it. */
dfa32483 1373
d853783f
AT
1374 if (preserve_hard_links)
1375 argstr[x++] = 'H';
1376 if (preserve_uid)
1377 argstr[x++] = 'o';
1378 if (preserve_gid)
1379 argstr[x++] = 'g';
1380 if (preserve_devices)
1381 argstr[x++] = 'D';
1382 if (preserve_times)
1383 argstr[x++] = 't';
d4021b6d 1384 if (omit_dir_times == 2 && am_sender)
20fb7b91 1385 argstr[x++] = 'O';
d853783f
AT
1386 if (preserve_perms)
1387 argstr[x++] = 'p';
aa7a6e87 1388 if (recurse)
d853783f
AT
1389 argstr[x++] = 'r';
1390 if (always_checksum)
1391 argstr[x++] = 'c';
1392 if (cvs_exclude)
1393 argstr[x++] = 'C';
1394 if (ignore_times)
1395 argstr[x++] = 'I';
1396 if (relative_paths)
1397 argstr[x++] = 'R';
1398 if (one_file_system)
1399 argstr[x++] = 'x';
1400 if (sparse_files)
1401 argstr[x++] = 'S';
1402 if (do_compression)
1403 argstr[x++] = 'z';
f0b36a48 1404
51d48398
WD
1405 /* This is a complete hack - blame Rusty. FIXME!
1406 * This hack is only needed for older rsync versions that
1407 * don't understand the --list-only option. */
da2a6c1f 1408 if (list_only == 1 && !recurse)
f0b36a48
AT
1409 argstr[x++] = 'r';
1410
d853783f
AT
1411 argstr[x] = 0;
1412
f98c60bf
WD
1413 if (x != 1)
1414 args[ac++] = argstr;
d853783f 1415
51d48398
WD
1416 if (list_only > 1)
1417 args[ac++] = "--list-only";
1418
5c5e1598
WD
1419 /* The server side doesn't use our log-format, but in certain
1420 * circumstances they need to know a little about the option. */
684d7582
WD
1421 if (log_format && am_sender) {
1422 if (log_format_has_i)
1423 args[ac++] = "--log-format=%i";
1424 else if (log_format_has_o_or_i)
5c5e1598
WD
1425 args[ac++] = "--log-format=%o";
1426 else if (!verbose)
1427 args[ac++] = "--log-format=X";
1428 }
1f30a674 1429
195bd906 1430 if (block_size) {
a06b419d 1431 if (asprintf(&arg, "-B%lu", block_size) < 0)
f98c60bf
WD
1432 goto oom;
1433 args[ac++] = arg;
dfa32483 1434 }
d853783f 1435
0b73ca12 1436 if (max_delete && am_sender) {
f98c60bf
WD
1437 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1438 goto oom;
1439 args[ac++] = arg;
dfa32483
WD
1440 }
1441
7d5acf1d
WD
1442 if (max_size && am_sender) {
1443 args[ac++] = "--max-size";
1444 args[ac++] = max_size_arg;
1445 }
1446
d853783f 1447 if (io_timeout) {
f98c60bf
WD
1448 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1449 goto oom;
1450 args[ac++] = arg;
dfa32483 1451 }
d853783f 1452
ef5d23eb 1453 if (bwlimit) {
f98c60bf
WD
1454 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1455 goto oom;
1456 args[ac++] = arg;
ef5d23eb
DD
1457 }
1458
d175d7e1
WD
1459 if (backup_dir) {
1460 args[ac++] = "--backup-dir";
1461 args[ac++] = backup_dir;
1462 }
1463
1464 /* Only send --suffix if it specifies a non-default value. */
f98c60bf 1465 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
191e40da 1466 /* We use the following syntax to avoid weirdness with '~'. */
f98c60bf
WD
1467 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1468 goto oom;
1469 args[ac++] = arg;
d853783f
AT
1470 }
1471
06a50542
WD
1472 if (am_sender) {
1473 if (delete_excluded)
1474 args[ac++] = "--delete-excluded";
c6eb7fad 1475 else if (delete_before == 1 || delete_after)
06a50542 1476 args[ac++] = "--delete";
57f74bd1 1477 if (delete_before > 1)
c6eb7fad 1478 args[ac++] = "--delete-before";
3359acb8
WD
1479 if (delete_during)
1480 args[ac++] = "--delete-during";
06a50542
WD
1481 if (delete_after)
1482 args[ac++] = "--delete-after";
06a50542
WD
1483 if (force_delete)
1484 args[ac++] = "--force";
11e758a4
WD
1485 if (write_batch < 0)
1486 args[ac++] = "--only-write-batch=X";
06a50542 1487 }
b33b791e 1488
f83f0548
AT
1489 if (size_only)
1490 args[ac++] = "--size-only";
1491
5b56cc19 1492 if (modify_window_set) {
f98c60bf
WD
1493 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1494 goto oom;
1495 args[ac++] = arg;
5b56cc19
AT
1496 }
1497
c8d895de 1498 if (checksum_seed) {
221ddb94 1499 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
c8d895de
WD
1500 goto oom;
1501 args[ac++] = arg;
1502 }
1503
a7260c40 1504 if (partial_dir && am_sender) {
3671987f
WD
1505 if (partial_dir != partialdir_for_delayupdate) {
1506 args[ac++] = "--partial-dir";
1507 args[ac++] = partial_dir;
1508 }
f06e7082
WD
1509 if (delay_updates)
1510 args[ac++] = "--delay-updates";
a7260c40 1511 } else if (keep_partial)
d853783f
AT
1512 args[ac++] = "--partial";
1513
ef55c686
AT
1514 if (ignore_errors)
1515 args[ac++] = "--ignore-errors";
1516
b5313607
DD
1517 if (copy_unsafe_links)
1518 args[ac++] = "--copy-unsafe-links";
1519
d853783f
AT
1520 if (safe_symlinks)
1521 args[ac++] = "--safe-links";
1522
1523 if (numeric_ids)
1524 args[ac++] = "--numeric-ids";
1525
e90aab49 1526 if (ignore_existing && am_sender)
3d6feada
MP
1527 args[ac++] = "--ignore-existing";
1528
e90aab49
WD
1529 /* Backward compatibility: send --existing, not --ignore-non-existing. */
1530 if (ignore_non_existing && am_sender)
1531 args[ac++] = "--existing";
1532
a015788d
WD
1533 if (append_mode)
1534 args[ac++] = "--append";
1535 else if (inplace)
a3221d2a
WD
1536 args[ac++] = "--inplace";
1537
d853783f
AT
1538 if (tmpdir) {
1539 args[ac++] = "--temp-dir";
1540 args[ac++] = tmpdir;
1541 }
1542
e012f858 1543 if (basis_dir[0] && am_sender) {
375a4556
DD
1544 /* the server only needs this option if it is not the sender,
1545 * and it may be an older version that doesn't know this
1546 * option, so don't send it if client is the sender.
1547 */
e012f858
WD
1548 int i;
1549 for (i = 0; i < basis_dir_cnt; i++) {
1550 args[ac++] = dest_option;
1551 args[ac++] = basis_dir[i];
1552 }
375a4556
DD
1553 }
1554
305666bf
WD
1555 if (files_from && (!am_sender || filesfrom_host)) {
1556 if (filesfrom_host) {
ea5164d1 1557 args[ac++] = "--files-from";
305666bf 1558 args[ac++] = files_from;
ea5164d1
WD
1559 if (eol_nulls)
1560 args[ac++] = "--from0";
1561 } else {
1562 args[ac++] = "--files-from=-";
1563 args[ac++] = "--from0";
1564 }
c0ab28d1
WD
1565 if (!relative_paths)
1566 args[ac++] = "--no-relative";
ea5164d1 1567 }
89f2a4c2 1568 if (relative_paths && !implied_dirs && !am_sender)
3a90ea0a 1569 args[ac++] = "--no-implied-dirs";
ea5164d1 1570
c4ed1487
WD
1571 if (fuzzy_basis && am_sender)
1572 args[ac++] = "--fuzzy";
1573
07c6ae7d
WD
1574 if (remove_sent_files)
1575 args[ac++] = "--remove-sent-files";
1576
d853783f 1577 *argc = ac;
f98c60bf
WD
1578 return;
1579
1580 oom:
1581 out_of_memory("server_options");
7a6421fa
AT
1582}
1583
305666bf
WD
1584/* Look for a HOST specfication of the form "HOST:PATH", "HOST::PATH", or
1585 * "rsync://HOST:PORT/PATH". If found, *host_ptr will be set to some allocated
1586 * memory with the HOST. If a daemon-accessing spec was specified, the value
1587 * of *port_ptr will contain a non-0 port number, otherwise it will be set to
1588 * 0. The return value is a pointer to the PATH. Note that the HOST spec can
1589 * be an IPv6 literal address enclosed in '[' and ']' (such as "[::1]" or
1590 * "[::ffff:127.0.0.1]") which is returned without the '[' and ']'. */
1591char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
ea5164d1 1592{
305666bf
WD
1593 char *p;
1594 int not_host;
1595
1596 if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) {
1597 char *path;
1598 int hostlen;
1599 s += strlen(URL_PREFIX);
1600 if ((p = strchr(s, '/')) != NULL) {
1601 hostlen = p - s;
1602 path = p + 1;
1603 } else {
1604 hostlen = strlen(s);
1605 path = "";
1606 }
1607 if (*s == '[' && (p = strchr(s, ']')) != NULL) {
1608 s++;
1609 hostlen = p - s;
c60b7056
WD
1610 if (p[1] == ':')
1611 *port_ptr = atoi(p+2);
305666bf
WD
1612 } else {
1613 if ((p = strchr(s, ':')) != NULL) {
1614 hostlen = p - s;
1615 *port_ptr = atoi(p+1);
c60b7056 1616 }
305666bf 1617 }
c60b7056
WD
1618 if (!*port_ptr)
1619 *port_ptr = RSYNC_PORT;
305666bf
WD
1620 *host_ptr = new_array(char, hostlen + 1);
1621 strlcpy(*host_ptr, s, hostlen + 1);
1622 return path;
1623 }
ea5164d1 1624
305666bf
WD
1625 if (*s == '[' && (p = strchr(s, ']')) != NULL && p[1] == ':') {
1626 s++;
1627 *p = '\0';
1628 not_host = strchr(s, '/') || !strchr(s, ':');
1629 *p = ']';
1630 if (not_host)
1631 return NULL;
c60b7056 1632 p++;
305666bf
WD
1633 } else {
1634 if (!(p = strchr(s, ':')))
1635 return NULL;
1636 *p = '\0';
1637 not_host = strchr(s, '/') != NULL;
1638 *p = ':';
1639 if (not_host)
1640 return NULL;
1641 }
1642
1643 *host_ptr = new_array(char, p - s + 1);
1644 strlcpy(*host_ptr, s, p - s + 1);
ea5164d1 1645
305666bf
WD
1646 if (p[1] == ':') {
1647 if (port_ptr && !*port_ptr)
1648 *port_ptr = RSYNC_PORT;
1649 return p + 2;
1650 }
1651 if (port_ptr)
1652 *port_ptr = 0;
ea5164d1 1653
305666bf 1654 return p + 1;
ea5164d1 1655}