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