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