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