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