Decided that we don't need to limit the block size after all now
[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 (write_batch && read_batch) {
664                 snprintf(err_buf, sizeof err_buf,
665                         "--write-batch and --read-batch can not be used together\n");
666                 return 0;
667         }
668         if (write_batch || read_batch) {
669                 if (dry_run) {
670                         snprintf(err_buf, sizeof err_buf,
671                                 "--%s-batch cannot be used with --dry_run (-n)\n",
672                                 write_batch ? "write" : "read");
673                         return 0;
674                 }
675                 if (am_server) {
676                         rprintf(FINFO,
677                                 "ignoring --%s-batch option sent to server\n",
678                                 write_batch ? "write" : "read");
679                         /* We don't actually exit_cleanup(), so that we can
680                          * still service older version clients that still send
681                          * batch args to server. */
682                         read_batch = write_batch = 0;
683                         batch_name = NULL;
684                 }
685         }
686         if (read_batch && files_from) {
687                 snprintf(err_buf, sizeof err_buf,
688                         "--read-batch cannot be used with --files-from\n");
689                 return 0;
690         }
691         if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
692                 snprintf(err_buf, sizeof err_buf,
693                         "the batch-file name must be %d characters or less.\n",
694                         MAX_BATCH_NAME_LEN);
695                 return 0;
696         }
697
698         if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
699                 snprintf(err_buf, sizeof err_buf,
700                          "the --temp-dir path is WAY too long.\n");
701                 return 0;
702         }
703
704         if (archive_mode) {
705                 if (!files_from)
706                         recurse = 1;
707 #if SUPPORT_LINKS
708                 preserve_links = 1;
709 #endif
710                 preserve_perms = 1;
711                 preserve_times = 1;
712                 preserve_gid = 1;
713                 preserve_uid = 1;
714                 preserve_devices = 1;
715         }
716
717         if (relative_paths < 0)
718                 relative_paths = files_from? 1 : 0;
719
720         *argv = poptGetArgs(pc);
721         if (*argv)
722                 *argc = count_args(*argv);
723         else
724                 *argc = 0;
725
726         if (sanitize_paths) {
727                 int i;
728                 for (i = *argc; i-- > 0; )
729                         (*argv)[i] = alloc_sanitize_path((*argv)[i], NULL);
730                 if (tmpdir)
731                         tmpdir = alloc_sanitize_path(tmpdir, curr_dir);
732                 if (partial_dir)
733                         partial_dir = alloc_sanitize_path(partial_dir, curr_dir);
734                 if (compare_dest)
735                         compare_dest = alloc_sanitize_path(compare_dest, curr_dir);
736                 if (backup_dir)
737                         backup_dir = alloc_sanitize_path(backup_dir, curr_dir);
738                 if (files_from)
739                         files_from = alloc_sanitize_path(files_from, curr_dir);
740         }
741         if (server_exclude_list.head && !am_sender) {
742                 struct exclude_list_struct *elp = &server_exclude_list;
743                 if (tmpdir) {
744                         clean_fname(tmpdir);
745                         if (check_exclude(elp, tmpdir, 1) < 0)
746                                 goto options_rejected;
747                 }
748                 if (partial_dir) {
749                         clean_fname(partial_dir);
750                         if (check_exclude(elp, partial_dir, 1) < 0)
751                                 goto options_rejected;
752                 }
753                 if (compare_dest) {
754                         clean_fname(compare_dest);
755                         if (check_exclude(elp, compare_dest, 1) < 0)
756                                 goto options_rejected;
757                 }
758                 if (backup_dir) {
759                         clean_fname(backup_dir);
760                         if (check_exclude(elp, backup_dir, 1) < 0)
761                                 goto options_rejected;
762                 }
763         }
764         if (server_exclude_list.head && files_from) {
765                 clean_fname(files_from);
766                 if (check_exclude(&server_exclude_list, files_from, 0) < 0) {
767                     options_rejected:
768                         snprintf(err_buf, sizeof err_buf,
769                             "Your options have been rejected by the server.\n");
770                         return 0;
771                 }
772         }
773
774         if (daemon_opt) {
775                 daemon_opt = 0;
776                 am_daemon = 1;
777                 return 1;
778         }
779
780         if (!backup_suffix)
781                 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
782         backup_suffix_len = strlen(backup_suffix);
783         if (strchr(backup_suffix, '/') != NULL) {
784                 snprintf(err_buf, sizeof err_buf,
785                         "--suffix cannot contain slashes: %s\n",
786                         backup_suffix);
787                 return 0;
788         }
789         if (backup_dir) {
790                 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
791                 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
792                 if (backup_dir_remainder < 32) {
793                         snprintf(err_buf, sizeof err_buf,
794                                 "the --backup-dir path is WAY too long.\n");
795                         return 0;
796                 }
797                 if (backup_dir_buf[backup_dir_len - 1] != '/') {
798                         backup_dir_buf[backup_dir_len++] = '/';
799                         backup_dir_buf[backup_dir_len] = '\0';
800                 }
801                 if (verbose > 1 && !am_sender)
802                         rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
803         } else if (!backup_suffix_len && (!am_server || !am_sender)) {
804                 snprintf(err_buf, sizeof err_buf,
805                         "--suffix cannot be a null string without --backup-dir\n");
806                 return 0;
807         }
808
809         if (do_progress && !verbose)
810                 verbose = 1;
811
812         if (bwlimit) {
813                 bwlimit_writemax = (size_t)bwlimit * 128;
814                 if (bwlimit_writemax < 512)
815                         bwlimit_writemax = 512;
816         }
817
818         if (inplace) {
819 #if HAVE_FTRUNCATE
820                 if (partial_dir) {
821                         snprintf(err_buf, sizeof err_buf,
822                                  "--inplace cannot be used with --partial-dir\n");
823                         return 0;
824                 }
825                 keep_partial = 0;
826 #else
827                 snprintf(err_buf, sizeof err_buf,
828                          "--inplace is not supported on this %s\n",
829                          am_server ? "server" : "client");
830                 return 0;
831 #endif
832         } else if (partial_dir) {
833                 if (strcmp(partial_dir, ".") == 0)
834                         partial_dir = NULL;
835                 keep_partial = 1;
836         }
837
838         if (files_from) {
839                 char *colon;
840                 if (*argc > 2 || (!am_daemon && *argc == 1)) {
841                         usage(FERROR);
842                         exit_cleanup(RERR_SYNTAX);
843                 }
844                 if (strcmp(files_from, "-") == 0) {
845                         filesfrom_fd = 0;
846                         if (am_server)
847                                 remote_filesfrom_file = "-";
848                 }
849                 else if ((colon = find_colon(files_from)) != 0) {
850                         if (am_server) {
851                                 usage(FERROR);
852                                 exit_cleanup(RERR_SYNTAX);
853                         }
854                         remote_filesfrom_file = colon+1 + (colon[1] == ':');
855                         if (strcmp(remote_filesfrom_file, "-") == 0) {
856                                 snprintf(err_buf, sizeof err_buf,
857                                         "Invalid --files-from remote filename\n");
858                                 return 0;
859                         }
860                 } else {
861                         filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
862                         if (filesfrom_fd < 0) {
863                                 snprintf(err_buf, sizeof err_buf,
864                                         "failed to open files-from file %s: %s\n",
865                                         files_from, strerror(errno));
866                                 return 0;
867                         }
868                 }
869         }
870
871         return 1;
872 }
873
874
875 /**
876  * Construct a filtered list of options to pass through from the
877  * client to the server.
878  *
879  * This involves setting options that will tell the server how to
880  * behave, and also filtering out options that are processed only
881  * locally.
882  **/
883 void server_options(char **args,int *argc)
884 {
885         int ac = *argc;
886         static char argstr[50];
887         char *arg;
888
889         int i, x;
890
891         if (blocking_io == -1)
892                 blocking_io = 0;
893
894         args[ac++] = "--server";
895
896         if (daemon_over_rsh) {
897                 args[ac++] = "--daemon";
898                 *argc = ac;
899                 /* if we're passing --daemon, we're done */
900                 return;
901         }
902
903         if (!am_sender)
904                 args[ac++] = "--sender";
905
906         x = 1;
907         argstr[0] = '-';
908         for (i = 0; i < verbose; i++)
909                 argstr[x++] = 'v';
910
911         /* the -q option is intentionally left out */
912         if (make_backups)
913                 argstr[x++] = 'b';
914         if (update_only)
915                 argstr[x++] = 'u';
916         if (dry_run)
917                 argstr[x++] = 'n';
918         if (preserve_links)
919                 argstr[x++] = 'l';
920         if (copy_links)
921                 argstr[x++] = 'L';
922         if (keep_dirlinks && am_sender)
923                 argstr[x++] = 'K';
924
925         if (whole_file > 0)
926                 argstr[x++] = 'W';
927         /* We don't need to send --no-whole-file, because it's the
928          * default for remote transfers, and in any case old versions
929          * of rsync will not understand it. */
930
931         if (preserve_hard_links)
932                 argstr[x++] = 'H';
933         if (preserve_uid)
934                 argstr[x++] = 'o';
935         if (preserve_gid)
936                 argstr[x++] = 'g';
937         if (preserve_devices)
938                 argstr[x++] = 'D';
939         if (preserve_times)
940                 argstr[x++] = 't';
941         if (preserve_perms)
942                 argstr[x++] = 'p';
943         if (recurse)
944                 argstr[x++] = 'r';
945         if (always_checksum)
946                 argstr[x++] = 'c';
947         if (cvs_exclude)
948                 argstr[x++] = 'C';
949         if (ignore_times)
950                 argstr[x++] = 'I';
951         if (relative_paths)
952                 argstr[x++] = 'R';
953         if (one_file_system)
954                 argstr[x++] = 'x';
955         if (sparse_files)
956                 argstr[x++] = 'S';
957         if (do_compression)
958                 argstr[x++] = 'z';
959
960         /* this is a complete hack - blame Rusty
961
962            this is a hack to make the list_only (remote file list)
963            more useful */
964         if (list_only && !recurse)
965                 argstr[x++] = 'r';
966
967         argstr[x] = 0;
968
969         if (x != 1)
970                 args[ac++] = argstr;
971
972         if (block_size) {
973                 if (asprintf(&arg, "-B%u", block_size) < 0)
974                         goto oom;
975                 args[ac++] = arg;
976         }
977
978         if (max_delete && am_sender) {
979                 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
980                         goto oom;
981                 args[ac++] = arg;
982         }
983
984         if (io_timeout) {
985                 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
986                         goto oom;
987                 args[ac++] = arg;
988         }
989
990         if (bwlimit) {
991                 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
992                         goto oom;
993                 args[ac++] = arg;
994         }
995
996         if (backup_dir) {
997                 args[ac++] = "--backup-dir";
998                 args[ac++] = backup_dir;
999         }
1000
1001         /* Only send --suffix if it specifies a non-default value. */
1002         if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1003                 /* We use the following syntax to avoid weirdness with '~'. */
1004                 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1005                         goto oom;
1006                 args[ac++] = arg;
1007         }
1008
1009         if (am_sender) {
1010                 if (delete_excluded)
1011                         args[ac++] = "--delete-excluded";
1012                 else if (delete_mode
1013                     && (!delete_after || protocol_version < 27))
1014                         args[ac++] = "--delete";
1015
1016                 if (delete_after)
1017                         args[ac++] = "--delete-after";
1018
1019                 if (force_delete)
1020                         args[ac++] = "--force";
1021         }
1022
1023         if (size_only)
1024                 args[ac++] = "--size-only";
1025
1026         if (modify_window_set) {
1027                 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1028                         goto oom;
1029                 args[ac++] = arg;
1030         }
1031
1032         if (checksum_seed) {
1033                 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1034                         goto oom;
1035                 args[ac++] = arg;
1036         }
1037
1038         if (partial_dir && am_sender) {
1039                 args[ac++] = "--partial-dir";
1040                 args[ac++] = partial_dir;
1041         } else if (keep_partial)
1042                 args[ac++] = "--partial";
1043
1044         if (ignore_errors)
1045                 args[ac++] = "--ignore-errors";
1046
1047         if (copy_unsafe_links)
1048                 args[ac++] = "--copy-unsafe-links";
1049
1050         if (safe_symlinks)
1051                 args[ac++] = "--safe-links";
1052
1053         if (numeric_ids)
1054                 args[ac++] = "--numeric-ids";
1055
1056         if (only_existing && am_sender)
1057                 args[ac++] = "--existing";
1058
1059         if (opt_ignore_existing && am_sender)
1060                 args[ac++] = "--ignore-existing";
1061
1062         if (inplace)
1063                 args[ac++] = "--inplace";
1064
1065         if (tmpdir) {
1066                 args[ac++] = "--temp-dir";
1067                 args[ac++] = tmpdir;
1068         }
1069
1070         if (compare_dest && am_sender) {
1071                 /* the server only needs this option if it is not the sender,
1072                  *   and it may be an older version that doesn't know this
1073                  *   option, so don't send it if client is the sender.
1074                  */
1075                 args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
1076                 args[ac++] = compare_dest;
1077         }
1078
1079         if (files_from && (!am_sender || remote_filesfrom_file)) {
1080                 if (remote_filesfrom_file) {
1081                         args[ac++] = "--files-from";
1082                         args[ac++] = remote_filesfrom_file;
1083                         if (eol_nulls)
1084                                 args[ac++] = "--from0";
1085                 } else {
1086                         args[ac++] = "--files-from=-";
1087                         args[ac++] = "--from0";
1088                 }
1089         }
1090
1091         *argc = ac;
1092         return;
1093
1094     oom:
1095         out_of_memory("server_options");
1096 }
1097
1098 /**
1099  * Return the position of a ':' IF it is not part of a filename (i.e. as
1100  * long as it doesn't occur after a slash.
1101  */
1102 char *find_colon(char *s)
1103 {
1104         char *p, *p2;
1105
1106         p = strchr(s,':');
1107         if (!p)
1108                 return NULL;
1109
1110         /* now check to see if there is a / in the string before the : - if there is then
1111            discard the colon on the assumption that the : is part of a filename */
1112         p2 = strchr(s,'/');
1113         if (p2 && p2 < p)
1114                 return NULL;
1115
1116         return p;
1117 }