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