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