fdab554cb99aee92ef79fec192c552b91599da18
[rsync.git] / options.c
1 /*  -*- c-file-style: "linux" -*-
2  *
3  * Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
4  * Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include "rsync.h"
22 #include "popt.h"
23
24 extern int sanitize_paths;
25 extern int select_timeout;
26 extern char curr_dir[MAXPATHLEN];
27 extern struct exclude_list_struct exclude_list;
28
29 int make_backups = 0;
30
31 /**
32  * If 1, send the whole file as literal data rather than trying to
33  * create an incremental diff.
34  *
35  * If -1, then look at whether we're local or remote and go by that.
36  *
37  * @sa disable_deltas_p()
38  **/
39 int whole_file = -1;
40
41 int archive_mode = 0;
42 int keep_dirlinks = 0;
43 int copy_links = 0;
44 int preserve_links = 0;
45 int preserve_hard_links = 0;
46 int preserve_perms = 0;
47 int preserve_devices = 0;
48 int preserve_uid = 0;
49 int preserve_gid = 0;
50 int preserve_times = 0;
51 int update_only = 0;
52 int cvs_exclude = 0;
53 int dry_run = 0;
54 int local_server = 0;
55 int ignore_times = 0;
56 int delete_mode = 0;
57 int delete_excluded = 0;
58 int one_file_system = 0;
59 int protocol_version = PROTOCOL_VERSION;
60 int sparse_files = 0;
61 int do_compression = 0;
62 int am_root = 0;
63 int orig_umask = 0;
64 int relative_paths = -1;
65 int implied_dirs = 1;
66 int numeric_ids = 0;
67 int force_delete = 0;
68 int io_timeout = 0;
69 int read_only = 0;
70 int module_id = -1;
71 int am_server = 0;
72 int am_sender = 0;
73 int am_generator = 0;
74 char *files_from = NULL;
75 int filesfrom_fd = -1;
76 char *remote_filesfrom_file = NULL;
77 int eol_nulls = 0;
78 int recurse = 0;
79 int am_daemon = 0;
80 int daemon_over_rsh = 0;
81 int do_stats = 0;
82 int do_progress = 0;
83 int keep_partial = 0;
84 int safe_symlinks = 0;
85 int copy_unsafe_links = 0;
86 int size_only = 0;
87 int bwlimit = 0;
88 size_t bwlimit_writemax = 0;
89 int delete_after = 0;
90 int only_existing = 0;
91 int opt_ignore_existing = 0;
92 int max_delete = 0;
93 int ignore_errors = 0;
94 int modify_window = 0;
95 int blocking_io = -1;
96 int checksum_seed = 0;
97 int inplace = 0;
98 unsigned int block_size = 0;
99
100
101 /** Network address family. **/
102 #ifdef INET6
103 int default_af_hint = 0;        /* Any protocol */
104 #else
105 int default_af_hint = AF_INET;  /* Must use IPv4 */
106 #endif
107
108 /** Do not go into the background when run as --daemon.  Good
109  * for debugging and required for running as a service on W32,
110  * or under Unix process-monitors. **/
111 int no_detach = 0;
112
113 int write_batch = 0;
114 int read_batch = 0;
115 int backup_dir_len = 0;
116 int backup_suffix_len;
117 unsigned int backup_dir_remainder;
118
119 char *backup_suffix = NULL;
120 char *tmpdir = NULL;
121 char *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       checksum blocking size (default %d)\n",BLOCK_SIZE);
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;
442
443         while (1) {
444                 if ((cp = strchr(bp, ' ')) != NULL)
445                         *cp= '\0';
446                 for (op = long_options; ; op++) {
447                         if (!op->longName) {
448                                 rprintf(FLOG,
449                                     "Unknown option %s in \"refuse options\" setting\n",
450                                     bp);
451                                 break;
452                         }
453                         if (strcmp(bp, op->longName) == 0) {
454                                 op->val = (op - long_options)+OPT_REFUSED_BASE;
455                                 break;
456                         }
457                 }
458                 if (!cp)
459                         break;
460                 *cp = ' ';
461                 bp = cp + 1;
462         }
463 }
464
465
466 static int count_args(char const **argv)
467 {
468         int i = 0;
469
470         while (argv[i] != NULL)
471                 i++;
472
473         return i;
474 }
475
476
477 /**
478  * Process command line arguments.  Called on both local and remote.
479  *
480  * @retval 1 if all options are OK; with globals set to appropriate
481  * values
482  *
483  * @retval 0 on error, with err_buf containing an explanation
484  **/
485 int parse_arguments(int *argc, const char ***argv, int frommain)
486 {
487         int opt;
488         char *ref = lp_refuse_options(module_id);
489         const char *arg;
490         poptContext pc;
491
492         if (ref && *ref)
493                 set_refuse_options(ref);
494
495         /* TODO: Call poptReadDefaultConfig; handle errors. */
496
497         /* The context leaks in case of an error, but if there's a
498          * problem we always exit anyhow. */
499         pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
500
501         while ((opt = poptGetNextOpt(pc)) != -1) {
502                 /* most options are handled automatically by popt;
503                  * only special cases are returned and listed here. */
504
505                 switch (opt) {
506                 case OPT_VERSION:
507                         print_rsync_version(FINFO);
508                         exit_cleanup(0);
509
510                 case OPT_MODIFY_WINDOW:
511                         /* The value has already been set by popt, but
512                          * we need to remember that we're using a
513                          * non-default setting. */
514                         modify_window_set = 1;
515                         break;
516
517                 case OPT_DELETE_AFTER:
518                         delete_after = 1;
519                         delete_mode = 1;
520                         break;
521
522                 case OPT_DELETE_EXCLUDED:
523                         delete_excluded = 1;
524                         delete_mode = 1;
525                         break;
526
527                 case OPT_EXCLUDE:
528                         if (am_server || sanitize_paths)
529                                 return 0; /* Impossible... */
530                         add_exclude(&exclude_list, poptGetOptArg(pc), 0);
531                         break;
532
533                 case OPT_INCLUDE:
534                         if (am_server || sanitize_paths)
535                                 return 0; /* Impossible... */
536                         add_exclude(&exclude_list, poptGetOptArg(pc),
537                                     XFLG_DEF_INCLUDE);
538                         break;
539
540                 case OPT_EXCLUDE_FROM:
541                         if (am_server || sanitize_paths)
542                                 return 0; /* Impossible... */
543                         arg = poptGetOptArg(pc);
544                         add_exclude_file(&exclude_list, arg,
545                                          XFLG_FATAL_ERRORS);
546                         break;
547
548                 case OPT_INCLUDE_FROM:
549                         if (am_server || sanitize_paths)
550                                 return 0; /* Impossible... */
551                         arg = poptGetOptArg(pc);
552                         add_exclude_file(&exclude_list, arg,
553                                          XFLG_FATAL_ERRORS | XFLG_DEF_INCLUDE);
554                         break;
555
556                 case 'h':
557                         usage(FINFO);
558                         exit_cleanup(0);
559
560                 case 'v':
561                         verbose++;
562                         break;
563
564                 case 'q':
565                         if (frommain)
566                                 quiet++;
567                         break;
568
569                 case OPT_SENDER:
570                         if (!am_server) {
571                                 usage(FERROR);
572                                 exit_cleanup(RERR_SYNTAX);
573                         }
574                         am_sender = 1;
575                         break;
576
577                 case 'P':
578                         do_progress = 1;
579                         keep_partial = 1;
580                         break;
581
582                 case OPT_WRITE_BATCH:
583                         /* batch_name is already set */
584                         write_batch = 1;
585                         break;
586
587                 case OPT_READ_BATCH:
588                         /* batch_name is already set */
589                         read_batch = 1;
590                         break;
591
592                 case OPT_TIMEOUT:
593                         if (io_timeout && io_timeout < select_timeout)
594                                 select_timeout = io_timeout;
595                         break;
596
597                 case OPT_LINK_DEST:
598 #if HAVE_LINK
599                         link_dest = 1;
600                         break;
601 #else
602                         snprintf(err_buf, sizeof err_buf,
603                                  "hard links are not supported on this %s\n",
604                                  am_server ? "server" : "client");
605                         return 0;
606 #endif
607
608                 default:
609                         /* A large opt value means that set_refuse_options()
610                          * turned this option off (opt-BASE is its index). */
611                         if (opt >= OPT_REFUSED_BASE) {
612                                 struct poptOption *op =
613                                     &long_options[opt-OPT_REFUSED_BASE];
614                                 int n = snprintf(err_buf, sizeof err_buf,
615                                     "This server does not support --%s\n",
616                                     op->longName) - 1;
617                                 if (op->shortName) {
618                                         snprintf(err_buf+n, sizeof err_buf-n,
619                                             " (-%c)\n", op->shortName);
620                                 }
621                         } else {
622                                 snprintf(err_buf, sizeof err_buf,
623                                     "%s%s: %s\n",
624                                     am_server ? "on remote machine: " : "",
625                                     poptBadOption(pc, POPT_BADOPTION_NOALIAS),
626                                     poptStrerror(opt));
627                         }
628                         return 0;
629                 }
630         }
631
632 #if !SUPPORT_LINKS
633         if (preserve_links && !am_sender) {
634                 snprintf(err_buf, sizeof err_buf,
635                          "symlinks are not supported on this %s\n",
636                          am_server ? "server" : "client");
637                 return 0;
638         }
639 #endif
640
641 #if !SUPPORT_HARD_LINKS
642         if (preserve_hard_links) {
643                 snprintf(err_buf, sizeof err_buf,
644                          "hard links are not supported on this %s\n",
645                          am_server ? "server" : "client");
646                 return 0;
647         }
648 #endif
649
650         if (block_size > MAX_MAP_SIZE) {
651                 rprintf(FINFO, "limiting block-size to %d bytes\n",
652                         MAX_MAP_SIZE);
653                 block_size = MAX_MAP_SIZE;
654         }
655
656         if (write_batch && read_batch) {
657                 rprintf(FERROR,
658                         "--write-batch and --read-batch can not be used together\n");
659                 exit_cleanup(RERR_SYNTAX);
660         }
661         if (write_batch || read_batch) {
662                 if (dry_run) {
663                         rprintf(FERROR,
664                                 "--%s-batch cannot be used with --dry_run (-n)\n",
665                                 write_batch ? "write" : "read");
666                         exit_cleanup(RERR_SYNTAX);
667                 }
668                 if (am_server) {
669                         rprintf(FINFO,
670                                 "ignoring --%s-batch option sent to server\n",
671                                 write_batch ? "write" : "read");
672                         /* We don't actually exit_cleanup(), so that we can
673                          * still service older version clients that still send
674                          * batch args to server. */
675                         read_batch = write_batch = 0;
676                         batch_name = NULL;
677                 }
678         }
679         if (read_batch && files_from) {
680                 rprintf(FERROR,
681                         "--read-batch cannot be used with --files-from\n");
682                 exit_cleanup(RERR_SYNTAX);
683         }
684         if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
685                 rprintf(FERROR,
686                         "the batch-file name must be %d characters or less.\n",
687                         MAX_BATCH_NAME_LEN);
688                 exit_cleanup(RERR_SYNTAX);
689         }
690
691         if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
692                 rprintf(FERROR, "the --temp-dir path is WAY too long.\n");
693                 exit_cleanup(RERR_SYNTAX);
694         }
695
696         if (archive_mode) {
697                 if (!files_from)
698                         recurse = 1;
699 #if SUPPORT_LINKS
700                 preserve_links = 1;
701 #endif
702                 preserve_perms = 1;
703                 preserve_times = 1;
704                 preserve_gid = 1;
705                 preserve_uid = 1;
706                 preserve_devices = 1;
707         }
708
709         if (relative_paths < 0)
710                 relative_paths = files_from? 1 : 0;
711
712         *argv = poptGetArgs(pc);
713         if (*argv)
714                 *argc = count_args(*argv);
715         else
716                 *argc = 0;
717
718         if (sanitize_paths) {
719                 int i;
720                 for (i = *argc; i-- > 0; )
721                         (*argv)[i] = alloc_sanitize_path((*argv)[i], NULL);
722                 if (tmpdir)
723                         tmpdir = alloc_sanitize_path(tmpdir, curr_dir);
724                 if (partial_dir)
725                         partial_dir = alloc_sanitize_path(partial_dir, curr_dir);
726                 if (compare_dest)
727                         compare_dest = alloc_sanitize_path(compare_dest, curr_dir);
728                 if (backup_dir)
729                         backup_dir = alloc_sanitize_path(backup_dir, curr_dir);
730                 if (files_from)
731                         files_from = alloc_sanitize_path(files_from, curr_dir);
732         }
733
734         if (daemon_opt) {
735                 daemon_opt = 0;
736                 am_daemon = 1;
737                 return 1;
738         }
739
740         if (!backup_suffix)
741                 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
742         backup_suffix_len = strlen(backup_suffix);
743         if (strchr(backup_suffix, '/') != NULL) {
744                 rprintf(FERROR, "--suffix cannot contain slashes: %s\n",
745                         backup_suffix);
746                 exit_cleanup(RERR_SYNTAX);
747         }
748         if (backup_dir) {
749                 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
750                 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
751                 if (backup_dir_remainder < 32) {
752                         rprintf(FERROR, "the --backup-dir path is WAY too long.\n");
753                         exit_cleanup(RERR_SYNTAX);
754                 }
755                 if (backup_dir_buf[backup_dir_len - 1] != '/') {
756                         backup_dir_buf[backup_dir_len++] = '/';
757                         backup_dir_buf[backup_dir_len] = '\0';
758                 }
759                 if (verbose > 1 && !am_sender)
760                         rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
761         } else if (!backup_suffix_len && (!am_server || !am_sender)) {
762                 rprintf(FERROR,
763                         "--suffix cannot be a null string without --backup-dir\n");
764                 exit_cleanup(RERR_SYNTAX);
765         }
766
767         if (do_progress && !verbose)
768                 verbose = 1;
769
770         if (bwlimit) {
771                 bwlimit_writemax = (size_t)bwlimit * 128;
772                 if (bwlimit_writemax < 512)
773                         bwlimit_writemax = 512;
774         }
775
776         if (inplace) {
777 #if HAVE_FTRUNCATE
778                 if (partial_dir) {
779                         snprintf(err_buf, sizeof err_buf,
780                                  "--inplace cannot be used with --partial-dir\n");
781                         return 0;
782                 }
783                 keep_partial = 0;
784 #else
785                 snprintf(err_buf, sizeof err_buf,
786                          "--inplace is not supported on this %s\n",
787                          am_server ? "server" : "client");
788                 return 0;
789 #endif
790         } else if (partial_dir) {
791                 if (strcmp(partial_dir, ".") == 0)
792                         partial_dir = NULL;
793                 keep_partial = 1;
794         }
795
796         if (files_from) {
797                 char *colon;
798                 if (*argc != 2 && !(am_server && am_sender && *argc == 1)) {
799                         usage(FERROR);
800                         exit_cleanup(RERR_SYNTAX);
801                 }
802                 if (strcmp(files_from, "-") == 0) {
803                         filesfrom_fd = 0;
804                         if (am_server)
805                                 remote_filesfrom_file = "-";
806                 }
807                 else if ((colon = find_colon(files_from)) != 0) {
808                         if (am_server) {
809                                 usage(FERROR);
810                                 exit_cleanup(RERR_SYNTAX);
811                         }
812                         remote_filesfrom_file = colon+1 + (colon[1] == ':');
813                         if (strcmp(remote_filesfrom_file, "-") == 0) {
814                                 rprintf(FERROR, "Invalid --files-from remote filename\n");
815                                 exit_cleanup(RERR_SYNTAX);
816                         }
817                 } else {
818                         filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
819                         if (filesfrom_fd < 0) {
820                                 rsyserr(FERROR, errno,
821                                         "failed to open files-from file %s",
822                                         files_from);
823                                 exit_cleanup(RERR_FILEIO);
824                         }
825                 }
826         }
827
828         return 1;
829 }
830
831
832 /**
833  * Construct a filtered list of options to pass through from the
834  * client to the server.
835  *
836  * This involves setting options that will tell the server how to
837  * behave, and also filtering out options that are processed only
838  * locally.
839  **/
840 void server_options(char **args,int *argc)
841 {
842         int ac = *argc;
843         static char argstr[50];
844         char *arg;
845
846         int i, x;
847
848         if (blocking_io == -1)
849                 blocking_io = 0;
850
851         args[ac++] = "--server";
852
853         if (daemon_over_rsh) {
854                 args[ac++] = "--daemon";
855                 *argc = ac;
856                 /* if we're passing --daemon, we're done */
857                 return;
858         }
859
860         if (!am_sender)
861                 args[ac++] = "--sender";
862
863         x = 1;
864         argstr[0] = '-';
865         for (i = 0; i < verbose; i++)
866                 argstr[x++] = 'v';
867
868         /* the -q option is intentionally left out */
869         if (make_backups)
870                 argstr[x++] = 'b';
871         if (update_only)
872                 argstr[x++] = 'u';
873         if (dry_run)
874                 argstr[x++] = 'n';
875         if (preserve_links)
876                 argstr[x++] = 'l';
877         if (copy_links)
878                 argstr[x++] = 'L';
879         if (keep_dirlinks && am_sender)
880                 argstr[x++] = 'K';
881
882         if (whole_file > 0)
883                 argstr[x++] = 'W';
884         /* We don't need to send --no-whole-file, because it's the
885          * default for remote transfers, and in any case old versions
886          * of rsync will not understand it. */
887
888         if (preserve_hard_links)
889                 argstr[x++] = 'H';
890         if (preserve_uid)
891                 argstr[x++] = 'o';
892         if (preserve_gid)
893                 argstr[x++] = 'g';
894         if (preserve_devices)
895                 argstr[x++] = 'D';
896         if (preserve_times)
897                 argstr[x++] = 't';
898         if (preserve_perms)
899                 argstr[x++] = 'p';
900         if (recurse)
901                 argstr[x++] = 'r';
902         if (always_checksum)
903                 argstr[x++] = 'c';
904         if (cvs_exclude)
905                 argstr[x++] = 'C';
906         if (ignore_times)
907                 argstr[x++] = 'I';
908         if (relative_paths)
909                 argstr[x++] = 'R';
910         if (one_file_system)
911                 argstr[x++] = 'x';
912         if (sparse_files)
913                 argstr[x++] = 'S';
914         if (do_compression)
915                 argstr[x++] = 'z';
916
917         /* this is a complete hack - blame Rusty
918
919            this is a hack to make the list_only (remote file list)
920            more useful */
921         if (list_only && !recurse)
922                 argstr[x++] = 'r';
923
924         argstr[x] = 0;
925
926         if (x != 1)
927                 args[ac++] = argstr;
928
929         if (block_size) {
930                 if (asprintf(&arg, "-B%u", block_size) < 0)
931                         goto oom;
932                 args[ac++] = arg;
933         }
934
935         if (max_delete && am_sender) {
936                 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
937                         goto oom;
938                 args[ac++] = arg;
939         }
940
941         if (io_timeout) {
942                 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
943                         goto oom;
944                 args[ac++] = arg;
945         }
946
947         if (bwlimit) {
948                 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
949                         goto oom;
950                 args[ac++] = arg;
951         }
952
953         if (backup_dir) {
954                 args[ac++] = "--backup-dir";
955                 args[ac++] = backup_dir;
956         }
957
958         /* Only send --suffix if it specifies a non-default value. */
959         if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
960                 /* We use the following syntax to avoid weirdness with '~'. */
961                 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
962                         goto oom;
963                 args[ac++] = arg;
964         }
965
966         if (delete_excluded)
967                 args[ac++] = "--delete-excluded";
968         else if (delete_mode)
969                 args[ac++] = "--delete";
970
971         if (size_only)
972                 args[ac++] = "--size-only";
973
974         if (modify_window_set) {
975                 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
976                         goto oom;
977                 args[ac++] = arg;
978         }
979
980         if (checksum_seed) {
981                 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
982                         goto oom;
983                 args[ac++] = arg;
984         }
985
986         if (partial_dir && am_sender) {
987                 args[ac++] = "--partial-dir";
988                 args[ac++] = partial_dir;
989         } else if (keep_partial)
990                 args[ac++] = "--partial";
991
992         if (force_delete)
993                 args[ac++] = "--force";
994
995         if (delete_after)
996                 args[ac++] = "--delete-after";
997
998         if (ignore_errors)
999                 args[ac++] = "--ignore-errors";
1000
1001         if (copy_unsafe_links)
1002                 args[ac++] = "--copy-unsafe-links";
1003
1004         if (safe_symlinks)
1005                 args[ac++] = "--safe-links";
1006
1007         if (numeric_ids)
1008                 args[ac++] = "--numeric-ids";
1009
1010         if (only_existing && am_sender)
1011                 args[ac++] = "--existing";
1012
1013         if (opt_ignore_existing && am_sender)
1014                 args[ac++] = "--ignore-existing";
1015
1016         if (inplace)
1017                 args[ac++] = "--inplace";
1018
1019         if (tmpdir) {
1020                 args[ac++] = "--temp-dir";
1021                 args[ac++] = tmpdir;
1022         }
1023
1024         if (compare_dest && am_sender) {
1025                 /* the server only needs this option if it is not the sender,
1026                  *   and it may be an older version that doesn't know this
1027                  *   option, so don't send it if client is the sender.
1028                  */
1029                 args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
1030                 args[ac++] = compare_dest;
1031         }
1032
1033         if (files_from && (!am_sender || remote_filesfrom_file)) {
1034                 if (remote_filesfrom_file) {
1035                         args[ac++] = "--files-from";
1036                         args[ac++] = remote_filesfrom_file;
1037                         if (eol_nulls)
1038                                 args[ac++] = "--from0";
1039                 } else {
1040                         args[ac++] = "--files-from=-";
1041                         args[ac++] = "--from0";
1042                 }
1043         }
1044
1045         *argc = ac;
1046         return;
1047
1048     oom:
1049         out_of_memory("server_options");
1050 }
1051
1052 /**
1053  * Return the position of a ':' IF it is not part of a filename (i.e. as
1054  * long as it doesn't occur after a slash.
1055  */
1056 char *find_colon(char *s)
1057 {
1058         char *p, *p2;
1059
1060         p = strchr(s,':');
1061         if (!p)
1062                 return NULL;
1063
1064         /* now check to see if there is a / in the string before the : - if there is then
1065            discard the colon on the assumption that the : is part of a filename */
1066         p2 = strchr(s,'/');
1067         if (p2 && p2 < p)
1068                 return NULL;
1069
1070         return p;
1071 }