Keeping silent about stat() errors is never a good idea -- it hides
[rsync/rsync.git] / options.c
... / ...
CommitLineData
1/* -*- c-file-style: "linux" -*-
2 *
3 * Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
4 * Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
5 *
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.
10 *
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.
15 *
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.
19 */
20
21#include "rsync.h"
22#include "popt.h"
23
24extern int module_id;
25extern int sanitize_paths;
26extern struct filter_list_struct filter_list;
27extern struct filter_list_struct server_filter_list;
28
29int make_backups = 0;
30
31/**
32 * If 1, send the whole file as literal data rather than trying to
33 * create an incremental diff.
34 *
35 * If -1, then look at whether we're local or remote and go by that.
36 *
37 * @sa disable_deltas_p()
38 **/
39int whole_file = -1;
40
41int append_mode = 0;
42int keep_dirlinks = 0;
43int copy_links = 0;
44int preserve_links = 0;
45int preserve_hard_links = 0;
46int preserve_perms = 0;
47int preserve_devices = 0;
48int preserve_uid = 0;
49int preserve_gid = 0;
50int preserve_times = 0;
51int omit_dir_times = 0;
52int update_only = 0;
53int cvs_exclude = 0;
54int dry_run = 0;
55int do_xfers = 1;
56int ignore_times = 0;
57int delete_mode = 0;
58int delete_during = 0;
59int delete_before = 0;
60int delete_after = 0;
61int delete_excluded = 0;
62int remove_sent_files = 0;
63int one_file_system = 0;
64int protocol_version = PROTOCOL_VERSION;
65int sparse_files = 0;
66int do_compression = 0;
67int am_root = 0;
68int am_server = 0;
69int am_sender = 0;
70int am_generator = 0;
71int am_starting_up = 1;
72int orig_umask = 0;
73int relative_paths = -1;
74int implied_dirs = 1;
75int numeric_ids = 0;
76int force_delete = 0;
77int io_timeout = 0;
78int allowed_lull = 0;
79char *files_from = NULL;
80int filesfrom_fd = -1;
81char *filesfrom_host = NULL;
82int eol_nulls = 0;
83int recurse = 0;
84int xfer_dirs = -1;
85int am_daemon = 0;
86int daemon_over_rsh = 0;
87int do_stats = 0;
88int do_progress = 0;
89int keep_partial = 0;
90int safe_symlinks = 0;
91int copy_unsafe_links = 0;
92int size_only = 0;
93int daemon_bwlimit = 0;
94int bwlimit = 0;
95int fuzzy_basis = 0;
96size_t bwlimit_writemax = 0;
97int only_existing = 0;
98int opt_ignore_existing = 0;
99int need_messages_from_generator = 0;
100int max_delete = 0;
101OFF_T max_size = 0;
102int ignore_errors = 0;
103int modify_window = 0;
104int blocking_io = -1;
105int checksum_seed = 0;
106int inplace = 0;
107int delay_updates = 0;
108long block_size = 0; /* "long" because popt can't set an int32. */
109
110
111/** Network address family. **/
112#ifdef INET6
113int default_af_hint = 0; /* Any protocol */
114#else
115int default_af_hint = AF_INET; /* Must use IPv4 */
116#endif
117
118/** Do not go into the background when run as --daemon. Good
119 * for debugging and required for running as a service on W32,
120 * or under Unix process-monitors. **/
121int no_detach
122#if defined _WIN32 || defined __WIN32__
123 = 1;
124#else
125 = 0;
126#endif
127
128int write_batch = 0;
129int read_batch = 0;
130int backup_dir_len = 0;
131int backup_suffix_len;
132unsigned int backup_dir_remainder;
133
134char *backup_suffix = NULL;
135char *tmpdir = NULL;
136char *partial_dir = NULL;
137char *basis_dir[MAX_BASIS_DIRS+1];
138char *config_file = NULL;
139char *shell_cmd = NULL;
140char *log_format = NULL;
141char *password_file = NULL;
142char *rsync_path = RSYNC_PATH;
143char *backup_dir = NULL;
144char backup_dir_buf[MAXPATHLEN];
145int rsync_port = 0;
146int compare_dest = 0;
147int copy_dest = 0;
148int link_dest = 0;
149int basis_dir_cnt = 0;
150char *dest_option = NULL;
151
152int verbose = 0;
153int quiet = 0;
154int log_before_transfer = 0;
155int log_format_has_i = 0;
156int log_format_has_o_or_i = 0;
157int always_checksum = 0;
158int list_only = 0;
159
160#define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
161char *batch_name = NULL;
162
163static int daemon_opt; /* sets am_daemon after option error-reporting */
164static int F_option_cnt = 0;
165static int modify_window_set;
166static int itemize_changes = 0;
167static int refused_delete, refused_archive_part;
168static int refused_partial, refused_progress, refused_delete_before;
169static int refused_inplace;
170static char *max_size_arg;
171static char partialdir_for_delayupdate[] = ".~tmp~";
172
173/** Local address to bind. As a character string because it's
174 * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
175 * address, or a hostname. **/
176char *bind_address;
177
178
179static void print_rsync_version(enum logcode f)
180{
181 char const *got_socketpair = "no ";
182 char const *have_inplace = "no ";
183 char const *hardlinks = "no ";
184 char const *links = "no ";
185 char const *ipv6 = "no ";
186 STRUCT_STAT *dumstat;
187
188#ifdef HAVE_SOCKETPAIR
189 got_socketpair = "";
190#endif
191
192#ifdef HAVE_FTRUNCATE
193 have_inplace = "";
194#endif
195
196#ifdef SUPPORT_HARD_LINKS
197 hardlinks = "";
198#endif
199
200#ifdef SUPPORT_LINKS
201 links = "";
202#endif
203
204#ifdef INET6
205 ipv6 = "";
206#endif
207
208 rprintf(f, "%s version %s protocol version %d\n",
209 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
210 rprintf(f,
211 "Copyright (C) 1996-2005 by Andrew Tridgell and others\n");
212 rprintf(f, "<http://rsync.samba.org/>\n");
213 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
214 "%shard links, %ssymlinks, batchfiles, \n",
215 (int) (sizeof (OFF_T) * 8),
216 got_socketpair, hardlinks, links);
217
218 /* Note that this field may not have type ino_t. It depends
219 * on the complicated interaction between largefile feature
220 * macros. */
221 rprintf(f, " %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
222 have_inplace, ipv6,
223 (int) (sizeof dumstat->st_ino * 8),
224 (int) (sizeof (int64) * 8));
225#ifdef MAINTAINER_MODE
226 rprintf(f, " panic action: \"%s\"\n",
227 get_panic_action());
228#endif
229
230#if SIZEOF_INT64 < 8
231 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
232#endif
233 if (sizeof (int64) != SIZEOF_INT64) {
234 rprintf(f,
235 "WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
236 (int) SIZEOF_INT64, (int) sizeof (int64));
237 }
238
239 rprintf(f,
240"\n"
241"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
242"are welcome to redistribute it under certain conditions. See the GNU\n"
243"General Public Licence for details.\n"
244 );
245}
246
247
248void usage(enum logcode F)
249{
250 print_rsync_version(F);
251
252 rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
253
254 rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... DEST\n");
255 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
256 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
257 rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
258 rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC [DEST]\n");
259 rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
260 rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
261 rprintf(F,"The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect\n");
262 rprintf(F,"to an rsync daemon, and require SRC or DEST to start with a module name.\n");
263 rprintf(F,"\nOptions\n");
264 rprintf(F," -v, --verbose increase verbosity\n");
265 rprintf(F," -q, --quiet suppress non-error messages\n");
266 rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n");
267 rprintf(F," -a, --archive archive mode; same as -rlptgoD (no -H)\n");
268 rprintf(F," --no-OPTION turn of an implied OPTION (e.g. --no-D)\n");
269 rprintf(F," -r, --recursive recurse into directories\n");
270 rprintf(F," -R, --relative use relative path names\n");
271 rprintf(F," --no-implied-dirs don't send implied dirs with --relative\n");
272 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
273 rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
274 rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
275 rprintf(F," -u, --update skip files that are newer on the receiver\n");
276 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
277 rprintf(F," --append append data onto shorter files\n");
278 rprintf(F," -d, --dirs transfer directories without recursing\n");
279 rprintf(F," -l, --links copy symlinks as symlinks\n");
280 rprintf(F," -L, --copy-links transform symlink into referent file/dir\n");
281 rprintf(F," --copy-unsafe-links only \"unsafe\" symlinks are transformed\n");
282 rprintf(F," --safe-links ignore symlinks that point outside the source tree\n");
283 rprintf(F," -H, --hard-links preserve hard links\n");
284 rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
285 rprintf(F," -p, --perms preserve permissions\n");
286 rprintf(F," -o, --owner preserve owner (root only)\n");
287 rprintf(F," -g, --group preserve group\n");
288 rprintf(F," -D, --devices preserve devices (root only)\n");
289 rprintf(F," -t, --times preserve times\n");
290 rprintf(F," -O, --omit-dir-times omit directories when preserving times\n");
291 rprintf(F," -S, --sparse handle sparse files efficiently\n");
292 rprintf(F," -n, --dry-run show what would have been transferred\n");
293 rprintf(F," -W, --whole-file copy files whole (without rsync algorithm)\n");
294 rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
295 rprintf(F," -B, --block-size=SIZE force a fixed checksum block-size\n");
296 rprintf(F," -e, --rsh=COMMAND specify the remote shell to use\n");
297 rprintf(F," --rsync-path=PROGRAM specify the rsync to run on the remote machine\n");
298 rprintf(F," --existing only update files that already exist on receiver\n");
299 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
300 rprintf(F," --remove-sent-files sent files/symlinks are removed from sending side\n");
301 rprintf(F," --del an alias for --delete-during\n");
302 rprintf(F," --delete delete files that don't exist on the sending side\n");
303 rprintf(F," --delete-before receiver deletes before transfer (default)\n");
304 rprintf(F," --delete-during receiver deletes during transfer, not before\n");
305 rprintf(F," --delete-after receiver deletes after transfer, not before\n");
306 rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
307 rprintf(F," --ignore-errors delete even if there are I/O errors\n");
308 rprintf(F," --force force deletion of directories even if not empty\n");
309 rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
310 rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n");
311 rprintf(F," --partial keep partially transferred files\n");
312 rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
313 rprintf(F," --delay-updates put all updated files into place at transfer's end\n");
314 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
315 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
316 rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
317 rprintf(F," --size-only skip files that match in size\n");
318 rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
319 rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
320 rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n");
321 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
322 rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
323 rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
324 rprintf(F," -z, --compress compress file data during the transfer\n");
325 rprintf(F," -C, --cvs-exclude auto-ignore files the same way CVS does\n");
326 rprintf(F," -f, --filter=RULE add a file-filtering RULE\n");
327 rprintf(F," -F same as --filter='dir-merge /.rsync-filter'\n");
328 rprintf(F," repeated: --filter='- .rsync-filter'\n");
329 rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
330 rprintf(F," --exclude-from=FILE read exclude patterns from FILE\n");
331 rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
332 rprintf(F," --include-from=FILE read include patterns from FILE\n");
333 rprintf(F," --files-from=FILE read list of source-file names from FILE\n");
334 rprintf(F," -0, --from0 all *-from/filter files are delimited by 0s\n");
335 rprintf(F," --address=ADDRESS bind address for outgoing socket to daemon\n");
336 rprintf(F," --port=PORT specify double-colon alternate port number\n");
337 rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
338 rprintf(F," --stats give some file-transfer stats\n");
339 rprintf(F," --progress show progress during transfer\n");
340 rprintf(F," -P same as --partial --progress\n");
341 rprintf(F," -i, --itemize-changes output a change-summary for all updates\n");
342 rprintf(F," --log-format=FORMAT output filenames using the specified format\n");
343 rprintf(F," --password-file=FILE read password from FILE\n");
344 rprintf(F," --list-only list the files instead of copying them\n");
345 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
346 rprintf(F," --write-batch=FILE write a batched update to FILE\n");
347 rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
348 rprintf(F," --read-batch=FILE read a batched update from FILE\n");
349 rprintf(F," --protocol=NUM force an older protocol version to be used\n");
350#ifdef INET6
351 rprintf(F," -4, --ipv4 prefer IPv4\n");
352 rprintf(F," -6, --ipv6 prefer IPv6\n");
353#endif
354 rprintf(F," --version print version number\n");
355 rprintf(F," -h, --help show this help screen\n");
356
357 rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
358 rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
359 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
360}
361
362enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
363 OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
364 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
365 OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
366 OPT_REFUSED_BASE = 9000};
367
368static struct poptOption long_options[] = {
369 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
370 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
371 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
372 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
373 {"no-verbose", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
374 {"no-v", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
375 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
376 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
377 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
378 {"archive", 'a', POPT_ARG_NONE, 0, 'a', 0, 0 },
379 {"recursive", 'r', POPT_ARG_VAL, &recurse, 2, 0, 0 },
380 {"no-recursive", 0, POPT_ARG_VAL, &recurse, 0, 0, 0 },
381 {"no-r", 0, POPT_ARG_VAL, &recurse, 0, 0, 0 },
382 {"dirs", 'd', POPT_ARG_VAL, &xfer_dirs, 2, 0, 0 },
383 {"no-dirs", 0, POPT_ARG_VAL, &xfer_dirs, 0, 0, 0 },
384 {"no-d", 0, POPT_ARG_VAL, &xfer_dirs, 0, 0, 0 },
385 {"perms", 'p', POPT_ARG_VAL, &preserve_perms, 1, 0, 0 },
386 {"no-perms", 0, POPT_ARG_VAL, &preserve_perms, 0, 0, 0 },
387 {"no-p", 0, POPT_ARG_VAL, &preserve_perms, 0, 0, 0 },
388 {"times", 't', POPT_ARG_VAL, &preserve_times, 1, 0, 0 },
389 {"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
390 {"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
391 {"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 2, 0, 0 },
392 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
393 {"owner", 'o', POPT_ARG_VAL, &preserve_uid, 1, 0, 0 },
394 {"no-owner", 0, POPT_ARG_VAL, &preserve_uid, 0, 0, 0 },
395 {"no-o", 0, POPT_ARG_VAL, &preserve_uid, 0, 0, 0 },
396 {"group", 'g', POPT_ARG_VAL, &preserve_gid, 1, 0, 0 },
397 {"no-group", 0, POPT_ARG_VAL, &preserve_gid, 0, 0, 0 },
398 {"no-g", 0, POPT_ARG_VAL, &preserve_gid, 0, 0, 0 },
399 {"devices", 'D', POPT_ARG_VAL, &preserve_devices, 1, 0, 0 },
400 {"no-devices", 0, POPT_ARG_VAL, &preserve_devices, 0, 0, 0 },
401 {"no-D", 0, POPT_ARG_VAL, &preserve_devices, 0, 0, 0 },
402 {"links", 'l', POPT_ARG_VAL, &preserve_links, 1, 0, 0 },
403 {"no-links", 0, POPT_ARG_VAL, &preserve_links, 0, 0, 0 },
404 {"no-l", 0, POPT_ARG_VAL, &preserve_links, 0, 0, 0 },
405 {"copy-links", 'L', POPT_ARG_NONE, &copy_links, 0, 0, 0 },
406 {"copy-unsafe-links",0, POPT_ARG_NONE, &copy_unsafe_links, 0, 0, 0 },
407 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
408 {"keep-dirlinks", 'K', POPT_ARG_NONE, &keep_dirlinks, 0, 0, 0 },
409 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
410 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
411 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
412 {"no-R", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
413 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
414 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
415 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
416 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
417 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
418 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
419 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
420 {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
421 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
422 {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
423 {"append", 0, POPT_ARG_VAL, &append_mode, 1, 0, 0 },
424 {"del", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
425 {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
426 {"delete-before", 0, POPT_ARG_VAL, &delete_before, 2, 0, 0 },
427 {"delete-during", 0, POPT_ARG_NONE, &delete_during, 0, 0, 0 },
428 {"delete-after", 0, POPT_ARG_NONE, &delete_after, 0, 0, 0 },
429 {"delete-excluded", 0, POPT_ARG_NONE, &delete_excluded, 0, 0, 0 },
430 {"remove-sent-files",0, POPT_ARG_NONE, &remove_sent_files, 0, 0, 0 },
431 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
432 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
433 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
434 {0, 'F', POPT_ARG_NONE, 0, 'F', 0, 0 },
435 {"filter", 'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
436 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
437 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
438 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
439 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
440 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
441 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
442 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
443 {"no-W", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
444 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
445 {"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 },
446 {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
447 {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
448 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
449 {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
450 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
451 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
452 {"progress", 0, POPT_ARG_VAL, &do_progress, 1, 0, 0 },
453 {"no-progress", 0, POPT_ARG_VAL, &do_progress, 0, 0, 0 },
454 {"partial", 0, POPT_ARG_VAL, &keep_partial, 1, 0, 0 },
455 {"no-partial", 0, POPT_ARG_VAL, &keep_partial, 0, 0, 0 },
456 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
457 {"delay-updates", 0, POPT_ARG_NONE, &delay_updates, 0, 0, 0 },
458 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
459 {"itemize-changes", 'i', POPT_ARG_NONE, &itemize_changes, 0, 0, 0 },
460 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
461 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
462 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
463 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
464 {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
465 {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
466 {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
467 {"only-write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 },
468 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
469 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
470 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
471 {"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 },
472 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
473 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
474 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
475#ifdef INET6
476 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
477 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
478#endif
479 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
480 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
481 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
482 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
483 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
484 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
485 {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
486 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
487 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
488 /* All the following options switch us into daemon-mode option-parsing. */
489 {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
490 {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
491 {"detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
492 {"no-detach", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
493 {0,0,0,0, 0, 0, 0}
494};
495
496static void daemon_usage(enum logcode F)
497{
498 print_rsync_version(F);
499
500 rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
501 rprintf(F," --address=ADDRESS bind to the specified address\n");
502 rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
503 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
504 rprintf(F," --no-detach do not detach from the parent\n");
505 rprintf(F," --port=PORT listen on alternate port number\n");
506 rprintf(F," -v, --verbose increase verbosity\n");
507#ifdef INET6
508 rprintf(F," -4, --ipv4 prefer IPv4\n");
509 rprintf(F," -6, --ipv6 prefer IPv6\n");
510#endif
511 rprintf(F," -h, --help show this help screen\n");
512
513 rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
514 rprintf(F,"daemon-specific rsync options. See also the rsyncd.conf(5) man page.\n");
515}
516
517static struct poptOption long_daemon_options[] = {
518 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
519 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
520 {"bwlimit", 0, POPT_ARG_INT, &daemon_bwlimit, 0, 0, 0 },
521 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
522 {"daemon", 0, POPT_ARG_NONE, &daemon_opt, 0, 0, 0 },
523#ifdef INET6
524 {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
525 {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
526#endif
527 {"detach", 0, POPT_ARG_VAL, &no_detach, 0, 0, 0 },
528 {"no-detach", 0, POPT_ARG_VAL, &no_detach, 1, 0, 0 },
529 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
530 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
531 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
532 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
533 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
534 {"no-verbose", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
535 {"no-v", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
536 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
537 {0,0,0,0, 0, 0, 0}
538};
539
540
541static char err_buf[200];
542
543
544/**
545 * Store the option error message, if any, so that we can log the
546 * connection attempt (which requires parsing the options), and then
547 * show the error later on.
548 **/
549void option_error(void)
550{
551 if (!err_buf[0]) {
552 strcpy(err_buf, "Error parsing options: "
553 "option may be supported on client but not on server?\n");
554 }
555
556 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
557}
558
559
560/**
561 * Tweak the option table to disable all options that the rsyncd.conf
562 * file has told us to refuse.
563 **/
564static void set_refuse_options(char *bp)
565{
566 struct poptOption *op;
567 char *cp, shortname[2];
568 int is_wild, found_match;
569
570 shortname[1] = '\0';
571
572 while (1) {
573 while (*bp == ' ') bp++;
574 if (!*bp)
575 break;
576 if ((cp = strchr(bp, ' ')) != NULL)
577 *cp= '\0';
578 is_wild = strpbrk(bp, "*?[") != NULL;
579 found_match = 0;
580 for (op = long_options; ; op++) {
581 *shortname = op->shortName;
582 if (!op->longName && !*shortname)
583 break;
584 if ((op->longName && wildmatch(bp, op->longName))
585 || (*shortname && wildmatch(bp, shortname))) {
586 if (op->argInfo == POPT_ARG_VAL)
587 op->argInfo = POPT_ARG_NONE;
588 op->val = (op - long_options) + OPT_REFUSED_BASE;
589 found_match = 1;
590 /* These flags are set to let us easily check
591 * an implied option later in the code. */
592 switch (*shortname) {
593 case 'r': case 'd': case 'l': case 'p':
594 case 't': case 'g': case 'o': case 'D':
595 refused_archive_part = op->val;
596 break;
597 case '\0':
598 if (wildmatch("delete", op->longName))
599 refused_delete = op->val;
600 else if (wildmatch("delete-before", op->longName))
601 refused_delete_before = op->val;
602 else if (wildmatch("partial", op->longName))
603 refused_partial = op->val;
604 else if (wildmatch("progress", op->longName))
605 refused_progress = op->val;
606 else if (wildmatch("inplace", op->longName))
607 refused_inplace = op->val;
608 break;
609 }
610 if (!is_wild)
611 break;
612 }
613 }
614 if (!found_match) {
615 rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
616 bp);
617 }
618 if (!cp)
619 break;
620 *cp = ' ';
621 bp = cp + 1;
622 }
623
624 for (op = long_options; ; op++) {
625 *shortname = op->shortName;
626 if (!op->longName && !*shortname)
627 break;
628 if (op->val == OPT_DAEMON) {
629 if (op->argInfo == POPT_ARG_VAL)
630 op->argInfo = POPT_ARG_NONE;
631 op->val = (op - long_options) + OPT_REFUSED_BASE;
632 }
633 }
634}
635
636
637static int count_args(const char **argv)
638{
639 int i = 0;
640
641 if (argv) {
642 while (argv[i] != NULL)
643 i++;
644 }
645
646 return i;
647}
648
649
650static OFF_T parse_size_arg(const char *size_arg)
651{
652 const char *arg;
653 OFF_T size;
654
655 for (arg = size_arg; isdigit(*(uchar*)arg); arg++) {}
656 if (*arg == '.')
657 for (arg++; isdigit(*(uchar*)arg); arg++) {}
658 switch (*arg) {
659 case 'k': case 'K':
660 size = atof(size_arg) * 1024;
661 break;
662 case 'm': case 'M':
663 size = atof(size_arg) * 1024*1024;
664 break;
665 case 'g': case 'G':
666 size = atof(size_arg) * 1024*1024*1024;
667 break;
668 case '\0':
669 size = atof(size_arg);
670 break;
671 default:
672 size = 0;
673 break;
674 }
675 return size;
676}
677
678
679static void create_refuse_error(int which)
680{
681 /* The "which" value is the index + OPT_REFUSED_BASE. */
682 struct poptOption *op = &long_options[which - OPT_REFUSED_BASE];
683 int n = snprintf(err_buf, sizeof err_buf,
684 "The server is configured to refuse --%s\n",
685 op->longName) - 1;
686 if (op->shortName) {
687 snprintf(err_buf + n, sizeof err_buf - n,
688 " (-%c)\n", op->shortName);
689 }
690}
691
692
693/**
694 * Process command line arguments. Called on both local and remote.
695 *
696 * @retval 1 if all options are OK; with globals set to appropriate
697 * values
698 *
699 * @retval 0 on error, with err_buf containing an explanation
700 **/
701int parse_arguments(int *argc, const char ***argv, int frommain)
702{
703 int opt;
704 char *ref = lp_refuse_options(module_id);
705 const char *arg;
706 poptContext pc;
707
708 if (ref && *ref)
709 set_refuse_options(ref);
710
711 /* TODO: Call poptReadDefaultConfig; handle errors. */
712
713 /* The context leaks in case of an error, but if there's a
714 * problem we always exit anyhow. */
715 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
716 poptReadDefaultConfig(pc, 0);
717
718 while ((opt = poptGetNextOpt(pc)) != -1) {
719 /* most options are handled automatically by popt;
720 * only special cases are returned and listed here. */
721
722 switch (opt) {
723 case OPT_VERSION:
724 print_rsync_version(FINFO);
725 exit_cleanup(0);
726
727 case OPT_DAEMON:
728 if (am_daemon) {
729 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
730 return 0;
731 }
732 poptFreeContext(pc);
733 pc = poptGetContext(RSYNC_NAME, *argc, *argv,
734 long_daemon_options, 0);
735 while ((opt = poptGetNextOpt(pc)) != -1) {
736 switch (opt) {
737 case 'h':
738 daemon_usage(FINFO);
739 exit_cleanup(0);
740
741 case 'v':
742 verbose++;
743 break;
744
745 default:
746 rprintf(FERROR,
747 "rsync: %s: %s (in daemon mode)\n",
748 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
749 poptStrerror(opt));
750 goto daemon_error;
751 }
752 }
753
754 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
755 snprintf(err_buf, sizeof err_buf,
756 "the --temp-dir path is WAY too long.\n");
757 return 0;
758 }
759
760 if (!daemon_opt) {
761 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
762 daemon_error:
763 rprintf(FERROR,
764 "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
765 exit_cleanup(RERR_SYNTAX);
766 }
767
768 *argv = poptGetArgs(pc);
769 *argc = count_args(*argv);
770 am_starting_up = 0;
771 daemon_opt = 0;
772 am_daemon = 1;
773 return 1;
774
775 case OPT_MODIFY_WINDOW:
776 /* The value has already been set by popt, but
777 * we need to remember that we're using a
778 * non-default setting. */
779 modify_window_set = 1;
780 break;
781
782 case OPT_FILTER:
783 parse_rule(&filter_list, poptGetOptArg(pc), 0, 0);
784 break;
785
786 case OPT_EXCLUDE:
787 parse_rule(&filter_list, poptGetOptArg(pc),
788 0, XFLG_OLD_PREFIXES);
789 break;
790
791 case OPT_INCLUDE:
792 parse_rule(&filter_list, poptGetOptArg(pc),
793 MATCHFLG_INCLUDE, XFLG_OLD_PREFIXES);
794 break;
795
796 case OPT_EXCLUDE_FROM:
797 case OPT_INCLUDE_FROM:
798 arg = poptGetOptArg(pc);
799 if (sanitize_paths)
800 arg = sanitize_path(NULL, arg, NULL, 0);
801 if (server_filter_list.head) {
802 char *cp = (char *)arg;
803 if (!*cp)
804 goto options_rejected;
805 clean_fname(cp, 1);
806 if (check_filter(&server_filter_list, cp, 0) < 0)
807 goto options_rejected;
808 }
809 parse_filter_file(&filter_list, arg,
810 opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
811 XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
812 break;
813
814 case 'a':
815 if (refused_archive_part) {
816 create_refuse_error(refused_archive_part);
817 return 0;
818 }
819 if (!recurse) /* preserve recurse == 2 */
820 recurse = 1;
821#ifdef SUPPORT_LINKS
822 preserve_links = 1;
823#endif
824 preserve_perms = 1;
825 preserve_times = 1;
826 preserve_gid = 1;
827 preserve_uid = 1;
828 preserve_devices = 1;
829 break;
830
831 case 'h':
832 usage(FINFO);
833 exit_cleanup(0);
834
835 case 'v':
836 verbose++;
837 break;
838
839 case 'q':
840 if (frommain)
841 quiet++;
842 break;
843
844 case OPT_SENDER:
845 if (!am_server) {
846 usage(FERROR);
847 exit_cleanup(RERR_SYNTAX);
848 }
849 am_sender = 1;
850 break;
851
852 case 'F':
853 switch (++F_option_cnt) {
854 case 1:
855 parse_rule(&filter_list,": /.rsync-filter",0,0);
856 break;
857 case 2:
858 parse_rule(&filter_list,"- .rsync-filter",0,0);
859 break;
860 }
861 break;
862
863 case 'P':
864 if (refused_partial || refused_progress) {
865 create_refuse_error(refused_partial
866 ? refused_partial : refused_progress);
867 return 0;
868 }
869 do_progress = 1;
870 keep_partial = 1;
871 break;
872
873 case OPT_WRITE_BATCH:
874 /* batch_name is already set */
875 write_batch = 1;
876 break;
877
878 case OPT_ONLY_WRITE_BATCH:
879 /* batch_name is already set */
880 write_batch = -1;
881 break;
882
883 case OPT_READ_BATCH:
884 /* batch_name is already set */
885 read_batch = 1;
886 break;
887
888 case OPT_MAX_SIZE:
889 if ((max_size = parse_size_arg(max_size_arg)) <= 0) {
890 snprintf(err_buf, sizeof err_buf,
891 "--max-size value is invalid: %s\n",
892 max_size_arg);
893 return 0;
894 }
895 break;
896
897 case OPT_LINK_DEST:
898#ifdef HAVE_LINK
899 link_dest = 1;
900 dest_option = "--link-dest";
901 goto set_dest_dir;
902#else
903 snprintf(err_buf, sizeof err_buf,
904 "hard links are not supported on this %s\n",
905 am_server ? "server" : "client");
906 return 0;
907#endif
908
909 case OPT_COPY_DEST:
910 copy_dest = 1;
911 dest_option = "--copy-dest";
912 goto set_dest_dir;
913
914 case OPT_COMPARE_DEST:
915 compare_dest = 1;
916 dest_option = "--compare-dest";
917 set_dest_dir:
918 if (basis_dir_cnt >= MAX_BASIS_DIRS) {
919 snprintf(err_buf, sizeof err_buf,
920 "ERROR: at most %d %s args may be specified\n",
921 MAX_BASIS_DIRS, dest_option);
922 return 0;
923 }
924 arg = poptGetOptArg(pc);
925 if (sanitize_paths)
926 arg = sanitize_path(NULL, arg, NULL, 0);
927 basis_dir[basis_dir_cnt++] = (char *)arg;
928 break;
929
930 default:
931 /* A large opt value means that set_refuse_options()
932 * turned this option off. */
933 if (opt >= OPT_REFUSED_BASE) {
934 create_refuse_error(opt);
935 return 0;
936 }
937 snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
938 am_server ? "on remote machine: " : "",
939 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
940 poptStrerror(opt));
941 return 0;
942 }
943 }
944
945#ifndef SUPPORT_LINKS
946 if (preserve_links && !am_sender) {
947 snprintf(err_buf, sizeof err_buf,
948 "symlinks are not supported on this %s\n",
949 am_server ? "server" : "client");
950 return 0;
951 }
952#endif
953
954#ifndef SUPPORT_HARD_LINKS
955 if (preserve_hard_links) {
956 snprintf(err_buf, sizeof err_buf,
957 "hard links are not supported on this %s\n",
958 am_server ? "server" : "client");
959 return 0;
960 }
961#endif
962
963 if (write_batch && read_batch) {
964 snprintf(err_buf, sizeof err_buf,
965 "--write-batch and --read-batch can not be used together\n");
966 return 0;
967 }
968 if (write_batch > 0 || read_batch) {
969 if (am_server) {
970 rprintf(FINFO,
971 "ignoring --%s-batch option sent to server\n",
972 write_batch ? "write" : "read");
973 /* We don't actually exit_cleanup(), so that we can
974 * still service older version clients that still send
975 * batch args to server. */
976 read_batch = write_batch = 0;
977 batch_name = NULL;
978 } else if (dry_run)
979 write_batch = 0;
980 }
981 if (read_batch && files_from) {
982 snprintf(err_buf, sizeof err_buf,
983 "--read-batch cannot be used with --files-from\n");
984 return 0;
985 }
986 if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
987 snprintf(err_buf, sizeof err_buf,
988 "the batch-file name must be %d characters or less.\n",
989 MAX_BATCH_NAME_LEN);
990 return 0;
991 }
992
993 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
994 snprintf(err_buf, sizeof err_buf,
995 "the --temp-dir path is WAY too long.\n");
996 return 0;
997 }
998
999 if (compare_dest + copy_dest + link_dest > 1) {
1000 snprintf(err_buf, sizeof err_buf,
1001 "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
1002 return 0;
1003 }
1004
1005 if (files_from) {
1006 if (recurse == 1) /* preserve recurse == 2 */
1007 recurse = 0;
1008 if (xfer_dirs < 1)
1009 xfer_dirs = 1;
1010 }
1011
1012 if (xfer_dirs < 1)
1013 xfer_dirs = recurse || list_only;
1014
1015 if (relative_paths < 0)
1016 relative_paths = files_from? 1 : 0;
1017 if (!relative_paths)
1018 implied_dirs = 0;
1019
1020 if (!!delete_before + delete_during + delete_after > 1) {
1021 snprintf(err_buf, sizeof err_buf,
1022 "You may not combine multiple --delete-WHEN options.\n");
1023 return 0;
1024 }
1025 if (!xfer_dirs) {
1026 delete_before = delete_during = delete_after = 0;
1027 delete_mode = delete_excluded = 0;
1028 } else if (delete_before || delete_during || delete_after)
1029 delete_mode = 1;
1030 else if (delete_mode || delete_excluded) {
1031 if (refused_delete_before) {
1032 create_refuse_error(refused_delete_before);
1033 return 0;
1034 }
1035 delete_mode = delete_before = 1;
1036 }
1037
1038 if (delete_mode && refused_delete) {
1039 create_refuse_error(refused_delete);
1040 return 0;
1041 }
1042
1043 if (remove_sent_files) {
1044 /* We only want to infer this refusal of --remove-sent-files
1045 * via the refusal of "delete", not any of the "delete-FOO"
1046 * options. */
1047 if (refused_delete && am_sender) {
1048 create_refuse_error(refused_delete);
1049 return 0;
1050 }
1051 need_messages_from_generator = 1;
1052 }
1053
1054 *argv = poptGetArgs(pc);
1055 *argc = count_args(*argv);
1056
1057 if (sanitize_paths) {
1058 int i;
1059 for (i = *argc; i-- > 0; )
1060 (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
1061 if (tmpdir)
1062 tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
1063 if (partial_dir)
1064 partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
1065 if (backup_dir)
1066 backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
1067 }
1068 if (server_filter_list.head && !am_sender) {
1069 struct filter_list_struct *elp = &server_filter_list;
1070 int i;
1071 if (tmpdir) {
1072 if (!*tmpdir)
1073 goto options_rejected;
1074 clean_fname(tmpdir, 1);
1075 if (check_filter(elp, tmpdir, 1) < 0)
1076 goto options_rejected;
1077 }
1078 if (partial_dir && *partial_dir) {
1079 clean_fname(partial_dir, 1);
1080 if (check_filter(elp, partial_dir, 1) < 0)
1081 goto options_rejected;
1082 }
1083 for (i = 0; i < basis_dir_cnt; i++) {
1084 if (!*basis_dir[i])
1085 goto options_rejected;
1086 clean_fname(basis_dir[i], 1);
1087 if (check_filter(elp, basis_dir[i], 1) < 0)
1088 goto options_rejected;
1089 }
1090 if (backup_dir) {
1091 if (!*backup_dir)
1092 goto options_rejected;
1093 clean_fname(backup_dir, 1);
1094 if (check_filter(elp, backup_dir, 1) < 0) {
1095 options_rejected:
1096 snprintf(err_buf, sizeof err_buf,
1097 "Your options have been rejected by the server.\n");
1098 return 0;
1099 }
1100 }
1101 }
1102
1103 if (!backup_suffix)
1104 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
1105 backup_suffix_len = strlen(backup_suffix);
1106 if (strchr(backup_suffix, '/') != NULL) {
1107 snprintf(err_buf, sizeof err_buf,
1108 "--suffix cannot contain slashes: %s\n",
1109 backup_suffix);
1110 return 0;
1111 }
1112 if (backup_dir) {
1113 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
1114 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
1115 if (backup_dir_remainder < 32) {
1116 snprintf(err_buf, sizeof err_buf,
1117 "the --backup-dir path is WAY too long.\n");
1118 return 0;
1119 }
1120 if (backup_dir_buf[backup_dir_len - 1] != '/') {
1121 backup_dir_buf[backup_dir_len++] = '/';
1122 backup_dir_buf[backup_dir_len] = '\0';
1123 }
1124 if (verbose > 1 && !am_sender) {
1125 rprintf(FINFO, "backup_dir is %s\n",
1126 safe_fname(backup_dir_buf));
1127 }
1128 } else if (!backup_suffix_len && (!am_server || !am_sender)) {
1129 snprintf(err_buf, sizeof err_buf,
1130 "--suffix cannot be a null string without --backup-dir\n");
1131 return 0;
1132 }
1133 if (make_backups && !backup_dir)
1134 omit_dir_times = 1;
1135
1136 if (log_format) {
1137 if (log_format_has(log_format, 'i'))
1138 log_format_has_i = 1;
1139 if (!log_format_has(log_format, 'b')
1140 && !log_format_has(log_format, 'c'))
1141 log_before_transfer = !am_server;
1142 } else if (itemize_changes) {
1143 log_format = "%i %n%L";
1144 log_format_has_i = 1;
1145 log_before_transfer = !am_server;
1146 }
1147
1148 if ((do_progress || dry_run) && !verbose && !log_before_transfer
1149 && !am_server)
1150 verbose = 1;
1151
1152 if (dry_run)
1153 do_xfers = 0;
1154
1155 set_io_timeout(io_timeout);
1156
1157 if (verbose && !log_format) {
1158 log_format = "%n%L";
1159 log_before_transfer = !am_server;
1160 }
1161 if (log_format_has_i || log_format_has(log_format, 'o'))
1162 log_format_has_o_or_i = 1;
1163
1164 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1165 bwlimit = daemon_bwlimit;
1166 if (bwlimit) {
1167 bwlimit_writemax = (size_t)bwlimit * 128;
1168 if (bwlimit_writemax < 512)
1169 bwlimit_writemax = 512;
1170 }
1171
1172 if (sparse_files && inplace) {
1173 /* Note: we don't check for this below, because --append is
1174 * OK with --sparse (as long as redos are handled right). */
1175 snprintf(err_buf, sizeof err_buf,
1176 "--sparse cannot be used with --inplace\n");
1177 return 0;
1178 }
1179
1180 if (append_mode) {
1181 if (whole_file > 0) {
1182 snprintf(err_buf, sizeof err_buf,
1183 "--append cannot be used with --whole-file\n");
1184 return 0;
1185 }
1186 if (refused_inplace) {
1187 create_refuse_error(refused_inplace);
1188 return 0;
1189 }
1190 inplace = 1;
1191 }
1192
1193 if (delay_updates && !partial_dir)
1194 partial_dir = partialdir_for_delayupdate;
1195
1196 if (inplace) {
1197#ifdef HAVE_FTRUNCATE
1198 if (partial_dir) {
1199 snprintf(err_buf, sizeof err_buf,
1200 "--%s cannot be used with --%s\n",
1201 append_mode ? "append" : "inplace",
1202 delay_updates ? "delay-updates" : "partial-dir");
1203 return 0;
1204 }
1205 /* --inplace implies --partial for refusal purposes, but we
1206 * clear the keep_partial flag for internal logic purposes. */
1207 if (refused_partial) {
1208 create_refuse_error(refused_partial);
1209 return 0;
1210 }
1211 keep_partial = 0;
1212#else
1213 snprintf(err_buf, sizeof err_buf,
1214 "--%s is not supported on this %s\n",
1215 append_mode ? "append" : "inplace",
1216 am_server ? "server" : "client");
1217 return 0;
1218#endif
1219 } else {
1220 if (keep_partial && !partial_dir) {
1221 if ((arg = getenv("RSYNC_PARTIAL_DIR")) != NULL && *arg)
1222 partial_dir = strdup(arg);
1223 }
1224 if (partial_dir) {
1225 if (*partial_dir)
1226 clean_fname(partial_dir, 1);
1227 if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1228 partial_dir = NULL;
1229 else if (*partial_dir != '/') {
1230 parse_rule(&filter_list, partial_dir,
1231 MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
1232 }
1233 if (!partial_dir && refused_partial) {
1234 create_refuse_error(refused_partial);
1235 return 0;
1236 }
1237 keep_partial = 1;
1238 }
1239 }
1240
1241 if (files_from) {
1242 char *h, *p;
1243 int q;
1244 if (*argc > 2 || (!am_daemon && *argc == 1)) {
1245 usage(FERROR);
1246 exit_cleanup(RERR_SYNTAX);
1247 }
1248 if (strcmp(files_from, "-") == 0) {
1249 filesfrom_fd = 0;
1250 if (am_server)
1251 filesfrom_host = ""; /* reading from socket */
1252 } else if ((p = check_for_hostspec(files_from, &h, &q)) != 0) {
1253 if (am_server) {
1254 snprintf(err_buf, sizeof err_buf,
1255 "The --files-from sent to the server cannot specify a host.\n");
1256 return 0;
1257 }
1258 files_from = p;
1259 filesfrom_host = h;
1260 if (strcmp(files_from, "-") == 0) {
1261 snprintf(err_buf, sizeof err_buf,
1262 "Invalid --files-from remote filename\n");
1263 return 0;
1264 }
1265 } else {
1266 if (sanitize_paths)
1267 files_from = sanitize_path(NULL, files_from, NULL, 0);
1268 if (server_filter_list.head) {
1269 if (!*files_from)
1270 goto options_rejected;
1271 clean_fname(files_from, 1);
1272 if (check_filter(&server_filter_list, files_from, 0) < 0)
1273 goto options_rejected;
1274 }
1275 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1276 if (filesfrom_fd < 0) {
1277 snprintf(err_buf, sizeof err_buf,
1278 "failed to open files-from file %s: %s\n",
1279 files_from, strerror(errno));
1280 return 0;
1281 }
1282 }
1283 }
1284
1285 am_starting_up = 0;
1286
1287 return 1;
1288}
1289
1290
1291/**
1292 * Construct a filtered list of options to pass through from the
1293 * client to the server.
1294 *
1295 * This involves setting options that will tell the server how to
1296 * behave, and also filtering out options that are processed only
1297 * locally.
1298 **/
1299void server_options(char **args,int *argc)
1300{
1301 static char argstr[64];
1302 int ac = *argc;
1303 char *arg;
1304
1305 int i, x;
1306
1307 if (blocking_io == -1)
1308 blocking_io = 0;
1309
1310 args[ac++] = "--server";
1311
1312 if (daemon_over_rsh) {
1313 args[ac++] = "--daemon";
1314 *argc = ac;
1315 /* if we're passing --daemon, we're done */
1316 return;
1317 }
1318
1319 if (!am_sender)
1320 args[ac++] = "--sender";
1321
1322 x = 1;
1323 argstr[0] = '-';
1324 for (i = 0; i < verbose; i++)
1325 argstr[x++] = 'v';
1326
1327 /* the -q option is intentionally left out */
1328 if (make_backups)
1329 argstr[x++] = 'b';
1330 if (update_only)
1331 argstr[x++] = 'u';
1332 if (!do_xfers) /* NOT "dry_run"! */
1333 argstr[x++] = 'n';
1334 if (preserve_links)
1335 argstr[x++] = 'l';
1336 if (copy_links)
1337 argstr[x++] = 'L';
1338 if (xfer_dirs > 1)
1339 argstr[x++] = 'd';
1340 if (keep_dirlinks && am_sender)
1341 argstr[x++] = 'K';
1342
1343 if (whole_file > 0)
1344 argstr[x++] = 'W';
1345 /* We don't need to send --no-whole-file, because it's the
1346 * default for remote transfers, and in any case old versions
1347 * of rsync will not understand it. */
1348
1349 if (preserve_hard_links)
1350 argstr[x++] = 'H';
1351 if (preserve_uid)
1352 argstr[x++] = 'o';
1353 if (preserve_gid)
1354 argstr[x++] = 'g';
1355 if (preserve_devices)
1356 argstr[x++] = 'D';
1357 if (preserve_times)
1358 argstr[x++] = 't';
1359 if (omit_dir_times == 2 && am_sender)
1360 argstr[x++] = 'O';
1361 if (preserve_perms)
1362 argstr[x++] = 'p';
1363 if (recurse)
1364 argstr[x++] = 'r';
1365 if (always_checksum)
1366 argstr[x++] = 'c';
1367 if (cvs_exclude)
1368 argstr[x++] = 'C';
1369 if (ignore_times)
1370 argstr[x++] = 'I';
1371 if (relative_paths)
1372 argstr[x++] = 'R';
1373 if (one_file_system)
1374 argstr[x++] = 'x';
1375 if (sparse_files)
1376 argstr[x++] = 'S';
1377 if (do_compression)
1378 argstr[x++] = 'z';
1379
1380 /* This is a complete hack - blame Rusty. FIXME!
1381 * This hack is only needed for older rsync versions that
1382 * don't understand the --list-only option. */
1383 if (list_only == 1 && !recurse)
1384 argstr[x++] = 'r';
1385
1386 argstr[x] = 0;
1387
1388 if (x != 1)
1389 args[ac++] = argstr;
1390
1391 if (list_only > 1)
1392 args[ac++] = "--list-only";
1393
1394 /* The server side doesn't use our log-format, but in certain
1395 * circumstances they need to know a little about the option. */
1396 if (log_format && am_sender) {
1397 if (log_format_has_i)
1398 args[ac++] = "--log-format=%i";
1399 else if (log_format_has_o_or_i)
1400 args[ac++] = "--log-format=%o";
1401 else if (!verbose)
1402 args[ac++] = "--log-format=X";
1403 }
1404
1405 if (block_size) {
1406 if (asprintf(&arg, "-B%lu", block_size) < 0)
1407 goto oom;
1408 args[ac++] = arg;
1409 }
1410
1411 if (max_delete && am_sender) {
1412 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1413 goto oom;
1414 args[ac++] = arg;
1415 }
1416
1417 if (max_size && am_sender) {
1418 args[ac++] = "--max-size";
1419 args[ac++] = max_size_arg;
1420 }
1421
1422 if (io_timeout) {
1423 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1424 goto oom;
1425 args[ac++] = arg;
1426 }
1427
1428 if (bwlimit) {
1429 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1430 goto oom;
1431 args[ac++] = arg;
1432 }
1433
1434 if (backup_dir) {
1435 args[ac++] = "--backup-dir";
1436 args[ac++] = backup_dir;
1437 }
1438
1439 /* Only send --suffix if it specifies a non-default value. */
1440 if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1441 /* We use the following syntax to avoid weirdness with '~'. */
1442 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1443 goto oom;
1444 args[ac++] = arg;
1445 }
1446
1447 if (am_sender) {
1448 if (delete_excluded)
1449 args[ac++] = "--delete-excluded";
1450 else if (delete_before == 1 || delete_after)
1451 args[ac++] = "--delete";
1452 if (delete_before > 1)
1453 args[ac++] = "--delete-before";
1454 if (delete_during)
1455 args[ac++] = "--delete-during";
1456 if (delete_after)
1457 args[ac++] = "--delete-after";
1458 if (force_delete)
1459 args[ac++] = "--force";
1460 if (write_batch < 0)
1461 args[ac++] = "--only-write-batch=X";
1462 }
1463
1464 if (size_only)
1465 args[ac++] = "--size-only";
1466
1467 if (modify_window_set) {
1468 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1469 goto oom;
1470 args[ac++] = arg;
1471 }
1472
1473 if (checksum_seed) {
1474 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1475 goto oom;
1476 args[ac++] = arg;
1477 }
1478
1479 if (partial_dir && am_sender) {
1480 if (partial_dir != partialdir_for_delayupdate) {
1481 args[ac++] = "--partial-dir";
1482 args[ac++] = partial_dir;
1483 }
1484 if (delay_updates)
1485 args[ac++] = "--delay-updates";
1486 } else if (keep_partial)
1487 args[ac++] = "--partial";
1488
1489 if (ignore_errors)
1490 args[ac++] = "--ignore-errors";
1491
1492 if (copy_unsafe_links)
1493 args[ac++] = "--copy-unsafe-links";
1494
1495 if (safe_symlinks)
1496 args[ac++] = "--safe-links";
1497
1498 if (numeric_ids)
1499 args[ac++] = "--numeric-ids";
1500
1501 if (only_existing && am_sender)
1502 args[ac++] = "--existing";
1503
1504 if (opt_ignore_existing && am_sender)
1505 args[ac++] = "--ignore-existing";
1506
1507 if (append_mode)
1508 args[ac++] = "--append";
1509 else if (inplace)
1510 args[ac++] = "--inplace";
1511
1512 if (tmpdir) {
1513 args[ac++] = "--temp-dir";
1514 args[ac++] = tmpdir;
1515 }
1516
1517 if (basis_dir[0] && am_sender) {
1518 /* the server only needs this option if it is not the sender,
1519 * and it may be an older version that doesn't know this
1520 * option, so don't send it if client is the sender.
1521 */
1522 int i;
1523 for (i = 0; i < basis_dir_cnt; i++) {
1524 args[ac++] = dest_option;
1525 args[ac++] = basis_dir[i];
1526 }
1527 }
1528
1529 if (files_from && (!am_sender || filesfrom_host)) {
1530 if (filesfrom_host) {
1531 args[ac++] = "--files-from";
1532 args[ac++] = files_from;
1533 if (eol_nulls)
1534 args[ac++] = "--from0";
1535 } else {
1536 args[ac++] = "--files-from=-";
1537 args[ac++] = "--from0";
1538 }
1539 if (!relative_paths)
1540 args[ac++] = "--no-relative";
1541 }
1542 if (relative_paths && !implied_dirs && !am_sender)
1543 args[ac++] = "--no-implied-dirs";
1544
1545 if (fuzzy_basis && am_sender)
1546 args[ac++] = "--fuzzy";
1547
1548 if (remove_sent_files)
1549 args[ac++] = "--remove-sent-files";
1550
1551 *argc = ac;
1552 return;
1553
1554 oom:
1555 out_of_memory("server_options");
1556}
1557
1558/* Look for a HOST specfication of the form "HOST:PATH", "HOST::PATH", or
1559 * "rsync://HOST:PORT/PATH". If found, *host_ptr will be set to some allocated
1560 * memory with the HOST. If a daemon-accessing spec was specified, the value
1561 * of *port_ptr will contain a non-0 port number, otherwise it will be set to
1562 * 0. The return value is a pointer to the PATH. Note that the HOST spec can
1563 * be an IPv6 literal address enclosed in '[' and ']' (such as "[::1]" or
1564 * "[::ffff:127.0.0.1]") which is returned without the '[' and ']'. */
1565char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
1566{
1567 char *p;
1568 int not_host;
1569
1570 if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) {
1571 char *path;
1572 int hostlen;
1573 s += strlen(URL_PREFIX);
1574 if ((p = strchr(s, '/')) != NULL) {
1575 hostlen = p - s;
1576 path = p + 1;
1577 } else {
1578 hostlen = strlen(s);
1579 path = "";
1580 }
1581 if (*s == '[' && (p = strchr(s, ']')) != NULL) {
1582 s++;
1583 hostlen = p - s;
1584 if (p[1] == ':')
1585 *port_ptr = atoi(p+2);
1586 } else {
1587 if ((p = strchr(s, ':')) != NULL) {
1588 hostlen = p - s;
1589 *port_ptr = atoi(p+1);
1590 }
1591 }
1592 if (!*port_ptr)
1593 *port_ptr = RSYNC_PORT;
1594 *host_ptr = new_array(char, hostlen + 1);
1595 strlcpy(*host_ptr, s, hostlen + 1);
1596 return path;
1597 }
1598
1599 if (*s == '[' && (p = strchr(s, ']')) != NULL && p[1] == ':') {
1600 s++;
1601 *p = '\0';
1602 not_host = strchr(s, '/') || !strchr(s, ':');
1603 *p = ']';
1604 if (not_host)
1605 return NULL;
1606 p++;
1607 } else {
1608 if (!(p = strchr(s, ':')))
1609 return NULL;
1610 *p = '\0';
1611 not_host = strchr(s, '/') != NULL;
1612 *p = ':';
1613 if (not_host)
1614 return NULL;
1615 }
1616
1617 *host_ptr = new_array(char, p - s + 1);
1618 strlcpy(*host_ptr, s, p - s + 1);
1619
1620 if (p[1] == ':') {
1621 if (port_ptr && !*port_ptr)
1622 *port_ptr = RSYNC_PORT;
1623 return p + 2;
1624 }
1625 if (port_ptr)
1626 *port_ptr = 0;
1627
1628 return p + 1;
1629}