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