From be2a934add7d3fdf29752e6d4f31ba5e7e365022 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sun, 26 Jan 2014 10:06:58 -0800 Subject: [PATCH] The patches for 3.1.1pre1. --- acls.diff | 10 +- adaptec_acl_mods.diff | 2 +- atimes.diff | 24 +- backup-deleted.diff | 10 +- catch_crash_signals.diff | 4 +- checksum-reading.diff | 20 +- checksum-updating.diff | 18 +- checksum-xattr.diff | 6 +- copy-devices.diff | 6 +- crtimes.diff | 20 +- cvs-entries.diff | 2 +- date-only.diff | 4 +- db.diff | 2 +- detect-renamed-lax.diff | 2 +- detect-renamed.diff | 40 +- direct-io.diff | 2 +- downdate.diff | 8 +- fileflags.diff | 44 +- filter-attribute-mods.diff | 10 +- fsync.diff | 8 +- hfs-compression.diff | 38 +- ignore-case.diff | 2 +- link-by-hash.diff | 4 +- nameconverter.diff | 4 +- netgroup-auth.diff | 2 +- omit-dir-changes.diff | 10 +- openssl-support.diff | 1167 -------------------------------- slow-down.diff | 2 +- slp.diff | 2 +- soften-links.diff | 2 +- source-backup.diff | 2 +- source-filter_dest-filter.diff | 16 +- sparse-block.diff | 2 +- time-limit.diff | 8 +- transliterate.diff | 2 +- tru64.diff | 2 +- write-devices.diff | 16 +- xattrs.diff | 22 +- 38 files changed, 189 insertions(+), 1356 deletions(-) delete mode 100644 openssl-support.diff diff --git a/acls.diff b/acls.diff index 8d855af..4e62c17 100644 --- a/acls.diff +++ b/acls.diff @@ -9,7 +9,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/acls.c b/acls.c --- a/acls.c +++ b/acls.c @@ -40,7 +40,7 @@ diff --git a/acls.c b/acls.c static int calc_sacl_entries(const rsync_acl *racl) { /* A System ACL always gets user/group/other permission entries. */ -@@ -580,6 +593,96 @@ int get_acl(const char *fname, stat_x *sxp) +@@ -581,6 +594,96 @@ int get_acl(const char *fname, stat_x *sxp) return 0; } @@ -137,7 +137,7 @@ diff --git a/acls.c b/acls.c /* === Send functions === */ /* Send the ida list over the file descriptor. */ -@@ -655,6 +758,11 @@ static void send_rsync_acl(int f, rsync_acl *racl, SMB_ACL_TYPE_T type, +@@ -656,6 +759,11 @@ static void send_rsync_acl(int f, rsync_acl *racl, SMB_ACL_TYPE_T type, * This also frees the ACL data. */ void send_acl(int f, stat_x *sxp) { @@ -149,7 +149,7 @@ diff --git a/acls.c b/acls.c if (!sxp->acc_acl) { sxp->acc_acl = create_racl(); rsync_acl_fake_perms(sxp->acc_acl, sxp->st.st_mode); -@@ -672,6 +780,160 @@ void send_acl(int f, stat_x *sxp) +@@ -673,6 +781,160 @@ void send_acl(int f, stat_x *sxp) } } @@ -310,7 +310,7 @@ diff --git a/acls.c b/acls.c /* === Receive functions === */ static uint32 recv_acl_access(int f, uchar *name_follows_ptr) -@@ -793,6 +1055,11 @@ static int recv_rsync_acl(int f, item_list *racl_list, SMB_ACL_TYPE_T type, mode +@@ -794,6 +1056,11 @@ static int recv_rsync_acl(int f, item_list *racl_list, SMB_ACL_TYPE_T type, mode /* Receive the ACL info the sender has included for this file-list entry. */ void receive_acl(int f, struct file_struct *file) { diff --git a/adaptec_acl_mods.diff b/adaptec_acl_mods.diff index 91f5e80..26ffc45 100644 --- a/adaptec_acl_mods.diff +++ b/adaptec_acl_mods.diff @@ -24,7 +24,7 @@ Todo: Fix a bug that could lose some bits when stripping some (supposedly) superfluous ACL info. -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/lib/sysacls.c b/lib/sysacls.c --- a/lib/sysacls.c +++ b/lib/sysacls.c diff --git a/atimes.diff b/atimes.diff index fb47106..f43d0ec 100644 --- a/atimes.diff +++ b/atimes.diff @@ -4,7 +4,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/compat.c b/compat.c --- a/compat.c +++ b/compat.c @@ -134,7 +134,7 @@ diff --git a/generator.c b/generator.c #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST if (S_ISLNK(file->mode)) { ; -@@ -907,6 +910,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, +@@ -905,6 +908,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, if (link_dest) { if (!hard_link_one(file, fname, cmpbuf, 1)) goto try_a_copy; @@ -143,7 +143,7 @@ diff --git a/generator.c b/generator.c if (preserve_hard_links && F_IS_HLINKED(file)) finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j); if (!maybe_ATTRS_REPORT && (INFO_GTE(NAME, 2) || stdout_format_has_i > 1)) { -@@ -1109,6 +1114,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, +@@ -1107,6 +1112,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, static void list_file_entry(struct file_struct *f) { char permbuf[PERMSTRING_SIZE]; @@ -151,7 +151,7 @@ diff --git a/generator.c b/generator.c int64 len; int colwidth = human_readable ? 14 : 11; -@@ -1124,10 +1130,12 @@ static void list_file_entry(struct file_struct *f) +@@ -1122,10 +1128,12 @@ static void list_file_entry(struct file_struct *f) #ifdef SUPPORT_LINKS if (preserve_links && S_ISLNK(f->mode)) { @@ -167,7 +167,7 @@ diff --git a/generator.c b/generator.c } else #endif if (missing_args == 2 && f->mode == 0) { -@@ -1135,9 +1143,12 @@ static void list_file_entry(struct file_struct *f) +@@ -1133,9 +1141,12 @@ static void list_file_entry(struct file_struct *f) colwidth + 31, "*missing", f_name(f, NULL)); } else { @@ -182,7 +182,7 @@ diff --git a/generator.c b/generator.c } } -@@ -2034,7 +2045,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx) +@@ -2036,7 +2047,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx) STRUCT_STAT st; if (link_stat(fname, &st, 0) == 0 && cmp_time(st.st_mtime, file->modtime) != 0) @@ -226,7 +226,7 @@ diff --git a/ifuncs.h b/ifuncs.h diff --git a/log.c b/log.c --- a/log.c +++ b/log.c -@@ -721,7 +721,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op, +@@ -720,7 +720,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op, c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p'; c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o'; c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g'; @@ -285,7 +285,7 @@ diff --git a/rsync.c b/rsync.c mode_t new_mode = file->mode; int inherit; -@@ -496,22 +497,40 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -543,22 +544,40 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, set_xattr(fname, file, fnamecmp, sxp); #endif @@ -329,7 +329,7 @@ diff --git a/rsync.c b/rsync.c + } } - change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file); + #ifdef SUPPORT_ACLS @@ -662,7 +681,7 @@ int finish_transfer(const char *fname, const char *fnametmp, /* Change permissions before putting the file into place. */ @@ -692,7 +692,7 @@ diff --git a/tls.c b/tls.c diff --git a/util.c b/util.c --- a/util.c +++ b/util.c -@@ -116,20 +116,24 @@ void print_child_argv(const char *prefix, char **cmd) +@@ -117,20 +117,24 @@ void print_child_argv(const char *prefix, char **cmd) /* This returns 0 for success, 1 for a symlink if symlink time-setting * is not possible, or -1 for any other error. */ @@ -721,7 +721,7 @@ diff --git a/util.c b/util.c break; if (errno != ENOSYS) return -1; -@@ -139,7 +143,7 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) +@@ -140,7 +144,7 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) #ifdef HAVE_LUTIMES #include "case_N.h" @@ -730,7 +730,7 @@ diff --git a/util.c b/util.c break; if (errno != ENOSYS) return -1; -@@ -158,10 +162,10 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) +@@ -159,10 +163,10 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) #include "case_N.h" #ifdef HAVE_UTIMES diff --git a/backup-deleted.diff b/backup-deleted.diff index 9f520bc..67a18c5 100644 --- a/backup-deleted.diff +++ b/backup-deleted.diff @@ -7,11 +7,11 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -1764,7 +1764,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1766,7 +1766,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto notify_others; if (read_batch || whole_file) { @@ -20,7 +20,7 @@ diff --git a/generator.c b/generator.c if (!(backupptr = get_backup_name(fname))) goto cleanup; if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) -@@ -1800,7 +1800,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1802,7 +1802,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto notify_others; } @@ -29,7 +29,7 @@ diff --git a/generator.c b/generator.c if (!(backupptr = get_backup_name(fname))) { close(fd); goto cleanup; -@@ -1924,7 +1924,7 @@ int atomic_create(struct file_struct *file, char *fname, const char *lnk, +@@ -1926,7 +1926,7 @@ int atomic_create(struct file_struct *file, char *fname, const char *lnk, skip_atomic = 0; if (del_for_flag) { @@ -82,7 +82,7 @@ diff --git a/receiver.c b/receiver.c continue; if (DEBUG_GTE(RECV, 1)) { rprintf(FINFO, "renaming %s to %s\n", -@@ -732,7 +732,7 @@ int recv_files(int f_in, int f_out, char *local_name) +@@ -730,7 +730,7 @@ int recv_files(int f_in, int f_out, char *local_name) } else { /* Reminder: --inplace && --partial-dir are never * enabled at the same time. */ diff --git a/catch_crash_signals.diff b/catch_crash_signals.diff index 8e435f7..700baa6 100644 --- a/catch_crash_signals.diff +++ b/catch_crash_signals.diff @@ -25,7 +25,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/errcode.h b/errcode.h --- a/errcode.h +++ b/errcode.h @@ -41,7 +41,7 @@ diff --git a/errcode.h b/errcode.h diff --git a/log.c b/log.c --- a/log.c +++ b/log.c -@@ -92,6 +92,7 @@ struct { +@@ -91,6 +91,7 @@ struct { { RERR_TERMINATED , "sibling process terminated abnormally" }, { RERR_SIGNAL1 , "received SIGUSR1" }, { RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" }, diff --git a/checksum-reading.diff b/checksum-reading.diff index 49e6957..6735e5c 100644 --- a/checksum-reading.diff +++ b/checksum-reading.diff @@ -16,7 +16,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/checksum.c b/checksum.c --- a/checksum.c +++ b/checksum.c @@ -475,7 +475,7 @@ diff --git a/generator.c b/generator.c extern int remove_source_files; extern int delay_updates; extern int update_only; -@@ -565,7 +566,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre +@@ -563,7 +564,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre /* Perform our quick-check heuristic for determining if a file is unchanged. */ @@ -484,7 +484,7 @@ diff --git a/generator.c b/generator.c { if (st->st_size != F_LENGTH(file)) return 0; -@@ -574,7 +575,10 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st) +@@ -572,7 +573,10 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st) of the file time to determine whether to sync */ if (always_checksum > 0 && S_ISREG(st->st_mode)) { char sum[MAX_DIGEST_LEN]; @@ -496,7 +496,7 @@ diff --git a/generator.c b/generator.c return memcmp(sum, F_SUM(file), checksum_len) == 0; } -@@ -867,7 +871,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, +@@ -865,7 +869,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, match_level = 1; /* FALL THROUGH */ case 1: @@ -505,7 +505,7 @@ diff --git a/generator.c b/generator.c continue; best_match = j; match_level = 2; -@@ -1173,7 +1177,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1171,7 +1175,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, * --ignore-non-existing, daemon exclude, or mkdir failure. */ static struct file_struct *skip_dir = NULL; static struct file_list *fuzzy_dirlist[MAX_BASIS_DIRS+1]; @@ -514,7 +514,7 @@ diff --git a/generator.c b/generator.c struct file_struct *fuzzy_file = NULL; int fd = -1, f_copy = -1; stat_x sx, real_sx; -@@ -1264,8 +1268,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1262,8 +1266,9 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, fuzzy_dirlist[i] = NULL; } } @@ -526,7 +526,7 @@ diff --git a/generator.c b/generator.c #ifdef SUPPORT_ACLS if (!preserve_perms) dflt_perms = default_perms_for_dir(dn); -@@ -1273,7 +1278,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1271,7 +1276,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } parent_dirname = dn; @@ -535,7 +535,7 @@ diff --git a/generator.c b/generator.c int i; strlcpy(fnamecmpbuf, dn, sizeof fnamecmpbuf); for (i = 0; i < fuzzy_basis; i++) { -@@ -1285,7 +1290,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1283,7 +1288,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, fuzzy_dirlist[i] = NULL; } } @@ -547,7 +547,7 @@ diff --git a/generator.c b/generator.c } statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir); -@@ -1724,7 +1732,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1726,7 +1734,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, ; else if (fnamecmp_type == FNAMECMP_FUZZY) ; @@ -717,7 +717,7 @@ diff --git a/rsync.h b/rsync.h /* Some utility defines: */ #define F_IS_ACTIVE(f) (f)->basename[0] #define F_IS_HLINKED(f) ((f)->flags & FLAG_HLINKED) -@@ -967,6 +971,13 @@ typedef struct { +@@ -969,6 +973,13 @@ typedef struct { char fname[1]; /* has variable size */ } relnamecache; diff --git a/checksum-updating.diff b/checksum-updating.diff index 3e17a8d..478132f 100644 --- a/checksum-updating.diff +++ b/checksum-updating.diff @@ -455,7 +455,7 @@ diff --git a/generator.c b/generator.c static const char *solo_file = NULL; enum nonregtype { -@@ -576,7 +577,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot +@@ -574,7 +575,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot if (always_checksum > 0 && S_ISREG(st->st_mode)) { char sum[MAX_DIGEST_LEN]; if (checksum_files && slot >= 0) @@ -464,7 +464,7 @@ diff --git a/generator.c b/generator.c else file_checksum(fn, st->st_size, sum); return memcmp(sum, F_SUM(file), checksum_len) == 0; -@@ -1291,7 +1292,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1289,7 +1290,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } } if (checksum_files) { @@ -474,7 +474,7 @@ diff --git a/generator.c b/generator.c } need_new_dirscan = 0; } -@@ -1463,6 +1465,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1461,6 +1463,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, else change_local_filter_dir(fname, strlen(fname), F_DEPTH(file)); } @@ -482,7 +482,7 @@ diff --git a/generator.c b/generator.c goto cleanup; } -@@ -1738,6 +1741,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1740,6 +1743,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, handle_partial_dir(partialptr, PDIR_DELETE); } set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT); @@ -491,7 +491,7 @@ diff --git a/generator.c b/generator.c if (itemizing) itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL); #ifdef SUPPORT_HARD_LINKS -@@ -2232,6 +2237,7 @@ void generate_files(int f_out, const char *local_name) +@@ -2234,6 +2239,7 @@ void generate_files(int f_out, const char *local_name) } else change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp)); } @@ -499,7 +499,7 @@ diff --git a/generator.c b/generator.c } for (i = cur_flist->low; i <= cur_flist->high; i++) { struct file_struct *file = cur_flist->sorted[i]; -@@ -2326,6 +2332,9 @@ void generate_files(int f_out, const char *local_name) +@@ -2328,6 +2334,9 @@ void generate_files(int f_out, const char *local_name) wait_for_receiver(); } @@ -520,7 +520,7 @@ diff --git a/io.c b/io.c extern int protocol_version; extern int remove_source_files; extern int preserve_hard_links; -@@ -1067,6 +1068,9 @@ static void got_flist_entry_status(enum festatus status, int ndx) +@@ -1050,6 +1051,9 @@ static void got_flist_entry_status(enum festatus status, int ndx) if (inc_recurse) flist->in_progress++; } @@ -584,7 +584,7 @@ diff --git a/receiver.c b/receiver.c || (preserve_hard_links && F_IS_HLINKED(file))) send_msg_int(MSG_SUCCESS, ndx); handle_partial_dir(partialptr, PDIR_DELETE); -@@ -894,7 +895,7 @@ int recv_files(int f_in, int f_out, char *local_name) +@@ -892,7 +893,7 @@ int recv_files(int f_in, int f_out, char *local_name) case 2: break; case 1: @@ -596,7 +596,7 @@ diff --git a/receiver.c b/receiver.c diff --git a/rsync.h b/rsync.h --- a/rsync.h +++ b/rsync.h -@@ -973,6 +973,8 @@ typedef struct { +@@ -975,6 +975,8 @@ typedef struct { #define CSF_ENABLE (1<<1) #define CSF_LAX (1<<2) diff --git a/checksum-xattr.diff b/checksum-xattr.diff index bceeb0f..0fef552 100644 --- a/checksum-xattr.diff +++ b/checksum-xattr.diff @@ -8,7 +8,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/flist.c b/flist.c --- a/flist.c +++ b/flist.c @@ -25,7 +25,7 @@ diff --git a/flist.c b/flist.c diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -574,7 +574,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st) +@@ -572,7 +572,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st) of the file time to determine whether to sync */ if (always_checksum > 0 && S_ISREG(st->st_mode)) { char sum[MAX_DIGEST_LEN]; @@ -278,7 +278,7 @@ diff --git a/xattrs.c b/xattrs.c continue; } -@@ -957,6 +965,39 @@ int del_def_xattr_acl(const char *fname) +@@ -958,6 +966,39 @@ int del_def_xattr_acl(const char *fname) } #endif diff --git a/copy-devices.diff b/copy-devices.diff index 39b629f..9a0f9d9 100644 --- a/copy-devices.diff +++ b/copy-devices.diff @@ -8,7 +8,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c @@ -20,7 +20,7 @@ diff --git a/generator.c b/generator.c extern int preserve_specials; extern int preserve_hard_links; extern int preserve_executability; -@@ -1620,7 +1621,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1622,7 +1623,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } @@ -90,7 +90,7 @@ diff --git a/rsync.c b/rsync.c diff --git a/sender.c b/sender.c --- a/sender.c +++ b/sender.c -@@ -364,6 +364,20 @@ void send_files(int f_in, int f_out) +@@ -363,6 +363,20 @@ void send_files(int f_in, int f_out) exit_cleanup(RERR_FILEIO); } diff --git a/crtimes.diff b/crtimes.diff index bb14dd8..78f93f2 100644 --- a/crtimes.diff +++ b/crtimes.diff @@ -188,7 +188,7 @@ diff --git a/generator.c b/generator.c #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST if (S_ISLNK(file->mode)) { ; -@@ -1120,6 +1134,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, +@@ -1118,6 +1132,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, static void list_file_entry(struct file_struct *f) { char permbuf[PERMSTRING_SIZE]; @@ -196,7 +196,7 @@ diff --git a/generator.c b/generator.c int64 len; int colwidth = human_readable ? 14 : 11; -@@ -1135,10 +1150,12 @@ static void list_file_entry(struct file_struct *f) +@@ -1133,10 +1148,12 @@ static void list_file_entry(struct file_struct *f) #ifdef SUPPORT_LINKS if (preserve_links && S_ISLNK(f->mode)) { @@ -212,7 +212,7 @@ diff --git a/generator.c b/generator.c } else #endif if (missing_args == 2 && f->mode == 0) { -@@ -1146,9 +1163,12 @@ static void list_file_entry(struct file_struct *f) +@@ -1144,9 +1161,12 @@ static void list_file_entry(struct file_struct *f) colwidth + 31, "*missing", f_name(f, NULL)); } else { @@ -227,7 +227,7 @@ diff --git a/generator.c b/generator.c } } -@@ -1240,6 +1260,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1238,6 +1258,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, return; } } @@ -270,7 +270,7 @@ diff --git a/ifuncs.h b/ifuncs.h diff --git a/log.c b/log.c --- a/log.c +++ b/log.c -@@ -724,7 +724,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op, +@@ -723,7 +723,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op, c[8] = !(iflags & ITEM_REPORT_FFLAGS) ? '.' : 'f'; c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a'; c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x'; @@ -321,7 +321,7 @@ diff --git a/options.c b/options.c diff --git a/rsync.c b/rsync.c --- a/rsync.c +++ b/rsync.c -@@ -534,6 +534,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -581,6 +581,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, || (!(preserve_times & PRESERVE_DIR_TIMES) && S_ISDIR(sxp->st.st_mode)) || (!(preserve_times & PRESERVE_LINK_TIMES) && S_ISLNK(sxp->st.st_mode))) flags |= ATTRS_SKIP_MTIME; @@ -331,7 +331,7 @@ diff --git a/rsync.c b/rsync.c if (!(flags & ATTRS_SKIP_MTIME) && cmp_time(sxp->st.st_mtime, file->modtime) != 0) { int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode, ST_FLAGS(sxp->st)); -@@ -547,6 +550,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -594,6 +597,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, else file->flags |= FLAG_TIME_FAILED; } @@ -344,8 +344,8 @@ diff --git a/rsync.c b/rsync.c + updated = 1; + } - change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file); - change_gid = gid_ndx && !(file->flags & FLAG_SKIP_GROUP) + #ifdef SUPPORT_ACLS + /* It's OK to call set_acl() now, even for a dir, as the generator @@ -710,7 +721,7 @@ int finish_transfer(const char *fname, const char *fnametmp, /* Change permissions before putting the file into place. */ set_file_attrs(fnametmp, file, NULL, fnamecmp, @@ -410,7 +410,7 @@ diff --git a/rsync.h b/rsync.h #define DEV_EXTRA_CNT 2 #define DIRNODE_EXTRA_CNT 3 #define SUM_EXTRA_CNT ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN) -@@ -1019,6 +1023,7 @@ typedef struct { +@@ -1021,6 +1025,7 @@ typedef struct { typedef struct { STRUCT_STAT st; diff --git a/cvs-entries.diff b/cvs-entries.diff index e6e99bb..53355c1 100644 --- a/cvs-entries.diff +++ b/cvs-entries.diff @@ -8,7 +8,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/exclude.c b/exclude.c --- a/exclude.c +++ b/exclude.c diff --git a/date-only.diff b/date-only.diff index 5cc76dd..43fe88f 100644 --- a/date-only.diff +++ b/date-only.diff @@ -14,7 +14,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c @@ -26,7 +26,7 @@ diff --git a/generator.c b/generator.c extern int size_only; extern OFF_T max_size; extern OFF_T min_size; -@@ -567,6 +568,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre +@@ -565,6 +566,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre /* Perform our quick-check heuristic for determining if a file is unchanged. */ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st) { diff --git a/db.diff b/db.diff index a151907..865fb66 100644 --- a/db.diff +++ b/db.diff @@ -21,7 +21,7 @@ To use this patch, run these commands for a successful build: ./configure make -based-on: a3f852bd7864ffd61ae709bc756e73034d4c33a3 +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore diff --git a/detect-renamed-lax.diff b/detect-renamed-lax.diff index 7aa5159..67f30ad 100644 --- a/detect-renamed-lax.diff +++ b/detect-renamed-lax.diff @@ -35,7 +35,7 @@ diff --git a/generator.c b/generator.c diff = u_strcmp(fmid->basename, f->basename); if (diff == 0) { good_match = mid; -@@ -1908,6 +1910,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1910,6 +1912,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, fnamecmp = partialptr; fnamecmp_type = FNAMECMP_PARTIAL_DIR; statret = 0; diff --git a/detect-renamed.diff b/detect-renamed.diff index 92ae775..495bfdc 100644 --- a/detect-renamed.diff +++ b/detect-renamed.diff @@ -38,7 +38,7 @@ TODO: a file that can't use it, while missing out on giving it to a file that could use it. -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/compat.c b/compat.c --- a/compat.c +++ b/compat.c @@ -458,7 +458,7 @@ diff --git a/generator.c b/generator.c static inline int time_differs(struct file_struct *file, stat_x *sxp) { return cmp_time(sxp->st.st_mtime, file->modtime); -@@ -1141,6 +1281,7 @@ static void list_file_entry(struct file_struct *f) +@@ -1139,6 +1279,7 @@ static void list_file_entry(struct file_struct *f) } } @@ -466,7 +466,7 @@ diff --git a/generator.c b/generator.c static int phase = 0; static int dflt_perms; -@@ -1250,7 +1391,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1248,7 +1389,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, && do_stat(dn, &sx.st) < 0) { if (dry_run) goto parent_is_dry_missing; @@ -475,7 +475,7 @@ diff --git a/generator.c b/generator.c rsyserr(FERROR_XFER, errno, "recv_generator: mkdir %s failed", full_fname(dn)); -@@ -1401,7 +1542,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1399,7 +1540,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } if (real_ret != 0 && do_mkdir(fname,file->mode|added_perms) < 0 && errno != EEXIST) { if (!relative_paths || errno != ENOENT @@ -484,7 +484,7 @@ diff --git a/generator.c b/generator.c || (do_mkdir(fname, file->mode|added_perms) < 0 && errno != EEXIST)) { rsyserr(FERROR_XFER, errno, "recv_generator: mkdir %s failed", -@@ -1450,9 +1591,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1448,9 +1589,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } else if (delete_during && f_out != -1 && !phase && !(file->flags & FLAG_MISSING_DIR)) { @@ -500,7 +500,7 @@ diff --git a/generator.c b/generator.c change_local_filter_dir(fname, strlen(fname), F_DEPTH(file)); } goto cleanup; -@@ -1713,8 +1857,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1715,8 +1859,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } #endif @@ -516,7 +516,7 @@ diff --git a/generator.c b/generator.c rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s", full_fname(fname)); goto cleanup; -@@ -2174,6 +2324,12 @@ void generate_files(int f_out, const char *local_name) +@@ -2176,6 +2326,12 @@ void generate_files(int f_out, const char *local_name) if (DEBUG_GTE(GENR, 1)) rprintf(FINFO, "generator starting pid=%d\n", (int)getpid()); @@ -529,7 +529,7 @@ diff --git a/generator.c b/generator.c if (delete_before && !solo_file && cur_flist->used > 0) do_delete_pass(); if (delete_during == 2) { -@@ -2184,7 +2340,7 @@ void generate_files(int f_out, const char *local_name) +@@ -2186,7 +2342,7 @@ void generate_files(int f_out, const char *local_name) } info_levels[INFO_FLIST] = info_levels[INFO_PROGRESS] = 0; @@ -538,7 +538,7 @@ diff --git a/generator.c b/generator.c whole_file = 0; if (DEBUG_GTE(FLIST, 1)) { rprintf(FINFO, "delta-transmission %s\n", -@@ -2220,7 +2376,7 @@ void generate_files(int f_out, const char *local_name) +@@ -2222,7 +2378,7 @@ void generate_files(int f_out, const char *local_name) dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); } else dirdev = MAKEDEV(0, 0); @@ -547,7 +547,7 @@ diff --git a/generator.c b/generator.c } else change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp)); } -@@ -2267,7 +2423,21 @@ void generate_files(int f_out, const char *local_name) +@@ -2269,7 +2425,21 @@ void generate_files(int f_out, const char *local_name) } while ((cur_flist = cur_flist->next) != NULL); if (delete_during) @@ -703,7 +703,7 @@ diff --git a/rsync.yo b/rsync.yo diff --git a/util.c b/util.c --- a/util.c +++ b/util.c -@@ -174,7 +174,7 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) +@@ -175,7 +175,7 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) /* Create any necessary directories in fname. Any missing directories are * created with default permissions. Returns < 0 on error, or the number * of directories created. */ @@ -712,16 +712,16 @@ diff --git a/util.c b/util.c { char *end, *p; int ret = 0; -@@ -197,7 +197,7 @@ int make_path(char *fname, int flags) - - /* Try to find an existing dir, starting from the deepest dir. */ - for (p = end; ; ) { -- if (do_mkdir(fname, ACCESSPERMS) == 0) { -+ if (do_mkdir(fname, mode) == 0) { +@@ -206,7 +206,7 @@ int make_path(char *fname, int flags) + else + errno = ENOTDIR; + } +- } else if (do_mkdir(fname, ACCESSPERMS) == 0) { ++ } else if (do_mkdir(fname, mode) == 0) { ret++; break; } -@@ -229,7 +229,7 @@ int make_path(char *fname, int flags) +@@ -243,7 +243,7 @@ int make_path(char *fname, int flags) p += strlen(p); if (ret < 0) /* Skip mkdir on error, but keep restoring the path. */ continue; @@ -730,7 +730,7 @@ diff --git a/util.c b/util.c ret = -ret - 1; else ret++; -@@ -1111,6 +1111,32 @@ char *normalize_path(char *path, BOOL force_newbuf, unsigned int *len_ptr) +@@ -1125,6 +1125,32 @@ char *normalize_path(char *path, BOOL force_newbuf, unsigned int *len_ptr) return path; } @@ -763,7 +763,7 @@ diff --git a/util.c b/util.c /** * Return a quoted string with the full pathname of the indicated filename. * The string " (in MODNAME)" may also be appended. The returned pointer -@@ -1204,7 +1230,7 @@ int handle_partial_dir(const char *fname, int create) +@@ -1218,7 +1244,7 @@ int handle_partial_dir(const char *fname, int create) } statret = -1; } diff --git a/direct-io.diff b/direct-io.diff index 33d888c..1f057da 100644 --- a/direct-io.diff +++ b/direct-io.diff @@ -10,7 +10,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/options.c b/options.c --- a/options.c +++ b/options.c diff --git a/downdate.diff b/downdate.diff index 476e73f..d98e67b 100644 --- a/downdate.diff +++ b/downdate.diff @@ -7,7 +7,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c @@ -19,7 +19,7 @@ diff --git a/generator.c b/generator.c extern int human_readable; extern int ignore_existing; extern int ignore_non_existing; -@@ -1655,6 +1656,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1657,6 +1658,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } @@ -33,7 +33,7 @@ diff --git a/generator.c b/generator.c fnamecmp_type = FNAMECMP_FNAME; if (statret == 0 && !S_ISREG(sx.st.st_mode)) { -@@ -2080,6 +2088,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) +@@ -2082,6 +2090,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) ignore_existing = -ignore_existing; ignore_non_existing = -ignore_non_existing; update_only = -update_only; @@ -41,7 +41,7 @@ diff --git a/generator.c b/generator.c always_checksum = -always_checksum; size_only = -size_only; append_mode = -append_mode; -@@ -2105,6 +2114,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) +@@ -2107,6 +2116,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) ignore_existing = -ignore_existing; ignore_non_existing = -ignore_non_existing; update_only = -update_only; diff --git a/fileflags.diff b/fileflags.diff index 908892c..1f265fc 100644 --- a/fileflags.diff +++ b/fileflags.diff @@ -8,7 +8,7 @@ To use this patch, run these commands for a successful build: ./configure make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/Makefile.in b/Makefile.in --- a/Makefile.in +++ b/Makefile.in @@ -257,7 +257,7 @@ diff --git a/generator.c b/generator.c #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { if (!ACL_READY(*sxp)) -@@ -1383,6 +1394,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1381,6 +1392,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms, statret == 0); } @@ -268,7 +268,7 @@ diff --git a/generator.c b/generator.c if (statret != 0 && basis_dir[0] != NULL) { int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx, itemizing, code); -@@ -1427,10 +1442,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1425,10 +1440,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, * readable and writable permissions during the time we are * putting files within them. This is then restored to the * former permissions after the transfer is done. */ @@ -285,7 +285,7 @@ diff --git a/generator.c b/generator.c rsyserr(FERROR_XFER, errno, "failed to modify permissions on %s", full_fname(fname)); -@@ -1465,6 +1485,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1463,6 +1483,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms, exists); } @@ -296,7 +296,7 @@ diff --git a/generator.c b/generator.c #ifdef SUPPORT_HARD_LINKS if (preserve_hard_links && F_HLINK_NOT_FIRST(file) -@@ -2029,13 +2053,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx) +@@ -2031,13 +2055,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx) continue; fname = f_name(file, NULL); if (fix_dir_perms) @@ -319,7 +319,7 @@ diff --git a/generator.c b/generator.c diff --git a/log.c b/log.c --- a/log.c +++ b/log.c -@@ -721,7 +721,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op, +@@ -720,7 +720,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op, c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p'; c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o'; c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g'; @@ -548,16 +548,7 @@ diff --git a/rsync.c b/rsync.c int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, const char *fnamecmp, int flags) { -@@ -502,7 +536,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, - flags |= ATTRS_SKIP_MTIME; - if (!(flags & ATTRS_SKIP_MTIME) - && cmp_time(sxp->st.st_mtime, file->modtime) != 0) { -- int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode); -+ int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode, ST_FLAGS(sxp->st)); - if (ret < 0) { - rsyserr(FERROR_XFER, errno, "failed to set times on %s", - full_fname(fname)); -@@ -538,7 +572,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -513,7 +547,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, if (am_root >= 0) { uid_t uid = change_uid ? (uid_t)F_OWNER(file) : sxp->st.st_uid; gid_t gid = change_gid ? (gid_t)F_GROUP(file) : sxp->st.st_gid; @@ -566,6 +557,15 @@ diff --git a/rsync.c b/rsync.c /* We shouldn't have attempted to change uid * or gid unless have the privilege. */ rsyserr(FERROR_XFER, errno, "%s %s failed", +@@ -549,7 +583,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, + flags |= ATTRS_SKIP_MTIME; + if (!(flags & ATTRS_SKIP_MTIME) + && cmp_time(sxp->st.st_mtime, file->modtime) != 0) { +- int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode); ++ int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode, ST_FLAGS(sxp->st)); + if (ret < 0) { + rsyserr(FERROR_XFER, errno, "failed to set times on %s", + full_fname(fname)); @@ -576,7 +610,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, #ifdef HAVE_CHMOD @@ -1031,7 +1031,7 @@ diff --git a/t_stub.c b/t_stub.c diff --git a/util.c b/util.c --- a/util.c +++ b/util.c -@@ -32,6 +32,7 @@ extern int relative_paths; +@@ -33,6 +33,7 @@ extern int relative_paths; extern int preserve_times; extern int preserve_xattrs; extern int preallocate_files; @@ -1039,7 +1039,7 @@ diff --git a/util.c b/util.c extern char *module_dir; extern unsigned int module_dirlen; extern char *partial_dir; -@@ -114,9 +115,36 @@ void print_child_argv(const char *prefix, char **cmd) +@@ -115,9 +116,36 @@ void print_child_argv(const char *prefix, char **cmd) rprintf(FCLIENT, " (%d args)\n", cnt); } @@ -1077,7 +1077,7 @@ diff --git a/util.c b/util.c { static int switch_step = 0; -@@ -131,6 +159,11 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) +@@ -132,6 +160,11 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) #include "case_N.h" if (do_utimensat(fname, modtime, mod_nsec) == 0) break; @@ -1089,7 +1089,7 @@ diff --git a/util.c b/util.c if (errno != ENOSYS) return -1; switch_step++; -@@ -141,6 +174,11 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) +@@ -142,6 +175,11 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) #include "case_N.h" if (do_lutimes(fname, modtime, mod_nsec) == 0) break; @@ -1101,7 +1101,7 @@ diff --git a/util.c b/util.c if (errno != ENOSYS) return -1; switch_step++; -@@ -164,6 +202,13 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) +@@ -165,6 +203,13 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) if (do_utime(fname, modtime, mod_nsec) == 0) break; #endif @@ -1118,7 +1118,7 @@ diff --git a/util.c b/util.c diff --git a/xattrs.c b/xattrs.c --- a/xattrs.c +++ b/xattrs.c -@@ -1043,7 +1043,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) +@@ -1044,7 +1044,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) mode = (fst.st_mode & _S_IFMT) | (fmode & ACCESSPERMS) | (S_ISDIR(fst.st_mode) ? 0700 : 0600); if (fst.st_mode != mode) diff --git a/filter-attribute-mods.diff b/filter-attribute-mods.diff index ac05ac0..3afaf3e 100644 --- a/filter-attribute-mods.diff +++ b/filter-attribute-mods.diff @@ -9,7 +9,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/exclude.c b/exclude.c --- a/exclude.c +++ b/exclude.c @@ -343,7 +343,7 @@ diff --git a/rsync.h b/rsync.h #define XFLG_FATAL_ERRORS (1<<0) #define XFLG_OLD_PREFIXES (1<<1) -@@ -853,6 +856,8 @@ struct map_struct { +@@ -855,6 +858,8 @@ struct map_struct { int status; /* first errno from read errors */ }; @@ -352,7 +352,7 @@ diff --git a/rsync.h b/rsync.h #define FILTRULE_WILD (1<<0) /* pattern has '*', '[', and/or '?' */ #define FILTRULE_WILD2 (1<<1) /* pattern has '**' */ #define FILTRULE_WILD2_PREFIX (1<<2) /* pattern starts with "**" */ -@@ -873,8 +878,18 @@ struct map_struct { +@@ -875,8 +880,18 @@ struct map_struct { #define FILTRULE_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */ #define FILTRULE_CLEAR_LIST (1<<18)/* this item is the "!" token */ #define FILTRULE_PERISHABLE (1<<19)/* perishable if parent dir goes away */ @@ -371,7 +371,7 @@ diff --git a/rsync.h b/rsync.h typedef struct filter_struct { struct filter_struct *next; -@@ -884,6 +899,11 @@ typedef struct filter_struct { +@@ -886,6 +901,11 @@ typedef struct filter_struct { int slash_cnt; struct filter_list_struct *mergelist; } u; @@ -438,7 +438,7 @@ diff --git a/rsync.yo b/rsync.yo diff --git a/util.c b/util.c --- a/util.c +++ b/util.c -@@ -836,6 +836,25 @@ size_t stringjoin(char *dest, size_t destsize, ...) +@@ -850,6 +850,25 @@ size_t stringjoin(char *dest, size_t destsize, ...) return ret; } diff --git a/fsync.diff b/fsync.diff index 31e0a6c..7bb6ae7 100644 --- a/fsync.diff +++ b/fsync.diff @@ -7,7 +7,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/options.c b/options.c --- a/options.c +++ b/options.c @@ -83,15 +83,15 @@ diff --git a/t_stub.c b/t_stub.c diff --git a/util.c b/util.c --- a/util.c +++ b/util.c -@@ -26,6 +26,7 @@ - #include "inums.h" +@@ -27,6 +27,7 @@ + extern int dry_run; extern int module_id; +extern int do_fsync; extern int protect_args; extern int modify_window; extern int relative_paths; -@@ -397,6 +398,13 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode) +@@ -411,6 +412,13 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode) } #endif diff --git a/hfs-compression.diff b/hfs-compression.diff index c614aba..b1b2125 100644 --- a/hfs-compression.diff +++ b/hfs-compression.diff @@ -43,7 +43,7 @@ diff --git a/generator.c b/generator.c extern int preserve_links; extern int preserve_devices; extern int preserve_specials; -@@ -1750,6 +1751,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1748,6 +1749,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, fname, fnamecmpbuf); } sx.st.st_size = F_LENGTH(fuzzy_file); @@ -58,7 +58,7 @@ diff --git a/generator.c b/generator.c statret = 0; fnamecmp = fnamecmpbuf; } -@@ -1917,6 +1926,18 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1915,6 +1924,18 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, if (read_batch) goto cleanup; @@ -311,7 +311,7 @@ diff --git a/options.c b/options.c diff --git a/rsync.c b/rsync.c --- a/rsync.c +++ b/rsync.c -@@ -526,8 +526,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -573,8 +573,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, #ifdef SUPPORT_XATTRS if (am_root < 0) set_stat_xattr(fname, file, new_mode); @@ -327,7 +327,7 @@ diff --git a/rsync.c b/rsync.c #endif if (!preserve_times -@@ -538,6 +544,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -585,6 +591,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, if (sxp->st.st_ino == 2 && S_ISDIR(sxp->st.st_mode)) flags |= ATTRS_SKIP_CRTIME; if (!(flags & ATTRS_SKIP_MTIME) @@ -586,16 +586,16 @@ diff --git a/xattrs.c b/xattrs.c } else name_offset = datum_len; -@@ -310,7 +359,7 @@ int get_xattr(const char *fname, stat_x *sxp) - return 0; - } +@@ -311,7 +360,7 @@ int get_xattr(const char *fname, stat_x *sxp) + } else if (IS_MISSING_FILE(sxp->st)) + return 0; - if (rsync_xal_get(fname, sxp->xattr) < 0) { + if (rsync_xal_get(fname, sxp) < 0) { free_xattr(sxp); return -1; } -@@ -345,6 +394,8 @@ int copy_xattrs(const char *source, const char *dest) +@@ -346,6 +395,8 @@ int copy_xattrs(const char *source, const char *dest) datum_len = 0; if (!(ptr = get_xattr_data(source, name, &datum_len, 0))) return -1; @@ -604,7 +604,7 @@ diff --git a/xattrs.c b/xattrs.c if (sys_lsetxattr(dest, name, ptr, datum_len) < 0) { int save_errno = errno ? errno : EINVAL; rsyserr(FERROR_XFER, errno, -@@ -361,6 +412,10 @@ int copy_xattrs(const char *source, const char *dest) +@@ -362,6 +413,10 @@ int copy_xattrs(const char *source, const char *dest) static int find_matching_xattr(item_list *xalp) { @@ -615,7 +615,7 @@ diff --git a/xattrs.c b/xattrs.c size_t i, j; item_list *lst = rsync_xal_l.items; -@@ -394,6 +449,7 @@ static int find_matching_xattr(item_list *xalp) +@@ -395,6 +450,7 @@ static int find_matching_xattr(item_list *xalp) } return -1; @@ -623,7 +623,7 @@ diff --git a/xattrs.c b/xattrs.c } /* Store *xalp on the end of rsync_xal_l */ -@@ -573,11 +629,13 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out) +@@ -574,11 +630,13 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out) /* Re-read the long datum. */ if (!(ptr = get_xattr_data(fname, rxa->name, &len, 0))) { @@ -638,7 +638,7 @@ diff --git a/xattrs.c b/xattrs.c write_varint(f_out, len); /* length might have changed! */ write_bigbuf(f_out, ptr, len); free(ptr); -@@ -793,7 +851,7 @@ static int rsync_xal_set(const char *fname, item_list *xalp, +@@ -794,7 +852,7 @@ static int rsync_xal_set(const char *fname, item_list *xalp, int user_only = am_root <= 0; #endif size_t name_len; @@ -647,7 +647,7 @@ diff --git a/xattrs.c b/xattrs.c /* This puts the current name list into the "namebuf" buffer. */ if ((list_len = get_xattr_names(fname)) < 0) -@@ -805,7 +863,10 @@ static int rsync_xal_set(const char *fname, item_list *xalp, +@@ -806,7 +864,10 @@ static int rsync_xal_set(const char *fname, item_list *xalp, if (XATTR_ABBREV(rxas[i])) { /* See if the fnamecmp version is identical. */ len = name_len = rxas[i].name_len; @@ -659,7 +659,7 @@ diff --git a/xattrs.c b/xattrs.c still_abbrev: if (am_generator) continue; -@@ -814,14 +875,14 @@ static int rsync_xal_set(const char *fname, item_list *xalp, +@@ -815,14 +876,14 @@ static int rsync_xal_set(const char *fname, item_list *xalp, ret = -1; continue; } @@ -677,7 +677,7 @@ diff --git a/xattrs.c b/xattrs.c if (memcmp(sum, rxas[i].datum + 1, MAX_DIGEST_LEN) != 0) { free(ptr); goto still_abbrev; -@@ -890,6 +951,10 @@ static int rsync_xal_set(const char *fname, item_list *xalp, +@@ -891,6 +952,10 @@ static int rsync_xal_set(const char *fname, item_list *xalp, } } @@ -688,7 +688,7 @@ diff --git a/xattrs.c b/xattrs.c return ret; } -@@ -936,7 +1001,7 @@ char *get_xattr_acl(const char *fname, int is_access_acl, size_t *len_p) +@@ -937,7 +1002,7 @@ char *get_xattr_acl(const char *fname, int is_access_acl, size_t *len_p) { const char *name = is_access_acl ? XACC_ACL_ATTR : XDEF_ACL_ATTR; *len_p = 0; /* no extra data alloc needed from get_xattr_data() */ @@ -697,7 +697,7 @@ diff --git a/xattrs.c b/xattrs.c } int set_xattr_acl(const char *fname, int is_access_acl, const char *buf, size_t buf_len) -@@ -1079,11 +1144,33 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) +@@ -1080,11 +1145,33 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) return 0; } @@ -731,7 +731,7 @@ diff --git a/xattrs.c b/xattrs.c return ret; } -@@ -1092,6 +1179,9 @@ int x_lstat(const char *fname, STRUCT_STAT *fst, STRUCT_STAT *xst) +@@ -1093,6 +1180,9 @@ int x_lstat(const char *fname, STRUCT_STAT *fst, STRUCT_STAT *xst) int ret = do_lstat(fname, fst); if ((ret < 0 || get_stat_xattr(fname, -1, fst, xst) < 0) && xst) xst->st_mode = 0; @@ -741,7 +741,7 @@ diff --git a/xattrs.c b/xattrs.c return ret; } -@@ -1100,6 +1190,9 @@ int x_fstat(int fd, STRUCT_STAT *fst, STRUCT_STAT *xst) +@@ -1101,6 +1191,9 @@ int x_fstat(int fd, STRUCT_STAT *fst, STRUCT_STAT *xst) int ret = do_fstat(fd, fst); if ((ret < 0 || get_stat_xattr(NULL, fd, fst, xst) < 0) && xst) xst->st_mode = 0; diff --git a/ignore-case.diff b/ignore-case.diff index 7c48cfb..4bfbc83 100644 --- a/ignore-case.diff +++ b/ignore-case.diff @@ -12,7 +12,7 @@ TODO: - Make this code handle multibyte character encodings, and honor the --iconv setting when converting case. -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/exclude.c b/exclude.c --- a/exclude.c +++ b/exclude.c diff --git a/link-by-hash.diff b/link-by-hash.diff index dea14ea..dc3a9c5 100644 --- a/link-by-hash.diff +++ b/link-by-hash.diff @@ -12,7 +12,7 @@ To use this patch, run these commands for a successful build: ./configure make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/Makefile.in b/Makefile.in --- a/Makefile.in +++ b/Makefile.in @@ -374,7 +374,7 @@ diff --git a/rsync.c b/rsync.c diff --git a/rsync.h b/rsync.h --- a/rsync.h +++ b/rsync.h -@@ -1263,7 +1263,8 @@ extern short info_levels[], debug_levels[]; +@@ -1265,7 +1265,8 @@ extern short info_levels[], debug_levels[]; #define DEBUG_FUZZY (DEBUG_FLIST+1) #define DEBUG_GENR (DEBUG_FUZZY+1) #define DEBUG_HASH (DEBUG_GENR+1) diff --git a/nameconverter.diff b/nameconverter.diff index 85c032b..19b8959 100644 --- a/nameconverter.diff +++ b/nameconverter.diff @@ -20,7 +20,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/authenticate.c b/authenticate.c --- a/authenticate.c +++ b/authenticate.c @@ -439,7 +439,7 @@ diff --git a/uidlist.c b/uidlist.c diff --git a/util.c b/util.c --- a/util.c +++ b/util.c -@@ -35,6 +35,8 @@ extern int preallocate_files; +@@ -36,6 +36,8 @@ extern int preallocate_files; extern char *module_dir; extern unsigned int module_dirlen; extern char *partial_dir; diff --git a/netgroup-auth.diff b/netgroup-auth.diff index 40f8fb6..61c7158 100644 --- a/netgroup-auth.diff +++ b/netgroup-auth.diff @@ -9,7 +9,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/access.c b/access.c --- a/access.c +++ b/access.c diff --git a/omit-dir-changes.diff b/omit-dir-changes.diff index 8a6d979..e9cd841 100644 --- a/omit-dir-changes.diff +++ b/omit-dir-changes.diff @@ -7,7 +7,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c @@ -42,7 +42,7 @@ diff --git a/generator.c b/generator.c iflags |= ITEM_REPORT_GROUP; #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { -@@ -1379,7 +1382,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1377,7 +1380,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, real_ret = statret; if (file->flags & FLAG_DIR_CREATED) statret = -1; @@ -108,9 +108,9 @@ diff --git a/rsync.c b/rsync.c extern int am_root; extern int am_server; extern int am_daemon; -@@ -514,9 +515,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, - file->flags |= FLAG_TIME_FAILED; - } +@@ -489,9 +490,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, + get_acl(fname, sxp); + #endif - change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file); + change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file) diff --git a/openssl-support.diff b/openssl-support.diff deleted file mode 100644 index cbaa1a8..0000000 --- a/openssl-support.diff +++ /dev/null @@ -1,1167 +0,0 @@ -Casey Marshall wrote: - -I've been hacking together a way to use rsync with OpenSSL, and have -attached my current patch against a recent CVS tree. The details of -this implementation are: - - 1. The SSL code is added as a "layer" that is forked into its own - process. - - 2. An SSL connection is established by the client issuing the - command: - - #starttls - - And, if the daemon allows SSL, it replies with - - @RSYNCD: starttls - - At which point both sides begin negotiating the SSL connection. - Servers that can't or don't want to use SSL just treat it as a - normal unknown command. - - 3. The SSL code is meant to be unobtrusive, and when this patch is - applied the program may still be built with no SSL code. - - 4. There are a number of details not implemented. - -All warnings apply; I don't do C programming all that often, so I -can't say if I've left any cleanup/compatibility errors in the code. - -To use this patch, run these commands for a successful build: - - patch -p1 = 0 ? WNOHANG : 0); -+ if (waited_pid) -+ break; -+ if (timeout == 0) { -+ if (graceful) { -+ graceful = 0; -+ timeout = 3000; -+ } else { -+ signo = SIGKILL; -+ timeout = -1; -+ } -+ rprintf(FINFO, "%s:%s shutdown didn't work - sending signal %d\n", -+ __FUNCTION__, graceful ? " graceful" : "", signo); -+ kill(pid, signo); -+ } -+ -+ if (timeout > 0) { -+ /* interruptible wait and calculate the time left for waiting */ -+ struct timeval tval, t1, t2; -+ -+ gettimeofday(&t1, NULL); -+ -+ tval.tv_sec = timeout/1000; -+ tval.tv_usec = (timeout%1000)*1000; -+ select(0, NULL, NULL, NULL, &tval); -+ gettimeofday(&t2, NULL); -+ -+ timeout -= (t2.tv_sec-t1.tv_sec)*1000 + (t2.tv_usec-t1.tv_usec)/1000; -+ if (timeout < 0) -+ timeout = 0; -+ } -+ } -+ -+ return waited_pid; -+} -+ - /* Wait for a process to exit, calling io_flush while waiting. */ - static void wait_process_with_flush(pid_t pid, int *exit_code_ptr) - { -@@ -809,6 +858,11 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[]) - argv[0] = "."; - } - -+#ifdef HAVE_OPENSSL -+ if (use_ssl) -+ start_tls_buffering(); -+#endif -+ - flist = send_file_list(f_out,argc,argv); - if (!flist || flist->used == 0) { - /* Make sure input buffering is off so we can't hang in noop_io_until_death(). */ -@@ -933,6 +987,10 @@ static int do_recv(int f_in, int f_out, char *local_name) - - io_start_buffering_out(f_out); - io_start_multiplex_in(f_in); -+#ifdef HAVE_OPENSSL -+ if (use_ssl) -+ start_tls_buffering(); -+#endif - - #ifdef SUPPORT_HARD_LINKS - if (preserve_hard_links && inc_recurse) { -@@ -1135,6 +1193,10 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) - io_start_multiplex_in(f_in); - else - io_start_buffering_in(f_in); -+#ifdef HAVE_OPENSSL -+ if (use_ssl) -+ start_tls_buffering(); -+#endif - send_filter_list(f_out); - if (filesfrom_host) - filesfrom_fd = f_in; -diff --git a/options.c b/options.c ---- a/options.c -+++ b/options.c -@@ -191,6 +191,14 @@ int logfile_format_has_o_or_i = 0; - int always_checksum = 0; - int list_only = 0; - -+#ifdef 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; - -@@ -572,6 +580,7 @@ static void print_rsync_version(enum logcode f) - char const *links = "no "; - char const *iconv = "no "; - char const *ipv6 = "no "; -+ char const *ssl = "no "; - STRUCT_STAT *dumstat; - - #if SUBPROTOCOL_VERSION != 0 -@@ -608,6 +617,9 @@ static void print_rsync_version(enum logcode f) - #ifdef CAN_SET_SYMLINK_TIMES - symtimes = ""; - #endif -+#ifdef HAVE_OPENSSL -+ ssl = ""; -+#endif - - rprintf(f, "%s version %s protocol version %d%s\n", - RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol); -@@ -621,8 +633,8 @@ static void print_rsync_version(enum logcode f) - (int)(sizeof (int64) * 8)); - rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n", - got_socketpair, hardlinks, links, ipv6, have_inplace); -- rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %ssymtimes, %sprealloc\n", -- have_inplace, acls, xattrs, iconv, symtimes, prealloc); -+ rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %ssymtimes, %sprealloc, %sSSL\n", -+ have_inplace, acls, xattrs, iconv, symtimes, prealloc, ssl); - - #ifdef MAINTAINER_MODE - rprintf(f, "Panic Action: \"%s\"\n", get_panic_action()); -@@ -804,6 +816,13 @@ void usage(enum logcode F) - rprintf(F," --checksum-seed=NUM set block/file checksum seed (advanced)\n"); - rprintf(F," -4, --ipv4 prefer IPv4\n"); - rprintf(F," -6, --ipv6 prefer IPv6\n"); -+#ifdef 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 (-h is --help only if used alone)\n"); - -@@ -817,7 +836,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_HELP, - OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD, - OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE, -- OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG, -+ OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG, OPT_USE_SSL, - OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, - OPT_SERVER, OPT_REFUSED_BASE = 9000}; - -@@ -1039,6 +1058,13 @@ static struct poptOption long_options[] = { - {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 }, - {"server", 0, POPT_ARG_NONE, 0, OPT_SERVER, 0, 0 }, - {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 }, -+#ifdef 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 the following 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 }, -@@ -1066,6 +1092,13 @@ static void daemon_usage(enum logcode F) - rprintf(F," -v, --verbose increase verbosity\n"); - rprintf(F," -4, --ipv4 prefer IPv4\n"); - rprintf(F," -6, --ipv6 prefer IPv6\n"); -+#ifdef 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," --help show this help screen\n"); - - rprintf(F,"\n"); -@@ -1091,6 +1124,13 @@ static struct poptOption long_daemon_options[] = { - {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 }, - {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 }, - {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 }, -+#ifdef 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 }, - {"no-verbose", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 }, - {"no-v", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 }, -@@ -1386,6 +1426,12 @@ int parse_arguments(int *argc_p, const char ***argv_p) - verbose++; - break; - -+#ifdef HAVE_OPENSSL -+ case OPT_USE_SSL: -+ use_ssl = 1; -+ break; -+#endif -+ - default: - rprintf(FERROR, - "rsync: %s: %s (in daemon mode)\n", -@@ -1412,6 +1458,17 @@ int parse_arguments(int *argc_p, const char ***argv_p) - exit_cleanup(RERR_SYNTAX); - } - -+#ifdef HAVE_OPENSSL -+ if (use_ssl) { -+ if (init_tls()) { -+ snprintf(err_buf, sizeof(err_buf), -+ "Openssl error: %s\n", -+ get_ssl_error()); -+ return 0; -+ } -+ } -+#endif -+ - *argv_p = argv = poptGetArgs(pc); - *argc_p = argc = count_args(argv); - am_starting_up = 0; -@@ -1794,6 +1851,12 @@ int parse_arguments(int *argc_p, const char ***argv_p) - return 0; - #endif - -+#ifdef HAVE_OPENSSL -+ case OPT_USE_SSL: -+ use_ssl = 1; -+ break; -+#endif -+ - default: - /* A large opt value means that set_refuse_options() - * turned this option off. */ -@@ -2231,6 +2294,17 @@ int parse_arguments(int *argc_p, const char ***argv_p) - if (delay_updates && !partial_dir) - partial_dir = tmp_partialdir; - -+#ifdef 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) { -@@ -2831,9 +2905,21 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr) - { - char *path; - -- if (port_ptr && strncasecmp(URL_PREFIX, s, strlen(URL_PREFIX)) == 0) { -- *host_ptr = parse_hostspec(s + strlen(URL_PREFIX), &path, port_ptr); -- if (*host_ptr) { -+ if (port_ptr) { -+ int url_prefix_len; -+ if (strncasecmp(URL_PREFIX, s, sizeof URL_PREFIX - 1) == 0) -+ url_prefix_len = sizeof URL_PREFIX - 1; -+#ifdef HAVE_OPENSSL -+ else if (strncasecmp(SSL_URL_PREFIX, s, sizeof SSL_URL_PREFIX - 1) == 0) { -+ if (!use_ssl) -+ init_tls(); -+ use_ssl = 1; -+ url_prefix_len = sizeof SSL_URL_PREFIX - 1; -+ } -+#endif -+ else -+ url_prefix_len = 0; -+ if (url_prefix_len && (*host_ptr = parse_hostspec(s + url_prefix_len, &path, port_ptr))) { - if (!*port_ptr) - *port_ptr = RSYNC_PORT; - return path; -diff --git a/rsync.h b/rsync.h ---- a/rsync.h -+++ b/rsync.h -@@ -31,6 +31,7 @@ - - #define DEFAULT_LOCK_FILE "/var/run/rsyncd.lock" - #define URL_PREFIX "rsync://" -+#define SSL_URL_PREFIX "rsyncs://" - - #define SYMLINK_PREFIX "/rsyncd-munged/" /* This MUST have a trailing slash! */ - #define SYMLINK_PREFIX_LEN ((int)sizeof SYMLINK_PREFIX - 1) -@@ -608,6 +609,11 @@ typedef unsigned int size_t; - # define SIZEOF_INT64 SIZEOF_OFF_T - #endif - -+#ifdef HAVE_OPENSSL -+#include -+#include -+#endif -+ - struct hashtable { - void *nodes; - int32 size, entries; -diff --git a/ssl.c b/ssl.c -new file mode 100644 ---- /dev/null -+++ b/ssl.c -@@ -0,0 +1,603 @@ -+/* -*- 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" -+ -+#ifdef HAVE_SYS_SELECT_H -+#include -+#else -+#include -+#include -+#include -+#endif -+#include -+ -+#define SSL_MAX_RECORD_SIZE (1024*16) /* TLS record size */ -+#define MAX_BUFFERING_TIME_MS 100 -+ -+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_min_send_size; -+static int ssl_pid = -1; -+ -+#ifdef HAVE_SIGACTION -+static struct sigaction sigact; -+#endif -+ -+/* copied from progress.c */ -+static unsigned long msdiff(struct timeval *t1, struct timeval *t2) -+{ -+ return (t2->tv_sec - t1->tv_sec) * 1000L -+ + (t2->tv_usec - t1->tv_usec) / 1000; -+} -+ -+/** -+ * 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 (DEBUG_GTE(CONNECT, 1)) { -+ 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); -+ -+ SSL_CTX_set_options(ssl_ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3); -+ -+ /* 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)) -+{ -+ ssl_running = 0; -+} -+ -+/* Signal handler that starts record-size buffering. */ -+static RETSIGTYPE tls_sigusr2(int UNUSED(val)) -+{ -+ ssl_min_send_size = SSL_MAX_RECORD_SIZE; -+} -+ -+/** -+ * 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. -+ * rsync to network algorithm: -+ * A buffer ring of two buffers is maintained. Data is read from the local -+ * socket into the current buffer. The buffer is eligible for sending if -+ * enough data has been buffered, or enough time has passed. Once the buffer -+ * becomes eligible for sending it is marked "ready" and buffering continues -+ * on the other buffer (assuming it's "unready"). This algorithm tries to -+ * maximize SSL record size. -+ * -+ * network to rsync algorithm: -+ * One receive buffer twice the size of the SSL max record size. Reading -+ * from the network is attempted only if there's enough space for a whole -+ * record (this is done to optimize OpenSSL per-call overhead). -+ * As bytes enter the buffer sending to rsync begins, when the buffer becomes -+ * full we wait for sending to rsync to finish. -+ * -+ * A graceful stop is attempted on both directions. So if the pipe from rsync -+ * is gracefully shut down, we try to send all data to the network before closing -+ * the connection and if the SSL connection is gracefully shut down we try to -+ * send everything to rsync before closing the rsync pipe. -+ */ -+int start_tls(int f_in, int f_out) -+{ -+ int n = 0, r; -+ unsigned char buf_tonetwork[2][SSL_MAX_RECORD_SIZE], buf_fromnetwork[2*SSL_MAX_RECORD_SIZE]; -+ int tonet_ready[2] = {0}, tonet_size[2] = {0}, write_tonet = 0, tonet_fill_idx = 0, tonet_send_idx = 0; -+ struct timeval buffering_start, now, timeout, *tp; -+ int avail_fromnet = 0, write_fromnet = 0; -+ int want_read_fromnet = 1, want_write_tonet = 0; -+ int want_read_fromrsync = 1, want_write_torsync = 0; -+ int write_tonet_blocks = 0, read_fromnet_blocks = 0; -+ int write_torsync_blocks = 0, read_fromrsync_blocks = 0; -+ int ssl_readfd_blocks = 0, ssl_writefd_blocks = 0; -+ int ssl_write_count = 0; -+ int want_more_io; -+ int net_closed = 0, rsync_closed = 0; -+ int loopcount; -+ fd_set rd, wd; -+ const char *ssl_ciphers; -+ -+ if (fd_pair(tls_read)) -+ return 1; -+ if (fd_pair(tls_write)) -+ return 1; -+ -+ set_blocking(tls_read[0]); -+ set_nonblocking(tls_read[1]); -+ set_nonblocking(tls_write[0]); -+ set_blocking(tls_write[1]); -+ set_nonblocking(f_in); -+ set_nonblocking(f_out); -+ -+ ssl_pid = do_fork(); -+ if (ssl_pid < 0) -+ return -1; -+ if (ssl_pid != 0) { -+ close(tls_write[0]); -+ close(tls_read[1]); -+ close(f_in); -+ close(f_out); -+ return 0; -+ } -+ -+ close(tls_write[1]); -+ close(tls_read[0]); -+ -+ SIGACTION(SIGUSR1, tls_sigusr1); -+ SIGACTION(SIGUSR2, tls_sigusr2); -+ ssl = SSL_new(ssl_ctx); -+ if (!ssl) -+ goto out; -+ if (am_daemon || am_server) -+ SSL_set_accept_state(ssl); -+ else { -+ SSL_set_connect_state(ssl); -+ ssl_ciphers = getenv("RSYNC_SSL_CIPHERS"); -+ if (ssl_ciphers) -+ SSL_set_cipher_list(ssl, ssl_ciphers); -+ } -+ -+ SSL_set_rfd(ssl, f_in); -+ SSL_set_wfd(ssl, f_out); -+ -+ n = tls_write[0]; -+ n = MAX(tls_read[1], n); -+ n = MAX(f_in, n); -+ n = MAX(f_out, n) + 1; -+ -+ ssl_running = 1; -+ loopcount = 0; -+ while (ssl_running) { -+ ++loopcount; /* the loopcount prevents starvation of one transfer direction by the other */ -+ want_more_io = 0; -+ -+ if (want_read_fromrsync && !read_fromrsync_blocks) { -+ int cur_buf_size = tonet_size[tonet_fill_idx]; -+ r = read(tls_write[0], buf_tonetwork[tonet_fill_idx]+cur_buf_size, sizeof(buf_tonetwork[0])-cur_buf_size); -+ if (r > 0) { -+ want_more_io = 1; -+ if (!net_closed) { -+ if (cur_buf_size == 0) -+ gettimeofday(&buffering_start, NULL); -+ cur_buf_size += r; -+ tonet_size[tonet_fill_idx] = cur_buf_size; -+ if (cur_buf_size >= ssl_min_send_size) { -+ want_write_tonet = 1; -+ tonet_ready[tonet_fill_idx] = 1; -+ tonet_fill_idx = !tonet_fill_idx; -+ if (tonet_ready[tonet_fill_idx]) -+ want_read_fromrsync = 0; -+ } -+ } -+ } else if (r < 0 && errno == EWOULDBLOCK) -+ read_fromrsync_blocks = 1; -+ else if (r < 0) { -+ rprintf(FERROR, "pipe read error: %s\n", -+ strerror(errno)); -+ break; -+ } else { -+ rsync_closed = 1; -+ if (cur_buf_size) { -+ want_write_tonet = 1; -+ tonet_ready[tonet_fill_idx] = 1; /* close current buffer */ -+ } -+ want_read_fromrsync = 0; /* don't read */ -+ want_write_torsync = 0; /* don't write */ -+ read_fromrsync_blocks = 0; /* don't select */ -+ write_torsync_blocks = 0; -+ want_read_fromnet = 1; /* purge incoming data from network */ -+ avail_fromnet = 0; -+ if (net_closed || !want_write_tonet) -+ break; -+ } -+ } -+ -+ if (want_read_fromnet && !read_fromnet_blocks) { -+ r = SSL_read(ssl, buf_fromnetwork+avail_fromnet, SSL_MAX_RECORD_SIZE); -+ if (r > 0) { -+ want_more_io = 1; -+ if (!rsync_closed) { -+ avail_fromnet += r; -+ want_write_torsync = 1; -+ if (avail_fromnet >= (int)(sizeof(buf_fromnetwork)-SSL_MAX_RECORD_SIZE)) -+ want_read_fromnet = 0; -+ } -+ } else { -+ switch (SSL_get_error(ssl, r)) { -+ case SSL_ERROR_ZERO_RETURN: -+ net_closed = 1; -+ want_read_fromnet = 0; /* don't read */ -+ want_write_tonet = 0; /* don't write */ -+ ssl_readfd_blocks = 0; /* and for heaven's sake - don't select() */ -+ ssl_writefd_blocks = 0; -+ want_read_fromrsync = 1; /* and purge stuff from rsync side */ -+ tonet_size[tonet_fill_idx] = 0; -+ tonet_ready[tonet_fill_idx] = 0; -+ if (rsync_closed || !want_write_torsync) -+ goto graceful_stop; -+ break; -+ case SSL_ERROR_WANT_READ: -+ ssl_readfd_blocks = 1; -+ read_fromnet_blocks = 1; -+ break; -+ case SSL_ERROR_WANT_WRITE: -+ ssl_writefd_blocks = 1; -+ read_fromnet_blocks = 1; -+ 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 (want_write_torsync && !write_torsync_blocks) { -+ r = write(tls_read[1], buf_fromnetwork+write_fromnet, avail_fromnet-write_fromnet); -+ if (r > 0) { -+ want_more_io = 1; -+ write_fromnet += r; -+ if (write_fromnet >= avail_fromnet) { -+ write_fromnet = 0; -+ avail_fromnet = 0; -+ if (net_closed) -+ break; -+ want_read_fromnet = 1; -+ want_write_torsync = 0; -+ } -+ } -+ else if (errno == EWOULDBLOCK) -+ write_torsync_blocks = 1; -+ else { -+ if (errno != EPIPE) -+ rprintf(FERROR, "pipe write error: %s\n", strerror(errno)); -+ break; -+ } -+ } -+ -+ if (want_write_tonet && !write_tonet_blocks) { -+ /* lock the write count, 'cause if SSL_write fails on non-blocking IO, it -+ * must be repeated with same parameters. */ -+ if (ssl_write_count == 0) -+ ssl_write_count = tonet_size[tonet_send_idx] - write_tonet; -+ r = SSL_write(ssl, buf_tonetwork[tonet_send_idx]+write_tonet, ssl_write_count); -+ if (r > 0) { -+ want_more_io = 1; -+ write_tonet += r; -+ ssl_write_count = 0; -+ if (write_tonet >= tonet_size[tonet_send_idx]) { -+ write_tonet = 0; -+ tonet_size[tonet_send_idx] = 0; -+ tonet_ready[tonet_send_idx] = 0; -+ if (!rsync_closed) -+ want_read_fromrsync = 1; -+ tonet_send_idx = !tonet_send_idx; -+ if (!tonet_ready[tonet_send_idx]) { -+ want_write_tonet = 0; -+ if (rsync_closed) -+ break; -+ } -+ } -+ } else { -+ switch (SSL_get_error(ssl, r)) { -+ case SSL_ERROR_ZERO_RETURN: -+ goto graceful_stop; -+ case SSL_ERROR_WANT_READ: -+ ssl_readfd_blocks = 1; -+ write_tonet_blocks = 1; -+ break; -+ case SSL_ERROR_WANT_WRITE: -+ ssl_writefd_blocks = 1; -+ write_tonet_blocks = 1; -+ 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 (!want_more_io || (loopcount&31) == 0) { -+ int has_buffered = 0; -+ if (!net_closed && !tonet_ready[tonet_fill_idx] && tonet_size[tonet_fill_idx]) { -+ has_buffered = 1; -+ unsigned long buffering_time; -+ gettimeofday(&now,NULL); -+ buffering_time = msdiff(&buffering_start,&now); -+ if (buffering_time >= MAX_BUFFERING_TIME_MS) { -+ want_write_tonet = 1; -+ want_more_io = 1; -+ tonet_ready[tonet_fill_idx] = 1; -+ tonet_fill_idx = !tonet_fill_idx; -+ if (tonet_ready[tonet_fill_idx]) -+ want_read_fromrsync = 0; -+ } -+ } -+ -+ int waiting_on_something = 0; -+ FD_ZERO(&rd); -+ FD_ZERO(&wd); -+ if (read_fromrsync_blocks) { -+ waiting_on_something = 1; -+ FD_SET(tls_write[0], &rd); -+ } -+ if (write_torsync_blocks) { -+ waiting_on_something = 1; -+ FD_SET(tls_read[1], &wd); -+ } -+ if (ssl_readfd_blocks) { -+ waiting_on_something = 1; -+ FD_SET(f_in, &rd); -+ } -+ if (ssl_writefd_blocks) { -+ waiting_on_something = 1; -+ FD_SET(f_out, &wd); -+ } -+ -+ if (want_more_io) { -+ /* just poll to see if some sockets became non-blocking*/ -+ timeout.tv_sec = 0; -+ timeout.tv_usec = 0; -+ tp = &timeout; -+ } else if (waiting_on_something && !has_buffered) -+ tp = NULL; /*infinite wait until a socket becomes available*/ -+ else { -+ timeout.tv_sec = MAX_BUFFERING_TIME_MS/1000; -+ timeout.tv_usec = (MAX_BUFFERING_TIME_MS%1000)*1000; -+ tp = &timeout; -+ } -+ -+ if (waiting_on_something || !want_more_io) { -+ r = select(n, &rd, &wd, NULL, tp); -+ -+ if (r == -1) { -+ if (errno != EINTR) { -+ rprintf(FERROR, "select error: %s\n", -+ strerror(errno)); -+ break; -+ } -+ } -+ -+ if (r > 0) { -+ if (FD_ISSET(tls_write[0], &rd)) -+ read_fromrsync_blocks = 0; -+ if (FD_ISSET(f_in,&rd)) { -+ read_fromnet_blocks = 0; -+ write_tonet_blocks = 0; -+ ssl_readfd_blocks = 0; -+ } -+ if (FD_ISSET(tls_read[1],&wd)) -+ write_torsync_blocks = 0; -+ if (FD_ISSET(f_out,&wd)) { -+ read_fromnet_blocks = 0; -+ write_tonet_blocks = 0; -+ ssl_writefd_blocks = 0; -+ } -+ } -+ } -+ } -+ } -+ -+ graceful_stop: -+ /* The SSL shutdown API looks pretty broken with respect to corner cases -+ * where the underlying socket is blocking. This is a "best effort". */ -+ if (SSL_shutdown(ssl) != 1) -+ SSL_shutdown(ssl); -+ closed: -+ SSL_free(ssl); -+ -+ /* We're finished. */ -+ out: -+ close(tls_read[1]); -+ close(tls_write[0]); -+ close(f_in); -+ if (f_out != f_in) -+ close(f_out); -+ _exit(0); -+} -+ -+void start_tls_buffering(void) -+{ -+ if (ssl_pid > 0) -+ kill(ssl_pid, SIGUSR2); -+} -+ -+/** -+ * Ends the TLS connection. -+ */ -+void end_tls(void) -+{ -+ if (ssl_pid > 0) { -+ int status; -+ /* try a graceful stop - this makes sure all data is sent, and -+ * also causes our side to send a close_notify alert, as required -+ * by TLS specs. */ -+ close(get_tls_rfd()); -+ if (get_tls_wfd() != get_tls_rfd()) -+ close(get_tls_wfd()); -+ terminate_process(ssl_pid, &status, SIGUSR1, 1); -+ ssl_pid = -1; -+ } -+} diff --git a/slow-down.diff b/slow-down.diff index bdb0f9f..5644982 100644 --- a/slow-down.diff +++ b/slow-down.diff @@ -14,7 +14,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/flist.c b/flist.c --- a/flist.c +++ b/flist.c diff --git a/slp.diff b/slp.diff index 3dc5f3f..6657f21 100644 --- a/slp.diff +++ b/slp.diff @@ -10,7 +10,7 @@ To use this patch, run these commands for a successful build: TODO: the configure changes should abort if the user requests --enable-slp and we can't honor that request. -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/Makefile.in b/Makefile.in --- a/Makefile.in +++ b/Makefile.in diff --git a/soften-links.diff b/soften-links.diff index 9da4011..06e23a6 100644 --- a/soften-links.diff +++ b/soften-links.diff @@ -10,7 +10,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/syscall.c b/syscall.c --- a/syscall.c +++ b/syscall.c diff --git a/source-backup.diff b/source-backup.diff index ad7b515..f6e9f7a 100644 --- a/source-backup.diff +++ b/source-backup.diff @@ -9,7 +9,7 @@ To use this patch, run these commands for a successful build: -- Matt McCutchen -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/options.c b/options.c --- a/options.c +++ b/options.c diff --git a/source-filter_dest-filter.diff b/source-filter_dest-filter.diff index 5db5adf..d9ad417 100644 --- a/source-filter_dest-filter.diff +++ b/source-filter_dest-filter.diff @@ -30,7 +30,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c @@ -42,7 +42,7 @@ diff --git a/generator.c b/generator.c extern int size_only; extern OFF_T max_size; extern OFF_T min_size; -@@ -567,7 +568,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre +@@ -565,7 +566,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre /* Perform our quick-check heuristic for determining if a file is unchanged. */ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st) { @@ -293,7 +293,7 @@ diff --git a/receiver.c b/receiver.c while (1) { cleanup_disable(); -@@ -842,6 +862,9 @@ int recv_files(int f_in, int f_out, char *local_name) +@@ -840,6 +860,9 @@ int recv_files(int f_in, int f_out, char *local_name) else if (!am_server && INFO_GTE(NAME, 1) && INFO_EQ(PROGRESS, 1)) rprintf(FINFO, "%s\n", fname); @@ -303,7 +303,7 @@ diff --git a/receiver.c b/receiver.c /* recv file data */ recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size, fname, fd2, F_LENGTH(file)); -@@ -856,6 +879,16 @@ int recv_files(int f_in, int f_out, char *local_name) +@@ -854,6 +877,16 @@ int recv_files(int f_in, int f_out, char *local_name) exit_cleanup(RERR_FILEIO); } @@ -396,7 +396,7 @@ diff --git a/sender.c b/sender.c extern struct stats stats; extern struct file_list *cur_flist, *first_flist, *dir_flist; -@@ -200,6 +201,26 @@ void send_files(int f_in, int f_out) +@@ -199,6 +200,26 @@ void send_files(int f_in, int f_out) int f_xfer = write_batch < 0 ? batch_fd : f_out; int save_io_error = io_error; int ndx, j; @@ -423,7 +423,7 @@ diff --git a/sender.c b/sender.c if (DEBUG_GTE(SEND, 1)) rprintf(FINFO, "send_files starting\n"); -@@ -334,6 +355,7 @@ void send_files(int f_in, int f_out) +@@ -333,6 +354,7 @@ void send_files(int f_in, int f_out) exit_cleanup(RERR_PROTOCOL); } @@ -431,7 +431,7 @@ diff --git a/sender.c b/sender.c fd = do_open(fname, O_RDONLY, 0); if (fd == -1) { if (errno == ENOENT) { -@@ -355,6 +377,33 @@ void send_files(int f_in, int f_out) +@@ -354,6 +376,33 @@ void send_files(int f_in, int f_out) continue; } @@ -465,7 +465,7 @@ diff --git a/sender.c b/sender.c /* map the local file */ if (do_fstat(fd, &st) != 0) { io_error |= IOERR_GENERAL; -@@ -405,6 +454,8 @@ void send_files(int f_in, int f_out) +@@ -404,6 +453,8 @@ void send_files(int f_in, int f_out) } } close(fd); diff --git a/sparse-block.diff b/sparse-block.diff index 3e2324b..cd2cb8e 100644 --- a/sparse-block.diff +++ b/sparse-block.diff @@ -18,7 +18,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/fileio.c b/fileio.c --- a/fileio.c +++ b/fileio.c diff --git a/time-limit.diff b/time-limit.diff index 0a378da..ad71108 100644 --- a/time-limit.diff +++ b/time-limit.diff @@ -9,7 +9,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/io.c b/io.c --- a/io.c +++ b/io.c @@ -21,7 +21,7 @@ diff --git a/io.c b/io.c extern struct file_list *cur_flist; #ifdef ICONV_OPTION extern int filesfrom_convert; -@@ -170,11 +171,19 @@ static void check_timeout(BOOL allow_keepalive) +@@ -170,11 +171,19 @@ static void check_timeout(BOOL allow_keepalive, int keepalive_flags) * generator might be blocked trying to send checksums, it needs to * know that the receiver is active). Thus, as long as one or the * other is successfully doing work, the generator will not timeout. */ @@ -41,7 +41,7 @@ diff --git a/io.c b/io.c + if (allow_keepalive) { /* This may put data into iobuf.msg w/o flushing. */ - maybe_send_keepalive(t, 0); + maybe_send_keepalive(t, keepalive_flags); diff --git a/options.c b/options.c --- a/options.c +++ b/options.c @@ -167,7 +167,7 @@ diff --git a/rsync.yo b/rsync.yo diff --git a/util.c b/util.c --- a/util.c +++ b/util.c -@@ -114,6 +114,133 @@ void print_child_argv(const char *prefix, char **cmd) +@@ -115,6 +115,133 @@ void print_child_argv(const char *prefix, char **cmd) rprintf(FCLIENT, " (%d args)\n", cnt); } diff --git a/transliterate.diff b/transliterate.diff index 6080b3d..fd340bd 100644 --- a/transliterate.diff +++ b/transliterate.diff @@ -10,7 +10,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/flist.c b/flist.c --- a/flist.c +++ b/flist.c diff --git a/tru64.diff b/tru64.diff index 7dc86a3..c3965f1 100644 --- a/tru64.diff +++ b/tru64.diff @@ -6,7 +6,7 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/syscall.c b/syscall.c --- a/syscall.c +++ b/syscall.c diff --git a/write-devices.diff b/write-devices.diff index 3ce6756..1f3674c 100644 --- a/write-devices.diff +++ b/write-devices.diff @@ -10,7 +10,7 @@ To use this patch, run these commands for a successful build: This patch has not yet been tested by me (Wayne), but was provided Darryl Dixon. Thanks! -based-on: 63f91976112b8b2118cc17eb5fc8142175566f4f +based-on: 8946cfc6f8018e30740ee1db4cc2e2008e4f7e7e diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c @@ -22,7 +22,7 @@ diff --git a/generator.c b/generator.c extern int preserve_specials; extern int preserve_hard_links; extern int preserve_executability; -@@ -1657,7 +1658,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1659,7 +1660,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, fnamecmp_type = FNAMECMP_FNAME; @@ -179,7 +179,7 @@ diff --git a/receiver.c b/receiver.c } static void handle_delayed_updates(char *local_name) -@@ -662,7 +663,7 @@ int recv_files(int f_in, int f_out, char *local_name) +@@ -660,7 +661,7 @@ int recv_files(int f_in, int f_out, char *local_name) "(Skipping batched update for%s \"%s\")\n", redoing ? " resend of" : "", fname); @@ -188,7 +188,7 @@ diff --git a/receiver.c b/receiver.c file->flags |= FLAG_FILE_SENT; continue; } -@@ -674,13 +675,13 @@ int recv_files(int f_in, int f_out, char *local_name) +@@ -672,13 +673,13 @@ int recv_files(int f_in, int f_out, char *local_name) if (!do_xfers) { /* log the transfer */ log_item(FCLIENT, file, iflags, NULL); if (read_batch) @@ -204,7 +204,7 @@ diff --git a/receiver.c b/receiver.c if (inc_recurse) send_msg_int(MSG_SUCCESS, ndx); continue; -@@ -770,7 +771,7 @@ int recv_files(int f_in, int f_out, char *local_name) +@@ -768,7 +769,7 @@ int recv_files(int f_in, int f_out, char *local_name) } else if (do_fstat(fd1,&st) != 0) { rsyserr(FERROR_XFER, errno, "fstat %s failed", full_fname(fnamecmp)); @@ -213,7 +213,7 @@ diff --git a/receiver.c b/receiver.c close(fd1); if (inc_recurse) send_msg_int(MSG_NO_SEND, ndx); -@@ -785,18 +786,32 @@ int recv_files(int f_in, int f_out, char *local_name) +@@ -783,18 +784,32 @@ int recv_files(int f_in, int f_out, char *local_name) */ rprintf(FERROR_XFER, "recv_files: %s is a directory\n", full_fname(fnamecmp)); @@ -248,7 +248,7 @@ diff --git a/receiver.c b/receiver.c /* If we're not preserving permissions, change the file-list's * mode based on the local permissions and some heuristics. */ if (!preserve_perms) { -@@ -828,7 +843,7 @@ int recv_files(int f_in, int f_out, char *local_name) +@@ -826,7 +841,7 @@ int recv_files(int f_in, int f_out, char *local_name) } if (fd2 == -1) { @@ -257,7 +257,7 @@ diff --git a/receiver.c b/receiver.c if (fd1 != -1) close(fd1); if (inc_recurse) -@@ -843,8 +858,7 @@ int recv_files(int f_in, int f_out, char *local_name) +@@ -841,8 +856,7 @@ int recv_files(int f_in, int f_out, char *local_name) rprintf(FINFO, "%s\n", fname); /* recv file data */ diff --git a/xattrs.diff b/xattrs.diff index 3269e60..accfa10 100644 --- a/xattrs.diff +++ b/xattrs.diff @@ -56,7 +56,7 @@ diff --git a/xattrs.c b/xattrs.c /* For large datums, we store a flag and a checksum. */ name_offset = 1 + MAX_DIGEST_LEN; sum_init(checksum_seed); -@@ -377,7 +379,7 @@ static int find_matching_xattr(item_list *xalp) +@@ -378,7 +380,7 @@ static int find_matching_xattr(item_list *xalp) || rxas1[j].datum_len != rxas2[j].datum_len || strcmp(rxas1[j].name, rxas2[j].name)) break; @@ -65,7 +65,7 @@ diff --git a/xattrs.c b/xattrs.c if (memcmp(rxas1[j].datum + 1, rxas2[j].datum + 1, MAX_DIGEST_LEN) != 0) -@@ -414,13 +416,22 @@ int send_xattr(int f, stat_x *sxp) +@@ -415,13 +417,22 @@ int send_xattr(int f, stat_x *sxp) { int ndx = find_matching_xattr(sxp->xattr); @@ -91,7 +91,7 @@ diff --git a/xattrs.c b/xattrs.c for (rxa = sxp->xattr->items; count--; rxa++) { size_t name_len = rxa->name_len; const char *name = rxa->name; -@@ -439,8 +450,8 @@ int send_xattr(int f, stat_x *sxp) +@@ -440,8 +451,8 @@ int send_xattr(int f, stat_x *sxp) name_len += UPRE_LEN; } #endif @@ -102,7 +102,7 @@ diff --git a/xattrs.c b/xattrs.c #ifndef HAVE_LINUX_XATTRS if (name_len > rxa->name_len) { write_buf(f, USER_PREFIX, UPRE_LEN); -@@ -448,7 +459,7 @@ int send_xattr(int f, stat_x *sxp) +@@ -449,7 +460,7 @@ int send_xattr(int f, stat_x *sxp) } #endif write_buf(f, name, name_len); @@ -110,8 +110,8 @@ diff --git a/xattrs.c b/xattrs.c + if (rxa->datum_len > MAX_FULL_DATUM && protocol_version >= 30) write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN); else - write_buf(f, rxa->datum, rxa->datum_len); -@@ -498,7 +509,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all) + write_bigbuf(f, rxa->datum, rxa->datum_len); +@@ -499,7 +510,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all) cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1; if (cmp > 0) same = 0; @@ -120,7 +120,7 @@ diff --git a/xattrs.c b/xattrs.c same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1, MAX_DIGEST_LEN) == 0; -@@ -543,6 +554,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out) +@@ -544,6 +555,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out) int cnt, prior_req = 0; rsync_xa *rxa; @@ -130,7 +130,7 @@ diff --git a/xattrs.c b/xattrs.c lst += F_XATTR(file); for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) { if (rxa->datum_len <= MAX_FULL_DATUM) -@@ -599,6 +613,9 @@ int recv_xattr_request(struct file_struct *file, int f_in) +@@ -600,6 +614,9 @@ int recv_xattr_request(struct file_struct *file, int f_in) rsync_xa *rxa; int rel_pos, cnt, num, got_xattr_data = 0; @@ -140,7 +140,7 @@ diff --git a/xattrs.c b/xattrs.c if (F_XATTR(file) < 0) { rprintf(FERROR, "recv_xattr_request: internal data error!\n"); exit_cleanup(RERR_PROTOCOL); -@@ -661,7 +678,22 @@ void receive_xattr(int f, struct file_struct *file) +@@ -662,7 +679,22 @@ void receive_xattr(int f, struct file_struct *file) #else int need_sort = 1; #endif @@ -164,7 +164,7 @@ diff --git a/xattrs.c b/xattrs.c if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) { rprintf(FERROR, "receive_xattr: xa index %d out of" -@@ -674,7 +706,7 @@ void receive_xattr(int f, struct file_struct *file) +@@ -675,7 +707,7 @@ void receive_xattr(int f, struct file_struct *file) return; } @@ -173,7 +173,7 @@ diff --git a/xattrs.c b/xattrs.c (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count); temp_xattr.count = 0; } -@@ -682,9 +714,10 @@ void receive_xattr(int f, struct file_struct *file) +@@ -683,9 +715,10 @@ void receive_xattr(int f, struct file_struct *file) for (num = 1; num <= count; num++) { char *ptr, *name; rsync_xa *rxa; -- 2.34.1