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