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