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