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