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;
92 size_t bwlimit_writemax = 0;
93 int only_existing = 0;
94 int opt_ignore_existing = 0;
97 int ignore_errors = 0;
98 int modify_window = 0;
100 int checksum_seed = 0;
102 int delay_updates = 0;
103 long block_size = 0; /* "long" because popt can't set an int32. */
106 /** Network address family. **/
108 int default_af_hint = 0; /* Any protocol */
110 int default_af_hint = AF_INET; /* Must use IPv4 */
113 /** Do not go into the background when run as --daemon. Good
114 * for debugging and required for running as a service on W32,
115 * or under Unix process-monitors. **/
120 int backup_dir_len = 0;
121 int backup_suffix_len;
122 unsigned int backup_dir_remainder;
124 char *backup_suffix = NULL;
126 char *partial_dir = NULL;
127 char *basis_dir[MAX_BASIS_DIRS+1];
128 char *config_file = NULL;
129 char *shell_cmd = NULL;
130 char *log_format = NULL;
131 char *password_file = NULL;
132 char *rsync_path = RSYNC_PATH;
133 char *backup_dir = NULL;
134 char backup_dir_buf[MAXPATHLEN];
136 int compare_dest = 0;
139 int basis_dir_cnt = 0;
143 int always_checksum = 0;
146 #define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
147 char *batch_name = NULL;
149 static int daemon_opt; /* sets am_daemon after option error-reporting */
150 static int F_option_cnt = 0;
151 static int modify_window_set;
152 static int refused_verbose, refused_delete, refused_archive_part;
153 static int refused_partial, refused_progress;
154 static char *dest_option = NULL;
155 static char *max_size_arg;
156 static char partialdir_for_delayupdate[] = ".~tmp~";
158 /** Local address to bind. As a character string because it's
159 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
160 * address, or a hostname. **/
164 static void print_rsync_version(enum logcode f)
166 char const *got_socketpair = "no ";
167 char const *have_inplace = "no ";
168 char const *hardlinks = "no ";
169 char const *links = "no ";
170 char const *ipv6 = "no ";
171 STRUCT_STAT *dumstat;
181 #if SUPPORT_HARD_LINKS
193 rprintf(f, "%s version %s protocol version %d\n",
194 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
196 "Copyright (C) 1996-2005 by Andrew Tridgell and others\n");
197 rprintf(f, "<http://rsync.samba.org/>\n");
198 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
199 "%shard links, %ssymlinks, batchfiles, \n",
200 (int) (sizeof (OFF_T) * 8),
201 got_socketpair, hardlinks, links);
203 /* Note that this field may not have type ino_t. It depends
204 * on the complicated interaction between largefile feature
206 rprintf(f, " %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
208 (int) (sizeof dumstat->st_ino * 8),
209 (int) (sizeof (int64) * 8));
210 #ifdef MAINTAINER_MODE
211 rprintf(f, " panic action: \"%s\"\n",
216 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
218 if (sizeof (int64) != SIZEOF_INT64) {
220 "WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
221 (int) SIZEOF_INT64, (int) sizeof (int64));
226 "rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
227 "are welcome to redistribute it under certain conditions. See the GNU\n"
228 "General Public Licence for details.\n"
233 void usage(enum logcode F)
235 print_rsync_version(F);
237 rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
239 rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
240 rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
241 rprintf(F," or rsync [OPTION]... SRC [SRC]... DEST\n");
242 rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
243 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
244 rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
245 rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
246 rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
247 rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
248 rprintf(F," sources separated by space as long as they have same top-level\n");
249 rprintf(F,"\nOptions\n");
250 rprintf(F," -v, --verbose increase verbosity\n");
251 rprintf(F," -q, --quiet suppress non-error messages\n");
252 rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n");
253 rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H)\n");
254 rprintf(F," -r, --recursive recurse into directories\n");
255 rprintf(F," -R, --relative use relative path names\n");
256 rprintf(F," --no-relative turn off --relative\n");
257 rprintf(F," --no-implied-dirs don't send implied dirs with -R\n");
258 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
259 rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
260 rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
261 rprintf(F," -u, --update skip files that are newer on the receiver\n");
262 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
263 rprintf(F," -d, --dirs transfer directories without recursing\n");
264 rprintf(F," -l, --links copy symlinks as symlinks\n");
265 rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
266 rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n");
267 rprintf(F," --safe-links ignore symlinks that point outside the source tree\n");
268 rprintf(F," -H, --hard-links preserve hard links\n");
269 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
270 rprintf(F," -p, --perms preserve permissions\n");
271 rprintf(F," -o, --owner preserve owner (root only)\n");
272 rprintf(F," -g, --group preserve group\n");
273 rprintf(F," -D, --devices preserve devices (root only)\n");
274 rprintf(F," -t, --times preserve times\n");
275 rprintf(F," -O, --omit-dir-times omit directories when preserving times\n");
276 rprintf(F," -S, --sparse handle sparse files efficiently\n");
277 rprintf(F," -n, --dry-run show what would have been transferred\n");
278 rprintf(F," -W, --whole-file copy files whole\n");
279 rprintf(F," --no-whole-file always use incremental rsync algorithm\n");
280 rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
281 rprintf(F," -B, --block-size=SIZE force a fixed checksum block-size\n");
282 rprintf(F," -e, --rsh=COMMAND specify the remote shell to use\n");
283 rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
284 rprintf(F," --existing only update files that already exist on receiver\n");
285 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
286 rprintf(F," --del an alias for --delete-during\n");
287 rprintf(F," --delete delete files that don't exist on the sending side\n");
288 rprintf(F," --delete-before receiver deletes before transfer (default)\n");
289 rprintf(F," --delete-during receiver deletes during transfer, not before\n");
290 rprintf(F," --delete-after receiver deletes after transfer, not before\n");
291 rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
292 rprintf(F," --ignore-errors delete even if there are I/O errors\n");
293 rprintf(F," --force force deletion of directories even if not empty\n");
294 rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
295 rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n");
296 rprintf(F," --partial keep partially transferred files\n");
297 rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
298 rprintf(F," --delay-updates put all updated files into place at transfer's end\n");
299 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
300 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
301 rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
302 rprintf(F," --size-only skip files that match in size\n");
303 rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
304 rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
305 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
306 rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
307 rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
308 rprintf(F," -z, --compress compress file data during the transfer\n");
309 rprintf(F," -C, --cvs-exclude auto-ignore files the same way CVS does\n");
310 rprintf(F," -f, --filter=RULE add a file-filtering RULE\n");
311 rprintf(F," -F same as --filter=': /.rsync-filter'\n");
312 rprintf(F," repeated: --filter='- .rsync-filter'\n");
313 rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
314 rprintf(F," --exclude-from=FILE read exclude patterns from FILE\n");
315 rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
316 rprintf(F," --include-from=FILE read include patterns from FILE\n");
317 rprintf(F," --files-from=FILE read list of source-file names from FILE\n");
318 rprintf(F," -0, --from0 all *-from file lists are delimited by nulls\n");
319 rprintf(F," --version print version number\n");
320 rprintf(F," --port=PORT specify double-colon alternate port number\n");
321 rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
322 rprintf(F," --no-blocking-io turn off blocking I/O when it is the default\n");
323 rprintf(F," --stats give some file-transfer stats\n");
324 rprintf(F," --progress show progress during transfer\n");
325 rprintf(F," -P same as --partial --progress\n");
326 rprintf(F," --log-format=FORMAT log file-transfers using specified format\n");
327 rprintf(F," --password-file=FILE read password from FILE\n");
328 rprintf(F," --list-only list the files instead of copying them\n");
329 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
330 rprintf(F," --write-batch=FILE write a batched update to FILE\n");
331 rprintf(F," --read-batch=FILE read a batched update from FILE\n");
333 rprintf(F," -4, --ipv4 prefer IPv4\n");
334 rprintf(F," -6, --ipv6 prefer IPv6\n");
336 rprintf(F," -h, --help show this help screen\n");
338 rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
339 rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
340 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
343 enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
344 OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
345 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
346 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
347 OPT_REFUSED_BASE = 9000};
349 static struct poptOption long_options[] = {
350 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
351 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
352 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
353 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
354 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
355 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
356 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
357 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
358 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
359 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
360 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
361 {"del", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
362 {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
363 {"delete-before", 0, POPT_ARG_VAL, &delete_before, 2, 0, 0 },
364 {"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
365 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
366 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
367 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
368 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
369 {"filter", 'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
370 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
371 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
372 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
373 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
374 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
375 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
376 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
377 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
378 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
379 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
380 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
381 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
382 {"dirs", 'd', POPT_ARG_VAL, &xfer_dirs, 2, 0, 0 },
383 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
384 {"copy-links", 'L', POPT_ARG_NONE, ©_links, 0, 0, 0 },
385 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
386 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
387 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
388 {"copy-unsafe-links", 0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 },
389 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
390 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
391 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
392 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
393 {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
394 {"omit-dir-times", 'O', POPT_ARG_NONE, &omit_dir_times, 0, 0, 0 },
395 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
396 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
397 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
398 {"archive", 'a', POPT_ARG_NONE, &archive_mode, 0, 0, 0 },
399 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
400 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
401 {"recursive", 'r', POPT_ARG_VAL, &recurse, -1, 0, 0 },
402 {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
403 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
404 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
405 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
406 {"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
407 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
408 {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
409 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
410 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
411 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
412 {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
413 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
414 /* TODO: Should this take an optional int giving the compression level? */
415 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
416 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
417 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
418 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
419 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
420 {"delay-updates", 0, POPT_ARG_NONE, &delay_updates, 0, 0, 0 },
421 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
422 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
423 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
424 {0, 'F', POPT_ARG_NONE, 0, 'F', 0, 0 },
425 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
426 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
427 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
428 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
429 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
430 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
431 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
432 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
433 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
434 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
435 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
436 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
437 {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
439 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
440 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
442 /* All these options switch us into daemon-mode option-parsing. */
443 {"address", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
444 {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
445 {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
446 {"no-detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
450 static void daemon_usage(enum logcode F)
452 print_rsync_version(F);
454 rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
455 rprintf(F," --address=ADDRESS bind to the specified address\n");
456 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
457 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
458 rprintf(F," --no-detach do not detach from the parent\n");
459 rprintf(F," --port=PORT listen on alternate port number\n");
460 rprintf(F," -v, --verbose increase verbosity\n");
462 rprintf(F," -4, --ipv4 prefer IPv4\n");
463 rprintf(F," -6, --ipv6 prefer IPv6\n");
465 rprintf(F," -h, --help show this help screen\n");
467 rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
468 rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
471 static struct poptOption long_daemon_options[] = {
472 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
473 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
474 {"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
475 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
476 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
478 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
479 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
481 {"no-detach", 0, POPT_ARG_NONE, &no_detach, 0, 0, 0 },
482 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
483 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
484 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
485 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
486 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
491 static char err_buf[200];
495 * Store the option error message, if any, so that we can log the
496 * connection attempt (which requires parsing the options), and then
497 * show the error later on.
499 void option_error(void)
502 strcpy(err_buf, "Error parsing options: "
503 "option may be supported on client but not on server?\n");
506 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
511 * Tweak the option table to disable all options that the rsyncd.conf
512 * file has told us to refuse.
514 static void set_refuse_options(char *bp)
516 struct poptOption *op;
517 char *cp, shortname[2];
518 int is_wild, found_match;
523 while (*bp == ' ') bp++;
526 if ((cp = strchr(bp, ' ')) != NULL)
528 is_wild = strpbrk(bp, "*?[") != NULL;
530 for (op = long_options; ; op++) {
531 *shortname = op->shortName;
532 if (!op->longName && !*shortname)
534 if ((op->longName && wildmatch(bp, op->longName))
535 || (*shortname && wildmatch(bp, shortname))
536 || op->val == OPT_DAEMON) {
537 if (op->argInfo == POPT_ARG_VAL)
538 op->argInfo = POPT_ARG_NONE;
539 op->val = (op - long_options) + OPT_REFUSED_BASE;
541 /* These flags are set to let us easily check
542 * an implied option later in the code. */
543 switch (*shortname) {
545 refused_verbose = op->val;
547 case 'r': case 'd': case 'l': case 'p':
548 case 't': case 'g': case 'o': case 'D':
549 refused_archive_part = op->val;
552 if (wildmatch("delete", op->longName))
553 refused_delete = op->val;
554 else if (wildmatch("partial", op->longName))
555 refused_partial = op->val;
556 else if (wildmatch("progress", op->longName))
557 refused_progress = op->val;
565 rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
576 static int count_args(const char **argv)
581 while (argv[i] != NULL)
589 static void create_refuse_error(int which)
591 /* The "which" value is the index + OPT_REFUSED_BASE. */
592 struct poptOption *op = &long_options[which - OPT_REFUSED_BASE];
593 int n = snprintf(err_buf, sizeof err_buf,
594 "The server is configured to refuse --%s\n",
597 snprintf(err_buf + n, sizeof err_buf - n,
598 " (-%c)\n", op->shortName);
604 * Process command line arguments. Called on both local and remote.
606 * @retval 1 if all options are OK; with globals set to appropriate
609 * @retval 0 on error, with err_buf containing an explanation
611 int parse_arguments(int *argc, const char ***argv, int frommain)
614 char *ref = lp_refuse_options(module_id);
619 set_refuse_options(ref);
621 /* TODO: Call poptReadDefaultConfig; handle errors. */
623 /* The context leaks in case of an error, but if there's a
624 * problem we always exit anyhow. */
625 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
626 poptReadDefaultConfig(pc, 0);
628 while ((opt = poptGetNextOpt(pc)) != -1) {
629 /* most options are handled automatically by popt;
630 * only special cases are returned and listed here. */
634 print_rsync_version(FINFO);
639 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
643 pc = poptGetContext(RSYNC_NAME, *argc, *argv,
644 long_daemon_options, 0);
645 while ((opt = poptGetNextOpt(pc)) != -1) {
657 "rsync: %s: %s (in daemon mode)\n",
658 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
664 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
667 "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
668 exit_cleanup(RERR_SYNTAX);
670 *argv = poptGetArgs(pc);
671 *argc = count_args(*argv);
676 case OPT_MODIFY_WINDOW:
677 /* The value has already been set by popt, but
678 * we need to remember that we're using a
679 * non-default setting. */
680 modify_window_set = 1;
684 parse_rule(&filter_list, poptGetOptArg(pc), 0, 0);
688 parse_rule(&filter_list, poptGetOptArg(pc),
689 0, XFLG_OLD_PREFIXES);
693 parse_rule(&filter_list, poptGetOptArg(pc),
694 MATCHFLG_INCLUDE, XFLG_OLD_PREFIXES);
697 case OPT_EXCLUDE_FROM:
698 case OPT_INCLUDE_FROM:
699 arg = poptGetOptArg(pc);
701 arg = sanitize_path(NULL, arg, NULL, 0);
702 if (server_filter_list.head) {
703 char *cp = (char *)arg;
705 goto options_rejected;
707 if (check_filter(&server_filter_list, cp, 0) < 0)
708 goto options_rejected;
710 parse_filter_file(&filter_list, arg,
711 opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
712 XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
731 exit_cleanup(RERR_SYNTAX);
737 switch (++F_option_cnt) {
739 parse_rule(&filter_list,": /.rsync-filter",0,0);
742 parse_rule(&filter_list,"- .rsync-filter",0,0);
748 if (refused_partial || refused_progress) {
749 create_refuse_error(refused_partial
750 ? refused_partial : refused_progress);
757 case OPT_WRITE_BATCH:
758 /* batch_name is already set */
763 /* batch_name is already set */
768 for (arg = max_size_arg; isdigit(*(uchar*)arg); arg++) {}
770 for (arg++; isdigit(*(uchar*)arg); arg++) {}
773 max_size = atof(max_size_arg) * 1024;
776 max_size = atof(max_size_arg) * 1024*1024;
779 max_size = atof(max_size_arg) * 1024*1024*1024;
782 max_size = atof(max_size_arg);
789 snprintf(err_buf, sizeof err_buf,
790 "--max-size value is invalid: %s\n",
797 if (io_timeout && io_timeout < select_timeout)
798 select_timeout = io_timeout;
804 dest_option = "--link-dest";
807 snprintf(err_buf, sizeof err_buf,
808 "hard links are not supported on this %s\n",
809 am_server ? "server" : "client");
815 dest_option = "--copy-dest";
818 case OPT_COMPARE_DEST:
820 dest_option = "--compare-dest";
822 if (basis_dir_cnt >= MAX_BASIS_DIRS) {
823 snprintf(err_buf, sizeof err_buf,
824 "ERROR: at most %d %s args may be specified\n",
825 MAX_BASIS_DIRS, dest_option);
828 arg = poptGetOptArg(pc);
830 arg = sanitize_path(NULL, arg, NULL, 0);
831 basis_dir[basis_dir_cnt++] = (char *)arg;
835 /* A large opt value means that set_refuse_options()
836 * turned this option off. */
837 if (opt >= OPT_REFUSED_BASE) {
838 create_refuse_error(opt);
841 snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
842 am_server ? "on remote machine: " : "",
843 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
853 if (preserve_links && !am_sender) {
854 snprintf(err_buf, sizeof err_buf,
855 "symlinks are not supported on this %s\n",
856 am_server ? "server" : "client");
861 #if !SUPPORT_HARD_LINKS
862 if (preserve_hard_links) {
863 snprintf(err_buf, sizeof err_buf,
864 "hard links are not supported on this %s\n",
865 am_server ? "server" : "client");
870 if (write_batch && read_batch) {
871 snprintf(err_buf, sizeof err_buf,
872 "--write-batch and --read-batch can not be used together\n");
875 if (write_batch || read_batch) {
877 snprintf(err_buf, sizeof err_buf,
878 "--%s-batch cannot be used with --dry_run (-n)\n",
879 write_batch ? "write" : "read");
884 "ignoring --%s-batch option sent to server\n",
885 write_batch ? "write" : "read");
886 /* We don't actually exit_cleanup(), so that we can
887 * still service older version clients that still send
888 * batch args to server. */
889 read_batch = write_batch = 0;
893 if (read_batch && files_from) {
894 snprintf(err_buf, sizeof err_buf,
895 "--read-batch cannot be used with --files-from\n");
898 if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
899 snprintf(err_buf, sizeof err_buf,
900 "the batch-file name must be %d characters or less.\n",
905 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
906 snprintf(err_buf, sizeof err_buf,
907 "the --temp-dir path is WAY too long.\n");
911 if (compare_dest + copy_dest + link_dest > 1) {
912 snprintf(err_buf, sizeof err_buf,
913 "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
918 if (refused_archive_part) {
919 create_refuse_error(refused_archive_part);
923 recurse = -1; /* infinite recursion */
931 preserve_devices = 1;
934 if (recurse || list_only || files_from)
937 if (relative_paths < 0)
938 relative_paths = files_from? 1 : 0;
940 if (!!delete_before + delete_during + delete_after > 1) {
941 snprintf(err_buf, sizeof err_buf,
942 "You may not combine multiple --delete-WHEN options.\n");
946 delete_before = delete_during = delete_after = 0;
947 delete_mode = delete_excluded = 0;
948 } else if (delete_before || delete_during || delete_after)
950 else if (delete_mode || delete_excluded)
951 delete_mode = delete_before = 1;
953 if (delete_mode && refused_delete) {
954 create_refuse_error(refused_delete);
958 *argv = poptGetArgs(pc);
959 *argc = count_args(*argv);
961 if (sanitize_paths) {
963 for (i = *argc; i-- > 0; )
964 (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
966 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
968 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
970 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
972 files_from = sanitize_path(NULL, files_from, NULL, 0);
974 if (server_filter_list.head && !am_sender) {
975 struct filter_list_struct *elp = &server_filter_list;
979 goto options_rejected;
980 clean_fname(tmpdir, 1);
981 if (check_filter(elp, tmpdir, 1) < 0)
982 goto options_rejected;
984 if (partial_dir && *partial_dir) {
985 clean_fname(partial_dir, 1);
986 if (check_filter(elp, partial_dir, 1) < 0)
987 goto options_rejected;
989 for (i = 0; i < basis_dir_cnt; i++) {
991 goto options_rejected;
992 clean_fname(basis_dir[i], 1);
993 if (check_filter(elp, basis_dir[i], 1) < 0)
994 goto options_rejected;
998 goto options_rejected;
999 clean_fname(backup_dir, 1);
1000 if (check_filter(elp, backup_dir, 1) < 0)
1001 goto options_rejected;
1004 if (server_filter_list.head && files_from) {
1006 goto options_rejected;
1007 clean_fname(files_from, 1);
1008 if (check_filter(&server_filter_list, files_from, 0) < 0) {
1010 snprintf(err_buf, sizeof err_buf,
1011 "Your options have been rejected by the server.\n");
1017 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
1018 backup_suffix_len = strlen(backup_suffix);
1019 if (strchr(backup_suffix, '/') != NULL) {
1020 snprintf(err_buf, sizeof err_buf,
1021 "--suffix cannot contain slashes: %s\n",
1026 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
1027 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
1028 if (backup_dir_remainder < 32) {
1029 snprintf(err_buf, sizeof err_buf,
1030 "the --backup-dir path is WAY too long.\n");
1033 if (backup_dir_buf[backup_dir_len - 1] != '/') {
1034 backup_dir_buf[backup_dir_len++] = '/';
1035 backup_dir_buf[backup_dir_len] = '\0';
1037 if (verbose > 1 && !am_sender) {
1038 rprintf(FINFO, "backup_dir is %s\n",
1039 safe_fname(backup_dir_buf));
1041 } else if (!backup_suffix_len && (!am_server || !am_sender)) {
1042 snprintf(err_buf, sizeof err_buf,
1043 "--suffix cannot be a null string without --backup-dir\n");
1047 if (do_progress && !verbose) {
1048 if (refused_verbose) {
1049 create_refuse_error(refused_verbose);
1055 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1056 bwlimit = daemon_bwlimit;
1058 bwlimit_writemax = (size_t)bwlimit * 128;
1059 if (bwlimit_writemax < 512)
1060 bwlimit_writemax = 512;
1063 if (delay_updates && !partial_dir)
1064 partial_dir = partialdir_for_delayupdate;
1069 snprintf(err_buf, sizeof err_buf,
1070 "--inplace cannot be used with --%s\n",
1071 delay_updates ? "delay-updates" : "partial-dir");
1074 /* --inplace implies --partial for refusal purposes, but we
1075 * clear the keep_partial flag for internal logic purposes. */
1076 if (refused_partial) {
1077 create_refuse_error(refused_partial);
1082 snprintf(err_buf, sizeof err_buf,
1083 "--inplace is not supported on this %s\n",
1084 am_server ? "server" : "client");
1088 if (keep_partial && !partial_dir) {
1089 if ((arg = getenv("RSYNC_PARTIAL_DIR")) != NULL && *arg)
1090 partial_dir = strdup(arg);
1094 clean_fname(partial_dir, 1);
1095 if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1097 else if (*partial_dir != '/') {
1098 parse_rule(&filter_list, partial_dir,
1099 MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
1101 if (!partial_dir && refused_partial) {
1102 create_refuse_error(refused_partial);
1111 if (*argc > 2 || (!am_daemon && *argc == 1)) {
1113 exit_cleanup(RERR_SYNTAX);
1115 if (strcmp(files_from, "-") == 0) {
1118 remote_filesfrom_file = "-";
1120 else if ((colon = find_colon(files_from)) != 0) {
1123 exit_cleanup(RERR_SYNTAX);
1125 remote_filesfrom_file = colon+1 + (colon[1] == ':');
1126 if (strcmp(remote_filesfrom_file, "-") == 0) {
1127 snprintf(err_buf, sizeof err_buf,
1128 "Invalid --files-from remote filename\n");
1132 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1133 if (filesfrom_fd < 0) {
1134 snprintf(err_buf, sizeof err_buf,
1135 "failed to open files-from file %s: %s\n",
1136 files_from, strerror(errno));
1147 * Construct a filtered list of options to pass through from the
1148 * client to the server.
1150 * This involves setting options that will tell the server how to
1151 * behave, and also filtering out options that are processed only
1154 void server_options(char **args,int *argc)
1156 static char argstr[50+MAX_BASIS_DIRS*2];
1162 if (blocking_io == -1)
1165 args[ac++] = "--server";
1167 if (daemon_over_rsh) {
1168 args[ac++] = "--daemon";
1170 /* if we're passing --daemon, we're done */
1175 args[ac++] = "--sender";
1179 for (i = 0; i < verbose; i++)
1182 /* the -q option is intentionally left out */
1195 if (keep_dirlinks && am_sender)
1200 /* We don't need to send --no-whole-file, because it's the
1201 * default for remote transfers, and in any case old versions
1202 * of rsync will not understand it. */
1204 if (preserve_hard_links)
1210 if (preserve_devices)
1214 if (omit_dir_times && am_sender)
1220 if (always_checksum)
1228 if (one_file_system)
1235 /* This is a complete hack - blame Rusty. FIXME!
1236 * This hack is only needed for older rsync versions that
1237 * don't understand the --list-only option. */
1238 if (list_only == 1 && recurse >= 0)
1244 args[ac++] = argstr;
1247 args[ac++] = "--list-only";
1250 if (asprintf(&arg, "-B%lu", block_size) < 0)
1255 if (max_delete && am_sender) {
1256 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1261 if (max_size && am_sender) {
1262 args[ac++] = "--max-size";
1263 args[ac++] = max_size_arg;
1267 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1273 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1279 args[ac++] = "--backup-dir";
1280 args[ac++] = backup_dir;
1283 /* Only send --suffix if it specifies a non-default value. */
1284 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1285 /* We use the following syntax to avoid weirdness with '~'. */
1286 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1292 if (delete_excluded)
1293 args[ac++] = "--delete-excluded";
1294 else if (delete_before == 1 || delete_after)
1295 args[ac++] = "--delete";
1296 if (delete_before > 1)
1297 args[ac++] = "--delete-before";
1299 args[ac++] = "--delete-during";
1301 args[ac++] = "--delete-after";
1303 args[ac++] = "--force";
1307 args[ac++] = "--size-only";
1309 if (modify_window_set) {
1310 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1315 if (checksum_seed) {
1316 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1321 if (partial_dir && am_sender) {
1322 if (partial_dir != partialdir_for_delayupdate) {
1323 args[ac++] = "--partial-dir";
1324 args[ac++] = partial_dir;
1327 args[ac++] = "--delay-updates";
1328 } else if (keep_partial)
1329 args[ac++] = "--partial";
1332 args[ac++] = "--ignore-errors";
1334 if (copy_unsafe_links)
1335 args[ac++] = "--copy-unsafe-links";
1338 args[ac++] = "--safe-links";
1341 args[ac++] = "--numeric-ids";
1343 if (only_existing && am_sender)
1344 args[ac++] = "--existing";
1346 if (opt_ignore_existing && am_sender)
1347 args[ac++] = "--ignore-existing";
1350 args[ac++] = "--inplace";
1353 args[ac++] = "--temp-dir";
1354 args[ac++] = tmpdir;
1357 if (basis_dir[0] && am_sender) {
1358 /* the server only needs this option if it is not the sender,
1359 * and it may be an older version that doesn't know this
1360 * option, so don't send it if client is the sender.
1363 for (i = 0; i < basis_dir_cnt; i++) {
1364 args[ac++] = dest_option;
1365 args[ac++] = basis_dir[i];
1369 if (files_from && (!am_sender || remote_filesfrom_file)) {
1370 if (remote_filesfrom_file) {
1371 args[ac++] = "--files-from";
1372 args[ac++] = remote_filesfrom_file;
1374 args[ac++] = "--from0";
1376 args[ac++] = "--files-from=-";
1377 args[ac++] = "--from0";
1379 if (!relative_paths)
1380 args[ac++] = "--no-relative";
1382 if (!implied_dirs && !am_sender)
1383 args[ac++] = "--no-implied-dirs";
1389 out_of_memory("server_options");
1393 * Return the position of a ':' IF it is not part of a filename (i.e. as
1394 * long as it doesn't occur after a slash.
1396 char *find_colon(char *s)
1404 /* now check to see if there is a / in the string before the : - if there is then
1405 discard the colon on the assumption that the : is part of a filename */