1 /* -*- c-file-style: "linux" -*-
3 * Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
4 * Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
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.
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.
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.
25 extern int sanitize_paths;
26 extern int select_timeout;
27 extern struct filter_list_struct filter_list;
28 extern struct filter_list_struct server_filter_list;
33 * If 1, send the whole file as literal data rather than trying to
34 * create an incremental diff.
36 * If -1, then look at whether we're local or remote and go by that.
38 * @sa disable_deltas_p()
43 int keep_dirlinks = 0;
45 int preserve_links = 0;
46 int preserve_hard_links = 0;
47 int preserve_perms = 0;
48 int preserve_devices = 0;
51 int preserve_times = 0;
52 int omit_dir_times = 0;
58 int delete_during = 0;
59 int delete_before = 0;
61 int delete_excluded = 0;
62 int remove_sent_files = 0;
63 int one_file_system = 0;
64 int protocol_version = PROTOCOL_VERSION;
66 int do_compression = 0;
69 int relative_paths = -1;
77 char *files_from = NULL;
78 int filesfrom_fd = -1;
79 char *remote_filesfrom_file = NULL;
84 int daemon_over_rsh = 0;
88 int safe_symlinks = 0;
89 int copy_unsafe_links = 0;
91 int daemon_bwlimit = 0;
94 size_t bwlimit_writemax = 0;
95 int only_existing = 0;
96 int opt_ignore_existing = 0;
97 int need_messages_from_generator = 0;
100 int ignore_errors = 0;
101 int modify_window = 0;
102 int blocking_io = -1;
103 int checksum_seed = 0;
105 int delay_updates = 0;
106 long block_size = 0; /* "long" because popt can't set an int32. */
109 /** Network address family. **/
111 int default_af_hint = 0; /* Any protocol */
113 int default_af_hint = AF_INET; /* Must use IPv4 */
116 /** Do not go into the background when run as --daemon. Good
117 * for debugging and required for running as a service on W32,
118 * or under Unix process-monitors. **/
123 int backup_dir_len = 0;
124 int backup_suffix_len;
125 unsigned int backup_dir_remainder;
127 char *backup_suffix = NULL;
129 char *partial_dir = NULL;
130 char *basis_dir[MAX_BASIS_DIRS+1];
131 char *config_file = NULL;
132 char *shell_cmd = NULL;
133 char *log_format = NULL;
134 char *password_file = NULL;
135 char *rsync_path = RSYNC_PATH;
136 char *backup_dir = NULL;
137 char backup_dir_buf[MAXPATHLEN];
139 int compare_dest = 0;
142 int basis_dir_cnt = 0;
146 int itemize_changes = 0;
147 int log_before_transfer = 0;
148 int log_format_has_i = 0;
149 int log_format_has_o_or_i = 0;
150 int always_checksum = 0;
153 #define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
154 char *batch_name = NULL;
156 static int daemon_opt; /* sets am_daemon after option error-reporting */
157 static int F_option_cnt = 0;
158 static int modify_window_set;
159 static int refused_delete, refused_archive_part;
160 static int refused_partial, refused_progress, refused_delete_before;
161 static char *dest_option = NULL;
162 static char *max_size_arg;
163 static char partialdir_for_delayupdate[] = ".~tmp~";
165 /** Local address to bind. As a character string because it's
166 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
167 * address, or a hostname. **/
171 static void print_rsync_version(enum logcode f)
173 char const *got_socketpair = "no ";
174 char const *have_inplace = "no ";
175 char const *hardlinks = "no ";
176 char const *links = "no ";
177 char const *ipv6 = "no ";
178 STRUCT_STAT *dumstat;
180 #ifdef HAVE_SOCKETPAIR
184 #ifdef HAVE_FTRUNCATE
188 #ifdef SUPPORT_HARD_LINKS
200 rprintf(f, "%s version %s protocol version %d\n",
201 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
203 "Copyright (C) 1996-2005 by Andrew Tridgell and others\n");
204 rprintf(f, "<http://rsync.samba.org/>\n");
205 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
206 "%shard links, %ssymlinks, batchfiles, \n",
207 (int) (sizeof (OFF_T) * 8),
208 got_socketpair, hardlinks, links);
210 /* Note that this field may not have type ino_t. It depends
211 * on the complicated interaction between largefile feature
213 rprintf(f, " %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
215 (int) (sizeof dumstat->st_ino * 8),
216 (int) (sizeof (int64) * 8));
217 #ifdef MAINTAINER_MODE
218 rprintf(f, " panic action: \"%s\"\n",
223 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
225 if (sizeof (int64) != SIZEOF_INT64) {
227 "WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
228 (int) SIZEOF_INT64, (int) sizeof (int64));
233 "rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
234 "are welcome to redistribute it under certain conditions. See the GNU\n"
235 "General Public Licence for details.\n"
240 void usage(enum logcode F)
242 print_rsync_version(F);
244 rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
246 rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
247 rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
248 rprintf(F," or rsync [OPTION]... SRC [SRC]... DEST\n");
249 rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
250 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
251 rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
252 rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
253 rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
254 rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
255 rprintf(F," sources separated by space as long as they have same top-level\n");
256 rprintf(F,"\nOptions\n");
257 rprintf(F," -v, --verbose increase verbosity\n");
258 rprintf(F," -q, --quiet suppress non-error messages\n");
259 rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n");
260 rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H)\n");
261 rprintf(F," -r, --recursive recurse into directories\n");
262 rprintf(F," -R, --relative use relative path names\n");
263 rprintf(F," --no-relative turn off --relative\n");
264 rprintf(F," --no-implied-dirs don't send implied dirs with -R\n");
265 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
266 rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
267 rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
268 rprintf(F," -u, --update skip files that are newer on the receiver\n");
269 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
270 rprintf(F," -d, --dirs transfer directories without recursing\n");
271 rprintf(F," -l, --links copy symlinks as symlinks\n");
272 rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
273 rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n");
274 rprintf(F," --safe-links ignore symlinks that point outside the source tree\n");
275 rprintf(F," -H, --hard-links preserve hard links\n");
276 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
277 rprintf(F," -p, --perms preserve permissions\n");
278 rprintf(F," -o, --owner preserve owner (root only)\n");
279 rprintf(F," -g, --group preserve group\n");
280 rprintf(F," -D, --devices preserve devices (root only)\n");
281 rprintf(F," -t, --times preserve times\n");
282 rprintf(F," -O, --omit-dir-times omit directories when preserving times\n");
283 rprintf(F," -S, --sparse handle sparse files efficiently\n");
284 rprintf(F," -n, --dry-run show what would have been transferred\n");
285 rprintf(F," -W, --whole-file copy files whole (without rsync algorithm)\n");
286 rprintf(F," --no-whole-file always use incremental rsync algorithm\n");
287 rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
288 rprintf(F," -B, --block-size=SIZE force a fixed checksum block-size\n");
289 rprintf(F," -e, --rsh=COMMAND specify the remote shell to use\n");
290 rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
291 rprintf(F," --existing only update files that already exist on receiver\n");
292 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
293 rprintf(F," --remove-sent-files sent files/symlinks are removed from sending side\n");
294 rprintf(F," --del an alias for --delete-during\n");
295 rprintf(F," --delete delete files that don't exist on the sending side\n");
296 rprintf(F," --delete-before receiver deletes before transfer (default)\n");
297 rprintf(F," --delete-during receiver deletes during transfer, not before\n");
298 rprintf(F," --delete-after receiver deletes after transfer, not before\n");
299 rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
300 rprintf(F," --ignore-errors delete even if there are I/O errors\n");
301 rprintf(F," --force force deletion of directories even if not empty\n");
302 rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
303 rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n");
304 rprintf(F," --partial keep partially transferred files\n");
305 rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
306 rprintf(F," --delay-updates put all updated files into place at transfer's end\n");
307 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
308 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
309 rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
310 rprintf(F," --size-only skip files that match in size\n");
311 rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
312 rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
313 rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n");
314 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
315 rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
316 rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
317 rprintf(F," -z, --compress compress file data during the transfer\n");
318 rprintf(F," -C, --cvs-exclude auto-ignore files the same way CVS does\n");
319 rprintf(F," -f, --filter=RULE add a file-filtering RULE\n");
320 rprintf(F," -F same as --filter='dir-merge /.rsync-filter'\n");
321 rprintf(F," repeated: --filter='- .rsync-filter'\n");
322 rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
323 rprintf(F," --exclude-from=FILE read exclude patterns from FILE\n");
324 rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
325 rprintf(F," --include-from=FILE read include patterns from FILE\n");
326 rprintf(F," --files-from=FILE read list of source-file names from FILE\n");
327 rprintf(F," -0, --from0 all *-from file lists are delimited by nulls\n");
328 rprintf(F," --version print version number\n");
329 rprintf(F," --port=PORT specify double-colon alternate port number\n");
330 rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
331 rprintf(F," --no-blocking-io turn off blocking I/O when it is the default\n");
332 rprintf(F," --stats give some file-transfer stats\n");
333 rprintf(F," --progress show progress during transfer\n");
334 rprintf(F," -P same as --partial --progress\n");
335 rprintf(F," -i, --itemize-changes output a change-summary for all updates\n");
336 rprintf(F," --log-format=FORMAT log file-transfers using specified format\n");
337 rprintf(F," --password-file=FILE read password from FILE\n");
338 rprintf(F," --list-only list the files instead of copying them\n");
339 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
340 rprintf(F," --write-batch=FILE write a batched update to FILE\n");
341 rprintf(F," --read-batch=FILE read a batched update from FILE\n");
343 rprintf(F," -4, --ipv4 prefer IPv4\n");
344 rprintf(F," -6, --ipv6 prefer IPv6\n");
346 rprintf(F," -h, --help show this help screen\n");
348 rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
349 rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
350 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
353 enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
354 OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
355 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
356 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
357 OPT_REFUSED_BASE = 9000};
359 static struct poptOption long_options[] = {
360 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
361 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
362 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
363 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
364 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
365 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
366 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
367 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
368 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
369 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
370 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
371 {"del", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
372 {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
373 {"delete-before", 0, POPT_ARG_VAL, &delete_before, 2, 0, 0 },
374 {"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
375 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
376 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
377 {"remove-sent-files",0, POPT_ARG_NONE, &remove_sent_files, 0, 0, 0 },
378 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
379 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
380 {"filter", 'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
381 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
382 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
383 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
384 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
385 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
386 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
387 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
388 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
389 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
390 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
391 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
392 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
393 {"dirs", 'd', POPT_ARG_VAL, &xfer_dirs, 2, 0, 0 },
394 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
395 {"copy-links", 'L', POPT_ARG_NONE, ©_links, 0, 0, 0 },
396 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
397 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
398 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
399 {"copy-unsafe-links",0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 },
400 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
401 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
402 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
403 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
404 {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
405 {"omit-dir-times", 'O', POPT_ARG_NONE, &omit_dir_times, 0, 0, 0 },
406 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
407 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
408 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
409 {"archive", 'a', POPT_ARG_NONE, &archive_mode, 0, 0, 0 },
410 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
411 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
412 {"recursive", 'r', POPT_ARG_VAL, &recurse, -1, 0, 0 },
413 {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
414 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
415 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
416 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
417 {"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
418 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
419 {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
420 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
421 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
422 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
423 {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
424 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
425 {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
426 /* TODO: Should this take an optional int giving the compression level? */
427 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
428 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
429 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
430 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
431 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
432 {"delay-updates", 0, POPT_ARG_NONE, &delay_updates, 0, 0, 0 },
433 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
434 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
435 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
436 {0, 'F', POPT_ARG_NONE, 0, 'F', 0, 0 },
437 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
438 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
439 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
440 {"itemize-changes", 'i', POPT_ARG_NONE, &itemize_changes, 0, 0, 0 },
441 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
442 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
443 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
444 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
445 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
446 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
447 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
448 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
449 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
450 {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
452 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
453 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
455 /* All these options switch us into daemon-mode option-parsing. */
456 {"address", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
457 {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
458 {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
459 {"no-detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
463 static void daemon_usage(enum logcode F)
465 print_rsync_version(F);
467 rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
468 rprintf(F," --address=ADDRESS bind to the specified address\n");
469 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
470 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
471 rprintf(F," --no-detach do not detach from the parent\n");
472 rprintf(F," --port=PORT listen on alternate port number\n");
473 rprintf(F," -v, --verbose increase verbosity\n");
475 rprintf(F," -4, --ipv4 prefer IPv4\n");
476 rprintf(F," -6, --ipv6 prefer IPv6\n");
478 rprintf(F," -h, --help show this help screen\n");
480 rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
481 rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
484 static struct poptOption long_daemon_options[] = {
485 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
486 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
487 {"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
488 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
489 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
491 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
492 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
494 {"no-detach", 0, POPT_ARG_NONE, &no_detach, 0, 0, 0 },
495 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
496 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
497 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
498 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
499 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
504 static char err_buf[200];
508 * Store the option error message, if any, so that we can log the
509 * connection attempt (which requires parsing the options), and then
510 * show the error later on.
512 void option_error(void)
515 strcpy(err_buf, "Error parsing options: "
516 "option may be supported on client but not on server?\n");
519 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
524 * Tweak the option table to disable all options that the rsyncd.conf
525 * file has told us to refuse.
527 static void set_refuse_options(char *bp)
529 struct poptOption *op;
530 char *cp, shortname[2];
531 int is_wild, found_match;
536 while (*bp == ' ') bp++;
539 if ((cp = strchr(bp, ' ')) != NULL)
541 is_wild = strpbrk(bp, "*?[") != NULL;
543 for (op = long_options; ; op++) {
544 *shortname = op->shortName;
545 if (!op->longName && !*shortname)
547 if ((op->longName && wildmatch(bp, op->longName))
548 || (*shortname && wildmatch(bp, shortname))) {
549 if (op->argInfo == POPT_ARG_VAL)
550 op->argInfo = POPT_ARG_NONE;
551 op->val = (op - long_options) + OPT_REFUSED_BASE;
553 /* These flags are set to let us easily check
554 * an implied option later in the code. */
555 switch (*shortname) {
556 case 'r': case 'd': case 'l': case 'p':
557 case 't': case 'g': case 'o': case 'D':
558 refused_archive_part = op->val;
561 if (wildmatch("delete", op->longName))
562 refused_delete = op->val;
563 else if (wildmatch("delete-before", op->longName))
564 refused_delete_before = op->val;
565 else if (wildmatch("partial", op->longName))
566 refused_partial = op->val;
567 else if (wildmatch("progress", op->longName))
568 refused_progress = op->val;
576 rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
585 for (op = long_options; ; op++) {
586 *shortname = op->shortName;
587 if (!op->longName && !*shortname)
589 if (op->val == OPT_DAEMON) {
590 if (op->argInfo == POPT_ARG_VAL)
591 op->argInfo = POPT_ARG_NONE;
592 op->val = (op - long_options) + OPT_REFUSED_BASE;
598 static int count_args(const char **argv)
603 while (argv[i] != NULL)
611 static void create_refuse_error(int which)
613 /* The "which" value is the index + OPT_REFUSED_BASE. */
614 struct poptOption *op = &long_options[which - OPT_REFUSED_BASE];
615 int n = snprintf(err_buf, sizeof err_buf,
616 "The server is configured to refuse --%s\n",
619 snprintf(err_buf + n, sizeof err_buf - n,
620 " (-%c)\n", op->shortName);
626 * Process command line arguments. Called on both local and remote.
628 * @retval 1 if all options are OK; with globals set to appropriate
631 * @retval 0 on error, with err_buf containing an explanation
633 int parse_arguments(int *argc, const char ***argv, int frommain)
636 char *ref = lp_refuse_options(module_id);
641 set_refuse_options(ref);
643 /* TODO: Call poptReadDefaultConfig; handle errors. */
645 /* The context leaks in case of an error, but if there's a
646 * problem we always exit anyhow. */
647 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
648 poptReadDefaultConfig(pc, 0);
650 while ((opt = poptGetNextOpt(pc)) != -1) {
651 /* most options are handled automatically by popt;
652 * only special cases are returned and listed here. */
656 print_rsync_version(FINFO);
661 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
665 pc = poptGetContext(RSYNC_NAME, *argc, *argv,
666 long_daemon_options, 0);
667 while ((opt = poptGetNextOpt(pc)) != -1) {
679 "rsync: %s: %s (in daemon mode)\n",
680 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
686 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
689 "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
690 exit_cleanup(RERR_SYNTAX);
692 *argv = poptGetArgs(pc);
693 *argc = count_args(*argv);
698 case OPT_MODIFY_WINDOW:
699 /* The value has already been set by popt, but
700 * we need to remember that we're using a
701 * non-default setting. */
702 modify_window_set = 1;
706 parse_rule(&filter_list, poptGetOptArg(pc), 0, 0);
710 parse_rule(&filter_list, poptGetOptArg(pc),
711 0, XFLG_OLD_PREFIXES);
715 parse_rule(&filter_list, poptGetOptArg(pc),
716 MATCHFLG_INCLUDE, XFLG_OLD_PREFIXES);
719 case OPT_EXCLUDE_FROM:
720 case OPT_INCLUDE_FROM:
721 arg = poptGetOptArg(pc);
723 arg = sanitize_path(NULL, arg, NULL, 0);
724 if (server_filter_list.head) {
725 char *cp = (char *)arg;
727 goto options_rejected;
729 if (check_filter(&server_filter_list, cp, 0) < 0)
730 goto options_rejected;
732 parse_filter_file(&filter_list, arg,
733 opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
734 XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
753 exit_cleanup(RERR_SYNTAX);
759 switch (++F_option_cnt) {
761 parse_rule(&filter_list,": /.rsync-filter",0,0);
764 parse_rule(&filter_list,"- .rsync-filter",0,0);
770 if (refused_partial || refused_progress) {
771 create_refuse_error(refused_partial
772 ? refused_partial : refused_progress);
779 case OPT_WRITE_BATCH:
780 /* batch_name is already set */
785 /* batch_name is already set */
790 for (arg = max_size_arg; isdigit(*(uchar*)arg); arg++) {}
792 for (arg++; isdigit(*(uchar*)arg); arg++) {}
795 max_size = atof(max_size_arg) * 1024;
798 max_size = atof(max_size_arg) * 1024*1024;
801 max_size = atof(max_size_arg) * 1024*1024*1024;
804 max_size = atof(max_size_arg);
811 snprintf(err_buf, sizeof err_buf,
812 "--max-size value is invalid: %s\n",
819 if (io_timeout && io_timeout < select_timeout)
820 select_timeout = io_timeout;
826 dest_option = "--link-dest";
829 snprintf(err_buf, sizeof err_buf,
830 "hard links are not supported on this %s\n",
831 am_server ? "server" : "client");
837 dest_option = "--copy-dest";
840 case OPT_COMPARE_DEST:
842 dest_option = "--compare-dest";
844 if (basis_dir_cnt >= MAX_BASIS_DIRS) {
845 snprintf(err_buf, sizeof err_buf,
846 "ERROR: at most %d %s args may be specified\n",
847 MAX_BASIS_DIRS, dest_option);
850 arg = poptGetOptArg(pc);
852 arg = sanitize_path(NULL, arg, NULL, 0);
853 basis_dir[basis_dir_cnt++] = (char *)arg;
857 /* A large opt value means that set_refuse_options()
858 * turned this option off. */
859 if (opt >= OPT_REFUSED_BASE) {
860 create_refuse_error(opt);
863 snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
864 am_server ? "on remote machine: " : "",
865 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
874 #ifndef SUPPORT_LINKS
875 if (preserve_links && !am_sender) {
876 snprintf(err_buf, sizeof err_buf,
877 "symlinks are not supported on this %s\n",
878 am_server ? "server" : "client");
883 #ifndef SUPPORT_HARD_LINKS
884 if (preserve_hard_links) {
885 snprintf(err_buf, sizeof err_buf,
886 "hard links are not supported on this %s\n",
887 am_server ? "server" : "client");
892 if (write_batch && read_batch) {
893 snprintf(err_buf, sizeof err_buf,
894 "--write-batch and --read-batch can not be used together\n");
897 if (write_batch || read_batch) {
899 snprintf(err_buf, sizeof err_buf,
900 "--%s-batch cannot be used with --dry_run (-n)\n",
901 write_batch ? "write" : "read");
906 "ignoring --%s-batch option sent to server\n",
907 write_batch ? "write" : "read");
908 /* We don't actually exit_cleanup(), so that we can
909 * still service older version clients that still send
910 * batch args to server. */
911 read_batch = write_batch = 0;
915 if (read_batch && files_from) {
916 snprintf(err_buf, sizeof err_buf,
917 "--read-batch cannot be used with --files-from\n");
920 if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
921 snprintf(err_buf, sizeof err_buf,
922 "the batch-file name must be %d characters or less.\n",
927 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
928 snprintf(err_buf, sizeof err_buf,
929 "the --temp-dir path is WAY too long.\n");
933 if (compare_dest + copy_dest + link_dest > 1) {
934 snprintf(err_buf, sizeof err_buf,
935 "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
940 if (refused_archive_part) {
941 create_refuse_error(refused_archive_part);
945 recurse = -1; /* infinite recursion */
953 preserve_devices = 1;
956 if (recurse || list_only || files_from)
959 if (relative_paths < 0)
960 relative_paths = files_from? 1 : 0;
962 if (!!delete_before + delete_during + delete_after > 1) {
963 snprintf(err_buf, sizeof err_buf,
964 "You may not combine multiple --delete-WHEN options.\n");
968 delete_before = delete_during = delete_after = 0;
969 delete_mode = delete_excluded = 0;
970 } else if (delete_before || delete_during || delete_after)
972 else if (delete_mode || delete_excluded) {
973 if (refused_delete_before) {
974 create_refuse_error(refused_delete_before);
977 delete_mode = delete_before = 1;
980 if (delete_mode && refused_delete) {
981 create_refuse_error(refused_delete);
985 if (remove_sent_files) {
986 /* We only want to infer this refusal of --remove-sent-files
987 * via the refusal of "delete", not any of the "delete-FOO"
989 if (refused_delete && am_sender) {
990 create_refuse_error(refused_delete);
993 need_messages_from_generator = 1;
996 *argv = poptGetArgs(pc);
997 *argc = count_args(*argv);
999 if (sanitize_paths) {
1001 for (i = *argc; i-- > 0; )
1002 (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
1004 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
1006 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
1008 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
1010 files_from = sanitize_path(NULL, files_from, NULL, 0);
1012 if (server_filter_list.head && !am_sender) {
1013 struct filter_list_struct *elp = &server_filter_list;
1017 goto options_rejected;
1018 clean_fname(tmpdir, 1);
1019 if (check_filter(elp, tmpdir, 1) < 0)
1020 goto options_rejected;
1022 if (partial_dir && *partial_dir) {
1023 clean_fname(partial_dir, 1);
1024 if (check_filter(elp, partial_dir, 1) < 0)
1025 goto options_rejected;
1027 for (i = 0; i < basis_dir_cnt; i++) {
1029 goto options_rejected;
1030 clean_fname(basis_dir[i], 1);
1031 if (check_filter(elp, basis_dir[i], 1) < 0)
1032 goto options_rejected;
1036 goto options_rejected;
1037 clean_fname(backup_dir, 1);
1038 if (check_filter(elp, backup_dir, 1) < 0)
1039 goto options_rejected;
1042 if (server_filter_list.head && files_from) {
1044 goto options_rejected;
1045 clean_fname(files_from, 1);
1046 if (check_filter(&server_filter_list, files_from, 0) < 0) {
1048 snprintf(err_buf, sizeof err_buf,
1049 "Your options have been rejected by the server.\n");
1055 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
1056 backup_suffix_len = strlen(backup_suffix);
1057 if (strchr(backup_suffix, '/') != NULL) {
1058 snprintf(err_buf, sizeof err_buf,
1059 "--suffix cannot contain slashes: %s\n",
1064 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
1065 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
1066 if (backup_dir_remainder < 32) {
1067 snprintf(err_buf, sizeof err_buf,
1068 "the --backup-dir path is WAY too long.\n");
1071 if (backup_dir_buf[backup_dir_len - 1] != '/') {
1072 backup_dir_buf[backup_dir_len++] = '/';
1073 backup_dir_buf[backup_dir_len] = '\0';
1075 if (verbose > 1 && !am_sender) {
1076 rprintf(FINFO, "backup_dir is %s\n",
1077 safe_fname(backup_dir_buf));
1079 } else if (!backup_suffix_len && (!am_server || !am_sender)) {
1080 snprintf(err_buf, sizeof err_buf,
1081 "--suffix cannot be a null string without --backup-dir\n");
1086 if (strstr(log_format, "%i") != NULL)
1087 log_format_has_i = 1;
1088 if (strstr(log_format, "%b") == NULL
1089 && strstr(log_format, "%c") == NULL)
1090 log_before_transfer = !am_server;
1091 } else if (itemize_changes) {
1092 log_format = "%i %n%L";
1093 log_format_has_i = 1;
1094 log_before_transfer = !am_server;
1097 if ((do_progress || dry_run) && !verbose && !log_before_transfer
1101 if (verbose && !log_format) {
1102 log_format = "%n%L";
1103 log_before_transfer = !am_server;
1105 if (log_format_has_i
1106 || (log_format && strstr(log_format, "%o") != NULL))
1107 log_format_has_o_or_i = 1;
1109 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1110 bwlimit = daemon_bwlimit;
1112 bwlimit_writemax = (size_t)bwlimit * 128;
1113 if (bwlimit_writemax < 512)
1114 bwlimit_writemax = 512;
1117 if (delay_updates && !partial_dir)
1118 partial_dir = partialdir_for_delayupdate;
1121 #ifdef HAVE_FTRUNCATE
1123 snprintf(err_buf, sizeof err_buf,
1124 "--inplace cannot be used with --%s\n",
1125 delay_updates ? "delay-updates" : "partial-dir");
1128 /* --inplace implies --partial for refusal purposes, but we
1129 * clear the keep_partial flag for internal logic purposes. */
1130 if (refused_partial) {
1131 create_refuse_error(refused_partial);
1136 snprintf(err_buf, sizeof err_buf,
1137 "--inplace is not supported on this %s\n",
1138 am_server ? "server" : "client");
1142 if (keep_partial && !partial_dir) {
1143 if ((arg = getenv("RSYNC_PARTIAL_DIR")) != NULL && *arg)
1144 partial_dir = strdup(arg);
1148 clean_fname(partial_dir, 1);
1149 if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1151 else if (*partial_dir != '/') {
1152 parse_rule(&filter_list, partial_dir,
1153 MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
1155 if (!partial_dir && refused_partial) {
1156 create_refuse_error(refused_partial);
1165 if (*argc > 2 || (!am_daemon && *argc == 1)) {
1167 exit_cleanup(RERR_SYNTAX);
1169 if (strcmp(files_from, "-") == 0) {
1172 remote_filesfrom_file = "-";
1174 else if ((colon = find_colon(files_from)) != 0) {
1177 exit_cleanup(RERR_SYNTAX);
1179 remote_filesfrom_file = colon+1 + (colon[1] == ':');
1180 if (strcmp(remote_filesfrom_file, "-") == 0) {
1181 snprintf(err_buf, sizeof err_buf,
1182 "Invalid --files-from remote filename\n");
1186 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1187 if (filesfrom_fd < 0) {
1188 snprintf(err_buf, sizeof err_buf,
1189 "failed to open files-from file %s: %s\n",
1190 files_from, strerror(errno));
1201 * Construct a filtered list of options to pass through from the
1202 * client to the server.
1204 * This involves setting options that will tell the server how to
1205 * behave, and also filtering out options that are processed only
1208 void server_options(char **args,int *argc)
1210 static char argstr[50+MAX_BASIS_DIRS*2];
1216 if (blocking_io == -1)
1219 args[ac++] = "--server";
1221 if (daemon_over_rsh) {
1222 args[ac++] = "--daemon";
1224 /* if we're passing --daemon, we're done */
1229 args[ac++] = "--sender";
1233 for (i = 0; i < verbose; i++)
1236 /* the -q option is intentionally left out */
1249 if (keep_dirlinks && am_sender)
1254 /* We don't need to send --no-whole-file, because it's the
1255 * default for remote transfers, and in any case old versions
1256 * of rsync will not understand it. */
1258 if (preserve_hard_links)
1264 if (preserve_devices)
1268 if (omit_dir_times && am_sender)
1274 if (always_checksum)
1282 if (one_file_system)
1289 /* This is a complete hack - blame Rusty. FIXME!
1290 * This hack is only needed for older rsync versions that
1291 * don't understand the --list-only option. */
1292 if (list_only == 1 && recurse >= 0)
1298 args[ac++] = argstr;
1301 args[ac++] = "--list-only";
1303 /* The server side doesn't use our log-format, but in certain
1304 * circumstances they need to know a little about the option. */
1305 if (log_format && am_sender) {
1306 if (log_format_has_i)
1307 args[ac++] = "--log-format=%i";
1308 else if (log_format_has_o_or_i)
1309 args[ac++] = "--log-format=%o";
1311 args[ac++] = "--log-format=X";
1315 if (asprintf(&arg, "-B%lu", block_size) < 0)
1320 if (max_delete && am_sender) {
1321 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1326 if (max_size && am_sender) {
1327 args[ac++] = "--max-size";
1328 args[ac++] = max_size_arg;
1332 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1338 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1344 args[ac++] = "--backup-dir";
1345 args[ac++] = backup_dir;
1348 /* Only send --suffix if it specifies a non-default value. */
1349 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1350 /* We use the following syntax to avoid weirdness with '~'. */
1351 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1357 if (delete_excluded)
1358 args[ac++] = "--delete-excluded";
1359 else if (delete_before == 1 || delete_after)
1360 args[ac++] = "--delete";
1361 if (delete_before > 1)
1362 args[ac++] = "--delete-before";
1364 args[ac++] = "--delete-during";
1366 args[ac++] = "--delete-after";
1368 args[ac++] = "--force";
1372 args[ac++] = "--size-only";
1374 if (modify_window_set) {
1375 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1380 if (checksum_seed) {
1381 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1386 if (partial_dir && am_sender) {
1387 if (partial_dir != partialdir_for_delayupdate) {
1388 args[ac++] = "--partial-dir";
1389 args[ac++] = partial_dir;
1392 args[ac++] = "--delay-updates";
1393 } else if (keep_partial)
1394 args[ac++] = "--partial";
1397 args[ac++] = "--ignore-errors";
1399 if (copy_unsafe_links)
1400 args[ac++] = "--copy-unsafe-links";
1403 args[ac++] = "--safe-links";
1406 args[ac++] = "--numeric-ids";
1408 if (only_existing && am_sender)
1409 args[ac++] = "--existing";
1411 if (opt_ignore_existing && am_sender)
1412 args[ac++] = "--ignore-existing";
1415 args[ac++] = "--inplace";
1418 args[ac++] = "--temp-dir";
1419 args[ac++] = tmpdir;
1422 if (basis_dir[0] && am_sender) {
1423 /* the server only needs this option if it is not the sender,
1424 * and it may be an older version that doesn't know this
1425 * option, so don't send it if client is the sender.
1428 for (i = 0; i < basis_dir_cnt; i++) {
1429 args[ac++] = dest_option;
1430 args[ac++] = basis_dir[i];
1434 if (files_from && (!am_sender || remote_filesfrom_file)) {
1435 if (remote_filesfrom_file) {
1436 args[ac++] = "--files-from";
1437 args[ac++] = remote_filesfrom_file;
1439 args[ac++] = "--from0";
1441 args[ac++] = "--files-from=-";
1442 args[ac++] = "--from0";
1444 if (!relative_paths)
1445 args[ac++] = "--no-relative";
1447 if (!implied_dirs && !am_sender)
1448 args[ac++] = "--no-implied-dirs";
1450 if (fuzzy_basis && am_sender)
1451 args[ac++] = "--fuzzy";
1453 if (remove_sent_files)
1454 args[ac++] = "--remove-sent-files";
1460 out_of_memory("server_options");
1464 * Return the position of a ':' IF it is not part of a filename (i.e. as
1465 * long as it doesn't occur after a slash.
1467 char *find_colon(char *s)
1475 /* now check to see if there is a / in the string before the : - if there is then
1476 discard the colon on the assumption that the : is part of a filename */