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