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