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