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