From 681400bba6127041f38a56e77e2ac7e5a0936019 Mon Sep 17 00:00:00 2001 From: Jakub Bogusz Date: Sun, 12 Mar 2006 08:56:32 +0000 Subject: [PATCH] - outdated Changed files: rsync-ssl.patch -> 1.2 rsync-xattr.patch -> 1.2 --- rsync-ssl.patch | 738 ------------------------------------- rsync-xattr.patch | 910 ---------------------------------------------- 2 files changed, 1648 deletions(-) delete mode 100644 rsync-ssl.patch delete mode 100644 rsync-xattr.patch diff --git a/rsync-ssl.patch b/rsync-ssl.patch deleted file mode 100644 index a268dc2..0000000 --- a/rsync-ssl.patch +++ /dev/null @@ -1,738 +0,0 @@ -diff -urbBN rsync-2.6.6.org/cleanup.c rsync-2.6.6/cleanup.c ---- rsync-2.6.6.org/cleanup.c 2005-03-05 19:58:38.000000000 +0100 -+++ rsync-2.6.6/cleanup.c 2005-11-14 16:49:56.182884500 +0100 -@@ -22,6 +22,9 @@ - #include "rsync.h" - - extern int io_error; -+#if HAVE_OPENSSL -+extern int use_ssl; -+#endif - extern int keep_partial; - extern int log_got_error; - extern char *partial_dir; -@@ -97,6 +100,11 @@ - signal(SIGUSR1, SIG_IGN); - signal(SIGUSR2, SIG_IGN); - -+#if HAVE_OPENSSL -+ if (use_ssl) -+ end_tls(); -+#endif -+ - if (verbose > 3) { - rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n", - code, safe_fname(file), line); -diff -urbBN rsync-2.6.6.org/clientserver.c rsync-2.6.6/clientserver.c ---- rsync-2.6.6.org/clientserver.c 2005-06-10 18:57:43.000000000 +0200 -+++ rsync-2.6.6/clientserver.c 2005-11-14 16:49:56.182884500 +0100 -@@ -44,6 +44,9 @@ - extern int orig_umask; - extern int no_detach; - extern int default_af_hint; -+#if HAVE_OPENSSL -+extern int use_ssl; -+#endif - extern char *bind_address; - extern struct filter_list_struct server_filter_list; - extern char *config_file; -@@ -98,8 +101,18 @@ - exit_cleanup(RERR_SOCKETIO); - - ret = start_inband_exchange(user, path, fd, fd, argc); -+ if (ret) -+ return ret; -+ -+#if HAVE_OPENSSL -+ if (use_ssl) { -+ int f_in = get_tls_rfd(); -+ int f_out = get_tls_wfd(); -+ return client_run(f_in, f_out, -1, argc, argv); -+ } -+#endif - -- return ret ? ret : client_run(fd, fd, -1, argc, argv); -+ return client_run(fd, fd, -1, argc, argv); - } - - int start_inband_exchange(char *user, char *path, int f_in, int f_out, -@@ -160,6 +173,33 @@ - if (verbose > 1) - print_child_argv(sargs); - -+#if HAVE_OPENSSL -+ if (use_ssl) { -+ io_printf(f_out, "#starttls\n"); -+ while (1) { -+ if (!read_line(f_in, line, sizeof(line)-1)) { -+ rprintf(FERROR, "rsync: did not receive reply to #starttls\n"); -+ return -1; -+ } -+ if (strncmp(line, "@ERROR", 6) == 0) { -+ rprintf(FERROR, "%s\n", line); -+ return -1; -+ } -+ if (strcmp(line, "@RSYNCD: starttls") == 0) { -+ break; -+ } -+ rprintf(FINFO, "%s\n", line); -+ } -+ if (start_tls(f_in, f_out)) { -+ rprintf(FERROR, "rsync: error during SSL handshake: %s\n", -+ get_ssl_error()); -+ return -1; -+ } -+ f_in = get_tls_rfd(); -+ f_out = get_tls_wfd(); -+ } -+#endif -+ - p = strchr(path,'/'); - if (p) *p = 0; - io_printf(f_out, "%s\n", path); -@@ -188,6 +228,10 @@ - * server to terminate the listing of modules. - * We don't want to go on and transfer - * anything; just exit. */ -+#if HAVE_OPENSSL -+ if (use_ssl) -+ end_tls(); -+#endif - exit(0); - } - -@@ -195,6 +239,10 @@ - rprintf(FERROR, "%s\n", line); - /* This is always fatal; the server will now - * close the socket. */ -+#if HAVE_OPENSSL -+ if (use_ssl) -+ end_tls(); -+#endif - return -1; - } - -@@ -590,6 +639,9 @@ - if (protocol_version > remote_protocol) - protocol_version = remote_protocol; - -+#if HAVE_OPENSSL -+retry: -+#endif - line[0] = 0; - if (!read_line(f_in, line, sizeof line - 1)) - return -1; -@@ -599,6 +651,20 @@ - return -1; - } - -+#if HAVE_OPENSSL -+ if (use_ssl && strcmp(line, "#starttls") == 0) { -+ io_printf(f_out, "@RSYNCD: starttls\n"); -+ if (start_tls(f_in, f_out)) { -+ rprintf(FLOG, "SSL connection failed: %s\n", -+ get_ssl_error()); -+ return -1; -+ } -+ f_in = get_tls_rfd(); -+ f_out = get_tls_wfd(); -+ goto retry; -+ } -+#endif -+ - if (*line == '#') { - /* it's some sort of command that I don't understand */ - io_printf(f_out, "@ERROR: Unknown command '%s'\n", line); -diff -urbBN rsync-2.6.6.org/configure.in rsync-2.6.6/configure.in ---- rsync-2.6.6.org/configure.in 2005-07-28 21:31:05.000000000 +0200 -+++ rsync-2.6.6/configure.in 2005-11-14 16:49:56.186884750 +0100 -@@ -293,6 +293,21 @@ - AC_SEARCH_LIBS(getaddrinfo, inet6) - fi - -+AC_ARG_ENABLE(openssl, -+ AC_HELP_STRING([--enable-openssl], [compile SSL support with OpenSSL.])) -+ -+if test "x$enable_openssl" != xno -+then -+ have_ssl=yes -+ AC_CHECK_LIB(ssl, SSL_library_init, , [have_ssl=no]) -+ if test "x$have_ssl" = xyes -+ then -+ AC_DEFINE(HAVE_OPENSSL, 1, [true if you want to use SSL.]) -+ SSL_OBJS=ssl.o -+ AC_SUBST(SSL_OBJS) -+ fi -+fi -+ - AC_MSG_CHECKING([whether to call shutdown on all sockets]) - case $host_os in - *cygwin* ) AC_MSG_RESULT(yes) -diff -urbBN rsync-2.6.6.org/Makefile.in rsync-2.6.6/Makefile.in ---- rsync-2.6.6.org/Makefile.in 2005-07-07 23:29:57.000000000 +0200 -+++ rsync-2.6.6/Makefile.in 2005-11-14 16:49:56.182884500 +0100 -@@ -38,7 +38,7 @@ - DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o - popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \ - popt/popthelp.o popt/poptparse.o --OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@ -+OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@ @SSL_OBJS@ - - TLS_OBJ = tls.o syscall.o lib/compat.o lib/snprintf.o lib/permstring.o - -diff -urbBN rsync-2.6.6.org/options.c rsync-2.6.6/options.c ---- rsync-2.6.6.org/options.c 2005-05-19 10:52:17.000000000 +0200 -+++ rsync-2.6.6/options.c 2005-11-14 16:50:48.190134750 +0100 -@@ -157,6 +157,14 @@ - int always_checksum = 0; - int list_only = 0; - -+#if HAVE_OPENSSL -+int use_ssl = 0; -+char *ssl_cert_path = NULL; -+char *ssl_key_path = NULL; -+char *ssl_key_passwd = NULL; -+char *ssl_ca_path = NULL; -+#endif -+ - #define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */ - char *batch_name = NULL; - -@@ -182,6 +190,7 @@ - char const *hardlinks = "no "; - char const *links = "no "; - char const *ipv6 = "no "; -+ char const *ssl = "no "; - STRUCT_STAT *dumstat; - - #ifdef HAVE_SOCKETPAIR -@@ -204,6 +213,10 @@ - ipv6 = ""; - #endif - -+#if HAVE_OPENSSL -+ ssl = ""; -+#endif -+ - rprintf(f, "%s version %s protocol version %d\n", - RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION); - rprintf(f, -@@ -217,10 +230,10 @@ - /* Note that this field may not have type ino_t. It depends - * on the complicated interaction between largefile feature - * macros. */ -- rprintf(f, " %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums\n", -+ rprintf(f, " %sinplace, %sIPv6, %d-bit system inums, %d-bit internal inums, %sssl\n", - have_inplace, ipv6, - (int) (sizeof dumstat->st_ino * 8), -- (int) (sizeof (int64) * 8)); -+ (int) (sizeof (int64) * 8), ssl); - #ifdef MAINTAINER_MODE - rprintf(f, " panic action: \"%s\"\n", - get_panic_action()); -@@ -352,6 +365,13 @@ - rprintf(F," -4, --ipv4 prefer IPv4\n"); - rprintf(F," -6, --ipv6 prefer IPv6\n"); - #endif -+#if HAVE_OPENSSL -+ rprintf(F," --ssl allow socket connections to use SSL\n"); -+ rprintf(F," --ssl-cert=FILE path to daemon's SSL certificate\n"); -+ rprintf(F," --ssl-key=FILE path to daemon's SSL private key\n"); -+ rprintf(F," --ssl-key-passwd=PASS password for PEM-encoded private key\n"); -+ rprintf(F," --ssl-ca-certs=FILE path to trusted CA certificates\n"); -+#endif - rprintf(F," --version print version number\n"); - rprintf(F," -h, --help show this help screen\n"); - -@@ -362,7 +382,7 @@ - - enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, - OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST, -- OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, -+ OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_USE_SSL, - OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE, - OPT_REFUSED_BASE = 9000}; - -@@ -464,6 +484,13 @@ - {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 }, - {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 }, - #endif -+#if HAVE_OPENSSL -+ {"ssl", 0, POPT_ARG_NONE, 0, OPT_USE_SSL, 0, 0}, -+ {"ssl-cert", 0, POPT_ARG_STRING, &ssl_cert_path, OPT_USE_SSL, 0, 0}, -+ {"ssl-key", 0, POPT_ARG_STRING, &ssl_key_path, OPT_USE_SSL, 0, 0}, -+ {"ssl-key-passwd", 0, POPT_ARG_STRING, &ssl_key_passwd, OPT_USE_SSL, 0, 0}, -+ {"ssl-ca-certs", 0, POPT_ARG_STRING, &ssl_ca_path, OPT_USE_SSL, 0, 0}, -+#endif - /* All these options switch us into daemon-mode option-parsing. */ - {"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 }, - {"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 }, -@@ -508,6 +535,13 @@ - {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 }, - {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 }, - {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 }, -+#if HAVE_OPENSSL -+ {"ssl", 0, POPT_ARG_NONE, 0, OPT_USE_SSL, 0, 0}, -+ {"ssl-cert", 0, POPT_ARG_STRING, &ssl_cert_path, OPT_USE_SSL, 0, 0}, -+ {"ssl-key", 0, POPT_ARG_STRING, &ssl_key_path, OPT_USE_SSL, 0, 0}, -+ {"ssl-key-passwd", 0, POPT_ARG_STRING, &ssl_key_passwd, OPT_USE_SSL, 0, 0}, -+ {"ssl-ca-certs", 0, POPT_ARG_STRING, &ssl_ca_path, OPT_USE_SSL, 0, 0}, -+#endif - {"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 }, - {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 }, - {0,0,0,0, 0, 0, 0} -@@ -876,6 +910,12 @@ - basis_dir[basis_dir_cnt++] = (char *)arg; - break; - -+ case OPT_USE_SSL: -+#if HAVE_OPENSSL -+ use_ssl = 1; -+#endif -+ break; -+ - default: - /* A large opt value means that set_refuse_options() - * turned this option off. */ -@@ -1129,6 +1169,17 @@ - if (delay_updates && !partial_dir) - partial_dir = partialdir_for_delayupdate; - -+#if HAVE_OPENSSL -+ if (use_ssl) { -+ if (init_tls()) { -+ snprintf(err_buf, sizeof(err_buf), -+ "Openssl error: %s\n", -+ get_ssl_error()); -+ return 0; -+ } -+ } -+#endif -+ - if (inplace) { - #ifdef HAVE_FTRUNCATE - if (partial_dir) { -@@ -1498,11 +1549,28 @@ - { - char *p; - int not_host; -+ int url_prefix_len = sizeof URL_PREFIX - 1; - -- if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) { -+ if (!port_ptr) -+ url_prefix_len = 0; -+ else if (strncasecmp(URL_PREFIX, s, url_prefix_len) != 0) { -+#if HAVE_OPENSSL -+ url_prefix_len = sizeof SSL_URL_PREFIX - 1; -+ if (strncasecmp(SSL_URL_PREFIX, s, url_prefix_len) != 0) -+ url_prefix_len = 0; -+ else { -+ if (!use_ssl) -+ init_tls(); -+ use_ssl = 1; -+ } -+#else -+ url_prefix_len = 0; -+#endif -+ } -+ if (url_prefix_len) { - char *path; - int hostlen; -- s += strlen(URL_PREFIX); -+ s += url_prefix_len; - if ((p = strchr(s, '/')) != NULL) { - hostlen = p - s; - path = p + 1; -diff -urbBN rsync-2.6.6.org/rsync.h rsync-2.6.6/rsync.h ---- rsync-2.6.6.org/rsync.h 2005-05-03 19:00:47.000000000 +0200 -+++ rsync-2.6.6/rsync.h 2005-11-14 16:49:56.190885000 +0100 -@@ -32,6 +32,7 @@ - - #define DEFAULT_LOCK_FILE "/var/run/rsyncd.lock" - #define URL_PREFIX "rsync://" -+#define SSL_URL_PREFIX "rsyncs://" - - #define BACKUP_SUFFIX "~" - -@@ -410,6 +411,11 @@ - # define SIZEOF_INT64 SIZEOF_OFF_T - #endif - -+#if HAVE_OPENSSL -+#include -+#include -+#endif -+ - /* Starting from protocol version 26, we always use 64-bit - * ino_t and dev_t internally, even if this platform does not - * allow files to have 64-bit inums. That's because the -diff -urbBN rsync-2.6.6.org/ssl.c rsync-2.6.6/ssl.c ---- rsync-2.6.6.org/ssl.c 1970-01-01 01:00:00.000000000 +0100 -+++ rsync-2.6.6/ssl.c 2005-11-14 16:49:56.190885000 +0100 -@@ -0,0 +1,366 @@ -+/* -*- c-file-style: "linux" -*- -+ * ssl.c: operations for negotiating SSL rsync connections. -+ * -+ * Copyright (C) 2003 Casey Marshall -+ * -+ * 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 -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include "rsync.h" -+ -+#if HAVE_SYS_SELECT_H -+#include -+#else -+#include -+#include -+#include -+#endif -+#include -+ -+#define BUF_SIZE 1024 -+ -+extern int verbose; -+extern int am_daemon; -+extern int am_server; -+ -+extern char *ssl_cert_path; -+extern char *ssl_key_path; -+extern char *ssl_key_passwd; -+extern char *ssl_ca_path; -+ -+static SSL_CTX *ssl_ctx; -+static SSL *ssl; -+static int tls_read[2] = { -1, -1 }; -+static int tls_write[2] = { -1, -1 }; -+static int ssl_running; -+static int ssl_pid = -1; -+ -+/** -+ * A non-interactive callback to be passed to SSL_CTX_set_default_password_cb, -+ * which merely copies the value of ssl_key_passwd into buf. This is -+ * used for when the private key password is supplied via an option. -+ */ -+static int default_password_cb(char *buf, int n, UNUSED(int f), UNUSED(void *u)) -+{ -+ if (ssl_key_passwd == NULL || n < (int)strlen(ssl_key_passwd)) -+ return 0; -+ strncpy(buf, ssl_key_passwd, n-1); -+ return strlen(ssl_key_passwd); -+} -+ -+/** -+ * If verbose, this method traces the status of the SSL handshake. -+ */ -+static void info_callback(const SSL *ssl, int cb, int val) -+{ -+ char buf[128]; -+ char *cbs; -+ -+ switch (cb) { -+ case SSL_CB_LOOP: -+ cbs = "SSL_CB_LOOP"; -+ break; -+ case SSL_CB_EXIT: -+ cbs = "SSL_CB_EXIT"; -+ break; -+ case SSL_CB_READ: -+ cbs = "SSL_CB_READ"; -+ break; -+ case SSL_CB_WRITE: -+ cbs = "SSL_CB_WRITE"; -+ break; -+ case SSL_CB_ALERT: -+ cbs = "SSL_CB_ALERT"; -+ break; -+ case SSL_CB_READ_ALERT: -+ cbs = "SSL_CB_READ_ALERT"; -+ break; -+ case SSL_CB_WRITE_ALERT: -+ cbs = "SSL_CB_WRITE_ALERT"; -+ break; -+ case SSL_CB_ACCEPT_LOOP: -+ cbs = "SSL_CB_ACCEPT_LOOP"; -+ break; -+ case SSL_CB_ACCEPT_EXIT: -+ cbs = "SSL_CB_ACCEPT_EXIT"; -+ break; -+ case SSL_CB_CONNECT_LOOP: -+ cbs = "SSL_CB_CONNECT_LOOP"; -+ break; -+ case SSL_CB_CONNECT_EXIT: -+ cbs = "SSL_CB_CONNECT_EXIT"; -+ break; -+ case SSL_CB_HANDSHAKE_START: -+ cbs = "SSL_CB_HANDSHAKE_START"; -+ break; -+ case SSL_CB_HANDSHAKE_DONE: -+ cbs = "SSL_CB_HANDSHAKE_DONE"; -+ break; -+ default: -+ snprintf(buf, sizeof buf, "??? (%d)", cb); -+ cbs = buf; -+ break; -+ } -+ if (verbose > 2) { -+ rprintf(FLOG, "SSL: info_callback(%p,%s,%d)\n", ssl, cbs, val); -+ if (cb == SSL_CB_HANDSHAKE_DONE) { -+ SSL_CIPHER_description(SSL_get_current_cipher((SSL*)ssl), -+ buf, sizeof buf); -+ rprintf(FLOG, "SSL: cipher: %s", buf); -+ } -+ } -+} -+ -+/** -+ * Initializes the SSL context for TLSv1 connections; returns zero on -+ * success. -+ */ -+int init_tls(void) -+{ -+ if (ssl_ctx) -+ return 0; -+ SSL_library_init(); -+ SSL_load_error_strings(); -+ ssl_ctx = SSL_CTX_new(TLSv1_method()); -+ if (!ssl_ctx) -+ return 1; -+ SSL_CTX_set_info_callback(ssl_ctx, info_callback); -+ -+ /* Sets the certificate sent to the other party. */ -+ if (ssl_cert_path != NULL -+ && SSL_CTX_use_certificate_file(ssl_ctx, ssl_cert_path, -+ SSL_FILETYPE_PEM) != 1) -+ return 1; -+ /* Set up the simple non-interactive callback if the password -+ * was supplied on the command line. */ -+ if (ssl_key_passwd != NULL) -+ SSL_CTX_set_default_passwd_cb(ssl_ctx, default_password_cb); -+ /* Sets the private key that matches the public certificate. */ -+ if (ssl_key_path != NULL) { -+ if (SSL_CTX_use_PrivateKey_file(ssl_ctx, ssl_key_path, -+ SSL_FILETYPE_PEM) != 1) -+ return 1; -+ if (SSL_CTX_check_private_key(ssl_ctx) != 1) -+ return 1; -+ } -+ if (ssl_ca_path != NULL -+ && !SSL_CTX_load_verify_locations(ssl_ctx, ssl_ca_path, NULL)) -+ return 1; -+ -+ return 0; -+} -+ -+/** -+ * Returns the error string for the current SSL error, if any. -+ */ -+char *get_ssl_error(void) -+{ -+ return ERR_error_string(ERR_get_error(), NULL); -+} -+ -+/** -+ * Returns the input file descriptor for the SSL connection. -+ */ -+int get_tls_rfd(void) -+{ -+ return tls_read[0]; -+} -+ -+/** -+ * Returns the output file descriptor for the SSL connection. -+ */ -+int get_tls_wfd(void) -+{ -+ return tls_write[1]; -+} -+ -+/** -+ * Signal handler that ends the SSL connection. -+ */ -+static RETSIGTYPE tls_sigusr1(int UNUSED(val)) -+{ -+ if (ssl) { -+ SSL_shutdown(ssl); -+ SSL_free(ssl); -+ ssl = NULL; -+ } -+ ssl_running = 0; -+} -+ -+/** -+ * Negotiates the TLS connection, creates a socket pair for communicating -+ * with the rsync process, then forks into a new process that will handle -+ * the communication. -+ * -+ * 0 is returned on success. -+ */ -+int start_tls(int f_in, int f_out) -+{ -+ int tls_fd; -+ int n = 0, r; -+ unsigned char buf1[BUF_SIZE], buf2[BUF_SIZE]; -+ int avail1 = 0, avail2 = 0, write1 = 0, write2 = 0; -+ fd_set rd, wd; -+ -+ if (fd_pair(tls_read)) -+ return 1; -+ if (fd_pair(tls_write)) -+ return 1; -+ -+ set_blocking(tls_read[0]); -+ set_blocking(tls_read[1]); -+ set_blocking(tls_write[0]); -+ set_blocking(tls_write[1]); -+ set_blocking(f_in); -+ set_blocking(f_out); -+ -+ ssl_pid = do_fork(); -+ if (ssl_pid < 0) -+ return -1; -+ if (ssl_pid != 0) { -+ close(tls_write[0]); -+ close(tls_read[1]); -+ return 0; -+ } -+ -+ signal(SIGUSR1, tls_sigusr1); -+ ssl = SSL_new(ssl_ctx); -+ if (!ssl) -+ goto closed; -+ if (am_daemon || am_server) -+ SSL_set_accept_state(ssl); -+ else -+ SSL_set_connect_state(ssl); -+ SSL_set_rfd(ssl, f_in); -+ SSL_set_wfd(ssl, f_out); -+ -+ tls_fd = SSL_get_fd(ssl); -+ n = tls_write[0]; -+ n = MAX(tls_read[1], n); -+ n = MAX(tls_fd, n) + 1; -+ -+ ssl_running = 1; -+ while (ssl_running) { -+ FD_ZERO(&rd); -+ FD_ZERO(&wd); -+ FD_SET(tls_write[0], &rd); -+ FD_SET(tls_read[1], &wd); -+ FD_SET(tls_fd, &rd); -+ FD_SET(tls_fd, &wd); -+ -+ r = select(n, &rd, &wd, NULL, NULL); -+ -+ if (r == -1 && errno == EINTR) -+ continue; -+ if (FD_ISSET(tls_write[0], &rd)) { -+ r = read(tls_write[0], buf1+avail1, BUF_SIZE-avail1); -+ if (r >= 0) -+ avail1 += r; -+ else { -+ rprintf(FERROR, "pipe read error: %s\n", -+ strerror(errno)); -+ break; -+ } -+ } -+ if (FD_ISSET(tls_fd, &rd)) { -+ r = SSL_read(ssl, buf2+avail2, BUF_SIZE-avail2); -+ if (r > 0) -+ avail2 += r; -+ else { -+ switch (SSL_get_error(ssl, r)) { -+ case SSL_ERROR_ZERO_RETURN: -+ goto closed; -+ case SSL_ERROR_WANT_READ: -+ case SSL_ERROR_WANT_WRITE: -+ break; -+ case SSL_ERROR_SYSCALL: -+ if (r == 0) -+ rprintf(FERROR, "SSL spurious EOF\n"); -+ else -+ rprintf(FERROR, "SSL I/O error: %s\n", -+ strerror(errno)); -+ goto closed; -+ case SSL_ERROR_SSL: -+ rprintf(FERROR, "SSL: %s\n", -+ ERR_error_string(ERR_get_error(), NULL)); -+ goto closed; -+ default: -+ rprintf(FERROR, "unexpected ssl error %d\n", r); -+ goto closed; -+ } -+ } -+ } -+ if (FD_ISSET(tls_read[1], &wd) && write2 < avail2) { -+ r = write(tls_read[1], buf2+write2, avail2-write2); -+ if (r >= 0) -+ write2 += r; -+ else { -+ rprintf(FERROR, "pipe write error: %s\n", -+ strerror(errno)); -+ break; -+ } -+ } -+ if (FD_ISSET(tls_fd, &wd) && write1 < avail1) { -+ r = SSL_write(ssl, buf1+write1, avail1-write1); -+ if (r > 0) -+ write1 += r; -+ else { -+ switch (SSL_get_error(ssl, r)) { -+ case SSL_ERROR_ZERO_RETURN: -+ goto closed; -+ case SSL_ERROR_WANT_READ: -+ case SSL_ERROR_WANT_WRITE: -+ break; -+ case SSL_ERROR_SYSCALL: -+ if (r == 0) -+ rprintf(FERROR, "SSL: spurious EOF\n"); -+ else -+ rprintf(FERROR, "SSL: I/O error: %s\n", -+ strerror(errno)); -+ goto closed; -+ case SSL_ERROR_SSL: -+ rprintf(FERROR, "SSL: %s\n", -+ ERR_error_string(ERR_get_error(), NULL)); -+ goto closed; -+ default: -+ rprintf(FERROR, "unexpected ssl error %d\n", r); -+ goto closed; -+ } -+ } -+ } -+ if (avail1 == write1) -+ avail1 = write1 = 0; -+ if (avail2 == write2) -+ avail2 = write2 = 0; -+ } -+ -+ /* XXX I'm pretty sure that there is a lot that I am not considering -+ here. Bugs? Yes, probably. */ -+ -+ /* We're finished. */ -+ closed: -+ close(tls_read[1]); -+ close(tls_write[0]); -+ exit(0); -+} -+ -+/** -+ * Ends the TLS connection. -+ */ -+void end_tls(void) -+{ -+ if (ssl_pid > 0) -+ kill(ssl_pid, SIGUSR1); -+} diff --git a/rsync-xattr.patch b/rsync-xattr.patch deleted file mode 100644 index 9716d86..0000000 --- a/rsync-xattr.patch +++ /dev/null @@ -1,910 +0,0 @@ -Common subdirectories: rsync-2.6.4pre2-prexattr/autom4te.cache and rsync-2.6.4pre2/autom4te.cache -diff -u -N rsync-2.6.4pre2-prexattr/backup.c rsync-2.6.4pre2/backup.c ---- rsync-2.6.4pre2-prexattr/backup.c 2005-03-02 20:15:48.000000000 -0500 -+++ rsync-2.6.4pre2/backup.c 2005-03-02 20:20:46.000000000 -0500 -@@ -136,6 +136,7 @@ - do_lchown(fullpath, st.st_uid, st.st_gid); - do_chmod(fullpath, st.st_mode); - (void)DUP_ACL(end, fullpath, st.st_mode); -+ (void)DUP_XATTR(end, fullpath ); - } - } - *p = '/'; -@@ -189,6 +190,7 @@ - return 0; - - PUSH_KEEP_BACKUP_ACL(file, fname, buf); -+ PUSH_KEEP_BACKUP_XATTR( file, fname, buf ); - - /* Check to see if this is a device file, or link */ - if (IS_DEVICE(file->mode)) { -@@ -264,6 +266,7 @@ - } - set_perms(buf, file, NULL, 0); - CLEANUP_KEEP_BACKUP_ACL(); -+ CLEANUP_KEEP_BACKUP_XATTR(); - free(file); - - if (verbose > 1) { -diff -u -N rsync-2.6.4pre2-prexattr/configure.in rsync-2.6.4pre2/configure.in ---- rsync-2.6.4pre2-prexattr/configure.in 2005-03-02 20:15:48.000000000 -0500 -+++ rsync-2.6.4pre2/configure.in 2005-03-02 20:20:46.000000000 -0500 -@@ -789,6 +789,30 @@ - AC_MSG_RESULT(no) - ) - -+AC_CHECK_HEADERS(attr/xattr.h) -++AC_MSG_CHECKING(whether to support extended attributes) -+AC_ARG_WITH(xattr-support, -+[ --with-xattr-support Include extended attribute support (default=no)], -+[ case "$withval" in -+ yes) -+ case "$host_os" in -+ *linux*) -+ AC_MSG_RESULT(Using Linux xattrs) -+ AC_DEFINE(HAVE_LINUX_XATTRS, 1, [True if you have Linux xattrs]) -+ ;; -+ *) -+ AC_MSG_RESULT(Xattrs requested but not linux. Good luck) -+ ;; -+ esac -+ ;; -+ *) -+ AC_MSG_RESULT(no) -+ AC_DEFINE(HAVE_NA_XATTRS, 1, [True if you don't have extended attributes]) -+ esac ], -+ AC_MSG_RESULT(no) -+ AC_DEFINE(HAVE_NO_XATTRL, 1, [True if you don't have extended attributes]) -+) -+ - AC_CONFIG_FILES([Makefile lib/dummy zlib/dummy popt/dummy shconfig]) - AC_OUTPUT - -diff -u -N rsync-2.6.4pre2-prexattr/options.c rsync-2.6.4pre2/options.c ---- rsync-2.6.4pre2-prexattr/options.c 2005-03-02 20:15:48.000000000 -0500 -+++ rsync-2.6.4pre2/options.c 2005-03-02 20:31:22.000000000 -0500 -@@ -45,6 +45,7 @@ - int preserve_links = 0; - int preserve_hard_links = 0; - int preserve_acls = 0; -+int preserve_xattrs = 0; - int preserve_perms = 0; - int preserve_devices = 0; - int preserve_uid = 0; -@@ -180,6 +181,7 @@ - char const *have_inplace = "no "; - char const *hardlinks = "no "; - char const *acls = "no "; -+ char const *xattrs = "no "; - char const *links = "no "; - char const *ipv6 = "no "; - STRUCT_STAT *dumstat; -@@ -199,7 +201,9 @@ - #ifdef SUPPORT_ACLS - acls = ""; - #endif -- -+#if SUPPORT_XATTRS -+ xattrs = ""; -+#endif - #ifdef SUPPORT_LINKS - links = ""; - #endif -@@ -214,9 +218,9 @@ - "Copyright (C) 1996-2005 by Andrew Tridgell and others\n"); - rprintf(f, "\n"); - rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, " -- "%shard links, %sACLs, %ssymlinks, batchfiles, \n", -+ "%shard links, %sACLs, %sxattrs, %ssymlinks, batchfiles, \n", - (int) (sizeof (OFF_T) * 8), -- got_socketpair, hardlinks, acls, links); -+ got_socketpair, hardlinks, acls, xattrs, links); - - /* Note that this field may not have type ino_t. It depends - * on the complicated interaction between largefile feature -@@ -287,6 +291,7 @@ - rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n"); - rprintf(F," -p, --perms preserve permissions\n"); - rprintf(F," -A, --acls preserve ACLs (implies --perms)\n"); -+ rprintf(F," -X, --xattrs preserve extended attributes (implies --perms)\n"); - rprintf(F," -o, --owner preserve owner (root only)\n"); - rprintf(F," -g, --group preserve group\n"); - rprintf(F," -D, --devices preserve devices (root only)\n"); -@@ -410,6 +415,7 @@ - {"copy-unsafe-links",0, POPT_ARG_NONE, ©_unsafe_links, 0, 0, 0 }, - {"perms", 'p', POPT_ARG_NONE, &preserve_perms, 0, 0, 0 }, - {"acls", 'A', POPT_ARG_NONE, 0, 'A', 0, 0 }, -+ {"xattrs", 'X', POPT_ARG_NONE, 0, 'X', 0, 0 }, - {"owner", 'o', POPT_ARG_NONE, &preserve_uid, 0, 0, 0 }, - {"group", 'g', POPT_ARG_NONE, &preserve_gid, 0, 0, 0 }, - {"devices", 'D', POPT_ARG_NONE, &preserve_devices, 0, 0, 0 }, -@@ -879,6 +885,17 @@ - #endif /* SUPPORT_ACLS */ - break; - -+ case 'X': -+#if SUPPORT_XATTRS -+ preserve_xattrs = 1; -+ preserve_perms = 1; -+#else -+ snprintf(err_buf,sizeof(err_buf), -+ "extended attributes are not supported on this %s\n", -+ am_server ? "server" : "client"); -+ return 0; -+#endif /* SUPPORT_XATTRS */ -+ break; - - default: - /* A large opt value means that set_refuse_options() -@@ -1289,6 +1306,8 @@ - argstr[x++] = 'H'; - if (preserve_acls) - argstr[x++] = 'A'; -+ if ( preserve_xattrs ) -+ argstr[x++] = 'X'; - if (preserve_uid) - argstr[x++] = 'o'; - if (preserve_gid) -Common subdirectories: rsync-2.6.4pre2-prexattr/packaging and rsync-2.6.4pre2/packaging -Common subdirectories: rsync-2.6.4pre2-prexattr/patches and rsync-2.6.4pre2/patches -Common subdirectories: rsync-2.6.4pre2-prexattr/popt and rsync-2.6.4pre2/popt -diff -u -N rsync-2.6.4pre2-prexattr/rsync.c rsync-2.6.4pre2/rsync.c ---- rsync-2.6.4pre2-prexattr/rsync.c 2005-03-02 20:15:48.000000000 -0500 -+++ rsync-2.6.4pre2/rsync.c 2005-03-02 20:31:22.000000000 -0500 -@@ -145,6 +145,14 @@ - if (SET_ACL(fname, file) == 0) - updated = 1; - } -+ /* If this is a directory, SET_XATTR() will be called on the cleanup -+ * receive_generator() pass--if we called it here, we might clobber -+ * writability on the directory (SELinux security contexts are stored -+ * in xattrs). everything else is OK to do now. */ -+ if (!S_ISDIR(st->st_mode)) { -+ if (SET_XATTR(fname, file) == 0) -+ updated = 1; -+ } - - if (verbose > 1 && flags & PERMS_REPORT) { - enum logcode code = daemon_log_format_has_i || dry_run -diff -u -N rsync-2.6.4pre2-prexattr/rsync.h rsync-2.6.4pre2/rsync.h ---- rsync-2.6.4pre2-prexattr/rsync.h 2005-03-02 20:15:48.000000000 -0500 -+++ rsync-2.6.4pre2/rsync.h 2005-03-02 20:32:39.000000000 -0500 -@@ -662,6 +662,36 @@ - #endif /* SUPPORT_ACLS */ - #include "smb_acls.h" - -+#define SUPPORT_XATTRS HAVE_LINUX_XATTRS -+ -+#if SUPPORT_XATTRS -+#ifdef HAVE_ATTR_XATTR_H -+#include -+#endif -+#define MAKE_XATTR(file, fname) make_xattr(file, fname) -+#define SEND_XATTR(file, f) send_xattr(file, f) -+#define RECEIVE_XATTR(file, f) receive_xattr(file, f) -+#define SORT_FILE_XATTR_INDEX_LISTS() sort_file_xattr_index_lists() -+#define SET_XATTR(fname, file) set_xattr(fname, file) -+#define NEXT_XATTR_UID() next_xattr_uid() -+#define XATTR_UID_MAP(uid) xattr_uid_map(uid) -+#define PUSH_KEEP_BACKUP_XATTR(file, orig, dest) \ -+ push_keep_backup_xattr(file, orig, dest) -+#define CLEANUP_KEEP_BACKUP_XATTR() cleanup_keep_backup_xattr() -+#define DUP_XATTR(orig, dest) dup_xattr(orig, dest) -+#else /* SUPPORT_XATTRS */ -+#define MAKE_XATTR(file, fname) 1 /* checked return value */ -+#define SEND_XATTR(file, f) -+#define RECEIVE_XATTR(file, f) -+#define SORT_FILE_XATTR_INDEX_LISTS() -+#define SET_XATTR(fname, file) 0 /* checked return value */ -+#define NEXT_XATTR_UID() -+#define XATTR_UID_MAP(uid) -+#define PUSH_KEEP_BACKUP_XATTR(file, orig, dest) -+#define CLEANUP_KEEP_BACKUP_XATTR() -+#define DUP_XATTR(src, orig) 0 /* checked return value */ -+#endif /* SUPPORT_XATTRS */ -+ - #include "proto.h" - - /* We have replacement versions of these if they're missing. */ -diff -u -N rsync-2.6.4pre2-prexattr/rsync.yo rsync-2.6.4pre2/rsync.yo ---- rsync-2.6.4pre2-prexattr/rsync.yo 2005-03-02 20:15:48.000000000 -0500 -+++ rsync-2.6.4pre2/rsync.yo 2005-03-02 20:33:53.000000000 -0500 -@@ -318,6 +318,7 @@ - -K, --keep-dirlinks treat symlinked dir on receiver as dir - -p, --perms preserve permissions - -A, --acls preserve ACLs (implies -p) [local option] -+ -X, --xattrs preserve extended attributes (implies -p) [local option] - -o, --owner preserve owner (root only) - -g, --group preserve group - -D, --devices preserve devices (root only) -@@ -630,6 +631,11 @@ - remote machine's rsync supports this option also. This is a non-standard - option. - -+dit(bf(-X, --xattrs)) This option causes rsync to update the remote -+extended attributes to be the same as the local ones. This will work -+only if the remote machine's rsync supports this option also. This is -+a non-standard option. -+ - dit(bf(-o, --owner)) This option causes rsync to set the owner of the - destination file to be the same as the source file. On most systems, - only the super-user can set file ownership. By default, the preservation -Common subdirectories: rsync-2.6.4pre2-prexattr/support and rsync-2.6.4pre2/support -diff -u -N rsync-2.6.4pre2-prexattr/lib/sysxattr.c rsync-2.6.4pre2/sysxattr.c ---- rsync-2.6.4pre2-prexattr/lib/sysxattr.c 1969-12-31 19:00:00.000000000 -0500 -+++ rsync-2.6.4pre2/lib/sysxattr.c 2005-03-02 20:34:10.000000000 -0500 -@@ -0,0 +1,41 @@ -+/* Extended attribute support for rsync. */ -+/* This file Copyright (C) 2004 Red Hat, Inc. */ -+/* Written by Jay Fenlason */ -+ -+/* 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 -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#include "rsync.h" -+ -+#if defined(HAVE_LINUX_XATTRS) -+ -+ssize_t sys_lgetxattr ( const char *path, const char *name, void *value, size_t size ) -+{ -+ return lgetxattr ( path, name, value, size ); -+} -+ -+int sys_lsetxattr ( const char *path, const char *name, const void *value, size_t size, int flags ) -+{ -+ return lsetxattr ( path, name, value, size, flags ); -+} -+ -+ssize_t sys_llistxattr ( const char *path, char *list, size_t size ) -+{ -+ return llistxattr ( path, list, size ); -+} -+ -+#else -+ -+#endif /* No xattrs */ -Common subdirectories: rsync-2.6.4pre2-prexattr/testhelp and rsync-2.6.4pre2/testhelp -Common subdirectories: rsync-2.6.4pre2-prexattr/testsuite and rsync-2.6.4pre2/testsuite -diff -u -N rsync-2.6.4pre2-prexattr/xattr.c rsync-2.6.4pre2/xattr.c ---- rsync-2.6.4pre2-prexattr/xattr.c 1969-12-31 19:00:00.000000000 -0500 -+++ rsync-2.6.4pre2/xattr.c 2005-03-02 20:34:47.000000000 -0500 -@@ -0,0 +1,556 @@ -+/* Extended Attribute support for rsync */ -+/* Copyright (C) 2004 Red Hat, Inc */ -+/* Written by Jay Fenlason, vaguely based on the ACLs patch */ -+ -+/* 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 -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+*/ -+ -+#include "rsync.h" -+ -+#if SUPPORT_XATTRS -+ -+extern int preserve_xattrs; -+extern int dry_run; -+ -+#define RSYNC_XAL_INITIAL 5 -+#define RSYNC_XAL_LIST_INITIAL 100 -+ -+ -+typedef struct { -+ size_t name_len; -+ char *name; -+ size_t datum_len; -+ char *datum; -+} rsync_xa; -+ -+typedef struct { -+ size_t count; -+ size_t alloc; -+ rsync_xa *rxas; -+} rsync_xal; -+ -+typedef struct { -+ size_t count; -+ size_t alloc; -+ rsync_xal *rxals; -+} rsync_xal_list; -+ -+static size_t namebuf_len = 0; -+static char *namebuf = NULL; -+ -+static size_t datumbuf_len = 0; -+static char *datumbuf = NULL; -+ -+static rsync_xal curr_rsync_xal = { 0, 0, NULL }; -+static rsync_xal_list rsync_xal_l = { 0, 0, NULL }; -+ -+ -+/* ------------------------------------------------------------------------- */ -+ -+/* the below stuff is only used by the receiver */ -+ -+/* structure to hold index to rsync_xal_l member corresponding to -+ * flist->files[i] */ -+ -+typedef struct { -+ const struct file_struct *file; -+ int xalidx; -+} file_xal_index; -+ -+typedef struct { -+ size_t count; -+ size_t alloc; -+ file_xal_index *filexalidxs; -+} file_xal_index_list; -+ -+static file_xal_index_list fxil = {0, 0, NULL }; -+ -+/* stuff for redirecting calls to set_acl() from set_perms() -+ * for keep_backup() */ -+static const struct file_struct *backup_orig_file = NULL; -+static const char null_string[] = ""; -+static const char *backup_orig_fname = null_string; -+static const char *backup_dest_fname = null_string; -+static rsync_xal backup_xal; -+ -+/* ------------------------------------------------------------------------- */ -+ -+static void rsync_xal_free ( rsync_xal *x ) { -+ size_t i; -+ -+ for ( i = 0; i < x->count; i++ ) { -+ free ( x->rxas[i].name ); -+ /* free ( x->rxas[i].value ); */ -+ } -+ x->count = 0; -+} -+ -+static int rsync_xal_compare_names ( const void *x1, const void *x2 ) { -+ const rsync_xa *xa1; -+ const rsync_xa *xa2; -+ -+ xa1 = x1; -+ xa2 = x2; -+ return strcmp ( xa1->name, xa2->name ); -+} -+ -+static BOOL rsync_xal_get ( const char *fname, rsync_xal *x ) { -+ ssize_t name_size; -+ ssize_t datum_size; -+ ssize_t left; -+ char *name; -+ size_t len; -+ char *ptr; -+ -+ if ( ! namebuf ) { -+ namebuf_len = 100; -+ namebuf = malloc ( 100 ); -+ datumbuf_len = 100; -+ datumbuf = malloc ( 100 ); -+ if ( ! namebuf || ! datumbuf ) { -+ rprintf(FERROR, "%s: rsync_xal_get: allocate intial buffers failed: %s\n", -+ fname, strerror(errno)); -+ return False; -+ } -+ } -+ -+ name_size = sys_llistxattr ( fname, namebuf, namebuf_len ); -+ if ( name_size > namebuf_len ) { -+ name_size = -1; -+ errno = ERANGE; -+ } -+ if ( name_size < 0 ) { -+ if ( errno == ENOTSUP ) -+ return False; -+ if ( errno == ERANGE ) { -+ name_size = sys_llistxattr ( fname, NULL, 0 ); -+ if ( name_size < 0 ) { -+ rprintf ( FERROR, "%s: rsync_xal_get: llistxattr: %s\n", -+ fname, strerror(errno) ); -+ return False; -+ } -+ namebuf = realloc ( namebuf, name_size + 1 ); -+ if ( ! namebuf ) { -+ rprintf ( FERROR, "%s: rsync_xal_get: reallocate namebuf to %lu failed: %s\n", -+ fname, (unsigned long)name_size, strerror(errno) ); -+ return False; -+ } -+ namebuf_len = name_size; -+ name_size = sys_llistxattr ( fname, namebuf, namebuf_len ); -+ if ( name_size < 0 ) { -+ rprintf ( FERROR, "%s: rsync_xal_get: re-llistxattr failed: %s\n", -+ fname, strerror(errno) ); -+ return False; -+ } -+ } else { -+ rprintf(FERROR, "%s: rsync_xal_get: llistxattr failed: %s\n", -+ fname, strerror(errno)); -+ return False; -+ } -+ } -+ rsync_xal_free ( x ); -+ if ( name_size == 0 ) -+ return True; -+ for ( left = name_size, name = namebuf; left > 0 ; left -= len, name += len ) { -+ len = strlen ( name ) + 1; -+ -+ if ( x->count >= x->alloc ) { -+ size_t new_alloc; -+ size_t new_size; -+ rsync_xa *new_rxas; -+ -+ new_alloc = ( x->alloc < RSYNC_XAL_INITIAL ) ? RSYNC_XAL_INITIAL : x->alloc * 2; -+ new_size = new_alloc * sizeof(rsync_xa); -+ new_rxas = x->alloc ? realloc ( x->rxas, new_size ) : malloc ( new_size ); -+ if ( new_rxas == NULL ) { -+ rprintf(FERROR, "%s: rsync_xal_get: allocate %lufailed: %s\n", -+ fname, (unsigned long)new_size, strerror(errno)); -+ return False; -+ } -+ x->alloc = new_alloc; -+ x->rxas = new_rxas; -+ } -+ datum_size = sys_lgetxattr ( fname, name, datumbuf, datumbuf_len ); -+ if ( datum_size > datumbuf_len ) { -+ datum_size = -1; -+ errno = ERANGE; -+ } -+ if ( datum_size < 0 ) { -+ if ( errno == ENOTSUP ) -+ return False; -+ if ( errno == ERANGE ) { -+ datum_size = sys_lgetxattr ( fname, name, NULL, 0 ); -+ if ( datum_size < 0 ) { -+ rprintf ( FERROR, "%s: rsync_xal_get: lgetxattr %s failed: %s\n", -+ fname, name, strerror(errno) ); -+ return False; -+ } -+ datumbuf = realloc ( datumbuf, datum_size + 1 ); -+ if ( ! datumbuf ) { -+ rprintf(FERROR, "%s: rsync_xal_get: allocate %lu for datumbuf failed: %s\n", -+ fname, (unsigned long)(datum_size + 1), strerror(errno)); -+ return False; -+ } -+ datumbuf_len = datum_size; -+ datum_size = sys_lgetxattr ( fname, name, datumbuf, datumbuf_len ); -+ if ( datum_size < 0 ) { -+ rprintf ( FERROR, "%s: rsync_xal_get: re-lgetxattr of %s failed: %s\n", -+ name, fname, strerror(errno) ); -+ return False; -+ } -+ } else { -+ rprintf(FERROR, "%s: rsync_xal_get: lgetxattr %s failed: %s\n", -+ fname, name, strerror(errno)); -+ return False; -+ } -+ } -+ ptr = malloc ( len + datum_size ); -+ strcpy ( ptr, name ); -+ if ( datum_size ) -+ memcpy ( ptr + len, datumbuf, datum_size ); -+ x->rxas[curr_rsync_xal.count].name_len = len; -+ x->rxas[curr_rsync_xal.count].name = ptr; -+ x->rxas[curr_rsync_xal.count].datum_len = datum_size; -+ x->rxas[curr_rsync_xal.count].datum = ptr + len; -+ x->count++; -+ } -+ if ( x->count > 1 ) { -+ qsort ( x->rxas, x->count, sizeof(rsync_xa), rsync_xal_compare_names ); -+ } -+ return True; -+} -+ -+ -+/* generate the xattr(s) for this flist entry; -+ * xattr(s) are either sent or cleaned-up by send_xattr() below */ -+ -+BOOL make_xattr(const struct file_struct *file, const char *fname) -+{ -+ if (!preserve_xattrs) -+ return True; -+ -+ rsync_xal_get ( fname, &curr_rsync_xal ); -+ return True; -+} -+ -+static ssize_t rsync_xal_find_matching ( void ) { -+ size_t i; -+ size_t j; -+ -+ for ( i = 0; i < rsync_xal_l.count; i++ ) { -+ /* Wrong number of elements? */ -+ if ( rsync_xal_l.rxals[i].count != curr_rsync_xal.count ) -+ continue; -+ /* any elements different? */ -+ for ( j = 0; j < curr_rsync_xal.count; j++ ) { -+ if ( -+ rsync_xal_l.rxals[i].rxas[j].name_len != curr_rsync_xal.rxas[j].name_len -+ || rsync_xal_l.rxals[i].rxas[j].datum_len != curr_rsync_xal.rxas[j].datum_len -+ || strcmp ( rsync_xal_l.rxals[i].rxas[j].name, curr_rsync_xal.rxas[j].name ) -+ || memcmp ( rsync_xal_l.rxals[i].rxas[j].datum, curr_rsync_xal.rxas[j].datum, curr_rsync_xal.rxas[j].datum_len ) ) -+ break; -+ } -+ /* no differences found. This is The One! */ -+ if ( j == curr_rsync_xal.count ) -+ break; -+ } -+ if ( i < rsync_xal_l.count ) -+ return i; -+ return (ssize_t)-1; -+} -+ -+/* Store curr_rsync_xal on the end of rsync_xal_l */ -+static void rsync_xal_store ( void ) { -+ if ( rsync_xal_l.count <= rsync_xal_l.alloc ) { -+ size_t new_alloc; -+ size_t new_size; -+ void *new_xal; -+ -+ new_alloc = ( rsync_xal_l.count < RSYNC_XAL_LIST_INITIAL ) ? RSYNC_XAL_LIST_INITIAL : rsync_xal_l.count * 2; -+ new_size = new_alloc * sizeof(rsync_xal); -+ new_xal = rsync_xal_l.count ? realloc ( rsync_xal_l.rxals, new_size ) : malloc ( new_size ); -+ if ( new_xal == NULL ) { -+ rprintf ( FERROR, "rsync_xal_store: allocate %lu for new_xal failed\n", (unsigned long)new_size ); -+ exit_cleanup(RERR_STREAMIO ); -+ } -+ rsync_xal_l.alloc = new_alloc; -+ rsync_xal_l.rxals = new_xal; -+ } -+ rsync_xal_l.rxals[rsync_xal_l.count] = curr_rsync_xal; -+ rsync_xal_l.count++; -+ curr_rsync_xal.count = 0; -+ curr_rsync_xal.alloc = 0; -+} -+ -+/* send the make_xattr()-generated xattr list for this flist entry, -+ * or clean up after an flist entry that's not being sent (f == -1) */ -+ -+void send_xattr ( const struct file_struct *file, int f ) -+{ -+ ssize_t index; -+ -+ if ( ! preserve_xattrs ) -+ return; -+ -+ if (f == -1) { -+ rsync_xal_free ( &curr_rsync_xal ); -+ return; -+ } -+ index = rsync_xal_find_matching ( ); -+ if ( index != -1) { -+ write_byte(f, 'x' ); -+ write_int(f, index); -+ rsync_xal_free ( &curr_rsync_xal ); -+ } else { -+ rsync_xa *rxa; -+ size_t count; -+ -+ count = curr_rsync_xal.count; -+ write_byte(f, 'X' ); -+ write_int(f, count); -+ for (rxa = curr_rsync_xal.rxas; count--; rxa++) { -+ write_int( f, rxa->name_len ); -+ write_int ( f, rxa->datum_len ); -+ write_buf ( f, rxa->name, rxa->name_len ); -+ write_buf ( f, rxa->datum, rxa->datum_len ); -+ } -+ rsync_xal_store(); -+ } -+} -+ -+ -+/* ------------------------------------------------------------------------- */ -+/* receive and build the rsync_xattr_lists */ -+ -+void receive_xattr(struct file_struct *file, int f) -+{ -+ char *fname; -+ int tag; -+ -+ if ( ! preserve_xattrs ) -+ return; -+ fname = f_name(file); -+ tag = read_byte(f); -+ if (tag != 'X' && tag != 'x') { -+ rprintf(FERROR, "%s: receive_xattr: unknown extended attribute type tag: %c\n", -+ fname, tag); -+ exit_cleanup(RERR_STREAMIO); -+ } -+ -+ if ( fxil.alloc <= fxil.count) { -+ void *new_ptr; -+ size_t new_alloc; -+ size_t new_size; -+ -+ if ( fxil.count < RSYNC_XAL_LIST_INITIAL ) -+ new_alloc = fxil.alloc + RSYNC_XAL_LIST_INITIAL; -+ else -+ new_alloc = fxil.alloc * 2; -+ new_size = new_alloc * sizeof(file_xal_index); -+ if ( fxil.alloc ) -+ new_ptr = realloc ( fxil.filexalidxs, new_size ); -+ else -+ new_ptr = malloc ( new_size ); -+ if (!new_ptr) -+ out_of_memory("receive_xattr"); -+ if (verbose >= 3) { -+ rprintf(FINFO, "receive_xattr to %lu bytes, %s move\n", -+ (unsigned long) new_size, -+ fxil.filexalidxs == new_ptr ? "did not" : "did"); -+ } -+ -+ fxil.filexalidxs = new_ptr; -+ fxil.alloc = new_alloc; -+ } -+ -+ fxil.filexalidxs[fxil.count].file = file; -+ if (tag == 'X' ) { -+ size_t count; -+ size_t i; -+ -+ fxil.filexalidxs[fxil.count].xalidx = rsync_xal_l.count; -+ -+ count = read_int ( f ); -+ curr_rsync_xal.count = count; -+ curr_rsync_xal.alloc = count; -+ curr_rsync_xal.rxas = malloc ( count * sizeof(rsync_xa) ); -+ if ( curr_rsync_xal.rxas == NULL ) { -+ rprintf(FERROR, "%s: receive_xattr: allocate %lu xas failed\n", -+ fname, (unsigned long)count ); -+ exit_cleanup(RERR_STREAMIO); -+ } -+ for ( i = 0; i < count; i++ ) { -+ size_t name_len; -+ size_t datum_len; -+ char *ptr; -+ -+ name_len = read_int ( f ); -+ datum_len = read_int ( f ); -+ ptr = malloc ( name_len + datum_len ); -+ read_buf ( f, ptr, name_len ); -+ read_buf ( f, ptr + name_len, datum_len ); -+ curr_rsync_xal.rxas[i].name_len = name_len; -+ curr_rsync_xal.rxas[i].datum_len = datum_len; -+ curr_rsync_xal.rxas[i].name = ptr; -+ curr_rsync_xal.rxas[i].datum = ptr + name_len; -+ } -+ rsync_xal_store(); -+ } else { -+ size_t index; -+ -+ index = read_int(f); -+ if ( index >= rsync_xal_l.count) { -+ rprintf(FERROR, "%s: receive_xattr: xa index %lu out of range\n", -+fname, (unsigned long)index ); -+ exit_cleanup(RERR_STREAMIO); -+ } -+ fxil.filexalidxs[fxil.count].xalidx = index; -+ } -+ fxil.count++; -+} -+ -+static BOOL rsync_xal_set ( const char *fname, rsync_xal *x ) { -+ size_t i; -+ int status; -+ BOOL ret; -+ -+ ret = True; -+ for ( i = 0; i < x->count; i++ ) { -+ status = sys_lsetxattr ( fname, x->rxas[i].name, x->rxas[i].datum, x->rxas[i].datum_len, 0 ); -+ if ( status < 0 ) { -+ rprintf(FERROR, "%s: rsync_xal_set: lsetxattr %s failed: %s\n", -+ fname, x->rxas[i].name, strerror(errno)); -+ ret = False; -+ } -+ } -+ return ret; -+} -+ -+/* for duplicating xattrs on backups when using backup_dir */ -+ -+int dup_xattr ( const char *orig, const char *bak ) -+{ -+ int ret; -+ -+ ret = 0; -+ if (!preserve_xattrs) -+ return ret; -+ -+ ret = rsync_xal_get ( orig, &backup_xal ); -+ if ( ret == True ) -+ ret = rsync_xal_set ( bak, &backup_xal ); -+ rsync_xal_free ( &backup_xal ); -+ return ret; -+} -+ -+void push_keep_backup_xattr ( const struct file_struct *file, const char *orig, const char *dest ) -+{ -+ if ( ! preserve_xattrs ) -+ return; -+ -+ backup_orig_file = file; -+ backup_orig_fname = orig; -+ backup_dest_fname = dest; -+ rsync_xal_get ( orig, &backup_xal ); -+} -+ -+static int set_keep_backup_xal ( void ) { -+ if ( ! preserve_xattrs ) -+ return 0; -+ return rsync_xal_set ( backup_dest_fname, &backup_xal ); -+} -+ -+void cleanup_keep_backup_xattr ( void ) -+{ -+ if ( ! preserve_xattrs) -+ return; -+ -+ backup_orig_file = NULL; -+ backup_orig_fname = null_string; -+ backup_dest_fname = null_string; -+ rsync_xal_free ( &backup_xal ); -+} -+ -+static int file_xal_index_compare ( const void *x1, const void *x2 ) { -+ const file_xal_index *xa1; -+ const file_xal_index *xa2; -+ -+ xa1 = x1; -+ xa2 = x2; -+ return ( xa1->file == xa2->file) ? 0 : -+ ( ( xa1->file < xa2->file ) ? -1: 1 ); -+} -+void sort_file_xattr_index_lists ( void ) -+{ -+ if ( ! preserve_xattrs ) -+ return; -+ qsort ( fxil.filexalidxs, fxil.count, sizeof(file_xal_index), -+ file_xal_index_compare ); -+} -+ -+ -+static int find_file_xal_index( const struct file_struct *file) { -+ int low = 0, high = fxil.count; -+ const struct file_struct *file_mid; -+ -+ if ( ! high-- ) { -+ rprintf(FERROR, "find_file_xal_index: no entries\n"); -+ exit_cleanup(RERR_STREAMIO); -+ return -1; -+ } -+ do { -+ int mid = (high + low) / 2; -+ file_mid = fxil.filexalidxs[mid].file; -+ if (file_mid == file) -+ return fxil.filexalidxs[mid].xalidx; -+ if (file_mid > file) -+ high = mid - 1; -+ else -+ low = mid + 1; -+ } while (low < high); -+ if (low == high) { -+ file_mid = fxil.filexalidxs[low].file; -+ if (file_mid == file) -+ return fxil.filexalidxs[low].xalidx; -+ } -+ rprintf(FERROR, -+ "find_file_xal_index: can't find entry for file in list\n"); -+ exit_cleanup(RERR_STREAMIO); -+ return -1; -+} -+ -+ -+/* set extended attributes on rsync-ed or keep_backup-ed file */ -+ -+int set_xattr ( const char *fname, const struct file_struct *file ) -+{ -+ int updated; -+ int xalidx; -+ rsync_xal *x; -+ -+ updated = 0; -+ if ( dry_run || ! preserve_xattrs ) -+ return 0; -+ if (file == backup_orig_file) { -+ if (!strcmp(fname, backup_dest_fname)) -+ return set_keep_backup_xal(); -+ } -+ xalidx = find_file_xal_index( file ); -+ x = &(rsync_xal_l.rxals[xalidx]); -+ updated = rsync_xal_set ( fname, x ); -+ return updated; -+} -+ -+#endif /* SUPPORT_XATTRS */ -Common subdirectories: rsync-2.6.4pre2-prexattr/zlib and rsync-2.6.4pre2/zlib ---- rsync-2.6.4/generator.c.xattr 2005-03-31 09:49:39.000000000 -0500 -+++ rsync-2.6.4/generator.c 2005-03-31 09:59:22.000000000 -0500 -@@ -715,6 +715,10 @@ - if (f_out == -1) - SET_ACL(fname, file); - #endif -+#if SUPPORT_XATTRS -+ if ( f_out == -1 ) -+ SET_XATTR( fname, file ); -+#endif - if (delete_during && f_out != -1 && !phase && dry_run < 2 - && (file->flags & FLAG_DEL_HERE)) - delete_in_dir(the_file_list, fname, file); ---- rsync-2.6.5/flist.c.xattr 2005-06-02 14:26:25.000000000 -0400 -+++ rsync-2.6.5/flist.c 2005-06-02 14:33:02.000000000 -0400 -@@ -976,6 +976,8 @@ - return NULL; - if (!MAKE_ACL(file, fname)) - return NULL; -+ if ( ! MAKE_XATTR(file, fname ) ) -+ return; - - maybe_emit_filelist_progress(flist->count + flist_count_offset); - -@@ -985,9 +987,11 @@ - flist->files[flist->count++] = file; - send_file_entry(file, f, base_flags); - SEND_ACL(file, f); -+ SEND_XATTR ( file, f ); - } else { - /* Cleanup unsent ACL(s). */ - SEND_ACL(file, -1); -+ SEND_XATTR( file, -1 ); - } - return file; - } -@@ -1325,6 +1329,7 @@ - file = receive_file_entry(flist, flags, f); - - RECEIVE_ACL(file, f); -+ RECEIVE_XATTR(file, f ); - - if (S_ISREG(file->mode)) - stats.total_size += file->length; -@@ -1349,6 +1354,7 @@ - clean_flist(flist, relative_paths, 1); - - SORT_FILE_ACL_INDEX_LISTS(); -+ SORT_FILE_XATTR_INDEX_LISTS(); - - if (f >= 0) { - /* Now send the uid/gid list. This was introduced in ---- rsync-2.6.6/Makefile.in.xattr 2005-07-28 16:16:07.000000000 -0400 -+++ rsync-2.6.6/Makefile.in 2005-07-28 16:18:13.000000000 -0400 -@@ -27,13 +27,13 @@ - - HEADERS=byteorder.h config.h errcode.h proto.h rsync.h smb_acls.h lib/pool_alloc.h - LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \ -- lib/permstring.o lib/pool_alloc.o lib/sysacls.o @LIBOBJS@ -+ lib/permstring.o lib/pool_alloc.o lib/sysacls.o lib/sysxattr.o @LIBOBJS@ - ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \ - zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o - OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \ - main.o checksum.o match.o syscall.o log.o backup.o - OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \ -- fileio.o batch.o clientname.o acls.o -+ fileio.o batch.o clientname.o acls.o xattr.o - OBJS3=progress.o pipe.o - DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o - popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \ -- 2.43.0