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