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