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 one_file_system = 0;
63 int protocol_version = PROTOCOL_VERSION;
65 int do_compression = 0;
68 int relative_paths = -1;
76 char *files_from = NULL;
77 int filesfrom_fd = -1;
78 char *remote_filesfrom_file = NULL;
83 int daemon_over_rsh = 0;
87 int safe_symlinks = 0;
88 int copy_unsafe_links = 0;
90 int daemon_bwlimit = 0;
93 size_t bwlimit_writemax = 0;
94 int only_existing = 0;
95 int opt_ignore_existing = 0;
98 int ignore_errors = 0;
99 int modify_window = 0;
100 int blocking_io = -1;
101 int checksum_seed = 0;
103 int delay_updates = 0;
104 long block_size = 0; /* "long" because popt can't set an int32. */
107 /** Network address family. **/
109 int default_af_hint = 0; /* Any protocol */
111 int default_af_hint = AF_INET; /* Must use IPv4 */
114 /** Do not go into the background when run as --daemon. Good
115 * for debugging and required for running as a service on W32,
116 * or under Unix process-monitors. **/
121 int backup_dir_len = 0;
122 int backup_suffix_len;
123 unsigned int backup_dir_remainder;
125 char *backup_suffix = NULL;
127 char *partial_dir = NULL;
128 char *basis_dir[MAX_BASIS_DIRS+1];
129 char *config_file = NULL;
130 char *shell_cmd = NULL;
131 char *log_format = NULL;
132 char *password_file = NULL;
133 char *rsync_path = RSYNC_PATH;
134 char *backup_dir = NULL;
135 char backup_dir_buf[MAXPATHLEN];
137 int compare_dest = 0;
140 int basis_dir_cnt = 0;
144 int itemize_changes = 0;
145 int log_before_transfer = 0;
146 int log_format_has_o_or_i = 0;
147 int always_checksum = 0;
150 #define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
151 char *batch_name = NULL;
153 static int daemon_opt; /* sets am_daemon after option error-reporting */
154 static int F_option_cnt = 0;
155 static int modify_window_set;
156 static int refused_delete, refused_archive_part;
157 static int refused_partial, refused_progress, refused_delete_before;
158 static char *dest_option = NULL;
159 static char *max_size_arg;
160 static char partialdir_for_delayupdate[] = ".~tmp~";
162 /** Local address to bind. As a character string because it's
163 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
164 * address, or a hostname. **/
168 static void print_rsync_version(enum logcode f)
170 char const *got_socketpair = "no ";
171 char const *have_inplace = "no ";
172 char const *hardlinks = "no ";
173 char const *links = "no ";
174 char const *ipv6 = "no ";
175 STRUCT_STAT *dumstat;
177 #ifdef HAVE_SOCKETPAIR
181 #ifdef HAVE_FTRUNCATE
185 #ifdef SUPPORT_HARD_LINKS
197 rprintf(f, "%s version %s protocol version %d\n",
198 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
200 "Copyright (C) 1996-2005 by Andrew Tridgell and others\n");
201 rprintf(f, "<http://rsync.samba.org/>\n");
202 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
203 "%shard links, %ssymlinks, batchfiles, \n",
204 (int) (sizeof (OFF_T) * 8),
205 got_socketpair, hardlinks, links);
207 /* Note that this field may not have type ino_t. It depends
208 * on the complicated interaction between largefile feature
210 rprintf(f, " %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
212 (int) (sizeof dumstat->st_ino * 8),
213 (int) (sizeof (int64) * 8));
214 #ifdef MAINTAINER_MODE
215 rprintf(f, " panic action: \"%s\"\n",
220 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
222 if (sizeof (int64) != SIZEOF_INT64) {
224 "WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
225 (int) SIZEOF_INT64, (int) sizeof (int64));
230 "rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
231 "are welcome to redistribute it under certain conditions. See the GNU\n"
232 "General Public Licence for details.\n"
237 void usage(enum logcode F)
239 print_rsync_version(F);
241 rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
243 rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
244 rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
245 rprintf(F," or rsync [OPTION]... SRC [SRC]... DEST\n");
246 rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
247 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
248 rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
249 rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
250 rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
251 rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
252 rprintf(F," sources separated by space as long as they have same top-level\n");
253 rprintf(F,"\nOptions\n");
254 rprintf(F," -v, --verbose increase verbosity\n");
255 rprintf(F," -q, --quiet suppress non-error messages\n");
256 rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n");
257 rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H)\n");
258 rprintf(F," -r, --recursive recurse into directories\n");
259 rprintf(F," -R, --relative use relative path names\n");
260 rprintf(F," --no-relative turn off --relative\n");
261 rprintf(F," --no-implied-dirs don't send implied dirs with -R\n");
262 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
263 rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
264 rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
265 rprintf(F," -u, --update skip files that are newer on the receiver\n");
266 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
267 rprintf(F," -d, --dirs transfer directories without recursing\n");
268 rprintf(F," -l, --links copy symlinks as symlinks\n");
269 rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
270 rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n");
271 rprintf(F," --safe-links ignore symlinks that point outside the source tree\n");
272 rprintf(F," -H, --hard-links preserve hard links\n");
273 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
274 rprintf(F," -p, --perms preserve permissions\n");
275 rprintf(F," -o, --owner preserve owner (root only)\n");
276 rprintf(F," -g, --group preserve group\n");
277 rprintf(F," -D, --devices preserve devices (root only)\n");
278 rprintf(F," -t, --times preserve times\n");
279 rprintf(F," -O, --omit-dir-times omit directories when preserving times\n");
280 rprintf(F," -S, --sparse handle sparse files efficiently\n");
281 rprintf(F," -n, --dry-run show what would have been transferred\n");
282 rprintf(F," -W, --whole-file copy files whole (without rsync algorithm)\n");
283 rprintf(F," --no-whole-file always use incremental rsync algorithm\n");
284 rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
285 rprintf(F," -B, --block-size=SIZE force a fixed checksum block-size\n");
286 rprintf(F," -e, --rsh=COMMAND specify the remote shell to use\n");
287 rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
288 rprintf(F," --existing only update files that already exist on receiver\n");
289 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
290 rprintf(F," --del an alias for --delete-during\n");
291 rprintf(F," --delete delete files that don't exist on the sending side\n");
292 rprintf(F," --delete-before receiver deletes before transfer (default)\n");
293 rprintf(F," --delete-during receiver deletes during transfer, not before\n");
294 rprintf(F," --delete-after receiver deletes after transfer, not before\n");
295 rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
296 rprintf(F," --ignore-errors delete even if there are I/O errors\n");
297 rprintf(F," --force force deletion of directories even if not empty\n");
298 rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
299 rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n");
300 rprintf(F," --partial keep partially transferred files\n");
301 rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
302 rprintf(F," --delay-updates put all updated files into place at transfer's end\n");
303 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
304 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
305 rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
306 rprintf(F," --size-only skip files that match in size\n");
307 rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
308 rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
309 rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n");
310 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
311 rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
312 rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
313 rprintf(F," -z, --compress compress file data during the transfer\n");
314 rprintf(F," -C, --cvs-exclude auto-ignore files the same way CVS does\n");
315 rprintf(F," -f, --filter=RULE add a file-filtering RULE\n");
316 rprintf(F," -F same as --filter='dir-merge /.rsync-filter'\n");
317 rprintf(F," repeated: --filter='- .rsync-filter'\n");
318 rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
319 rprintf(F," --exclude-from=FILE read exclude patterns from FILE\n");
320 rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
321 rprintf(F," --include-from=FILE read include patterns from FILE\n");
322 rprintf(F," --files-from=FILE read list of source-file names from FILE\n");
323 rprintf(F," -0, --from0 all *-from file lists are delimited by nulls\n");
324 rprintf(F," --version print version number\n");
325 rprintf(F," --port=PORT specify double-colon alternate port number\n");
326 rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
327 rprintf(F," --no-blocking-io turn off blocking I/O when it is the default\n");
328 rprintf(F," --stats give some file-transfer stats\n");
329 rprintf(F," --progress show progress during transfer\n");
330 rprintf(F," -P same as --partial --progress\n");
331 rprintf(F," -i, --itemize-changes output a change-summary for all updates\n");
332 rprintf(F," --log-format=FORMAT log file-transfers using specified format\n");
333 rprintf(F," --password-file=FILE read password from FILE\n");
334 rprintf(F," --list-only list the files instead of copying them\n");
335 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
336 rprintf(F," --write-batch=FILE write a batched update to FILE\n");
337 rprintf(F," --read-batch=FILE read a batched update from FILE\n");
339 rprintf(F," -4, --ipv4 prefer IPv4\n");
340 rprintf(F," -6, --ipv6 prefer IPv6\n");
342 rprintf(F," -h, --help show this help screen\n");
344 rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
345 rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
346 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
349 enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
350 OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
351 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
352 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
353 OPT_REFUSED_BASE = 9000};
355 static struct poptOption long_options[] = {
356 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
357 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
358 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
359 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
360 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
361 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
362 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
363 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
364 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
365 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
366 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
367 {"del", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
368 {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
369 {"delete-before", 0, POPT_ARG_VAL, &delete_before, 2, 0, 0 },
370 {"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
371 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
372 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
373 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
374 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
375 {"filter", 'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
376 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
377 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
378 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
379 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
380 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
381 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
382 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
383 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
384 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
385 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
386 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
387 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
388 {"dirs", 'd', POPT_ARG_VAL, &xfer_dirs, 2, 0, 0 },
389 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
390 {"copy-links", 'L', POPT_ARG_NONE, ©_links, 0, 0, 0 },
391 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
392 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
393 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
394 {"copy-unsafe-links",0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 },
395 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
396 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
397 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
398 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
399 {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
400 {"omit-dir-times", 'O', POPT_ARG_NONE, &omit_dir_times, 0, 0, 0 },
401 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
402 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
403 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
404 {"archive", 'a', POPT_ARG_NONE, &archive_mode, 0, 0, 0 },
405 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
406 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
407 {"recursive", 'r', POPT_ARG_VAL, &recurse, -1, 0, 0 },
408 {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
409 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
410 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
411 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
412 {"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
413 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
414 {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
415 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
416 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
417 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
418 {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
419 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
420 {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
421 /* TODO: Should this take an optional int giving the compression level? */
422 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
423 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
424 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
425 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
426 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
427 {"delay-updates", 0, POPT_ARG_NONE, &delay_updates, 0, 0, 0 },
428 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
429 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
430 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
431 {0, 'F', POPT_ARG_NONE, 0, 'F', 0, 0 },
432 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
433 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
434 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
435 {"itemize-changes", 'i', POPT_ARG_NONE, &itemize_changes, 0, 0, 0 },
436 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
437 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
438 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
439 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
440 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
441 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
442 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
443 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
444 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
445 {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
447 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
448 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
450 /* All these options switch us into daemon-mode option-parsing. */
451 {"address", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
452 {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
453 {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
454 {"no-detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
458 static void daemon_usage(enum logcode F)
460 print_rsync_version(F);
462 rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
463 rprintf(F," --address=ADDRESS bind to the specified address\n");
464 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
465 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
466 rprintf(F," --no-detach do not detach from the parent\n");
467 rprintf(F," --port=PORT listen on alternate port number\n");
468 rprintf(F," -v, --verbose increase verbosity\n");
470 rprintf(F," -4, --ipv4 prefer IPv4\n");
471 rprintf(F," -6, --ipv6 prefer IPv6\n");
473 rprintf(F," -h, --help show this help screen\n");
475 rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
476 rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
479 static struct poptOption long_daemon_options[] = {
480 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
481 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
482 {"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
483 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
484 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
486 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
487 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
489 {"no-detach", 0, POPT_ARG_NONE, &no_detach, 0, 0, 0 },
490 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
491 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
492 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
493 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
494 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
499 static char err_buf[200];
503 * Store the option error message, if any, so that we can log the
504 * connection attempt (which requires parsing the options), and then
505 * show the error later on.
507 void option_error(void)
510 strcpy(err_buf, "Error parsing options: "
511 "option may be supported on client but not on server?\n");
514 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
519 * Tweak the option table to disable all options that the rsyncd.conf
520 * file has told us to refuse.
522 static void set_refuse_options(char *bp)
524 struct poptOption *op;
525 char *cp, shortname[2];
526 int is_wild, found_match;
531 while (*bp == ' ') bp++;
534 if ((cp = strchr(bp, ' ')) != NULL)
536 is_wild = strpbrk(bp, "*?[") != NULL;
538 for (op = long_options; ; op++) {
539 *shortname = op->shortName;
540 if (!op->longName && !*shortname)
542 if ((op->longName && wildmatch(bp, op->longName))
543 || (*shortname && wildmatch(bp, shortname))
544 || op->val == OPT_DAEMON) {
545 if (op->argInfo == POPT_ARG_VAL)
546 op->argInfo = POPT_ARG_NONE;
547 op->val = (op - long_options) + OPT_REFUSED_BASE;
549 /* These flags are set to let us easily check
550 * an implied option later in the code. */
551 switch (*shortname) {
552 case 'r': case 'd': case 'l': case 'p':
553 case 't': case 'g': case 'o': case 'D':
554 refused_archive_part = op->val;
557 if (wildmatch("delete", op->longName))
558 refused_delete = op->val;
559 else if (wildmatch("delete-before", op->longName))
560 refused_delete_before = op->val;
561 else if (wildmatch("partial", op->longName))
562 refused_partial = op->val;
563 else if (wildmatch("progress", op->longName))
564 refused_progress = op->val;
572 rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
583 static int count_args(const char **argv)
588 while (argv[i] != NULL)
596 static void create_refuse_error(int which)
598 /* The "which" value is the index + OPT_REFUSED_BASE. */
599 struct poptOption *op = &long_options[which - OPT_REFUSED_BASE];
600 int n = snprintf(err_buf, sizeof err_buf,
601 "The server is configured to refuse --%s\n",
604 snprintf(err_buf + n, sizeof err_buf - n,
605 " (-%c)\n", op->shortName);
611 * Process command line arguments. Called on both local and remote.
613 * @retval 1 if all options are OK; with globals set to appropriate
616 * @retval 0 on error, with err_buf containing an explanation
618 int parse_arguments(int *argc, const char ***argv, int frommain)
621 char *ref = lp_refuse_options(module_id);
626 set_refuse_options(ref);
628 /* TODO: Call poptReadDefaultConfig; handle errors. */
630 /* The context leaks in case of an error, but if there's a
631 * problem we always exit anyhow. */
632 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
633 poptReadDefaultConfig(pc, 0);
635 while ((opt = poptGetNextOpt(pc)) != -1) {
636 /* most options are handled automatically by popt;
637 * only special cases are returned and listed here. */
641 print_rsync_version(FINFO);
646 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
650 pc = poptGetContext(RSYNC_NAME, *argc, *argv,
651 long_daemon_options, 0);
652 while ((opt = poptGetNextOpt(pc)) != -1) {
664 "rsync: %s: %s (in daemon mode)\n",
665 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
671 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
674 "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
675 exit_cleanup(RERR_SYNTAX);
677 *argv = poptGetArgs(pc);
678 *argc = count_args(*argv);
683 case OPT_MODIFY_WINDOW:
684 /* The value has already been set by popt, but
685 * we need to remember that we're using a
686 * non-default setting. */
687 modify_window_set = 1;
691 parse_rule(&filter_list, poptGetOptArg(pc), 0, 0);
695 parse_rule(&filter_list, poptGetOptArg(pc),
696 0, XFLG_OLD_PREFIXES);
700 parse_rule(&filter_list, poptGetOptArg(pc),
701 MATCHFLG_INCLUDE, XFLG_OLD_PREFIXES);
704 case OPT_EXCLUDE_FROM:
705 case OPT_INCLUDE_FROM:
706 arg = poptGetOptArg(pc);
708 arg = sanitize_path(NULL, arg, NULL, 0);
709 if (server_filter_list.head) {
710 char *cp = (char *)arg;
712 goto options_rejected;
714 if (check_filter(&server_filter_list, cp, 0) < 0)
715 goto options_rejected;
717 parse_filter_file(&filter_list, arg,
718 opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
719 XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
738 exit_cleanup(RERR_SYNTAX);
744 switch (++F_option_cnt) {
746 parse_rule(&filter_list,": /.rsync-filter",0,0);
749 parse_rule(&filter_list,"- .rsync-filter",0,0);
755 if (refused_partial || refused_progress) {
756 create_refuse_error(refused_partial
757 ? refused_partial : refused_progress);
764 case OPT_WRITE_BATCH:
765 /* batch_name is already set */
770 /* batch_name is already set */
775 for (arg = max_size_arg; isdigit(*(uchar*)arg); arg++) {}
777 for (arg++; isdigit(*(uchar*)arg); arg++) {}
780 max_size = atof(max_size_arg) * 1024;
783 max_size = atof(max_size_arg) * 1024*1024;
786 max_size = atof(max_size_arg) * 1024*1024*1024;
789 max_size = atof(max_size_arg);
796 snprintf(err_buf, sizeof err_buf,
797 "--max-size value is invalid: %s\n",
804 if (io_timeout && io_timeout < select_timeout)
805 select_timeout = io_timeout;
811 dest_option = "--link-dest";
814 snprintf(err_buf, sizeof err_buf,
815 "hard links are not supported on this %s\n",
816 am_server ? "server" : "client");
822 dest_option = "--copy-dest";
825 case OPT_COMPARE_DEST:
827 dest_option = "--compare-dest";
829 if (basis_dir_cnt >= MAX_BASIS_DIRS) {
830 snprintf(err_buf, sizeof err_buf,
831 "ERROR: at most %d %s args may be specified\n",
832 MAX_BASIS_DIRS, dest_option);
835 arg = poptGetOptArg(pc);
837 arg = sanitize_path(NULL, arg, NULL, 0);
838 basis_dir[basis_dir_cnt++] = (char *)arg;
842 /* A large opt value means that set_refuse_options()
843 * turned this option off. */
844 if (opt >= OPT_REFUSED_BASE) {
845 create_refuse_error(opt);
848 snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
849 am_server ? "on remote machine: " : "",
850 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
859 #ifndef SUPPORT_LINKS
860 if (preserve_links && !am_sender) {
861 snprintf(err_buf, sizeof err_buf,
862 "symlinks are not supported on this %s\n",
863 am_server ? "server" : "client");
868 #ifndef SUPPORT_HARD_LINKS
869 if (preserve_hard_links) {
870 snprintf(err_buf, sizeof err_buf,
871 "hard links are not supported on this %s\n",
872 am_server ? "server" : "client");
877 if (write_batch && read_batch) {
878 snprintf(err_buf, sizeof err_buf,
879 "--write-batch and --read-batch can not be used together\n");
882 if (write_batch || read_batch) {
884 snprintf(err_buf, sizeof err_buf,
885 "--%s-batch cannot be used with --dry_run (-n)\n",
886 write_batch ? "write" : "read");
891 "ignoring --%s-batch option sent to server\n",
892 write_batch ? "write" : "read");
893 /* We don't actually exit_cleanup(), so that we can
894 * still service older version clients that still send
895 * batch args to server. */
896 read_batch = write_batch = 0;
900 if (read_batch && files_from) {
901 snprintf(err_buf, sizeof err_buf,
902 "--read-batch cannot be used with --files-from\n");
905 if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
906 snprintf(err_buf, sizeof err_buf,
907 "the batch-file name must be %d characters or less.\n",
912 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
913 snprintf(err_buf, sizeof err_buf,
914 "the --temp-dir path is WAY too long.\n");
918 if (compare_dest + copy_dest + link_dest > 1) {
919 snprintf(err_buf, sizeof err_buf,
920 "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
925 if (refused_archive_part) {
926 create_refuse_error(refused_archive_part);
930 recurse = -1; /* infinite recursion */
938 preserve_devices = 1;
941 if (recurse || list_only || files_from)
944 if (relative_paths < 0)
945 relative_paths = files_from? 1 : 0;
947 if (!!delete_before + delete_during + delete_after > 1) {
948 snprintf(err_buf, sizeof err_buf,
949 "You may not combine multiple --delete-WHEN options.\n");
953 delete_before = delete_during = delete_after = 0;
954 delete_mode = delete_excluded = 0;
955 } else if (delete_before || delete_during || delete_after)
957 else if (delete_mode || delete_excluded) {
958 if (refused_delete_before) {
959 create_refuse_error(refused_delete_before);
962 delete_mode = delete_before = 1;
965 if (delete_mode && refused_delete) {
966 create_refuse_error(refused_delete);
970 *argv = poptGetArgs(pc);
971 *argc = count_args(*argv);
973 if (sanitize_paths) {
975 for (i = *argc; i-- > 0; )
976 (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
978 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
980 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
982 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
984 files_from = sanitize_path(NULL, files_from, NULL, 0);
986 if (server_filter_list.head && !am_sender) {
987 struct filter_list_struct *elp = &server_filter_list;
991 goto options_rejected;
992 clean_fname(tmpdir, 1);
993 if (check_filter(elp, tmpdir, 1) < 0)
994 goto options_rejected;
996 if (partial_dir && *partial_dir) {
997 clean_fname(partial_dir, 1);
998 if (check_filter(elp, partial_dir, 1) < 0)
999 goto options_rejected;
1001 for (i = 0; i < basis_dir_cnt; i++) {
1003 goto options_rejected;
1004 clean_fname(basis_dir[i], 1);
1005 if (check_filter(elp, basis_dir[i], 1) < 0)
1006 goto options_rejected;
1010 goto options_rejected;
1011 clean_fname(backup_dir, 1);
1012 if (check_filter(elp, backup_dir, 1) < 0)
1013 goto options_rejected;
1016 if (server_filter_list.head && files_from) {
1018 goto options_rejected;
1019 clean_fname(files_from, 1);
1020 if (check_filter(&server_filter_list, files_from, 0) < 0) {
1022 snprintf(err_buf, sizeof err_buf,
1023 "Your options have been rejected by the server.\n");
1029 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
1030 backup_suffix_len = strlen(backup_suffix);
1031 if (strchr(backup_suffix, '/') != NULL) {
1032 snprintf(err_buf, sizeof err_buf,
1033 "--suffix cannot contain slashes: %s\n",
1038 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
1039 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
1040 if (backup_dir_remainder < 32) {
1041 snprintf(err_buf, sizeof err_buf,
1042 "the --backup-dir path is WAY too long.\n");
1045 if (backup_dir_buf[backup_dir_len - 1] != '/') {
1046 backup_dir_buf[backup_dir_len++] = '/';
1047 backup_dir_buf[backup_dir_len] = '\0';
1049 if (verbose > 1 && !am_sender) {
1050 rprintf(FINFO, "backup_dir is %s\n",
1051 safe_fname(backup_dir_buf));
1053 } else if (!backup_suffix_len && (!am_server || !am_sender)) {
1054 snprintf(err_buf, sizeof err_buf,
1055 "--suffix cannot be a null string without --backup-dir\n");
1060 if (strstr(log_format, "%i") != NULL)
1061 itemize_changes = 1;
1063 itemize_changes = 0;
1064 if (strstr(log_format, "%b") == NULL
1065 && strstr(log_format, "%c") == NULL)
1066 log_before_transfer = !am_server;
1067 } else if (itemize_changes) {
1068 log_format = "%i %n%L";
1069 log_before_transfer = !am_server;
1072 if ((do_progress || dry_run) && !verbose && !log_before_transfer
1076 if (verbose && !log_format) {
1077 log_format = "%n%L";
1078 log_before_transfer = !am_server;
1080 if (itemize_changes || (log_format && strstr(log_format, "%o") != NULL))
1081 log_format_has_o_or_i = 1;
1083 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1084 bwlimit = daemon_bwlimit;
1086 bwlimit_writemax = (size_t)bwlimit * 128;
1087 if (bwlimit_writemax < 512)
1088 bwlimit_writemax = 512;
1091 if (delay_updates && !partial_dir)
1092 partial_dir = partialdir_for_delayupdate;
1095 #ifdef HAVE_FTRUNCATE
1097 snprintf(err_buf, sizeof err_buf,
1098 "--inplace cannot be used with --%s\n",
1099 delay_updates ? "delay-updates" : "partial-dir");
1102 /* --inplace implies --partial for refusal purposes, but we
1103 * clear the keep_partial flag for internal logic purposes. */
1104 if (refused_partial) {
1105 create_refuse_error(refused_partial);
1110 snprintf(err_buf, sizeof err_buf,
1111 "--inplace is not supported on this %s\n",
1112 am_server ? "server" : "client");
1116 if (keep_partial && !partial_dir) {
1117 if ((arg = getenv("RSYNC_PARTIAL_DIR")) != NULL && *arg)
1118 partial_dir = strdup(arg);
1122 clean_fname(partial_dir, 1);
1123 if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1125 else if (*partial_dir != '/') {
1126 parse_rule(&filter_list, partial_dir,
1127 MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
1129 if (!partial_dir && refused_partial) {
1130 create_refuse_error(refused_partial);
1139 if (*argc > 2 || (!am_daemon && *argc == 1)) {
1141 exit_cleanup(RERR_SYNTAX);
1143 if (strcmp(files_from, "-") == 0) {
1146 remote_filesfrom_file = "-";
1148 else if ((colon = find_colon(files_from)) != 0) {
1151 exit_cleanup(RERR_SYNTAX);
1153 remote_filesfrom_file = colon+1 + (colon[1] == ':');
1154 if (strcmp(remote_filesfrom_file, "-") == 0) {
1155 snprintf(err_buf, sizeof err_buf,
1156 "Invalid --files-from remote filename\n");
1160 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1161 if (filesfrom_fd < 0) {
1162 snprintf(err_buf, sizeof err_buf,
1163 "failed to open files-from file %s: %s\n",
1164 files_from, strerror(errno));
1175 * Construct a filtered list of options to pass through from the
1176 * client to the server.
1178 * This involves setting options that will tell the server how to
1179 * behave, and also filtering out options that are processed only
1182 void server_options(char **args,int *argc)
1184 static char argstr[50+MAX_BASIS_DIRS*2];
1190 if (blocking_io == -1)
1193 args[ac++] = "--server";
1195 if (daemon_over_rsh) {
1196 args[ac++] = "--daemon";
1198 /* if we're passing --daemon, we're done */
1203 args[ac++] = "--sender";
1207 for (i = 0; i < verbose; i++)
1210 /* the -q option is intentionally left out */
1223 if (keep_dirlinks && am_sender)
1228 /* We don't need to send --no-whole-file, because it's the
1229 * default for remote transfers, and in any case old versions
1230 * of rsync will not understand it. */
1232 if (itemize_changes && am_sender)
1234 if (preserve_hard_links)
1240 if (preserve_devices)
1244 if (omit_dir_times && am_sender)
1250 if (always_checksum)
1258 if (one_file_system)
1265 /* This is a complete hack - blame Rusty. FIXME!
1266 * This hack is only needed for older rsync versions that
1267 * don't understand the --list-only option. */
1268 if (list_only == 1 && recurse >= 0)
1274 args[ac++] = argstr;
1277 args[ac++] = "--list-only";
1279 /* The server side doesn't use our log-format, but in certain
1280 * circumstances they need to know a little about the option. */
1281 if (log_format && am_sender && !itemize_changes) {
1282 if (log_format_has_o_or_i)
1283 args[ac++] = "--log-format=%o";
1285 args[ac++] = "--log-format=X";
1289 if (asprintf(&arg, "-B%lu", block_size) < 0)
1294 if (max_delete && am_sender) {
1295 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1300 if (max_size && am_sender) {
1301 args[ac++] = "--max-size";
1302 args[ac++] = max_size_arg;
1306 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1312 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1318 args[ac++] = "--backup-dir";
1319 args[ac++] = backup_dir;
1322 /* Only send --suffix if it specifies a non-default value. */
1323 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1324 /* We use the following syntax to avoid weirdness with '~'. */
1325 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1331 if (delete_excluded)
1332 args[ac++] = "--delete-excluded";
1333 else if (delete_before == 1 || delete_after)
1334 args[ac++] = "--delete";
1335 if (delete_before > 1)
1336 args[ac++] = "--delete-before";
1338 args[ac++] = "--delete-during";
1340 args[ac++] = "--delete-after";
1342 args[ac++] = "--force";
1346 args[ac++] = "--size-only";
1348 if (modify_window_set) {
1349 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1354 if (checksum_seed) {
1355 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1360 if (partial_dir && am_sender) {
1361 if (partial_dir != partialdir_for_delayupdate) {
1362 args[ac++] = "--partial-dir";
1363 args[ac++] = partial_dir;
1366 args[ac++] = "--delay-updates";
1367 } else if (keep_partial)
1368 args[ac++] = "--partial";
1371 args[ac++] = "--ignore-errors";
1373 if (copy_unsafe_links)
1374 args[ac++] = "--copy-unsafe-links";
1377 args[ac++] = "--safe-links";
1380 args[ac++] = "--numeric-ids";
1382 if (only_existing && am_sender)
1383 args[ac++] = "--existing";
1385 if (opt_ignore_existing && am_sender)
1386 args[ac++] = "--ignore-existing";
1389 args[ac++] = "--inplace";
1392 args[ac++] = "--temp-dir";
1393 args[ac++] = tmpdir;
1396 if (basis_dir[0] && am_sender) {
1397 /* the server only needs this option if it is not the sender,
1398 * and it may be an older version that doesn't know this
1399 * option, so don't send it if client is the sender.
1402 for (i = 0; i < basis_dir_cnt; i++) {
1403 args[ac++] = dest_option;
1404 args[ac++] = basis_dir[i];
1408 if (files_from && (!am_sender || remote_filesfrom_file)) {
1409 if (remote_filesfrom_file) {
1410 args[ac++] = "--files-from";
1411 args[ac++] = remote_filesfrom_file;
1413 args[ac++] = "--from0";
1415 args[ac++] = "--files-from=-";
1416 args[ac++] = "--from0";
1418 if (!relative_paths)
1419 args[ac++] = "--no-relative";
1421 if (!implied_dirs && !am_sender)
1422 args[ac++] = "--no-implied-dirs";
1424 if (fuzzy_basis && am_sender)
1425 args[ac++] = "--fuzzy";
1431 out_of_memory("server_options");
1435 * Return the position of a ':' IF it is not part of a filename (i.e. as
1436 * long as it doesn't occur after a slash.
1438 char *find_colon(char *s)
1446 /* now check to see if there is a / in the string before the : - if there is then
1447 discard the colon on the assumption that the : is part of a filename */