Added the --append option.
[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 -R\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   {"version",          0,  POPT_ARG_NONE,   0, OPT_VERSION, 0, 0},
375   {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
376   {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
377   {"password-file",    0,  POPT_ARG_STRING, &password_file, 0, 0, 0 },
378   {"ignore-times",    'I', POPT_ARG_NONE,   &ignore_times, 0, 0, 0 },
379   {"size-only",        0,  POPT_ARG_NONE,   &size_only, 0, 0, 0 },
380   {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
381   {"one-file-system", 'x', POPT_ARG_NONE,   &one_file_system, 0, 0, 0 },
382   {"existing",         0,  POPT_ARG_NONE,   &only_existing, 0, 0, 0 },
383   {"ignore-existing",  0,  POPT_ARG_NONE,   &opt_ignore_existing, 0, 0, 0 },
384   {"del",              0,  POPT_ARG_NONE,   &delete_during, 0, 0, 0 },
385   {"delete",           0,  POPT_ARG_NONE,   &delete_mode, 0, 0, 0 },
386   {"delete-before",    0,  POPT_ARG_VAL,    &delete_before, 2, 0, 0 },
387   {"delete-during",    0,  POPT_ARG_NONE,   &delete_during, 0, 0, 0 },
388   {"delete-after",     0,  POPT_ARG_NONE,   &delete_after, 0, 0, 0 },
389   {"delete-excluded",  0,  POPT_ARG_NONE,   &delete_excluded, 0, 0, 0 },
390   {"remove-sent-files",0,  POPT_ARG_NONE,   &remove_sent_files, 0, 0, 0 },
391   {"force",            0,  POPT_ARG_NONE,   &force_delete, 0, 0, 0 },
392   {"numeric-ids",      0,  POPT_ARG_NONE,   &numeric_ids, 0, 0, 0 },
393   {"filter",          'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
394   {"exclude",          0,  POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
395   {"include",          0,  POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
396   {"exclude-from",     0,  POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
397   {"include-from",     0,  POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
398   {"safe-links",       0,  POPT_ARG_NONE,   &safe_symlinks, 0, 0, 0 },
399   {"help",            'h', POPT_ARG_NONE,   0, 'h', 0, 0 },
400   {"backup",          'b', POPT_ARG_NONE,   &make_backups, 0, 0, 0 },
401   {"dry-run",         'n', POPT_ARG_NONE,   &dry_run, 0, 0, 0 },
402   {"sparse",          'S', POPT_ARG_NONE,   &sparse_files, 0, 0, 0 },
403   {"cvs-exclude",     'C', POPT_ARG_NONE,   &cvs_exclude, 0, 0, 0 },
404   {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
405   {"inplace",          0,  POPT_ARG_NONE,   &inplace, 0, 0, 0 },
406   {"dirs",            'd', POPT_ARG_VAL,    &xfer_dirs, 2, 0, 0 },
407   {"links",           'l', POPT_ARG_NONE,   &preserve_links, 0, 0, 0 },
408   {"copy-links",      'L', POPT_ARG_NONE,   &copy_links, 0, 0, 0 },
409   {"keep-dirlinks",   'K', POPT_ARG_NONE,   &keep_dirlinks, 0, 0, 0 },
410   {"append",           0,  POPT_ARG_VAL,    &append_mode, 1, 0, 0 },
411   {"whole-file",      'W', POPT_ARG_VAL,    &whole_file, 1, 0, 0 },
412   {"no-whole-file",    0,  POPT_ARG_VAL,    &whole_file, 0, 0, 0 },
413   {"copy-unsafe-links",0,  POPT_ARG_NONE,   &copy_unsafe_links, 0, 0, 0 },
414   {"perms",           'p', POPT_ARG_NONE,   &preserve_perms, 0, 0, 0 },
415   {"owner",           'o', POPT_ARG_NONE,   &preserve_uid, 0, 0, 0 },
416   {"group",           'g', POPT_ARG_NONE,   &preserve_gid, 0, 0, 0 },
417   {"devices",         'D', POPT_ARG_NONE,   &preserve_devices, 0, 0, 0 },
418   {"times",           't', POPT_ARG_NONE,   &preserve_times, 0, 0, 0 },
419   {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
420   {"checksum",        'c', POPT_ARG_NONE,   &always_checksum, 0, 0, 0 },
421   {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
422   {"quiet",           'q', POPT_ARG_NONE,   0, 'q', 0, 0 },
423   {"archive",         'a', POPT_ARG_NONE,   &archive_mode, 0, 0, 0 },
424   {"server",           0,  POPT_ARG_NONE,   &am_server, 0, 0, 0 },
425   {"sender",           0,  POPT_ARG_NONE,   0, OPT_SENDER, 0, 0 },
426   {"recursive",       'r', POPT_ARG_NONE,   &recurse, 0, 0, 0 },
427   {"list-only",        0,  POPT_ARG_VAL,    &list_only, 2, 0, 0 },
428   {"relative",        'R', POPT_ARG_VAL,    &relative_paths, 1, 0, 0 },
429   {"no-relative",      0,  POPT_ARG_VAL,    &relative_paths, 0, 0, 0 },
430   {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
431   {"block-size",      'B', POPT_ARG_LONG,   &block_size, 0, 0, 0 },
432   {"max-delete",       0,  POPT_ARG_INT,    &max_delete, 0, 0, 0 },
433   {"max-size",         0,  POPT_ARG_STRING, &max_size_arg,  OPT_MAX_SIZE, 0, 0 },
434   {"timeout",          0,  POPT_ARG_INT,    &io_timeout, 0, 0, 0 },
435   {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
436   {"compare-dest",     0,  POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
437   {"copy-dest",        0,  POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
438   {"link-dest",        0,  POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
439   {"fuzzy",           'y', POPT_ARG_NONE,   &fuzzy_basis, 0, 0, 0 },
440   /* TODO: Should this take an optional int giving the compression level? */
441   {"compress",        'z', POPT_ARG_NONE,   &do_compression, 0, 0, 0 },
442   {"stats",            0,  POPT_ARG_NONE,   &do_stats, 0, 0, 0 },
443   {"progress",         0,  POPT_ARG_NONE,   &do_progress, 0, 0, 0 },
444   {"partial",          0,  POPT_ARG_NONE,   &keep_partial, 0, 0, 0 },
445   {"partial-dir",      0,  POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
446   {"delay-updates",    0,  POPT_ARG_NONE,   &delay_updates, 0, 0, 0 },
447   {"ignore-errors",    0,  POPT_ARG_NONE,   &ignore_errors, 0, 0, 0 },
448   {"blocking-io",      0,  POPT_ARG_VAL,    &blocking_io, 1, 0, 0 },
449   {"no-blocking-io",   0,  POPT_ARG_VAL,    &blocking_io, 0, 0, 0 },
450   {0,                 'F', POPT_ARG_NONE,   0, 'F', 0, 0 },
451   {0,                 'P', POPT_ARG_NONE,   0, 'P', 0, 0 },
452   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
453   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
454   {"log-format",       0,  POPT_ARG_STRING, &log_format, 0, 0, 0 },
455   {"itemize-changes", 'i', POPT_ARG_NONE,   &itemize_changes, 0, 0, 0 },
456   {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit, 0, 0, 0 },
457   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
458   {"hard-links",      'H', POPT_ARG_NONE,   &preserve_hard_links, 0, 0, 0 },
459   {"read-batch",       0,  POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
460   {"write-batch",      0,  POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
461   {"only-write-batch", 0,  POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 },
462   {"files-from",       0,  POPT_ARG_STRING, &files_from, 0, 0, 0 },
463   {"from0",           '0', POPT_ARG_NONE,   &eol_nulls, 0, 0, 0},
464   {"no-implied-dirs",  0,  POPT_ARG_VAL,    &implied_dirs, 0, 0, 0 },
465   {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
466   {"checksum-seed",    0,  POPT_ARG_INT,    &checksum_seed, 0, 0, 0 },
467 #ifdef INET6
468   {"ipv4",            '4', POPT_ARG_VAL,    &default_af_hint, AF_INET, 0, 0 },
469   {"ipv6",            '6', POPT_ARG_VAL,    &default_af_hint, AF_INET6, 0, 0 },
470 #endif
471   /* All these options switch us into daemon-mode option-parsing. */
472   {"config",           0,  POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
473   {"daemon",           0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
474   {"detach",           0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
475   {"no-detach",        0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
476   {0,0,0,0, 0, 0, 0}
477 };
478
479 static void daemon_usage(enum logcode F)
480 {
481   print_rsync_version(F);
482
483   rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
484   rprintf(F,"     --address=ADDRESS       bind to the specified address\n");
485   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth; KBytes per second\n");
486   rprintf(F,"     --config=FILE           specify alternate rsyncd.conf file\n");
487   rprintf(F,"     --no-detach             do not detach from the parent\n");
488   rprintf(F,"     --port=PORT             listen on alternate port number\n");
489   rprintf(F," -v, --verbose               increase verbosity\n");
490 #ifdef INET6
491   rprintf(F," -4, --ipv4                  prefer IPv4\n");
492   rprintf(F," -6, --ipv6                  prefer IPv6\n");
493 #endif
494   rprintf(F," -h, --help                  show this help screen\n");
495
496   rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
497   rprintf(F,"daemon-specific rsync options.  See also the rsyncd.conf(5) man page.\n");
498 }
499
500 static struct poptOption long_daemon_options[] = {
501   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
502   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
503   {"bwlimit",          0,  POPT_ARG_INT,    &daemon_bwlimit, 0, 0, 0 },
504   {"config",           0,  POPT_ARG_STRING, &config_file, 0, 0, 0 },
505   {"daemon",           0,  POPT_ARG_NONE,   &daemon_opt, 0, 0, 0 },
506 #ifdef INET6
507   {"ipv4",            '4', POPT_ARG_VAL,    &default_af_hint, AF_INET, 0, 0 },
508   {"ipv6",            '6', POPT_ARG_VAL,    &default_af_hint, AF_INET6, 0, 0 },
509 #endif
510   {"detach",           0,  POPT_ARG_VAL,    &no_detach, 0, 0, 0 },
511   {"no-detach",        0,  POPT_ARG_VAL,    &no_detach, 1, 0, 0 },
512   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
513   {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
514   {"server",           0,  POPT_ARG_NONE,   &am_server, 0, 0, 0 },
515   {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
516   {"help",            'h', POPT_ARG_NONE,   0, 'h', 0, 0 },
517   {0,0,0,0, 0, 0, 0}
518 };
519
520
521 static char err_buf[200];
522
523
524 /**
525  * Store the option error message, if any, so that we can log the
526  * connection attempt (which requires parsing the options), and then
527  * show the error later on.
528  **/
529 void option_error(void)
530 {
531         if (!err_buf[0]) {
532                 strcpy(err_buf, "Error parsing options: "
533                     "option may be supported on client but not on server?\n");
534         }
535
536         rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
537 }
538
539
540 /**
541  * Tweak the option table to disable all options that the rsyncd.conf
542  * file has told us to refuse.
543  **/
544 static void set_refuse_options(char *bp)
545 {
546         struct poptOption *op;
547         char *cp, shortname[2];
548         int is_wild, found_match;
549
550         shortname[1] = '\0';
551
552         while (1) {
553                 while (*bp == ' ') bp++;
554                 if (!*bp)
555                         break;
556                 if ((cp = strchr(bp, ' ')) != NULL)
557                         *cp= '\0';
558                 is_wild = strpbrk(bp, "*?[") != NULL;
559                 found_match = 0;
560                 for (op = long_options; ; op++) {
561                         *shortname = op->shortName;
562                         if (!op->longName && !*shortname)
563                                 break;
564                         if ((op->longName && wildmatch(bp, op->longName))
565                             || (*shortname && wildmatch(bp, shortname))) {
566                                 if (op->argInfo == POPT_ARG_VAL)
567                                         op->argInfo = POPT_ARG_NONE;
568                                 op->val = (op - long_options) + OPT_REFUSED_BASE;
569                                 found_match = 1;
570                                 /* These flags are set to let us easily check
571                                  * an implied option later in the code. */
572                                 switch (*shortname) {
573                                 case 'r': case 'd': case 'l': case 'p':
574                                 case 't': case 'g': case 'o': case 'D':
575                                         refused_archive_part = op->val;
576                                         break;
577                                 case '\0':
578                                         if (wildmatch("delete", op->longName))
579                                                 refused_delete = op->val;
580                                         else if (wildmatch("delete-before", op->longName))
581                                                 refused_delete_before = op->val;
582                                         else if (wildmatch("partial", op->longName))
583                                                 refused_partial = op->val;
584                                         else if (wildmatch("progress", op->longName))
585                                                 refused_progress = op->val;
586                                         else if (wildmatch("inplace", op->longName))
587                                                 refused_inplace = op->val;
588                                         break;
589                                 }
590                                 if (!is_wild)
591                                         break;
592                         }
593                 }
594                 if (!found_match) {
595                         rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
596                                 bp);
597                 }
598                 if (!cp)
599                         break;
600                 *cp = ' ';
601                 bp = cp + 1;
602         }
603
604         for (op = long_options; ; op++) {
605                 *shortname = op->shortName;
606                 if (!op->longName && !*shortname)
607                         break;
608                 if (op->val == OPT_DAEMON) {
609                         if (op->argInfo == POPT_ARG_VAL)
610                                 op->argInfo = POPT_ARG_NONE;
611                         op->val = (op - long_options) + OPT_REFUSED_BASE;
612                 }
613         }
614 }
615
616
617 static int count_args(const char **argv)
618 {
619         int i = 0;
620
621         if (argv) {
622                 while (argv[i] != NULL)
623                         i++;
624         }
625
626         return i;
627 }
628
629
630 static OFF_T parse_size_arg(const char *size_arg)
631 {
632         const char *arg;
633         OFF_T size;
634
635         for (arg = size_arg; isdigit(*(uchar*)arg); arg++) {}
636         if (*arg == '.')
637                 for (arg++; isdigit(*(uchar*)arg); arg++) {}
638         switch (*arg) {
639         case 'k': case 'K':
640                 size = atof(size_arg) * 1024;
641                 break;
642         case 'm': case 'M':
643                 size = atof(size_arg) * 1024*1024;
644                 break;
645         case 'g': case 'G':
646                 size = atof(size_arg) * 1024*1024*1024;
647                 break;
648         case '\0':
649                 size = atof(size_arg);
650                 break;
651         default:
652                 size = 0;
653                 break;
654         }
655         return size;
656 }
657
658
659 static void create_refuse_error(int which)
660 {
661         /* The "which" value is the index + OPT_REFUSED_BASE. */
662         struct poptOption *op = &long_options[which - OPT_REFUSED_BASE];
663         int n = snprintf(err_buf, sizeof err_buf,
664                          "The server is configured to refuse --%s\n",
665                          op->longName) - 1;
666         if (op->shortName) {
667                 snprintf(err_buf + n, sizeof err_buf - n,
668                          " (-%c)\n", op->shortName);
669         }
670 }
671
672
673 /**
674  * Process command line arguments.  Called on both local and remote.
675  *
676  * @retval 1 if all options are OK; with globals set to appropriate
677  * values
678  *
679  * @retval 0 on error, with err_buf containing an explanation
680  **/
681 int parse_arguments(int *argc, const char ***argv, int frommain)
682 {
683         int opt;
684         char *ref = lp_refuse_options(module_id);
685         const char *arg;
686         poptContext pc;
687
688         if (ref && *ref)
689                 set_refuse_options(ref);
690
691         /* TODO: Call poptReadDefaultConfig; handle errors. */
692
693         /* The context leaks in case of an error, but if there's a
694          * problem we always exit anyhow. */
695         pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
696         poptReadDefaultConfig(pc, 0);
697
698         while ((opt = poptGetNextOpt(pc)) != -1) {
699                 /* most options are handled automatically by popt;
700                  * only special cases are returned and listed here. */
701
702                 switch (opt) {
703                 case OPT_VERSION:
704                         print_rsync_version(FINFO);
705                         exit_cleanup(0);
706
707                 case OPT_DAEMON:
708                         if (am_daemon) {
709                                 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
710                                 return 0;
711                         }
712                         poptFreeContext(pc);
713                         pc = poptGetContext(RSYNC_NAME, *argc, *argv,
714                                             long_daemon_options, 0);
715                         while ((opt = poptGetNextOpt(pc)) != -1) {
716                                 switch (opt) {
717                                 case 'h':
718                                         daemon_usage(FINFO);
719                                         exit_cleanup(0);
720
721                                 case 'v':
722                                         verbose++;
723                                         break;
724
725                                 default:
726                                         rprintf(FERROR,
727                                             "rsync: %s: %s (in daemon mode)\n",
728                                             poptBadOption(pc, POPT_BADOPTION_NOALIAS),
729                                             poptStrerror(opt));
730                                         goto daemon_error;
731                                 }
732                         }
733                         if (!daemon_opt) {
734                                 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
735                             daemon_error:
736                                 rprintf(FERROR,
737                                     "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
738                                 exit_cleanup(RERR_SYNTAX);
739                         }
740                         *argv = poptGetArgs(pc);
741                         *argc = count_args(*argv);
742                         am_starting_up = 0;
743                         daemon_opt = 0;
744                         am_daemon = 1;
745                         return 1;
746
747                 case OPT_MODIFY_WINDOW:
748                         /* The value has already been set by popt, but
749                          * we need to remember that we're using a
750                          * non-default setting. */
751                         modify_window_set = 1;
752                         break;
753
754                 case OPT_FILTER:
755                         parse_rule(&filter_list, poptGetOptArg(pc), 0, 0);
756                         break;
757
758                 case OPT_EXCLUDE:
759                         parse_rule(&filter_list, poptGetOptArg(pc),
760                                    0, XFLG_OLD_PREFIXES);
761                         break;
762
763                 case OPT_INCLUDE:
764                         parse_rule(&filter_list, poptGetOptArg(pc),
765                                    MATCHFLG_INCLUDE, XFLG_OLD_PREFIXES);
766                         break;
767
768                 case OPT_EXCLUDE_FROM:
769                 case OPT_INCLUDE_FROM:
770                         arg = poptGetOptArg(pc);
771                         if (sanitize_paths)
772                                 arg = sanitize_path(NULL, arg, NULL, 0);
773                         if (server_filter_list.head) {
774                                 char *cp = (char *)arg;
775                                 if (!*cp)
776                                         goto options_rejected;
777                                 clean_fname(cp, 1);
778                                 if (check_filter(&server_filter_list, cp, 0) < 0)
779                                         goto options_rejected;
780                         }
781                         parse_filter_file(&filter_list, arg,
782                                 opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
783                                 XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
784                         break;
785
786                 case 'h':
787                         usage(FINFO);
788                         exit_cleanup(0);
789
790                 case 'v':
791                         verbose++;
792                         break;
793
794                 case 'q':
795                         if (frommain)
796                                 quiet++;
797                         break;
798
799                 case OPT_SENDER:
800                         if (!am_server) {
801                                 usage(FERROR);
802                                 exit_cleanup(RERR_SYNTAX);
803                         }
804                         am_sender = 1;
805                         break;
806
807                 case 'F':
808                         switch (++F_option_cnt) {
809                         case 1:
810                                 parse_rule(&filter_list,": /.rsync-filter",0,0);
811                                 break;
812                         case 2:
813                                 parse_rule(&filter_list,"- .rsync-filter",0,0);
814                                 break;
815                         }
816                         break;
817
818                 case 'P':
819                         if (refused_partial || refused_progress) {
820                                 create_refuse_error(refused_partial
821                                     ? refused_partial : refused_progress);
822                                 return 0;
823                         }
824                         do_progress = 1;
825                         keep_partial = 1;
826                         break;
827
828                 case OPT_WRITE_BATCH:
829                         /* batch_name is already set */
830                         write_batch = 1;
831                         break;
832
833                 case OPT_ONLY_WRITE_BATCH:
834                         /* batch_name is already set */
835                         write_batch = -1;
836                         break;
837
838                 case OPT_READ_BATCH:
839                         /* batch_name is already set */
840                         read_batch = 1;
841                         break;
842
843                 case OPT_MAX_SIZE:
844                         if ((max_size = parse_size_arg(max_size_arg)) <= 0) {
845                                 snprintf(err_buf, sizeof err_buf,
846                                         "--max-size value is invalid: %s\n",
847                                         max_size_arg);
848                                 return 0;
849                         }
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         if (!relative_paths)
983                 implied_dirs = 0;
984
985         if (!!delete_before + delete_during + delete_after > 1) {
986                 snprintf(err_buf, sizeof err_buf,
987                         "You may not combine multiple --delete-WHEN options.\n");
988                 return 0;
989         }
990         if (!recurse) {
991                 delete_before = delete_during = delete_after = 0;
992                 delete_mode = delete_excluded = 0;
993         } else if (delete_before || delete_during || delete_after)
994                 delete_mode = 1;
995         else if (delete_mode || delete_excluded) {
996                 if (refused_delete_before) {
997                         create_refuse_error(refused_delete_before);
998                         return 0;
999                 }
1000                 delete_mode = delete_before = 1;
1001         }
1002
1003         if (delete_mode && refused_delete) {
1004                 create_refuse_error(refused_delete);
1005                 return 0;
1006         }
1007
1008         if (remove_sent_files) {
1009                 /* We only want to infer this refusal of --remove-sent-files
1010                  * via the refusal of "delete", not any of the "delete-FOO"
1011                  * options. */
1012                 if (refused_delete && am_sender) {
1013                         create_refuse_error(refused_delete);
1014                         return 0;
1015                 }
1016                 need_messages_from_generator = 1;
1017         }
1018
1019         *argv = poptGetArgs(pc);
1020         *argc = count_args(*argv);
1021
1022         if (sanitize_paths) {
1023                 int i;
1024                 for (i = *argc; i-- > 0; )
1025                         (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
1026                 if (tmpdir)
1027                         tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
1028                 if (partial_dir)
1029                         partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
1030                 if (backup_dir)
1031                         backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
1032         }
1033         if (server_filter_list.head && !am_sender) {
1034                 struct filter_list_struct *elp = &server_filter_list;
1035                 int i;
1036                 if (tmpdir) {
1037                         if (!*tmpdir)
1038                                 goto options_rejected;
1039                         clean_fname(tmpdir, 1);
1040                         if (check_filter(elp, tmpdir, 1) < 0)
1041                                 goto options_rejected;
1042                 }
1043                 if (partial_dir && *partial_dir) {
1044                         clean_fname(partial_dir, 1);
1045                         if (check_filter(elp, partial_dir, 1) < 0)
1046                                 goto options_rejected;
1047                 }
1048                 for (i = 0; i < basis_dir_cnt; i++) {
1049                         if (!*basis_dir[i])
1050                                 goto options_rejected;
1051                         clean_fname(basis_dir[i], 1);
1052                         if (check_filter(elp, basis_dir[i], 1) < 0)
1053                                 goto options_rejected;
1054                 }
1055                 if (backup_dir) {
1056                         if (!*backup_dir)
1057                                 goto options_rejected;
1058                         clean_fname(backup_dir, 1);
1059                         if (check_filter(elp, backup_dir, 1) < 0) {
1060                             options_rejected:
1061                                 snprintf(err_buf, sizeof err_buf,
1062                                     "Your options have been rejected by the server.\n");
1063                                 return 0;
1064                         }
1065                 }
1066         }
1067
1068         if (!backup_suffix)
1069                 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
1070         backup_suffix_len = strlen(backup_suffix);
1071         if (strchr(backup_suffix, '/') != NULL) {
1072                 snprintf(err_buf, sizeof err_buf,
1073                         "--suffix cannot contain slashes: %s\n",
1074                         backup_suffix);
1075                 return 0;
1076         }
1077         if (backup_dir) {
1078                 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
1079                 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
1080                 if (backup_dir_remainder < 32) {
1081                         snprintf(err_buf, sizeof err_buf,
1082                                 "the --backup-dir path is WAY too long.\n");
1083                         return 0;
1084                 }
1085                 if (backup_dir_buf[backup_dir_len - 1] != '/') {
1086                         backup_dir_buf[backup_dir_len++] = '/';
1087                         backup_dir_buf[backup_dir_len] = '\0';
1088                 }
1089                 if (verbose > 1 && !am_sender) {
1090                         rprintf(FINFO, "backup_dir is %s\n",
1091                                 safe_fname(backup_dir_buf));
1092                 }
1093         } else if (!backup_suffix_len && (!am_server || !am_sender)) {
1094                 snprintf(err_buf, sizeof err_buf,
1095                         "--suffix cannot be a null string without --backup-dir\n");
1096                 return 0;
1097         }
1098         if (make_backups && !backup_dir)
1099                 omit_dir_times = 1;
1100
1101         if (log_format) {
1102                 if (log_format_has(log_format, 'i'))
1103                         log_format_has_i = 1;
1104                 if (!log_format_has(log_format, 'b')
1105                  && !log_format_has(log_format, 'c'))
1106                         log_before_transfer = !am_server;
1107         } else if (itemize_changes) {
1108                 log_format = "%i %n%L";
1109                 log_format_has_i = 1;
1110                 log_before_transfer = !am_server;
1111         }
1112
1113         if ((do_progress || dry_run) && !verbose && !log_before_transfer
1114             && !am_server)
1115                 verbose = 1;
1116
1117         if (dry_run)
1118                 do_xfers = 0;
1119
1120         set_io_timeout(io_timeout);
1121
1122         if (verbose && !log_format) {
1123                 log_format = "%n%L";
1124                 log_before_transfer = !am_server;
1125         }
1126         if (log_format_has_i || log_format_has(log_format, 'o'))
1127                 log_format_has_o_or_i = 1;
1128
1129         if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1130                 bwlimit = daemon_bwlimit;
1131         if (bwlimit) {
1132                 bwlimit_writemax = (size_t)bwlimit * 128;
1133                 if (bwlimit_writemax < 512)
1134                         bwlimit_writemax = 512;
1135         }
1136
1137         if (append_mode) {
1138                 if (whole_file > 0) {
1139                         snprintf(err_buf, sizeof err_buf,
1140                                  "--append cannot be used with --whole-file\n");
1141                         return 0;
1142                 }
1143                 if (refused_inplace) {
1144                         create_refuse_error(refused_inplace);
1145                         return 0;
1146                 }
1147                 inplace = 1;
1148         }
1149
1150         if (delay_updates && !partial_dir)
1151                 partial_dir = partialdir_for_delayupdate;
1152
1153         if (inplace) {
1154 #ifdef HAVE_FTRUNCATE
1155                 if (partial_dir) {
1156                         snprintf(err_buf, sizeof err_buf,
1157                                  "--%s cannot be used with --%s\n",
1158                                  append_mode ? "append" : "inplace",
1159                                  delay_updates ? "delay-updates" : "partial-dir");
1160                         return 0;
1161                 }
1162                 /* --inplace implies --partial for refusal purposes, but we
1163                  * clear the keep_partial flag for internal logic purposes. */
1164                 if (refused_partial) {
1165                         create_refuse_error(refused_partial);
1166                         return 0;
1167                 }
1168                 keep_partial = 0;
1169 #else
1170                 snprintf(err_buf, sizeof err_buf,
1171                          "--%s is not supported on this %s\n",
1172                          append_mode ? "append" : "inplace",
1173                          am_server ? "server" : "client");
1174                 return 0;
1175 #endif
1176         } else {
1177                 if (keep_partial && !partial_dir) {
1178                         if ((arg = getenv("RSYNC_PARTIAL_DIR")) != NULL && *arg)
1179                                 partial_dir = strdup(arg);
1180                 }
1181                 if (partial_dir) {
1182                         if (*partial_dir)
1183                                 clean_fname(partial_dir, 1);
1184                         if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1185                                 partial_dir = NULL;
1186                         else if (*partial_dir != '/') {
1187                                 parse_rule(&filter_list, partial_dir,
1188                                     MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
1189                         }
1190                         if (!partial_dir && refused_partial) {
1191                                 create_refuse_error(refused_partial);
1192                                 return 0;
1193                         }
1194                         keep_partial = 1;
1195                 }
1196         }
1197
1198         if (files_from) {
1199                 char *h, *p;
1200                 int q;
1201                 if (*argc > 2 || (!am_daemon && *argc == 1)) {
1202                         usage(FERROR);
1203                         exit_cleanup(RERR_SYNTAX);
1204                 }
1205                 if (strcmp(files_from, "-") == 0) {
1206                         filesfrom_fd = 0;
1207                         if (am_server)
1208                                 filesfrom_host = ""; /* reading from socket */
1209                 } else if ((p = check_for_hostspec(files_from, &h, &q)) != 0) {
1210                         if (am_server) {
1211                                 snprintf(err_buf, sizeof err_buf,
1212                                         "The --files-from sent to the server cannot specify a host.\n");
1213                                 return 0;
1214                         }
1215                         files_from = p;
1216                         filesfrom_host = h;
1217                         if (strcmp(files_from, "-") == 0) {
1218                                 snprintf(err_buf, sizeof err_buf,
1219                                         "Invalid --files-from remote filename\n");
1220                                 return 0;
1221                         }
1222                 } else {
1223                         if (sanitize_paths)
1224                                 files_from = sanitize_path(NULL, files_from, NULL, 0);
1225                         if (server_filter_list.head) {
1226                                 if (!*files_from)
1227                                         goto options_rejected;
1228                                 clean_fname(files_from, 1);
1229                                 if (check_filter(&server_filter_list, files_from, 0) < 0)
1230                                         goto options_rejected;
1231                         }
1232                         filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1233                         if (filesfrom_fd < 0) {
1234                                 snprintf(err_buf, sizeof err_buf,
1235                                         "failed to open files-from file %s: %s\n",
1236                                         files_from, strerror(errno));
1237                                 return 0;
1238                         }
1239                 }
1240         }
1241
1242         am_starting_up = 0;
1243
1244         return 1;
1245 }
1246
1247
1248 /**
1249  * Construct a filtered list of options to pass through from the
1250  * client to the server.
1251  *
1252  * This involves setting options that will tell the server how to
1253  * behave, and also filtering out options that are processed only
1254  * locally.
1255  **/
1256 void server_options(char **args,int *argc)
1257 {
1258         static char argstr[64];
1259         int ac = *argc;
1260         char *arg;
1261
1262         int i, x;
1263
1264         if (blocking_io == -1)
1265                 blocking_io = 0;
1266
1267         args[ac++] = "--server";
1268
1269         if (daemon_over_rsh) {
1270                 args[ac++] = "--daemon";
1271                 *argc = ac;
1272                 /* if we're passing --daemon, we're done */
1273                 return;
1274         }
1275
1276         if (!am_sender)
1277                 args[ac++] = "--sender";
1278
1279         x = 1;
1280         argstr[0] = '-';
1281         for (i = 0; i < verbose; i++)
1282                 argstr[x++] = 'v';
1283
1284         /* the -q option is intentionally left out */
1285         if (make_backups)
1286                 argstr[x++] = 'b';
1287         if (update_only)
1288                 argstr[x++] = 'u';
1289         if (!do_xfers) /* NOT "dry_run"! */
1290                 argstr[x++] = 'n';
1291         if (preserve_links)
1292                 argstr[x++] = 'l';
1293         if (copy_links)
1294                 argstr[x++] = 'L';
1295         if (xfer_dirs > 1)
1296                 argstr[x++] = 'd';
1297         if (keep_dirlinks && am_sender)
1298                 argstr[x++] = 'K';
1299
1300         if (whole_file > 0)
1301                 argstr[x++] = 'W';
1302         /* We don't need to send --no-whole-file, because it's the
1303          * default for remote transfers, and in any case old versions
1304          * of rsync will not understand it. */
1305
1306         if (preserve_hard_links)
1307                 argstr[x++] = 'H';
1308         if (preserve_uid)
1309                 argstr[x++] = 'o';
1310         if (preserve_gid)
1311                 argstr[x++] = 'g';
1312         if (preserve_devices)
1313                 argstr[x++] = 'D';
1314         if (preserve_times)
1315                 argstr[x++] = 't';
1316         if (omit_dir_times == 2 && am_sender)
1317                 argstr[x++] = 'O';
1318         if (preserve_perms)
1319                 argstr[x++] = 'p';
1320         if (recurse)
1321                 argstr[x++] = 'r';
1322         if (always_checksum)
1323                 argstr[x++] = 'c';
1324         if (cvs_exclude)
1325                 argstr[x++] = 'C';
1326         if (ignore_times)
1327                 argstr[x++] = 'I';
1328         if (relative_paths)
1329                 argstr[x++] = 'R';
1330         if (one_file_system)
1331                 argstr[x++] = 'x';
1332         if (sparse_files)
1333                 argstr[x++] = 'S';
1334         if (do_compression)
1335                 argstr[x++] = 'z';
1336
1337         /* This is a complete hack - blame Rusty.  FIXME!
1338          * This hack is only needed for older rsync versions that
1339          * don't understand the --list-only option. */
1340         if (list_only == 1 && !recurse)
1341                 argstr[x++] = 'r';
1342
1343         argstr[x] = 0;
1344
1345         if (x != 1)
1346                 args[ac++] = argstr;
1347
1348         if (list_only > 1)
1349                 args[ac++] = "--list-only";
1350
1351         /* The server side doesn't use our log-format, but in certain
1352          * circumstances they need to know a little about the option. */
1353         if (log_format && am_sender) {
1354                 if (log_format_has_i)
1355                         args[ac++] = "--log-format=%i";
1356                 else if (log_format_has_o_or_i)
1357                         args[ac++] = "--log-format=%o";
1358                 else if (!verbose)
1359                         args[ac++] = "--log-format=X";
1360         }
1361
1362         if (block_size) {
1363                 if (asprintf(&arg, "-B%lu", block_size) < 0)
1364                         goto oom;
1365                 args[ac++] = arg;
1366         }
1367
1368         if (max_delete && am_sender) {
1369                 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1370                         goto oom;
1371                 args[ac++] = arg;
1372         }
1373
1374         if (max_size && am_sender) {
1375                 args[ac++] = "--max-size";
1376                 args[ac++] = max_size_arg;
1377         }
1378
1379         if (io_timeout) {
1380                 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1381                         goto oom;
1382                 args[ac++] = arg;
1383         }
1384
1385         if (bwlimit) {
1386                 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1387                         goto oom;
1388                 args[ac++] = arg;
1389         }
1390
1391         if (backup_dir) {
1392                 args[ac++] = "--backup-dir";
1393                 args[ac++] = backup_dir;
1394         }
1395
1396         /* Only send --suffix if it specifies a non-default value. */
1397         if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1398                 /* We use the following syntax to avoid weirdness with '~'. */
1399                 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1400                         goto oom;
1401                 args[ac++] = arg;
1402         }
1403
1404         if (am_sender) {
1405                 if (delete_excluded)
1406                         args[ac++] = "--delete-excluded";
1407                 else if (delete_before == 1 || delete_after)
1408                         args[ac++] = "--delete";
1409                 if (delete_before > 1)
1410                         args[ac++] = "--delete-before";
1411                 if (delete_during)
1412                         args[ac++] = "--delete-during";
1413                 if (delete_after)
1414                         args[ac++] = "--delete-after";
1415                 if (force_delete)
1416                         args[ac++] = "--force";
1417                 if (write_batch < 0)
1418                         args[ac++] = "--only-write-batch=X";
1419         }
1420
1421         if (size_only)
1422                 args[ac++] = "--size-only";
1423
1424         if (modify_window_set) {
1425                 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1426                         goto oom;
1427                 args[ac++] = arg;
1428         }
1429
1430         if (checksum_seed) {
1431                 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1432                         goto oom;
1433                 args[ac++] = arg;
1434         }
1435
1436         if (partial_dir && am_sender) {
1437                 if (partial_dir != partialdir_for_delayupdate) {
1438                         args[ac++] = "--partial-dir";
1439                         args[ac++] = partial_dir;
1440                 }
1441                 if (delay_updates)
1442                         args[ac++] = "--delay-updates";
1443         } else if (keep_partial)
1444                 args[ac++] = "--partial";
1445
1446         if (ignore_errors)
1447                 args[ac++] = "--ignore-errors";
1448
1449         if (copy_unsafe_links)
1450                 args[ac++] = "--copy-unsafe-links";
1451
1452         if (safe_symlinks)
1453                 args[ac++] = "--safe-links";
1454
1455         if (numeric_ids)
1456                 args[ac++] = "--numeric-ids";
1457
1458         if (only_existing && am_sender)
1459                 args[ac++] = "--existing";
1460
1461         if (opt_ignore_existing && am_sender)
1462                 args[ac++] = "--ignore-existing";
1463
1464         if (append_mode)
1465                 args[ac++] = "--append";
1466         else if (inplace)
1467                 args[ac++] = "--inplace";
1468
1469         if (tmpdir) {
1470                 args[ac++] = "--temp-dir";
1471                 args[ac++] = tmpdir;
1472         }
1473
1474         if (basis_dir[0] && am_sender) {
1475                 /* the server only needs this option if it is not the sender,
1476                  *   and it may be an older version that doesn't know this
1477                  *   option, so don't send it if client is the sender.
1478                  */
1479                 int i;
1480                 for (i = 0; i < basis_dir_cnt; i++) {
1481                         args[ac++] = dest_option;
1482                         args[ac++] = basis_dir[i];
1483                 }
1484         }
1485
1486         if (files_from && (!am_sender || filesfrom_host)) {
1487                 if (filesfrom_host) {
1488                         args[ac++] = "--files-from";
1489                         args[ac++] = files_from;
1490                         if (eol_nulls)
1491                                 args[ac++] = "--from0";
1492                 } else {
1493                         args[ac++] = "--files-from=-";
1494                         args[ac++] = "--from0";
1495                 }
1496                 if (!relative_paths)
1497                         args[ac++] = "--no-relative";
1498         }
1499         if (relative_paths && !implied_dirs && !am_sender)
1500                 args[ac++] = "--no-implied-dirs";
1501
1502         if (fuzzy_basis && am_sender)
1503                 args[ac++] = "--fuzzy";
1504
1505         if (remove_sent_files)
1506                 args[ac++] = "--remove-sent-files";
1507
1508         *argc = ac;
1509         return;
1510
1511     oom:
1512         out_of_memory("server_options");
1513 }
1514
1515 /* Look for a HOST specfication of the form "HOST:PATH", "HOST::PATH", or
1516  * "rsync://HOST:PORT/PATH".  If found, *host_ptr will be set to some allocated
1517  * memory with the HOST.  If a daemon-accessing spec was specified, the value
1518  * of *port_ptr will contain a non-0 port number, otherwise it will be set to
1519  * 0.  The return value is a pointer to the PATH.  Note that the HOST spec can
1520  * be an IPv6 literal address enclosed in '[' and ']' (such as "[::1]" or
1521  * "[::ffff:127.0.0.1]") which is returned without the '[' and ']'. */
1522 char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
1523 {
1524         char *p;
1525         int not_host;
1526
1527         if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) {
1528                 char *path;
1529                 int hostlen;
1530                 s += strlen(URL_PREFIX);
1531                 if ((p = strchr(s, '/')) != NULL) {
1532                         hostlen = p - s;
1533                         path = p + 1;
1534                 } else {
1535                         hostlen = strlen(s);
1536                         path = "";
1537                 }
1538                 if (*s == '[' && (p = strchr(s, ']')) != NULL) {
1539                         s++;
1540                         hostlen = p - s;
1541                         if (p[1] == ':')
1542                                 *port_ptr = atoi(p+2);
1543                 } else {
1544                         if ((p = strchr(s, ':')) != NULL) {
1545                                 hostlen = p - s;
1546                                 *port_ptr = atoi(p+1);
1547                         }
1548                 }
1549                 if (!*port_ptr)
1550                         *port_ptr = RSYNC_PORT;
1551                 *host_ptr = new_array(char, hostlen + 1);
1552                 strlcpy(*host_ptr, s, hostlen + 1);
1553                 return path;
1554         }
1555
1556         if (*s == '[' && (p = strchr(s, ']')) != NULL && p[1] == ':') {
1557                 s++;
1558                 *p = '\0';
1559                 not_host = strchr(s, '/') || !strchr(s, ':');
1560                 *p = ']';
1561                 if (not_host)
1562                         return NULL;
1563                 p++;
1564         } else {
1565                 if (!(p = strchr(s, ':')))
1566                         return NULL;
1567                 *p = '\0';
1568                 not_host = strchr(s, '/') != NULL;
1569                 *p = ':';
1570                 if (not_host)
1571                         return NULL;
1572         }
1573
1574         *host_ptr = new_array(char, p - s + 1);
1575         strlcpy(*host_ptr, s, p - s + 1);
1576
1577         if (p[1] == ':') {
1578                 if (port_ptr && !*port_ptr)
1579                         *port_ptr = RSYNC_PORT;
1580                 return p + 2;
1581         }
1582         if (port_ptr)
1583                 *port_ptr = 0;
1584
1585         return p + 1;
1586 }