Changed the rdev code to have both an "rdev" variable (which always
[rsync/rsync.git] / options.c
... / ...
CommitLineData
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
24extern struct exclude_struct **exclude_list;
25
26int make_backups = 0;
27
28/**
29 * If 1, send the whole file as literal data rather than trying to
30 * create an incremental diff.
31 *
32 * If -1, then look at whether we're local or remote and go by that.
33 *
34 * @sa disable_deltas_p()
35 **/
36int whole_file = -1;
37
38int archive_mode = 0;
39int copy_links = 0;
40int preserve_links = 0;
41int preserve_hard_links = 0;
42int preserve_perms = 0;
43int preserve_devices = 0;
44int preserve_uid = 0;
45int preserve_gid = 0;
46int preserve_times = 0;
47int update_only = 0;
48int cvs_exclude = 0;
49int dry_run=0;
50int local_server=0;
51int ignore_times=0;
52int delete_mode=0;
53int delete_excluded=0;
54int one_file_system=0;
55int protocol_version = PROTOCOL_VERSION;
56int sparse_files=0;
57int do_compression=0;
58int am_root=0;
59int orig_umask=0;
60int relative_paths = -1;
61int implied_dirs = 1;
62int numeric_ids = 0;
63int force_delete = 0;
64int io_timeout = 0;
65int read_only = 0;
66int module_id = -1;
67int am_server = 0;
68int am_sender = 0;
69int am_generator = 0;
70char *files_from = NULL;
71int filesfrom_fd = -1;
72char *remote_filesfrom_file = NULL;
73int eol_nulls = 0;
74int recurse = 0;
75int am_daemon = 0;
76int daemon_over_rsh = 0;
77int do_stats=0;
78int do_progress=0;
79int keep_partial=0;
80int safe_symlinks=0;
81int copy_unsafe_links=0;
82int size_only=0;
83int bwlimit=0;
84int delete_after=0;
85int only_existing=0;
86int opt_ignore_existing=0;
87int max_delete=0;
88int ignore_errors=0;
89int modify_window=0;
90int blocking_io=-1;
91unsigned int block_size = 0;
92
93
94/** Network address family. **/
95#ifdef INET6
96int default_af_hint = 0; /* Any protocol */
97#else
98int default_af_hint = AF_INET; /* Must use IPv4 */
99#endif
100
101/** Do not go into the background when run as --daemon. Good
102 * for debugging and required for running as a service on W32,
103 * or under Unix process-monitors. **/
104int no_detach = 0;
105
106int write_batch = 0;
107int read_batch = 0;
108int backup_dir_len = 0;
109int backup_suffix_len;
110
111char *backup_suffix = NULL;
112char *tmpdir = NULL;
113char *compare_dest = NULL;
114char *config_file = NULL;
115char *shell_cmd = NULL;
116char *log_format = NULL;
117char *password_file = NULL;
118char *rsync_path = RSYNC_PATH;
119char *backup_dir = NULL;
120int rsync_port = RSYNC_PORT;
121int link_dest = 0;
122
123int verbose = 0;
124int quiet = 0;
125int always_checksum = 0;
126int list_only = 0;
127
128#define MAX_BATCH_PREFIX_LEN 256 /* Must be less than MAXPATHLEN-13 */
129char *batch_prefix = NULL;
130
131static int modify_window_set;
132
133/** Local address to bind. As a character string because it's
134 * interpreted by the IPv6 layer: should be a numeric IP4 or ip6
135 * address, or a hostname. **/
136char *bind_address;
137
138
139static void print_rsync_version(enum logcode f)
140{
141 char const *got_socketpair = "no ";
142 char const *hardlinks = "no ";
143 char const *links = "no ";
144 char const *ipv6 = "no ";
145 STRUCT_STAT *dumstat;
146
147#ifdef HAVE_SOCKETPAIR
148 got_socketpair = "";
149#endif
150
151#if SUPPORT_HARD_LINKS
152 hardlinks = "";
153#endif
154
155#if SUPPORT_LINKS
156 links = "";
157#endif
158
159#if INET6
160 ipv6 = "";
161#endif
162
163 rprintf(f, "%s version %s protocol version %d\n",
164 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
165 rprintf(f,
166 "Copyright (C) 1996-2004 by Andrew Tridgell and others\n");
167 rprintf(f, "<http://rsync.samba.org/>\n");
168 rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
169 "%shard links, %ssymlinks, batchfiles, \n",
170 (int) (sizeof(OFF_T) * 8),
171 got_socketpair, hardlinks, links);
172
173 /* Note that this field may not have type ino_t. It depends
174 * on the complicated interaction between largefile feature
175 * macros. */
176 rprintf(f, " %sIPv6, %d-bit system inums, %d-bit internal inums\n",
177 ipv6,
178 (int) (sizeof(dumstat->st_ino) * 8),
179 (int) (sizeof(INO64_T) * 8));
180#ifdef MAINTAINER_MODE
181 rprintf(f, " panic action: \"%s\"\n",
182 get_panic_action());
183#endif
184
185#ifdef NO_INT64
186 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
187#endif
188
189 rprintf(f,
190"\n"
191"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
192"are welcome to redistribute it under certain conditions. See the GNU\n"
193"General Public Licence for details.\n"
194 );
195}
196
197
198void usage(enum logcode F)
199{
200 print_rsync_version(F);
201
202 rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
203
204 rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
205 rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
206 rprintf(F," or rsync [OPTION]... SRC [SRC]... DEST\n");
207 rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
208 rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
209 rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
210 rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
211 rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
212 rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
213 rprintf(F," sources separated by space as long as they have same top-level\n");
214 rprintf(F,"\nOptions\n");
215 rprintf(F," -v, --verbose increase verbosity\n");
216 rprintf(F," -q, --quiet decrease verbosity\n");
217 rprintf(F," -c, --checksum always checksum\n");
218 rprintf(F," -a, --archive archive mode, equivalent to -rlptgoD\n");
219 rprintf(F," -r, --recursive recurse into directories\n");
220 rprintf(F," -R, --relative use relative path names\n");
221 rprintf(F," --no-relative turn off --relative\n");
222 rprintf(F," --no-implied-dirs don't send implied dirs with -R\n");
223 rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
224 rprintf(F," --backup-dir make backups into this directory\n");
225 rprintf(F," --suffix=SUFFIX backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
226 rprintf(F," -u, --update update only (don't overwrite newer files)\n");
227 rprintf(F," -l, --links copy symlinks as symlinks\n");
228 rprintf(F," -L, --copy-links copy the referent of symlinks\n");
229 rprintf(F," --copy-unsafe-links copy links outside the source tree\n");
230 rprintf(F," --safe-links ignore links outside the destination tree\n");
231 rprintf(F," -H, --hard-links preserve hard links\n");
232 rprintf(F," -p, --perms preserve permissions\n");
233 rprintf(F," -o, --owner preserve owner (root only)\n");
234 rprintf(F," -g, --group preserve group\n");
235 rprintf(F," -D, --devices preserve devices (root only)\n");
236 rprintf(F," -t, --times preserve times\n");
237 rprintf(F," -S, --sparse handle sparse files efficiently\n");
238 rprintf(F," -n, --dry-run show what would have been transferred\n");
239 rprintf(F," -W, --whole-file copy whole files, no incremental checks\n");
240 rprintf(F," --no-whole-file turn off --whole-file\n");
241 rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
242 rprintf(F," -B, --block-size=SIZE checksum blocking size (default %d)\n",BLOCK_SIZE);
243 rprintf(F," -e, --rsh=COMMAND specify the remote shell\n");
244 rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
245 rprintf(F," --existing only update files that already exist\n");
246 rprintf(F," --ignore-existing ignore files that already exist on receiving side\n");
247 rprintf(F," --delete delete files that don't exist on the sending side\n");
248 rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
249 rprintf(F," --delete-after receiver deletes after transferring, not before\n");
250 rprintf(F," --ignore-errors delete even if there are I/O errors\n");
251 rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
252 rprintf(F," --partial keep partially transferred files\n");
253 rprintf(F," --force force deletion of directories even if not empty\n");
254 rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
255 rprintf(F," --timeout=TIME set I/O timeout in seconds\n");
256 rprintf(F," -I, --ignore-times turn off mod time & file size quick check\n");
257 rprintf(F," --size-only ignore mod time for quick check (use size)\n");
258 rprintf(F," --modify-window=NUM compare mod times with reduced accuracy\n");
259 rprintf(F," -T --temp-dir=DIR create temporary files in directory DIR\n");
260 rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
261 rprintf(F," --link-dest=DIR create hardlinks to DIR for unchanged files\n");
262 rprintf(F," -P equivalent to --partial --progress\n");
263 rprintf(F," -z, --compress compress file data\n");
264 rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
265 rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
266 rprintf(F," --exclude-from=FILE exclude patterns listed in FILE\n");
267 rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
268 rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n");
269 rprintf(F," --files-from=FILE read FILE for list of source-file names\n");
270 rprintf(F," -0 --from0 all *-from file lists are delimited by nulls\n");
271 rprintf(F," --version print version number\n");
272 rprintf(F," --daemon run as an rsync daemon\n");
273 rprintf(F," --no-detach do not detach from the parent\n");
274 rprintf(F," --address=ADDRESS bind to the specified address\n");
275 rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
276 rprintf(F," --port=PORT specify alternate rsyncd port number\n");
277 rprintf(F," --blocking-io use blocking I/O for the remote shell\n");
278 rprintf(F," --no-blocking-io turn off --blocking-io\n");
279 rprintf(F," --stats give some file transfer stats\n");
280 rprintf(F," --progress show progress during transfer\n");
281 rprintf(F," --log-format=FORMAT log file transfers using specified format\n");
282 rprintf(F," --password-file=FILE get password from FILE\n");
283 rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
284 rprintf(F," --write-batch=PREFIX write batch fileset starting with PREFIX\n");
285 rprintf(F," --read-batch=PREFIX read batch fileset starting with PREFIX\n");
286 rprintf(F," -h, --help show this help screen\n");
287#ifdef INET6
288 rprintf(F," -4 prefer IPv4\n");
289 rprintf(F," -6 prefer IPv6\n");
290#endif
291
292 rprintf(F,"\n");
293
294 rprintf(F,"\nPlease see the rsync(1) and rsyncd.conf(5) man pages for full documentation\n");
295 rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
296}
297
298enum {OPT_VERSION = 1000, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
299 OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
300 OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
301 OPT_READ_BATCH, OPT_WRITE_BATCH};
302
303static struct poptOption long_options[] = {
304 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
305 {"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
306 {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
307 {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
308 {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
309 {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
310 {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
311 {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
312 {"one-file-system", 'x', POPT_ARG_NONE, &one_file_system, 0, 0, 0 },
313 {"delete", 0, POPT_ARG_NONE, &delete_mode, 0, 0, 0 },
314 {"existing", 0, POPT_ARG_NONE, &only_existing, 0, 0, 0 },
315 {"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing, 0, 0, 0 },
316 {"delete-after", 0, POPT_ARG_NONE, 0, OPT_DELETE_AFTER, 0, 0 },
317 {"delete-excluded", 0, POPT_ARG_NONE, 0, OPT_DELETE_EXCLUDED, 0, 0 },
318 {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 },
319 {"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids, 0, 0, 0 },
320 {"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
321 {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
322 {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
323 {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
324 {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks, 0, 0, 0 },
325 {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
326 {"backup", 'b', POPT_ARG_NONE, &make_backups, 0, 0, 0 },
327 {"dry-run", 'n', POPT_ARG_NONE, &dry_run, 0, 0, 0 },
328 {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
329 {"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude, 0, 0, 0 },
330 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
331 {"links", 'l', POPT_ARG_NONE, &preserve_links, 0, 0, 0 },
332 {"copy-links", 'L', POPT_ARG_NONE, &copy_links, 0, 0, 0 },
333 {"whole-file", 'W', POPT_ARG_VAL, &whole_file, 1, 0, 0 },
334 {"no-whole-file", 0, POPT_ARG_VAL, &whole_file, 0, 0, 0 },
335 {"copy-unsafe-links", 0, POPT_ARG_NONE, &copy_unsafe_links, 0, 0, 0 },
336 {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 },
337 {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 },
338 {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 },
339 {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 },
340 {"times", 't', POPT_ARG_NONE, &preserve_times, 0, 0, 0 },
341 {"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
342 {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
343 {"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
344 {"archive", 'a', POPT_ARG_NONE, &archive_mode, 0, 0, 0 },
345 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
346 {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
347 {"recursive", 'r', POPT_ARG_NONE, &recurse, 0, 0, 0 },
348 {"relative", 'R', POPT_ARG_VAL, &relative_paths, 1, 0, 0 },
349 {"no-relative", 0, POPT_ARG_VAL, &relative_paths, 0, 0, 0 },
350 {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
351 {"block-size", 'B', POPT_ARG_INT, &block_size, 0, 0, 0 },
352 {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 },
353 {"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 },
354 {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
355 {"compare-dest", 0, POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
356 {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
357 /* TODO: Should this take an optional int giving the compression level? */
358 {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
359 {"daemon", 0, POPT_ARG_NONE, &am_daemon, 0, 0, 0 },
360 {"no-detach", 0, POPT_ARG_NONE, &no_detach, 0, 0, 0 },
361 {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
362 {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 },
363 {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 },
364 {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 },
365 {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
366 {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
367 {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
368 {"config", 0, POPT_ARG_STRING, &config_file, 0, 0, 0 },
369 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
370 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
371 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
372 {"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
373 {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
374 {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
375 {"read-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_READ_BATCH, 0, 0 },
376 {"write-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_WRITE_BATCH, 0, 0 },
377 {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
378 {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
379 {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
380 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
381#ifdef INET6
382 {0, '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
383 {0, '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
384#endif
385 {0,0,0,0, 0, 0, 0}
386};
387
388
389static char err_buf[100];
390
391
392/**
393 * Store the option error message, if any, so that we can log the
394 * connection attempt (which requires parsing the options), and then
395 * show the error later on.
396 **/
397void option_error(void)
398{
399 if (err_buf[0]) {
400 rprintf(FLOG, "%s", err_buf);
401 rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
402 } else {
403 rprintf (FERROR, "Error parsing options: "
404 "option may be supported on client but not on server?\n");
405 rprintf (FERROR, RSYNC_NAME ": Error parsing options: "
406 "option may be supported on client but not on server?\n");
407 }
408}
409
410
411/**
412 * Check to see if we should refuse this option
413 **/
414static int check_refuse_options(char *ref, int opt)
415{
416 int i, len;
417 char *p;
418 const char *name;
419
420 for (i=0; long_options[i].longName; i++) {
421 if (long_options[i].val == opt) break;
422 }
423
424 if (!long_options[i].longName) return 0;
425
426 name = long_options[i].longName;
427 len = strlen(name);
428
429 while ((p = strstr(ref,name))) {
430 if ((p==ref || p[-1]==' ') &&
431 (p[len] == ' ' || p[len] == 0)) {
432 snprintf(err_buf,sizeof(err_buf),
433 "The '%s' option is not supported by this server\n", name);
434 return 1;
435 }
436 ref += len;
437 }
438 return 0;
439}
440
441
442static int count_args(char const **argv)
443{
444 int i = 0;
445
446 while (argv[i] != NULL)
447 i++;
448
449 return i;
450}
451
452
453/**
454 * Process command line arguments. Called on both local and remote.
455 *
456 * @retval 1 if all options are OK; with globals set to appropriate
457 * values
458 *
459 * @retval 0 on error, with err_buf containing an explanation
460 **/
461int parse_arguments(int *argc, const char ***argv, int frommain)
462{
463 int opt;
464 char *ref = lp_refuse_options(module_id);
465 poptContext pc;
466
467 /* TODO: Call poptReadDefaultConfig; handle errors. */
468
469 /* The context leaks in case of an error, but if there's a
470 * problem we always exit anyhow. */
471 pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
472
473 while ((opt = poptGetNextOpt(pc)) != -1) {
474 if (ref) {
475 if (check_refuse_options(ref, opt)) return 0;
476 }
477
478 /* most options are handled automatically by popt;
479 * only special cases are returned and listed here. */
480
481 switch (opt) {
482 case OPT_VERSION:
483 print_rsync_version(FINFO);
484 exit_cleanup(0);
485
486 case OPT_MODIFY_WINDOW:
487 /* The value has already been set by popt, but
488 * we need to remember that we're using a
489 * non-default setting. */
490 modify_window_set = 1;
491 break;
492
493 case OPT_DELETE_AFTER:
494 delete_after = 1;
495 delete_mode = 1;
496 break;
497
498 case OPT_DELETE_EXCLUDED:
499 delete_excluded = 1;
500 delete_mode = 1;
501 break;
502
503 case OPT_EXCLUDE:
504 add_exclude(&exclude_list, poptGetOptArg(pc),
505 ADD_EXCLUDE);
506 break;
507
508 case OPT_INCLUDE:
509 add_exclude(&exclude_list, poptGetOptArg(pc),
510 ADD_INCLUDE);
511 break;
512
513 case OPT_EXCLUDE_FROM:
514 add_exclude_file(&exclude_list, poptGetOptArg(pc),
515 MISSING_FATAL, ADD_EXCLUDE);
516 break;
517
518 case OPT_INCLUDE_FROM:
519 add_exclude_file(&exclude_list, poptGetOptArg(pc),
520 MISSING_FATAL, ADD_INCLUDE);
521 break;
522
523 case 'h':
524 usage(FINFO);
525 exit_cleanup(0);
526
527 case 'H':
528#if SUPPORT_HARD_LINKS
529 preserve_hard_links=1;
530#else
531 /* FIXME: Don't say "server" if this is
532 * happening on the client. */
533 /* FIXME: Why do we have the duplicated
534 * rprintf? Everybody who gets this message
535 * ought to send it to the client and also to
536 * the logs. */
537 snprintf(err_buf, sizeof err_buf,
538 "hard links are not supported on this %s\n",
539 am_server ? "server" : "client");
540 rprintf(FERROR, "ERROR: %s", err_buf);
541 return 0;
542#endif /* SUPPORT_HARD_LINKS */
543 break;
544
545 case 'v':
546 verbose++;
547 break;
548
549 case 'q':
550 if (frommain) quiet++;
551 break;
552
553 case OPT_SENDER:
554 if (!am_server) {
555 usage(FERROR);
556 exit_cleanup(RERR_SYNTAX);
557 }
558 am_sender = 1;
559 break;
560
561 case 'P':
562 do_progress = 1;
563 keep_partial = 1;
564 break;
565
566 case OPT_WRITE_BATCH:
567 /* popt stores the filename in batch_prefix for us */
568 write_batch = 1;
569 break;
570
571 case OPT_READ_BATCH:
572 /* popt stores the filename in batch_prefix for us */
573 read_batch = 1;
574 break;
575
576 case OPT_LINK_DEST:
577#if HAVE_LINK
578 compare_dest = (char *)poptGetOptArg(pc);
579 link_dest = 1;
580 break;
581#else
582 snprintf(err_buf, sizeof err_buf,
583 "hard links are not supported on this %s\n",
584 am_server ? "server" : "client");
585 rprintf(FERROR, "ERROR: %s", err_buf);
586 return 0;
587#endif
588
589
590 default:
591 /* FIXME: If --daemon is specified, then errors for later
592 * parameters seem to disappear. */
593 snprintf(err_buf, sizeof(err_buf),
594 "%s%s: %s\n",
595 am_server ? "on remote machine: " : "",
596 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
597 poptStrerror(opt));
598 return 0;
599 }
600 }
601
602 if (write_batch && read_batch) {
603 rprintf(FERROR,
604 "write-batch and read-batch can not be used together\n");
605 exit_cleanup(RERR_SYNTAX);
606 }
607 if (batch_prefix && strlen(batch_prefix) > MAX_BATCH_PREFIX_LEN) {
608 rprintf(FERROR,
609 "the batch-file prefix must be %d characters or less.\n",
610 MAX_BATCH_PREFIX_LEN);
611 exit_cleanup(RERR_SYNTAX);
612 }
613
614 if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
615 rprintf(FERROR, "the --temp-dir path is WAY too long.\n");
616 exit_cleanup(RERR_SYNTAX);
617 }
618
619 if (do_compression && (write_batch || read_batch)) {
620 rprintf(FERROR,
621 "compress can not be used with write-batch or read-batch\n");
622 exit_cleanup(RERR_SYNTAX);
623 }
624
625 if (archive_mode) {
626 if (!files_from)
627 recurse = 1;
628#if SUPPORT_LINKS
629 preserve_links = 1;
630#endif
631 preserve_perms = 1;
632 preserve_times = 1;
633 preserve_gid = 1;
634 preserve_uid = 1;
635 preserve_devices = 1;
636 }
637
638 if (relative_paths < 0)
639 relative_paths = files_from? 1 : 0;
640
641 if (!backup_suffix)
642 backup_suffix = backup_dir? "" : BACKUP_SUFFIX;
643 backup_suffix_len = strlen(backup_suffix);
644 if (strchr(backup_suffix, '/') != NULL) {
645 rprintf(FERROR, "--suffix cannot contain slashes: %s\n",
646 backup_suffix);
647 exit_cleanup(RERR_SYNTAX);
648 }
649 if (backup_dir)
650 backup_dir_len = strlen(backup_dir);
651 else if (!backup_suffix_len) {
652 rprintf(FERROR,
653 "--suffix cannot be a null string without --backup-dir\n");
654 exit_cleanup(RERR_SYNTAX);
655 }
656
657 if (do_progress && !verbose)
658 verbose = 1;
659
660 *argv = poptGetArgs(pc);
661 if (*argv)
662 *argc = count_args(*argv);
663 else
664 *argc = 0;
665
666 if (files_from) {
667 char *colon;
668 if (*argc != 2) {
669 usage(FERROR);
670 exit_cleanup(RERR_SYNTAX);
671 }
672 if (strcmp(files_from, "-") == 0) {
673 filesfrom_fd = 0;
674 if (am_server)
675 remote_filesfrom_file = "-";
676 }
677 else if ((colon = find_colon(files_from)) != 0) {
678 if (am_server) {
679 usage(FERROR);
680 exit_cleanup(RERR_SYNTAX);
681 }
682 remote_filesfrom_file = colon+1 + (colon[1] == ':');
683 if (strcmp(remote_filesfrom_file, "-") == 0) {
684 rprintf(FERROR, "Invalid --files-from remote filename\n");
685 exit_cleanup(RERR_SYNTAX);
686 }
687 } else {
688 extern int sanitize_paths;
689 if (sanitize_paths) {
690 files_from = strdup(files_from);
691 sanitize_path(files_from, NULL);
692 }
693 filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
694 if (filesfrom_fd < 0) {
695 rsyserr(FERROR, errno,
696 "failed to open files-from file %s",
697 files_from);
698 exit_cleanup(RERR_FILEIO);
699 }
700 }
701 }
702
703 return 1;
704}
705
706
707/**
708 * Construct a filtered list of options to pass through from the
709 * client to the server.
710 *
711 * This involves setting options that will tell the server how to
712 * behave, and also filtering out options that are processed only
713 * locally.
714 **/
715void server_options(char **args,int *argc)
716{
717 int ac = *argc;
718 static char argstr[50];
719 static char bsize[30];
720 static char iotime[30];
721 static char mdelete[30];
722 static char mwindow[30];
723 static char bw[50];
724 /* Leave room for ``--(write|read)-batch='' */
725 static char fext[MAX_BATCH_PREFIX_LEN + 15];
726
727 int i, x;
728
729 if (blocking_io == -1)
730 blocking_io = 0;
731
732 args[ac++] = "--server";
733
734 if (daemon_over_rsh) {
735 args[ac++] = "--daemon";
736 *argc = ac;
737 /* if we're passing --daemon, we're done */
738 return;
739 }
740
741 if (!am_sender)
742 args[ac++] = "--sender";
743
744 x = 1;
745 argstr[0] = '-';
746 for (i=0;i<verbose;i++)
747 argstr[x++] = 'v';
748
749 /* the -q option is intentionally left out */
750 if (make_backups)
751 argstr[x++] = 'b';
752 if (update_only)
753 argstr[x++] = 'u';
754 if (dry_run)
755 argstr[x++] = 'n';
756 if (preserve_links)
757 argstr[x++] = 'l';
758 if (copy_links)
759 argstr[x++] = 'L';
760
761 if (whole_file > 0)
762 argstr[x++] = 'W';
763 /* We don't need to send --no-whole-file, because it's the
764 * default for remote transfers, and in any case old versions
765 * of rsync will not understand it. */
766
767 if (preserve_hard_links)
768 argstr[x++] = 'H';
769 if (preserve_uid)
770 argstr[x++] = 'o';
771 if (preserve_gid)
772 argstr[x++] = 'g';
773 if (preserve_devices)
774 argstr[x++] = 'D';
775 if (preserve_times)
776 argstr[x++] = 't';
777 if (preserve_perms)
778 argstr[x++] = 'p';
779 if (recurse)
780 argstr[x++] = 'r';
781 if (always_checksum)
782 argstr[x++] = 'c';
783 if (cvs_exclude)
784 argstr[x++] = 'C';
785 if (ignore_times)
786 argstr[x++] = 'I';
787 if (relative_paths)
788 argstr[x++] = 'R';
789 if (one_file_system)
790 argstr[x++] = 'x';
791 if (sparse_files)
792 argstr[x++] = 'S';
793 if (do_compression)
794 argstr[x++] = 'z';
795
796 /* this is a complete hack - blame Rusty
797
798 this is a hack to make the list_only (remote file list)
799 more useful */
800 if (list_only && !recurse)
801 argstr[x++] = 'r';
802
803 argstr[x] = 0;
804
805 if (x != 1) args[ac++] = argstr;
806
807 if (block_size) {
808 snprintf(bsize, sizeof bsize, "-B%u", block_size);
809 args[ac++] = bsize;
810 }
811
812 if (max_delete && am_sender) {
813 snprintf(mdelete,sizeof(mdelete),"--max-delete=%d",max_delete);
814 args[ac++] = mdelete;
815 }
816
817 if (batch_prefix != NULL) {
818 char *fmt = "";
819 if (write_batch)
820 fmt = "--write-batch=%s";
821 else
822 if (read_batch)
823 fmt = "--read-batch=%s";
824 snprintf(fext,sizeof(fext),fmt,batch_prefix);
825 args[ac++] = fext;
826 }
827
828 if (io_timeout) {
829 snprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
830 args[ac++] = iotime;
831 }
832
833 if (bwlimit) {
834 snprintf(bw,sizeof(bw),"--bwlimit=%d",bwlimit);
835 args[ac++] = bw;
836 }
837
838 if (backup_dir) {
839 args[ac++] = "--backup-dir";
840 args[ac++] = backup_dir;
841 }
842
843 /* Only send --suffix if it specifies a non-default value. */
844 if (strcmp(backup_suffix, backup_dir? "" : BACKUP_SUFFIX) != 0) {
845 char *s = new_array(char, 9+backup_suffix_len+1);
846 if (!s)
847 out_of_memory("server_options");
848 /* We use the following syntax to avoid weirdness with '~'. */
849 sprintf(s, "--suffix=%s", backup_suffix);
850 args[ac++] = s;
851 }
852
853 if (delete_mode && !delete_excluded)
854 args[ac++] = "--delete";
855
856 if (delete_excluded)
857 args[ac++] = "--delete-excluded";
858
859 if (size_only)
860 args[ac++] = "--size-only";
861
862 if (modify_window_set) {
863 snprintf(mwindow,sizeof(mwindow),"--modify-window=%d",
864 modify_window);
865 args[ac++] = mwindow;
866 }
867
868 if (keep_partial)
869 args[ac++] = "--partial";
870
871 if (force_delete)
872 args[ac++] = "--force";
873
874 if (delete_after)
875 args[ac++] = "--delete-after";
876
877 if (ignore_errors)
878 args[ac++] = "--ignore-errors";
879
880 if (copy_unsafe_links)
881 args[ac++] = "--copy-unsafe-links";
882
883 if (safe_symlinks)
884 args[ac++] = "--safe-links";
885
886 if (numeric_ids)
887 args[ac++] = "--numeric-ids";
888
889 if (only_existing && am_sender)
890 args[ac++] = "--existing";
891
892 if (opt_ignore_existing && am_sender)
893 args[ac++] = "--ignore-existing";
894
895 if (tmpdir) {
896 args[ac++] = "--temp-dir";
897 args[ac++] = tmpdir;
898 }
899
900 if (compare_dest && am_sender) {
901 /* the server only needs this option if it is not the sender,
902 * and it may be an older version that doesn't know this
903 * option, so don't send it if client is the sender.
904 */
905 args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
906 args[ac++] = compare_dest;
907 }
908
909 if (files_from && (!am_sender || remote_filesfrom_file)) {
910 if (remote_filesfrom_file) {
911 args[ac++] = "--files-from";
912 args[ac++] = remote_filesfrom_file;
913 if (eol_nulls)
914 args[ac++] = "--from0";
915 } else {
916 args[ac++] = "--files-from=-";
917 args[ac++] = "--from0";
918 }
919 }
920
921 *argc = ac;
922}
923
924/**
925 * Return the position of a ':' IF it is not part of a filename (i.e. as
926 * long as it doesn't occur after a slash.
927 */
928char *find_colon(char *s)
929{
930 char *p, *p2;
931
932 p = strchr(s,':');
933 if (!p) return NULL;
934
935 /* now check to see if there is a / in the string before the : - if there is then
936 discard the colon on the assumption that the : is part of a filename */
937 p2 = strchr(s,'/');
938 if (p2 && p2 < p) return NULL;
939
940 return p;
941}