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