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