Another bug fix.
[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
8645af1d
WD
24extern struct exclude_struct **exclude_list;
25
7a6421fa 26int make_backups = 0;
1bfbf40b
MP
27
28/**
dfa32483 29 * If 1, send the whole file as literal data rather than trying to
dafe63ca 30 * create an incremental diff.
1bfbf40b 31 *
dfa32483 32 * If -1, then look at whether we're local or remote and go by that.
dafe63ca
MP
33 *
34 * @sa disable_deltas_p()
1bfbf40b 35 **/
dfa32483 36int whole_file = -1;
1bfbf40b 37
dfa32483 38int archive_mode = 0;
7a6421fa
AT
39int copy_links = 0;
40int preserve_links = 0;
41int preserve_hard_links = 0;
42int preserve_perms = 0;
43int preserve_devices = 0;
44int preserve_uid = 0;
45int preserve_gid = 0;
46int preserve_times = 0;
47int update_only = 0;
48int cvs_exclude = 0;
a5c11139
WD
49int dry_run = 0;
50int local_server = 0;
51int ignore_times = 0;
52int delete_mode = 0;
53int delete_excluded = 0;
54int one_file_system = 0;
4f3e9a0f 55int protocol_version = PROTOCOL_VERSION;
a5c11139
WD
56int sparse_files = 0;
57int do_compression = 0;
58int am_root = 0;
59int orig_umask = 0;
ea5164d1
WD
60int relative_paths = -1;
61int implied_dirs = 1;
7a6421fa
AT
62int numeric_ids = 0;
63int force_delete = 0;
64int io_timeout = 0;
7a6421fa
AT
65int read_only = 0;
66int module_id = -1;
67int am_server = 0;
30ce7e8a 68int am_sender = 0;
4337c8f8 69int am_generator = 0;
ea5164d1
WD
70char *files_from = NULL;
71int filesfrom_fd = -1;
72char *remote_filesfrom_file = NULL;
73int eol_nulls = 0;
7a6421fa 74int recurse = 0;
1312d9fc
WD
75int am_daemon = 0;
76int daemon_over_rsh = 0;
a5c11139
WD
77int do_stats = 0;
78int do_progress = 0;
79int keep_partial = 0;
80int safe_symlinks = 0;
81int copy_unsafe_links = 0;
82int size_only = 0;
83int bwlimit = 0;
84int delete_after = 0;
85int only_existing = 0;
86int opt_ignore_existing = 0;
87int max_delete = 0;
88int ignore_errors = 0;
89int modify_window = 0;
90int blocking_io = -1;
2289bf64 91int checksum_seed = 0;
da9d12f5 92unsigned int block_size = 0;
7a6421fa 93
b35d0d8e 94
13e29995 95/** Network address family. **/
6ab6d4bf 96#ifdef INET6
13e29995 97int default_af_hint = 0; /* Any protocol */
6ab6d4bf 98#else
13e29995 99int default_af_hint = AF_INET; /* Must use IPv4 */
6ab6d4bf 100#endif
06963d0f 101
13e29995
MP
102/** Do not go into the background when run as --daemon. Good
103 * for debugging and required for running as a service on W32,
104 * or under Unix process-monitors. **/
105int no_detach = 0;
106
088aac85
DD
107int write_batch = 0;
108int read_batch = 0;
d175d7e1
WD
109int backup_dir_len = 0;
110int backup_suffix_len;
e0391f81 111unsigned int backup_dir_remainder;
6902ed17 112
d175d7e1 113char *backup_suffix = NULL;
7a6421fa 114char *tmpdir = NULL;
375a4556 115char *compare_dest = NULL;
30e8c8e1 116char *config_file = NULL;
7a6421fa 117char *shell_cmd = NULL;
b6062654 118char *log_format = NULL;
65575e96 119char *password_file = NULL;
41bd28fe 120char *rsync_path = RSYNC_PATH;
66203a98 121char *backup_dir = NULL;
e0391f81 122char backup_dir_buf[MAXPATHLEN];
7a6421fa 123int rsync_port = RSYNC_PORT;
59c95e42 124int link_dest = 0;
7a6421fa
AT
125
126int verbose = 0;
b86f0cef 127int quiet = 0;
7a6421fa 128int always_checksum = 0;
f7632fc6 129int list_only = 0;
7a6421fa 130
2289bf64 131#define FIXED_CHECKSUM_SEED 32761
beb93684 132#define MAX_BATCH_PREFIX_LEN 256 /* Must be less than MAXPATHLEN-13 */
088aac85 133char *batch_prefix = NULL;
6902ed17 134
e1add893 135static int daemon_opt; /* sets am_daemon after option error-reporting */
5b56cc19
AT
136static int modify_window_set;
137
06963d0f
MP
138/** Local address to bind. As a character string because it's
139 * interpreted by the IPv6 layer: should be a numeric IP4 or ip6
140 * address, or a hostname. **/
141char *bind_address;
5c9730a4 142
7a24c346 143
27a12348 144static void print_rsync_version(enum logcode f)
7a24c346 145{
dfa32483
WD
146 char const *got_socketpair = "no ";
147 char const *hardlinks = "no ";
148 char const *links = "no ";
a358449a 149 char const *ipv6 = "no ";
736a6a29 150 STRUCT_STAT *dumstat;
0c80cd8e
MP
151
152#ifdef HAVE_SOCKETPAIR
dfa32483 153 got_socketpair = "";
0c80cd8e 154#endif
2855f61f
MP
155
156#if SUPPORT_HARD_LINKS
dfa32483 157 hardlinks = "";
2855f61f
MP
158#endif
159
160#if SUPPORT_LINKS
dfa32483 161 links = "";
2855f61f
MP
162#endif
163
a358449a
MP
164#if INET6
165 ipv6 = "";
dfa32483 166#endif
a358449a 167
dfa32483
WD
168 rprintf(f, "%s version %s protocol version %d\n",
169 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
170 rprintf(f,
45ddbf62 171 "Copyright (C) 1996-2004 by Andrew Tridgell and others\n");
3b4b1984 172 rprintf(f, "<http://rsync.samba.org/>\n");
dfa32483
WD
173 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
174 "%shard links, %ssymlinks, batchfiles, \n",
a5c11139 175 (int) (sizeof (OFF_T) * 8),
dfa32483 176 got_socketpair, hardlinks, links);
2855f61f 177
736a6a29
MP
178 /* Note that this field may not have type ino_t. It depends
179 * on the complicated interaction between largefile feature
180 * macros. */
7a52790b 181 rprintf(f, " %sIPv6, %d-bit system inums, %d-bit internal inums\n",
dfa32483 182 ipv6,
a5c11139
WD
183 (int) (sizeof dumstat->st_ino * 8),
184 (int) (sizeof (INO64_T) * 8));
fc0302cf
MP
185#ifdef MAINTAINER_MODE
186 rprintf(f, " panic action: \"%s\"\n",
187 get_panic_action());
188#endif
736a6a29 189
7a24c346 190#ifdef NO_INT64
dfa32483 191 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
7a24c346 192#endif
7b329a2d
MP
193
194 rprintf(f,
195"\n"
196"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
197"are welcome to redistribute it under certain conditions. See the GNU\n"
198"General Public Licence for details.\n"
199 );
7a24c346
MP
200}
201
202
0f3203c3 203void usage(enum logcode F)
7a6421fa 204{
2855f61f 205 print_rsync_version(F);
704f908e 206
3ff984d7 207 rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
704f908e 208
9ef53907 209 rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
704f908e 210 rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
9ef53907 211 rprintf(F," or rsync [OPTION]... SRC [SRC]... DEST\n");
14d43f1f 212 rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
9ef53907 213 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
14d43f1f 214 rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
eaa4c150 215 rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
9ef53907
DD
216 rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
217 rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
218 rprintf(F," sources separated by space as long as they have same top-level\n");
704f908e
AT
219 rprintf(F,"\nOptions\n");
220 rprintf(F," -v, --verbose increase verbosity\n");
b86f0cef 221 rprintf(F," -q, --quiet decrease verbosity\n");
704f908e 222 rprintf(F," -c, --checksum always checksum\n");
06891710 223 rprintf(F," -a, --archive archive mode, equivalent to -rlptgoD\n");
704f908e
AT
224 rprintf(F," -r, --recursive recurse into directories\n");
225 rprintf(F," -R, --relative use relative path names\n");
ea5164d1
WD
226 rprintf(F," --no-relative turn off --relative\n");
227 rprintf(F," --no-implied-dirs don't send implied dirs with -R\n");
6839140e 228 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
e20c5e95 229 rprintf(F," --backup-dir make backups into this directory\n");
6839140e 230 rprintf(F," --suffix=SUFFIX backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
704f908e 231 rprintf(F," -u, --update update only (don't overwrite newer files)\n");
13e29995 232 rprintf(F," -l, --links copy symlinks as symlinks\n");
06d76beb
WD
233 rprintf(F," -L, --copy-links copy the referent of all symlinks\n");
234 rprintf(F," --copy-unsafe-links copy the referent of \"unsafe\" symlinks\n");
235 rprintf(F," --safe-links ignore \"unsafe\" symlinks\n");
704f908e
AT
236 rprintf(F," -H, --hard-links preserve hard links\n");
237 rprintf(F," -p, --perms preserve permissions\n");
238 rprintf(F," -o, --owner preserve owner (root only)\n");
239 rprintf(F," -g, --group preserve group\n");
240 rprintf(F," -D, --devices preserve devices (root only)\n");
dfa32483 241 rprintf(F," -t, --times preserve times\n");
704f908e
AT
242 rprintf(F," -S, --sparse handle sparse files efficiently\n");
243 rprintf(F," -n, --dry-run show what would have been transferred\n");
244 rprintf(F," -W, --whole-file copy whole files, no incremental checks\n");
93689aa5 245 rprintf(F," --no-whole-file turn off --whole-file\n");
704f908e 246 rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
dfa32483 247 rprintf(F," -B, --block-size=SIZE checksum blocking size (default %d)\n",BLOCK_SIZE);
54170a08 248 rprintf(F," -e, --rsh=COMMAND specify the remote shell\n");
704f908e 249 rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
1347d512 250 rprintf(F," --existing only update files that already exist\n");
6839140e 251 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
704f908e 252 rprintf(F," --delete delete files that don't exist on the sending side\n");
b33b791e 253 rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
ad1a09a5 254 rprintf(F," --delete-after receiver deletes after transferring, not before\n");
db2b5cb7 255 rprintf(F," --ignore-errors delete even if there are I/O errors\n");
0b73ca12 256 rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
c95da96a 257 rprintf(F," --partial keep partially transferred files\n");
704f908e
AT
258 rprintf(F," --force force deletion of directories even if not empty\n");
259 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
db2b5cb7 260 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
6839140e
WD
261 rprintf(F," -I, --ignore-times turn off mod time & file size quick check\n");
262 rprintf(F," --size-only ignore mod time for quick check (use size)\n");
263 rprintf(F," --modify-window=NUM compare mod times with reduced accuracy\n");
704f908e 264 rprintf(F," -T --temp-dir=DIR create temporary files in directory DIR\n");
375a4556 265 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
8294b00c 266 rprintf(F," --link-dest=DIR create hardlinks to DIR for unchanged files\n");
d9fcc198 267 rprintf(F," -P equivalent to --partial --progress\n");
704f908e 268 rprintf(F," -z, --compress compress file data\n");
ea5164d1 269 rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
2acf81eb 270 rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
858fb9eb 271 rprintf(F," --exclude-from=FILE exclude patterns listed in FILE\n");
2acf81eb 272 rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
858fb9eb 273 rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n");
ea5164d1 274 rprintf(F," --files-from=FILE read FILE for list of source-file names\n");
6839140e 275 rprintf(F," -0 --from0 all *-from file lists are delimited by nulls\n");
dfa32483 276 rprintf(F," --version print version number\n");
db2b5cb7 277 rprintf(F," --daemon run as an rsync daemon\n");
dfa32483
WD
278 rprintf(F," --no-detach do not detach from the parent\n");
279 rprintf(F," --address=ADDRESS bind to the specified address\n");
280 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
704f908e 281 rprintf(F," --port=PORT specify alternate rsyncd port number\n");
db2b5cb7 282 rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
dfa32483
WD
283 rprintf(F," --no-blocking-io turn off --blocking-io\n");
284 rprintf(F," --stats give some file transfer stats\n");
285 rprintf(F," --progress show progress during transfer\n");
286 rprintf(F," --log-format=FORMAT log file transfers using specified format\n");
65575e96 287 rprintf(F," --password-file=FILE get password from FILE\n");
ef5d23eb 288 rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
088aac85
DD
289 rprintf(F," --write-batch=PREFIX write batch fileset starting with PREFIX\n");
290 rprintf(F," --read-batch=PREFIX read batch fileset starting with PREFIX\n");
704f908e 291 rprintf(F," -h, --help show this help screen\n");
06963d0f
MP
292#ifdef INET6
293 rprintf(F," -4 prefer IPv4\n");
294 rprintf(F," -6 prefer IPv6\n");
295#endif
7a6421fa
AT
296
297 rprintf(F,"\n");
b72f24c7
AT
298
299 rprintf(F,"\nPlease see the rsync(1) and rsyncd.conf(5) man pages for full documentation\n");
2855f61f 300 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
7a6421fa
AT
301}
302
1f3d6cdd
WD
303enum {OPT_VERSION = 1000, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
304 OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
305 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
306 OPT_READ_BATCH, OPT_WRITE_BATCH};
7a6421fa 307
2855f61f
MP
308static struct poptOption long_options[] = {
309 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
dfa32483 310 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
d175d7e1 311 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
8b54f004
MP
312 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
313 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
afb6e945
WD
314 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
315 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
8b54f004 316 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
afb6e945
WD
317 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
318 {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
319 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
320 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
1de50993 321 {"delete-after", 0, POPT_ARG_NONE, 0, OPT_DELETE_AFTER, 0, 0 },
8b54f004 322 {"delete-excluded", 0, POPT_ARG_NONE, 0, OPT_DELETE_EXCLUDED, 0, 0 },
afb6e945
WD
323 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
324 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
8b54f004
MP
325 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
326 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
327 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
328 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
afb6e945 329 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
8b54f004 330 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
afb6e945
WD
331 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
332 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
333 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
334 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
335 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
336 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
337 {"copy-links", 'L', POPT_ARG_NONE, &copy_links, 0, 0, 0 },
338 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
339 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
340 {"copy-unsafe-links", 0, POPT_ARG_NONE, &copy_unsafe_links, 0, 0, 0 },
341 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
342 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
343 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
344 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
345 {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
346 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
8b54f004
MP
347 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
348 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
dfa32483 349 {"archive", 'a', POPT_ARG_NONE, &archive_mode, 0, 0, 0 },
afb6e945 350 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
dfa32483 351 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
afb6e945 352 {"recursive", 'r', POPT_ARG_NONE, &recurse, 0, 0, 0 },
ea5164d1
WD
353 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
354 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
afb6e945
WD
355 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
356 {"block-size", 'B', POPT_ARG_INT, &block_size, 0, 0, 0 },
357 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
358 {"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 },
359 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
360 {"compare-dest", 0, POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
dfa32483 361 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
2855f61f 362 /* TODO: Should this take an optional int giving the compression level? */
afb6e945 363 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
e1add893 364 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
afb6e945
WD
365 {"no-detach", 0, POPT_ARG_NONE, &no_detach, 0, 0, 0 },
366 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
367 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
368 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
369 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
370 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
371 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
dfa32483 372 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
afb6e945
WD
373 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
374 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
375 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
376 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
8b54f004 377 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
afb6e945
WD
378 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
379 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
dfa32483
WD
380 {"read-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_READ_BATCH, 0, 0 },
381 {"write-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_WRITE_BATCH, 0, 0 },
ea5164d1
WD
382 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
383 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
384 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
4f3e9a0f 385 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
06963d0f 386#ifdef INET6
afb6e945
WD
387 {0, '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
388 {0, '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
06963d0f 389#endif
8b54f004 390 {0,0,0,0, 0, 0, 0}
2855f61f 391};
7a6421fa 392
06963d0f 393
cd8185f2
AT
394static char err_buf[100];
395
2855f61f 396
dafe63ca
MP
397/**
398 * Store the option error message, if any, so that we can log the
399 * connection attempt (which requires parsing the options), and then
400 * show the error later on.
401 **/
cd8185f2
AT
402void option_error(void)
403{
404 if (err_buf[0]) {
2855f61f 405 rprintf(FLOG, "%s", err_buf);
b7b2741f 406 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
cd8185f2 407 } else {
add7e8fb
MP
408 rprintf (FERROR, "Error parsing options: "
409 "option may be supported on client but not on server?\n");
410 rprintf (FERROR, RSYNC_NAME ": Error parsing options: "
411 "option may be supported on client but not on server?\n");
cd8185f2 412 }
cd8185f2
AT
413}
414
dafe63ca
MP
415
416/**
27ed20f7
WD
417 * Tweak the option table to disable all options that the rsyncd.conf
418 * file has told us to refuse.
dafe63ca 419 **/
27ed20f7 420static void set_refuse_options(char *bp)
cd8185f2 421{
27ed20f7
WD
422 struct poptOption *op;
423 char *cp;
424
425 while (1) {
426 if ((cp = strchr(bp, ' ')) != NULL)
427 *cp= '\0';
55afbb52
WD
428 for (op = long_options; ; op++) {
429 if (!op->longName) {
430 rprintf(FLOG,
431 "Unknown option %s in \"refuse options\" setting\n",
432 bp);
433 break;
434 }
27ed20f7 435 if (strcmp(bp, op->longName) == 0) {
55afbb52 436 op->val = (op - long_options) + 9000;
27ed20f7
WD
437 break;
438 }
cd8185f2 439 }
27ed20f7
WD
440 if (!cp)
441 break;
442 *cp = ' ';
443 bp = cp + 1;
cd8185f2 444 }
cd8185f2
AT
445}
446
447
2855f61f
MP
448static int count_args(char const **argv)
449{
dfa32483 450 int i = 0;
2855f61f 451
dfa32483
WD
452 while (argv[i] != NULL)
453 i++;
454
455 return i;
2855f61f
MP
456}
457
458
dafe63ca
MP
459/**
460 * Process command line arguments. Called on both local and remote.
461 *
462 * @retval 1 if all options are OK; with globals set to appropriate
463 * values
464 *
465 * @retval 0 on error, with err_buf containing an explanation
466 **/
2855f61f 467int parse_arguments(int *argc, const char ***argv, int frommain)
7a6421fa 468{
d853783f 469 int opt;
cd8185f2 470 char *ref = lp_refuse_options(module_id);
dfa32483 471 poptContext pc;
d853783f 472
27ed20f7
WD
473 if (ref && *ref)
474 set_refuse_options(ref);
475
dfa32483 476 /* TODO: Call poptReadDefaultConfig; handle errors. */
cd8185f2 477
dfa32483
WD
478 /* The context leaks in case of an error, but if there's a
479 * problem we always exit anyhow. */
480 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
2855f61f
MP
481
482 while ((opt = poptGetNextOpt(pc)) != -1) {
dfa32483
WD
483 /* most options are handled automatically by popt;
484 * only special cases are returned and listed here. */
2855f61f 485
d853783f
AT
486 switch (opt) {
487 case OPT_VERSION:
dfa32483 488 print_rsync_version(FINFO);
d853783f 489 exit_cleanup(0);
dfa32483 490
5b56cc19 491 case OPT_MODIFY_WINDOW:
dfa32483
WD
492 /* The value has already been set by popt, but
493 * we need to remember that we're using a
494 * non-default setting. */
5b56cc19
AT
495 modify_window_set = 1;
496 break;
1de50993
WD
497
498 case OPT_DELETE_AFTER:
499 delete_after = 1;
500 delete_mode = 1;
501 break;
502
b33b791e
DD
503 case OPT_DELETE_EXCLUDED:
504 delete_excluded = 1;
505 delete_mode = 1;
506 break;
507
d853783f 508 case OPT_EXCLUDE:
8645af1d
WD
509 add_exclude(&exclude_list, poptGetOptArg(pc),
510 ADD_EXCLUDE);
d853783f
AT
511 break;
512
513 case OPT_INCLUDE:
8645af1d
WD
514 add_exclude(&exclude_list, poptGetOptArg(pc),
515 ADD_INCLUDE);
d853783f
AT
516 break;
517
518 case OPT_EXCLUDE_FROM:
8645af1d
WD
519 add_exclude_file(&exclude_list, poptGetOptArg(pc),
520 MISSING_FATAL, ADD_EXCLUDE);
d853783f
AT
521 break;
522
93695764 523 case OPT_INCLUDE_FROM:
8645af1d
WD
524 add_exclude_file(&exclude_list, poptGetOptArg(pc),
525 MISSING_FATAL, ADD_INCLUDE);
93695764
DD
526 break;
527
d853783f
AT
528 case 'h':
529 usage(FINFO);
530 exit_cleanup(0);
531
d853783f
AT
532 case 'v':
533 verbose++;
534 break;
7a6421fa 535
b86f0cef 536 case 'q':
f98c60bf
WD
537 if (frommain)
538 quiet++;
b86f0cef
DD
539 break;
540
d853783f
AT
541 case OPT_SENDER:
542 if (!am_server) {
543 usage(FERROR);
65417579 544 exit_cleanup(RERR_SYNTAX);
d853783f
AT
545 }
546 am_sender = 1;
547 break;
548
d9fcc198
AT
549 case 'P':
550 do_progress = 1;
551 keep_partial = 1;
552 break;
553
088aac85
DD
554 case OPT_WRITE_BATCH:
555 /* popt stores the filename in batch_prefix for us */
556 write_batch = 1;
2289bf64 557 checksum_seed = FIXED_CHECKSUM_SEED;
088aac85
DD
558 break;
559
76f79ba7 560 case OPT_READ_BATCH:
088aac85 561 /* popt stores the filename in batch_prefix for us */
6902ed17 562 read_batch = 1;
2289bf64 563 checksum_seed = FIXED_CHECKSUM_SEED;
6902ed17 564 break;
ea5164d1 565
59c95e42
DD
566 case OPT_LINK_DEST:
567#if HAVE_LINK
9680f811 568 compare_dest = (char *)poptGetOptArg(pc);
59c95e42
DD
569 link_dest = 1;
570 break;
571#else
d175d7e1 572 snprintf(err_buf, sizeof err_buf,
dfa32483 573 "hard links are not supported on this %s\n",
59c95e42 574 am_server ? "server" : "client");
d175d7e1 575 rprintf(FERROR, "ERROR: %s", err_buf);
59c95e42
DD
576 return 0;
577#endif
578
d853783f 579 default:
55afbb52
WD
580 /* A large opt value means that set_refuse_options()
581 * turned this option off (opt-9000 is its index). */
582 if (opt >= 9000) {
583 struct poptOption *op = &long_options[opt-9000];
27ed20f7
WD
584 int n = snprintf(err_buf, sizeof err_buf,
585 "This server does not support --%s\n",
586 op->longName) - 1;
587 if (op->shortName) {
588 snprintf(err_buf+n, sizeof err_buf-n,
589 " (-%c)\n", op->shortName);
590 }
591 } else {
592 snprintf(err_buf, sizeof err_buf,
593 "%s%s: %s\n",
594 am_server ? "on remote machine: " : "",
595 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
596 poptStrerror(opt));
597 }
dfa32483 598 return 0;
d853783f 599 }
7a6421fa 600 }
2855f61f 601
e1add893 602#if !SUPPORT_LINKS
54e87b4b 603 if (preserve_links && !am_sender) {
e1add893
WD
604 snprintf(err_buf, sizeof err_buf,
605 "symlinks are not supported on this %s\n",
606 am_server ? "server" : "client");
607 rprintf(FERROR, "ERROR: %s", err_buf);
608 return 0;
609 }
610#endif
611
612#if !SUPPORT_HARD_LINKS
613 if (preserve_hard_links) {
614 snprintf(err_buf, sizeof err_buf,
615 "hard links are not supported on this %s\n",
616 am_server ? "server" : "client");
617 rprintf(FERROR, "ERROR: %s", err_buf);
618 return 0;
619 }
620#endif
621
088aac85 622 if (write_batch && read_batch) {
d175d7e1
WD
623 rprintf(FERROR,
624 "write-batch and read-batch can not be used together\n");
625 exit_cleanup(RERR_SYNTAX);
088aac85 626 }
beb93684
WD
627 if (batch_prefix && strlen(batch_prefix) > MAX_BATCH_PREFIX_LEN) {
628 rprintf(FERROR,
ce58b1b4 629 "the batch-file prefix must be %d characters or less.\n",
beb93684
WD
630 MAX_BATCH_PREFIX_LEN);
631 exit_cleanup(RERR_SYNTAX);
632 }
088aac85 633
ce58b1b4
WD
634 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
635 rprintf(FERROR, "the --temp-dir path is WAY too long.\n");
636 exit_cleanup(RERR_SYNTAX);
637 }
638
088aac85 639 if (do_compression && (write_batch || read_batch)) {
d175d7e1
WD
640 rprintf(FERROR,
641 "compress can not be used with write-batch or read-batch\n");
642 exit_cleanup(RERR_SYNTAX);
088aac85
DD
643 }
644
dfa32483 645 if (archive_mode) {
ea5164d1
WD
646 if (!files_from)
647 recurse = 1;
dfa32483
WD
648#if SUPPORT_LINKS
649 preserve_links = 1;
650#endif
651 preserve_perms = 1;
652 preserve_times = 1;
653 preserve_gid = 1;
654 preserve_uid = 1;
655 preserve_devices = 1;
656 }
657
ea5164d1
WD
658 if (relative_paths < 0)
659 relative_paths = files_from? 1 : 0;
660
d175d7e1 661 if (!backup_suffix)
e0391f81 662 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
d175d7e1 663 backup_suffix_len = strlen(backup_suffix);
80ddadb7
WD
664 if (strchr(backup_suffix, '/') != NULL) {
665 rprintf(FERROR, "--suffix cannot contain slashes: %s\n",
666 backup_suffix);
667 exit_cleanup(RERR_SYNTAX);
668 }
e0391f81
WD
669 if (backup_dir) {
670 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
671 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
672 if (backup_dir_remainder < 32) {
673 rprintf(FERROR, "the --backup-dir path is WAY too long.\n");
674 exit_cleanup(RERR_SYNTAX);
675 }
676 if (backup_dir_buf[backup_dir_len - 1] != '/') {
677 backup_dir_buf[backup_dir_len++] = '/';
678 backup_dir_buf[backup_dir_len] = '\0';
679 }
680 if (verbose > 1)
681 rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
682 } else if (!backup_suffix_len) {
d175d7e1
WD
683 rprintf(FERROR,
684 "--suffix cannot be a null string without --backup-dir\n");
685 exit_cleanup(RERR_SYNTAX);
686 }
687
e2559dbe
S
688 if (do_progress && !verbose)
689 verbose = 1;
690
dfa32483
WD
691 *argv = poptGetArgs(pc);
692 if (*argv)
693 *argc = count_args(*argv);
694 else
695 *argc = 0;
2855f61f 696
ea5164d1
WD
697 if (files_from) {
698 char *colon;
699 if (*argc != 2) {
700 usage(FERROR);
701 exit_cleanup(RERR_SYNTAX);
702 }
63596e1c 703 if (strcmp(files_from, "-") == 0) {
ea5164d1 704 filesfrom_fd = 0;
63596e1c
WD
705 if (am_server)
706 remote_filesfrom_file = "-";
707 }
ea5164d1
WD
708 else if ((colon = find_colon(files_from)) != 0) {
709 if (am_server) {
710 usage(FERROR);
711 exit_cleanup(RERR_SYNTAX);
712 }
713 remote_filesfrom_file = colon+1 + (colon[1] == ':');
714 if (strcmp(remote_filesfrom_file, "-") == 0) {
715 rprintf(FERROR, "Invalid --files-from remote filename\n");
716 exit_cleanup(RERR_SYNTAX);
717 }
718 } else {
719 extern int sanitize_paths;
5dc4003e
WD
720 if (sanitize_paths) {
721 files_from = strdup(files_from);
722 sanitize_path(files_from, NULL);
723 }
ea5164d1
WD
724 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
725 if (filesfrom_fd < 0) {
726 rsyserr(FERROR, errno,
727 "failed to open files-from file %s",
728 files_from);
729 exit_cleanup(RERR_FILEIO);
730 }
731 }
732 }
733
e1add893
WD
734 if (daemon_opt)
735 am_daemon = 1;
736
b11ed3b1 737 return 1;
7a6421fa
AT
738}
739
740
dafe63ca
MP
741/**
742 * Construct a filtered list of options to pass through from the
743 * client to the server.
744 *
745 * This involves setting options that will tell the server how to
746 * behave, and also filtering out options that are processed only
747 * locally.
748 **/
7a6421fa
AT
749void server_options(char **args,int *argc)
750{
d853783f
AT
751 int ac = *argc;
752 static char argstr[50];
f98c60bf 753 char *arg;
ef5d23eb 754
d853783f
AT
755 int i, x;
756
93689aa5
DD
757 if (blocking_io == -1)
758 blocking_io = 0;
759
d853783f
AT
760 args[ac++] = "--server";
761
1312d9fc
WD
762 if (daemon_over_rsh) {
763 args[ac++] = "--daemon";
764 *argc = ac;
765 /* if we're passing --daemon, we're done */
766 return;
767 }
768
d853783f
AT
769 if (!am_sender)
770 args[ac++] = "--sender";
771
772 x = 1;
773 argstr[0] = '-';
f98c60bf 774 for (i = 0; i < verbose; i++)
d853783f 775 argstr[x++] = 'v';
f0b36a48 776
b86f0cef 777 /* the -q option is intentionally left out */
d853783f
AT
778 if (make_backups)
779 argstr[x++] = 'b';
780 if (update_only)
781 argstr[x++] = 'u';
782 if (dry_run)
783 argstr[x++] = 'n';
784 if (preserve_links)
785 argstr[x++] = 'l';
786 if (copy_links)
787 argstr[x++] = 'L';
1bfbf40b 788
dfa32483 789 if (whole_file > 0)
d853783f 790 argstr[x++] = 'W';
bceec82f
MP
791 /* We don't need to send --no-whole-file, because it's the
792 * default for remote transfers, and in any case old versions
793 * of rsync will not understand it. */
dfa32483 794
d853783f
AT
795 if (preserve_hard_links)
796 argstr[x++] = 'H';
797 if (preserve_uid)
798 argstr[x++] = 'o';
799 if (preserve_gid)
800 argstr[x++] = 'g';
801 if (preserve_devices)
802 argstr[x++] = 'D';
803 if (preserve_times)
804 argstr[x++] = 't';
805 if (preserve_perms)
806 argstr[x++] = 'p';
807 if (recurse)
808 argstr[x++] = 'r';
809 if (always_checksum)
810 argstr[x++] = 'c';
811 if (cvs_exclude)
812 argstr[x++] = 'C';
813 if (ignore_times)
814 argstr[x++] = 'I';
815 if (relative_paths)
816 argstr[x++] = 'R';
817 if (one_file_system)
818 argstr[x++] = 'x';
819 if (sparse_files)
820 argstr[x++] = 'S';
821 if (do_compression)
822 argstr[x++] = 'z';
f0b36a48 823
dfa32483 824 /* this is a complete hack - blame Rusty
f0b36a48
AT
825
826 this is a hack to make the list_only (remote file list)
827 more useful */
dfa32483 828 if (list_only && !recurse)
f0b36a48
AT
829 argstr[x++] = 'r';
830
d853783f
AT
831 argstr[x] = 0;
832
f98c60bf
WD
833 if (x != 1)
834 args[ac++] = argstr;
d853783f 835
195bd906 836 if (block_size) {
f98c60bf
WD
837 if (asprintf(&arg, "-B%u", block_size) < 0)
838 goto oom;
839 args[ac++] = arg;
dfa32483 840 }
d853783f 841
0b73ca12 842 if (max_delete && am_sender) {
f98c60bf
WD
843 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
844 goto oom;
845 args[ac++] = arg;
dfa32483
WD
846 }
847
f98c60bf
WD
848 if (batch_prefix) {
849 char *r_or_w = write_batch ? "write" : "read";
850 if (asprintf(&arg, "--%s-batch=%s", r_or_w, batch_prefix) < 0)
851 goto oom;
852 args[ac++] = arg;
6902ed17 853 }
0b73ca12 854
d853783f 855 if (io_timeout) {
f98c60bf
WD
856 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
857 goto oom;
858 args[ac++] = arg;
dfa32483 859 }
d853783f 860
ef5d23eb 861 if (bwlimit) {
f98c60bf
WD
862 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
863 goto oom;
864 args[ac++] = arg;
ef5d23eb
DD
865 }
866
d175d7e1
WD
867 if (backup_dir) {
868 args[ac++] = "--backup-dir";
869 args[ac++] = backup_dir;
870 }
871
872 /* Only send --suffix if it specifies a non-default value. */
f98c60bf 873 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
191e40da 874 /* We use the following syntax to avoid weirdness with '~'. */
f98c60bf
WD
875 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
876 goto oom;
877 args[ac++] = arg;
d853783f
AT
878 }
879
b33b791e
DD
880 if (delete_excluded)
881 args[ac++] = "--delete-excluded";
f98c60bf
WD
882 else if (delete_mode)
883 args[ac++] = "--delete";
b33b791e 884
f83f0548
AT
885 if (size_only)
886 args[ac++] = "--size-only";
887
5b56cc19 888 if (modify_window_set) {
f98c60bf
WD
889 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
890 goto oom;
891 args[ac++] = arg;
5b56cc19
AT
892 }
893
d853783f
AT
894 if (keep_partial)
895 args[ac++] = "--partial";
896
897 if (force_delete)
898 args[ac++] = "--force";
899
57df171b
AT
900 if (delete_after)
901 args[ac++] = "--delete-after";
902
ef55c686
AT
903 if (ignore_errors)
904 args[ac++] = "--ignore-errors";
905
b5313607
DD
906 if (copy_unsafe_links)
907 args[ac++] = "--copy-unsafe-links";
908
d853783f
AT
909 if (safe_symlinks)
910 args[ac++] = "--safe-links";
911
912 if (numeric_ids)
913 args[ac++] = "--numeric-ids";
914
0b73ca12 915 if (only_existing && am_sender)
1347d512
AT
916 args[ac++] = "--existing";
917
dfa32483 918 if (opt_ignore_existing && am_sender)
3d6feada
MP
919 args[ac++] = "--ignore-existing";
920
d853783f
AT
921 if (tmpdir) {
922 args[ac++] = "--temp-dir";
923 args[ac++] = tmpdir;
924 }
925
375a4556
DD
926 if (compare_dest && am_sender) {
927 /* the server only needs this option if it is not the sender,
928 * and it may be an older version that doesn't know this
929 * option, so don't send it if client is the sender.
930 */
59c95e42 931 args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
375a4556
DD
932 args[ac++] = compare_dest;
933 }
934
ea5164d1
WD
935 if (files_from && (!am_sender || remote_filesfrom_file)) {
936 if (remote_filesfrom_file) {
937 args[ac++] = "--files-from";
938 args[ac++] = remote_filesfrom_file;
939 if (eol_nulls)
940 args[ac++] = "--from0";
941 } else {
942 args[ac++] = "--files-from=-";
943 args[ac++] = "--from0";
944 }
945 }
946
d853783f 947 *argc = ac;
f98c60bf
WD
948 return;
949
950 oom:
951 out_of_memory("server_options");
7a6421fa
AT
952}
953
ea5164d1
WD
954/**
955 * Return the position of a ':' IF it is not part of a filename (i.e. as
956 * long as it doesn't occur after a slash.
957 */
958char *find_colon(char *s)
959{
960 char *p, *p2;
961
962 p = strchr(s,':');
f98c60bf
WD
963 if (!p)
964 return NULL;
ea5164d1
WD
965
966 /* now check to see if there is a / in the string before the : - if there is then
967 discard the colon on the assumption that the : is part of a filename */
968 p2 = strchr(s,'/');
f98c60bf
WD
969 if (p2 && p2 < p)
970 return NULL;
ea5164d1
WD
971
972 return p;
973}