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