Improved parse_size_arg() a little more.
[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 module_id;
25 extern int sanitize_paths;
26 extern struct filter_list_struct filter_list;
27 extern struct filter_list_struct server_filter_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 append_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 omit_dir_times = 0;
52 int update_only = 0;
53 int cvs_exclude = 0;
54 int dry_run = 0;
55 int do_xfers = 1;
56 int ignore_times = 0;
57 int delete_mode = 0;
58 int delete_during = 0;
59 int delete_before = 0;
60 int delete_after = 0;
61 int delete_excluded = 0;
62 int remove_sent_files = 0;
63 int one_file_system = 0;
64 int protocol_version = PROTOCOL_VERSION;
65 int sparse_files = 0;
66 int do_compression = 0;
67 int am_root = 0;
68 int am_server = 0;
69 int am_sender = 0;
70 int am_generator = 0;
71 int am_starting_up = 1;
72 int orig_umask = 0;
73 int relative_paths = -1;
74 int implied_dirs = 1;
75 int numeric_ids = 0;
76 int force_delete = 0;
77 int io_timeout = 0;
78 int allowed_lull = 0;
79 char *files_from = NULL;
80 int filesfrom_fd = -1;
81 char *filesfrom_host = NULL;
82 int eol_nulls = 0;
83 int recurse = 0;
84 int xfer_dirs = -1;
85 int am_daemon = 0;
86 int daemon_over_rsh = 0;
87 int do_stats = 0;
88 int do_progress = 0;
89 int keep_partial = 0;
90 int safe_symlinks = 0;
91 int copy_unsafe_links = 0;
92 int size_only = 0;
93 int daemon_bwlimit = 0;
94 int bwlimit = 0;
95 int fuzzy_basis = 0;
96 size_t bwlimit_writemax = 0;
97 int ignore_existing = 0;
98 int ignore_non_existing = 0;
99 int need_messages_from_generator = 0;
100 int max_delete = 0;
101 OFF_T max_size = 0;
102 int ignore_errors = 0;
103 int modify_window = 0;
104 int blocking_io = -1;
105 int checksum_seed = 0;
106 int inplace = 0;
107 int delay_updates = 0;
108 long block_size = 0; /* "long" because popt can't set an int32. */
109
110
111 /** Network address family. **/
112 #ifdef INET6
113 int default_af_hint = 0;        /* Any protocol */
114 #else
115 int default_af_hint = AF_INET;  /* Must use IPv4 */
116 #endif
117
118 /** Do not go into the background when run as --daemon.  Good
119  * for debugging and required for running as a service on W32,
120  * or under Unix process-monitors. **/
121 int no_detach
122 #if defined _WIN32 || defined __WIN32__
123         = 1;
124 #else
125         = 0;
126 #endif
127
128 int write_batch = 0;
129 int read_batch = 0;
130 int backup_dir_len = 0;
131 int backup_suffix_len;
132 unsigned int backup_dir_remainder;
133
134 char *backup_suffix = NULL;
135 char *tmpdir = NULL;
136 char *partial_dir = NULL;
137 char *basis_dir[MAX_BASIS_DIRS+1];
138 char *config_file = NULL;
139 char *shell_cmd = NULL;
140 char *log_format = NULL;
141 char *password_file = NULL;
142 char *rsync_path = RSYNC_PATH;
143 char *backup_dir = NULL;
144 char backup_dir_buf[MAXPATHLEN];
145 int rsync_port = 0;
146 int compare_dest = 0;
147 int copy_dest = 0;
148 int link_dest = 0;
149 int basis_dir_cnt = 0;
150 char *dest_option = NULL;
151
152 int verbose = 0;
153 int quiet = 0;
154 int log_before_transfer = 0;
155 int log_format_has_i = 0;
156 int log_format_has_o_or_i = 0;
157 int always_checksum = 0;
158 int list_only = 0;
159
160 #define MAX_BATCH_NAME_LEN 256  /* Must be less than MAXPATHLEN-13 */
161 char *batch_name = NULL;
162
163 static int daemon_opt;   /* sets am_daemon after option error-reporting */
164 static int F_option_cnt = 0;
165 static int modify_window_set;
166 static int itemize_changes = 0;
167 static int refused_delete, refused_archive_part;
168 static int refused_partial, refused_progress, refused_delete_before;
169 static int refused_inplace;
170 static char *max_size_arg;
171 static char partialdir_for_delayupdate[] = ".~tmp~";
172
173 /** Local address to bind.  As a character string because it's
174  * interpreted by the IPv6 layer: should be a numeric IP4 or IP6
175  * address, or a hostname. **/
176 char *bind_address;
177
178
179 static void print_rsync_version(enum logcode f)
180 {
181         char const *got_socketpair = "no ";
182         char const *have_inplace = "no ";
183         char const *hardlinks = "no ";
184         char const *links = "no ";
185         char const *ipv6 = "no ";
186         STRUCT_STAT *dumstat;
187
188 #ifdef HAVE_SOCKETPAIR
189         got_socketpair = "";
190 #endif
191
192 #ifdef HAVE_FTRUNCATE
193         have_inplace = "";
194 #endif
195
196 #ifdef SUPPORT_HARD_LINKS
197         hardlinks = "";
198 #endif
199
200 #ifdef SUPPORT_LINKS
201         links = "";
202 #endif
203
204 #ifdef INET6
205         ipv6 = "";
206 #endif
207
208         rprintf(f, "%s  version %s  protocol version %d\n",
209                 RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION);
210         rprintf(f,
211                 "Copyright (C) 1996-2005 by Andrew Tridgell and others\n");
212         rprintf(f, "<http://rsync.samba.org/>\n");
213         rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
214                 "%shard links, %ssymlinks, batchfiles, \n",
215                 (int) (sizeof (OFF_T) * 8),
216                 got_socketpair, hardlinks, links);
217
218         /* Note that this field may not have type ino_t.  It depends
219          * on the complicated interaction between largefile feature
220          * macros. */
221         rprintf(f, "              %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n",
222                 have_inplace, ipv6,
223                 (int) (sizeof dumstat->st_ino * 8),
224                 (int) (sizeof (int64) * 8));
225 #ifdef MAINTAINER_MODE
226         rprintf(f, "              panic action: \"%s\"\n",
227                 get_panic_action());
228 #endif
229
230 #if SIZEOF_INT64 < 8
231         rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
232 #endif
233         if (sizeof (int64) != SIZEOF_INT64) {
234                 rprintf(f,
235                         "WARNING: size mismatch in SIZEOF_INT64 define (%d != %d)\n",
236                         (int) SIZEOF_INT64, (int) sizeof (int64));
237         }
238
239         rprintf(f,
240 "\n"
241 "rsync comes with ABSOLUTELY NO WARRANTY.  This is free software, and you\n"
242 "are welcome to redistribute it under certain conditions.  See the GNU\n"
243 "General Public Licence for details.\n"
244                 );
245 }
246
247
248 void usage(enum logcode F)
249 {
250   print_rsync_version(F);
251
252   rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
253
254   rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... DEST\n");
255   rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
256   rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
257   rprintf(F,"  or   rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
258   rprintf(F,"  or   rsync [OPTION]... [USER@]HOST:SRC [DEST]\n");
259   rprintf(F,"  or   rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
260   rprintf(F,"  or   rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
261   rprintf(F,"The ':' usages connect via remote shell, while '::' & 'rsync://' usages connect\n");
262   rprintf(F,"to an rsync daemon, and require SRC or DEST to start with a module name.\n");
263   rprintf(F,"\nOptions\n");
264   rprintf(F," -v, --verbose               increase verbosity\n");
265   rprintf(F," -q, --quiet                 suppress non-error messages\n");
266   rprintf(F," -c, --checksum              skip based on checksum, not mod-time & size\n");
267   rprintf(F," -a, --archive               archive mode; same as -rlptgoD (no -H)\n");
268   rprintf(F,"     --no-OPTION             turn of an implied OPTION (e.g. --no-D)\n");
269   rprintf(F," -r, --recursive             recurse into directories\n");
270   rprintf(F," -R, --relative              use relative path names\n");
271   rprintf(F,"     --no-implied-dirs       don't send implied dirs with --relative\n");
272   rprintf(F," -b, --backup                make backups (see --suffix & --backup-dir)\n");
273   rprintf(F,"     --backup-dir=DIR        make backups into hierarchy based in DIR\n");
274   rprintf(F,"     --suffix=SUFFIX         set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
275   rprintf(F," -u, --update                skip files that are newer on the receiver\n");
276   rprintf(F,"     --inplace               update destination files in-place (SEE MAN PAGE)\n");
277   rprintf(F,"     --append                append data onto shorter files\n");
278   rprintf(F," -d, --dirs                  transfer directories without recursing\n");
279   rprintf(F," -l, --links                 copy symlinks as symlinks\n");
280   rprintf(F," -L, --copy-links            transform symlink into referent file/dir\n");
281   rprintf(F,"     --copy-unsafe-links     only \"unsafe\" symlinks are transformed\n");
282   rprintf(F,"     --safe-links            ignore symlinks that point outside the source tree\n");
283   rprintf(F," -H, --hard-links            preserve hard links\n");
284   rprintf(F," -K, --keep-dirlinks         treat symlinked dir on receiver as dir\n");
285   rprintf(F," -p, --perms                 preserve permissions\n");
286   rprintf(F," -o, --owner                 preserve owner (root only)\n");
287   rprintf(F," -g, --group                 preserve group\n");
288   rprintf(F," -D, --devices               preserve devices (root only)\n");
289   rprintf(F," -t, --times                 preserve times\n");
290   rprintf(F," -O, --omit-dir-times        omit directories when preserving times\n");
291   rprintf(F," -S, --sparse                handle sparse files efficiently\n");
292   rprintf(F," -n, --dry-run               show what would have been transferred\n");
293   rprintf(F," -W, --whole-file            copy files whole (without rsync algorithm)\n");
294   rprintf(F," -x, --one-file-system       don't cross filesystem boundaries\n");
295   rprintf(F," -B, --block-size=SIZE       force a fixed checksum block-size\n");
296   rprintf(F," -e, --rsh=COMMAND           specify the remote shell to use\n");
297   rprintf(F,"     --rsync-path=PROGRAM    specify the rsync to run on the remote machine\n");
298   rprintf(F,"     --existing              only update files that already exist on receiver\n");
299   rprintf(F,"     --ignore-existing       ignore files that already exist on receiving side\n");
300   rprintf(F,"     --remove-sent-files     sent files/symlinks are removed from sending side\n");
301   rprintf(F,"     --del                   an alias for --delete-during\n");
302   rprintf(F,"     --delete                delete files that don't exist on the sending side\n");
303   rprintf(F,"     --delete-before         receiver deletes before transfer (default)\n");
304   rprintf(F,"     --delete-during         receiver deletes during transfer, not before\n");
305   rprintf(F,"     --delete-after          receiver deletes after transfer, not before\n");
306   rprintf(F,"     --delete-excluded       also delete excluded files on the receiving side\n");
307   rprintf(F,"     --ignore-errors         delete even if there are I/O errors\n");
308   rprintf(F,"     --force                 force deletion of directories even if not empty\n");
309   rprintf(F,"     --max-delete=NUM        don't delete more than NUM files\n");
310   rprintf(F,"     --max-size=SIZE         don't transfer any file larger than SIZE\n");
311   rprintf(F,"     --partial               keep partially transferred files\n");
312   rprintf(F,"     --partial-dir=DIR       put a partially transferred file into DIR\n");
313   rprintf(F,"     --delay-updates         put all updated files into place at transfer's end\n");
314   rprintf(F,"     --numeric-ids           don't map uid/gid values by user/group name\n");
315   rprintf(F,"     --timeout=TIME          set I/O timeout in seconds\n");
316   rprintf(F," -I, --ignore-times          don't skip files that match in size and mod-time\n");
317   rprintf(F,"     --size-only             skip files that match in size\n");
318   rprintf(F,"     --modify-window=NUM     compare mod-times with reduced accuracy\n");
319   rprintf(F," -T, --temp-dir=DIR          create temporary files in directory DIR\n");
320   rprintf(F," -y, --fuzzy                 find similar file for basis if no dest file\n");
321   rprintf(F,"     --compare-dest=DIR      also compare destination files relative to DIR\n");
322   rprintf(F,"     --copy-dest=DIR         ... and include copies of unchanged files\n");
323   rprintf(F,"     --link-dest=DIR         hardlink to files in DIR when unchanged\n");
324   rprintf(F," -z, --compress              compress file data during the transfer\n");
325   rprintf(F," -C, --cvs-exclude           auto-ignore files the same way CVS does\n");
326   rprintf(F," -f, --filter=RULE           add a file-filtering RULE\n");
327   rprintf(F," -F                          same as --filter='dir-merge /.rsync-filter'\n");
328   rprintf(F,"                             repeated: --filter='- .rsync-filter'\n");
329   rprintf(F,"     --exclude=PATTERN       exclude files matching PATTERN\n");
330   rprintf(F,"     --exclude-from=FILE     read exclude patterns from FILE\n");
331   rprintf(F,"     --include=PATTERN       don't exclude files matching PATTERN\n");
332   rprintf(F,"     --include-from=FILE     read include patterns from FILE\n");
333   rprintf(F,"     --files-from=FILE       read list of source-file names from FILE\n");
334   rprintf(F," -0, --from0                 all *-from/filter files are delimited by 0s\n");
335   rprintf(F,"     --address=ADDRESS       bind address for outgoing socket to daemon\n");
336   rprintf(F,"     --port=PORT             specify double-colon alternate port number\n");
337   rprintf(F,"     --blocking-io           use blocking I/O for the remote shell\n");
338   rprintf(F,"     --stats                 give some file-transfer stats\n");
339   rprintf(F,"     --progress              show progress during transfer\n");
340   rprintf(F," -P                          same as --partial --progress\n");
341   rprintf(F," -i, --itemize-changes       output a change-summary for all updates\n");
342   rprintf(F,"     --log-format=FORMAT     output filenames using the specified format\n");
343   rprintf(F,"     --password-file=FILE    read password from FILE\n");
344   rprintf(F,"     --list-only             list the files instead of copying them\n");
345   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth; KBytes per second\n");
346   rprintf(F,"     --write-batch=FILE      write a batched update to FILE\n");
347   rprintf(F,"     --only-write-batch=FILE like --write-batch but w/o updating destination\n");
348   rprintf(F,"     --read-batch=FILE       read a batched update from FILE\n");
349   rprintf(F,"     --protocol=NUM          force an older protocol version to be used\n");
350 #ifdef INET6
351   rprintf(F," -4, --ipv4                  prefer IPv4\n");
352   rprintf(F," -6, --ipv6                  prefer IPv6\n");
353 #endif
354   rprintf(F,"     --version               print version number\n");
355   rprintf(F," -h, --help                  show this help screen\n");
356
357   rprintf(F,"\nUse \"rsync --daemon --help\" to see the daemon-mode command-line options.\n");
358   rprintf(F,"Please see the rsync(1) and rsyncd.conf(5) man pages for full documentation.\n");
359   rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n");
360 }
361
362 enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
363       OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
364       OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
365       OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
366       OPT_REFUSED_BASE = 9000};
367
368 static struct poptOption long_options[] = {
369   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
370   {"help",            'h', POPT_ARG_NONE,   0, 'h', 0, 0 },
371   {"version",          0,  POPT_ARG_NONE,   0, OPT_VERSION, 0, 0},
372   {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
373   {"no-verbose",       0,  POPT_ARG_VAL,    &verbose, 0, 0, 0 },
374   {"no-v",             0,  POPT_ARG_VAL,    &verbose, 0, 0, 0 },
375   {"quiet",           'q', POPT_ARG_NONE,   0, 'q', 0, 0 },
376   {"stats",            0,  POPT_ARG_NONE,   &do_stats, 0, 0, 0 },
377   {"dry-run",         'n', POPT_ARG_NONE,   &dry_run, 0, 0, 0 },
378   {"archive",         'a', POPT_ARG_NONE,   0, 'a', 0, 0 },
379   {"recursive",       'r', POPT_ARG_VAL,    &recurse, 2, 0, 0 },
380   {"no-recursive",     0,  POPT_ARG_VAL,    &recurse, 0, 0, 0 },
381   {"no-r",             0,  POPT_ARG_VAL,    &recurse, 0, 0, 0 },
382   {"dirs",            'd', POPT_ARG_VAL,    &xfer_dirs, 2, 0, 0 },
383   {"no-dirs",          0,  POPT_ARG_VAL,    &xfer_dirs, 0, 0, 0 },
384   {"no-d",             0,  POPT_ARG_VAL,    &xfer_dirs, 0, 0, 0 },
385   {"perms",           'p', POPT_ARG_VAL,    &preserve_perms, 1, 0, 0 },
386   {"no-perms",         0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
387   {"no-p",             0,  POPT_ARG_VAL,    &preserve_perms, 0, 0, 0 },
388   {"times",           't', POPT_ARG_VAL,    &preserve_times, 1, 0, 0 },
389   {"no-times",         0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
390   {"no-t",             0,  POPT_ARG_VAL,    &preserve_times, 0, 0, 0 },
391   {"omit-dir-times",  'O', POPT_ARG_VAL,    &omit_dir_times, 2, 0, 0 },
392   {"modify-window",    0,  POPT_ARG_INT,    &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
393   {"owner",           'o', POPT_ARG_VAL,    &preserve_uid, 1, 0, 0 },
394   {"no-owner",         0,  POPT_ARG_VAL,    &preserve_uid, 0, 0, 0 },
395   {"no-o",             0,  POPT_ARG_VAL,    &preserve_uid, 0, 0, 0 },
396   {"group",           'g', POPT_ARG_VAL,    &preserve_gid, 1, 0, 0 },
397   {"no-group",         0,  POPT_ARG_VAL,    &preserve_gid, 0, 0, 0 },
398   {"no-g",             0,  POPT_ARG_VAL,    &preserve_gid, 0, 0, 0 },
399   {"devices",         'D', POPT_ARG_VAL,    &preserve_devices, 1, 0, 0 },
400   {"no-devices",       0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
401   {"no-D",             0,  POPT_ARG_VAL,    &preserve_devices, 0, 0, 0 },
402   {"links",           'l', POPT_ARG_VAL,    &preserve_links, 1, 0, 0 },
403   {"no-links",         0,  POPT_ARG_VAL,    &preserve_links, 0, 0, 0 },
404   {"no-l",             0,  POPT_ARG_VAL,    &preserve_links, 0, 0, 0 },
405   {"copy-links",      'L', POPT_ARG_NONE,   &copy_links, 0, 0, 0 },
406   {"copy-unsafe-links",0,  POPT_ARG_NONE,   &copy_unsafe_links, 0, 0, 0 },
407   {"safe-links",       0,  POPT_ARG_NONE,   &safe_symlinks, 0, 0, 0 },
408   {"keep-dirlinks",   'K', POPT_ARG_NONE,   &keep_dirlinks, 0, 0, 0 },
409   {"hard-links",      'H', POPT_ARG_NONE,   &preserve_hard_links, 0, 0, 0 },
410   {"relative",        'R', POPT_ARG_VAL,    &relative_paths, 1, 0, 0 },
411   {"no-relative",      0,  POPT_ARG_VAL,    &relative_paths, 0, 0, 0 },
412   {"no-R",             0,  POPT_ARG_VAL,    &relative_paths, 0, 0, 0 },
413   {"no-implied-dirs",  0,  POPT_ARG_VAL,    &implied_dirs, 0, 0, 0 },
414   {"ignore-times",    'I', POPT_ARG_NONE,   &ignore_times, 0, 0, 0 },
415   {"size-only",        0,  POPT_ARG_NONE,   &size_only, 0, 0, 0 },
416   {"one-file-system", 'x', POPT_ARG_NONE,   &one_file_system, 0, 0, 0 },
417   {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
418   {"existing",         0,  POPT_ARG_NONE,   &ignore_non_existing, 0, 0, 0 },
419   {"ignore-existing",  0,  POPT_ARG_NONE,   &ignore_existing, 0, 0, 0 },
420   {"ignore-non-existing",0,POPT_ARG_NONE,   &ignore_non_existing, 0, 0, 0 },
421   {"max-size",         0,  POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
422   {"sparse",          'S', POPT_ARG_NONE,   &sparse_files, 0, 0, 0 },
423   {"inplace",          0,  POPT_ARG_NONE,   &inplace, 0, 0, 0 },
424   {"append",           0,  POPT_ARG_VAL,    &append_mode, 1, 0, 0 },
425   {"del",              0,  POPT_ARG_NONE,   &delete_during, 0, 0, 0 },
426   {"delete",           0,  POPT_ARG_NONE,   &delete_mode, 0, 0, 0 },
427   {"delete-before",    0,  POPT_ARG_VAL,    &delete_before, 2, 0, 0 },
428   {"delete-during",    0,  POPT_ARG_NONE,   &delete_during, 0, 0, 0 },
429   {"delete-after",     0,  POPT_ARG_NONE,   &delete_after, 0, 0, 0 },
430   {"delete-excluded",  0,  POPT_ARG_NONE,   &delete_excluded, 0, 0, 0 },
431   {"remove-sent-files",0,  POPT_ARG_NONE,   &remove_sent_files, 0, 0, 0 },
432   {"force",            0,  POPT_ARG_NONE,   &force_delete, 0, 0, 0 },
433   {"ignore-errors",    0,  POPT_ARG_NONE,   &ignore_errors, 0, 0, 0 },
434   {"max-delete",       0,  POPT_ARG_INT,    &max_delete, 0, 0, 0 },
435   {0,                 'F', POPT_ARG_NONE,   0, 'F', 0, 0 },
436   {"filter",          'f', POPT_ARG_STRING, 0, OPT_FILTER, 0, 0 },
437   {"exclude",          0,  POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
438   {"include",          0,  POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
439   {"exclude-from",     0,  POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
440   {"include-from",     0,  POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
441   {"cvs-exclude",     'C', POPT_ARG_NONE,   &cvs_exclude, 0, 0, 0 },
442   {"whole-file",      'W', POPT_ARG_VAL,    &whole_file, 1, 0, 0 },
443   {"no-whole-file",    0,  POPT_ARG_VAL,    &whole_file, 0, 0, 0 },
444   {"no-W",             0,  POPT_ARG_VAL,    &whole_file, 0, 0, 0 },
445   {"checksum",        'c', POPT_ARG_NONE,   &always_checksum, 0, 0, 0 },
446   {"block-size",      'B', POPT_ARG_LONG,   &block_size, 0, 0, 0 },
447   {"compare-dest",     0,  POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
448   {"copy-dest",        0,  POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
449   {"link-dest",        0,  POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
450   {"fuzzy",           'y', POPT_ARG_NONE,   &fuzzy_basis, 0, 0, 0 },
451   {"compress",        'z', POPT_ARG_NONE,   &do_compression, 0, 0, 0 },
452   {0,                 'P', POPT_ARG_NONE,   0, 'P', 0, 0 },
453   {"progress",         0,  POPT_ARG_VAL,    &do_progress, 1, 0, 0 },
454   {"no-progress",      0,  POPT_ARG_VAL,    &do_progress, 0, 0, 0 },
455   {"partial",          0,  POPT_ARG_VAL,    &keep_partial, 1, 0, 0 },
456   {"no-partial",       0,  POPT_ARG_VAL,    &keep_partial, 0, 0, 0 },
457   {"partial-dir",      0,  POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
458   {"delay-updates",    0,  POPT_ARG_NONE,   &delay_updates, 0, 0, 0 },
459   {"log-format",       0,  POPT_ARG_STRING, &log_format, 0, 0, 0 },
460   {"itemize-changes", 'i', POPT_ARG_NONE,   &itemize_changes, 0, 0, 0 },
461   {"bwlimit",          0,  POPT_ARG_INT,    &bwlimit, 0, 0, 0 },
462   {"backup",          'b', POPT_ARG_NONE,   &make_backups, 0, 0, 0 },
463   {"backup-dir",       0,  POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
464   {"suffix",           0,  POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
465   {"list-only",        0,  POPT_ARG_VAL,    &list_only, 2, 0, 0 },
466   {"read-batch",       0,  POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
467   {"write-batch",      0,  POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
468   {"only-write-batch", 0,  POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 },
469   {"files-from",       0,  POPT_ARG_STRING, &files_from, 0, 0, 0 },
470   {"from0",           '0', POPT_ARG_NONE,   &eol_nulls, 0, 0, 0},
471   {"numeric-ids",      0,  POPT_ARG_NONE,   &numeric_ids, 0, 0, 0 },
472   {"timeout",          0,  POPT_ARG_INT,    &io_timeout, 0, 0, 0 },
473   {"rsh",             'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
474   {"rsync-path",       0,  POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
475   {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
476 #ifdef INET6
477   {"ipv4",            '4', POPT_ARG_VAL,    &default_af_hint, AF_INET, 0, 0 },
478   {"ipv6",            '6', POPT_ARG_VAL,    &default_af_hint, AF_INET6, 0, 0 },
479 #endif
480   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
481   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
482   {"password-file",    0,  POPT_ARG_STRING, &password_file, 0, 0, 0 },
483   {"blocking-io",      0,  POPT_ARG_VAL,    &blocking_io, 1, 0, 0 },
484   {"no-blocking-io",   0,  POPT_ARG_VAL,    &blocking_io, 0, 0, 0 },
485   {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
486   {"checksum-seed",    0,  POPT_ARG_INT,    &checksum_seed, 0, 0, 0 },
487   {"server",           0,  POPT_ARG_NONE,   &am_server, 0, 0, 0 },
488   {"sender",           0,  POPT_ARG_NONE,   0, OPT_SENDER, 0, 0 },
489   /* All the following options switch us into daemon-mode option-parsing. */
490   {"config",           0,  POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
491   {"daemon",           0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
492   {"detach",           0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
493   {"no-detach",        0,  POPT_ARG_NONE,   0, OPT_DAEMON, 0, 0 },
494   {0,0,0,0, 0, 0, 0}
495 };
496
497 static void daemon_usage(enum logcode F)
498 {
499   print_rsync_version(F);
500
501   rprintf(F,"\nUsage: rsync --daemon [OPTION]...\n");
502   rprintf(F,"     --address=ADDRESS       bind to the specified address\n");
503   rprintf(F,"     --bwlimit=KBPS          limit I/O bandwidth; KBytes per second\n");
504   rprintf(F,"     --config=FILE           specify alternate rsyncd.conf file\n");
505   rprintf(F,"     --no-detach             do not detach from the parent\n");
506   rprintf(F,"     --port=PORT             listen on alternate port number\n");
507   rprintf(F," -v, --verbose               increase verbosity\n");
508 #ifdef INET6
509   rprintf(F," -4, --ipv4                  prefer IPv4\n");
510   rprintf(F," -6, --ipv6                  prefer IPv6\n");
511 #endif
512   rprintf(F," -h, --help                  show this help screen\n");
513
514   rprintf(F,"\nIf you were not trying to invoke rsync as a daemon, avoid using any of the\n");
515   rprintf(F,"daemon-specific rsync options.  See also the rsyncd.conf(5) man page.\n");
516 }
517
518 static struct poptOption long_daemon_options[] = {
519   /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
520   {"address",          0,  POPT_ARG_STRING, &bind_address, 0, 0, 0 },
521   {"bwlimit",          0,  POPT_ARG_INT,    &daemon_bwlimit, 0, 0, 0 },
522   {"config",           0,  POPT_ARG_STRING, &config_file, 0, 0, 0 },
523   {"daemon",           0,  POPT_ARG_NONE,   &daemon_opt, 0, 0, 0 },
524 #ifdef INET6
525   {"ipv4",            '4', POPT_ARG_VAL,    &default_af_hint, AF_INET, 0, 0 },
526   {"ipv6",            '6', POPT_ARG_VAL,    &default_af_hint, AF_INET6, 0, 0 },
527 #endif
528   {"detach",           0,  POPT_ARG_VAL,    &no_detach, 0, 0, 0 },
529   {"no-detach",        0,  POPT_ARG_VAL,    &no_detach, 1, 0, 0 },
530   {"port",             0,  POPT_ARG_INT,    &rsync_port, 0, 0, 0 },
531   {"protocol",         0,  POPT_ARG_INT,    &protocol_version, 0, 0, 0 },
532   {"server",           0,  POPT_ARG_NONE,   &am_server, 0, 0, 0 },
533   {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
534   {"verbose",         'v', POPT_ARG_NONE,   0, 'v', 0, 0 },
535   {"no-verbose",       0,  POPT_ARG_VAL,    &verbose, 0, 0, 0 },
536   {"no-v",             0,  POPT_ARG_VAL,    &verbose, 0, 0, 0 },
537   {"help",            'h', POPT_ARG_NONE,   0, 'h', 0, 0 },
538   {0,0,0,0, 0, 0, 0}
539 };
540
541
542 static char err_buf[200];
543
544
545 /**
546  * Store the option error message, if any, so that we can log the
547  * connection attempt (which requires parsing the options), and then
548  * show the error later on.
549  **/
550 void option_error(void)
551 {
552         if (!err_buf[0]) {
553                 strcpy(err_buf, "Error parsing options: "
554                     "option may be supported on client but not on server?\n");
555         }
556
557         rprintf(FERROR, RSYNC_NAME ": %s", err_buf);
558 }
559
560
561 /**
562  * Tweak the option table to disable all options that the rsyncd.conf
563  * file has told us to refuse.
564  **/
565 static void set_refuse_options(char *bp)
566 {
567         struct poptOption *op;
568         char *cp, shortname[2];
569         int is_wild, found_match;
570
571         shortname[1] = '\0';
572
573         while (1) {
574                 while (*bp == ' ') bp++;
575                 if (!*bp)
576                         break;
577                 if ((cp = strchr(bp, ' ')) != NULL)
578                         *cp= '\0';
579                 is_wild = strpbrk(bp, "*?[") != NULL;
580                 found_match = 0;
581                 for (op = long_options; ; op++) {
582                         *shortname = op->shortName;
583                         if (!op->longName && !*shortname)
584                                 break;
585                         if ((op->longName && wildmatch(bp, op->longName))
586                             || (*shortname && wildmatch(bp, shortname))) {
587                                 if (op->argInfo == POPT_ARG_VAL)
588                                         op->argInfo = POPT_ARG_NONE;
589                                 op->val = (op - long_options) + OPT_REFUSED_BASE;
590                                 found_match = 1;
591                                 /* These flags are set to let us easily check
592                                  * an implied option later in the code. */
593                                 switch (*shortname) {
594                                 case 'r': case 'd': case 'l': case 'p':
595                                 case 't': case 'g': case 'o': case 'D':
596                                         refused_archive_part = op->val;
597                                         break;
598                                 case '\0':
599                                         if (wildmatch("delete", op->longName))
600                                                 refused_delete = op->val;
601                                         else if (wildmatch("delete-before", op->longName))
602                                                 refused_delete_before = op->val;
603                                         else if (wildmatch("partial", op->longName))
604                                                 refused_partial = op->val;
605                                         else if (wildmatch("progress", op->longName))
606                                                 refused_progress = op->val;
607                                         else if (wildmatch("inplace", op->longName))
608                                                 refused_inplace = op->val;
609                                         break;
610                                 }
611                                 if (!is_wild)
612                                         break;
613                         }
614                 }
615                 if (!found_match) {
616                         rprintf(FLOG, "No match for refuse-options string \"%s\"\n",
617                                 bp);
618                 }
619                 if (!cp)
620                         break;
621                 *cp = ' ';
622                 bp = cp + 1;
623         }
624
625         for (op = long_options; ; op++) {
626                 *shortname = op->shortName;
627                 if (!op->longName && !*shortname)
628                         break;
629                 if (op->val == OPT_DAEMON) {
630                         if (op->argInfo == POPT_ARG_VAL)
631                                 op->argInfo = POPT_ARG_NONE;
632                         op->val = (op - long_options) + OPT_REFUSED_BASE;
633                 }
634         }
635 }
636
637
638 static int count_args(const char **argv)
639 {
640         int i = 0;
641
642         if (argv) {
643                 while (argv[i] != NULL)
644                         i++;
645         }
646
647         return i;
648 }
649
650
651 static OFF_T parse_size_arg(char **size_arg, char def_suf)
652 {
653         int mult, make_compatible = 0;
654         const char *arg, *p;
655         OFF_T size = 0;
656
657         for (arg = *size_arg; isdigit(*(uchar*)arg); arg++) {}
658         if (*arg == '.')
659                 for (arg++; isdigit(*(uchar*)arg); arg++) {}
660         if (*arg && (arg[1] == 't' || arg[1] == 'T'))
661                 mult = 1000, make_compatible = 1;
662         else
663                 mult = 1024;
664         if ((p = strstr(arg, "+1")) != NULL
665          || (p = strstr(arg, "-1")) != NULL) {
666                 if (p[2] == '\0') {
667                         size = atoi(p + (*p == '+'));
668                         make_compatible = 1;
669                 } else
670                         p = NULL;
671         }
672         switch (*arg && arg != p ? *arg : def_suf) {
673         case 'b': case 'B':
674                 size += atof(*size_arg);
675                 break;
676         case 'k': case 'K':
677                 size += atof(*size_arg) * mult;
678                 break;
679         case 'm': case 'M':
680                 size += atof(*size_arg) * mult*mult;
681                 break;
682         case 'g': case 'G':
683                 size += atof(*size_arg) * mult*mult*mult;
684                 break;
685         default:
686                 size = -1;
687                 break;
688         }
689         if (size > 0 && make_compatible) {
690                 /* We convert this manually because we many need %lld
691                  * precision, and that's not portable. */
692                 char buf[128], *s = buf + sizeof buf;
693                 OFF_T num = size;
694                 *--s = '\0';
695                 while (num) {
696                         if (s == buf) /* impossible... */
697                                 out_of_memory("parse_size_arg@buf");
698                         *--s = (num % 10) + '0';
699                         num /= 10;
700                 }
701                 if (!(*size_arg = strdup(s)))
702                         out_of_memory("parse_size_arg");
703         }
704         return size;
705 }
706
707
708 static void create_refuse_error(int which)
709 {
710         /* The "which" value is the index + OPT_REFUSED_BASE. */
711         struct poptOption *op = &long_options[which - OPT_REFUSED_BASE];
712         int n = snprintf(err_buf, sizeof err_buf,
713                          "The server is configured to refuse --%s\n",
714                          op->longName) - 1;
715         if (op->shortName) {
716                 snprintf(err_buf + n, sizeof err_buf - n,
717                          " (-%c)\n", op->shortName);
718         }
719 }
720
721
722 /**
723  * Process command line arguments.  Called on both local and remote.
724  *
725  * @retval 1 if all options are OK; with globals set to appropriate
726  * values
727  *
728  * @retval 0 on error, with err_buf containing an explanation
729  **/
730 int parse_arguments(int *argc, const char ***argv, int frommain)
731 {
732         int opt;
733         char *ref = lp_refuse_options(module_id);
734         const char *arg;
735         poptContext pc;
736
737         if (ref && *ref)
738                 set_refuse_options(ref);
739
740         /* TODO: Call poptReadDefaultConfig; handle errors. */
741
742         /* The context leaks in case of an error, but if there's a
743          * problem we always exit anyhow. */
744         pc = poptGetContext(RSYNC_NAME, *argc, *argv, long_options, 0);
745         poptReadDefaultConfig(pc, 0);
746
747         while ((opt = poptGetNextOpt(pc)) != -1) {
748                 /* most options are handled automatically by popt;
749                  * only special cases are returned and listed here. */
750
751                 switch (opt) {
752                 case OPT_VERSION:
753                         print_rsync_version(FINFO);
754                         exit_cleanup(0);
755
756                 case OPT_DAEMON:
757                         if (am_daemon) {
758                                 strcpy(err_buf, "Attempt to hack rsync thwarted!\n");
759                                 return 0;
760                         }
761                         poptFreeContext(pc);
762                         pc = poptGetContext(RSYNC_NAME, *argc, *argv,
763                                             long_daemon_options, 0);
764                         while ((opt = poptGetNextOpt(pc)) != -1) {
765                                 switch (opt) {
766                                 case 'h':
767                                         daemon_usage(FINFO);
768                                         exit_cleanup(0);
769
770                                 case 'v':
771                                         verbose++;
772                                         break;
773
774                                 default:
775                                         rprintf(FERROR,
776                                             "rsync: %s: %s (in daemon mode)\n",
777                                             poptBadOption(pc, POPT_BADOPTION_NOALIAS),
778                                             poptStrerror(opt));
779                                         goto daemon_error;
780                                 }
781                         }
782
783                         if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
784                                 snprintf(err_buf, sizeof err_buf,
785                                          "the --temp-dir path is WAY too long.\n");
786                                 return 0;
787                         }
788
789                         if (!daemon_opt) {
790                                 rprintf(FERROR, "Daemon option(s) used without --daemon.\n");
791                             daemon_error:
792                                 rprintf(FERROR,
793                                     "(Type \"rsync --daemon --help\" for assistance with daemon mode.)\n");
794                                 exit_cleanup(RERR_SYNTAX);
795                         }
796
797                         *argv = poptGetArgs(pc);
798                         *argc = count_args(*argv);
799                         am_starting_up = 0;
800                         daemon_opt = 0;
801                         am_daemon = 1;
802                         return 1;
803
804                 case OPT_MODIFY_WINDOW:
805                         /* The value has already been set by popt, but
806                          * we need to remember that we're using a
807                          * non-default setting. */
808                         modify_window_set = 1;
809                         break;
810
811                 case OPT_FILTER:
812                         parse_rule(&filter_list, poptGetOptArg(pc), 0, 0);
813                         break;
814
815                 case OPT_EXCLUDE:
816                         parse_rule(&filter_list, poptGetOptArg(pc),
817                                    0, XFLG_OLD_PREFIXES);
818                         break;
819
820                 case OPT_INCLUDE:
821                         parse_rule(&filter_list, poptGetOptArg(pc),
822                                    MATCHFLG_INCLUDE, XFLG_OLD_PREFIXES);
823                         break;
824
825                 case OPT_EXCLUDE_FROM:
826                 case OPT_INCLUDE_FROM:
827                         arg = poptGetOptArg(pc);
828                         if (sanitize_paths)
829                                 arg = sanitize_path(NULL, arg, NULL, 0);
830                         if (server_filter_list.head) {
831                                 char *cp = (char *)arg;
832                                 if (!*cp)
833                                         goto options_rejected;
834                                 clean_fname(cp, 1);
835                                 if (check_filter(&server_filter_list, cp, 0) < 0)
836                                         goto options_rejected;
837                         }
838                         parse_filter_file(&filter_list, arg,
839                                 opt == OPT_INCLUDE_FROM ? MATCHFLG_INCLUDE : 0,
840                                 XFLG_FATAL_ERRORS | XFLG_OLD_PREFIXES);
841                         break;
842
843                 case 'a':
844                         if (refused_archive_part) {
845                                 create_refuse_error(refused_archive_part);
846                                 return 0;
847                         }
848                         if (!recurse) /* preserve recurse == 2 */
849                                 recurse = 1;
850 #ifdef SUPPORT_LINKS
851                         preserve_links = 1;
852 #endif
853                         preserve_perms = 1;
854                         preserve_times = 1;
855                         preserve_gid = 1;
856                         preserve_uid = 1;
857                         preserve_devices = 1;
858                         break;
859
860                 case 'h':
861                         usage(FINFO);
862                         exit_cleanup(0);
863
864                 case 'v':
865                         verbose++;
866                         break;
867
868                 case 'q':
869                         if (frommain)
870                                 quiet++;
871                         break;
872
873                 case OPT_SENDER:
874                         if (!am_server) {
875                                 usage(FERROR);
876                                 exit_cleanup(RERR_SYNTAX);
877                         }
878                         am_sender = 1;
879                         break;
880
881                 case 'F':
882                         switch (++F_option_cnt) {
883                         case 1:
884                                 parse_rule(&filter_list,": /.rsync-filter",0,0);
885                                 break;
886                         case 2:
887                                 parse_rule(&filter_list,"- .rsync-filter",0,0);
888                                 break;
889                         }
890                         break;
891
892                 case 'P':
893                         if (refused_partial || refused_progress) {
894                                 create_refuse_error(refused_partial
895                                     ? refused_partial : refused_progress);
896                                 return 0;
897                         }
898                         do_progress = 1;
899                         keep_partial = 1;
900                         break;
901
902                 case OPT_WRITE_BATCH:
903                         /* batch_name is already set */
904                         write_batch = 1;
905                         break;
906
907                 case OPT_ONLY_WRITE_BATCH:
908                         /* batch_name is already set */
909                         write_batch = -1;
910                         break;
911
912                 case OPT_READ_BATCH:
913                         /* batch_name is already set */
914                         read_batch = 1;
915                         break;
916
917                 case OPT_MAX_SIZE:
918                         if ((max_size = parse_size_arg(&max_size_arg, 'b')) <= 0) {
919                                 snprintf(err_buf, sizeof err_buf,
920                                         "--max-size value is invalid: %s\n",
921                                         max_size_arg);
922                                 return 0;
923                         }
924                         break;
925
926                 case OPT_LINK_DEST:
927 #ifdef HAVE_LINK
928                         link_dest = 1;
929                         dest_option = "--link-dest";
930                         goto set_dest_dir;
931 #else
932                         snprintf(err_buf, sizeof err_buf,
933                                  "hard links are not supported on this %s\n",
934                                  am_server ? "server" : "client");
935                         return 0;
936 #endif
937
938                 case OPT_COPY_DEST:
939                         copy_dest = 1;
940                         dest_option = "--copy-dest";
941                         goto set_dest_dir;
942
943                 case OPT_COMPARE_DEST:
944                         compare_dest = 1;
945                         dest_option = "--compare-dest";
946                 set_dest_dir:
947                         if (basis_dir_cnt >= MAX_BASIS_DIRS) {
948                                 snprintf(err_buf, sizeof err_buf,
949                                         "ERROR: at most %d %s args may be specified\n",
950                                         MAX_BASIS_DIRS, dest_option);
951                                 return 0;
952                         }
953                         arg = poptGetOptArg(pc);
954                         if (sanitize_paths)
955                                 arg = sanitize_path(NULL, arg, NULL, 0);
956                         basis_dir[basis_dir_cnt++] = (char *)arg;
957                         break;
958
959                 default:
960                         /* A large opt value means that set_refuse_options()
961                          * turned this option off. */
962                         if (opt >= OPT_REFUSED_BASE) {
963                                 create_refuse_error(opt);
964                                 return 0;
965                         }
966                         snprintf(err_buf, sizeof err_buf, "%s%s: %s\n",
967                                  am_server ? "on remote machine: " : "",
968                                  poptBadOption(pc, POPT_BADOPTION_NOALIAS),
969                                  poptStrerror(opt));
970                         return 0;
971                 }
972         }
973
974 #ifndef SUPPORT_LINKS
975         if (preserve_links && !am_sender) {
976                 snprintf(err_buf, sizeof err_buf,
977                          "symlinks are not supported on this %s\n",
978                          am_server ? "server" : "client");
979                 return 0;
980         }
981 #endif
982
983 #ifndef SUPPORT_HARD_LINKS
984         if (preserve_hard_links) {
985                 snprintf(err_buf, sizeof err_buf,
986                          "hard links are not supported on this %s\n",
987                          am_server ? "server" : "client");
988                 return 0;
989         }
990 #endif
991
992         if (write_batch && read_batch) {
993                 snprintf(err_buf, sizeof err_buf,
994                         "--write-batch and --read-batch can not be used together\n");
995                 return 0;
996         }
997         if (write_batch > 0 || read_batch) {
998                 if (am_server) {
999                         rprintf(FINFO,
1000                                 "ignoring --%s-batch option sent to server\n",
1001                                 write_batch ? "write" : "read");
1002                         /* We don't actually exit_cleanup(), so that we can
1003                          * still service older version clients that still send
1004                          * batch args to server. */
1005                         read_batch = write_batch = 0;
1006                         batch_name = NULL;
1007                 } else if (dry_run)
1008                         write_batch = 0;
1009         }
1010         if (read_batch && files_from) {
1011                 snprintf(err_buf, sizeof err_buf,
1012                         "--read-batch cannot be used with --files-from\n");
1013                 return 0;
1014         }
1015         if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
1016                 snprintf(err_buf, sizeof err_buf,
1017                         "the batch-file name must be %d characters or less.\n",
1018                         MAX_BATCH_NAME_LEN);
1019                 return 0;
1020         }
1021
1022         if (tmpdir && strlen(tmpdir) >= MAXPATHLEN - 10) {
1023                 snprintf(err_buf, sizeof err_buf,
1024                          "the --temp-dir path is WAY too long.\n");
1025                 return 0;
1026         }
1027
1028         if (compare_dest + copy_dest + link_dest > 1) {
1029                 snprintf(err_buf, sizeof err_buf,
1030                         "You may not mix --compare-dest, --copy-dest, and --link-dest.\n");
1031                 return 0;
1032         }
1033
1034         if (files_from) {
1035                 if (recurse == 1) /* preserve recurse == 2 */
1036                         recurse = 0;
1037                 if (xfer_dirs < 0)
1038                         xfer_dirs = 1;
1039         }
1040
1041         if (xfer_dirs < 1)
1042                 xfer_dirs = recurse || list_only;
1043
1044         if (relative_paths < 0)
1045                 relative_paths = files_from? 1 : 0;
1046         if (!relative_paths)
1047                 implied_dirs = 0;
1048
1049         if (!!delete_before + delete_during + delete_after > 1) {
1050                 snprintf(err_buf, sizeof err_buf,
1051                         "You may not combine multiple --delete-WHEN options.\n");
1052                 return 0;
1053         }
1054         if (!xfer_dirs) {
1055                 delete_before = delete_during = delete_after = 0;
1056                 delete_mode = delete_excluded = 0;
1057         } else if (delete_before || delete_during || delete_after)
1058                 delete_mode = 1;
1059         else if (delete_mode || delete_excluded) {
1060                 if (refused_delete_before) {
1061                         create_refuse_error(refused_delete_before);
1062                         return 0;
1063                 }
1064                 delete_mode = delete_before = 1;
1065         }
1066
1067         if (delete_mode && refused_delete) {
1068                 create_refuse_error(refused_delete);
1069                 return 0;
1070         }
1071
1072         if (remove_sent_files) {
1073                 /* We only want to infer this refusal of --remove-sent-files
1074                  * via the refusal of "delete", not any of the "delete-FOO"
1075                  * options. */
1076                 if (refused_delete && am_sender) {
1077                         create_refuse_error(refused_delete);
1078                         return 0;
1079                 }
1080                 need_messages_from_generator = 1;
1081         }
1082
1083         *argv = poptGetArgs(pc);
1084         *argc = count_args(*argv);
1085
1086         if (sanitize_paths) {
1087                 int i;
1088                 for (i = *argc; i-- > 0; )
1089                         (*argv)[i] = sanitize_path(NULL, (*argv)[i], "", 0);
1090                 if (tmpdir)
1091                         tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
1092                 if (partial_dir)
1093                         partial_dir = sanitize_path(NULL, partial_dir, NULL, 0);
1094                 if (backup_dir)
1095                         backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
1096         }
1097         if (server_filter_list.head && !am_sender) {
1098                 struct filter_list_struct *elp = &server_filter_list;
1099                 int i;
1100                 if (tmpdir) {
1101                         if (!*tmpdir)
1102                                 goto options_rejected;
1103                         clean_fname(tmpdir, 1);
1104                         if (check_filter(elp, tmpdir, 1) < 0)
1105                                 goto options_rejected;
1106                 }
1107                 if (partial_dir && *partial_dir) {
1108                         clean_fname(partial_dir, 1);
1109                         if (check_filter(elp, partial_dir, 1) < 0)
1110                                 goto options_rejected;
1111                 }
1112                 for (i = 0; i < basis_dir_cnt; i++) {
1113                         if (!*basis_dir[i])
1114                                 goto options_rejected;
1115                         clean_fname(basis_dir[i], 1);
1116                         if (check_filter(elp, basis_dir[i], 1) < 0)
1117                                 goto options_rejected;
1118                 }
1119                 if (backup_dir) {
1120                         if (!*backup_dir)
1121                                 goto options_rejected;
1122                         clean_fname(backup_dir, 1);
1123                         if (check_filter(elp, backup_dir, 1) < 0) {
1124                             options_rejected:
1125                                 snprintf(err_buf, sizeof err_buf,
1126                                     "Your options have been rejected by the server.\n");
1127                                 return 0;
1128                         }
1129                 }
1130         }
1131
1132         if (!backup_suffix)
1133                 backup_suffix = backup_dir ? "" : BACKUP_SUFFIX;
1134         backup_suffix_len = strlen(backup_suffix);
1135         if (strchr(backup_suffix, '/') != NULL) {
1136                 snprintf(err_buf, sizeof err_buf,
1137                         "--suffix cannot contain slashes: %s\n",
1138                         backup_suffix);
1139                 return 0;
1140         }
1141         if (backup_dir) {
1142                 backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
1143                 backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
1144                 if (backup_dir_remainder < 32) {
1145                         snprintf(err_buf, sizeof err_buf,
1146                                 "the --backup-dir path is WAY too long.\n");
1147                         return 0;
1148                 }
1149                 if (backup_dir_buf[backup_dir_len - 1] != '/') {
1150                         backup_dir_buf[backup_dir_len++] = '/';
1151                         backup_dir_buf[backup_dir_len] = '\0';
1152                 }
1153                 if (verbose > 1 && !am_sender) {
1154                         rprintf(FINFO, "backup_dir is %s\n",
1155                                 safe_fname(backup_dir_buf));
1156                 }
1157         } else if (!backup_suffix_len && (!am_server || !am_sender)) {
1158                 snprintf(err_buf, sizeof err_buf,
1159                         "--suffix cannot be a null string without --backup-dir\n");
1160                 return 0;
1161         }
1162         if (make_backups && !backup_dir)
1163                 omit_dir_times = 1;
1164
1165         if (log_format) {
1166                 if (log_format_has(log_format, 'i'))
1167                         log_format_has_i = 1;
1168                 if (!log_format_has(log_format, 'b')
1169                  && !log_format_has(log_format, 'c'))
1170                         log_before_transfer = !am_server;
1171         } else if (itemize_changes) {
1172                 log_format = "%i %n%L";
1173                 log_format_has_i = 1;
1174                 log_before_transfer = !am_server;
1175         }
1176
1177         if ((do_progress || dry_run) && !verbose && !log_before_transfer
1178             && !am_server)
1179                 verbose = 1;
1180
1181         if (dry_run)
1182                 do_xfers = 0;
1183
1184         set_io_timeout(io_timeout);
1185
1186         if (verbose && !log_format) {
1187                 log_format = "%n%L";
1188                 log_before_transfer = !am_server;
1189         }
1190         if (log_format_has_i || log_format_has(log_format, 'o'))
1191                 log_format_has_o_or_i = 1;
1192
1193         if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
1194                 bwlimit = daemon_bwlimit;
1195         if (bwlimit) {
1196                 bwlimit_writemax = (size_t)bwlimit * 128;
1197                 if (bwlimit_writemax < 512)
1198                         bwlimit_writemax = 512;
1199         }
1200
1201         if (sparse_files && inplace) {
1202                 /* Note: we don't check for this below, because --append is
1203                  * OK with --sparse (as long as redos are handled right). */
1204                 snprintf(err_buf, sizeof err_buf,
1205                          "--sparse cannot be used with --inplace\n");
1206                 return 0;
1207         }
1208
1209         if (append_mode) {
1210                 if (whole_file > 0) {
1211                         snprintf(err_buf, sizeof err_buf,
1212                                  "--append cannot be used with --whole-file\n");
1213                         return 0;
1214                 }
1215                 if (refused_inplace) {
1216                         create_refuse_error(refused_inplace);
1217                         return 0;
1218                 }
1219                 inplace = 1;
1220         }
1221
1222         if (delay_updates && !partial_dir)
1223                 partial_dir = partialdir_for_delayupdate;
1224
1225         if (inplace) {
1226 #ifdef HAVE_FTRUNCATE
1227                 if (partial_dir) {
1228                         snprintf(err_buf, sizeof err_buf,
1229                                  "--%s cannot be used with --%s\n",
1230                                  append_mode ? "append" : "inplace",
1231                                  delay_updates ? "delay-updates" : "partial-dir");
1232                         return 0;
1233                 }
1234                 /* --inplace implies --partial for refusal purposes, but we
1235                  * clear the keep_partial flag for internal logic purposes. */
1236                 if (refused_partial) {
1237                         create_refuse_error(refused_partial);
1238                         return 0;
1239                 }
1240                 keep_partial = 0;
1241 #else
1242                 snprintf(err_buf, sizeof err_buf,
1243                          "--%s is not supported on this %s\n",
1244                          append_mode ? "append" : "inplace",
1245                          am_server ? "server" : "client");
1246                 return 0;
1247 #endif
1248         } else {
1249                 if (keep_partial && !partial_dir) {
1250                         if ((arg = getenv("RSYNC_PARTIAL_DIR")) != NULL && *arg)
1251                                 partial_dir = strdup(arg);
1252                 }
1253                 if (partial_dir) {
1254                         if (*partial_dir)
1255                                 clean_fname(partial_dir, 1);
1256                         if (!*partial_dir || strcmp(partial_dir, ".") == 0)
1257                                 partial_dir = NULL;
1258                         else if (*partial_dir != '/') {
1259                                 parse_rule(&filter_list, partial_dir,
1260                                     MATCHFLG_NO_PREFIXES|MATCHFLG_DIRECTORY, 0);
1261                         }
1262                         if (!partial_dir && refused_partial) {
1263                                 create_refuse_error(refused_partial);
1264                                 return 0;
1265                         }
1266                         keep_partial = 1;
1267                 }
1268         }
1269
1270         if (files_from) {
1271                 char *h, *p;
1272                 int q;
1273                 if (*argc > 2 || (!am_daemon && *argc == 1)) {
1274                         usage(FERROR);
1275                         exit_cleanup(RERR_SYNTAX);
1276                 }
1277                 if (strcmp(files_from, "-") == 0) {
1278                         filesfrom_fd = 0;
1279                         if (am_server)
1280                                 filesfrom_host = ""; /* reading from socket */
1281                 } else if ((p = check_for_hostspec(files_from, &h, &q)) != 0) {
1282                         if (am_server) {
1283                                 snprintf(err_buf, sizeof err_buf,
1284                                         "The --files-from sent to the server cannot specify a host.\n");
1285                                 return 0;
1286                         }
1287                         files_from = p;
1288                         filesfrom_host = h;
1289                         if (strcmp(files_from, "-") == 0) {
1290                                 snprintf(err_buf, sizeof err_buf,
1291                                         "Invalid --files-from remote filename\n");
1292                                 return 0;
1293                         }
1294                 } else {
1295                         if (sanitize_paths)
1296                                 files_from = sanitize_path(NULL, files_from, NULL, 0);
1297                         if (server_filter_list.head) {
1298                                 if (!*files_from)
1299                                         goto options_rejected;
1300                                 clean_fname(files_from, 1);
1301                                 if (check_filter(&server_filter_list, files_from, 0) < 0)
1302                                         goto options_rejected;
1303                         }
1304                         filesfrom_fd = open(files_from, O_RDONLY|O_BINARY);
1305                         if (filesfrom_fd < 0) {
1306                                 snprintf(err_buf, sizeof err_buf,
1307                                         "failed to open files-from file %s: %s\n",
1308                                         files_from, strerror(errno));
1309                                 return 0;
1310                         }
1311                 }
1312         }
1313
1314         am_starting_up = 0;
1315
1316         return 1;
1317 }
1318
1319
1320 /**
1321  * Construct a filtered list of options to pass through from the
1322  * client to the server.
1323  *
1324  * This involves setting options that will tell the server how to
1325  * behave, and also filtering out options that are processed only
1326  * locally.
1327  **/
1328 void server_options(char **args,int *argc)
1329 {
1330         static char argstr[64];
1331         int ac = *argc;
1332         char *arg;
1333
1334         int i, x;
1335
1336         if (blocking_io == -1)
1337                 blocking_io = 0;
1338
1339         args[ac++] = "--server";
1340
1341         if (daemon_over_rsh) {
1342                 args[ac++] = "--daemon";
1343                 *argc = ac;
1344                 /* if we're passing --daemon, we're done */
1345                 return;
1346         }
1347
1348         if (!am_sender)
1349                 args[ac++] = "--sender";
1350
1351         x = 1;
1352         argstr[0] = '-';
1353         for (i = 0; i < verbose; i++)
1354                 argstr[x++] = 'v';
1355
1356         /* the -q option is intentionally left out */
1357         if (make_backups)
1358                 argstr[x++] = 'b';
1359         if (update_only)
1360                 argstr[x++] = 'u';
1361         if (!do_xfers) /* NOT "dry_run"! */
1362                 argstr[x++] = 'n';
1363         if (preserve_links)
1364                 argstr[x++] = 'l';
1365         if (copy_links)
1366                 argstr[x++] = 'L';
1367         if (xfer_dirs > 1)
1368                 argstr[x++] = 'd';
1369         if (keep_dirlinks && am_sender)
1370                 argstr[x++] = 'K';
1371
1372         if (whole_file > 0)
1373                 argstr[x++] = 'W';
1374         /* We don't need to send --no-whole-file, because it's the
1375          * default for remote transfers, and in any case old versions
1376          * of rsync will not understand it. */
1377
1378         if (preserve_hard_links)
1379                 argstr[x++] = 'H';
1380         if (preserve_uid)
1381                 argstr[x++] = 'o';
1382         if (preserve_gid)
1383                 argstr[x++] = 'g';
1384         if (preserve_devices)
1385                 argstr[x++] = 'D';
1386         if (preserve_times)
1387                 argstr[x++] = 't';
1388         if (omit_dir_times == 2 && am_sender)
1389                 argstr[x++] = 'O';
1390         if (preserve_perms)
1391                 argstr[x++] = 'p';
1392         if (recurse)
1393                 argstr[x++] = 'r';
1394         if (always_checksum)
1395                 argstr[x++] = 'c';
1396         if (cvs_exclude)
1397                 argstr[x++] = 'C';
1398         if (ignore_times)
1399                 argstr[x++] = 'I';
1400         if (relative_paths)
1401                 argstr[x++] = 'R';
1402         if (one_file_system)
1403                 argstr[x++] = 'x';
1404         if (sparse_files)
1405                 argstr[x++] = 'S';
1406         if (do_compression)
1407                 argstr[x++] = 'z';
1408
1409         /* This is a complete hack - blame Rusty.  FIXME!
1410          * This hack is only needed for older rsync versions that
1411          * don't understand the --list-only option. */
1412         if (list_only == 1 && !recurse)
1413                 argstr[x++] = 'r';
1414
1415         argstr[x] = 0;
1416
1417         if (x != 1)
1418                 args[ac++] = argstr;
1419
1420         if (list_only > 1)
1421                 args[ac++] = "--list-only";
1422
1423         /* The server side doesn't use our log-format, but in certain
1424          * circumstances they need to know a little about the option. */
1425         if (log_format && am_sender) {
1426                 if (log_format_has_i)
1427                         args[ac++] = "--log-format=%i";
1428                 else if (log_format_has_o_or_i)
1429                         args[ac++] = "--log-format=%o";
1430                 else if (!verbose)
1431                         args[ac++] = "--log-format=X";
1432         }
1433
1434         if (block_size) {
1435                 if (asprintf(&arg, "-B%lu", block_size) < 0)
1436                         goto oom;
1437                 args[ac++] = arg;
1438         }
1439
1440         if (max_delete && am_sender) {
1441                 if (asprintf(&arg, "--max-delete=%d", max_delete) < 0)
1442                         goto oom;
1443                 args[ac++] = arg;
1444         }
1445
1446         if (max_size && am_sender) {
1447                 args[ac++] = "--max-size";
1448                 args[ac++] = max_size_arg;
1449         }
1450
1451         if (io_timeout) {
1452                 if (asprintf(&arg, "--timeout=%d", io_timeout) < 0)
1453                         goto oom;
1454                 args[ac++] = arg;
1455         }
1456
1457         if (bwlimit) {
1458                 if (asprintf(&arg, "--bwlimit=%d", bwlimit) < 0)
1459                         goto oom;
1460                 args[ac++] = arg;
1461         }
1462
1463         if (backup_dir) {
1464                 args[ac++] = "--backup-dir";
1465                 args[ac++] = backup_dir;
1466         }
1467
1468         /* Only send --suffix if it specifies a non-default value. */
1469         if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
1470                 /* We use the following syntax to avoid weirdness with '~'. */
1471                 if (asprintf(&arg, "--suffix=%s", backup_suffix) < 0)
1472                         goto oom;
1473                 args[ac++] = arg;
1474         }
1475
1476         if (am_sender) {
1477                 if (delete_excluded)
1478                         args[ac++] = "--delete-excluded";
1479                 else if (delete_before == 1 || delete_after)
1480                         args[ac++] = "--delete";
1481                 if (delete_before > 1)
1482                         args[ac++] = "--delete-before";
1483                 if (delete_during)
1484                         args[ac++] = "--delete-during";
1485                 if (delete_after)
1486                         args[ac++] = "--delete-after";
1487                 if (force_delete)
1488                         args[ac++] = "--force";
1489                 if (write_batch < 0)
1490                         args[ac++] = "--only-write-batch=X";
1491         }
1492
1493         if (size_only)
1494                 args[ac++] = "--size-only";
1495
1496         if (modify_window_set) {
1497                 if (asprintf(&arg, "--modify-window=%d", modify_window) < 0)
1498                         goto oom;
1499                 args[ac++] = arg;
1500         }
1501
1502         if (checksum_seed) {
1503                 if (asprintf(&arg, "--checksum-seed=%d", checksum_seed) < 0)
1504                         goto oom;
1505                 args[ac++] = arg;
1506         }
1507
1508         if (partial_dir && am_sender) {
1509                 if (partial_dir != partialdir_for_delayupdate) {
1510                         args[ac++] = "--partial-dir";
1511                         args[ac++] = partial_dir;
1512                 }
1513                 if (delay_updates)
1514                         args[ac++] = "--delay-updates";
1515         } else if (keep_partial)
1516                 args[ac++] = "--partial";
1517
1518         if (ignore_errors)
1519                 args[ac++] = "--ignore-errors";
1520
1521         if (copy_unsafe_links)
1522                 args[ac++] = "--copy-unsafe-links";
1523
1524         if (safe_symlinks)
1525                 args[ac++] = "--safe-links";
1526
1527         if (numeric_ids)
1528                 args[ac++] = "--numeric-ids";
1529
1530         if (ignore_existing && am_sender)
1531                 args[ac++] = "--ignore-existing";
1532
1533         /* Backward compatibility: send --existing, not --ignore-non-existing. */
1534         if (ignore_non_existing && am_sender)
1535                 args[ac++] = "--existing";
1536
1537         if (append_mode)
1538                 args[ac++] = "--append";
1539         else if (inplace)
1540                 args[ac++] = "--inplace";
1541
1542         if (tmpdir) {
1543                 args[ac++] = "--temp-dir";
1544                 args[ac++] = tmpdir;
1545         }
1546
1547         if (basis_dir[0] && am_sender) {
1548                 /* the server only needs this option if it is not the sender,
1549                  *   and it may be an older version that doesn't know this
1550                  *   option, so don't send it if client is the sender.
1551                  */
1552                 int i;
1553                 for (i = 0; i < basis_dir_cnt; i++) {
1554                         args[ac++] = dest_option;
1555                         args[ac++] = basis_dir[i];
1556                 }
1557         }
1558
1559         if (files_from && (!am_sender || filesfrom_host)) {
1560                 if (filesfrom_host) {
1561                         args[ac++] = "--files-from";
1562                         args[ac++] = files_from;
1563                         if (eol_nulls)
1564                                 args[ac++] = "--from0";
1565                 } else {
1566                         args[ac++] = "--files-from=-";
1567                         args[ac++] = "--from0";
1568                 }
1569                 if (!relative_paths)
1570                         args[ac++] = "--no-relative";
1571         }
1572         if (relative_paths && !implied_dirs && !am_sender)
1573                 args[ac++] = "--no-implied-dirs";
1574
1575         if (fuzzy_basis && am_sender)
1576                 args[ac++] = "--fuzzy";
1577
1578         if (remove_sent_files)
1579                 args[ac++] = "--remove-sent-files";
1580
1581         *argc = ac;
1582         return;
1583
1584     oom:
1585         out_of_memory("server_options");
1586 }
1587
1588 /* Look for a HOST specfication of the form "HOST:PATH", "HOST::PATH", or
1589  * "rsync://HOST:PORT/PATH".  If found, *host_ptr will be set to some allocated
1590  * memory with the HOST.  If a daemon-accessing spec was specified, the value
1591  * of *port_ptr will contain a non-0 port number, otherwise it will be set to
1592  * 0.  The return value is a pointer to the PATH.  Note that the HOST spec can
1593  * be an IPv6 literal address enclosed in '[' and ']' (such as "[::1]" or
1594  * "[::ffff:127.0.0.1]") which is returned without the '[' and ']'. */
1595 char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
1596 {
1597         char *p;
1598         int not_host;
1599
1600         if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) {
1601                 char *path;
1602                 int hostlen;
1603                 s += strlen(URL_PREFIX);
1604                 if ((p = strchr(s, '/')) != NULL) {
1605                         hostlen = p - s;
1606                         path = p + 1;
1607                 } else {
1608                         hostlen = strlen(s);
1609                         path = "";
1610                 }
1611                 if (*s == '[' && (p = strchr(s, ']')) != NULL) {
1612                         s++;
1613                         hostlen = p - s;
1614                         if (p[1] == ':')
1615                                 *port_ptr = atoi(p+2);
1616                 } else {
1617                         if ((p = strchr(s, ':')) != NULL) {
1618                                 hostlen = p - s;
1619                                 *port_ptr = atoi(p+1);
1620                         }
1621                 }
1622                 if (!*port_ptr)
1623                         *port_ptr = RSYNC_PORT;
1624                 *host_ptr = new_array(char, hostlen + 1);
1625                 strlcpy(*host_ptr, s, hostlen + 1);
1626                 return path;
1627         }
1628
1629         if (*s == '[' && (p = strchr(s, ']')) != NULL && p[1] == ':') {
1630                 s++;
1631                 *p = '\0';
1632                 not_host = strchr(s, '/') || !strchr(s, ':');
1633                 *p = ']';
1634                 if (not_host)
1635                         return NULL;
1636                 p++;
1637         } else {
1638                 if (!(p = strchr(s, ':')))
1639                         return NULL;
1640                 *p = '\0';
1641                 not_host = strchr(s, '/') != NULL;
1642                 *p = ':';
1643                 if (not_host)
1644                         return NULL;
1645         }
1646
1647         *host_ptr = new_array(char, p - s + 1);
1648         strlcpy(*host_ptr, s, p - s + 1);
1649
1650         if (p[1] == ':') {
1651                 if (port_ptr && !*port_ptr)
1652                         *port_ptr = RSYNC_PORT;
1653                 return p + 2;
1654         }
1655         if (port_ptr)
1656                 *port_ptr = 0;
1657
1658         return p + 1;
1659 }