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