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