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