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