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