- Got rid of the iflag kluge for 2.6.4pre3.
[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 do_xfers = 1;
57 int ignore_times = 0;
58 int delete_mode = 0;
59 int delete_during = 0;
60 int delete_before = 0;
61 int delete_after = 0;
62 int delete_excluded = 0;
63 int remove_sent_files = 0;
64 int one_file_system = 0;
65 int protocol_version = PROTOCOL_VERSION;
66 int sparse_files = 0;
67 int do_compression = 0;
68 int am_root = 0;
69 int am_server = 0;
70 int am_sender = 0;
71 int am_generator = 0;
72 int am_starting_up = 1;
73 int orig_umask = 0;
74 int relative_paths = -1;
75 int implied_dirs = 1;
76 int numeric_ids = 0;
77 int force_delete = 0;
78 int io_timeout = 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 file lists are delimited by nulls\n");
335   rprintf(F,"     --version               print version number\n");
336   rprintf(F,"     --address=ADDRESS       bind address for outgoing socket to daemon\n");
337   rprintf(F,"     --port=PORT             specify double-colon alternate port number\n");
338   rprintf(F,"     --blocking-io           use blocking I/O for the remote shell\n");
339   rprintf(F,"     --no-blocking-io        turn off blocking I/O when it is the default\n");
340   rprintf(F,"     --stats                 give some file-transfer stats\n");
341   rprintf(F,"     --progress              show progress during transfer\n");
342   rprintf(F," -P                          same as --partial --progress\n");
343   rprintf(F," -i, --itemize-changes       output a change-summary for all updates\n");
344   rprintf(F,"     --log-format=FORMAT     log file-transfers using specified format\n");
345   rprintf(F,"     --password-file=FILE    read password from FILE\n");
346   rprintf(F,"     --list-only             list the files instead of copying them\n");
347   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth; KBytes per second\n");
348   rprintf(F,"     --write-batch=FILE      write a batched update to FILE\n");
349   rprintf(F,"     --only-write-batch=FILE like --write-batch but w/o updating destination\n");
350   rprintf(F,"     --read-batch=FILE       read a batched update from FILE\n");
351   rprintf(F,"     --protocol=NUM          force an older protocol version to be used\n");
352 #ifdef INET6
353   rprintf(F," -4, --ipv4                  prefer IPv4\n");
354   rprintf(F," -6, --ipv6                  prefer IPv6\n");
355 #endif
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,
367       OPT_TIMEOUT, OPT_MAX_SIZE,
368       OPT_REFUSED_BASE = 9000};
369
370 static struct poptOption long_options[] = {
371   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
372   {"version",          0,  POPT_ARG_NONE,   0, OPT_VERSION, 0, 0},
373   {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
374   {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
375   {"password-file",    0,  POPT_ARG_STRING, &password_file, 0, 0, 0 },
376   {"ignore-times",    'I', POPT_ARG_NONE,   &ignore_times, 0, 0, 0 },
377   {"size-only",        0,  POPT_ARG_NONE,   &size_only, 0, 0, 0 },
378   {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
379   {"one-file-system", 'x', POPT_ARG_NONE,   &one_file_system, 0, 0, 0 },
380   {"existing",         0,  POPT_ARG_NONE,   &only_existing, 0, 0, 0 },
381   {"ignore-existing",  0,  POPT_ARG_NONE,   &opt_ignore_existing, 0, 0, 0 },
382   {"del",              0,  POPT_ARG_NONE,   &delete_during, 0, 0, 0 },
383   {"delete",           0,  POPT_ARG_NONE,   &delete_mode, 0, 0, 0 },
384   {"delete-before",    0,  POPT_ARG_VAL,    &delete_before, 2, 0, 0 },
385   {"delete-during",    0,  POPT_ARG_NONE,   &delete_during, 0, 0, 0 },
386   {"delete-after",     0,  POPT_ARG_NONE,   &delete_after, 0, 0, 0 },
387   {"delete-excluded",  0,  POPT_ARG_NONE,   &delete_excluded, 0, 0, 0 },
388   {"remove-sent-files",0,  POPT_ARG_NONE,   &remove_sent_files, 0, 0, 0 },
389   {"force",            0,  POPT_ARG_NONE,   &force_delete, 0, 0, 0 },
390   {"numeric-ids",      0,  POPT_ARG_NONE,   &numeric_ids, 0, 0, 0 },
391   {"filter",          'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
392   {"exclude",          0,  POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
393   {"include",          0,  POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
394   {"exclude-from",     0,  POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
395   {"include-from",     0,  POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
396   {"safe-links",       0,  POPT_ARG_NONE,   &safe_symlinks, 0, 0, 0 },
397   {"help",            'h', POPT_ARG_NONE,   0, 'h', 0, 0 },
398   {"backup",          'b', POPT_ARG_NONE,   &make_backups, 0, 0, 0 },
399   {"dry-run",         'n', POPT_ARG_NONE,   &dry_run, 0, 0, 0 },
400   {"sparse",          'S', POPT_ARG_NONE,   &sparse_files, 0, 0, 0 },
401   {"cvs-exclude",     'C', POPT_ARG_NONE,   &cvs_exclude, 0, 0, 0 },
402   {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
403   {"inplace",          0,  POPT_ARG_NONE,   &inplace, 0, 0, 0 },
404   {"dirs",            'd', POPT_ARG_VAL,    &xfer_dirs, 2, 0, 0 },
405   {"links",           'l', POPT_ARG_NONE,   &preserve_links, 0, 0, 0 },
406   {"copy-links",      'L', POPT_ARG_NONE,   &copy_links, 0, 0, 0 },
407   {"keep-dirlinks",   'K', POPT_ARG_NONE,   &keep_dirlinks, 0, 0, 0 },
408   {"whole-file",      'W', POPT_ARG_VAL,    &whole_file, 1, 0, 0 },
409   {"no-whole-file",    0,  POPT_ARG_VAL,    &whole_file, 0, 0, 0 },
410   {"copy-unsafe-links",0,  POPT_ARG_NONE,   &copy_unsafe_links, 0, 0, 0 },
411   {"perms",           'p', POPT_ARG_NONE,   &preserve_perms, 0, 0, 0 },
412   {"owner",           'o', POPT_ARG_NONE,   &preserve_uid, 0, 0, 0 },
413   {"group",           'g', POPT_ARG_NONE,   &preserve_gid, 0, 0, 0 },
414   {"devices",         'D', POPT_ARG_NONE,   &preserve_devices, 0, 0, 0 },
415   {"times",           't', POPT_ARG_NONE,   &preserve_times, 0, 0, 0 },
416   {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
417   {"checksum",        'c', POPT_ARG_NONE,   &always_checksum, 0, 0, 0 },
418   {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
419   {"quiet",           'q', POPT_ARG_NONE,   0, 'q', 0, 0 },
420   {"archive",         'a', POPT_ARG_NONE,   &archive_mode, 0, 0, 0 },
421   {"server",           0,  POPT_ARG_NONE,   &am_server, 0, 0, 0 },
422   {"sender",           0,  POPT_ARG_NONE,   0, OPT_SENDER, 0, 0 },
423   {"recursive",       'r', POPT_ARG_NONE,   &recurse, 0, 0, 0 },
424   {"list-only",        0,  POPT_ARG_VAL,    &list_only, 2, 0, 0 },
425   {"relative",        'R', POPT_ARG_VAL,    &relative_paths, 1, 0, 0 },
426   {"no-relative",      0,  POPT_ARG_VAL,    &relative_paths, 0, 0, 0 },
427   {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
428   {"block-size",      'B', POPT_ARG_LONG,   &block_size, 0, 0, 0 },
429   {"max-delete",       0,  POPT_ARG_INT,    &max_delete, 0, 0, 0 },
430   {"max-size",         0,  POPT_ARG_STRING, &max_size_arg,  OPT_MAX_SIZE, 0, 0 },
431   {"timeout",          0,  POPT_ARG_INT,    &io_timeout, OPT_TIMEOUT, 0, 0 },
432   {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
433   {"compare-dest",     0,  POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
434   {"copy-dest",        0,  POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
435   {"link-dest",        0,  POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
436   {"fuzzy",           'y', POPT_ARG_NONE,   &fuzzy_basis, 0, 0, 0 },
437   /* TODO: Should this take an optional int giving the compression level? */
438   {"compress",        'z', POPT_ARG_NONE,   &do_compression, 0, 0, 0 },
439   {"stats",            0,  POPT_ARG_NONE,   &do_stats, 0, 0, 0 },
440   {"progress",         0,  POPT_ARG_NONE,   &do_progress, 0, 0, 0 },
441   {"partial",          0,  POPT_ARG_NONE,   &keep_partial, 0, 0, 0 },
442   {"partial-dir",      0,  POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
443   {"delay-updates",    0,  POPT_ARG_NONE,   &delay_updates, 0, 0, 0 },
444   {"ignore-errors",    0,  POPT_ARG_NONE,   &ignore_errors, 0, 0, 0 },
445   {"blocking-io",      0,  POPT_ARG_VAL,    &blocking_io, 1, 0, 0 },
446   {"no-blocking-io",   0,  POPT_ARG_VAL,    &blocking_io, 0, 0, 0 },
447   {0,                 'F', POPT_ARG_NONE,   0, 'F', 0, 0 },
448   {0,                 'P', POPT_ARG_NONE,   0, 'P', 0, 0 },
449   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
450   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
451   {"log-format",       0,  POPT_ARG_STRING, &log_format, 0, 0, 0 },
452   {"itemize-changes", 'i', POPT_ARG_NONE,   &itemize_changes, 0, 0, 0 },
453   {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit, 0, 0, 0 },
454   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
455   {"hard-links",      'H', POPT_ARG_NONE,   &preserve_hard_links, 0, 0, 0 },
456   {"read-batch",       0,  POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
457   {"write-batch",      0,  POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
458   {"only-write-batch", 0,  POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 },
459   {"files-from",       0,  POPT_ARG_STRING, &files_from, 0, 0, 0 },
460   {"from0",           '0', POPT_ARG_NONE,   &eol_nulls, 0, 0, 0},
461   {"no-implied-dirs",  0,  POPT_ARG_VAL,    &implied_dirs, 0, 0, 0 },
462   {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
463   {"checksum-seed",    0,  POPT_ARG_INT,    &checksum_seed, 0, 0, 0 },
464 #ifdef INET6
465   {"ipv4",            '4', POPT_ARG_VAL,    &default_af_hint, AF_INET, 0, 0 },
466   {"ipv6",            '6', POPT_ARG_VAL,    &default_af_hint, AF_INET6, 0, 0 },
467 #endif
468   /* All these options switch us into daemon-mode option-parsing. */
469   {"config",           0,  POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
470   {"daemon",           0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
471   {"detach",           0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
472   {"no-detach",        0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
473   {0,0,0,0, 0, 0, 0}
474 };
475
476 static void daemon_usage(enum logcode F)
477 {
478   print_rsync_version(F);
479
480   rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
481   rprintf(F,"     --address=ADDRESS       bind to the specified address\n");
482   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth; KBytes per second\n");
483   rprintf(F,"     --config=FILE           specify alternate rsyncd.conf file\n");
484   rprintf(F,"     --no-detach             do not detach from the parent\n");
485   rprintf(F,"     --port=PORT             listen on alternate port number\n");
486   rprintf(F," -v, --verbose               increase verbosity\n");
487 #ifdef INET6
488   rprintf(F," -4, --ipv4                  prefer IPv4\n");
489   rprintf(F," -6, --ipv6                  prefer IPv6\n");
490 #endif
491   rprintf(F," -h, --help                  show this help screen\n");
492
493   rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
494   rprintf(F,"daemon-specific rsync options.  See also the rsyncd.conf(5) man page.\n");
495 }
496
497 static struct poptOption long_daemon_options[] = {
498   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
499   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
500   {"bwlimit",          0,  POPT_ARG_INT,    &daemon_bwlimit, 0, 0, 0 },
501   {"config",           0,  POPT_ARG_STRING, &config_file, 0, 0, 0 },
502   {"daemon",           0,  POPT_ARG_NONE,   &daemon_opt, 0, 0, 0 },
503 #ifdef INET6
504   {"ipv4",            '4', POPT_ARG_VAL,    &default_af_hint, AF_INET, 0, 0 },
505   {"ipv6",            '6', POPT_ARG_VAL,    &default_af_hint, AF_INET6, 0, 0 },
506 #endif
507   {"detach",           0,  POPT_ARG_VAL,    &no_detach, 0, 0, 0 },
508   {"no-detach",        0,  POPT_ARG_VAL,    &no_detach, 1, 0, 0 },
509   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
510   {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
511   {"server",           0,  POPT_ARG_NONE,   &am_server, 0, 0, 0 },
512   {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
513   {"help",            'h', POPT_ARG_NONE,   0, 'h', 0, 0 },
514   {0,0,0,0, 0, 0, 0}
515 };
516
517
518 static char err_buf[200];
519
520
521 /**
522  * Store the option error message, if any, so that we can log the
523  * connection attempt (which requires parsing the options), and then
524  * show the error later on.
525  **/
526 void option_error(void)
527 {
528         if (!err_buf[0]) {
529                 strcpy(err_buf, "Error parsing options: "
530                     "option may be supported on client but not on server?\n");
531         }
532
533         rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
534 }
535
536
537 /**
538  * Tweak the option table to disable all options that the rsyncd.conf
539  * file has told us to refuse.
540  **/
541 static void set_refuse_options(char *bp)
542 {
543         struct poptOption *op;
544         char *cp, shortname[2];
545         int is_wild, found_match;
546
547         shortname[1] = '\0';
548
549         while (1) {
550                 while (*bp == ' ') bp++;
551                 if (!*bp)
552                         break;
553                 if ((cp = strchr(bp, ' ')) != NULL)
554                         *cp= '\0';
555                 is_wild = strpbrk(bp, "*?[") != NULL;
556                 found_match = 0;
557                 for (op = long_options; ; op++) {
558                         *shortname = op->shortName;
559                         if (!op->longName && !*shortname)
560                                 break;
561                         if ((op->longName && wildmatch(bp, op->longName))
562                             || (*shortname && wildmatch(bp, shortname))) {
563                                 if (op->argInfo == POPT_ARG_VAL)
564                                         op->argInfo = POPT_ARG_NONE;
565                                 op->val = (op - long_options) + OPT_REFUSED_BASE;
566                                 found_match = 1;
567                                 /* These flags are set to let us easily check
568                                  * an implied option later in the code. */
569                                 switch (*shortname) {
570                                 case 'r': case 'd': case 'l': case 'p':
571                                 case 't': case 'g': case 'o': case 'D':
572                                         refused_archive_part = op->val;
573                                         break;
574                                 case '\0':
575                                         if (wildmatch("delete", op->longName))
576                                                 refused_delete = op->val;
577                                         else if (wildmatch("delete-before", op->longName))
578                                                 refused_delete_before = op->val;
579                                         else if (wildmatch("partial", op->longName))
580                                                 refused_partial = op->val;
581                                         else if (wildmatch("progress", op->longName))
582                                                 refused_progress = op->val;
583                                         break;
584                                 }
585                                 if (!is_wild)
586                                         break;
587                         }
588                 }
589                 if (!found_match) {
590                         rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
591                                 bp);
592                 }
593                 if (!cp)
594                         break;
595                 *cp = ' ';
596                 bp = cp + 1;
597         }
598
599         for (op = long_options; ; op++) {
600                 *shortname = op->shortName;
601                 if (!op->longName && !*shortname)
602                         break;
603                 if (op->val == OPT_DAEMON) {
604                         if (op->argInfo == POPT_ARG_VAL)
605                                 op->argInfo = POPT_ARG_NONE;
606                         op->val = (op - long_options) + OPT_REFUSED_BASE;
607                 }
608         }
609 }
610
611
612 static int count_args(const char **argv)
613 {
614         int i = 0;
615
616         if (argv) {
617                 while (argv[i] != NULL)
618                         i++;
619         }
620
621         return i;
622 }
623
624
625 static void create_refuse_error(int which)
626 {
627         /* The "which" value is the index + OPT_REFUSED_BASE. */
628         struct poptOption *op = &long_options[which - OPT_REFUSED_BASE];
629         int n = snprintf(err_buf, sizeof err_buf,
630                          "The server is configured to refuse --%s\n",
631                          op->longName) - 1;
632         if (op->shortName) {
633                 snprintf(err_buf + n, sizeof err_buf - n,
634                          " (-%c)\n", op->shortName);
635         }
636 }
637
638
639 /**
640  * Process command line arguments.  Called on both local and remote.
641  *
642  * @retval 1 if all options are OK; with globals set to appropriate
643  * values
644  *
645  * @retval 0 on error, with err_buf containing an explanation
646  **/
647 int parse_arguments(int *argc, const char ***argv, int frommain)
648 {
649         int opt;
650         char *ref = lp_refuse_options(module_id);
651         const char *arg;
652         poptContext pc;
653
654         if (ref && *ref)
655                 set_refuse_options(ref);
656
657         /* TODO: Call poptReadDefaultConfig; handle errors. */
658
659         /* The context leaks in case of an error, but if there's a
660          * problem we always exit anyhow. */
661         pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
662         poptReadDefaultConfig(pc, 0);
663
664         while ((opt = poptGetNextOpt(pc)) != -1) {
665                 /* most options are handled automatically by popt;
666                  * only special cases are returned and listed here. */
667
668                 switch (opt) {
669                 case OPT_VERSION:
670                         print_rsync_version(FINFO);
671                         exit_cleanup(0);
672
673                 case OPT_DAEMON:
674                         if (am_daemon) {
675                                 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
676                                 return 0;
677                         }
678                         poptFreeContext(pc);
679                         pc = poptGetContext(RSYNC_NAME, *argc, *argv,
680                                             long_daemon_options, 0);
681                         while ((opt = poptGetNextOpt(pc)) != -1) {
682                                 switch (opt) {
683                                 case 'h':
684                                         daemon_usage(FINFO);
685                                         exit_cleanup(0);
686
687                                 case 'v':
688                                         verbose++;
689                                         break;
690
691                                 default:
692                                         rprintf(FERROR,
693                                             "rsync: %s: %s (in daemon mode)\n",
694                                             poptBadOption(pc, POPT_BADOPTION_NOALIAS),
695                                             poptStrerror(opt));
696                                         goto daemon_error;
697                                 }
698                         }
699                         if (!daemon_opt) {
700                                 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
701                             daemon_error:
702                                 rprintf(FERROR,
703                                     "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
704                                 exit_cleanup(RERR_SYNTAX);
705                         }
706                         *argv = poptGetArgs(pc);
707                         *argc = count_args(*argv);
708                         am_starting_up = 0;
709                         daemon_opt = 0;
710                         am_daemon = 1;
711                         return 1;
712
713                 case OPT_MODIFY_WINDOW:
714                         /* The value has already been set by popt, but
715                          * we need to remember that we're using a
716                          * non-default setting. */
717                         modify_window_set = 1;
718                         break;
719
720                 case OPT_FILTER:
721                         parse_rule(&filter_list, poptGetOptArg(pc), 0, 0);
722                         break;
723
724                 case OPT_EXCLUDE:
725                         parse_rule(&filter_list, poptGetOptArg(pc),
726                                    0, XFLG_OLD_PREFIXES);
727                         break;
728
729                 case OPT_INCLUDE:
730                         parse_rule(&filter_list, poptGetOptArg(pc),
731                                    MATCHFLG_INCLUDE, XFLG_OLD_PREFIXES);
732                         break;
733
734                 case OPT_EXCLUDE_FROM:
735                 case OPT_INCLUDE_FROM:
736                         arg = poptGetOptArg(pc);
737                         if (sanitize_paths)
738                                 arg = sanitize_path(NULL, arg, NULL, 0);
739                         if (server_filter_list.head) {
740                                 char *cp = (char *)arg;
741                                 if (!*cp)
742                                         goto options_rejected;
743                                 clean_fname(cp, 1);
744                                 if (check_filter(&server_filter_list, cp, 0) < 0)
745                                         goto options_rejected;
746                         }
747                         parse_filter_file(&filter_list, arg,
748                                 opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
749                                 XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
750                         break;
751
752                 case 'h':
753                         usage(FINFO);
754                         exit_cleanup(0);
755
756                 case 'v':
757                         verbose++;
758                         break;
759
760                 case 'q':
761                         if (frommain)
762                                 quiet++;
763                         break;
764
765                 case OPT_SENDER:
766                         if (!am_server) {
767                                 usage(FERROR);
768                                 exit_cleanup(RERR_SYNTAX);
769                         }
770                         am_sender = 1;
771                         break;
772
773                 case 'F':
774                         switch (++F_option_cnt) {
775                         case 1:
776                                 parse_rule(&filter_list,": /.rsync-filter",0,0);
777                                 break;
778                         case 2:
779                                 parse_rule(&filter_list,"- .rsync-filter",0,0);
780                                 break;
781                         }
782                         break;
783
784                 case 'P':
785                         if (refused_partial || refused_progress) {
786                                 create_refuse_error(refused_partial
787                                     ? refused_partial : refused_progress);
788                                 return 0;
789                         }
790                         do_progress = 1;
791                         keep_partial = 1;
792                         break;
793
794                 case OPT_WRITE_BATCH:
795                         /* batch_name is already set */
796                         write_batch = 1;
797                         break;
798
799                 case OPT_ONLY_WRITE_BATCH:
800                         /* batch_name is already set */
801                         write_batch = -1;
802                         break;
803
804                 case OPT_READ_BATCH:
805                         /* batch_name is already set */
806                         read_batch = 1;
807                         break;
808
809                 case OPT_MAX_SIZE:
810                         for (arg = max_size_arg; isdigit(*(uchar*)arg); arg++) {}
811                         if (*arg == '.')
812                                 for (arg++; isdigit(*(uchar*)arg); arg++) {}
813                         switch (*arg) {
814                         case 'k': case 'K':
815                                 max_size = atof(max_size_arg) * 1024;
816                                 break;
817                         case 'm': case 'M':
818                                 max_size = atof(max_size_arg) * 1024*1024;
819                                 break;
820                         case 'g': case 'G':
821                                 max_size = atof(max_size_arg) * 1024*1024*1024;
822                                 break;
823                         case '\0':
824                                 max_size = atof(max_size_arg);
825                                 break;
826                         default:
827                                 max_size = 0;
828                                 break;
829                         }
830                         if (max_size <= 0) {
831                                 snprintf(err_buf, sizeof err_buf,
832                                         "--max-size value is invalid: %s\n",
833                                         max_size_arg);
834                                 return 0;
835                         }
836                         break;
837
838                 case OPT_TIMEOUT:
839                         if (io_timeout && io_timeout < select_timeout)
840                                 select_timeout = io_timeout;
841                         break;
842
843                 case OPT_LINK_DEST:
844 #ifdef HAVE_LINK
845                         link_dest = 1;
846                         dest_option = "--link-dest";
847                         goto set_dest_dir;
848 #else
849                         snprintf(err_buf, sizeof err_buf,
850                                  "hard links are not supported on this %s\n",
851                                  am_server ? "server" : "client");
852                         return 0;
853 #endif
854
855                 case OPT_COPY_DEST:
856                         copy_dest = 1;
857                         dest_option = "--copy-dest";
858                         goto set_dest_dir;
859
860                 case OPT_COMPARE_DEST:
861                         compare_dest = 1;
862                         dest_option = "--compare-dest";
863                 set_dest_dir:
864                         if (basis_dir_cnt >= MAX_BASIS_DIRS) {
865                                 snprintf(err_buf, sizeof err_buf,
866                                         "ERROR: at most %d %s args may be specified\n",
867                                         MAX_BASIS_DIRS, dest_option);
868                                 return 0;
869                         }
870                         arg = poptGetOptArg(pc);
871                         if (sanitize_paths)
872                                 arg = sanitize_path(NULL, arg, NULL, 0);
873                         basis_dir[basis_dir_cnt++] = (char *)arg;
874                         break;
875
876                 default:
877                         /* A large opt value means that set_refuse_options()
878                          * turned this option off. */
879                         if (opt >= OPT_REFUSED_BASE) {
880                                 create_refuse_error(opt);
881                                 return 0;
882                         }
883                         snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
884                                  am_server ? "on remote machine: " : "",
885                                  poptBadOption(pc, POPT_BADOPTION_NOALIAS),
886                                  poptStrerror(opt));
887                         return 0;
888                 }
889         }
890
891 #ifndef SUPPORT_LINKS
892         if (preserve_links && !am_sender) {
893                 snprintf(err_buf, sizeof err_buf,
894                          "symlinks are not supported on this %s\n",
895                          am_server ? "server" : "client");
896                 return 0;
897         }
898 #endif
899
900 #ifndef SUPPORT_HARD_LINKS
901         if (preserve_hard_links) {
902                 snprintf(err_buf, sizeof err_buf,
903                          "hard links are not supported on this %s\n",
904                          am_server ? "server" : "client");
905                 return 0;
906         }
907 #endif
908
909         if (write_batch && read_batch) {
910                 snprintf(err_buf, sizeof err_buf,
911                         "--write-batch and --read-batch can not be used together\n");
912                 return 0;
913         }
914         if (write_batch > 0 || read_batch) {
915                 if (am_server) {
916                         rprintf(FINFO,
917                                 "ignoring --%s-batch option sent to server\n",
918                                 write_batch ? "write" : "read");
919                         /* We don't actually exit_cleanup(), so that we can
920                          * still service older version clients that still send
921                          * batch args to server. */
922                         read_batch = write_batch = 0;
923                         batch_name = NULL;
924                 } else if (dry_run)
925                         write_batch = 0;
926         }
927         if (read_batch && files_from) {
928                 snprintf(err_buf, sizeof err_buf,
929                         "--read-batch cannot be used with --files-from\n");
930                 return 0;
931         }
932         if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
933                 snprintf(err_buf, sizeof err_buf,
934                         "the batch-file name must be %d characters or less.\n",
935                         MAX_BATCH_NAME_LEN);
936                 return 0;
937         }
938
939         if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
940                 snprintf(err_buf, sizeof err_buf,
941                          "the --temp-dir path is WAY too long.\n");
942                 return 0;
943         }
944
945         if (compare_dest + copy_dest + link_dest > 1) {
946                 snprintf(err_buf, sizeof err_buf,
947                         "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
948                 return 0;
949         }
950
951         if (archive_mode) {
952                 if (refused_archive_part) {
953                         create_refuse_error(refused_archive_part);
954                         return 0;
955                 }
956                 if (!files_from)
957                         recurse = 1;
958 #ifdef SUPPORT_LINKS
959                 preserve_links = 1;
960 #endif
961                 preserve_perms = 1;
962                 preserve_times = 1;
963                 preserve_gid = 1;
964                 preserve_uid = 1;
965                 preserve_devices = 1;
966         }
967
968         if (recurse || list_only || files_from)
969                 xfer_dirs |= 1;
970
971         if (relative_paths < 0)
972                 relative_paths = files_from? 1 : 0;
973
974         if (!!delete_before + delete_during + delete_after > 1) {
975                 snprintf(err_buf, sizeof err_buf,
976                         "You may not combine multiple --delete-WHEN options.\n");
977                 return 0;
978         }
979         if (!recurse) {
980                 delete_before = delete_during = delete_after = 0;
981                 delete_mode = delete_excluded = 0;
982         } else if (delete_before || delete_during || delete_after)
983                 delete_mode = 1;
984         else if (delete_mode || delete_excluded) {
985                 if (refused_delete_before) {
986                         create_refuse_error(refused_delete_before);
987                         return 0;
988                 }
989                 delete_mode = delete_before = 1;
990         }
991
992         if (delete_mode && refused_delete) {
993                 create_refuse_error(refused_delete);
994                 return 0;
995         }
996
997         if (remove_sent_files) {
998                 /* We only want to infer this refusal of --remove-sent-files
999                  * via the refusal of "delete", not any of the "delete-FOO"
1000                  * options. */
1001                 if (refused_delete && am_sender) {
1002                         create_refuse_error(refused_delete);
1003                         return 0;
1004                 }
1005                 need_messages_from_generator = 1;
1006         }
1007
1008         *argv = poptGetArgs(pc);
1009         *argc = count_args(*argv);
1010
1011         if (sanitize_paths) {
1012                 int i;
1013                 for (i = *argc; i-- > 0; )
1014                         (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
1015                 if (tmpdir)
1016                         tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
1017                 if (partial_dir)
1018                         partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
1019                 if (backup_dir)
1020                         backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
1021         }
1022         if (server_filter_list.head && !am_sender) {
1023                 struct filter_list_struct *elp = &server_filter_list;
1024                 int i;
1025                 if (tmpdir) {
1026                         if (!*tmpdir)
1027                                 goto options_rejected;
1028                         clean_fname(tmpdir, 1);
1029                         if (check_filter(elp, tmpdir, 1) < 0)
1030                                 goto options_rejected;
1031                 }
1032                 if (partial_dir && *partial_dir) {
1033                         clean_fname(partial_dir, 1);
1034                         if (check_filter(elp, partial_dir, 1) < 0)
1035                                 goto options_rejected;
1036                 }
1037                 for (i = 0; i < basis_dir_cnt; i++) {
1038                         if (!*basis_dir[i])
1039                                 goto options_rejected;
1040                         clean_fname(basis_dir[i], 1);
1041                         if (check_filter(elp, basis_dir[i], 1) < 0)
1042                                 goto options_rejected;
1043                 }
1044                 if (backup_dir) {
1045                         if (!*backup_dir)
1046                                 goto options_rejected;
1047                         clean_fname(backup_dir, 1);
1048                         if (check_filter(elp, backup_dir, 1) < 0) {
1049                             options_rejected:
1050                                 snprintf(err_buf, sizeof err_buf,
1051                                     "Your options have been rejected by the server.\n");
1052                                 return 0;
1053                         }
1054                 }
1055         }
1056
1057         if (!backup_suffix)
1058                 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
1059         backup_suffix_len = strlen(backup_suffix);
1060         if (strchr(backup_suffix, '/') != NULL) {
1061                 snprintf(err_buf, sizeof err_buf,
1062                         "--suffix cannot contain slashes: %s\n",
1063                         backup_suffix);
1064                 return 0;
1065         }
1066         if (backup_dir) {
1067                 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
1068                 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
1069                 if (backup_dir_remainder < 32) {
1070                         snprintf(err_buf, sizeof err_buf,
1071                                 "the --backup-dir path is WAY too long.\n");
1072                         return 0;
1073                 }
1074                 if (backup_dir_buf[backup_dir_len - 1] != '/') {
1075                         backup_dir_buf[backup_dir_len++] = '/';
1076                         backup_dir_buf[backup_dir_len] = '\0';
1077                 }
1078                 if (verbose > 1 && !am_sender) {
1079                         rprintf(FINFO, "backup_dir is %s\n",
1080                                 safe_fname(backup_dir_buf));
1081                 }
1082         } else if (!backup_suffix_len && (!am_server || !am_sender)) {
1083                 snprintf(err_buf, sizeof err_buf,
1084                         "--suffix cannot be a null string without --backup-dir\n");
1085                 return 0;
1086         }
1087         if (make_backups && !backup_dir)
1088                 omit_dir_times = 1;
1089
1090         if (log_format) {
1091                 if (log_format_has(log_format, 'i'))
1092                         log_format_has_i = 1;
1093                 if (!log_format_has(log_format, 'b')
1094                  && !log_format_has(log_format, 'c'))
1095                         log_before_transfer = !am_server;
1096         } else if (itemize_changes) {
1097                 log_format = "%i %n%L";
1098                 log_format_has_i = 1;
1099                 log_before_transfer = !am_server;
1100         }
1101
1102         if ((do_progress || dry_run) && !verbose && !log_before_transfer
1103             && !am_server)
1104                 verbose = 1;
1105
1106         if (dry_run)
1107                 do_xfers = 0;
1108
1109         if (verbose && !log_format) {
1110                 log_format = "%n%L";
1111                 log_before_transfer = !am_server;
1112         }
1113         if (log_format_has_i || log_format_has(log_format, 'o'))
1114                 log_format_has_o_or_i = 1;
1115
1116         if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1117                 bwlimit = daemon_bwlimit;
1118         if (bwlimit) {
1119                 bwlimit_writemax = (size_t)bwlimit * 128;
1120                 if (bwlimit_writemax < 512)
1121                         bwlimit_writemax = 512;
1122         }
1123
1124         if (delay_updates && !partial_dir)
1125                 partial_dir = partialdir_for_delayupdate;
1126
1127         if (inplace) {
1128 #ifdef HAVE_FTRUNCATE
1129                 if (partial_dir) {
1130                         snprintf(err_buf, sizeof err_buf,
1131                                  "--inplace cannot be used with --%s\n",
1132                                  delay_updates ? "delay-updates" : "partial-dir");
1133                         return 0;
1134                 }
1135                 /* --inplace implies --partial for refusal purposes, but we
1136                  * clear the keep_partial flag for internal logic purposes. */
1137                 if (refused_partial) {
1138                         create_refuse_error(refused_partial);
1139                         return 0;
1140                 }
1141                 keep_partial = 0;
1142 #else
1143                 snprintf(err_buf, sizeof err_buf,
1144                          "--inplace is not supported on this %s\n",
1145                          am_server ? "server" : "client");
1146                 return 0;
1147 #endif
1148         } else {
1149                 if (keep_partial && !partial_dir) {
1150                         if ((arg = getenv("RSYNC_PARTIAL_DIR")) != NULL && *arg)
1151                                 partial_dir = strdup(arg);
1152                 }
1153                 if (partial_dir) {
1154                         if (*partial_dir)
1155                                 clean_fname(partial_dir, 1);
1156                         if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1157                                 partial_dir = NULL;
1158                         else if (*partial_dir != '/') {
1159                                 parse_rule(&filter_list, partial_dir,
1160                                     MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
1161                         }
1162                         if (!partial_dir && refused_partial) {
1163                                 create_refuse_error(refused_partial);
1164                                 return 0;
1165                         }
1166                         keep_partial = 1;
1167                 }
1168         }
1169
1170         if (files_from) {
1171                 char *h, *p;
1172                 int q;
1173                 if (*argc > 2 || (!am_daemon && *argc == 1)) {
1174                         usage(FERROR);
1175                         exit_cleanup(RERR_SYNTAX);
1176                 }
1177                 if (strcmp(files_from, "-") == 0) {
1178                         filesfrom_fd = 0;
1179                         if (am_server)
1180                                 filesfrom_host = ""; /* reading from socket */
1181                 } else if ((p = check_for_hostspec(files_from, &h, &q)) != 0) {
1182                         if (am_server) {
1183                                 snprintf(err_buf, sizeof err_buf,
1184                                         "The --files-from sent to the server cannot specify a host.\n");
1185                                 return 0;
1186                         }
1187                         files_from = p;
1188                         filesfrom_host = h;
1189                         if (strcmp(files_from, "-") == 0) {
1190                                 snprintf(err_buf, sizeof err_buf,
1191                                         "Invalid --files-from remote filename\n");
1192                                 return 0;
1193                         }
1194                 } else {
1195                         if (sanitize_paths)
1196                                 files_from = sanitize_path(NULL, files_from, NULL, 0);
1197                         if (server_filter_list.head) {
1198                                 if (!*files_from)
1199                                         goto options_rejected;
1200                                 clean_fname(files_from, 1);
1201                                 if (check_filter(&server_filter_list, files_from, 0) < 0)
1202                                         goto options_rejected;
1203                         }
1204                         filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1205                         if (filesfrom_fd < 0) {
1206                                 snprintf(err_buf, sizeof err_buf,
1207                                         "failed to open files-from file %s: %s\n",
1208                                         files_from, strerror(errno));
1209                                 return 0;
1210                         }
1211                 }
1212         }
1213
1214         am_starting_up = 0;
1215
1216         return 1;
1217 }
1218
1219
1220 /**
1221  * Construct a filtered list of options to pass through from the
1222  * client to the server.
1223  *
1224  * This involves setting options that will tell the server how to
1225  * behave, and also filtering out options that are processed only
1226  * locally.
1227  **/
1228 void server_options(char **args,int *argc)
1229 {
1230         static char argstr[50+MAX_BASIS_DIRS*2];
1231         int ac = *argc;
1232         char *arg;
1233
1234         int i, x;
1235
1236         if (blocking_io == -1)
1237                 blocking_io = 0;
1238
1239         args[ac++] = "--server";
1240
1241         if (daemon_over_rsh) {
1242                 args[ac++] = "--daemon";
1243                 *argc = ac;
1244                 /* if we're passing --daemon, we're done */
1245                 return;
1246         }
1247
1248         if (!am_sender)
1249                 args[ac++] = "--sender";
1250
1251         x = 1;
1252         argstr[0] = '-';
1253         for (i = 0; i < verbose; i++)
1254                 argstr[x++] = 'v';
1255
1256         /* the -q option is intentionally left out */
1257         if (make_backups)
1258                 argstr[x++] = 'b';
1259         if (update_only)
1260                 argstr[x++] = 'u';
1261         if (!do_xfers)
1262                 argstr[x++] = 'n';
1263         if (preserve_links)
1264                 argstr[x++] = 'l';
1265         if (copy_links)
1266                 argstr[x++] = 'L';
1267         if (xfer_dirs > 1)
1268                 argstr[x++] = 'd';
1269         if (keep_dirlinks && am_sender)
1270                 argstr[x++] = 'K';
1271
1272         if (whole_file > 0)
1273                 argstr[x++] = 'W';
1274         /* We don't need to send --no-whole-file, because it's the
1275          * default for remote transfers, and in any case old versions
1276          * of rsync will not understand it. */
1277
1278         if (preserve_hard_links)
1279                 argstr[x++] = 'H';
1280         if (preserve_uid)
1281                 argstr[x++] = 'o';
1282         if (preserve_gid)
1283                 argstr[x++] = 'g';
1284         if (preserve_devices)
1285                 argstr[x++] = 'D';
1286         if (preserve_times)
1287                 argstr[x++] = 't';
1288         if (omit_dir_times == 2 && am_sender)
1289                 argstr[x++] = 'O';
1290         if (preserve_perms)
1291                 argstr[x++] = 'p';
1292         if (recurse)
1293                 argstr[x++] = 'r';
1294         if (always_checksum)
1295                 argstr[x++] = 'c';
1296         if (cvs_exclude)
1297                 argstr[x++] = 'C';
1298         if (ignore_times)
1299                 argstr[x++] = 'I';
1300         if (relative_paths)
1301                 argstr[x++] = 'R';
1302         if (one_file_system)
1303                 argstr[x++] = 'x';
1304         if (sparse_files)
1305                 argstr[x++] = 'S';
1306         if (do_compression)
1307                 argstr[x++] = 'z';
1308
1309         /* This is a complete hack - blame Rusty.  FIXME!
1310          * This hack is only needed for older rsync versions that
1311          * don't understand the --list-only option. */
1312         if (list_only == 1 && !recurse)
1313                 argstr[x++] = 'r';
1314
1315         argstr[x] = 0;
1316
1317         if (x != 1)
1318                 args[ac++] = argstr;
1319
1320         if (list_only > 1)
1321                 args[ac++] = "--list-only";
1322
1323         /* The server side doesn't use our log-format, but in certain
1324          * circumstances they need to know a little about the option. */
1325         if (log_format && am_sender) {
1326                 if (log_format_has_i)
1327                         args[ac++] = "--log-format=%i";
1328                 else if (log_format_has_o_or_i)
1329                         args[ac++] = "--log-format=%o";
1330                 else if (!verbose)
1331                         args[ac++] = "--log-format=X";
1332         }
1333
1334         if (block_size) {
1335                 if (asprintf(&arg, "-B%lu", block_size) < 0)
1336                         goto oom;
1337                 args[ac++] = arg;
1338         }
1339
1340         if (max_delete && am_sender) {
1341                 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1342                         goto oom;
1343                 args[ac++] = arg;
1344         }
1345
1346         if (max_size && am_sender) {
1347                 args[ac++] = "--max-size";
1348                 args[ac++] = max_size_arg;
1349         }
1350
1351         if (io_timeout) {
1352                 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1353                         goto oom;
1354                 args[ac++] = arg;
1355         }
1356
1357         if (bwlimit) {
1358                 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1359                         goto oom;
1360                 args[ac++] = arg;
1361         }
1362
1363         if (backup_dir) {
1364                 args[ac++] = "--backup-dir";
1365                 args[ac++] = backup_dir;
1366         }
1367
1368         /* Only send --suffix if it specifies a non-default value. */
1369         if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1370                 /* We use the following syntax to avoid weirdness with '~'. */
1371                 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1372                         goto oom;
1373                 args[ac++] = arg;
1374         }
1375
1376         if (am_sender) {
1377                 if (delete_excluded)
1378                         args[ac++] = "--delete-excluded";
1379                 else if (delete_before == 1 || delete_after)
1380                         args[ac++] = "--delete";
1381                 if (delete_before > 1)
1382                         args[ac++] = "--delete-before";
1383                 if (delete_during)
1384                         args[ac++] = "--delete-during";
1385                 if (delete_after)
1386                         args[ac++] = "--delete-after";
1387                 if (force_delete)
1388                         args[ac++] = "--force";
1389                 if (write_batch < 0)
1390                         args[ac++] = "--only-write-batch=X";
1391         }
1392
1393         if (size_only)
1394                 args[ac++] = "--size-only";
1395
1396         if (modify_window_set) {
1397                 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1398                         goto oom;
1399                 args[ac++] = arg;
1400         }
1401
1402         if (checksum_seed) {
1403                 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1404                         goto oom;
1405                 args[ac++] = arg;
1406         }
1407
1408         if (partial_dir && am_sender) {
1409                 if (partial_dir != partialdir_for_delayupdate) {
1410                         args[ac++] = "--partial-dir";
1411                         args[ac++] = partial_dir;
1412                 }
1413                 if (delay_updates)
1414                         args[ac++] = "--delay-updates";
1415         } else if (keep_partial)
1416                 args[ac++] = "--partial";
1417
1418         if (ignore_errors)
1419                 args[ac++] = "--ignore-errors";
1420
1421         if (copy_unsafe_links)
1422                 args[ac++] = "--copy-unsafe-links";
1423
1424         if (safe_symlinks)
1425                 args[ac++] = "--safe-links";
1426
1427         if (numeric_ids)
1428                 args[ac++] = "--numeric-ids";
1429
1430         if (only_existing && am_sender)
1431                 args[ac++] = "--existing";
1432
1433         if (opt_ignore_existing && am_sender)
1434                 args[ac++] = "--ignore-existing";
1435
1436         if (inplace)
1437                 args[ac++] = "--inplace";
1438
1439         if (tmpdir) {
1440                 args[ac++] = "--temp-dir";
1441                 args[ac++] = tmpdir;
1442         }
1443
1444         if (basis_dir[0] && am_sender) {
1445                 /* the server only needs this option if it is not the sender,
1446                  *   and it may be an older version that doesn't know this
1447                  *   option, so don't send it if client is the sender.
1448                  */
1449                 int i;
1450                 for (i = 0; i < basis_dir_cnt; i++) {
1451                         args[ac++] = dest_option;
1452                         args[ac++] = basis_dir[i];
1453                 }
1454         }
1455
1456         if (files_from && (!am_sender || filesfrom_host)) {
1457                 if (filesfrom_host) {
1458                         args[ac++] = "--files-from";
1459                         args[ac++] = files_from;
1460                         if (eol_nulls)
1461                                 args[ac++] = "--from0";
1462                 } else {
1463                         args[ac++] = "--files-from=-";
1464                         args[ac++] = "--from0";
1465                 }
1466                 if (!relative_paths)
1467                         args[ac++] = "--no-relative";
1468         }
1469         if (!implied_dirs && !am_sender)
1470                 args[ac++] = "--no-implied-dirs";
1471
1472         if (fuzzy_basis && am_sender)
1473                 args[ac++] = "--fuzzy";
1474
1475         if (remove_sent_files)
1476                 args[ac++] = "--remove-sent-files";
1477
1478         *argc = ac;
1479         return;
1480
1481     oom:
1482         out_of_memory("server_options");
1483 }
1484
1485 /* Look for a HOST specfication of the form "HOST:PATH", "HOST::PATH", or
1486  * "rsync://HOST:PORT/PATH".  If found, *host_ptr will be set to some allocated
1487  * memory with the HOST.  If a daemon-accessing spec was specified, the value
1488  * of *port_ptr will contain a non-0 port number, otherwise it will be set to
1489  * 0.  The return value is a pointer to the PATH.  Note that the HOST spec can
1490  * be an IPv6 literal address enclosed in '[' and ']' (such as "[::1]" or
1491  * "[::ffff:127.0.0.1]") which is returned without the '[' and ']'. */
1492 char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
1493 {
1494         char *p;
1495         int not_host;
1496
1497         if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) {
1498                 char *path;
1499                 int hostlen;
1500                 s += strlen(URL_PREFIX);
1501                 if ((p = strchr(s, '/')) != NULL) {
1502                         hostlen = p - s;
1503                         path = p + 1;
1504                 } else {
1505                         hostlen = strlen(s);
1506                         path = "";
1507                 }
1508                 if (*s == '[' && (p = strchr(s, ']')) != NULL) {
1509                         s++;
1510                         hostlen = p - s;
1511                         if (p[1] == ':')
1512                                 *port_ptr = atoi(p+2);
1513                 } else {
1514                         if ((p = strchr(s, ':')) != NULL) {
1515                                 hostlen = p - s;
1516                                 *port_ptr = atoi(p+1);
1517                         }
1518                 }
1519                 if (!*port_ptr)
1520                         *port_ptr = RSYNC_PORT;
1521                 *host_ptr = new_array(char, hostlen + 1);
1522                 strlcpy(*host_ptr, s, hostlen + 1);
1523                 return path;
1524         }
1525
1526         if (*s == '[' && (p = strchr(s, ']')) != NULL && p[1] == ':') {
1527                 s++;
1528                 *p = '\0';
1529                 not_host = strchr(s, '/') || !strchr(s, ':');
1530                 *p = ']';
1531                 if (not_host)
1532                         return NULL;
1533                 p++;
1534         } else {
1535                 if (!(p = strchr(s, ':')))
1536                         return NULL;
1537                 *p = '\0';
1538                 not_host = strchr(s, '/') != NULL;
1539                 *p = ':';
1540                 if (not_host)
1541                         return NULL;
1542         }
1543
1544         *host_ptr = new_array(char, p - s + 1);
1545         strlcpy(*host_ptr, s, p - s + 1);
1546
1547         if (p[1] == ':') {
1548                 if (port_ptr && !*port_ptr)
1549                         *port_ptr = RSYNC_PORT;
1550                 return p + 2;
1551         }
1552         if (port_ptr)
1553                 *port_ptr = 0;
1554
1555         return p + 1;
1556 }