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