In set_refuse_options(): make sure we scan the whole list of options
[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, found_match;
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                 found_match = 0;
458                 for (op = long_options; ; op++) {
459                         *shortname = op->shortName;
460                         if (!op->longName && !*shortname)
461                                 break;
462                         if ((op->longName && wildmatch(bp, op->longName))
463                             || (*shortname && wildmatch(bp, shortname))) {
464                                 op->val = (op - long_options) + OPT_REFUSED_BASE;
465                                 found_match = 1;
466                                 if (!is_wild)
467                                         break;
468                         }
469                 }
470                 if (!found_match) {
471                         rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
472                                 bp);
473                 }
474                 if (!cp)
475                         break;
476                 *cp = ' ';
477                 bp = cp + 1;
478         }
479 }
480
481
482 static int count_args(char const **argv)
483 {
484         int i = 0;
485
486         while (argv[i] != NULL)
487                 i++;
488
489         return i;
490 }
491
492
493 /**
494  * Process command line arguments.  Called on both local and remote.
495  *
496  * @retval 1 if all options are OK; with globals set to appropriate
497  * values
498  *
499  * @retval 0 on error, with err_buf containing an explanation
500  **/
501 int parse_arguments(int *argc, const char ***argv, int frommain)
502 {
503         int opt;
504         char *ref = lp_refuse_options(module_id);
505         const char *arg;
506         poptContext pc;
507
508         if (ref && *ref)
509                 set_refuse_options(ref);
510
511         /* TODO: Call poptReadDefaultConfig; handle errors. */
512
513         /* The context leaks in case of an error, but if there's a
514          * problem we always exit anyhow. */
515         pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
516
517         while ((opt = poptGetNextOpt(pc)) != -1) {
518                 /* most options are handled automatically by popt;
519                  * only special cases are returned and listed here. */
520
521                 switch (opt) {
522                 case OPT_VERSION:
523                         print_rsync_version(FINFO);
524                         exit_cleanup(0);
525
526                 case OPT_MODIFY_WINDOW:
527                         /* The value has already been set by popt, but
528                          * we need to remember that we're using a
529                          * non-default setting. */
530                         modify_window_set = 1;
531                         break;
532
533                 case OPT_DELETE_AFTER:
534                         delete_after = 1;
535                         delete_mode = 1;
536                         break;
537
538                 case OPT_DELETE_EXCLUDED:
539                         delete_excluded = 1;
540                         delete_mode = 1;
541                         break;
542
543                 case OPT_EXCLUDE:
544                         if (am_server || sanitize_paths)
545                                 return 0; /* Impossible... */
546                         add_exclude(&exclude_list, poptGetOptArg(pc), 0);
547                         break;
548
549                 case OPT_INCLUDE:
550                         if (am_server || sanitize_paths)
551                                 return 0; /* Impossible... */
552                         add_exclude(&exclude_list, poptGetOptArg(pc),
553                                     XFLG_DEF_INCLUDE);
554                         break;
555
556                 case OPT_EXCLUDE_FROM:
557                         if (am_server || sanitize_paths)
558                                 return 0; /* Impossible... */
559                         arg = poptGetOptArg(pc);
560                         add_exclude_file(&exclude_list, arg,
561                                          XFLG_FATAL_ERRORS);
562                         break;
563
564                 case OPT_INCLUDE_FROM:
565                         if (am_server || sanitize_paths)
566                                 return 0; /* Impossible... */
567                         arg = poptGetOptArg(pc);
568                         add_exclude_file(&exclude_list, arg,
569                                          XFLG_FATAL_ERRORS | XFLG_DEF_INCLUDE);
570                         break;
571
572                 case 'h':
573                         usage(FINFO);
574                         exit_cleanup(0);
575
576                 case 'v':
577                         verbose++;
578                         break;
579
580                 case 'q':
581                         if (frommain)
582                                 quiet++;
583                         break;
584
585                 case OPT_SENDER:
586                         if (!am_server) {
587                                 usage(FERROR);
588                                 exit_cleanup(RERR_SYNTAX);
589                         }
590                         am_sender = 1;
591                         break;
592
593                 case 'P':
594                         do_progress = 1;
595                         keep_partial = 1;
596                         break;
597
598                 case OPT_WRITE_BATCH:
599                         /* batch_name is already set */
600                         write_batch = 1;
601                         break;
602
603                 case OPT_READ_BATCH:
604                         /* batch_name is already set */
605                         read_batch = 1;
606                         break;
607
608                 case OPT_TIMEOUT:
609                         if (io_timeout && io_timeout < select_timeout)
610                                 select_timeout = io_timeout;
611                         break;
612
613                 case OPT_LINK_DEST:
614 #if HAVE_LINK
615                         link_dest = 1;
616                         break;
617 #else
618                         snprintf(err_buf, sizeof err_buf,
619                                  "hard links are not supported on this %s\n",
620                                  am_server ? "server" : "client");
621                         return 0;
622 #endif
623
624                 default:
625                         /* A large opt value means that set_refuse_options()
626                          * turned this option off (opt-BASE is its index). */
627                         if (opt >= OPT_REFUSED_BASE) {
628                                 struct poptOption *op =
629                                     &long_options[opt-OPT_REFUSED_BASE];
630                                 int n = snprintf(err_buf, sizeof err_buf,
631                                     "This server does not support --%s\n",
632                                     op->longName) - 1;
633                                 if (op->shortName) {
634                                         snprintf(err_buf+n, sizeof err_buf-n,
635                                             " (-%c)\n", op->shortName);
636                                 }
637                         } else {
638                                 snprintf(err_buf, sizeof err_buf,
639                                     "%s%s: %s\n",
640                                     am_server ? "on remote machine: " : "",
641                                     poptBadOption(pc, POPT_BADOPTION_NOALIAS),
642                                     poptStrerror(opt));
643                         }
644                         return 0;
645                 }
646         }
647
648 #if !SUPPORT_LINKS
649         if (preserve_links && !am_sender) {
650                 snprintf(err_buf, sizeof err_buf,
651                          "symlinks are not supported on this %s\n",
652                          am_server ? "server" : "client");
653                 return 0;
654         }
655 #endif
656
657 #if !SUPPORT_HARD_LINKS
658         if (preserve_hard_links) {
659                 snprintf(err_buf, sizeof err_buf,
660                          "hard links are not supported on this %s\n",
661                          am_server ? "server" : "client");
662                 return 0;
663         }
664 #endif
665
666         if (write_batch && read_batch) {
667                 snprintf(err_buf, sizeof err_buf,
668                         "--write-batch and --read-batch can not be used together\n");
669                 return 0;
670         }
671         if (write_batch || read_batch) {
672                 if (dry_run) {
673                         snprintf(err_buf, sizeof err_buf,
674                                 "--%s-batch cannot be used with --dry_run (-n)\n",
675                                 write_batch ? "write" : "read");
676                         return 0;
677                 }
678                 if (am_server) {
679                         rprintf(FINFO,
680                                 "ignoring --%s-batch option sent to server\n",
681                                 write_batch ? "write" : "read");
682                         /* We don't actually exit_cleanup(), so that we can
683                          * still service older version clients that still send
684                          * batch args to server. */
685                         read_batch = write_batch = 0;
686                         batch_name = NULL;
687                 }
688         }
689         if (read_batch && files_from) {
690                 snprintf(err_buf, sizeof err_buf,
691                         "--read-batch cannot be used with --files-from\n");
692                 return 0;
693         }
694         if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
695                 snprintf(err_buf, sizeof err_buf,
696                         "the batch-file name must be %d characters or less.\n",
697                         MAX_BATCH_NAME_LEN);
698                 return 0;
699         }
700
701         if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
702                 snprintf(err_buf, sizeof err_buf,
703                          "the --temp-dir path is WAY too long.\n");
704                 return 0;
705         }
706
707         if (archive_mode) {
708                 if (!files_from)
709                         recurse = 1;
710 #if SUPPORT_LINKS
711                 preserve_links = 1;
712 #endif
713                 preserve_perms = 1;
714                 preserve_times = 1;
715                 preserve_gid = 1;
716                 preserve_uid = 1;
717                 preserve_devices = 1;
718         }
719
720         if (relative_paths < 0)
721                 relative_paths = files_from? 1 : 0;
722
723         *argv = poptGetArgs(pc);
724         if (*argv)
725                 *argc = count_args(*argv);
726         else
727                 *argc = 0;
728
729         if (sanitize_paths) {
730                 int i;
731                 for (i = *argc; i-- > 0; )
732                         (*argv)[i] = alloc_sanitize_path((*argv)[i], NULL);
733                 if (tmpdir)
734                         tmpdir = alloc_sanitize_path(tmpdir, curr_dir);
735                 if (partial_dir)
736                         partial_dir = alloc_sanitize_path(partial_dir, curr_dir);
737                 if (compare_dest)
738                         compare_dest = alloc_sanitize_path(compare_dest, curr_dir);
739                 if (backup_dir)
740                         backup_dir = alloc_sanitize_path(backup_dir, curr_dir);
741                 if (files_from)
742                         files_from = alloc_sanitize_path(files_from, curr_dir);
743         }
744         if (server_exclude_list.head && !am_sender) {
745                 struct exclude_list_struct *elp = &server_exclude_list;
746                 if (tmpdir) {
747                         clean_fname(tmpdir);
748                         if (check_exclude(elp, tmpdir, 1) < 0)
749                                 goto options_rejected;
750                 }
751                 if (partial_dir) {
752                         clean_fname(partial_dir);
753                         if (check_exclude(elp, partial_dir, 1) < 0)
754                                 goto options_rejected;
755                 }
756                 if (compare_dest) {
757                         clean_fname(compare_dest);
758                         if (check_exclude(elp, compare_dest, 1) < 0)
759                                 goto options_rejected;
760                 }
761                 if (backup_dir) {
762                         clean_fname(backup_dir);
763                         if (check_exclude(elp, backup_dir, 1) < 0)
764                                 goto options_rejected;
765                 }
766         }
767         if (server_exclude_list.head && files_from) {
768                 clean_fname(files_from);
769                 if (check_exclude(&server_exclude_list, files_from, 0) < 0) {
770                     options_rejected:
771                         snprintf(err_buf, sizeof err_buf,
772                             "Your options have been rejected by the server.\n");
773                         return 0;
774                 }
775         }
776
777         if (daemon_opt) {
778                 daemon_opt = 0;
779                 am_daemon = 1;
780                 return 1;
781         }
782
783         if (!backup_suffix)
784                 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
785         backup_suffix_len = strlen(backup_suffix);
786         if (strchr(backup_suffix, '/') != NULL) {
787                 snprintf(err_buf, sizeof err_buf,
788                         "--suffix cannot contain slashes: %s\n",
789                         backup_suffix);
790                 return 0;
791         }
792         if (backup_dir) {
793                 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
794                 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
795                 if (backup_dir_remainder < 32) {
796                         snprintf(err_buf, sizeof err_buf,
797                                 "the --backup-dir path is WAY too long.\n");
798                         return 0;
799                 }
800                 if (backup_dir_buf[backup_dir_len - 1] != '/') {
801                         backup_dir_buf[backup_dir_len++] = '/';
802                         backup_dir_buf[backup_dir_len] = '\0';
803                 }
804                 if (verbose > 1 && !am_sender)
805                         rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
806         } else if (!backup_suffix_len && (!am_server || !am_sender)) {
807                 snprintf(err_buf, sizeof err_buf,
808                         "--suffix cannot be a null string without --backup-dir\n");
809                 return 0;
810         }
811
812         if (do_progress && !verbose)
813                 verbose = 1;
814
815         if (bwlimit) {
816                 bwlimit_writemax = (size_t)bwlimit * 128;
817                 if (bwlimit_writemax < 512)
818                         bwlimit_writemax = 512;
819         }
820
821         if (inplace) {
822 #if HAVE_FTRUNCATE
823                 if (partial_dir) {
824                         snprintf(err_buf, sizeof err_buf,
825                                  "--inplace cannot be used with --partial-dir\n");
826                         return 0;
827                 }
828                 keep_partial = 0;
829 #else
830                 snprintf(err_buf, sizeof err_buf,
831                          "--inplace is not supported on this %s\n",
832                          am_server ? "server" : "client");
833                 return 0;
834 #endif
835         } else if (partial_dir) {
836                 if (strcmp(partial_dir, ".") == 0)
837                         partial_dir = NULL;
838                 keep_partial = 1;
839         }
840
841         if (files_from) {
842                 char *colon;
843                 if (*argc > 2 || (!am_daemon && *argc == 1)) {
844                         usage(FERROR);
845                         exit_cleanup(RERR_SYNTAX);
846                 }
847                 if (strcmp(files_from, "-") == 0) {
848                         filesfrom_fd = 0;
849                         if (am_server)
850                                 remote_filesfrom_file = "-";
851                 }
852                 else if ((colon = find_colon(files_from)) != 0) {
853                         if (am_server) {
854                                 usage(FERROR);
855                                 exit_cleanup(RERR_SYNTAX);
856                         }
857                         remote_filesfrom_file = colon+1 + (colon[1] == ':');
858                         if (strcmp(remote_filesfrom_file, "-") == 0) {
859                                 snprintf(err_buf, sizeof err_buf,
860                                         "Invalid --files-from remote filename\n");
861                                 return 0;
862                         }
863                 } else {
864                         filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
865                         if (filesfrom_fd < 0) {
866                                 snprintf(err_buf, sizeof err_buf,
867                                         "failed to open files-from file %s: %s\n",
868                                         files_from, strerror(errno));
869                                 return 0;
870                         }
871                 }
872         }
873
874         return 1;
875 }
876
877
878 /**
879  * Construct a filtered list of options to pass through from the
880  * client to the server.
881  *
882  * This involves setting options that will tell the server how to
883  * behave, and also filtering out options that are processed only
884  * locally.
885  **/
886 void server_options(char **args,int *argc)
887 {
888         int ac = *argc;
889         static char argstr[50];
890         char *arg;
891
892         int i, x;
893
894         if (blocking_io == -1)
895                 blocking_io = 0;
896
897         args[ac++] = "--server";
898
899         if (daemon_over_rsh) {
900                 args[ac++] = "--daemon";
901                 *argc = ac;
902                 /* if we're passing --daemon, we're done */
903                 return;
904         }
905
906         if (!am_sender)
907                 args[ac++] = "--sender";
908
909         x = 1;
910         argstr[0] = '-';
911         for (i = 0; i < verbose; i++)
912                 argstr[x++] = 'v';
913
914         /* the -q option is intentionally left out */
915         if (make_backups)
916                 argstr[x++] = 'b';
917         if (update_only)
918                 argstr[x++] = 'u';
919         if (dry_run)
920                 argstr[x++] = 'n';
921         if (preserve_links)
922                 argstr[x++] = 'l';
923         if (copy_links)
924                 argstr[x++] = 'L';
925         if (keep_dirlinks && am_sender)
926                 argstr[x++] = 'K';
927
928         if (whole_file > 0)
929                 argstr[x++] = 'W';
930         /* We don't need to send --no-whole-file, because it's the
931          * default for remote transfers, and in any case old versions
932          * of rsync will not understand it. */
933
934         if (preserve_hard_links)
935                 argstr[x++] = 'H';
936         if (preserve_uid)
937                 argstr[x++] = 'o';
938         if (preserve_gid)
939                 argstr[x++] = 'g';
940         if (preserve_devices)
941                 argstr[x++] = 'D';
942         if (preserve_times)
943                 argstr[x++] = 't';
944         if (preserve_perms)
945                 argstr[x++] = 'p';
946         if (recurse)
947                 argstr[x++] = 'r';
948         if (always_checksum)
949                 argstr[x++] = 'c';
950         if (cvs_exclude)
951                 argstr[x++] = 'C';
952         if (ignore_times)
953                 argstr[x++] = 'I';
954         if (relative_paths)
955                 argstr[x++] = 'R';
956         if (one_file_system)
957                 argstr[x++] = 'x';
958         if (sparse_files)
959                 argstr[x++] = 'S';
960         if (do_compression)
961                 argstr[x++] = 'z';
962
963         /* this is a complete hack - blame Rusty
964
965            this is a hack to make the list_only (remote file list)
966            more useful */
967         if (list_only && !recurse)
968                 argstr[x++] = 'r';
969
970         argstr[x] = 0;
971
972         if (x != 1)
973                 args[ac++] = argstr;
974
975         if (block_size) {
976                 if (asprintf(&arg, "-B%u", block_size) < 0)
977                         goto oom;
978                 args[ac++] = arg;
979         }
980
981         if (max_delete && am_sender) {
982                 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
983                         goto oom;
984                 args[ac++] = arg;
985         }
986
987         if (io_timeout) {
988                 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
989                         goto oom;
990                 args[ac++] = arg;
991         }
992
993         if (bwlimit) {
994                 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
995                         goto oom;
996                 args[ac++] = arg;
997         }
998
999         if (backup_dir) {
1000                 args[ac++] = "--backup-dir";
1001                 args[ac++] = backup_dir;
1002         }
1003
1004         /* Only send --suffix if it specifies a non-default value. */
1005         if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1006                 /* We use the following syntax to avoid weirdness with '~'. */
1007                 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1008                         goto oom;
1009                 args[ac++] = arg;
1010         }
1011
1012         if (am_sender) {
1013                 if (delete_excluded)
1014                         args[ac++] = "--delete-excluded";
1015                 else if (delete_mode
1016                     && (!delete_after || protocol_version < 27))
1017                         args[ac++] = "--delete";
1018
1019                 if (delete_after)
1020                         args[ac++] = "--delete-after";
1021
1022                 if (force_delete)
1023                         args[ac++] = "--force";
1024         }
1025
1026         if (size_only)
1027                 args[ac++] = "--size-only";
1028
1029         if (modify_window_set) {
1030                 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1031                         goto oom;
1032                 args[ac++] = arg;
1033         }
1034
1035         if (checksum_seed) {
1036                 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1037                         goto oom;
1038                 args[ac++] = arg;
1039         }
1040
1041         if (partial_dir && am_sender) {
1042                 args[ac++] = "--partial-dir";
1043                 args[ac++] = partial_dir;
1044         } else if (keep_partial)
1045                 args[ac++] = "--partial";
1046
1047         if (ignore_errors)
1048                 args[ac++] = "--ignore-errors";
1049
1050         if (copy_unsafe_links)
1051                 args[ac++] = "--copy-unsafe-links";
1052
1053         if (safe_symlinks)
1054                 args[ac++] = "--safe-links";
1055
1056         if (numeric_ids)
1057                 args[ac++] = "--numeric-ids";
1058
1059         if (only_existing && am_sender)
1060                 args[ac++] = "--existing";
1061
1062         if (opt_ignore_existing && am_sender)
1063                 args[ac++] = "--ignore-existing";
1064
1065         if (inplace)
1066                 args[ac++] = "--inplace";
1067
1068         if (tmpdir) {
1069                 args[ac++] = "--temp-dir";
1070                 args[ac++] = tmpdir;
1071         }
1072
1073         if (compare_dest && am_sender) {
1074                 /* the server only needs this option if it is not the sender,
1075                  *   and it may be an older version that doesn't know this
1076                  *   option, so don't send it if client is the sender.
1077                  */
1078                 args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
1079                 args[ac++] = compare_dest;
1080         }
1081
1082         if (files_from && (!am_sender || remote_filesfrom_file)) {
1083                 if (remote_filesfrom_file) {
1084                         args[ac++] = "--files-from";
1085                         args[ac++] = remote_filesfrom_file;
1086                         if (eol_nulls)
1087                                 args[ac++] = "--from0";
1088                 } else {
1089                         args[ac++] = "--files-from=-";
1090                         args[ac++] = "--from0";
1091                 }
1092         }
1093
1094         *argc = ac;
1095         return;
1096
1097     oom:
1098         out_of_memory("server_options");
1099 }
1100
1101 /**
1102  * Return the position of a ':' IF it is not part of a filename (i.e. as
1103  * long as it doesn't occur after a slash.
1104  */
1105 char *find_colon(char *s)
1106 {
1107         char *p, *p2;
1108
1109         p = strchr(s,':');
1110         if (!p)
1111                 return NULL;
1112
1113         /* now check to see if there is a / in the string before the : - if there is then
1114            discard the colon on the assumption that the : is part of a filename */
1115         p2 = strchr(s,'/');
1116         if (p2 && p2 < p)
1117                 return NULL;
1118
1119         return p;
1120 }