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