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