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