Allow --temp-dir to be specified with --daemon to set the default.
[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   {"help",            'h', POPT_ARG_NONE,   0, 'h', 0, 0 },
536   {0,0,0,0, 0, 0, 0}
537 };
538
539
540 static char err_buf[200];
541
542
543 /**
544  * Store the option error message, if any, so that we can log the
545  * connection attempt (which requires parsing the options), and then
546  * show the error later on.
547  **/
548 void option_error(void)
549 {
550         if (!err_buf[0]) {
551                 strcpy(err_buf, "Error parsing options: "
552                     "option may be supported on client but not on server?\n");
553         }
554
555         rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
556 }
557
558
559 /**
560  * Tweak the option table to disable all options that the rsyncd.conf
561  * file has told us to refuse.
562  **/
563 static void set_refuse_options(char *bp)
564 {
565         struct poptOption *op;
566         char *cp, shortname[2];
567         int is_wild, found_match;
568
569         shortname[1] = '\0';
570
571         while (1) {
572                 while (*bp == ' ') bp++;
573                 if (!*bp)
574                         break;
575                 if ((cp = strchr(bp, ' ')) != NULL)
576                         *cp= '\0';
577                 is_wild = strpbrk(bp, "*?[") != NULL;
578                 found_match = 0;
579                 for (op = long_options; ; op++) {
580                         *shortname = op->shortName;
581                         if (!op->longName && !*shortname)
582                                 break;
583                         if ((op->longName && wildmatch(bp, op->longName))
584                             || (*shortname && wildmatch(bp, shortname))) {
585                                 if (op->argInfo == POPT_ARG_VAL)
586                                         op->argInfo = POPT_ARG_NONE;
587                                 op->val = (op - long_options) + OPT_REFUSED_BASE;
588                                 found_match = 1;
589                                 /* These flags are set to let us easily check
590                                  * an implied option later in the code. */
591                                 switch (*shortname) {
592                                 case 'r': case 'd': case 'l': case 'p':
593                                 case 't': case 'g': case 'o': case 'D':
594                                         refused_archive_part = op->val;
595                                         break;
596                                 case '\0':
597                                         if (wildmatch("delete", op->longName))
598                                                 refused_delete = op->val;
599                                         else if (wildmatch("delete-before", op->longName))
600                                                 refused_delete_before = op->val;
601                                         else if (wildmatch("partial", op->longName))
602                                                 refused_partial = op->val;
603                                         else if (wildmatch("progress", op->longName))
604                                                 refused_progress = op->val;
605                                         else if (wildmatch("inplace", op->longName))
606                                                 refused_inplace = op->val;
607                                         break;
608                                 }
609                                 if (!is_wild)
610                                         break;
611                         }
612                 }
613                 if (!found_match) {
614                         rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
615                                 bp);
616                 }
617                 if (!cp)
618                         break;
619                 *cp = ' ';
620                 bp = cp + 1;
621         }
622
623         for (op = long_options; ; op++) {
624                 *shortname = op->shortName;
625                 if (!op->longName && !*shortname)
626                         break;
627                 if (op->val == OPT_DAEMON) {
628                         if (op->argInfo == POPT_ARG_VAL)
629                                 op->argInfo = POPT_ARG_NONE;
630                         op->val = (op - long_options) + OPT_REFUSED_BASE;
631                 }
632         }
633 }
634
635
636 static int count_args(const char **argv)
637 {
638         int i = 0;
639
640         if (argv) {
641                 while (argv[i] != NULL)
642                         i++;
643         }
644
645         return i;
646 }
647
648
649 static OFF_T parse_size_arg(const char *size_arg)
650 {
651         const char *arg;
652         OFF_T size;
653
654         for (arg = size_arg; isdigit(*(uchar*)arg); arg++) {}
655         if (*arg == '.')
656                 for (arg++; isdigit(*(uchar*)arg); arg++) {}
657         switch (*arg) {
658         case 'k': case 'K':
659                 size = atof(size_arg) * 1024;
660                 break;
661         case 'm': case 'M':
662                 size = atof(size_arg) * 1024*1024;
663                 break;
664         case 'g': case 'G':
665                 size = atof(size_arg) * 1024*1024*1024;
666                 break;
667         case '\0':
668                 size = atof(size_arg);
669                 break;
670         default:
671                 size = 0;
672                 break;
673         }
674         return size;
675 }
676
677
678 static void create_refuse_error(int which)
679 {
680         /* The "which" value is the index + OPT_REFUSED_BASE. */
681         struct poptOption *op = &long_options[which - OPT_REFUSED_BASE];
682         int n = snprintf(err_buf, sizeof err_buf,
683                          "The server is configured to refuse --%s\n",
684                          op->longName) - 1;
685         if (op->shortName) {
686                 snprintf(err_buf + n, sizeof err_buf - n,
687                          " (-%c)\n", op->shortName);
688         }
689 }
690
691
692 /**
693  * Process command line arguments.  Called on both local and remote.
694  *
695  * @retval 1 if all options are OK; with globals set to appropriate
696  * values
697  *
698  * @retval 0 on error, with err_buf containing an explanation
699  **/
700 int parse_arguments(int *argc, const char ***argv, int frommain)
701 {
702         int opt;
703         char *ref = lp_refuse_options(module_id);
704         const char *arg;
705         poptContext pc;
706
707         if (ref && *ref)
708                 set_refuse_options(ref);
709
710         /* TODO: Call poptReadDefaultConfig; handle errors. */
711
712         /* The context leaks in case of an error, but if there's a
713          * problem we always exit anyhow. */
714         pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
715         poptReadDefaultConfig(pc, 0);
716
717         while ((opt = poptGetNextOpt(pc)) != -1) {
718                 /* most options are handled automatically by popt;
719                  * only special cases are returned and listed here. */
720
721                 switch (opt) {
722                 case OPT_VERSION:
723                         print_rsync_version(FINFO);
724                         exit_cleanup(0);
725
726                 case OPT_DAEMON:
727                         if (am_daemon) {
728                                 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
729                                 return 0;
730                         }
731                         poptFreeContext(pc);
732                         pc = poptGetContext(RSYNC_NAME, *argc, *argv,
733                                             long_daemon_options, 0);
734                         while ((opt = poptGetNextOpt(pc)) != -1) {
735                                 switch (opt) {
736                                 case 'h':
737                                         daemon_usage(FINFO);
738                                         exit_cleanup(0);
739
740                                 case 'v':
741                                         verbose++;
742                                         break;
743
744                                 default:
745                                         rprintf(FERROR,
746                                             "rsync: %s: %s (in daemon mode)\n",
747                                             poptBadOption(pc, POPT_BADOPTION_NOALIAS),
748                                             poptStrerror(opt));
749                                         goto daemon_error;
750                                 }
751                         }
752                         if (!daemon_opt) {
753                                 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
754                             daemon_error:
755                                 rprintf(FERROR,
756                                     "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
757                                 exit_cleanup(RERR_SYNTAX);
758                         }
759                         *argv = poptGetArgs(pc);
760                         *argc = count_args(*argv);
761                         am_starting_up = 0;
762                         daemon_opt = 0;
763                         am_daemon = 1;
764                         return 1;
765
766                 case OPT_MODIFY_WINDOW:
767                         /* The value has already been set by popt, but
768                          * we need to remember that we're using a
769                          * non-default setting. */
770                         modify_window_set = 1;
771                         break;
772
773                 case OPT_FILTER:
774                         parse_rule(&filter_list, poptGetOptArg(pc), 0, 0);
775                         break;
776
777                 case OPT_EXCLUDE:
778                         parse_rule(&filter_list, poptGetOptArg(pc),
779                                    0, XFLG_OLD_PREFIXES);
780                         break;
781
782                 case OPT_INCLUDE:
783                         parse_rule(&filter_list, poptGetOptArg(pc),
784                                    MATCHFLG_INCLUDE, XFLG_OLD_PREFIXES);
785                         break;
786
787                 case OPT_EXCLUDE_FROM:
788                 case OPT_INCLUDE_FROM:
789                         arg = poptGetOptArg(pc);
790                         if (sanitize_paths)
791                                 arg = sanitize_path(NULL, arg, NULL, 0);
792                         if (server_filter_list.head) {
793                                 char *cp = (char *)arg;
794                                 if (!*cp)
795                                         goto options_rejected;
796                                 clean_fname(cp, 1);
797                                 if (check_filter(&server_filter_list, cp, 0) < 0)
798                                         goto options_rejected;
799                         }
800                         parse_filter_file(&filter_list, arg,
801                                 opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
802                                 XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
803                         break;
804
805                 case 'a':
806                         if (refused_archive_part) {
807                                 create_refuse_error(refused_archive_part);
808                                 return 0;
809                         }
810                         if (!recurse) /* preserve recurse == 2 */
811                                 recurse = 1;
812 #ifdef SUPPORT_LINKS
813                         preserve_links = 1;
814 #endif
815                         preserve_perms = 1;
816                         preserve_times = 1;
817                         preserve_gid = 1;
818                         preserve_uid = 1;
819                         preserve_devices = 1;
820                         break;
821
822                 case 'h':
823                         usage(FINFO);
824                         exit_cleanup(0);
825
826                 case 'v':
827                         verbose++;
828                         break;
829
830                 case 'q':
831                         if (frommain)
832                                 quiet++;
833                         break;
834
835                 case OPT_SENDER:
836                         if (!am_server) {
837                                 usage(FERROR);
838                                 exit_cleanup(RERR_SYNTAX);
839                         }
840                         am_sender = 1;
841                         break;
842
843                 case 'F':
844                         switch (++F_option_cnt) {
845                         case 1:
846                                 parse_rule(&filter_list,": /.rsync-filter",0,0);
847                                 break;
848                         case 2:
849                                 parse_rule(&filter_list,"- .rsync-filter",0,0);
850                                 break;
851                         }
852                         break;
853
854                 case 'P':
855                         if (refused_partial || refused_progress) {
856                                 create_refuse_error(refused_partial
857                                     ? refused_partial : refused_progress);
858                                 return 0;
859                         }
860                         do_progress = 1;
861                         keep_partial = 1;
862                         break;
863
864                 case OPT_WRITE_BATCH:
865                         /* batch_name is already set */
866                         write_batch = 1;
867                         break;
868
869                 case OPT_ONLY_WRITE_BATCH:
870                         /* batch_name is already set */
871                         write_batch = -1;
872                         break;
873
874                 case OPT_READ_BATCH:
875                         /* batch_name is already set */
876                         read_batch = 1;
877                         break;
878
879                 case OPT_MAX_SIZE:
880                         if ((max_size = parse_size_arg(max_size_arg)) <= 0) {
881                                 snprintf(err_buf, sizeof err_buf,
882                                         "--max-size value is invalid: %s\n",
883                                         max_size_arg);
884                                 return 0;
885                         }
886                         break;
887
888                 case OPT_LINK_DEST:
889 #ifdef HAVE_LINK
890                         link_dest = 1;
891                         dest_option = "--link-dest";
892                         goto set_dest_dir;
893 #else
894                         snprintf(err_buf, sizeof err_buf,
895                                  "hard links are not supported on this %s\n",
896                                  am_server ? "server" : "client");
897                         return 0;
898 #endif
899
900                 case OPT_COPY_DEST:
901                         copy_dest = 1;
902                         dest_option = "--copy-dest";
903                         goto set_dest_dir;
904
905                 case OPT_COMPARE_DEST:
906                         compare_dest = 1;
907                         dest_option = "--compare-dest";
908                 set_dest_dir:
909                         if (basis_dir_cnt >= MAX_BASIS_DIRS) {
910                                 snprintf(err_buf, sizeof err_buf,
911                                         "ERROR: at most %d %s args may be specified\n",
912                                         MAX_BASIS_DIRS, dest_option);
913                                 return 0;
914                         }
915                         arg = poptGetOptArg(pc);
916                         if (sanitize_paths)
917                                 arg = sanitize_path(NULL, arg, NULL, 0);
918                         basis_dir[basis_dir_cnt++] = (char *)arg;
919                         break;
920
921                 default:
922                         /* A large opt value means that set_refuse_options()
923                          * turned this option off. */
924                         if (opt >= OPT_REFUSED_BASE) {
925                                 create_refuse_error(opt);
926                                 return 0;
927                         }
928                         snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
929                                  am_server ? "on remote machine: " : "",
930                                  poptBadOption(pc, POPT_BADOPTION_NOALIAS),
931                                  poptStrerror(opt));
932                         return 0;
933                 }
934         }
935
936 #ifndef SUPPORT_LINKS
937         if (preserve_links && !am_sender) {
938                 snprintf(err_buf, sizeof err_buf,
939                          "symlinks are not supported on this %s\n",
940                          am_server ? "server" : "client");
941                 return 0;
942         }
943 #endif
944
945 #ifndef SUPPORT_HARD_LINKS
946         if (preserve_hard_links) {
947                 snprintf(err_buf, sizeof err_buf,
948                          "hard links are not supported on this %s\n",
949                          am_server ? "server" : "client");
950                 return 0;
951         }
952 #endif
953
954         if (write_batch && read_batch) {
955                 snprintf(err_buf, sizeof err_buf,
956                         "--write-batch and --read-batch can not be used together\n");
957                 return 0;
958         }
959         if (write_batch > 0 || read_batch) {
960                 if (am_server) {
961                         rprintf(FINFO,
962                                 "ignoring --%s-batch option sent to server\n",
963                                 write_batch ? "write" : "read");
964                         /* We don't actually exit_cleanup(), so that we can
965                          * still service older version clients that still send
966                          * batch args to server. */
967                         read_batch = write_batch = 0;
968                         batch_name = NULL;
969                 } else if (dry_run)
970                         write_batch = 0;
971         }
972         if (read_batch && files_from) {
973                 snprintf(err_buf, sizeof err_buf,
974                         "--read-batch cannot be used with --files-from\n");
975                 return 0;
976         }
977         if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
978                 snprintf(err_buf, sizeof err_buf,
979                         "the batch-file name must be %d characters or less.\n",
980                         MAX_BATCH_NAME_LEN);
981                 return 0;
982         }
983
984         if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
985                 snprintf(err_buf, sizeof err_buf,
986                          "the --temp-dir path is WAY too long.\n");
987                 return 0;
988         }
989
990         if (compare_dest + copy_dest + link_dest > 1) {
991                 snprintf(err_buf, sizeof err_buf,
992                         "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
993                 return 0;
994         }
995
996         if (files_from) {
997                 if (recurse == 1) /* preserve recurse == 2 */
998                         recurse = 0;
999                 if (xfer_dirs < 0)
1000                         xfer_dirs = 1;
1001         }
1002
1003         if (xfer_dirs < 1)
1004                 xfer_dirs = recurse || list_only;
1005
1006         if (relative_paths < 0)
1007                 relative_paths = files_from? 1 : 0;
1008         if (!relative_paths)
1009                 implied_dirs = 0;
1010
1011         if (!!delete_before + delete_during + delete_after > 1) {
1012                 snprintf(err_buf, sizeof err_buf,
1013                         "You may not combine multiple --delete-WHEN options.\n");
1014                 return 0;
1015         }
1016         if (!recurse) {
1017                 delete_before = delete_during = delete_after = 0;
1018                 delete_mode = delete_excluded = 0;
1019         } else if (delete_before || delete_during || delete_after)
1020                 delete_mode = 1;
1021         else if (delete_mode || delete_excluded) {
1022                 if (refused_delete_before) {
1023                         create_refuse_error(refused_delete_before);
1024                         return 0;
1025                 }
1026                 delete_mode = delete_before = 1;
1027         }
1028
1029         if (delete_mode && refused_delete) {
1030                 create_refuse_error(refused_delete);
1031                 return 0;
1032         }
1033
1034         if (remove_sent_files) {
1035                 /* We only want to infer this refusal of --remove-sent-files
1036                  * via the refusal of "delete", not any of the "delete-FOO"
1037                  * options. */
1038                 if (refused_delete && am_sender) {
1039                         create_refuse_error(refused_delete);
1040                         return 0;
1041                 }
1042                 need_messages_from_generator = 1;
1043         }
1044
1045         *argv = poptGetArgs(pc);
1046         *argc = count_args(*argv);
1047
1048         if (sanitize_paths) {
1049                 int i;
1050                 for (i = *argc; i-- > 0; )
1051                         (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
1052                 if (tmpdir)
1053                         tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
1054                 if (partial_dir)
1055                         partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
1056                 if (backup_dir)
1057                         backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
1058         }
1059         if (server_filter_list.head && !am_sender) {
1060                 struct filter_list_struct *elp = &server_filter_list;
1061                 int i;
1062                 if (tmpdir) {
1063                         if (!*tmpdir)
1064                                 goto options_rejected;
1065                         clean_fname(tmpdir, 1);
1066                         if (check_filter(elp, tmpdir, 1) < 0)
1067                                 goto options_rejected;
1068                 }
1069                 if (partial_dir && *partial_dir) {
1070                         clean_fname(partial_dir, 1);
1071                         if (check_filter(elp, partial_dir, 1) < 0)
1072                                 goto options_rejected;
1073                 }
1074                 for (i = 0; i < basis_dir_cnt; i++) {
1075                         if (!*basis_dir[i])
1076                                 goto options_rejected;
1077                         clean_fname(basis_dir[i], 1);
1078                         if (check_filter(elp, basis_dir[i], 1) < 0)
1079                                 goto options_rejected;
1080                 }
1081                 if (backup_dir) {
1082                         if (!*backup_dir)
1083                                 goto options_rejected;
1084                         clean_fname(backup_dir, 1);
1085                         if (check_filter(elp, backup_dir, 1) < 0) {
1086                             options_rejected:
1087                                 snprintf(err_buf, sizeof err_buf,
1088                                     "Your options have been rejected by the server.\n");
1089                                 return 0;
1090                         }
1091                 }
1092         }
1093
1094         if (!backup_suffix)
1095                 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
1096         backup_suffix_len = strlen(backup_suffix);
1097         if (strchr(backup_suffix, '/') != NULL) {
1098                 snprintf(err_buf, sizeof err_buf,
1099                         "--suffix cannot contain slashes: %s\n",
1100                         backup_suffix);
1101                 return 0;
1102         }
1103         if (backup_dir) {
1104                 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
1105                 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
1106                 if (backup_dir_remainder < 32) {
1107                         snprintf(err_buf, sizeof err_buf,
1108                                 "the --backup-dir path is WAY too long.\n");
1109                         return 0;
1110                 }
1111                 if (backup_dir_buf[backup_dir_len - 1] != '/') {
1112                         backup_dir_buf[backup_dir_len++] = '/';
1113                         backup_dir_buf[backup_dir_len] = '\0';
1114                 }
1115                 if (verbose > 1 && !am_sender) {
1116                         rprintf(FINFO, "backup_dir is %s\n",
1117                                 safe_fname(backup_dir_buf));
1118                 }
1119         } else if (!backup_suffix_len && (!am_server || !am_sender)) {
1120                 snprintf(err_buf, sizeof err_buf,
1121                         "--suffix cannot be a null string without --backup-dir\n");
1122                 return 0;
1123         }
1124         if (make_backups && !backup_dir)
1125                 omit_dir_times = 1;
1126
1127         if (log_format) {
1128                 if (log_format_has(log_format, 'i'))
1129                         log_format_has_i = 1;
1130                 if (!log_format_has(log_format, 'b')
1131                  && !log_format_has(log_format, 'c'))
1132                         log_before_transfer = !am_server;
1133         } else if (itemize_changes) {
1134                 log_format = "%i %n%L";
1135                 log_format_has_i = 1;
1136                 log_before_transfer = !am_server;
1137         }
1138
1139         if ((do_progress || dry_run) && !verbose && !log_before_transfer
1140             && !am_server)
1141                 verbose = 1;
1142
1143         if (dry_run)
1144                 do_xfers = 0;
1145
1146         set_io_timeout(io_timeout);
1147
1148         if (verbose && !log_format) {
1149                 log_format = "%n%L";
1150                 log_before_transfer = !am_server;
1151         }
1152         if (log_format_has_i || log_format_has(log_format, 'o'))
1153                 log_format_has_o_or_i = 1;
1154
1155         if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1156                 bwlimit = daemon_bwlimit;
1157         if (bwlimit) {
1158                 bwlimit_writemax = (size_t)bwlimit * 128;
1159                 if (bwlimit_writemax < 512)
1160                         bwlimit_writemax = 512;
1161         }
1162
1163         if (sparse_files && inplace) {
1164                 /* Note: we don't check for this below, because --append is
1165                  * OK with --sparse (as long as redos are handled right). */
1166                 snprintf(err_buf, sizeof err_buf,
1167                          "--sparse cannot be used with --inplace\n");
1168                 return 0;
1169         }
1170
1171         if (append_mode) {
1172                 if (whole_file > 0) {
1173                         snprintf(err_buf, sizeof err_buf,
1174                                  "--append cannot be used with --whole-file\n");
1175                         return 0;
1176                 }
1177                 if (refused_inplace) {
1178                         create_refuse_error(refused_inplace);
1179                         return 0;
1180                 }
1181                 inplace = 1;
1182         }
1183
1184         if (delay_updates && !partial_dir)
1185                 partial_dir = partialdir_for_delayupdate;
1186
1187         if (inplace) {
1188 #ifdef HAVE_FTRUNCATE
1189                 if (partial_dir) {
1190                         snprintf(err_buf, sizeof err_buf,
1191                                  "--%s cannot be used with --%s\n",
1192                                  append_mode ? "append" : "inplace",
1193                                  delay_updates ? "delay-updates" : "partial-dir");
1194                         return 0;
1195                 }
1196                 /* --inplace implies --partial for refusal purposes, but we
1197                  * clear the keep_partial flag for internal logic purposes. */
1198                 if (refused_partial) {
1199                         create_refuse_error(refused_partial);
1200                         return 0;
1201                 }
1202                 keep_partial = 0;
1203 #else
1204                 snprintf(err_buf, sizeof err_buf,
1205                          "--%s is not supported on this %s\n",
1206                          append_mode ? "append" : "inplace",
1207                          am_server ? "server" : "client");
1208                 return 0;
1209 #endif
1210         } else {
1211                 if (keep_partial && !partial_dir) {
1212                         if ((arg = getenv("RSYNC_PARTIAL_DIR")) != NULL && *arg)
1213                                 partial_dir = strdup(arg);
1214                 }
1215                 if (partial_dir) {
1216                         if (*partial_dir)
1217                                 clean_fname(partial_dir, 1);
1218                         if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1219                                 partial_dir = NULL;
1220                         else if (*partial_dir != '/') {
1221                                 parse_rule(&filter_list, partial_dir,
1222                                     MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
1223                         }
1224                         if (!partial_dir && refused_partial) {
1225                                 create_refuse_error(refused_partial);
1226                                 return 0;
1227                         }
1228                         keep_partial = 1;
1229                 }
1230         }
1231
1232         if (files_from) {
1233                 char *h, *p;
1234                 int q;
1235                 if (*argc > 2 || (!am_daemon && *argc == 1)) {
1236                         usage(FERROR);
1237                         exit_cleanup(RERR_SYNTAX);
1238                 }
1239                 if (strcmp(files_from, "-") == 0) {
1240                         filesfrom_fd = 0;
1241                         if (am_server)
1242                                 filesfrom_host = ""; /* reading from socket */
1243                 } else if ((p = check_for_hostspec(files_from, &h, &q)) != 0) {
1244                         if (am_server) {
1245                                 snprintf(err_buf, sizeof err_buf,
1246                                         "The --files-from sent to the server cannot specify a host.\n");
1247                                 return 0;
1248                         }
1249                         files_from = p;
1250                         filesfrom_host = h;
1251                         if (strcmp(files_from, "-") == 0) {
1252                                 snprintf(err_buf, sizeof err_buf,
1253                                         "Invalid --files-from remote filename\n");
1254                                 return 0;
1255                         }
1256                 } else {
1257                         if (sanitize_paths)
1258                                 files_from = sanitize_path(NULL, files_from, NULL, 0);
1259                         if (server_filter_list.head) {
1260                                 if (!*files_from)
1261                                         goto options_rejected;
1262                                 clean_fname(files_from, 1);
1263                                 if (check_filter(&server_filter_list, files_from, 0) < 0)
1264                                         goto options_rejected;
1265                         }
1266                         filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1267                         if (filesfrom_fd < 0) {
1268                                 snprintf(err_buf, sizeof err_buf,
1269                                         "failed to open files-from file %s: %s\n",
1270                                         files_from, strerror(errno));
1271                                 return 0;
1272                         }
1273                 }
1274         }
1275
1276         am_starting_up = 0;
1277
1278         return 1;
1279 }
1280
1281
1282 /**
1283  * Construct a filtered list of options to pass through from the
1284  * client to the server.
1285  *
1286  * This involves setting options that will tell the server how to
1287  * behave, and also filtering out options that are processed only
1288  * locally.
1289  **/
1290 void server_options(char **args,int *argc)
1291 {
1292         static char argstr[64];
1293         int ac = *argc;
1294         char *arg;
1295
1296         int i, x;
1297
1298         if (blocking_io == -1)
1299                 blocking_io = 0;
1300
1301         args[ac++] = "--server";
1302
1303         if (daemon_over_rsh) {
1304                 args[ac++] = "--daemon";
1305                 *argc = ac;
1306                 /* if we're passing --daemon, we're done */
1307                 return;
1308         }
1309
1310         if (!am_sender)
1311                 args[ac++] = "--sender";
1312
1313         x = 1;
1314         argstr[0] = '-';
1315         for (i = 0; i < verbose; i++)
1316                 argstr[x++] = 'v';
1317
1318         /* the -q option is intentionally left out */
1319         if (make_backups)
1320                 argstr[x++] = 'b';
1321         if (update_only)
1322                 argstr[x++] = 'u';
1323         if (!do_xfers) /* NOT "dry_run"! */
1324                 argstr[x++] = 'n';
1325         if (preserve_links)
1326                 argstr[x++] = 'l';
1327         if (copy_links)
1328                 argstr[x++] = 'L';
1329         if (xfer_dirs > 1)
1330                 argstr[x++] = 'd';
1331         if (keep_dirlinks && am_sender)
1332                 argstr[x++] = 'K';
1333
1334         if (whole_file > 0)
1335                 argstr[x++] = 'W';
1336         /* We don't need to send --no-whole-file, because it's the
1337          * default for remote transfers, and in any case old versions
1338          * of rsync will not understand it. */
1339
1340         if (preserve_hard_links)
1341                 argstr[x++] = 'H';
1342         if (preserve_uid)
1343                 argstr[x++] = 'o';
1344         if (preserve_gid)
1345                 argstr[x++] = 'g';
1346         if (preserve_devices)
1347                 argstr[x++] = 'D';
1348         if (preserve_times)
1349                 argstr[x++] = 't';
1350         if (omit_dir_times == 2 && am_sender)
1351                 argstr[x++] = 'O';
1352         if (preserve_perms)
1353                 argstr[x++] = 'p';
1354         if (recurse)
1355                 argstr[x++] = 'r';
1356         if (always_checksum)
1357                 argstr[x++] = 'c';
1358         if (cvs_exclude)
1359                 argstr[x++] = 'C';
1360         if (ignore_times)
1361                 argstr[x++] = 'I';
1362         if (relative_paths)
1363                 argstr[x++] = 'R';
1364         if (one_file_system)
1365                 argstr[x++] = 'x';
1366         if (sparse_files)
1367                 argstr[x++] = 'S';
1368         if (do_compression)
1369                 argstr[x++] = 'z';
1370
1371         /* This is a complete hack - blame Rusty.  FIXME!
1372          * This hack is only needed for older rsync versions that
1373          * don't understand the --list-only option. */
1374         if (list_only == 1 && !recurse)
1375                 argstr[x++] = 'r';
1376
1377         argstr[x] = 0;
1378
1379         if (x != 1)
1380                 args[ac++] = argstr;
1381
1382         if (list_only > 1)
1383                 args[ac++] = "--list-only";
1384
1385         /* The server side doesn't use our log-format, but in certain
1386          * circumstances they need to know a little about the option. */
1387         if (log_format && am_sender) {
1388                 if (log_format_has_i)
1389                         args[ac++] = "--log-format=%i";
1390                 else if (log_format_has_o_or_i)
1391                         args[ac++] = "--log-format=%o";
1392                 else if (!verbose)
1393                         args[ac++] = "--log-format=X";
1394         }
1395
1396         if (block_size) {
1397                 if (asprintf(&arg, "-B%lu", block_size) < 0)
1398                         goto oom;
1399                 args[ac++] = arg;
1400         }
1401
1402         if (max_delete && am_sender) {
1403                 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1404                         goto oom;
1405                 args[ac++] = arg;
1406         }
1407
1408         if (max_size && am_sender) {
1409                 args[ac++] = "--max-size";
1410                 args[ac++] = max_size_arg;
1411         }
1412
1413         if (io_timeout) {
1414                 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1415                         goto oom;
1416                 args[ac++] = arg;
1417         }
1418
1419         if (bwlimit) {
1420                 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1421                         goto oom;
1422                 args[ac++] = arg;
1423         }
1424
1425         if (backup_dir) {
1426                 args[ac++] = "--backup-dir";
1427                 args[ac++] = backup_dir;
1428         }
1429
1430         /* Only send --suffix if it specifies a non-default value. */
1431         if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1432                 /* We use the following syntax to avoid weirdness with '~'. */
1433                 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1434                         goto oom;
1435                 args[ac++] = arg;
1436         }
1437
1438         if (am_sender) {
1439                 if (delete_excluded)
1440                         args[ac++] = "--delete-excluded";
1441                 else if (delete_before == 1 || delete_after)
1442                         args[ac++] = "--delete";
1443                 if (delete_before > 1)
1444                         args[ac++] = "--delete-before";
1445                 if (delete_during)
1446                         args[ac++] = "--delete-during";
1447                 if (delete_after)
1448                         args[ac++] = "--delete-after";
1449                 if (force_delete)
1450                         args[ac++] = "--force";
1451                 if (write_batch < 0)
1452                         args[ac++] = "--only-write-batch=X";
1453         }
1454
1455         if (size_only)
1456                 args[ac++] = "--size-only";
1457
1458         if (modify_window_set) {
1459                 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1460                         goto oom;
1461                 args[ac++] = arg;
1462         }
1463
1464         if (checksum_seed) {
1465                 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1466                         goto oom;
1467                 args[ac++] = arg;
1468         }
1469
1470         if (partial_dir && am_sender) {
1471                 if (partial_dir != partialdir_for_delayupdate) {
1472                         args[ac++] = "--partial-dir";
1473                         args[ac++] = partial_dir;
1474                 }
1475                 if (delay_updates)
1476                         args[ac++] = "--delay-updates";
1477         } else if (keep_partial)
1478                 args[ac++] = "--partial";
1479
1480         if (ignore_errors)
1481                 args[ac++] = "--ignore-errors";
1482
1483         if (copy_unsafe_links)
1484                 args[ac++] = "--copy-unsafe-links";
1485
1486         if (safe_symlinks)
1487                 args[ac++] = "--safe-links";
1488
1489         if (numeric_ids)
1490                 args[ac++] = "--numeric-ids";
1491
1492         if (only_existing && am_sender)
1493                 args[ac++] = "--existing";
1494
1495         if (opt_ignore_existing && am_sender)
1496                 args[ac++] = "--ignore-existing";
1497
1498         if (append_mode)
1499                 args[ac++] = "--append";
1500         else if (inplace)
1501                 args[ac++] = "--inplace";
1502
1503         if (tmpdir) {
1504                 args[ac++] = "--temp-dir";
1505                 args[ac++] = tmpdir;
1506         }
1507
1508         if (basis_dir[0] && am_sender) {
1509                 /* the server only needs this option if it is not the sender,
1510                  *   and it may be an older version that doesn't know this
1511                  *   option, so don't send it if client is the sender.
1512                  */
1513                 int i;
1514                 for (i = 0; i < basis_dir_cnt; i++) {
1515                         args[ac++] = dest_option;
1516                         args[ac++] = basis_dir[i];
1517                 }
1518         }
1519
1520         if (files_from && (!am_sender || filesfrom_host)) {
1521                 if (filesfrom_host) {
1522                         args[ac++] = "--files-from";
1523                         args[ac++] = files_from;
1524                         if (eol_nulls)
1525                                 args[ac++] = "--from0";
1526                 } else {
1527                         args[ac++] = "--files-from=-";
1528                         args[ac++] = "--from0";
1529                 }
1530                 if (!relative_paths)
1531                         args[ac++] = "--no-relative";
1532         }
1533         if (relative_paths && !implied_dirs && !am_sender)
1534                 args[ac++] = "--no-implied-dirs";
1535
1536         if (fuzzy_basis && am_sender)
1537                 args[ac++] = "--fuzzy";
1538
1539         if (remove_sent_files)
1540                 args[ac++] = "--remove-sent-files";
1541
1542         *argc = ac;
1543         return;
1544
1545     oom:
1546         out_of_memory("server_options");
1547 }
1548
1549 /* Look for a HOST specfication of the form "HOST:PATH", "HOST::PATH", or
1550  * "rsync://HOST:PORT/PATH".  If found, *host_ptr will be set to some allocated
1551  * memory with the HOST.  If a daemon-accessing spec was specified, the value
1552  * of *port_ptr will contain a non-0 port number, otherwise it will be set to
1553  * 0.  The return value is a pointer to the PATH.  Note that the HOST spec can
1554  * be an IPv6 literal address enclosed in '[' and ']' (such as "[::1]" or
1555  * "[::ffff:127.0.0.1]") which is returned without the '[' and ']'. */
1556 char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
1557 {
1558         char *p;
1559         int not_host;
1560
1561         if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) {
1562                 char *path;
1563                 int hostlen;
1564                 s += strlen(URL_PREFIX);
1565                 if ((p = strchr(s, '/')) != NULL) {
1566                         hostlen = p - s;
1567                         path = p + 1;
1568                 } else {
1569                         hostlen = strlen(s);
1570                         path = "";
1571                 }
1572                 if (*s == '[' && (p = strchr(s, ']')) != NULL) {
1573                         s++;
1574                         hostlen = p - s;
1575                         if (p[1] == ':')
1576                                 *port_ptr = atoi(p+2);
1577                 } else {
1578                         if ((p = strchr(s, ':')) != NULL) {
1579                                 hostlen = p - s;
1580                                 *port_ptr = atoi(p+1);
1581                         }
1582                 }
1583                 if (!*port_ptr)
1584                         *port_ptr = RSYNC_PORT;
1585                 *host_ptr = new_array(char, hostlen + 1);
1586                 strlcpy(*host_ptr, s, hostlen + 1);
1587                 return path;
1588         }
1589
1590         if (*s == '[' && (p = strchr(s, ']')) != NULL && p[1] == ':') {
1591                 s++;
1592                 *p = '\0';
1593                 not_host = strchr(s, '/') || !strchr(s, ':');
1594                 *p = ']';
1595                 if (not_host)
1596                         return NULL;
1597                 p++;
1598         } else {
1599                 if (!(p = strchr(s, ':')))
1600                         return NULL;
1601                 *p = '\0';
1602                 not_host = strchr(s, '/') != NULL;
1603                 *p = ':';
1604                 if (not_host)
1605                         return NULL;
1606         }
1607
1608         *host_ptr = new_array(char, p - s + 1);
1609         strlcpy(*host_ptr, s, p - s + 1);
1610
1611         if (p[1] == ':') {
1612                 if (port_ptr && !*port_ptr)
1613                         *port_ptr = RSYNC_PORT;
1614                 return p + 2;
1615         }
1616         if (port_ptr)
1617                 *port_ptr = 0;
1618
1619         return p + 1;
1620 }