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," -k, --keep-dirs transfer a directory without recursing\n");
255 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
256 rprintf(F," -l, --links copy symlinks as symlinks\n");
257 rprintf(F," -L, --copy-links copy the referent of all symlinks\n");
258 rprintf(F," --copy-unsafe-links copy the referent of \"unsafe\" symlinks\n");
259 rprintf(F," --safe-links ignore \"unsafe\" symlinks\n");
260 rprintf(F," -H, --hard-links preserve hard links\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," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
312 rprintf(F," --write-batch=FILE write a batch to FILE\n");
313 rprintf(F," --read-batch=FILE read a batch from FILE\n");
315 rprintf(F," -4, --ipv4 prefer IPv4\n");
316 rprintf(F," -6, --ipv6 prefer IPv6\n");
318 rprintf(F," -h, --help show this help screen\n");
320 rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
321 rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
322 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
325 enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
326 OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
327 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
328 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
329 OPT_REFUSED_BASE = 9000};
331 static struct poptOption long_options[] = {
332 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
333 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
334 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
335 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
336 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
337 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
338 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
339 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
340 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
341 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
342 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
343 {"delete", 0, POPT_ARG_NONE, &delete_before, 0, 0, 0 },
344 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
345 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
346 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
347 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
348 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
349 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
350 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
351 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
352 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
353 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
354 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
355 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
356 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
357 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
358 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
359 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
360 {"keep-dirs", 'k', POPT_ARG_VAL, &keep_dirs, 2, 0, 0 },
361 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 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 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
365 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
366 {"copy-unsafe-links", 0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 },
367 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
368 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
369 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
370 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
371 {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
372 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
373 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
374 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
375 {"archive", 'a', POPT_ARG_NONE, &archive_mode, 0, 0, 0 },
376 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
377 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
378 {"recursive", 'r', POPT_ARG_VAL, &recurse, -1, 0, 0 },
379 {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
380 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
381 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
382 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
383 {"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
384 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
385 {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
386 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
387 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
388 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
389 {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
390 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
391 /* TODO: Should this take an optional int giving the compression level? */
392 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
393 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
394 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
395 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
396 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
397 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
398 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
399 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
400 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
401 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
402 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
403 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
404 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
405 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
406 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
407 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
408 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
409 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
410 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
411 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
412 {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
414 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
415 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
417 /* All these options switch us into daemon-mode option-parsing. */
418 {"address", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
419 {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
420 {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
421 {"no-detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
425 static void daemon_usage(enum logcode F)
427 print_rsync_version(F);
429 rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
430 rprintf(F," --address=ADDRESS bind to the specified address\n");
431 rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
432 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
433 rprintf(F," --no-detach do not detach from the parent\n");
434 rprintf(F," --port=PORT specify alternate rsyncd port number\n");
436 rprintf(F," -4, --ipv4 prefer IPv4\n");
437 rprintf(F," -6, --ipv6 prefer IPv6\n");
439 rprintf(F," -h, --help show this help screen\n");
441 rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
442 rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
445 static struct poptOption long_daemon_options[] = {
446 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
447 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
448 {"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
449 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
450 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
452 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
453 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
455 {"no-detach", 0, POPT_ARG_NONE, &no_detach, 0, 0, 0 },
456 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
457 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
458 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
459 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
464 static char err_buf[200];
468 * Store the option error message, if any, so that we can log the
469 * connection attempt (which requires parsing the options), and then
470 * show the error later on.
472 void option_error(void)
475 strcpy(err_buf, "Error parsing options: "
476 "option may be supported on client but not on server?\n");
479 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
484 * Tweak the option table to disable all options that the rsyncd.conf
485 * file has told us to refuse.
487 static void set_refuse_options(char *bp)
489 struct poptOption *op;
490 char *cp, shortname[2];
491 int is_wild, found_match;
496 while (*bp == ' ') bp++;
499 if ((cp = strchr(bp, ' ')) != NULL)
501 /* If they specify "delete", reject all delete options. */
502 if (strcmp(bp, "delete") == 0)
504 is_wild = strpbrk(bp, "*?[") != NULL;
506 for (op = long_options; ; op++) {
507 *shortname = op->shortName;
508 if (!op->longName && !*shortname)
510 if ((op->longName && wildmatch(bp, op->longName))
511 || (*shortname && wildmatch(bp, shortname))) {
512 op->val = (op - long_options) + OPT_REFUSED_BASE;
519 rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
530 static int count_args(const char **argv)
535 while (argv[i] != NULL)
544 * Process command line arguments. Called on both local and remote.
546 * @retval 1 if all options are OK; with globals set to appropriate
549 * @retval 0 on error, with err_buf containing an explanation
551 int parse_arguments(int *argc, const char ***argv, int frommain)
554 char *ref = lp_refuse_options(module_id);
559 set_refuse_options(ref);
561 /* TODO: Call poptReadDefaultConfig; handle errors. */
563 /* The context leaks in case of an error, but if there's a
564 * problem we always exit anyhow. */
565 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
566 poptReadDefaultConfig(pc, 0);
568 while ((opt = poptGetNextOpt(pc)) != -1) {
569 /* most options are handled automatically by popt;
570 * only special cases are returned and listed here. */
574 print_rsync_version(FINFO);
579 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
583 pc = poptGetContext(RSYNC_NAME, *argc, *argv,
584 long_daemon_options, 0);
585 while ((opt = poptGetNextOpt(pc)) != -1) {
593 "rsync: %s: %s (in daemon mode)\n",
594 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
600 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
603 "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
604 exit_cleanup(RERR_SYNTAX);
606 *argv = poptGetArgs(pc);
607 *argc = count_args(*argv);
612 case OPT_MODIFY_WINDOW:
613 /* The value has already been set by popt, but
614 * we need to remember that we're using a
615 * non-default setting. */
616 modify_window_set = 1;
620 add_exclude(&exclude_list, poptGetOptArg(pc), 0);
624 add_exclude(&exclude_list, poptGetOptArg(pc),
628 case OPT_EXCLUDE_FROM:
629 case OPT_INCLUDE_FROM:
630 arg = poptGetOptArg(pc);
632 arg = sanitize_path(NULL, arg, NULL, 0);
633 if (server_exclude_list.head) {
634 char *cp = (char *)arg;
636 if (check_exclude(&server_exclude_list, cp, 0) < 0)
637 goto options_rejected;
639 add_exclude_file(&exclude_list, arg, XFLG_FATAL_ERRORS
640 | (opt == OPT_INCLUDE_FROM
641 ? XFLG_DEF_INCLUDE : 0));
660 exit_cleanup(RERR_SYNTAX);
670 case OPT_WRITE_BATCH:
671 /* batch_name is already set */
676 /* batch_name is already set */
681 for (arg = max_size_arg; isdigit(*arg); arg++) {}
683 for (arg++; isdigit(*arg); arg++) {}
686 max_size = atof(max_size_arg) * 1024;
689 max_size = atof(max_size_arg) * 1024*1024;
692 max_size = atof(max_size_arg) * 1024*1024*1024;
695 max_size = atof(max_size_arg);
702 snprintf(err_buf, sizeof err_buf,
703 "--max-size value is invalid: %s\n",
710 if (io_timeout && io_timeout < select_timeout)
711 select_timeout = io_timeout;
717 dest_option = "--link-dest";
720 snprintf(err_buf, sizeof err_buf,
721 "hard links are not supported on this %s\n",
722 am_server ? "server" : "client");
728 dest_option = "--copy-dest";
731 case OPT_COMPARE_DEST:
733 dest_option = "--compare-dest";
735 if (basis_dir_cnt >= MAX_BASIS_DIRS) {
736 snprintf(err_buf, sizeof err_buf,
737 "ERROR: at most %d %s args may be specified\n",
738 MAX_BASIS_DIRS, dest_option);
741 arg = poptGetOptArg(pc);
743 arg = sanitize_path(NULL, arg, NULL, 0);
744 basis_dir[basis_dir_cnt++] = (char *)arg;
748 /* A large opt value means that set_refuse_options()
749 * turned this option off (opt-BASE is its index). */
750 if (opt >= OPT_REFUSED_BASE) {
751 struct poptOption *op =
752 &long_options[opt-OPT_REFUSED_BASE];
753 int n = snprintf(err_buf, sizeof err_buf,
754 "The server is configured to refuse --%s\n",
757 snprintf(err_buf+n, sizeof err_buf-n,
758 " (-%c)\n", op->shortName);
761 snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
762 am_server ? "on remote machine: " : "",
763 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
771 if (preserve_links && !am_sender) {
772 snprintf(err_buf, sizeof err_buf,
773 "symlinks are not supported on this %s\n",
774 am_server ? "server" : "client");
779 #if !SUPPORT_HARD_LINKS
780 if (preserve_hard_links) {
781 snprintf(err_buf, sizeof err_buf,
782 "hard links are not supported on this %s\n",
783 am_server ? "server" : "client");
788 if (write_batch && read_batch) {
789 snprintf(err_buf, sizeof err_buf,
790 "--write-batch and --read-batch can not be used together\n");
793 if (write_batch || read_batch) {
795 snprintf(err_buf, sizeof err_buf,
796 "--%s-batch cannot be used with --dry_run (-n)\n",
797 write_batch ? "write" : "read");
802 "ignoring --%s-batch option sent to server\n",
803 write_batch ? "write" : "read");
804 /* We don't actually exit_cleanup(), so that we can
805 * still service older version clients that still send
806 * batch args to server. */
807 read_batch = write_batch = 0;
811 if (read_batch && files_from) {
812 snprintf(err_buf, sizeof err_buf,
813 "--read-batch cannot be used with --files-from\n");
816 if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
817 snprintf(err_buf, sizeof err_buf,
818 "the batch-file name must be %d characters or less.\n",
823 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
824 snprintf(err_buf, sizeof err_buf,
825 "the --temp-dir path is WAY too long.\n");
829 if (compare_dest + copy_dest + link_dest > 1) {
830 snprintf(err_buf, sizeof err_buf,
831 "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
837 recurse = -1; /* infinite recursion */
845 preserve_devices = 1;
848 if (recurse || list_only || files_from)
851 if (relative_paths < 0)
852 relative_paths = files_from? 1 : 0;
854 if (delete_before || delete_after)
856 if (delete_excluded && !delete_mode)
857 delete_mode = delete_before = 1;
859 *argv = poptGetArgs(pc);
860 *argc = count_args(*argv);
862 if (sanitize_paths) {
864 for (i = *argc; i-- > 0; )
865 (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
867 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
869 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
871 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
873 files_from = sanitize_path(NULL, files_from, NULL, 0);
875 if (server_exclude_list.head && !am_sender) {
876 struct exclude_list_struct *elp = &server_exclude_list;
879 clean_fname(tmpdir, 1);
880 if (check_exclude(elp, tmpdir, 1) < 0)
881 goto options_rejected;
884 clean_fname(partial_dir, 1);
885 if (check_exclude(elp, partial_dir, 1) < 0)
886 goto options_rejected;
888 for (i = 0; i < basis_dir_cnt; i++) {
889 clean_fname(basis_dir[i], 1);
890 if (check_exclude(elp, basis_dir[i], 1) < 0)
891 goto options_rejected;
894 clean_fname(backup_dir, 1);
895 if (check_exclude(elp, backup_dir, 1) < 0)
896 goto options_rejected;
899 if (server_exclude_list.head && files_from) {
900 clean_fname(files_from, 1);
901 if (check_exclude(&server_exclude_list, files_from, 0) < 0) {
903 snprintf(err_buf, sizeof err_buf,
904 "Your options have been rejected by the server.\n");
910 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
911 backup_suffix_len = strlen(backup_suffix);
912 if (strchr(backup_suffix, '/') != NULL) {
913 snprintf(err_buf, sizeof err_buf,
914 "--suffix cannot contain slashes: %s\n",
919 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
920 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
921 if (backup_dir_remainder < 32) {
922 snprintf(err_buf, sizeof err_buf,
923 "the --backup-dir path is WAY too long.\n");
926 if (backup_dir_buf[backup_dir_len - 1] != '/') {
927 backup_dir_buf[backup_dir_len++] = '/';
928 backup_dir_buf[backup_dir_len] = '\0';
930 if (verbose > 1 && !am_sender)
931 rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
932 } else if (!backup_suffix_len && (!am_server || !am_sender)) {
933 snprintf(err_buf, sizeof err_buf,
934 "--suffix cannot be a null string without --backup-dir\n");
938 if (do_progress && !verbose)
941 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
942 bwlimit = daemon_bwlimit;
944 bwlimit_writemax = (size_t)bwlimit * 128;
945 if (bwlimit_writemax < 512)
946 bwlimit_writemax = 512;
952 snprintf(err_buf, sizeof err_buf,
953 "--inplace cannot be used with --partial-dir\n");
958 snprintf(err_buf, sizeof err_buf,
959 "--inplace is not supported on this %s\n",
960 am_server ? "server" : "client");
964 if (keep_partial && !partial_dir)
965 partial_dir = getenv("RSYNC_PARTIAL_DIR");
967 if (!*partial_dir || strcmp(partial_dir, ".") == 0)
969 else if (*partial_dir != '/') {
970 add_exclude(&exclude_list, partial_dir,
979 if (*argc > 2 || (!am_daemon && *argc == 1)) {
981 exit_cleanup(RERR_SYNTAX);
983 if (strcmp(files_from, "-") == 0) {
986 remote_filesfrom_file = "-";
988 else if ((colon = find_colon(files_from)) != 0) {
991 exit_cleanup(RERR_SYNTAX);
993 remote_filesfrom_file = colon+1 + (colon[1] == ':');
994 if (strcmp(remote_filesfrom_file, "-") == 0) {
995 snprintf(err_buf, sizeof err_buf,
996 "Invalid --files-from remote filename\n");
1000 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1001 if (filesfrom_fd < 0) {
1002 snprintf(err_buf, sizeof err_buf,
1003 "failed to open files-from file %s: %s\n",
1004 files_from, strerror(errno));
1015 * Construct a filtered list of options to pass through from the
1016 * client to the server.
1018 * This involves setting options that will tell the server how to
1019 * behave, and also filtering out options that are processed only
1022 void server_options(char **args,int *argc)
1024 static char argstr[50+MAX_BASIS_DIRS*2];
1030 if (blocking_io == -1)
1033 args[ac++] = "--server";
1035 if (daemon_over_rsh) {
1036 args[ac++] = "--daemon";
1038 /* if we're passing --daemon, we're done */
1043 args[ac++] = "--sender";
1047 for (i = 0; i < verbose; i++)
1050 /* the -q option is intentionally left out */
1063 if (keep_dirlinks && am_sender)
1068 /* We don't need to send --no-whole-file, because it's the
1069 * default for remote transfers, and in any case old versions
1070 * of rsync will not understand it. */
1072 if (preserve_hard_links)
1078 if (preserve_devices)
1086 if (always_checksum)
1094 if (one_file_system)
1101 /* This is a complete hack - blame Rusty. FIXME!
1102 * This hack is only needed for older rsync versions that
1103 * don't understand the --list-only option. */
1104 if (list_only == 1 && recurse >= 0)
1110 args[ac++] = argstr;
1113 args[ac++] = "--list-only";
1116 if (asprintf(&arg, "-B%lu", block_size) < 0)
1121 if (max_delete && am_sender) {
1122 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1127 if (max_size && am_sender) {
1128 args[ac++] = "--max-size";
1129 args[ac++] = max_size_arg;
1133 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1139 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1145 args[ac++] = "--backup-dir";
1146 args[ac++] = backup_dir;
1149 /* Only send --suffix if it specifies a non-default value. */
1150 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1151 /* We use the following syntax to avoid weirdness with '~'. */
1152 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1158 if (delete_excluded)
1159 args[ac++] = "--delete-excluded";
1160 else if (delete_before || delete_after)
1161 args[ac++] = "--delete";
1164 args[ac++] = "--delete-after";
1167 args[ac++] = "--force";
1171 args[ac++] = "--size-only";
1173 if (modify_window_set) {
1174 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1179 if (checksum_seed) {
1180 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1185 if (partial_dir && am_sender) {
1186 args[ac++] = "--partial-dir";
1187 args[ac++] = partial_dir;
1188 } else if (keep_partial)
1189 args[ac++] = "--partial";
1192 args[ac++] = "--ignore-errors";
1194 if (copy_unsafe_links)
1195 args[ac++] = "--copy-unsafe-links";
1198 args[ac++] = "--safe-links";
1201 args[ac++] = "--numeric-ids";
1203 if (only_existing && am_sender)
1204 args[ac++] = "--existing";
1206 if (opt_ignore_existing && am_sender)
1207 args[ac++] = "--ignore-existing";
1210 args[ac++] = "--inplace";
1213 args[ac++] = "--temp-dir";
1214 args[ac++] = tmpdir;
1217 if (basis_dir[0] && am_sender) {
1218 /* the server only needs this option if it is not the sender,
1219 * and it may be an older version that doesn't know this
1220 * option, so don't send it if client is the sender.
1223 for (i = 0; i < basis_dir_cnt; i++) {
1224 args[ac++] = dest_option;
1225 args[ac++] = basis_dir[i];
1229 if (files_from && (!am_sender || remote_filesfrom_file)) {
1230 if (remote_filesfrom_file) {
1231 args[ac++] = "--files-from";
1232 args[ac++] = remote_filesfrom_file;
1234 args[ac++] = "--from0";
1236 args[ac++] = "--files-from=-";
1237 args[ac++] = "--from0";
1239 if (!relative_paths)
1240 args[ac++] = "--no-relative";
1242 if (!implied_dirs && !am_sender)
1243 args[ac++] = "--no-implied-dirs";
1249 out_of_memory("server_options");
1253 * Return the position of a ':' IF it is not part of a filename (i.e. as
1254 * long as it doesn't occur after a slash.
1256 char *find_colon(char *s)
1264 /* now check to see if there is a / in the string before the : - if there is then
1265 discard the colon on the assumption that the : is part of a filename */