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