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