Preparing for release of 2.6.6pre1
[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
977         if (!!delete_before + delete_during + delete_after > 1) {
978                 snprintf(err_buf, sizeof err_buf,
979                         "You may not combine multiple --delete-WHEN options.\n");
980                 return 0;
981         }
982         if (!recurse) {
983                 delete_before = delete_during = delete_after = 0;
984                 delete_mode = delete_excluded = 0;
985         } else if (delete_before || delete_during || delete_after)
986                 delete_mode = 1;
987         else if (delete_mode || delete_excluded) {
988                 if (refused_delete_before) {
989                         create_refuse_error(refused_delete_before);
990                         return 0;
991                 }
992                 delete_mode = delete_before = 1;
993         }
994
995         if (delete_mode && refused_delete) {
996                 create_refuse_error(refused_delete);
997                 return 0;
998         }
999
1000         if (remove_sent_files) {
1001                 /* We only want to infer this refusal of --remove-sent-files
1002                  * via the refusal of "delete", not any of the "delete-FOO"
1003                  * options. */
1004                 if (refused_delete && am_sender) {
1005                         create_refuse_error(refused_delete);
1006                         return 0;
1007                 }
1008                 need_messages_from_generator = 1;
1009         }
1010
1011         *argv = poptGetArgs(pc);
1012         *argc = count_args(*argv);
1013
1014         if (sanitize_paths) {
1015                 int i;
1016                 for (i = *argc; i-- > 0; )
1017                         (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
1018                 if (tmpdir)
1019                         tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
1020                 if (partial_dir)
1021                         partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
1022                 if (backup_dir)
1023                         backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
1024         }
1025         if (server_filter_list.head && !am_sender) {
1026                 struct filter_list_struct *elp = &server_filter_list;
1027                 int i;
1028                 if (tmpdir) {
1029                         if (!*tmpdir)
1030                                 goto options_rejected;
1031                         clean_fname(tmpdir, 1);
1032                         if (check_filter(elp, tmpdir, 1) < 0)
1033                                 goto options_rejected;
1034                 }
1035                 if (partial_dir && *partial_dir) {
1036                         clean_fname(partial_dir, 1);
1037                         if (check_filter(elp, partial_dir, 1) < 0)
1038                                 goto options_rejected;
1039                 }
1040                 for (i = 0; i < basis_dir_cnt; i++) {
1041                         if (!*basis_dir[i])
1042                                 goto options_rejected;
1043                         clean_fname(basis_dir[i], 1);
1044                         if (check_filter(elp, basis_dir[i], 1) < 0)
1045                                 goto options_rejected;
1046                 }
1047                 if (backup_dir) {
1048                         if (!*backup_dir)
1049                                 goto options_rejected;
1050                         clean_fname(backup_dir, 1);
1051                         if (check_filter(elp, backup_dir, 1) < 0) {
1052                             options_rejected:
1053                                 snprintf(err_buf, sizeof err_buf,
1054                                     "Your options have been rejected by the server.\n");
1055                                 return 0;
1056                         }
1057                 }
1058         }
1059
1060         if (!backup_suffix)
1061                 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
1062         backup_suffix_len = strlen(backup_suffix);
1063         if (strchr(backup_suffix, '/') != NULL) {
1064                 snprintf(err_buf, sizeof err_buf,
1065                         "--suffix cannot contain slashes: %s\n",
1066                         backup_suffix);
1067                 return 0;
1068         }
1069         if (backup_dir) {
1070                 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
1071                 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
1072                 if (backup_dir_remainder < 32) {
1073                         snprintf(err_buf, sizeof err_buf,
1074                                 "the --backup-dir path is WAY too long.\n");
1075                         return 0;
1076                 }
1077                 if (backup_dir_buf[backup_dir_len - 1] != '/') {
1078                         backup_dir_buf[backup_dir_len++] = '/';
1079                         backup_dir_buf[backup_dir_len] = '\0';
1080                 }
1081                 if (verbose > 1 && !am_sender) {
1082                         rprintf(FINFO, "backup_dir is %s\n",
1083                                 safe_fname(backup_dir_buf));
1084                 }
1085         } else if (!backup_suffix_len && (!am_server || !am_sender)) {
1086                 snprintf(err_buf, sizeof err_buf,
1087                         "--suffix cannot be a null string without --backup-dir\n");
1088                 return 0;
1089         }
1090         if (make_backups && !backup_dir)
1091                 omit_dir_times = 1;
1092
1093         if (log_format) {
1094                 if (log_format_has(log_format, 'i'))
1095                         log_format_has_i = 1;
1096                 if (!log_format_has(log_format, 'b')
1097                  && !log_format_has(log_format, 'c'))
1098                         log_before_transfer = !am_server;
1099         } else if (itemize_changes) {
1100                 log_format = "%i %n%L";
1101                 log_format_has_i = 1;
1102                 log_before_transfer = !am_server;
1103         }
1104
1105         if ((do_progress || dry_run) && !verbose && !log_before_transfer
1106             && !am_server)
1107                 verbose = 1;
1108
1109         if (dry_run)
1110                 do_xfers = 0;
1111
1112         set_io_timeout(io_timeout);
1113
1114         if (verbose && !log_format) {
1115                 log_format = "%n%L";
1116                 log_before_transfer = !am_server;
1117         }
1118         if (log_format_has_i || log_format_has(log_format, 'o'))
1119                 log_format_has_o_or_i = 1;
1120
1121         if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1122                 bwlimit = daemon_bwlimit;
1123         if (bwlimit) {
1124                 bwlimit_writemax = (size_t)bwlimit * 128;
1125                 if (bwlimit_writemax < 512)
1126                         bwlimit_writemax = 512;
1127         }
1128
1129         if (delay_updates && !partial_dir)
1130                 partial_dir = partialdir_for_delayupdate;
1131
1132         if (inplace) {
1133 #ifdef HAVE_FTRUNCATE
1134                 if (partial_dir) {
1135                         snprintf(err_buf, sizeof err_buf,
1136                                  "--inplace cannot be used with --%s\n",
1137                                  delay_updates ? "delay-updates" : "partial-dir");
1138                         return 0;
1139                 }
1140                 /* --inplace implies --partial for refusal purposes, but we
1141                  * clear the keep_partial flag for internal logic purposes. */
1142                 if (refused_partial) {
1143                         create_refuse_error(refused_partial);
1144                         return 0;
1145                 }
1146                 keep_partial = 0;
1147 #else
1148                 snprintf(err_buf, sizeof err_buf,
1149                          "--inplace is not supported on this %s\n",
1150                          am_server ? "server" : "client");
1151                 return 0;
1152 #endif
1153         } else {
1154                 if (keep_partial && !partial_dir) {
1155                         if ((arg = getenv("RSYNC_PARTIAL_DIR")) != NULL && *arg)
1156                                 partial_dir = strdup(arg);
1157                 }
1158                 if (partial_dir) {
1159                         if (*partial_dir)
1160                                 clean_fname(partial_dir, 1);
1161                         if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1162                                 partial_dir = NULL;
1163                         else if (*partial_dir != '/') {
1164                                 parse_rule(&filter_list, partial_dir,
1165                                     MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
1166                         }
1167                         if (!partial_dir && refused_partial) {
1168                                 create_refuse_error(refused_partial);
1169                                 return 0;
1170                         }
1171                         keep_partial = 1;
1172                 }
1173         }
1174
1175         if (files_from) {
1176                 char *h, *p;
1177                 int q;
1178                 if (*argc > 2 || (!am_daemon && *argc == 1)) {
1179                         usage(FERROR);
1180                         exit_cleanup(RERR_SYNTAX);
1181                 }
1182                 if (strcmp(files_from, "-") == 0) {
1183                         filesfrom_fd = 0;
1184                         if (am_server)
1185                                 filesfrom_host = ""; /* reading from socket */
1186                 } else if ((p = check_for_hostspec(files_from, &h, &q)) != 0) {
1187                         if (am_server) {
1188                                 snprintf(err_buf, sizeof err_buf,
1189                                         "The --files-from sent to the server cannot specify a host.\n");
1190                                 return 0;
1191                         }
1192                         files_from = p;
1193                         filesfrom_host = h;
1194                         if (strcmp(files_from, "-") == 0) {
1195                                 snprintf(err_buf, sizeof err_buf,
1196                                         "Invalid --files-from remote filename\n");
1197                                 return 0;
1198                         }
1199                 } else {
1200                         if (sanitize_paths)
1201                                 files_from = sanitize_path(NULL, files_from, NULL, 0);
1202                         if (server_filter_list.head) {
1203                                 if (!*files_from)
1204                                         goto options_rejected;
1205                                 clean_fname(files_from, 1);
1206                                 if (check_filter(&server_filter_list, files_from, 0) < 0)
1207                                         goto options_rejected;
1208                         }
1209                         filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1210                         if (filesfrom_fd < 0) {
1211                                 snprintf(err_buf, sizeof err_buf,
1212                                         "failed to open files-from file %s: %s\n",
1213                                         files_from, strerror(errno));
1214                                 return 0;
1215                         }
1216                 }
1217         }
1218
1219         am_starting_up = 0;
1220
1221         return 1;
1222 }
1223
1224
1225 /**
1226  * Construct a filtered list of options to pass through from the
1227  * client to the server.
1228  *
1229  * This involves setting options that will tell the server how to
1230  * behave, and also filtering out options that are processed only
1231  * locally.
1232  **/
1233 void server_options(char **args,int *argc)
1234 {
1235         static char argstr[64];
1236         int ac = *argc;
1237         char *arg;
1238
1239         int i, x;
1240
1241         if (blocking_io == -1)
1242                 blocking_io = 0;
1243
1244         args[ac++] = "--server";
1245
1246         if (daemon_over_rsh) {
1247                 args[ac++] = "--daemon";
1248                 *argc = ac;
1249                 /* if we're passing --daemon, we're done */
1250                 return;
1251         }
1252
1253         if (!am_sender)
1254                 args[ac++] = "--sender";
1255
1256         x = 1;
1257         argstr[0] = '-';
1258         for (i = 0; i < verbose; i++)
1259                 argstr[x++] = 'v';
1260
1261         /* the -q option is intentionally left out */
1262         if (make_backups)
1263                 argstr[x++] = 'b';
1264         if (update_only)
1265                 argstr[x++] = 'u';
1266         if (!do_xfers) /* NOT "dry_run"! */
1267                 argstr[x++] = 'n';
1268         if (preserve_links)
1269                 argstr[x++] = 'l';
1270         if (copy_links)
1271                 argstr[x++] = 'L';
1272         if (xfer_dirs > 1)
1273                 argstr[x++] = 'd';
1274         if (keep_dirlinks && am_sender)
1275                 argstr[x++] = 'K';
1276
1277         if (whole_file > 0)
1278                 argstr[x++] = 'W';
1279         /* We don't need to send --no-whole-file, because it's the
1280          * default for remote transfers, and in any case old versions
1281          * of rsync will not understand it. */
1282
1283         if (preserve_hard_links)
1284                 argstr[x++] = 'H';
1285         if (preserve_uid)
1286                 argstr[x++] = 'o';
1287         if (preserve_gid)
1288                 argstr[x++] = 'g';
1289         if (preserve_devices)
1290                 argstr[x++] = 'D';
1291         if (preserve_times)
1292                 argstr[x++] = 't';
1293         if (omit_dir_times == 2 && am_sender)
1294                 argstr[x++] = 'O';
1295         if (preserve_perms)
1296                 argstr[x++] = 'p';
1297         if (recurse)
1298                 argstr[x++] = 'r';
1299         if (always_checksum)
1300                 argstr[x++] = 'c';
1301         if (cvs_exclude)
1302                 argstr[x++] = 'C';
1303         if (ignore_times)
1304                 argstr[x++] = 'I';
1305         if (relative_paths)
1306                 argstr[x++] = 'R';
1307         if (one_file_system)
1308                 argstr[x++] = 'x';
1309         if (sparse_files)
1310                 argstr[x++] = 'S';
1311         if (do_compression)
1312                 argstr[x++] = 'z';
1313
1314         /* This is a complete hack - blame Rusty.  FIXME!
1315          * This hack is only needed for older rsync versions that
1316          * don't understand the --list-only option. */
1317         if (list_only == 1 && !recurse)
1318                 argstr[x++] = 'r';
1319
1320         argstr[x] = 0;
1321
1322         if (x != 1)
1323                 args[ac++] = argstr;
1324
1325         if (list_only > 1)
1326                 args[ac++] = "--list-only";
1327
1328         /* The server side doesn't use our log-format, but in certain
1329          * circumstances they need to know a little about the option. */
1330         if (log_format && am_sender) {
1331                 if (log_format_has_i)
1332                         args[ac++] = "--log-format=%i";
1333                 else if (log_format_has_o_or_i)
1334                         args[ac++] = "--log-format=%o";
1335                 else if (!verbose)
1336                         args[ac++] = "--log-format=X";
1337         }
1338
1339         if (block_size) {
1340                 if (asprintf(&arg, "-B%lu", block_size) < 0)
1341                         goto oom;
1342                 args[ac++] = arg;
1343         }
1344
1345         if (max_delete && am_sender) {
1346                 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1347                         goto oom;
1348                 args[ac++] = arg;
1349         }
1350
1351         if (max_size && am_sender) {
1352                 args[ac++] = "--max-size";
1353                 args[ac++] = max_size_arg;
1354         }
1355
1356         if (io_timeout) {
1357                 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1358                         goto oom;
1359                 args[ac++] = arg;
1360         }
1361
1362         if (bwlimit) {
1363                 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1364                         goto oom;
1365                 args[ac++] = arg;
1366         }
1367
1368         if (backup_dir) {
1369                 args[ac++] = "--backup-dir";
1370                 args[ac++] = backup_dir;
1371         }
1372
1373         /* Only send --suffix if it specifies a non-default value. */
1374         if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1375                 /* We use the following syntax to avoid weirdness with '~'. */
1376                 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1377                         goto oom;
1378                 args[ac++] = arg;
1379         }
1380
1381         if (am_sender) {
1382                 if (delete_excluded)
1383                         args[ac++] = "--delete-excluded";
1384                 else if (delete_before == 1 || delete_after)
1385                         args[ac++] = "--delete";
1386                 if (delete_before > 1)
1387                         args[ac++] = "--delete-before";
1388                 if (delete_during)
1389                         args[ac++] = "--delete-during";
1390                 if (delete_after)
1391                         args[ac++] = "--delete-after";
1392                 if (force_delete)
1393                         args[ac++] = "--force";
1394                 if (write_batch < 0)
1395                         args[ac++] = "--only-write-batch=X";
1396         }
1397
1398         if (size_only)
1399                 args[ac++] = "--size-only";
1400
1401         if (modify_window_set) {
1402                 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1403                         goto oom;
1404                 args[ac++] = arg;
1405         }
1406
1407         if (checksum_seed) {
1408                 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1409                         goto oom;
1410                 args[ac++] = arg;
1411         }
1412
1413         if (partial_dir && am_sender) {
1414                 if (partial_dir != partialdir_for_delayupdate) {
1415                         args[ac++] = "--partial-dir";
1416                         args[ac++] = partial_dir;
1417                 }
1418                 if (delay_updates)
1419                         args[ac++] = "--delay-updates";
1420         } else if (keep_partial)
1421                 args[ac++] = "--partial";
1422
1423         if (ignore_errors)
1424                 args[ac++] = "--ignore-errors";
1425
1426         if (copy_unsafe_links)
1427                 args[ac++] = "--copy-unsafe-links";
1428
1429         if (safe_symlinks)
1430                 args[ac++] = "--safe-links";
1431
1432         if (numeric_ids)
1433                 args[ac++] = "--numeric-ids";
1434
1435         if (only_existing && am_sender)
1436                 args[ac++] = "--existing";
1437
1438         if (opt_ignore_existing && am_sender)
1439                 args[ac++] = "--ignore-existing";
1440
1441         if (inplace)
1442                 args[ac++] = "--inplace";
1443
1444         if (tmpdir) {
1445                 args[ac++] = "--temp-dir";
1446                 args[ac++] = tmpdir;
1447         }
1448
1449         if (basis_dir[0] && am_sender) {
1450                 /* the server only needs this option if it is not the sender,
1451                  *   and it may be an older version that doesn't know this
1452                  *   option, so don't send it if client is the sender.
1453                  */
1454                 int i;
1455                 for (i = 0; i < basis_dir_cnt; i++) {
1456                         args[ac++] = dest_option;
1457                         args[ac++] = basis_dir[i];
1458                 }
1459         }
1460
1461         if (files_from && (!am_sender || filesfrom_host)) {
1462                 if (filesfrom_host) {
1463                         args[ac++] = "--files-from";
1464                         args[ac++] = files_from;
1465                         if (eol_nulls)
1466                                 args[ac++] = "--from0";
1467                 } else {
1468                         args[ac++] = "--files-from=-";
1469                         args[ac++] = "--from0";
1470                 }
1471                 if (!relative_paths)
1472                         args[ac++] = "--no-relative";
1473         }
1474         if (!implied_dirs && !am_sender)
1475                 args[ac++] = "--no-implied-dirs";
1476
1477         if (fuzzy_basis && am_sender)
1478                 args[ac++] = "--fuzzy";
1479
1480         if (remove_sent_files)
1481                 args[ac++] = "--remove-sent-files";
1482
1483         *argc = ac;
1484         return;
1485
1486     oom:
1487         out_of_memory("server_options");
1488 }
1489
1490 /* Look for a HOST specfication of the form "HOST:PATH", "HOST::PATH", or
1491  * "rsync://HOST:PORT/PATH".  If found, *host_ptr will be set to some allocated
1492  * memory with the HOST.  If a daemon-accessing spec was specified, the value
1493  * of *port_ptr will contain a non-0 port number, otherwise it will be set to
1494  * 0.  The return value is a pointer to the PATH.  Note that the HOST spec can
1495  * be an IPv6 literal address enclosed in '[' and ']' (such as "[::1]" or
1496  * "[::ffff:127.0.0.1]") which is returned without the '[' and ']'. */
1497 char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
1498 {
1499         char *p;
1500         int not_host;
1501
1502         if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) {
1503                 char *path;
1504                 int hostlen;
1505                 s += strlen(URL_PREFIX);
1506                 if ((p = strchr(s, '/')) != NULL) {
1507                         hostlen = p - s;
1508                         path = p + 1;
1509                 } else {
1510                         hostlen = strlen(s);
1511                         path = "";
1512                 }
1513                 if (*s == '[' && (p = strchr(s, ']')) != NULL) {
1514                         s++;
1515                         hostlen = p - s;
1516                         if (p[1] == ':')
1517                                 *port_ptr = atoi(p+2);
1518                 } else {
1519                         if ((p = strchr(s, ':')) != NULL) {
1520                                 hostlen = p - s;
1521                                 *port_ptr = atoi(p+1);
1522                         }
1523                 }
1524                 if (!*port_ptr)
1525                         *port_ptr = RSYNC_PORT;
1526                 *host_ptr = new_array(char, hostlen + 1);
1527                 strlcpy(*host_ptr, s, hostlen + 1);
1528                 return path;
1529         }
1530
1531         if (*s == '[' && (p = strchr(s, ']')) != NULL && p[1] == ':') {
1532                 s++;
1533                 *p = '\0';
1534                 not_host = strchr(s, '/') || !strchr(s, ':');
1535                 *p = ']';
1536                 if (not_host)
1537                         return NULL;
1538                 p++;
1539         } else {
1540                 if (!(p = strchr(s, ':')))
1541                         return NULL;
1542                 *p = '\0';
1543                 not_host = strchr(s, '/') != NULL;
1544                 *p = ':';
1545                 if (not_host)
1546                         return NULL;
1547         }
1548
1549         *host_ptr = new_array(char, p - s + 1);
1550         strlcpy(*host_ptr, s, p - s + 1);
1551
1552         if (p[1] == ':') {
1553                 if (port_ptr && !*port_ptr)
1554                         *port_ptr = RSYNC_PORT;
1555                 return p + 2;
1556         }
1557         if (port_ptr)
1558                 *port_ptr = 0;
1559
1560         return p + 1;
1561 }