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