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