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