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