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