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