*
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2000, 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2002-2009 Wayne Davison
+ * Copyright (C) 2002-2010 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */
int am_server = 0;
int am_sender = 0;
-int am_generator = 0;
int am_starting_up = 1;
int relative_paths = -1;
int implied_dirs = 1;
int allow_8bit_chars = 0;
int force_delete = 0;
int io_timeout = 0;
-int allowed_lull = 0;
int prune_empty_dirs = 0;
int use_qsort = 0;
char *files_from = NULL;
rprintf(f, "%s version %s protocol version %d%s\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
- rprintf(f, "Copyright (C) 1996-2009 by Andrew Tridgell, Wayne Davison, and others.\n");
+ rprintf(f, "Copyright (C) 1996-2010 by Andrew Tridgell, Wayne Davison, and others.\n");
rprintf(f, "Web site: http://rsync.samba.org/\n");
rprintf(f, "Capabilities:\n");
rprintf(f, " %d-bit files, %d-bit inums, %d-bit timestamps, %d-bit long ints,\n",
{"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
{"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
{"one-file-system", 'x', POPT_ARG_NONE, 0, 'x', 0, 0 },
- {"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
- {"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
+ {"no-one-file-system",0, POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
+ {"no-x", 0, POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
{"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
{"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
{"ignore-non-existing",0,POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
"--read-batch cannot be used with --files-from\n");
return 0;
}
+ if (read_batch && remove_source_files) {
+ snprintf(err_buf, sizeof err_buf,
+ "--read-batch cannot be used with --remove-%s-files\n",
+ remove_source_files == 1 ? "source" : "sent");
+ return 0;
+ }
if (batch_name && strlen(batch_name) > MAX_BATCH_NAME_LEN) {
snprintf(err_buf, sizeof err_buf,
"the batch-file name must be %d characters or less.\n",
}
if (!xfer_dirs && delete_mode) {
snprintf(err_buf, sizeof err_buf,
- "--delete does not work without -r or -d.\n");
+ "--delete does not work without --recursive (-r) or --dirs (-d).\n");
return 0;
}
return 0;
}
if (backup_dir) {
- backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
- backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
- if (backup_dir_remainder < 32) {
+ size_t len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
+ if (len > sizeof backup_dir_buf - 128) {
snprintf(err_buf, sizeof err_buf,
"the --backup-dir path is WAY too long.\n");
return 0;
}
+ backup_dir_len = (int)len;
if (backup_dir_buf[backup_dir_len - 1] != '/') {
backup_dir_buf[backup_dir_len++] = '/';
backup_dir_buf[backup_dir_len] = '\0';
}
+ backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
if (verbose > 1 && !am_sender)
rprintf(FINFO, "backup_dir is %s\n", backup_dir_buf);
} else if (!backup_suffix_len && (!am_server || !am_sender)) {
#ifdef ICONV_OPTION
argstr[x++] = 's';
#endif
+ argstr[x++] = 'f';
}
if (x >= (int)sizeof argstr) { /* Not possible... */
out_of_memory("server_options");
}
+/* If str points to a valid hostspec, return allocated memory containing the
+ * [USER@]HOST part of the string, and set the path_start_ptr to the part of
+ * the string after the host part. Otherwise, return NULL. If port_ptr is
+ * non-NULL, we must be parsing an rsync:// URL hostname, and we will set
+ * *port_ptr if a port number is found. Note that IPv6 IPs will have their
+ * (required for parsing) [ and ] chars elided from the returned string. */
+static char *parse_hostspec(char *str, char **path_start_ptr, int *port_ptr)
+{
+ char *s, *host_start = str;
+ int hostlen = 0, userlen = 0;
+ char *ret;
+
+ for (s = str; ; s++) {
+ if (!*s) {
+ /* It is only OK if we run out of string with rsync:// */
+ if (!port_ptr)
+ return NULL;
+ if (!hostlen)
+ hostlen = s - host_start;
+ break;
+ }
+ if (*s == ':' || *s == '/') {
+ if (!hostlen)
+ hostlen = s - host_start;
+ if (*s++ == '/') {
+ if (!port_ptr)
+ return NULL;
+ } else if (port_ptr) {
+ *port_ptr = atoi(s);
+ while (isDigit(s)) s++;
+ if (*s && *s++ != '/')
+ return NULL;
+ }
+ break;
+ }
+ if (*s == '@') {
+ userlen = s - str + 1;
+ host_start = s + 1;
+ } else if (*s == '[') {
+ if (s != host_start++)
+ return NULL;
+ while (*s && *s != ']' && *s != '/') s++; /*SHARED ITERATOR*/
+ hostlen = s - host_start;
+ if (*s != ']' || (s[1] && s[1] != '/' && s[1] != ':') || !hostlen)
+ return NULL;
+ }
+ }
+
+ *path_start_ptr = s;
+ ret = new_array(char, userlen + hostlen + 1);
+ if (userlen)
+ strlcpy(ret, str, userlen + 1);
+ strlcpy(ret + userlen, host_start, hostlen + 1);
+ return ret;
+}
+
/* Look for a HOST specfication of the form "HOST:PATH", "HOST::PATH", or
* "rsync://HOST:PORT/PATH". If found, *host_ptr will be set to some allocated
* memory with the HOST. If a daemon-accessing spec was specified, the value
* "[::ffff:127.0.0.1]") which is returned without the '[' and ']'. */
char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
{
- char *p;
- int not_host;
- int hostlen;
+ char *path;
if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) {
- char *path;
- s += strlen(URL_PREFIX);
- if ((p = strchr(s, '/')) != NULL) {
- hostlen = p - s;
- path = p + 1;
- } else {
- hostlen = strlen(s);
- path = "";
+ *host_ptr = parse_hostspec(s + strlen(URL_PREFIX), &path, port_ptr);
+ if (*host_ptr) {
+ if (!*port_ptr)
+ *port_ptr = RSYNC_PORT;
+ return path;
}
- if (*s == '[' && (p = strchr(s, ']')) != NULL) {
- s++;
- hostlen = p - s;
- if (p[1] == ':')
- *port_ptr = atoi(p+2);
- } else {
- if ((p = strchr(s, ':')) != NULL && p < s + hostlen) {
- hostlen = p - s;
- *port_ptr = atoi(p+1);
- }
- }
- if (!*port_ptr)
- *port_ptr = RSYNC_PORT;
- *host_ptr = new_array(char, hostlen + 1);
- strlcpy(*host_ptr, s, hostlen + 1);
- return path;
- }
-
- if (*s == '[' && (p = strchr(s, ']')) != NULL && p[1] == ':') {
- s++;
- hostlen = p - s;
- *p = '\0';
- not_host = strchr(s, '/') || !strchr(s, ':');
- *p = ']';
- if (not_host)
- return NULL;
- p++;
- } else {
- if (!(p = strchr(s, ':')))
- return NULL;
- hostlen = p - s;
- *p = '\0';
- not_host = strchr(s, '/') != NULL;
- *p = ':';
- if (not_host)
- return NULL;
}
- *host_ptr = new_array(char, hostlen + 1);
- strlcpy(*host_ptr, s, hostlen + 1);
+ *host_ptr = parse_hostspec(s, &path, NULL);
+ if (!*host_ptr)
+ return NULL;
- if (p[1] == ':') {
+ if (*path == ':') {
if (port_ptr && !*port_ptr)
*port_ptr = RSYNC_PORT;
- return p + 2;
+ return path + 1;
}
if (port_ptr)
*port_ptr = 0;
- return p + 1;
+ return path;
}