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