Don't generate code for zlib and popt.
[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,"\nrsync 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_WHOLE_FILE, 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, 0, OPT_WHOLE_FILE, 0, 0 },
323 {"no-whole-file", 0, POPT_ARG_NONE, 0, OPT_NO_WHOLE_FILE, 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_WHOLE_FILE:
488 whole_file = 1;
489 no_whole_file = 0;
490 break;
491
492 case OPT_NO_WHOLE_FILE:
493 no_whole_file = 1;
494 whole_file = 0;
495 break;
496
497 case OPT_NO_BLOCKING_IO:
498 blocking_io = 0;
499 break;
500
501 case 'h':
502 usage(FINFO);
503 exit_cleanup(0);
504
505 case 'H':
506#if SUPPORT_HARD_LINKS
507 preserve_hard_links=1;
508#else
509 /* FIXME: Don't say "server" if this is
510 * happening on the client. */
511 /* FIXME: Why do we have the duplicated
512 * rprintf? Everybody who gets this message
513 * ought to send it to the client and also to
514 * the logs. */
515 snprintf(err_buf,sizeof(err_buf),
516 "hard links are not supported on this %s\n",
517 am_server ? "server" : "client");
518 rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
519 return 0;
520#endif /* SUPPORT_HARD_LINKS */
521 break;
522
523 case 'v':
524 verbose++;
525 break;
526
527 case 'q':
528 if (frommain) quiet++;
529 break;
530
531 case 'a':
532 recurse=1;
533#if SUPPORT_LINKS
534 preserve_links=1;
535#endif
536 preserve_perms=1;
537 preserve_times=1;
538 preserve_gid=1;
539 preserve_uid=1;
540 preserve_devices=1;
541 break;
542
543 case OPT_SENDER:
544 if (!am_server) {
545 usage(FERROR);
546 exit_cleanup(RERR_SYNTAX);
547 }
548 am_sender = 1;
549 break;
550
551 case 'P':
552 do_progress = 1;
553 keep_partial = 1;
554 break;
555
556 case OPT_WRITE_BATCH:
557 /* popt stores the filename in batch_prefix for us */
558 write_batch = 1;
559 break;
560
561 case OPT_READ_BATCH:
562 /* popt stores the filename in batch_prefix for us */
563 read_batch = 1;
564 break;
565
566 default:
567 /* FIXME: If --daemon is specified, then errors for later
568 * parameters seem to disappear. */
569 snprintf(err_buf, sizeof(err_buf),
570 "%s%s: %s\n",
571 am_server ? "on remote machine: " : "",
572 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
573 poptStrerror(opt));
574 return 0;
575 }
576 }
577
578 if (write_batch && read_batch) {
579 snprintf(err_buf,sizeof(err_buf),
580 "write-batch and read-batch can not be used together\n");
581 rprintf(FERROR,"ERROR: write-batch and read-batch"
582 " can not be used together\n");
583 return 0;
584 }
585
586 if (do_compression && (write_batch || read_batch)) {
587 snprintf(err_buf,sizeof(err_buf),
588 "compress can not be used with write-batch or read-batch\n");
589 rprintf(FERROR,"ERROR: compress can not be used with"
590 " write-batch or read-batch\n");
591 return 0;
592 }
593
594 *argv = poptGetArgs(pc);
595 if (*argv)
596 *argc = count_args(*argv);
597 else
598 *argc = 0;
599
600 return 1;
601}
602
603
604/* Construct a filtered list of options to pass through from the
605 * client to the server */
606void server_options(char **args,int *argc)
607{
608 int ac = *argc;
609 static char argstr[50];
610 static char bsize[30];
611 static char iotime[30];
612 static char mdelete[30];
613 static char mwindow[30];
614 static char bw[50];
615 /* Leave room for ``--(write|read)-batch='' */
616 static char fext[MAXPATHLEN + 15];
617
618 int i, x;
619
620 if (blocking_io == -1)
621 blocking_io = 0;
622
623 args[ac++] = "--server";
624
625 if (!am_sender)
626 args[ac++] = "--sender";
627
628 x = 1;
629 argstr[0] = '-';
630 for (i=0;i<verbose;i++)
631 argstr[x++] = 'v';
632
633 /* the -q option is intentionally left out */
634 if (make_backups)
635 argstr[x++] = 'b';
636 if (update_only)
637 argstr[x++] = 'u';
638 if (dry_run)
639 argstr[x++] = 'n';
640 if (preserve_links)
641 argstr[x++] = 'l';
642 if (copy_links)
643 argstr[x++] = 'L';
644
645 assert(whole_file == 0 || whole_file == 1);
646 if (whole_file)
647 argstr[x++] = 'W';
648 /* We don't need to send --no-whole-file, because it's the
649 * default for remote transfers, and in any case old versions
650 * of rsync will not understand it. */
651
652 if (preserve_hard_links)
653 argstr[x++] = 'H';
654 if (preserve_uid)
655 argstr[x++] = 'o';
656 if (preserve_gid)
657 argstr[x++] = 'g';
658 if (preserve_devices)
659 argstr[x++] = 'D';
660 if (preserve_times)
661 argstr[x++] = 't';
662 if (preserve_perms)
663 argstr[x++] = 'p';
664 if (recurse)
665 argstr[x++] = 'r';
666 if (always_checksum)
667 argstr[x++] = 'c';
668 if (cvs_exclude)
669 argstr[x++] = 'C';
670 if (ignore_times)
671 argstr[x++] = 'I';
672 if (relative_paths)
673 argstr[x++] = 'R';
674 if (one_file_system)
675 argstr[x++] = 'x';
676 if (sparse_files)
677 argstr[x++] = 'S';
678 if (do_compression)
679 argstr[x++] = 'z';
680
681 /* this is a complete hack - blame Rusty
682
683 this is a hack to make the list_only (remote file list)
684 more useful */
685 if (list_only && !recurse)
686 argstr[x++] = 'r';
687
688 argstr[x] = 0;
689
690 if (x != 1) args[ac++] = argstr;
691
692 if (block_size != BLOCK_SIZE) {
693 snprintf(bsize,sizeof(bsize),"-B%d",block_size);
694 args[ac++] = bsize;
695 }
696
697 if (max_delete && am_sender) {
698 snprintf(mdelete,sizeof(mdelete),"--max-delete=%d",max_delete);
699 args[ac++] = mdelete;
700 }
701
702 if (batch_prefix != NULL) {
703 char *fmt = "";
704 if (write_batch)
705 fmt = "--write-batch=%s";
706 else
707 if (read_batch)
708 fmt = "--read-batch=%s";
709 snprintf(fext,sizeof(fext),fmt,batch_prefix);
710 args[ac++] = fext;
711 }
712
713 if (io_timeout) {
714 snprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
715 args[ac++] = iotime;
716 }
717
718 if (bwlimit) {
719 snprintf(bw,sizeof(bw),"--bwlimit=%d",bwlimit);
720 args[ac++] = bw;
721 }
722
723 if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
724 args[ac++] = "--suffix";
725 args[ac++] = backup_suffix;
726 }
727
728 if (delete_mode && !delete_excluded)
729 args[ac++] = "--delete";
730
731 if (delete_excluded)
732 args[ac++] = "--delete-excluded";
733
734 if (size_only)
735 args[ac++] = "--size-only";
736
737 if (modify_window_set) {
738 snprintf(mwindow,sizeof(mwindow),"--modify-window=%d",
739 modify_window);
740 args[ac++] = mwindow;
741 }
742
743 if (keep_partial)
744 args[ac++] = "--partial";
745
746 if (force_delete)
747 args[ac++] = "--force";
748
749 if (delete_after)
750 args[ac++] = "--delete-after";
751
752 if (ignore_errors)
753 args[ac++] = "--ignore-errors";
754
755 if (copy_unsafe_links)
756 args[ac++] = "--copy-unsafe-links";
757
758 if (safe_symlinks)
759 args[ac++] = "--safe-links";
760
761 if (numeric_ids)
762 args[ac++] = "--numeric-ids";
763
764 if (only_existing && am_sender)
765 args[ac++] = "--existing";
766
767 if (opt_ignore_existing && am_sender)
768 args[ac++] = "--ignore-existing";
769
770 if (tmpdir) {
771 args[ac++] = "--temp-dir";
772 args[ac++] = tmpdir;
773 }
774
775 if (backup_dir && am_sender) {
776 /* only the receiver needs this option, if we are the sender
777 * then we need to send it to the receiver.
778 */
779 args[ac++] = "--backup-dir";
780 args[ac++] = backup_dir;
781 }
782
783 if (compare_dest && am_sender) {
784 /* the server only needs this option if it is not the sender,
785 * and it may be an older version that doesn't know this
786 * option, so don't send it if client is the sender.
787 */
788 args[ac++] = "--compare-dest";
789 args[ac++] = compare_dest;
790 }
791
792 *argc = ac;
793}
794