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