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