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_excluded = 0;
58 int one_file_system = 0;
59 int protocol_version = PROTOCOL_VERSION;
61 int do_compression = 0;
64 int relative_paths = -1;
74 char *files_from = NULL;
75 int filesfrom_fd = -1;
76 char *remote_filesfrom_file = NULL;
80 int daemon_over_rsh = 0;
84 int safe_symlinks = 0;
85 int copy_unsafe_links = 0;
87 int daemon_bwlimit = 0;
89 size_t bwlimit_writemax = 0;
91 int only_existing = 0;
92 int opt_ignore_existing = 0;
95 int ignore_errors = 0;
96 int modify_window = 0;
98 int checksum_seed = 0;
100 unsigned int block_size = 0;
103 /** Network address family. **/
105 int default_af_hint = 0; /* Any protocol */
107 int default_af_hint = AF_INET; /* Must use IPv4 */
110 /** Do not go into the background when run as --daemon. Good
111 * for debugging and required for running as a service on W32,
112 * or under Unix process-monitors. **/
117 int backup_dir_len = 0;
118 int backup_suffix_len;
119 unsigned int backup_dir_remainder;
121 char *backup_suffix = NULL;
123 char *partial_dir = NULL;
124 char *compare_dest = NULL;
125 char *config_file = NULL;
126 char *shell_cmd = NULL;
127 char *log_format = NULL;
128 char *password_file = NULL;
129 char *rsync_path = RSYNC_PATH;
130 char *backup_dir = NULL;
131 char backup_dir_buf[MAXPATHLEN];
132 int rsync_port = RSYNC_PORT;
137 int always_checksum = 0;
140 #define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
141 char *batch_name = NULL;
143 static int daemon_opt; /* sets am_daemon after option error-reporting */
144 static int modify_window_set;
145 static char *max_size_arg;
147 /** Local address to bind. As a character string because it's
148 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
149 * address, or a hostname. **/
153 static void print_rsync_version(enum logcode f)
155 char const *got_socketpair = "no ";
156 char const *have_inplace = "no ";
157 char const *hardlinks = "no ";
158 char const *links = "no ";
159 char const *ipv6 = "no ";
160 STRUCT_STAT *dumstat;
162 #ifdef HAVE_SOCKETPAIR
170 #if SUPPORT_HARD_LINKS
182 rprintf(f, "%s version %s protocol version %d\n",
183 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
185 "Copyright (C) 1996-2004 by Andrew Tridgell and others\n");
186 rprintf(f, "<http://rsync.samba.org/>\n");
187 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
188 "%shard links, %ssymlinks, batchfiles, \n",
189 (int) (sizeof (OFF_T) * 8),
190 got_socketpair, hardlinks, links);
192 /* Note that this field may not have type ino_t. It depends
193 * on the complicated interaction between largefile feature
195 rprintf(f, " %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
197 (int) (sizeof dumstat->st_ino * 8),
198 (int) (sizeof (uint64) * 8));
199 #ifdef MAINTAINER_MODE
200 rprintf(f, " panic action: \"%s\"\n",
204 #ifdef INT64_IS_OFF_T
205 if (sizeof (int64) < 8)
206 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
211 "rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
212 "are welcome to redistribute it under certain conditions. See the GNU\n"
213 "General Public Licence for details.\n"
218 void usage(enum logcode F)
220 print_rsync_version(F);
222 rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
224 rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
225 rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
226 rprintf(F," or rsync [OPTION]... SRC [SRC]... DEST\n");
227 rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
228 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
229 rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
230 rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
231 rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
232 rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
233 rprintf(F," sources separated by space as long as they have same top-level\n");
234 rprintf(F,"\nOptions\n");
235 rprintf(F," -v, --verbose increase verbosity\n");
236 rprintf(F," -q, --quiet decrease verbosity\n");
237 rprintf(F," -c, --checksum always checksum\n");
238 rprintf(F," -a, --archive archive mode, equivalent to -rlptgoD (no -H)\n");
239 rprintf(F," -r, --recursive recurse into directories\n");
240 rprintf(F," -R, --relative use relative path names\n");
241 rprintf(F," --no-relative turn off --relative\n");
242 rprintf(F," --no-implied-dirs don't send implied dirs with -R\n");
243 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
244 rprintf(F," --backup-dir make backups into this directory\n");
245 rprintf(F," --suffix=SUFFIX backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
246 rprintf(F," -u, --update update only (don't overwrite newer files)\n");
247 rprintf(F," --inplace update destination files inplace (SEE MAN PAGE)\n");
248 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
249 rprintf(F," -l, --links copy symlinks as symlinks\n");
250 rprintf(F," -L, --copy-links copy the referent of all symlinks\n");
251 rprintf(F," --copy-unsafe-links copy the referent of \"unsafe\" symlinks\n");
252 rprintf(F," --safe-links ignore \"unsafe\" symlinks\n");
253 rprintf(F," -H, --hard-links preserve hard links\n");
254 rprintf(F," -p, --perms preserve permissions\n");
255 rprintf(F," -o, --owner preserve owner (root only)\n");
256 rprintf(F," -g, --group preserve group\n");
257 rprintf(F," -D, --devices preserve devices (root only)\n");
258 rprintf(F," -t, --times preserve times\n");
259 rprintf(F," -S, --sparse handle sparse files efficiently\n");
260 rprintf(F," -n, --dry-run show what would have been transferred\n");
261 rprintf(F," -W, --whole-file copy whole files, no incremental checks\n");
262 rprintf(F," --no-whole-file turn off --whole-file\n");
263 rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
264 rprintf(F," -B, --block-size=SIZE force a fixed checksum block-size\n");
265 rprintf(F," -e, --rsh=COMMAND specify the remote shell\n");
266 rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
267 rprintf(F," --existing only update files that already exist\n");
268 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
269 rprintf(F," --delete delete files that don't exist on the sending side\n");
270 rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
271 rprintf(F," --delete-after receiver deletes after transferring, not before\n");
272 rprintf(F," --ignore-errors delete even if there are I/O errors\n");
273 rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
274 rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n");
275 rprintf(F," --partial keep partially transferred files\n");
276 rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
277 rprintf(F," --force force deletion of directories even if not empty\n");
278 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
279 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
280 rprintf(F," -I, --ignore-times turn off mod time & file size quick check\n");
281 rprintf(F," --size-only ignore mod time for quick check (use size)\n");
282 rprintf(F," --modify-window=NUM compare mod times with reduced accuracy\n");
283 rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
284 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
285 rprintf(F," --link-dest=DIR create hardlinks to DIR for unchanged files\n");
286 rprintf(F," -P equivalent to --partial --progress\n");
287 rprintf(F," -z, --compress compress file data\n");
288 rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
289 rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
290 rprintf(F," --exclude-from=FILE exclude patterns listed in FILE\n");
291 rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
292 rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n");
293 rprintf(F," --files-from=FILE read FILE for list of source-file names\n");
294 rprintf(F," -0, --from0 all *-from file lists are delimited by nulls\n");
295 rprintf(F," --version print version number\n");
296 rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
297 rprintf(F," --no-blocking-io turn off --blocking-io\n");
298 rprintf(F," --stats give some file transfer stats\n");
299 rprintf(F," --progress show progress during transfer\n");
300 rprintf(F," --log-format=FORMAT log file transfers using specified format\n");
301 rprintf(F," --password-file=FILE get password from FILE\n");
302 rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
303 rprintf(F," --write-batch=FILE write a batch to FILE\n");
304 rprintf(F," --read-batch=FILE read a batch from FILE\n");
306 rprintf(F," -4, --ipv4 prefer IPv4\n");
307 rprintf(F," -6, --ipv6 prefer IPv6\n");
309 rprintf(F," -h, --help show this help screen\n");
311 rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
312 rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
313 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
316 enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
317 OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
318 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
319 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
320 OPT_REFUSED_BASE = 9000};
322 static struct poptOption long_options[] = {
323 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
324 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
325 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
326 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
327 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
328 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
329 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
330 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
331 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
332 {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
333 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
334 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
335 {"delete-after", 0, POPT_ARG_NONE, 0, OPT_DELETE_AFTER, 0, 0 },
336 {"delete-excluded", 0, POPT_ARG_NONE, 0, OPT_DELETE_EXCLUDED, 0, 0 },
337 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
338 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
339 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
340 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
341 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
342 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
343 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
344 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
345 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
346 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
347 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
348 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
349 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
350 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
351 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
352 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
353 {"copy-links", 'L', POPT_ARG_NONE, ©_links, 0, 0, 0 },
354 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
355 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
356 {"copy-unsafe-links", 0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 },
357 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
358 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
359 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
360 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
361 {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
362 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
363 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
364 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
365 {"archive", 'a', POPT_ARG_NONE, &archive_mode, 0, 0, 0 },
366 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
367 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
368 {"recursive", 'r', POPT_ARG_NONE, &recurse, 0, 0, 0 },
369 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
370 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
371 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
372 {"block-size", 'B', POPT_ARG_INT, &block_size, 0, 0, 0 },
373 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
374 {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
375 {"timeout", 0, POPT_ARG_INT, &io_timeout, OPT_TIMEOUT, 0, 0 },
376 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
377 {"compare-dest", 0, POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
378 {"link-dest", 0, POPT_ARG_STRING, &compare_dest, OPT_LINK_DEST, 0, 0 },
379 /* TODO: Should this take an optional int giving the compression level? */
380 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
381 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
382 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
383 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
384 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
385 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
386 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
387 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
388 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
389 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
390 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
391 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
392 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
393 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
394 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
395 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
396 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
397 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
398 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
399 {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
401 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
402 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
404 /* All these options switch us into daemon-mode option-parsing. */
405 {"address", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
406 {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
407 {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
408 {"no-detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
409 {"port", 0, POPT_ARG_INT, 0, OPT_DAEMON, 0, 0 },
413 static void daemon_usage(enum logcode F)
415 print_rsync_version(F);
417 rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
418 rprintf(F," --address=ADDRESS bind to the specified address\n");
419 rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
420 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
421 rprintf(F," --no-detach do not detach from the parent\n");
422 rprintf(F," --port=PORT specify alternate rsyncd port number\n");
424 rprintf(F," -4, --ipv4 prefer IPv4\n");
425 rprintf(F," -6, --ipv6 prefer IPv6\n");
427 rprintf(F," -h, --help show this help screen\n");
429 rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
430 rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
433 static struct poptOption long_daemon_options[] = {
434 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
435 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
436 {"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
437 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
438 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
440 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
441 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
443 {"no-detach", 0, POPT_ARG_NONE, &no_detach, 0, 0, 0 },
444 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
445 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
446 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
447 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
452 static char err_buf[200];
456 * Store the option error message, if any, so that we can log the
457 * connection attempt (which requires parsing the options), and then
458 * show the error later on.
460 void option_error(void)
463 strcpy(err_buf, "Error parsing options: "
464 "option may be supported on client but not on server?\n");
467 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
472 * Tweak the option table to disable all options that the rsyncd.conf
473 * file has told us to refuse.
475 static void set_refuse_options(char *bp)
477 struct poptOption *op;
478 char *cp, shortname[2];
479 int is_wild, found_match;
484 while (*bp == ' ') bp++;
487 if ((cp = strchr(bp, ' ')) != NULL)
489 /* If they specify "delete", reject all delete options. */
490 if (strcmp(bp, "delete") == 0)
492 is_wild = strpbrk(bp, "*?[") != NULL;
494 for (op = long_options; ; op++) {
495 *shortname = op->shortName;
496 if (!op->longName && !*shortname)
498 if ((op->longName && wildmatch(bp, op->longName))
499 || (*shortname && wildmatch(bp, shortname))) {
500 op->val = (op - long_options) + OPT_REFUSED_BASE;
507 rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
518 static int count_args(const char **argv)
523 while (argv[i] != NULL)
532 * Process command line arguments. Called on both local and remote.
534 * @retval 1 if all options are OK; with globals set to appropriate
537 * @retval 0 on error, with err_buf containing an explanation
539 int parse_arguments(int *argc, const char ***argv, int frommain)
542 char *ref = lp_refuse_options(module_id);
547 set_refuse_options(ref);
549 /* TODO: Call poptReadDefaultConfig; handle errors. */
551 /* The context leaks in case of an error, but if there's a
552 * problem we always exit anyhow. */
553 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
554 poptReadDefaultConfig(pc, 0);
556 while ((opt = poptGetNextOpt(pc)) != -1) {
557 /* most options are handled automatically by popt;
558 * only special cases are returned and listed here. */
562 print_rsync_version(FINFO);
567 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
571 pc = poptGetContext(RSYNC_NAME, *argc, *argv,
572 long_daemon_options, 0);
573 while ((opt = poptGetNextOpt(pc)) != -1) {
581 "rsync: %s: %s (in daemon mode)\n",
582 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
588 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
591 "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
592 exit_cleanup(RERR_SYNTAX);
594 *argv = poptGetArgs(pc);
595 *argc = count_args(*argv);
600 case OPT_MODIFY_WINDOW:
601 /* The value has already been set by popt, but
602 * we need to remember that we're using a
603 * non-default setting. */
604 modify_window_set = 1;
607 case OPT_DELETE_AFTER:
612 case OPT_DELETE_EXCLUDED:
618 add_exclude(&exclude_list, poptGetOptArg(pc), 0);
622 add_exclude(&exclude_list, poptGetOptArg(pc),
626 case OPT_EXCLUDE_FROM:
627 case OPT_INCLUDE_FROM:
628 arg = poptGetOptArg(pc);
630 arg = sanitize_path(NULL, arg, NULL, 0);
631 if (server_exclude_list.head) {
632 char *cp = (char *)arg;
634 if (check_exclude(&server_exclude_list, cp, 0) < 0)
635 goto options_rejected;
637 add_exclude_file(&exclude_list, arg, XFLG_FATAL_ERRORS
638 | (opt == OPT_INCLUDE_FROM
639 ? XFLG_DEF_INCLUDE : 0));
658 exit_cleanup(RERR_SYNTAX);
668 case OPT_WRITE_BATCH:
669 /* batch_name is already set */
674 /* batch_name is already set */
679 for (arg = max_size_arg; isdigit(*arg); arg++) {}
681 for (arg++; isdigit(*arg); arg++) {}
684 max_size = atof(max_size_arg) * 1024;
687 max_size = atof(max_size_arg) * 1024*1024;
690 max_size = atof(max_size_arg) * 1024*1024*1024;
693 max_size = atof(max_size_arg);
701 "--max-size value is invalid: %s\n",
703 exit_cleanup(RERR_SYNTAX);
708 if (io_timeout && io_timeout < select_timeout)
709 select_timeout = io_timeout;
717 snprintf(err_buf, sizeof err_buf,
718 "hard links are not supported on this %s\n",
719 am_server ? "server" : "client");
724 /* A large opt value means that set_refuse_options()
725 * turned this option off (opt-BASE is its index). */
726 if (opt >= OPT_REFUSED_BASE) {
727 struct poptOption *op =
728 &long_options[opt-OPT_REFUSED_BASE];
729 int n = snprintf(err_buf, sizeof err_buf,
730 "The server is configured to refuse --%s\n",
733 snprintf(err_buf+n, sizeof err_buf-n,
734 " (-%c)\n", op->shortName);
737 snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
738 am_server ? "on remote machine: " : "",
739 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
747 if (preserve_links && !am_sender) {
748 snprintf(err_buf, sizeof err_buf,
749 "symlinks are not supported on this %s\n",
750 am_server ? "server" : "client");
755 #if !SUPPORT_HARD_LINKS
756 if (preserve_hard_links) {
757 snprintf(err_buf, sizeof err_buf,
758 "hard links are not supported on this %s\n",
759 am_server ? "server" : "client");
764 if (write_batch && read_batch) {
765 snprintf(err_buf, sizeof err_buf,
766 "--write-batch and --read-batch can not be used together\n");
769 if (write_batch || read_batch) {
771 snprintf(err_buf, sizeof err_buf,
772 "--%s-batch cannot be used with --dry_run (-n)\n",
773 write_batch ? "write" : "read");
778 "ignoring --%s-batch option sent to server\n",
779 write_batch ? "write" : "read");
780 /* We don't actually exit_cleanup(), so that we can
781 * still service older version clients that still send
782 * batch args to server. */
783 read_batch = write_batch = 0;
787 if (read_batch && files_from) {
788 snprintf(err_buf, sizeof err_buf,
789 "--read-batch cannot be used with --files-from\n");
792 if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
793 snprintf(err_buf, sizeof err_buf,
794 "the batch-file name must be %d characters or less.\n",
799 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
800 snprintf(err_buf, sizeof err_buf,
801 "the --temp-dir path is WAY too long.\n");
815 preserve_devices = 1;
818 if (relative_paths < 0)
819 relative_paths = files_from? 1 : 0;
821 *argv = poptGetArgs(pc);
822 *argc = count_args(*argv);
824 if (sanitize_paths) {
826 for (i = *argc; i-- > 0; )
827 (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
829 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
831 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
833 compare_dest = sanitize_path(NULL, compare_dest, NULL, 0);
835 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
837 files_from = sanitize_path(NULL, files_from, NULL, 0);
839 if (server_exclude_list.head && !am_sender) {
840 struct exclude_list_struct *elp = &server_exclude_list;
842 clean_fname(tmpdir, 1);
843 if (check_exclude(elp, tmpdir, 1) < 0)
844 goto options_rejected;
847 clean_fname(partial_dir, 1);
848 if (check_exclude(elp, partial_dir, 1) < 0)
849 goto options_rejected;
852 clean_fname(compare_dest, 1);
853 if (check_exclude(elp, compare_dest, 1) < 0)
854 goto options_rejected;
857 clean_fname(backup_dir, 1);
858 if (check_exclude(elp, backup_dir, 1) < 0)
859 goto options_rejected;
862 if (server_exclude_list.head && files_from) {
863 clean_fname(files_from, 1);
864 if (check_exclude(&server_exclude_list, files_from, 0) < 0) {
866 snprintf(err_buf, sizeof err_buf,
867 "Your options have been rejected by the server.\n");
873 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
874 backup_suffix_len = strlen(backup_suffix);
875 if (strchr(backup_suffix, '/') != NULL) {
876 snprintf(err_buf, sizeof err_buf,
877 "--suffix cannot contain slashes: %s\n",
882 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
883 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
884 if (backup_dir_remainder < 32) {
885 snprintf(err_buf, sizeof err_buf,
886 "the --backup-dir path is WAY too long.\n");
889 if (backup_dir_buf[backup_dir_len - 1] != '/') {
890 backup_dir_buf[backup_dir_len++] = '/';
891 backup_dir_buf[backup_dir_len] = '\0';
893 if (verbose > 1 && !am_sender)
894 rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
895 } else if (!backup_suffix_len && (!am_server || !am_sender)) {
896 snprintf(err_buf, sizeof err_buf,
897 "--suffix cannot be a null string without --backup-dir\n");
901 if (do_progress && !verbose)
904 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
905 bwlimit = daemon_bwlimit;
907 bwlimit_writemax = (size_t)bwlimit * 128;
908 if (bwlimit_writemax < 512)
909 bwlimit_writemax = 512;
915 snprintf(err_buf, sizeof err_buf,
916 "--inplace cannot be used with --partial-dir\n");
921 snprintf(err_buf, sizeof err_buf,
922 "--inplace is not supported on this %s\n",
923 am_server ? "server" : "client");
927 snprintf(err_buf, sizeof err_buf,
928 "--inplace does not yet work with %s\n",
929 link_dest ? "--link-dest" : "--compare-dest");
933 if (keep_partial && !partial_dir)
934 partial_dir = getenv("RSYNC_PARTIAL_DIR");
936 if (!*partial_dir || strcmp(partial_dir, ".") == 0)
938 else if (*partial_dir != '/') {
939 add_exclude(&exclude_list, partial_dir,
948 if (*argc > 2 || (!am_daemon && *argc == 1)) {
950 exit_cleanup(RERR_SYNTAX);
952 if (strcmp(files_from, "-") == 0) {
955 remote_filesfrom_file = "-";
957 else if ((colon = find_colon(files_from)) != 0) {
960 exit_cleanup(RERR_SYNTAX);
962 remote_filesfrom_file = colon+1 + (colon[1] == ':');
963 if (strcmp(remote_filesfrom_file, "-") == 0) {
964 snprintf(err_buf, sizeof err_buf,
965 "Invalid --files-from remote filename\n");
969 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
970 if (filesfrom_fd < 0) {
971 snprintf(err_buf, sizeof err_buf,
972 "failed to open files-from file %s: %s\n",
973 files_from, strerror(errno));
984 * Construct a filtered list of options to pass through from the
985 * client to the server.
987 * This involves setting options that will tell the server how to
988 * behave, and also filtering out options that are processed only
991 void server_options(char **args,int *argc)
994 static char argstr[50];
999 if (blocking_io == -1)
1002 args[ac++] = "--server";
1004 if (daemon_over_rsh) {
1005 args[ac++] = "--daemon";
1007 /* if we're passing --daemon, we're done */
1012 args[ac++] = "--sender";
1016 for (i = 0; i < verbose; i++)
1019 /* the -q option is intentionally left out */
1030 if (keep_dirlinks && am_sender)
1035 /* We don't need to send --no-whole-file, because it's the
1036 * default for remote transfers, and in any case old versions
1037 * of rsync will not understand it. */
1039 if (preserve_hard_links)
1045 if (preserve_devices)
1053 if (always_checksum)
1061 if (one_file_system)
1068 /* this is a complete hack - blame Rusty
1070 this is a hack to make the list_only (remote file list)
1072 if (list_only && !recurse)
1078 args[ac++] = argstr;
1081 if (asprintf(&arg, "-B%u", block_size) < 0)
1086 if (max_delete && am_sender) {
1087 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1092 if (max_size && am_sender) {
1093 args[ac++] = "--max-size";
1094 args[ac++] = max_size_arg;
1098 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1104 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1110 args[ac++] = "--backup-dir";
1111 args[ac++] = backup_dir;
1114 /* Only send --suffix if it specifies a non-default value. */
1115 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1116 /* We use the following syntax to avoid weirdness with '~'. */
1117 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1123 if (delete_excluded)
1124 args[ac++] = "--delete-excluded";
1125 else if (delete_mode)
1126 args[ac++] = "--delete";
1129 args[ac++] = "--delete-after";
1132 args[ac++] = "--force";
1136 args[ac++] = "--size-only";
1138 if (modify_window_set) {
1139 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1144 if (checksum_seed) {
1145 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1150 if (partial_dir && am_sender) {
1151 args[ac++] = "--partial-dir";
1152 args[ac++] = partial_dir;
1153 } else if (keep_partial)
1154 args[ac++] = "--partial";
1157 args[ac++] = "--ignore-errors";
1159 if (copy_unsafe_links)
1160 args[ac++] = "--copy-unsafe-links";
1163 args[ac++] = "--safe-links";
1166 args[ac++] = "--numeric-ids";
1168 if (only_existing && am_sender)
1169 args[ac++] = "--existing";
1171 if (opt_ignore_existing && am_sender)
1172 args[ac++] = "--ignore-existing";
1175 args[ac++] = "--inplace";
1178 args[ac++] = "--temp-dir";
1179 args[ac++] = tmpdir;
1182 if (compare_dest && am_sender) {
1183 /* the server only needs this option if it is not the sender,
1184 * and it may be an older version that doesn't know this
1185 * option, so don't send it if client is the sender.
1187 args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
1188 args[ac++] = compare_dest;
1191 if (files_from && (!am_sender || remote_filesfrom_file)) {
1192 if (remote_filesfrom_file) {
1193 args[ac++] = "--files-from";
1194 args[ac++] = remote_filesfrom_file;
1196 args[ac++] = "--from0";
1198 args[ac++] = "--files-from=-";
1199 args[ac++] = "--from0";
1207 out_of_memory("server_options");
1211 * Return the position of a ':' IF it is not part of a filename (i.e. as
1212 * long as it doesn't occur after a slash.
1214 char *find_colon(char *s)
1222 /* now check to see if there is a / in the string before the : - if there is then
1223 discard the colon on the assumption that the : is part of a filename */