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