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