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