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