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