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