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