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