The compare_dest variable changed.
[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 daemon_bwlimit = 0;
88 int bwlimit = 0;
89 size_t bwlimit_writemax = 0;
90 int delete_after = 0;
91 int only_existing = 0;
92 int opt_ignore_existing = 0;
93 int max_delete = 0;
94 OFF_T max_size = 0;
95 int ignore_errors = 0;
96 int modify_window = 0;
97 int blocking_io = -1;
98 int checksum_seed = 0;
99 int inplace = 0;
100 unsigned int block_size = 0;
101
102
103 /** Network address family. **/
104 #ifdef INET6
105 int default_af_hint = 0;        /* Any protocol */
106 #else
107 int 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. **/
113 int no_detach = 0;
114
115 int write_batch = 0;
116 int read_batch = 0;
117 int backup_dir_len = 0;
118 int backup_suffix_len;
119 unsigned int backup_dir_remainder;
120
121 char *backup_suffix = NULL;
122 char *tmpdir = NULL;
123 char *partial_dir = NULL;
124 char *compare_dest = NULL;
125 char *config_file = NULL;
126 char *shell_cmd = NULL;
127 char *log_format = NULL;
128 char *password_file = NULL;
129 char *rsync_path = RSYNC_PATH;
130 char *backup_dir = NULL;
131 char backup_dir_buf[MAXPATHLEN];
132 int rsync_port = RSYNC_PORT;
133 int link_dest = 0;
134
135 int verbose = 0;
136 int quiet = 0;
137 int always_checksum = 0;
138 int list_only = 0;
139
140 #define MAX_BATCH_NAME_LEN 256  /* Must be less than MAXPATHLEN-13 */
141 char *batch_name = NULL;
142
143 static int daemon_opt;   /* sets am_daemon after option error-reporting */
144 static int modify_window_set;
145 static 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. **/
150 char *bind_address;
151
152
153 static 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
218 void 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
316 enum {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
322 static 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
413 static 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
433 static 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
452 static 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  **/
460 void 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  **/
475 static 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
518 static 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  **/
539 int 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  **/
991 void 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  */
1214 char *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 }