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