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.
24 extern int sanitize_paths;
25 extern int select_timeout;
26 extern struct exclude_list_struct exclude_list;
27 extern struct exclude_list_struct server_exclude_list;
32 * If 1, send the whole file as literal data rather than trying to
33 * create an incremental diff.
35 * If -1, then look at whether we're local or remote and go by that.
37 * @sa disable_deltas_p()
42 int keep_dirlinks = 0;
44 int preserve_links = 0;
45 int preserve_hard_links = 0;
46 int preserve_perms = 0;
47 int preserve_devices = 0;
50 int preserve_times = 0;
57 int delete_before = 0;
59 int delete_excluded = 0;
60 int one_file_system = 0;
61 int protocol_version = PROTOCOL_VERSION;
63 int do_compression = 0;
66 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 long block_size = 0; /* "long" because popt can't set an int32. */
105 /** Network address family. **/
107 int default_af_hint = 0; /* Any protocol */
109 int default_af_hint = AF_INET; /* Must use IPv4 */
112 /** Do not go into the background when run as --daemon. Good
113 * for debugging and required for running as a service on W32,
114 * or under Unix process-monitors. **/
119 int backup_dir_len = 0;
120 int backup_suffix_len;
121 unsigned int backup_dir_remainder;
123 char *backup_suffix = NULL;
125 char *partial_dir = NULL;
126 char *basis_dir[MAX_BASIS_DIRS+1];
127 char *config_file = NULL;
128 char *shell_cmd = NULL;
129 char *log_format = NULL;
130 char *password_file = NULL;
131 char *rsync_path = RSYNC_PATH;
132 char *backup_dir = NULL;
133 char backup_dir_buf[MAXPATHLEN];
135 int compare_dest = 0;
138 int basis_dir_cnt = 0;
142 int always_checksum = 0;
145 #define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
146 char *batch_name = NULL;
148 static int daemon_opt; /* sets am_daemon after option error-reporting */
149 static int modify_window_set;
150 static char *dest_option = NULL;
151 static char *max_size_arg;
153 /** Local address to bind. As a character string because it's
154 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
155 * address, or a hostname. **/
159 static void print_rsync_version(enum logcode f)
161 char const *got_socketpair = "no ";
162 char const *have_inplace = "no ";
163 char const *hardlinks = "no ";
164 char const *links = "no ";
165 char const *ipv6 = "no ";
166 STRUCT_STAT *dumstat;
168 #ifdef HAVE_SOCKETPAIR
176 #if SUPPORT_HARD_LINKS
188 rprintf(f, "%s version %s protocol version %d\n",
189 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
191 "Copyright (C) 1996-2004 by Andrew Tridgell and others\n");
192 rprintf(f, "<http://rsync.samba.org/>\n");
193 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
194 "%shard links, %ssymlinks, batchfiles, \n",
195 (int) (sizeof (OFF_T) * 8),
196 got_socketpair, hardlinks, links);
198 /* Note that this field may not have type ino_t. It depends
199 * on the complicated interaction between largefile feature
201 rprintf(f, " %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
203 (int) (sizeof dumstat->st_ino * 8),
204 (int) (sizeof (int64) * 8));
205 #ifdef MAINTAINER_MODE
206 rprintf(f, " panic action: \"%s\"\n",
210 #ifdef INT64_IS_OFF_T
211 if (sizeof (int64) < 8)
212 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
217 "rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
218 "are welcome to redistribute it under certain conditions. See the GNU\n"
219 "General Public Licence for details.\n"
224 void usage(enum logcode F)
226 print_rsync_version(F);
228 rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
230 rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
231 rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
232 rprintf(F," or rsync [OPTION]... SRC [SRC]... DEST\n");
233 rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
234 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
235 rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
236 rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
237 rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
238 rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
239 rprintf(F," sources separated by space as long as they have same top-level\n");
240 rprintf(F,"\nOptions\n");
241 rprintf(F," -v, --verbose increase verbosity\n");
242 rprintf(F," -q, --quiet decrease verbosity\n");
243 rprintf(F," -c, --checksum always checksum\n");
244 rprintf(F," -a, --archive archive mode, equivalent to -rlptgoD (no -H)\n");
245 rprintf(F," -r, --recursive recurse into directories\n");
246 rprintf(F," -R, --relative use relative path names\n");
247 rprintf(F," --no-relative turn off --relative\n");
248 rprintf(F," --no-implied-dirs don't send implied dirs with -R\n");
249 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
250 rprintf(F," --backup-dir make backups into this directory\n");
251 rprintf(F," --suffix=SUFFIX backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
252 rprintf(F," -u, --update update only (don't overwrite newer files)\n");
253 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
254 rprintf(F," -d, --dirs transfer directories without recursing\n");
255 rprintf(F," -l, --links copy symlinks as symlinks\n");
256 rprintf(F," -L, --copy-links copy the referent of all symlinks\n");
257 rprintf(F," --copy-unsafe-links copy the referent of \"unsafe\" symlinks\n");
258 rprintf(F," --safe-links ignore \"unsafe\" symlinks\n");
259 rprintf(F," -H, --hard-links preserve hard links\n");
260 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
261 rprintf(F," -p, --perms preserve permissions\n");
262 rprintf(F," -o, --owner preserve owner (root only)\n");
263 rprintf(F," -g, --group preserve group\n");
264 rprintf(F," -D, --devices preserve devices (root only)\n");
265 rprintf(F," -t, --times preserve times\n");
266 rprintf(F," -S, --sparse handle sparse files efficiently\n");
267 rprintf(F," -n, --dry-run show what would have been transferred\n");
268 rprintf(F," -W, --whole-file copy whole files, no incremental checks\n");
269 rprintf(F," --no-whole-file turn off --whole-file\n");
270 rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
271 rprintf(F," -B, --block-size=SIZE force a fixed checksum block-size\n");
272 rprintf(F," -e, --rsh=COMMAND specify the remote shell\n");
273 rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
274 rprintf(F," --existing only update files that already exist\n");
275 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
276 rprintf(F," --delete delete files that don't exist on the sending side\n");
277 rprintf(F," --delete-after receiver deletes after transferring, not before\n");
278 rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
279 rprintf(F," --ignore-errors delete even if there are I/O errors\n");
280 rprintf(F," --force force deletion of directories even if not empty\n");
281 rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
282 rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n");
283 rprintf(F," --partial keep partially transferred files\n");
284 rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
285 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
286 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
287 rprintf(F," -I, --ignore-times turn off mod time & file size quick check\n");
288 rprintf(F," --size-only ignore mod time for quick check (use size)\n");
289 rprintf(F," --modify-window=NUM compare mod times with reduced accuracy\n");
290 rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
291 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
292 rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
293 rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
294 rprintf(F," -P equivalent to --partial --progress\n");
295 rprintf(F," -z, --compress compress file data\n");
296 rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
297 rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
298 rprintf(F," --exclude-from=FILE exclude patterns listed in FILE\n");
299 rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
300 rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n");
301 rprintf(F," --files-from=FILE read FILE for list of source-file names\n");
302 rprintf(F," -0, --from0 all *-from file lists are delimited by nulls\n");
303 rprintf(F," --version print version number\n");
304 rprintf(F," --port=PORT specify double-colon alternate port number\n");
305 rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
306 rprintf(F," --no-blocking-io turn off --blocking-io\n");
307 rprintf(F," --stats give some file transfer stats\n");
308 rprintf(F," --progress show progress during transfer\n");
309 rprintf(F," --log-format=FORMAT log file transfers using specified format\n");
310 rprintf(F," --password-file=FILE get password from FILE\n");
311 rprintf(F," --list-only list the files instead of copying them\n");
312 rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
313 rprintf(F," --write-batch=FILE write a batch to FILE\n");
314 rprintf(F," --read-batch=FILE read a batch from FILE\n");
316 rprintf(F," -4, --ipv4 prefer IPv4\n");
317 rprintf(F," -6, --ipv6 prefer IPv6\n");
319 rprintf(F," -h, --help show this help screen\n");
321 rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
322 rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
323 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
326 enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
327 OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
328 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
329 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
330 OPT_REFUSED_BASE = 9000};
332 static struct poptOption long_options[] = {
333 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
334 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
335 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
336 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
337 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
338 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
339 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
340 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
341 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
342 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
343 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
344 {"delete", 0, POPT_ARG_NONE, &delete_before, 0, 0, 0 },
345 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
346 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
347 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
348 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
349 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
350 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
351 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
352 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
353 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
354 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
355 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
356 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
357 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
358 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
359 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
360 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
361 {"dirs", 'd', POPT_ARG_VAL, &xfer_dirs, 2, 0, 0 },
362 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
363 {"copy-links", 'L', POPT_ARG_NONE, ©_links, 0, 0, 0 },
364 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
365 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
366 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
367 {"copy-unsafe-links", 0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 },
368 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
369 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
370 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
371 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
372 {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
373 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
374 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
375 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
376 {"archive", 'a', POPT_ARG_NONE, &archive_mode, 0, 0, 0 },
377 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
378 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
379 {"recursive", 'r', POPT_ARG_VAL, &recurse, -1, 0, 0 },
380 {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
381 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
382 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
383 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
384 {"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
385 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
386 {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
387 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
388 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
389 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
390 {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
391 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
392 /* TODO: Should this take an optional int giving the compression level? */
393 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
394 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
395 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
396 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
397 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
398 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
399 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
400 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
401 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
402 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
403 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
404 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
405 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
406 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
407 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
408 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
409 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
410 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
411 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
412 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
413 {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
415 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
416 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
418 /* All these options switch us into daemon-mode option-parsing. */
419 {"address", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
420 {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
421 {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
422 {"no-detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
426 static void daemon_usage(enum logcode F)
428 print_rsync_version(F);
430 rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
431 rprintf(F," --address=ADDRESS bind to the specified address\n");
432 rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
433 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
434 rprintf(F," --no-detach do not detach from the parent\n");
435 rprintf(F," --port=PORT specify alternate rsyncd port number\n");
437 rprintf(F," -4, --ipv4 prefer IPv4\n");
438 rprintf(F," -6, --ipv6 prefer IPv6\n");
440 rprintf(F," -h, --help show this help screen\n");
442 rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
443 rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
446 static struct poptOption long_daemon_options[] = {
447 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
448 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
449 {"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
450 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
451 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
453 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
454 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
456 {"no-detach", 0, POPT_ARG_NONE, &no_detach, 0, 0, 0 },
457 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
458 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
459 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
460 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
465 static char err_buf[200];
469 * Store the option error message, if any, so that we can log the
470 * connection attempt (which requires parsing the options), and then
471 * show the error later on.
473 void option_error(void)
476 strcpy(err_buf, "Error parsing options: "
477 "option may be supported on client but not on server?\n");
480 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
485 * Tweak the option table to disable all options that the rsyncd.conf
486 * file has told us to refuse.
488 static void set_refuse_options(char *bp)
490 struct poptOption *op;
491 char *cp, shortname[2];
492 int is_wild, found_match;
497 while (*bp == ' ') bp++;
500 if ((cp = strchr(bp, ' ')) != NULL)
502 /* If they specify "delete", reject all delete options. */
503 if (strcmp(bp, "delete") == 0)
505 is_wild = strpbrk(bp, "*?[") != NULL;
507 for (op = long_options; ; op++) {
508 *shortname = op->shortName;
509 if (!op->longName && !*shortname)
511 if ((op->longName && wildmatch(bp, op->longName))
512 || (*shortname && wildmatch(bp, shortname))) {
513 if (op->argInfo == POPT_ARG_VAL)
514 op->argInfo = POPT_ARG_NONE;
515 op->val = (op - long_options) + OPT_REFUSED_BASE;
522 rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
533 static int count_args(const char **argv)
538 while (argv[i] != NULL)
547 * Process command line arguments. Called on both local and remote.
549 * @retval 1 if all options are OK; with globals set to appropriate
552 * @retval 0 on error, with err_buf containing an explanation
554 int parse_arguments(int *argc, const char ***argv, int frommain)
557 char *ref = lp_refuse_options(module_id);
562 set_refuse_options(ref);
564 /* TODO: Call poptReadDefaultConfig; handle errors. */
566 /* The context leaks in case of an error, but if there's a
567 * problem we always exit anyhow. */
568 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
569 poptReadDefaultConfig(pc, 0);
571 while ((opt = poptGetNextOpt(pc)) != -1) {
572 /* most options are handled automatically by popt;
573 * only special cases are returned and listed here. */
577 print_rsync_version(FINFO);
582 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
586 pc = poptGetContext(RSYNC_NAME, *argc, *argv,
587 long_daemon_options, 0);
588 while ((opt = poptGetNextOpt(pc)) != -1) {
596 "rsync: %s: %s (in daemon mode)\n",
597 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
603 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
606 "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
607 exit_cleanup(RERR_SYNTAX);
609 *argv = poptGetArgs(pc);
610 *argc = count_args(*argv);
615 case OPT_MODIFY_WINDOW:
616 /* The value has already been set by popt, but
617 * we need to remember that we're using a
618 * non-default setting. */
619 modify_window_set = 1;
623 add_exclude(&exclude_list, poptGetOptArg(pc), 0);
627 add_exclude(&exclude_list, poptGetOptArg(pc),
631 case OPT_EXCLUDE_FROM:
632 case OPT_INCLUDE_FROM:
633 arg = poptGetOptArg(pc);
635 arg = sanitize_path(NULL, arg, NULL, 0);
636 if (server_exclude_list.head) {
637 char *cp = (char *)arg;
639 if (check_exclude(&server_exclude_list, cp, 0) < 0)
640 goto options_rejected;
642 add_exclude_file(&exclude_list, arg, XFLG_FATAL_ERRORS
643 | (opt == OPT_INCLUDE_FROM
644 ? XFLG_DEF_INCLUDE : 0));
663 exit_cleanup(RERR_SYNTAX);
673 case OPT_WRITE_BATCH:
674 /* batch_name is already set */
679 /* batch_name is already set */
684 for (arg = max_size_arg; isdigit(*arg); arg++) {}
686 for (arg++; isdigit(*arg); arg++) {}
689 max_size = atof(max_size_arg) * 1024;
692 max_size = atof(max_size_arg) * 1024*1024;
695 max_size = atof(max_size_arg) * 1024*1024*1024;
698 max_size = atof(max_size_arg);
705 snprintf(err_buf, sizeof err_buf,
706 "--max-size value is invalid: %s\n",
713 if (io_timeout && io_timeout < select_timeout)
714 select_timeout = io_timeout;
720 dest_option = "--link-dest";
723 snprintf(err_buf, sizeof err_buf,
724 "hard links are not supported on this %s\n",
725 am_server ? "server" : "client");
731 dest_option = "--copy-dest";
734 case OPT_COMPARE_DEST:
736 dest_option = "--compare-dest";
738 if (basis_dir_cnt >= MAX_BASIS_DIRS) {
739 snprintf(err_buf, sizeof err_buf,
740 "ERROR: at most %d %s args may be specified\n",
741 MAX_BASIS_DIRS, dest_option);
744 arg = poptGetOptArg(pc);
746 arg = sanitize_path(NULL, arg, NULL, 0);
747 basis_dir[basis_dir_cnt++] = (char *)arg;
751 /* A large opt value means that set_refuse_options()
752 * turned this option off (opt-BASE is its index). */
753 if (opt >= OPT_REFUSED_BASE) {
754 struct poptOption *op =
755 &long_options[opt-OPT_REFUSED_BASE];
756 int n = snprintf(err_buf, sizeof err_buf,
757 "The server is configured to refuse --%s\n",
760 snprintf(err_buf+n, sizeof err_buf-n,
761 " (-%c)\n", op->shortName);
764 snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
765 am_server ? "on remote machine: " : "",
766 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
774 if (preserve_links && !am_sender) {
775 snprintf(err_buf, sizeof err_buf,
776 "symlinks are not supported on this %s\n",
777 am_server ? "server" : "client");
782 #if !SUPPORT_HARD_LINKS
783 if (preserve_hard_links) {
784 snprintf(err_buf, sizeof err_buf,
785 "hard links are not supported on this %s\n",
786 am_server ? "server" : "client");
791 if (write_batch && read_batch) {
792 snprintf(err_buf, sizeof err_buf,
793 "--write-batch and --read-batch can not be used together\n");
796 if (write_batch || read_batch) {
798 snprintf(err_buf, sizeof err_buf,
799 "--%s-batch cannot be used with --dry_run (-n)\n",
800 write_batch ? "write" : "read");
805 "ignoring --%s-batch option sent to server\n",
806 write_batch ? "write" : "read");
807 /* We don't actually exit_cleanup(), so that we can
808 * still service older version clients that still send
809 * batch args to server. */
810 read_batch = write_batch = 0;
814 if (read_batch && files_from) {
815 snprintf(err_buf, sizeof err_buf,
816 "--read-batch cannot be used with --files-from\n");
819 if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
820 snprintf(err_buf, sizeof err_buf,
821 "the batch-file name must be %d characters or less.\n",
826 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
827 snprintf(err_buf, sizeof err_buf,
828 "the --temp-dir path is WAY too long.\n");
832 if (compare_dest + copy_dest + link_dest > 1) {
833 snprintf(err_buf, sizeof err_buf,
834 "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
840 recurse = -1; /* infinite recursion */
848 preserve_devices = 1;
851 if (recurse || list_only || files_from)
854 if (relative_paths < 0)
855 relative_paths = files_from? 1 : 0;
857 if (delete_before || delete_after)
859 if (delete_excluded && !delete_mode)
860 delete_mode = delete_before = 1;
862 *argv = poptGetArgs(pc);
863 *argc = count_args(*argv);
865 if (sanitize_paths) {
867 for (i = *argc; i-- > 0; )
868 (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
870 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
872 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
874 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
876 files_from = sanitize_path(NULL, files_from, NULL, 0);
878 if (server_exclude_list.head && !am_sender) {
879 struct exclude_list_struct *elp = &server_exclude_list;
882 clean_fname(tmpdir, 1);
883 if (check_exclude(elp, tmpdir, 1) < 0)
884 goto options_rejected;
887 clean_fname(partial_dir, 1);
888 if (check_exclude(elp, partial_dir, 1) < 0)
889 goto options_rejected;
891 for (i = 0; i < basis_dir_cnt; i++) {
892 clean_fname(basis_dir[i], 1);
893 if (check_exclude(elp, basis_dir[i], 1) < 0)
894 goto options_rejected;
897 clean_fname(backup_dir, 1);
898 if (check_exclude(elp, backup_dir, 1) < 0)
899 goto options_rejected;
902 if (server_exclude_list.head && files_from) {
903 clean_fname(files_from, 1);
904 if (check_exclude(&server_exclude_list, files_from, 0) < 0) {
906 snprintf(err_buf, sizeof err_buf,
907 "Your options have been rejected by the server.\n");
913 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
914 backup_suffix_len = strlen(backup_suffix);
915 if (strchr(backup_suffix, '/') != NULL) {
916 snprintf(err_buf, sizeof err_buf,
917 "--suffix cannot contain slashes: %s\n",
922 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
923 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
924 if (backup_dir_remainder < 32) {
925 snprintf(err_buf, sizeof err_buf,
926 "the --backup-dir path is WAY too long.\n");
929 if (backup_dir_buf[backup_dir_len - 1] != '/') {
930 backup_dir_buf[backup_dir_len++] = '/';
931 backup_dir_buf[backup_dir_len] = '\0';
933 if (verbose > 1 && !am_sender)
934 rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
935 } else if (!backup_suffix_len && (!am_server || !am_sender)) {
936 snprintf(err_buf, sizeof err_buf,
937 "--suffix cannot be a null string without --backup-dir\n");
941 if (do_progress && !verbose)
944 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
945 bwlimit = daemon_bwlimit;
947 bwlimit_writemax = (size_t)bwlimit * 128;
948 if (bwlimit_writemax < 512)
949 bwlimit_writemax = 512;
955 snprintf(err_buf, sizeof err_buf,
956 "--inplace cannot be used with --partial-dir\n");
961 snprintf(err_buf, sizeof err_buf,
962 "--inplace is not supported on this %s\n",
963 am_server ? "server" : "client");
967 if (keep_partial && !partial_dir)
968 partial_dir = getenv("RSYNC_PARTIAL_DIR");
970 if (!*partial_dir || strcmp(partial_dir, ".") == 0)
972 else if (*partial_dir != '/') {
973 add_exclude(&exclude_list, partial_dir,
982 if (*argc > 2 || (!am_daemon && *argc == 1)) {
984 exit_cleanup(RERR_SYNTAX);
986 if (strcmp(files_from, "-") == 0) {
989 remote_filesfrom_file = "-";
991 else if ((colon = find_colon(files_from)) != 0) {
994 exit_cleanup(RERR_SYNTAX);
996 remote_filesfrom_file = colon+1 + (colon[1] == ':');
997 if (strcmp(remote_filesfrom_file, "-") == 0) {
998 snprintf(err_buf, sizeof err_buf,
999 "Invalid --files-from remote filename\n");
1003 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1004 if (filesfrom_fd < 0) {
1005 snprintf(err_buf, sizeof err_buf,
1006 "failed to open files-from file %s: %s\n",
1007 files_from, strerror(errno));
1018 * Construct a filtered list of options to pass through from the
1019 * client to the server.
1021 * This involves setting options that will tell the server how to
1022 * behave, and also filtering out options that are processed only
1025 void server_options(char **args,int *argc)
1027 static char argstr[50+MAX_BASIS_DIRS*2];
1033 if (blocking_io == -1)
1036 args[ac++] = "--server";
1038 if (daemon_over_rsh) {
1039 args[ac++] = "--daemon";
1041 /* if we're passing --daemon, we're done */
1046 args[ac++] = "--sender";
1050 for (i = 0; i < verbose; i++)
1053 /* the -q option is intentionally left out */
1066 if (keep_dirlinks && am_sender)
1071 /* We don't need to send --no-whole-file, because it's the
1072 * default for remote transfers, and in any case old versions
1073 * of rsync will not understand it. */
1075 if (preserve_hard_links)
1081 if (preserve_devices)
1089 if (always_checksum)
1097 if (one_file_system)
1104 /* This is a complete hack - blame Rusty. FIXME!
1105 * This hack is only needed for older rsync versions that
1106 * don't understand the --list-only option. */
1107 if (list_only == 1 && recurse >= 0)
1113 args[ac++] = argstr;
1116 args[ac++] = "--list-only";
1119 if (asprintf(&arg, "-B%lu", block_size) < 0)
1124 if (max_delete && am_sender) {
1125 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1130 if (max_size && am_sender) {
1131 args[ac++] = "--max-size";
1132 args[ac++] = max_size_arg;
1136 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1142 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1148 args[ac++] = "--backup-dir";
1149 args[ac++] = backup_dir;
1152 /* Only send --suffix if it specifies a non-default value. */
1153 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1154 /* We use the following syntax to avoid weirdness with '~'. */
1155 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1161 if (delete_excluded)
1162 args[ac++] = "--delete-excluded";
1163 else if (delete_before || delete_after)
1164 args[ac++] = "--delete";
1167 args[ac++] = "--delete-after";
1170 args[ac++] = "--force";
1174 args[ac++] = "--size-only";
1176 if (modify_window_set) {
1177 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1182 if (checksum_seed) {
1183 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1188 if (partial_dir && am_sender) {
1189 args[ac++] = "--partial-dir";
1190 args[ac++] = partial_dir;
1191 } else if (keep_partial)
1192 args[ac++] = "--partial";
1195 args[ac++] = "--ignore-errors";
1197 if (copy_unsafe_links)
1198 args[ac++] = "--copy-unsafe-links";
1201 args[ac++] = "--safe-links";
1204 args[ac++] = "--numeric-ids";
1206 if (only_existing && am_sender)
1207 args[ac++] = "--existing";
1209 if (opt_ignore_existing && am_sender)
1210 args[ac++] = "--ignore-existing";
1213 args[ac++] = "--inplace";
1216 args[ac++] = "--temp-dir";
1217 args[ac++] = tmpdir;
1220 if (basis_dir[0] && am_sender) {
1221 /* the server only needs this option if it is not the sender,
1222 * and it may be an older version that doesn't know this
1223 * option, so don't send it if client is the sender.
1226 for (i = 0; i < basis_dir_cnt; i++) {
1227 args[ac++] = dest_option;
1228 args[ac++] = basis_dir[i];
1232 if (files_from && (!am_sender || remote_filesfrom_file)) {
1233 if (remote_filesfrom_file) {
1234 args[ac++] = "--files-from";
1235 args[ac++] = remote_filesfrom_file;
1237 args[ac++] = "--from0";
1239 args[ac++] = "--files-from=-";
1240 args[ac++] = "--from0";
1242 if (!relative_paths)
1243 args[ac++] = "--no-relative";
1245 if (!implied_dirs && !am_sender)
1246 args[ac++] = "--no-implied-dirs";
1252 out_of_memory("server_options");
1256 * Return the position of a ':' IF it is not part of a filename (i.e. as
1257 * long as it doesn't occur after a slash.
1259 char *find_colon(char *s)
1267 /* now check to see if there is a / in the string before the : - if there is then
1268 discard the colon on the assumption that the : is part of a filename */