Changed NO_INT64 to INT64_IS_OFF_T because off_t might actually be
[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 extern int sanitize_paths;
25 extern int select_timeout;
26 extern char curr_dir[MAXPATHLEN];
27 extern struct exclude_list_struct exclude_list;
28
29 int make_backups = 0;
30
31 /**
32  * If 1, send the whole file as literal data rather than trying to
33  * create an incremental diff.
34  *
35  * If -1, then look at whether we're local or remote and go by that.
36  *
37  * @sa disable_deltas_p()
38  **/
39 int whole_file = -1;
40
41 int archive_mode = 0;
42 int keep_dirlinks = 0;
43 int copy_links = 0;
44 int preserve_links = 0;
45 int preserve_hard_links = 0;
46 int preserve_perms = 0;
47 int preserve_devices = 0;
48 int preserve_uid = 0;
49 int preserve_gid = 0;
50 int preserve_times = 0;
51 int update_only = 0;
52 int cvs_exclude = 0;
53 int dry_run = 0;
54 int local_server = 0;
55 int ignore_times = 0;
56 int delete_mode = 0;
57 int delete_excluded = 0;
58 int one_file_system = 0;
59 int protocol_version = PROTOCOL_VERSION;
60 int sparse_files = 0;
61 int do_compression = 0;
62 int am_root = 0;
63 int orig_umask = 0;
64 int relative_paths = -1;
65 int implied_dirs = 1;
66 int numeric_ids = 0;
67 int force_delete = 0;
68 int io_timeout = 0;
69 int read_only = 0;
70 int module_id = -1;
71 int am_server = 0;
72 int am_sender = 0;
73 int am_generator = 0;
74 char *files_from = NULL;
75 int filesfrom_fd = -1;
76 char *remote_filesfrom_file = NULL;
77 int eol_nulls = 0;
78 int recurse = 0;
79 int am_daemon = 0;
80 int daemon_over_rsh = 0;
81 int do_stats = 0;
82 int do_progress = 0;
83 int keep_partial = 0;
84 int safe_symlinks = 0;
85 int copy_unsafe_links = 0;
86 int size_only = 0;
87 int bwlimit = 0;
88 size_t bwlimit_writemax = 0;
89 int delete_after = 0;
90 int only_existing = 0;
91 int opt_ignore_existing = 0;
92 int max_delete = 0;
93 int ignore_errors = 0;
94 int modify_window = 0;
95 int blocking_io = -1;
96 int checksum_seed = 0;
97 int inplace = 0;
98 unsigned int block_size = 0;
99
100
101 /** Network address family. **/
102 #ifdef INET6
103 int default_af_hint = 0;        /* Any protocol */
104 #else
105 int default_af_hint = AF_INET;  /* Must use IPv4 */
106 #endif
107
108 /** Do not go into the background when run as --daemon.  Good
109  * for debugging and required for running as a service on W32,
110  * or under Unix process-monitors. **/
111 int no_detach = 0;
112
113 int write_batch = 0;
114 int read_batch = 0;
115 int backup_dir_len = 0;
116 int backup_suffix_len;
117 unsigned int backup_dir_remainder;
118
119 char *backup_suffix = NULL;
120 char *tmpdir = NULL;
121 char *compare_dest = NULL;
122 char *config_file = NULL;
123 char *shell_cmd = NULL;
124 char *log_format = NULL;
125 char *password_file = NULL;
126 char *rsync_path = RSYNC_PATH;
127 char *backup_dir = NULL;
128 char backup_dir_buf[MAXPATHLEN];
129 int rsync_port = RSYNC_PORT;
130 int link_dest = 0;
131
132 int verbose = 0;
133 int quiet = 0;
134 int always_checksum = 0;
135 int list_only = 0;
136
137 #define MAX_BATCH_NAME_LEN 256  /* Must be less than MAXPATHLEN-13 */
138 char *batch_name = NULL;
139
140 static int daemon_opt;   /* sets am_daemon after option error-reporting */
141 static int modify_window_set;
142
143 /** Local address to bind.  As a character string because it's
144  * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
145  * address, or a hostname. **/
146 char *bind_address;
147
148
149 static void print_rsync_version(enum logcode f)
150 {
151         char const *got_socketpair = "no ";
152         char const *have_inplace = "no ";
153         char const *hardlinks = "no ";
154         char const *links = "no ";
155         char const *ipv6 = "no ";
156         STRUCT_STAT *dumstat;
157
158 #ifdef HAVE_SOCKETPAIR
159         got_socketpair = "";
160 #endif
161
162 #if HAVE_FTRUNCATE
163         have_inplace = "";
164 #endif
165
166 #if SUPPORT_HARD_LINKS
167         hardlinks = "";
168 #endif
169
170 #if SUPPORT_LINKS
171         links = "";
172 #endif
173
174 #if INET6
175         ipv6 = "";
176 #endif
177
178         rprintf(f, "%s  version %s  protocol version %d\n",
179                 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
180         rprintf(f,
181                 "Copyright (C) 1996-2004 by Andrew Tridgell and others\n");
182         rprintf(f, "<http://rsync.samba.org/>\n");
183         rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
184                 "%shard links, %ssymlinks, batchfiles, \n",
185                 (int) (sizeof (OFF_T) * 8),
186                 got_socketpair, hardlinks, links);
187
188         /* Note that this field may not have type ino_t.  It depends
189          * on the complicated interaction between largefile feature
190          * macros. */
191         rprintf(f, "              %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
192                 have_inplace, ipv6,
193                 (int) (sizeof dumstat->st_ino * 8),
194                 (int) (sizeof (uint64) * 8));
195 #ifdef MAINTAINER_MODE
196         rprintf(f, "              panic action: \"%s\"\n",
197                 get_panic_action());
198 #endif
199
200 #ifdef INT64_IS_OFF_T
201         if (sizeof (int64) < 8)
202                 rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
203 #endif
204
205         rprintf(f,
206 "\n"
207 "rsync comes with ABSOLUTELY NO WARRANTY.  This is free software, and you\n"
208 "are welcome to redistribute it under certain conditions.  See the GNU\n"
209 "General Public Licence for details.\n"
210                 );
211 }
212
213
214 void usage(enum logcode F)
215 {
216   print_rsync_version(F);
217
218   rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
219
220   rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
221   rprintf(F,"  or   rsync [OPTION]... [USER@]HOST:SRC DEST\n");
222   rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... DEST\n");
223   rprintf(F,"  or   rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
224   rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
225   rprintf(F,"  or   rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
226   rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
227   rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
228   rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
229   rprintf(F,"  sources separated by space as long as they have same top-level\n");
230   rprintf(F,"\nOptions\n");
231   rprintf(F," -v, --verbose               increase verbosity\n");
232   rprintf(F," -q, --quiet                 decrease verbosity\n");
233   rprintf(F," -c, --checksum              always checksum\n");
234   rprintf(F," -a, --archive               archive mode, equivalent to -rlptgoD\n");
235   rprintf(F," -r, --recursive             recurse into directories\n");
236   rprintf(F," -R, --relative              use relative path names\n");
237   rprintf(F,"     --no-relative           turn off --relative\n");
238   rprintf(F,"     --no-implied-dirs       don't send implied dirs with -R\n");
239   rprintf(F," -b, --backup                make backups (see --suffix & --backup-dir)\n");
240   rprintf(F,"     --backup-dir            make backups into this directory\n");
241   rprintf(F,"     --suffix=SUFFIX         backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
242   rprintf(F," -u, --update                update only (don't overwrite newer files)\n");
243   rprintf(F,"     --inplace               update destination files inplace (SEE MAN PAGE)\n");
244   rprintf(F," -K, --keep-dirlinks         treat symlinked dir on receiver as dir\n");
245   rprintf(F," -l, --links                 copy symlinks as symlinks\n");
246   rprintf(F," -L, --copy-links            copy the referent of all symlinks\n");
247   rprintf(F,"     --copy-unsafe-links     copy the referent of \"unsafe\" symlinks\n");
248   rprintf(F,"     --safe-links            ignore \"unsafe\" symlinks\n");
249   rprintf(F," -H, --hard-links            preserve hard links\n");
250   rprintf(F," -p, --perms                 preserve permissions\n");
251   rprintf(F," -o, --owner                 preserve owner (root only)\n");
252   rprintf(F," -g, --group                 preserve group\n");
253   rprintf(F," -D, --devices               preserve devices (root only)\n");
254   rprintf(F," -t, --times                 preserve times\n");
255   rprintf(F," -S, --sparse                handle sparse files efficiently\n");
256   rprintf(F," -n, --dry-run               show what would have been transferred\n");
257   rprintf(F," -W, --whole-file            copy whole files, no incremental checks\n");
258   rprintf(F,"     --no-whole-file         turn off --whole-file\n");
259   rprintf(F," -x, --one-file-system       don't cross filesystem boundaries\n");
260   rprintf(F," -B, --block-size=SIZE       checksum blocking size (default %d)\n",BLOCK_SIZE);
261   rprintf(F," -e, --rsh=COMMAND           specify the remote shell\n");
262   rprintf(F,"     --rsync-path=PATH       specify path to rsync on the remote machine\n");
263   rprintf(F,"     --existing              only update files that already exist\n");
264   rprintf(F,"     --ignore-existing       ignore files that already exist on receiving side\n");
265   rprintf(F,"     --delete                delete files that don't exist on the sending side\n");
266   rprintf(F,"     --delete-excluded       also delete excluded files on the receiving side\n");
267   rprintf(F,"     --delete-after          receiver deletes after transferring, not before\n");
268   rprintf(F,"     --ignore-errors         delete even if there are I/O errors\n");
269   rprintf(F,"     --max-delete=NUM        don't delete more than NUM files\n");
270   rprintf(F,"     --partial               keep partially transferred files\n");
271   rprintf(F,"     --force                 force deletion of directories even if not empty\n");
272   rprintf(F,"     --numeric-ids           don't map uid/gid values by user/group name\n");
273   rprintf(F,"     --timeout=TIME          set I/O timeout in seconds\n");
274   rprintf(F," -I, --ignore-times          turn off mod time & file size quick check\n");
275   rprintf(F,"     --size-only             ignore mod time for quick check (use size)\n");
276   rprintf(F,"     --modify-window=NUM     compare mod times with reduced accuracy\n");
277   rprintf(F," -T, --temp-dir=DIR          create temporary files in directory DIR\n");
278   rprintf(F,"     --compare-dest=DIR      also compare destination files relative to DIR\n");
279   rprintf(F,"     --link-dest=DIR         create hardlinks to DIR for unchanged files\n");
280   rprintf(F," -P                          equivalent to --partial --progress\n");
281   rprintf(F," -z, --compress              compress file data\n");
282   rprintf(F," -C, --cvs-exclude           auto ignore files in the same way CVS does\n");
283   rprintf(F,"     --exclude=PATTERN       exclude files matching PATTERN\n");
284   rprintf(F,"     --exclude-from=FILE     exclude patterns listed in FILE\n");
285   rprintf(F,"     --include=PATTERN       don't exclude files matching PATTERN\n");
286   rprintf(F,"     --include-from=FILE     don't exclude patterns listed in FILE\n");
287   rprintf(F,"     --files-from=FILE       read FILE for list of source-file names\n");
288   rprintf(F," -0, --from0                 all *-from file lists are delimited by nulls\n");
289   rprintf(F,"     --version               print version number\n");
290   rprintf(F,"     --daemon                run as an rsync daemon\n");
291   rprintf(F,"     --no-detach             do not detach from the parent\n");
292   rprintf(F,"     --address=ADDRESS       bind to the specified address\n");
293   rprintf(F,"     --config=FILE           specify alternate rsyncd.conf file\n");
294   rprintf(F,"     --port=PORT             specify alternate rsyncd port number\n");
295   rprintf(F,"     --blocking-io           use blocking I/O for the remote shell\n");
296   rprintf(F,"     --no-blocking-io        turn off --blocking-io\n");
297   rprintf(F,"     --stats                 give some file transfer stats\n");
298   rprintf(F,"     --progress              show progress during transfer\n");
299   rprintf(F,"     --log-format=FORMAT     log file transfers using specified format\n");
300   rprintf(F,"     --password-file=FILE    get password from FILE\n");
301   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth, KBytes per second\n");
302   rprintf(F,"     --write-batch=FILE      write a batch to FILE\n");
303   rprintf(F,"     --read-batch=FILE       read a batch from FILE\n");
304   rprintf(F,"     --checksum-seed=NUM     set block/file checksum seed\n");
305 #ifdef INET6
306   rprintf(F," -4, --ipv4                  prefer IPv4\n");
307   rprintf(F," -6, --ipv6                  prefer IPv6\n");
308 #endif
309   rprintf(F," -h, --help                  show this help screen\n");
310
311   rprintf(F,"\n");
312
313   rprintf(F,"\nPlease see the rsync(1) and rsyncd.conf(5) man pages for full documentation\n");
314   rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
315 }
316
317 enum {OPT_VERSION = 1000, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
318       OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
319       OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
320       OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT,
321       OPT_REFUSED_BASE = 9000};
322
323 static struct poptOption long_options[] = {
324   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
325   {"version",          0,  POPT_ARG_NONE,   0,              OPT_VERSION, 0, 0},
326   {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
327   {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
328   {"password-file",    0,  POPT_ARG_STRING, &password_file, 0, 0, 0 },
329   {"ignore-times",    'I', POPT_ARG_NONE,   &ignore_times, 0, 0, 0 },
330   {"size-only",        0,  POPT_ARG_NONE,   &size_only, 0, 0, 0 },
331   {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
332   {"one-file-system", 'x', POPT_ARG_NONE,   &one_file_system, 0, 0, 0 },
333   {"delete",           0,  POPT_ARG_NONE,   &delete_mode, 0, 0, 0 },
334   {"existing",         0,  POPT_ARG_NONE,   &only_existing, 0, 0, 0 },
335   {"ignore-existing",  0,  POPT_ARG_NONE,   &opt_ignore_existing, 0, 0, 0 },
336   {"delete-after",     0,  POPT_ARG_NONE,   0,              OPT_DELETE_AFTER, 0, 0 },
337   {"delete-excluded",  0,  POPT_ARG_NONE,   0,              OPT_DELETE_EXCLUDED, 0, 0 },
338   {"force",            0,  POPT_ARG_NONE,   &force_delete, 0, 0, 0 },
339   {"numeric-ids",      0,  POPT_ARG_NONE,   &numeric_ids, 0, 0, 0 },
340   {"exclude",          0,  POPT_ARG_STRING, 0,              OPT_EXCLUDE, 0, 0 },
341   {"include",          0,  POPT_ARG_STRING, 0,              OPT_INCLUDE, 0, 0 },
342   {"exclude-from",     0,  POPT_ARG_STRING, 0,              OPT_EXCLUDE_FROM, 0, 0 },
343   {"include-from",     0,  POPT_ARG_STRING, 0,              OPT_INCLUDE_FROM, 0, 0 },
344   {"safe-links",       0,  POPT_ARG_NONE,   &safe_symlinks, 0, 0, 0 },
345   {"help",            'h', POPT_ARG_NONE,   0,              'h', 0, 0 },
346   {"backup",          'b', POPT_ARG_NONE,   &make_backups, 0, 0, 0 },
347   {"dry-run",         'n', POPT_ARG_NONE,   &dry_run, 0, 0, 0 },
348   {"sparse",          'S', POPT_ARG_NONE,   &sparse_files, 0, 0, 0 },
349   {"cvs-exclude",     'C', POPT_ARG_NONE,   &cvs_exclude, 0, 0, 0 },
350   {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
351   {"inplace",          0,  POPT_ARG_NONE,   &inplace, 0, 0, 0 },
352   {"keep-dirlinks",   'K', POPT_ARG_NONE,   &keep_dirlinks, 0, 0, 0 },
353   {"links",           'l', POPT_ARG_NONE,   &preserve_links, 0, 0, 0 },
354   {"copy-links",      'L', POPT_ARG_NONE,   &copy_links, 0, 0, 0 },
355   {"whole-file",      'W', POPT_ARG_VAL,    &whole_file, 1, 0, 0 },
356   {"no-whole-file",    0,  POPT_ARG_VAL,    &whole_file, 0, 0, 0 },
357   {"copy-unsafe-links", 0, POPT_ARG_NONE,   &copy_unsafe_links, 0, 0, 0 },
358   {"perms",           'p', POPT_ARG_NONE,   &preserve_perms, 0, 0, 0 },
359   {"owner",           'o', POPT_ARG_NONE,   &preserve_uid, 0, 0, 0 },
360   {"group",           'g', POPT_ARG_NONE,   &preserve_gid, 0, 0, 0 },
361   {"devices",         'D', POPT_ARG_NONE,   &preserve_devices, 0, 0, 0 },
362   {"times",           't', POPT_ARG_NONE,   &preserve_times, 0, 0, 0 },
363   {"checksum",        'c', POPT_ARG_NONE,   &always_checksum, 0, 0, 0 },
364   {"verbose",         'v', POPT_ARG_NONE,   0,               'v', 0, 0 },
365   {"quiet",           'q', POPT_ARG_NONE,   0,               'q', 0, 0 },
366   {"archive",         'a', POPT_ARG_NONE,   &archive_mode, 0, 0, 0 },
367   {"server",           0,  POPT_ARG_NONE,   &am_server, 0, 0, 0 },
368   {"sender",           0,  POPT_ARG_NONE,   0,              OPT_SENDER, 0, 0 },
369   {"recursive",       'r', POPT_ARG_NONE,   &recurse, 0, 0, 0 },
370   {"relative",        'R', POPT_ARG_VAL,    &relative_paths, 1, 0, 0 },
371   {"no-relative",      0,  POPT_ARG_VAL,    &relative_paths, 0, 0, 0 },
372   {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
373   {"block-size",      'B', POPT_ARG_INT,    &block_size, 0, 0, 0 },
374   {"max-delete",       0,  POPT_ARG_INT,    &max_delete, 0, 0, 0 },
375   {"timeout",          0,  POPT_ARG_INT,    &io_timeout, OPT_TIMEOUT, 0, 0 },
376   {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
377   {"compare-dest",     0,  POPT_ARG_STRING, &compare_dest, 0, 0, 0 },
378   {"link-dest",        0,  POPT_ARG_STRING, &compare_dest,  OPT_LINK_DEST, 0, 0 },
379   /* TODO: Should this take an optional int giving the compression level? */
380   {"compress",        'z', POPT_ARG_NONE,   &do_compression, 0, 0, 0 },
381   {"daemon",           0,  POPT_ARG_NONE,   &daemon_opt, 0, 0, 0 },
382   {"no-detach",        0,  POPT_ARG_NONE,   &no_detach, 0, 0, 0 },
383   {"stats",            0,  POPT_ARG_NONE,   &do_stats, 0, 0, 0 },
384   {"progress",         0,  POPT_ARG_NONE,   &do_progress, 0, 0, 0 },
385   {"partial",          0,  POPT_ARG_NONE,   &keep_partial, 0, 0, 0 },
386   {"ignore-errors",    0,  POPT_ARG_NONE,   &ignore_errors, 0, 0, 0 },
387   {"blocking-io",      0,  POPT_ARG_VAL,    &blocking_io, 1, 0, 0 },
388   {"no-blocking-io",   0,  POPT_ARG_VAL,    &blocking_io, 0, 0, 0 },
389   {0,                 'P', POPT_ARG_NONE,   0,              'P', 0, 0 },
390   {"config",           0,  POPT_ARG_STRING, &config_file, 0, 0, 0 },
391   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
392   {"log-format",       0,  POPT_ARG_STRING, &log_format, 0, 0, 0 },
393   {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit, 0, 0, 0 },
394   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
395   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
396   {"hard-links",      'H', POPT_ARG_NONE,   &preserve_hard_links, 0, 0, 0 },
397   {"read-batch",       0,  POPT_ARG_STRING, &batch_name,  OPT_READ_BATCH, 0, 0 },
398   {"write-batch",      0,  POPT_ARG_STRING, &batch_name,  OPT_WRITE_BATCH, 0, 0 },
399   {"files-from",       0,  POPT_ARG_STRING, &files_from, 0, 0, 0 },
400   {"from0",           '0', POPT_ARG_NONE,   &eol_nulls, 0, 0, 0},
401   {"no-implied-dirs",  0,  POPT_ARG_VAL,    &implied_dirs, 0, 0, 0 },
402   {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
403   {"checksum-seed",    0,  POPT_ARG_INT,    &checksum_seed, 0, 0, 0 },
404 #ifdef INET6
405   {"ipv4",            '4', POPT_ARG_VAL,    &default_af_hint, AF_INET, 0, 0 },
406   {"ipv6",            '6', POPT_ARG_VAL,    &default_af_hint, AF_INET6, 0, 0 },
407 #endif
408   {0,0,0,0, 0, 0, 0}
409 };
410
411
412 static char err_buf[200];
413
414
415 /**
416  * Store the option error message, if any, so that we can log the
417  * connection attempt (which requires parsing the options), and then
418  * show the error later on.
419  **/
420 void option_error(void)
421 {
422         if (!err_buf[0]) {
423                 strcpy(err_buf, "Error parsing options: "
424                     "option may be supported on client but not on server?\n");
425         }
426
427         rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
428 }
429
430
431 /**
432  * Tweak the option table to disable all options that the rsyncd.conf
433  * file has told us to refuse.
434  **/
435 static void set_refuse_options(char *bp)
436 {
437         struct poptOption *op;
438         char *cp;
439
440         while (1) {
441                 if ((cp = strchr(bp, ' ')) != NULL)
442                         *cp= '\0';
443                 for (op = long_options; ; op++) {
444                         if (!op->longName) {
445                                 rprintf(FLOG,
446                                     "Unknown option %s in \"refuse options\" setting\n",
447                                     bp);
448                                 break;
449                         }
450                         if (strcmp(bp, op->longName) == 0) {
451                                 op->val = (op - long_options)+OPT_REFUSED_BASE;
452                                 break;
453                         }
454                 }
455                 if (!cp)
456                         break;
457                 *cp = ' ';
458                 bp = cp + 1;
459         }
460 }
461
462
463 static int count_args(char const **argv)
464 {
465         int i = 0;
466
467         while (argv[i] != NULL)
468                 i++;
469
470         return i;
471 }
472
473
474 /**
475  * Process command line arguments.  Called on both local and remote.
476  *
477  * @retval 1 if all options are OK; with globals set to appropriate
478  * values
479  *
480  * @retval 0 on error, with err_buf containing an explanation
481  **/
482 int parse_arguments(int *argc, const char ***argv, int frommain)
483 {
484         int opt;
485         char *ref = lp_refuse_options(module_id);
486         const char *arg;
487         poptContext pc;
488
489         if (ref && *ref)
490                 set_refuse_options(ref);
491
492         /* TODO: Call poptReadDefaultConfig; handle errors. */
493
494         /* The context leaks in case of an error, but if there's a
495          * problem we always exit anyhow. */
496         pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
497
498         while ((opt = poptGetNextOpt(pc)) != -1) {
499                 /* most options are handled automatically by popt;
500                  * only special cases are returned and listed here. */
501
502                 switch (opt) {
503                 case OPT_VERSION:
504                         print_rsync_version(FINFO);
505                         exit_cleanup(0);
506
507                 case OPT_MODIFY_WINDOW:
508                         /* The value has already been set by popt, but
509                          * we need to remember that we're using a
510                          * non-default setting. */
511                         modify_window_set = 1;
512                         break;
513
514                 case OPT_DELETE_AFTER:
515                         delete_after = 1;
516                         delete_mode = 1;
517                         break;
518
519                 case OPT_DELETE_EXCLUDED:
520                         delete_excluded = 1;
521                         delete_mode = 1;
522                         break;
523
524                 case OPT_EXCLUDE:
525                         if (am_server || sanitize_paths)
526                                 return 0; /* Impossible... */
527                         add_exclude(&exclude_list, poptGetOptArg(pc), 0);
528                         break;
529
530                 case OPT_INCLUDE:
531                         if (am_server || sanitize_paths)
532                                 return 0; /* Impossible... */
533                         add_exclude(&exclude_list, poptGetOptArg(pc),
534                                     XFLG_DEF_INCLUDE);
535                         break;
536
537                 case OPT_EXCLUDE_FROM:
538                         if (am_server || sanitize_paths)
539                                 return 0; /* Impossible... */
540                         arg = poptGetOptArg(pc);
541                         add_exclude_file(&exclude_list, arg,
542                                          XFLG_FATAL_ERRORS);
543                         break;
544
545                 case OPT_INCLUDE_FROM:
546                         if (am_server || sanitize_paths)
547                                 return 0; /* Impossible... */
548                         arg = poptGetOptArg(pc);
549                         add_exclude_file(&exclude_list, arg,
550                                          XFLG_FATAL_ERRORS | XFLG_DEF_INCLUDE);
551                         break;
552
553                 case 'h':
554                         usage(FINFO);
555                         exit_cleanup(0);
556
557                 case 'v':
558                         verbose++;
559                         break;
560
561                 case 'q':
562                         if (frommain)
563                                 quiet++;
564                         break;
565
566                 case OPT_SENDER:
567                         if (!am_server) {
568                                 usage(FERROR);
569                                 exit_cleanup(RERR_SYNTAX);
570                         }
571                         am_sender = 1;
572                         break;
573
574                 case 'P':
575                         do_progress = 1;
576                         keep_partial = 1;
577                         break;
578
579                 case OPT_WRITE_BATCH:
580                         /* batch_name is already set */
581                         write_batch = 1;
582                         break;
583
584                 case OPT_READ_BATCH:
585                         /* batch_name is already set */
586                         read_batch = 1;
587                         break;
588
589                 case OPT_TIMEOUT:
590                         if (io_timeout && io_timeout < select_timeout)
591                                 select_timeout = io_timeout;
592                         break;
593
594                 case OPT_LINK_DEST:
595 #if HAVE_LINK
596                         link_dest = 1;
597                         break;
598 #else
599                         snprintf(err_buf, sizeof err_buf,
600                                  "hard links are not supported on this %s\n",
601                                  am_server ? "server" : "client");
602                         return 0;
603 #endif
604
605                 default:
606                         /* A large opt value means that set_refuse_options()
607                          * turned this option off (opt-BASE is its index). */
608                         if (opt >= OPT_REFUSED_BASE) {
609                                 struct poptOption *op =
610                                     &long_options[opt-OPT_REFUSED_BASE];
611                                 int n = snprintf(err_buf, sizeof err_buf,
612                                     "This server does not support --%s\n",
613                                     op->longName) - 1;
614                                 if (op->shortName) {
615                                         snprintf(err_buf+n, sizeof err_buf-n,
616                                             " (-%c)\n", op->shortName);
617                                 }
618                         } else {
619                                 snprintf(err_buf, sizeof err_buf,
620                                     "%s%s: %s\n",
621                                     am_server ? "on remote machine: " : "",
622                                     poptBadOption(pc, POPT_BADOPTION_NOALIAS),
623                                     poptStrerror(opt));
624                         }
625                         return 0;
626                 }
627         }
628
629 #if !SUPPORT_LINKS
630         if (preserve_links && !am_sender) {
631                 snprintf(err_buf, sizeof err_buf,
632                          "symlinks are not supported on this %s\n",
633                          am_server ? "server" : "client");
634                 return 0;
635         }
636 #endif
637
638 #if !SUPPORT_HARD_LINKS
639         if (preserve_hard_links) {
640                 snprintf(err_buf, sizeof err_buf,
641                          "hard links are not supported on this %s\n",
642                          am_server ? "server" : "client");
643                 return 0;
644         }
645 #endif
646
647         if (block_size > MAX_MAP_SIZE) {
648                 rprintf(FINFO, "limiting block-size to %d bytes\n",
649                         MAX_MAP_SIZE);
650                 block_size = MAX_MAP_SIZE;
651         }
652
653         if (write_batch && read_batch) {
654                 rprintf(FERROR,
655                         "--write-batch and --read-batch can not be used together\n");
656                 exit_cleanup(RERR_SYNTAX);
657         }
658         if (write_batch || read_batch) {
659                 if (dry_run) {
660                         rprintf(FERROR,
661                                 "--%s-batch cannot be used with --dry_run (-n)\n",
662                                 write_batch ? "write" : "read");
663                         exit_cleanup(RERR_SYNTAX);
664                 }
665                 if (am_server) {
666                         rprintf(FINFO,
667                                 "ignoring --%s-batch option sent to server\n",
668                                 write_batch ? "write" : "read");
669                         /* We don't actually exit_cleanup(), so that we can
670                          * still service older version clients that still send
671                          * batch args to server. */
672                         read_batch = write_batch = 0;
673                         batch_name = NULL;
674                 }
675         }
676         if (read_batch && files_from) {
677                 rprintf(FERROR,
678                         "--read-batch cannot be used with --files-from\n");
679                 exit_cleanup(RERR_SYNTAX);
680         }
681         if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
682                 rprintf(FERROR,
683                         "the batch-file name must be %d characters or less.\n",
684                         MAX_BATCH_NAME_LEN);
685                 exit_cleanup(RERR_SYNTAX);
686         }
687
688         if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
689                 rprintf(FERROR, "the --temp-dir path is WAY too long.\n");
690                 exit_cleanup(RERR_SYNTAX);
691         }
692
693         if (archive_mode) {
694                 if (!files_from)
695                         recurse = 1;
696 #if SUPPORT_LINKS
697                 preserve_links = 1;
698 #endif
699                 preserve_perms = 1;
700                 preserve_times = 1;
701                 preserve_gid = 1;
702                 preserve_uid = 1;
703                 preserve_devices = 1;
704         }
705
706         if (relative_paths < 0)
707                 relative_paths = files_from? 1 : 0;
708
709         *argv = poptGetArgs(pc);
710         if (*argv)
711                 *argc = count_args(*argv);
712         else
713                 *argc = 0;
714
715         if (sanitize_paths) {
716                 int i;
717                 for (i = *argc; i-- > 0; )
718                         (*argv)[i] = alloc_sanitize_path((*argv)[i], NULL);
719                 if (tmpdir)
720                         tmpdir = alloc_sanitize_path(tmpdir, curr_dir);
721                 if (compare_dest)
722                         compare_dest = alloc_sanitize_path(compare_dest, curr_dir);
723                 if (backup_dir)
724                         backup_dir = alloc_sanitize_path(backup_dir, curr_dir);
725                 if (files_from)
726                         files_from = alloc_sanitize_path(files_from, curr_dir);
727         }
728
729         if (daemon_opt) {
730                 daemon_opt = 0;
731                 am_daemon = 1;
732                 return 1;
733         }
734
735         if (!backup_suffix)
736                 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
737         backup_suffix_len = strlen(backup_suffix);
738         if (strchr(backup_suffix, '/') != NULL) {
739                 rprintf(FERROR, "--suffix cannot contain slashes: %s\n",
740                         backup_suffix);
741                 exit_cleanup(RERR_SYNTAX);
742         }
743         if (backup_dir) {
744                 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
745                 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
746                 if (backup_dir_remainder < 32) {
747                         rprintf(FERROR, "the --backup-dir path is WAY too long.\n");
748                         exit_cleanup(RERR_SYNTAX);
749                 }
750                 if (backup_dir_buf[backup_dir_len - 1] != '/') {
751                         backup_dir_buf[backup_dir_len++] = '/';
752                         backup_dir_buf[backup_dir_len] = '\0';
753                 }
754                 if (verbose > 1 && !am_sender)
755                         rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
756         } else if (!backup_suffix_len && (!am_server || !am_sender)) {
757                 rprintf(FERROR,
758                         "--suffix cannot be a null string without --backup-dir\n");
759                 exit_cleanup(RERR_SYNTAX);
760         }
761
762         if (do_progress && !verbose)
763                 verbose = 1;
764
765         if (bwlimit) {
766                 bwlimit_writemax = (size_t)bwlimit * 128;
767                 if (bwlimit_writemax < 512)
768                         bwlimit_writemax = 512;
769         }
770
771         if (inplace) {
772 #if HAVE_FTRUNCATE
773                 keep_partial = 0;
774 #else
775                 snprintf(err_buf, sizeof err_buf,
776                          "--inplace is not supported on this %s\n",
777                          am_server ? "server" : "client");
778                 return 0;
779 #endif
780         }
781
782         if (files_from) {
783                 char *colon;
784                 if (*argc != 2 && !(am_server && am_sender && *argc == 1)) {
785                         usage(FERROR);
786                         exit_cleanup(RERR_SYNTAX);
787                 }
788                 if (strcmp(files_from, "-") == 0) {
789                         filesfrom_fd = 0;
790                         if (am_server)
791                                 remote_filesfrom_file = "-";
792                 }
793                 else if ((colon = find_colon(files_from)) != 0) {
794                         if (am_server) {
795                                 usage(FERROR);
796                                 exit_cleanup(RERR_SYNTAX);
797                         }
798                         remote_filesfrom_file = colon+1 + (colon[1] == ':');
799                         if (strcmp(remote_filesfrom_file, "-") == 0) {
800                                 rprintf(FERROR, "Invalid --files-from remote filename\n");
801                                 exit_cleanup(RERR_SYNTAX);
802                         }
803                 } else {
804                         filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
805                         if (filesfrom_fd < 0) {
806                                 rsyserr(FERROR, errno,
807                                         "failed to open files-from file %s",
808                                         files_from);
809                                 exit_cleanup(RERR_FILEIO);
810                         }
811                 }
812         }
813
814         return 1;
815 }
816
817
818 /**
819  * Construct a filtered list of options to pass through from the
820  * client to the server.
821  *
822  * This involves setting options that will tell the server how to
823  * behave, and also filtering out options that are processed only
824  * locally.
825  **/
826 void server_options(char **args,int *argc)
827 {
828         int ac = *argc;
829         static char argstr[50];
830         char *arg;
831
832         int i, x;
833
834         if (blocking_io == -1)
835                 blocking_io = 0;
836
837         args[ac++] = "--server";
838
839         if (daemon_over_rsh) {
840                 args[ac++] = "--daemon";
841                 *argc = ac;
842                 /* if we're passing --daemon, we're done */
843                 return;
844         }
845
846         if (!am_sender)
847                 args[ac++] = "--sender";
848
849         x = 1;
850         argstr[0] = '-';
851         for (i = 0; i < verbose; i++)
852                 argstr[x++] = 'v';
853
854         /* the -q option is intentionally left out */
855         if (make_backups)
856                 argstr[x++] = 'b';
857         if (update_only)
858                 argstr[x++] = 'u';
859         if (dry_run)
860                 argstr[x++] = 'n';
861         if (preserve_links)
862                 argstr[x++] = 'l';
863         if (copy_links)
864                 argstr[x++] = 'L';
865         if (keep_dirlinks && am_sender)
866                 argstr[x++] = 'K';
867
868         if (whole_file > 0)
869                 argstr[x++] = 'W';
870         /* We don't need to send --no-whole-file, because it's the
871          * default for remote transfers, and in any case old versions
872          * of rsync will not understand it. */
873
874         if (preserve_hard_links)
875                 argstr[x++] = 'H';
876         if (preserve_uid)
877                 argstr[x++] = 'o';
878         if (preserve_gid)
879                 argstr[x++] = 'g';
880         if (preserve_devices)
881                 argstr[x++] = 'D';
882         if (preserve_times)
883                 argstr[x++] = 't';
884         if (preserve_perms)
885                 argstr[x++] = 'p';
886         if (recurse)
887                 argstr[x++] = 'r';
888         if (always_checksum)
889                 argstr[x++] = 'c';
890         if (cvs_exclude)
891                 argstr[x++] = 'C';
892         if (ignore_times)
893                 argstr[x++] = 'I';
894         if (relative_paths)
895                 argstr[x++] = 'R';
896         if (one_file_system)
897                 argstr[x++] = 'x';
898         if (sparse_files)
899                 argstr[x++] = 'S';
900         if (do_compression)
901                 argstr[x++] = 'z';
902
903         /* this is a complete hack - blame Rusty
904
905            this is a hack to make the list_only (remote file list)
906            more useful */
907         if (list_only && !recurse)
908                 argstr[x++] = 'r';
909
910         argstr[x] = 0;
911
912         if (x != 1)
913                 args[ac++] = argstr;
914
915         if (block_size) {
916                 if (asprintf(&arg, "-B%u", block_size) < 0)
917                         goto oom;
918                 args[ac++] = arg;
919         }
920
921         if (max_delete && am_sender) {
922                 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
923                         goto oom;
924                 args[ac++] = arg;
925         }
926
927         if (io_timeout) {
928                 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
929                         goto oom;
930                 args[ac++] = arg;
931         }
932
933         if (bwlimit) {
934                 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
935                         goto oom;
936                 args[ac++] = arg;
937         }
938
939         if (backup_dir) {
940                 args[ac++] = "--backup-dir";
941                 args[ac++] = backup_dir;
942         }
943
944         /* Only send --suffix if it specifies a non-default value. */
945         if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
946                 /* We use the following syntax to avoid weirdness with '~'. */
947                 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
948                         goto oom;
949                 args[ac++] = arg;
950         }
951
952         if (delete_excluded)
953                 args[ac++] = "--delete-excluded";
954         else if (delete_mode)
955                 args[ac++] = "--delete";
956
957         if (size_only)
958                 args[ac++] = "--size-only";
959
960         if (modify_window_set) {
961                 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
962                         goto oom;
963                 args[ac++] = arg;
964         }
965
966         if (checksum_seed) {
967                 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
968                         goto oom;
969                 args[ac++] = arg;
970         }
971
972         if (keep_partial)
973                 args[ac++] = "--partial";
974
975         if (force_delete)
976                 args[ac++] = "--force";
977
978         if (delete_after)
979                 args[ac++] = "--delete-after";
980
981         if (ignore_errors)
982                 args[ac++] = "--ignore-errors";
983
984         if (copy_unsafe_links)
985                 args[ac++] = "--copy-unsafe-links";
986
987         if (safe_symlinks)
988                 args[ac++] = "--safe-links";
989
990         if (numeric_ids)
991                 args[ac++] = "--numeric-ids";
992
993         if (only_existing && am_sender)
994                 args[ac++] = "--existing";
995
996         if (opt_ignore_existing && am_sender)
997                 args[ac++] = "--ignore-existing";
998
999         if (inplace)
1000                 args[ac++] = "--inplace";
1001
1002         if (tmpdir) {
1003                 args[ac++] = "--temp-dir";
1004                 args[ac++] = tmpdir;
1005         }
1006
1007         if (compare_dest && am_sender) {
1008                 /* the server only needs this option if it is not the sender,
1009                  *   and it may be an older version that doesn't know this
1010                  *   option, so don't send it if client is the sender.
1011                  */
1012                 args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
1013                 args[ac++] = compare_dest;
1014         }
1015
1016         if (files_from && (!am_sender || remote_filesfrom_file)) {
1017                 if (remote_filesfrom_file) {
1018                         args[ac++] = "--files-from";
1019                         args[ac++] = remote_filesfrom_file;
1020                         if (eol_nulls)
1021                                 args[ac++] = "--from0";
1022                 } else {
1023                         args[ac++] = "--files-from=-";
1024                         args[ac++] = "--from0";
1025                 }
1026         }
1027
1028         *argc = ac;
1029         return;
1030
1031     oom:
1032         out_of_memory("server_options");
1033 }
1034
1035 /**
1036  * Return the position of a ':' IF it is not part of a filename (i.e. as
1037  * long as it doesn't occur after a slash.
1038  */
1039 char *find_colon(char *s)
1040 {
1041         char *p, *p2;
1042
1043         p = strchr(s,':');
1044         if (!p)
1045                 return NULL;
1046
1047         /* now check to see if there is a / in the string before the : - if there is then
1048            discard the colon on the assumption that the : is part of a filename */
1049         p2 = strchr(s,'/');
1050         if (p2 && p2 < p)
1051                 return NULL;
1052
1053         return p;
1054 }