From c0c7984e7f6009b6ab18ad3da998a56a9c0f083d Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Mon, 24 Mar 2008 22:24:02 -0700 Subject: [PATCH] The patches for 3.0.1pre1. --- atimes.diff | 74 +++++----- backup-dir-dels.diff | 64 +++++---- catch_crash_signals.diff | 8 +- checksum-reading.diff | 88 ++++++------ checksum-updating.diff | 70 +++++----- checksum-xattr.diff | 35 +++-- copy-devices.diff | 14 +- crtimes.diff | 78 +++++------ cvs-entries.diff | 20 +-- date-only.diff | 12 +- detect-renamed-lax.diff | 18 +-- detect-renamed.diff | 74 +++++----- downdate.diff | 14 +- drop-cache.diff | 12 +- fileflags.diff | 158 +++++++++++++--------- fsync.diff | 10 +- ignore-case.diff | 18 +-- link-by-hash.diff | 30 ++--- log-checksum.diff | 6 +- nameconverter.diff | 16 +-- omit-dir-changes.diff | 38 +++--- openssl-support.diff | 46 +++---- osx-create-time.diff | 133 ------------------ preallocate.diff | 34 ++--- remote-option.diff | 239 +++++++++++++++++++++++++++++++++ slow-down.diff | 8 +- slp.diff | 18 +-- source-backup.diff | 12 +- source-filter_dest-filter.diff | 26 ++-- sparse-block.diff | 107 +++++++++++++++ stdout.diff | 8 +- time-limit.diff | 20 +-- transliterate.diff | 18 +-- usermap.diff | 16 +-- xattrs.diff | 56 ++++---- 35 files changed, 930 insertions(+), 668 deletions(-) delete mode 100644 osx-create-time.diff create mode 100644 remote-option.diff create mode 100644 sparse-block.diff diff --git a/atimes.diff b/atimes.diff index 9b60c91..8e0f0a9 100644 --- a/atimes.diff +++ b/atimes.diff @@ -44,7 +44,7 @@ diff --git a/flist.c b/flist.c extern int relative_paths; extern int implied_dirs; extern int file_extra_cnt; -@@ -344,7 +345,7 @@ int push_pathname(const char *dir, int len) +@@ -379,7 +380,7 @@ int push_pathname(const char *dir, int len) static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ndx) { @@ -53,7 +53,7 @@ diff --git a/flist.c b/flist.c static mode_t mode; #ifdef SUPPORT_HARD_LINKS static int64 dev; -@@ -452,6 +453,13 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ +@@ -487,6 +488,13 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ xflags |= XMIT_SAME_TIME; else modtime = file->modtime; @@ -67,7 +67,7 @@ diff --git a/flist.c b/flist.c #ifdef SUPPORT_HARD_LINKS if (tmp_dev != 0) { -@@ -524,6 +532,8 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ +@@ -559,6 +567,8 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ } if (!(xflags & XMIT_SAME_MODE)) write_int(f, to_wire_mode(mode)); @@ -76,7 +76,7 @@ diff --git a/flist.c b/flist.c if (preserve_uid && !(xflags & XMIT_SAME_UID)) { if (protocol_version < 30) write_int(f, uid); -@@ -610,7 +620,7 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ +@@ -645,7 +655,7 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ static struct file_struct *recv_file_entry(struct file_list *flist, int xflags, int f) { @@ -85,7 +85,7 @@ diff --git a/flist.c b/flist.c static mode_t mode; #ifdef SUPPORT_HARD_LINKS static int64 dev; -@@ -743,6 +753,16 @@ static struct file_struct *recv_file_entry(struct file_list *flist, +@@ -778,6 +788,16 @@ static struct file_struct *recv_file_entry(struct file_list *flist, } if (!(xflags & XMIT_SAME_MODE)) mode = from_wire_mode(read_int(f)); @@ -102,7 +102,7 @@ diff --git a/flist.c b/flist.c if (chmod_modes && !S_ISLNK(mode)) mode = tweak_mode(mode, chmod_modes); -@@ -873,6 +893,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist, +@@ -907,6 +927,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist, F_GROUP(file) = gid; file->flags |= gid_flags; } @@ -111,7 +111,7 @@ diff --git a/flist.c b/flist.c if (unsort_ndx) F_NDX(file) = flist->used + flist->ndx_start; -@@ -1205,6 +1227,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, +@@ -1244,6 +1266,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, F_OWNER(file) = st.st_uid; if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */ F_GROUP(file) = st.st_gid; @@ -131,9 +131,9 @@ diff --git a/generator.c b/generator.c extern int verbose; extern int dry_run; -@@ -633,6 +634,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre +@@ -642,6 +643,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre + : iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED) && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname)) - || (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0)) iflags |= ITEM_REPORT_TIME; + if (atimes_ndx && !S_ISDIR(file->mode) && !S_ISLNK(file->mode) + && cmp_time(f_atime(file), sxp->st.st_atime) != 0) @@ -141,7 +141,7 @@ diff --git a/generator.c b/generator.c #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST if (S_ISLNK(file->mode)) { ; -@@ -987,6 +991,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, +@@ -999,6 +1003,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; @@ -150,7 +150,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 && (verbose > 1 || stdout_format_has_i > 1)) { -@@ -1173,6 +1179,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, +@@ -1184,6 +1190,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]; @@ -158,7 +158,7 @@ diff --git a/generator.c b/generator.c double len; if (!F_IS_ACTIVE(f)) { -@@ -1187,14 +1194,16 @@ static void list_file_entry(struct file_struct *f) +@@ -1198,14 +1205,16 @@ static void list_file_entry(struct file_struct *f) #ifdef SUPPORT_LINKS if (preserve_links && S_ISLNK(f->mode)) { @@ -177,20 +177,20 @@ diff --git a/generator.c b/generator.c f_name(f, NULL)); } } -@@ -1950,7 +1959,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx) - if (!(file->mode & S_IWUSR)) - do_chmod(fname, file->mode); - if (need_retouch_dir_times) -- set_modtime(fname, file->modtime, file->mode); -+ set_times(fname, file->modtime, file->modtime, file->mode); +@@ -2009,7 +2018,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) +- set_modtime(fname, file->modtime, file->mode); ++ set_times(fname, file->modtime, file->modtime, file->mode); + } if (allowed_lull && !(counter % lull_mod)) maybe_send_keepalive(); - else if (!(counter & 0xFF)) diff --git a/ifuncs.h b/ifuncs.h --- a/ifuncs.h +++ b/ifuncs.h -@@ -57,6 +57,28 @@ from_wire_mode(int mode) - return mode; +@@ -67,6 +67,28 @@ d_name(struct dirent *di) + #endif } +static inline time_t @@ -221,7 +221,7 @@ diff --git a/ifuncs.h b/ifuncs.h diff --git a/log.c b/log.c --- a/log.c +++ b/log.c -@@ -644,7 +644,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op, +@@ -650,7 +650,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'; @@ -234,7 +234,7 @@ diff --git a/log.c b/log.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -58,6 +58,7 @@ int preserve_specials = 0; +@@ -59,6 +59,7 @@ int preserve_specials = 0; int preserve_uid = 0; int preserve_gid = 0; int preserve_times = 0; @@ -242,7 +242,7 @@ diff --git a/options.c b/options.c int update_only = 0; int cvs_exclude = 0; int dry_run = 0; -@@ -352,6 +353,7 @@ void usage(enum logcode F) +@@ -353,6 +354,7 @@ void usage(enum logcode F) rprintf(F," -D same as --devices --specials\n"); rprintf(F," -t, --times preserve modification times\n"); rprintf(F," -O, --omit-dir-times omit directories from --times\n"); @@ -250,7 +250,7 @@ diff --git a/options.c b/options.c rprintf(F," --super receiver attempts super-user activities\n"); #ifdef SUPPORT_XATTRS rprintf(F," --fake-super store/recover privileged attrs using xattrs\n"); -@@ -487,6 +489,9 @@ static struct poptOption long_options[] = { +@@ -490,6 +492,9 @@ static struct poptOption long_options[] = { {"times", 't', POPT_ARG_VAL, &preserve_times, 2, 0, 0 }, {"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 }, {"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 }, @@ -260,7 +260,7 @@ diff --git a/options.c b/options.c {"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 }, {"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 }, {"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 }, -@@ -1747,6 +1752,8 @@ void server_options(char **args, int *argc_p) +@@ -1773,6 +1778,8 @@ void server_options(char **args, int *argc_p) argstr[x++] = 'D'; if (preserve_times) argstr[x++] = 't'; @@ -272,7 +272,7 @@ diff --git a/options.c b/options.c diff --git a/rsync.c b/rsync.c --- a/rsync.c +++ b/rsync.c -@@ -345,6 +345,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -380,6 +380,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, int updated = 0; stat_x sx2; int change_uid, change_gid; @@ -280,7 +280,7 @@ diff --git a/rsync.c b/rsync.c mode_t new_mode = file->mode; int inherit; -@@ -388,20 +389,39 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -423,20 +424,38 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, set_xattr(fname, file, fnamecmp, sxp); #endif @@ -315,17 +315,15 @@ diff --git a/rsync.c b/rsync.c } - if (ret == 0) /* ret == 1 if symlink could not be set */ - updated = 1; -- else if (receiver_symlink_times) -- file->flags |= FLAG_TIME_FAILED; +- else + if (ret > 0) { /* ret == 1 if symlink could not be set */ + updated = 0; -+ if (receiver_symlink_times) -+ file->flags |= FLAG_TIME_FAILED; + file->flags |= FLAG_TIME_FAILED; + } } change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file); -@@ -531,7 +551,7 @@ int finish_transfer(const char *fname, const char *fnametmp, +@@ -566,7 +585,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, @@ -334,7 +332,7 @@ diff --git a/rsync.c b/rsync.c /* move tmp file over real file */ if (verbose > 2) -@@ -558,7 +578,7 @@ int finish_transfer(const char *fname, const char *fnametmp, +@@ -593,7 +612,7 @@ int finish_transfer(const char *fname, const char *fnametmp, do_set_file_attrs: set_file_attrs(fnametmp, file, NULL, fnamecmp, @@ -354,7 +352,7 @@ diff --git a/rsync.h b/rsync.h /* These flags are used in the live flist data. */ -@@ -149,6 +150,7 @@ +@@ -151,6 +152,7 @@ #define ATTRS_REPORT (1<<0) #define ATTRS_SKIP_MTIME (1<<1) @@ -362,7 +360,7 @@ diff --git a/rsync.h b/rsync.h #define FULL_FLUSH 1 #define NORMAL_FLUSH 0 -@@ -620,12 +622,14 @@ extern int file_extra_cnt; +@@ -622,12 +624,14 @@ extern int file_extra_cnt; extern int inc_recurse; extern int uid_ndx; extern int gid_ndx; @@ -388,7 +386,7 @@ diff --git a/rsync.yo b/rsync.yo --super receiver attempts super-user activities --fake-super store/recover privileged attrs using xattrs -S, --sparse handle sparse files efficiently -@@ -987,6 +988,12 @@ it is preserving modification times (see bf(--times)). If NFS is sharing +@@ -994,6 +995,12 @@ it is preserving modification times (see bf(--times)). If NFS is sharing the directories on the receiving side, it is a good idea to use bf(-O). This option is inferred if you use bf(--backup) without bf(--backup-dir). @@ -401,7 +399,7 @@ diff --git a/rsync.yo b/rsync.yo dit(bf(--super)) This tells the receiving side to attempt super-user activities even if the receiving rsync wasn't run by the super-user. These activities include: preserving users via the bf(--owner) option, preserving -@@ -1689,7 +1696,10 @@ quote(itemization( +@@ -1701,7 +1708,10 @@ quote(itemization( sender's value (requires bf(--owner) and super-user privileges). it() A bf(g) means the group is different and is being updated to the sender's value (requires bf(--group) and the authority to set the group). diff --git a/backup-dir-dels.diff b/backup-dir-dels.diff index ee24be9..51d8489 100644 --- a/backup-dir-dels.diff +++ b/backup-dir-dels.diff @@ -89,7 +89,12 @@ diff --git a/backup.c b/backup.c unmake_file(file); return 0; } -@@ -326,3 +351,13 @@ int make_backup(const char *fname) +@@ -322,7 +347,17 @@ static int keep_backup(const char *fname) + /* main backup switch routine */ + int make_backup(const char *fname) + { +- if (backup_dir) ++ if (deleting ? backup_dir_dels : backup_dir) return keep_backup(fname); return make_simple_backup(fname); } @@ -106,7 +111,7 @@ diff --git a/backup.c b/backup.c diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -97,6 +97,9 @@ extern uid_t our_uid; +@@ -96,6 +96,9 @@ extern uid_t our_uid; extern char *backup_dir; extern char *backup_suffix; extern int backup_suffix_len; @@ -114,11 +119,11 @@ diff --git a/generator.c b/generator.c +extern char *backup_suffix_dels; +extern int backup_suffix_dels_len; extern struct file_list *cur_flist, *first_flist, *dir_flist; - extern struct filter_list_struct server_filter_list; + extern struct filter_list_struct daemon_filter_list; -@@ -138,10 +141,15 @@ enum delret { - /* Forward declaration for delete_item(). */ - static enum delret delete_dir_contents(char *fname, uint16 flags); +@@ -142,10 +145,15 @@ static void handle_skipped_hlink(struct file_struct *file, int itemizing, + enum logcode code, int f_out); + #endif + +/* Function now compares both backup_suffix and backup_suffix_dels. */ @@ -133,7 +138,7 @@ diff --git a/generator.c b/generator.c } /* Delete a file or directory. If DEL_RECURSE is set in the flags, this will -@@ -189,9 +197,9 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) +@@ -193,9 +201,9 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) if (S_ISDIR(mode)) { what = "rmdir"; ok = do_rmdir(fbuf) == 0; @@ -148,7 +153,7 @@ diff --git a/generator.c b/generator.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -149,10 +149,14 @@ int no_detach +@@ -150,10 +150,14 @@ int no_detach int write_batch = 0; int read_batch = 0; int backup_dir_len = 0; @@ -163,7 +168,7 @@ diff --git a/options.c b/options.c char *tmpdir = NULL; char *partial_dir = NULL; char *basis_dir[MAX_BASIS_DIRS+1]; -@@ -164,7 +168,9 @@ char *stdout_format = NULL; +@@ -165,7 +169,9 @@ char *stdout_format = NULL; char *password_file = NULL; char *rsync_path = RSYNC_PATH; char *backup_dir = NULL; @@ -173,16 +178,16 @@ diff --git a/options.c b/options.c char *sockopts = NULL; int rsync_port = 0; int compare_dest = 0; -@@ -324,6 +330,8 @@ void usage(enum logcode F) +@@ -325,6 +331,8 @@ void usage(enum logcode F) rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n"); rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n"); rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX); -+ rprintf(F," --backup-dir-dels make backups of removed files into current dir\n"); -+ rprintf(F," --suffix-dels=SUFFIX set removed-files suffix (defaults to --suffix)\n"); ++ rprintf(F," --backup-dir-dels=DIR backup removed files into hierarchy based in DIR\n"); ++ rprintf(F," --suffix-dels=SUFFIX set removed-files suffix (def. --suffix w/o b-d-d)\n"); rprintf(F," -u, --update skip files that are newer on the receiver\n"); rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n"); rprintf(F," --append append data onto shorter files\n"); -@@ -597,7 +605,9 @@ static struct poptOption long_options[] = { +@@ -609,7 +617,9 @@ static struct poptOption long_options[] = { {"backup", 'b', POPT_ARG_VAL, &make_backups, 1, 0, 0 }, {"no-backup", 0, POPT_ARG_VAL, &make_backups, 0, 0, 0 }, {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 }, @@ -192,17 +197,17 @@ diff --git a/options.c b/options.c {"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 }, {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 }, {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 }, -@@ -1427,6 +1437,8 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) - tmpdir = sanitize_path(NULL, tmpdir, NULL, 0); +@@ -1453,6 +1463,8 @@ int parse_arguments(int *argc_p, const char ***argv_p) + tmpdir = sanitize_path(NULL, tmpdir, NULL, 0, SP_DEFAULT); if (backup_dir) - backup_dir = sanitize_path(NULL, backup_dir, NULL, 0); + backup_dir = sanitize_path(NULL, backup_dir, NULL, 0, SP_DEFAULT); + if (backup_dir_dels) -+ backup_dir_dels = sanitize_path(NULL, backup_dir_dels, NULL, 0); ++ backup_dir_dels = sanitize_path(NULL, backup_dir_dels, NULL, 0, SP_DEFAULT); } - if (server_filter_list.head && !am_sender) { - struct filter_list_struct *elp = &server_filter_list; -@@ -1448,6 +1460,14 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) - if (check_filter(elp, dir, 1) < 0) + if (daemon_filter_list.head && !am_sender) { + struct filter_list_struct *elp = &daemon_filter_list; +@@ -1474,6 +1486,14 @@ int parse_arguments(int *argc_p, const char ***argv_p) + if (check_filter(elp, FLOG, dir, 1) < 0) goto options_rejected; } + /* Clean backup_dir_dels same as for backup_dir */ @@ -216,10 +221,15 @@ diff --git a/options.c b/options.c } if (!backup_suffix) -@@ -1459,6 +1479,15 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1485,6 +1505,20 @@ int parse_arguments(int *argc_p, const char ***argv_p) backup_suffix); return 0; } ++ /* --suffix-dels defaults to --suffix, or empty for a client given an ++ * explicit --backup-dir-dels (just as --suffix defaults to empty when ++ * a --backup-dir is given). The second case does not apply to the ++ * server for consistency with server_options, which sends --suffix-dels ++ * to the server iff it differs from --suffix. */ + if (!backup_suffix_dels) + backup_suffix_dels = backup_dir_dels && !am_server ? "" : backup_suffix; + backup_suffix_dels_len = strlen(backup_suffix_dels); @@ -232,7 +242,7 @@ diff --git a/options.c b/options.c if (backup_dir) { backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf); backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len; -@@ -1482,6 +1511,30 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1508,6 +1542,34 @@ int parse_arguments(int *argc_p, const char ***argv_p) "P *%s", backup_suffix); parse_rule(&filter_list, backup_dir_buf, 0, 0); } @@ -259,11 +269,15 @@ diff --git a/options.c b/options.c + snprintf(err_buf, sizeof err_buf, + "--suffix-dels cannot be a null string without --backup-dir-dels\n"); + return 0; ++ } else if (make_backups && delete_mode && !delete_excluded && !am_server) { ++ snprintf(backup_dir_dels_buf, sizeof backup_dir_dels_buf, ++ "P *%s", backup_suffix_dels); ++ parse_rule(&filter_list, backup_dir_dels_buf, 0, 0); + } if (make_backups && !backup_dir) { omit_dir_times = 0; /* Implied, so avoid -O to sender. */ -@@ -1875,6 +1928,10 @@ void server_options(char **args, int *argc_p) +@@ -1901,6 +1963,10 @@ void server_options(char **args, int *argc_p) args[ac++] = "--backup-dir"; args[ac++] = backup_dir; } @@ -274,7 +288,7 @@ diff --git a/options.c b/options.c /* Only send --suffix if it specifies a non-default value. */ if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) { -@@ -1883,7 +1940,14 @@ void server_options(char **args, int *argc_p) +@@ -1909,7 +1975,14 @@ void server_options(char **args, int *argc_p) goto oom; args[ac++] = arg; } diff --git a/catch_crash_signals.diff b/catch_crash_signals.diff index 2b7d8be..d7c0e12 100644 --- a/catch_crash_signals.diff +++ b/catch_crash_signals.diff @@ -51,7 +51,7 @@ diff --git a/log.c b/log.c diff --git a/main.c b/main.c --- a/main.c +++ b/main.c -@@ -166,8 +166,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr) +@@ -163,8 +163,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr) *exit_code_ptr = RERR_TERMINATED; else *exit_code_ptr = RERR_WAITCHILD; @@ -64,7 +64,7 @@ diff --git a/main.c b/main.c } /* This function gets called from all 3 processes. We want the client side -@@ -1346,6 +1349,14 @@ RETSIGTYPE remember_children(UNUSED(int val)) +@@ -1306,6 +1309,14 @@ RETSIGTYPE remember_children(UNUSED(int val)) break; } } @@ -79,7 +79,7 @@ diff --git a/main.c b/main.c } #endif #ifndef HAVE_SIGACTION -@@ -1404,6 +1415,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig)) +@@ -1364,6 +1375,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig)) } #endif @@ -92,7 +92,7 @@ diff --git a/main.c b/main.c int main(int argc,char *argv[]) { -@@ -1426,6 +1443,11 @@ int main(int argc,char *argv[]) +@@ -1386,6 +1403,11 @@ int main(int argc,char *argv[]) SIGACTMASK(SIGFPE, rsync_panic_handler); SIGACTMASK(SIGABRT, rsync_panic_handler); SIGACTMASK(SIGBUS, rsync_panic_handler); diff --git a/checksum-reading.diff b/checksum-reading.diff index ff96510..6618269 100644 --- a/checksum-reading.diff +++ b/checksum-reading.diff @@ -31,7 +31,7 @@ diff --git a/checksum.c b/checksum.c diff --git a/clientserver.c b/clientserver.c --- a/clientserver.c +++ b/clientserver.c -@@ -39,6 +39,8 @@ extern int numeric_ids; +@@ -42,6 +42,8 @@ extern int numeric_ids; extern int filesfrom_fd; extern int remote_protocol; extern int protocol_version; @@ -40,8 +40,8 @@ diff --git a/clientserver.c b/clientserver.c extern int io_timeout; extern int no_detach; extern int write_batch; -@@ -750,6 +752,9 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host) - else if (am_root < 0) /* Treat --fake-super from client as --super. */ +@@ -782,6 +784,9 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host) + } else if (am_root < 0) /* Treat --fake-super from client as --super. */ am_root = 2; + checksum_files = always_checksum ? lp_checksum_files(i) @@ -77,11 +77,12 @@ diff --git a/flist.c b/flist.c extern struct stats stats; extern char *filesfrom_host; -@@ -83,6 +86,11 @@ extern int filesfrom_convert; +@@ -83,6 +86,12 @@ extern int filesfrom_convert; extern iconv_t ic_send, ic_recv; #endif +#define RSYNCSUMS_FILE ".rsyncsums" ++#define RSYNCSUMS_LEN (sizeof RSYNCSUMS_FILE-1) + +#define CLEAN_STRIP_ROOT (1<<0) +#define CLEAN_KEEP_LAST (1<<1) @@ -89,7 +90,7 @@ diff --git a/flist.c b/flist.c #define PTR_SIZE (sizeof (struct file_struct *)) int io_error; -@@ -124,7 +132,11 @@ static char empty_sum[MAX_DIGEST_LEN]; +@@ -124,7 +133,11 @@ static char empty_sum[MAX_DIGEST_LEN]; static int flist_count_offset; /* for --delete --progress */ static int dir_count = 0; @@ -102,7 +103,7 @@ diff --git a/flist.c b/flist.c static void output_flist(struct file_list *flist); void init_flist(void) -@@ -315,6 +327,238 @@ static void flist_done_allocating(struct file_list *flist) +@@ -350,6 +363,238 @@ static void flist_done_allocating(struct file_list *flist) flist->pool_boundary = ptr; } @@ -133,8 +134,7 @@ diff --git a/flist.c b/flist.c + } +} + -+ -+/* The basename_len count is the length of the basename + 1 for the null. */ ++/* The basename_len count is the length of the basename + 1 for the '\0'. */ +static int add_checksum(struct file_list *flist, const char *dirname, + const char *basename, int basename_len, OFF_T file_length, + time_t mtime, uint32 ctime, uint32 inode, @@ -144,7 +144,8 @@ diff --git a/flist.c b/flist.c + int alloc_len, extra_len; + char *bp; + -+ if (basename_len == 10+1 && *basename == '.' && strcmp(basename, RSYNCSUMS_FILE) == 0) ++ if (basename_len == RSYNCSUMS_LEN+1 && *basename == '.' ++ && strcmp(basename, RSYNCSUMS_FILE) == 0) + return 0; + + /* "2" is for a 32-bit ctime num and an 32-bit inode num. */ @@ -198,7 +199,7 @@ diff --git a/flist.c b/flist.c + uint32 ctime, inode; + int dlen = dirname ? strlcpy(fbuf, dirname, sizeof fbuf) : 0; + -+ if (dlen >= (int)(sizeof fbuf - sizeof RSYNCSUMS_FILE)) ++ if (dlen >= (int)(sizeof fbuf - 1 - RSYNCSUMS_LEN)) + return; + if (dlen) + fbuf[dlen++] = '/'; @@ -341,7 +342,7 @@ diff --git a/flist.c b/flist.c int push_pathname(const char *dir, int len) { if (dir == pathname) -@@ -1005,7 +1249,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, +@@ -1039,7 +1284,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, STRUCT_STAT *stp, int flags, int filter_level) { static char *lastdir; @@ -350,7 +351,7 @@ diff --git a/flist.c b/flist.c struct file_struct *file; char thisname[MAXPATHLEN]; char linkname[MAXPATHLEN]; -@@ -1138,9 +1382,16 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, +@@ -1178,9 +1423,16 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, memcpy(lastdir, thisname, len); lastdir[len] = '\0'; lastdir_len = len; @@ -368,14 +369,17 @@ diff --git a/flist.c b/flist.c basename_len = strlen(basename) + 1; /* count the '\0' */ #ifdef SUPPORT_LINKS -@@ -1216,11 +1467,15 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, - } +@@ -1253,14 +1505,18 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, + memcpy(bp + basename_len, linkname, linkname_len); #endif - if (always_checksum && am_sender && S_ISREG(st.st_mode)) - file_checksum(thisname, tmp_sum, st.st_size); - - F_PATHNAME(file) = pathname; + if (am_sender) + F_PATHNAME(file) = pathname; + else if (!pool) + F_DEPTH(file) = extra_len / EXTRA_LEN; + if (always_checksum && am_sender && S_ISREG(st.st_mode)) { + if (flist && checksum_files) @@ -387,7 +391,7 @@ diff --git a/flist.c b/flist.c /* This code is only used by the receiver when it is building * a list of files for a delete pass. */ if (keep_dirlinks && linkname_len && flist) { -@@ -2076,7 +2331,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) +@@ -2131,7 +2387,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) * file-list to check if this is a 1-file xfer. */ send_extra_file_list(f, 1); } @@ -397,7 +401,7 @@ diff --git a/flist.c b/flist.c return flist; } -@@ -2178,7 +2434,7 @@ struct file_list *recv_file_list(int f) +@@ -2233,7 +2490,7 @@ struct file_list *recv_file_list(int f) else if (f >= 0) recv_id_list(f, flist); @@ -406,7 +410,7 @@ diff --git a/flist.c b/flist.c if (protocol_version < 30) { /* Recv the io_error flag */ -@@ -2376,7 +2632,7 @@ void flist_free(struct file_list *flist) +@@ -2431,7 +2688,7 @@ void flist_free(struct file_list *flist) /* This routine ensures we don't have any duplicate names in our file list. * duplicate names can cause corruption because of the pipelining. */ @@ -415,7 +419,7 @@ diff --git a/flist.c b/flist.c { char fbuf[MAXPATHLEN]; int i, prev_i; -@@ -2427,7 +2683,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root) +@@ -2482,7 +2739,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root) /* If one is a dir and the other is not, we want to * keep the dir because it might have contents in the * list. Otherwise keep the first one. */ @@ -424,7 +428,7 @@ diff --git a/flist.c b/flist.c struct file_struct *fp = flist->sorted[j]; if (!S_ISDIR(fp->mode)) keep = i, drop = j; -@@ -2443,8 +2699,8 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root) +@@ -2498,8 +2755,8 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root) } else keep = j, drop = i; @@ -435,7 +439,7 @@ diff --git a/flist.c b/flist.c rprintf(FINFO, "removing duplicate name %s from file list (%d)\n", f_name(file, fbuf), drop + flist->ndx_start); -@@ -2466,7 +2722,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root) +@@ -2521,7 +2778,7 @@ static void flist_sort_and_clean(struct file_list *flist, int strip_root) } flist->high = prev_i; @@ -447,7 +451,7 @@ diff --git a/flist.c b/flist.c diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -53,6 +53,7 @@ extern int delete_during; +@@ -52,6 +52,7 @@ extern int delete_during; extern int delete_after; extern int msgdone_cnt; extern int ignore_errors; @@ -455,7 +459,7 @@ diff --git a/generator.c b/generator.c extern int remove_source_files; extern int delay_updates; extern int update_only; -@@ -694,7 +695,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre +@@ -706,7 +707,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. */ @@ -464,7 +468,7 @@ diff --git a/generator.c b/generator.c { if (st->st_size != F_LENGTH(file)) return 0; -@@ -703,7 +704,10 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st) +@@ -715,7 +716,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]; @@ -476,7 +480,7 @@ diff --git a/generator.c b/generator.c return memcmp(sum, F_SUM(file), checksum_len) == 0; } -@@ -957,7 +961,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, +@@ -969,7 +973,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, match_level = 1; /* FALL THROUGH */ case 1: @@ -485,16 +489,16 @@ diff --git a/generator.c b/generator.c continue; best_match = j; match_level = 2; -@@ -1219,7 +1223,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, - static const char *parent_dirname = ""; - static struct file_struct *missing_dir = NULL, *excluded_dir = NULL; +@@ -1242,7 +1246,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 = NULL; - static int need_fuzzy_dirlist = 0; + static int need_new_dirscan = 0; struct file_struct *fuzzy_file = NULL; int fd = -1, f_copy = -1; stat_x sx, real_sx; -@@ -1309,8 +1313,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1331,8 +1335,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, flist_free(fuzzy_dirlist); fuzzy_dirlist = NULL; } @@ -505,7 +509,7 @@ diff --git a/generator.c b/generator.c #ifdef SUPPORT_ACLS if (!preserve_perms) dflt_perms = default_perms_for_dir(dn); -@@ -1318,10 +1322,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1340,10 +1344,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } parent_dirname = dn; @@ -525,7 +529,7 @@ diff --git a/generator.c b/generator.c } statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir); -@@ -1742,7 +1751,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1768,7 +1777,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, ; else if (fnamecmp_type == FNAMECMP_FUZZY) ; @@ -537,7 +541,7 @@ diff --git a/generator.c b/generator.c diff --git a/hlink.c b/hlink.c --- a/hlink.c +++ b/hlink.c -@@ -351,7 +351,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname, +@@ -388,7 +388,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname, } break; } @@ -549,7 +553,7 @@ diff --git a/hlink.c b/hlink.c diff --git a/ifuncs.h b/ifuncs.h --- a/ifuncs.h +++ b/ifuncs.h -@@ -64,6 +64,12 @@ isDigit(const char *ptr) +@@ -74,6 +74,12 @@ isDigit(const char *ptr) } static inline int @@ -613,7 +617,7 @@ diff --git a/loadparm.c b/loadparm.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -112,6 +112,7 @@ size_t bwlimit_writemax = 0; +@@ -113,6 +113,7 @@ size_t bwlimit_writemax = 0; int ignore_existing = 0; int ignore_non_existing = 0; int need_messages_from_generator = 0; @@ -621,7 +625,7 @@ diff --git a/options.c b/options.c int max_delete = INT_MIN; OFF_T max_size = 0; OFF_T min_size = 0; -@@ -316,6 +317,7 @@ void usage(enum logcode F) +@@ -317,6 +318,7 @@ void usage(enum logcode F) rprintf(F," -q, --quiet suppress non-error messages\n"); rprintf(F," --no-motd suppress daemon-mode MOTD (see manpage caveat)\n"); rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n"); @@ -629,7 +633,7 @@ diff --git a/options.c b/options.c rprintf(F," -a, --archive archive mode; equals -rlptgoD (no -H,-A,-X)\n"); rprintf(F," --no-OPTION turn off an implied OPTION (e.g. --no-D)\n"); rprintf(F," -r, --recursive recurse into directories\n"); -@@ -445,7 +447,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, +@@ -446,7 +448,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, @@ -638,7 +642,7 @@ diff --git a/options.c b/options.c OPT_SERVER, OPT_REFUSED_BASE = 9000}; static struct poptOption long_options[] = { -@@ -566,6 +568,7 @@ static struct poptOption long_options[] = { +@@ -574,6 +576,7 @@ static struct poptOption long_options[] = { {"checksum", 'c', POPT_ARG_VAL, &always_checksum, 1, 0, 0 }, {"no-checksum", 0, POPT_ARG_VAL, &always_checksum, 0, 0, 0 }, {"no-c", 0, POPT_ARG_VAL, &always_checksum, 0, 0, 0 }, @@ -646,7 +650,7 @@ diff --git a/options.c b/options.c {"block-size", 'B', POPT_ARG_LONG, &block_size, 0, 0, 0 }, {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 }, {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 }, -@@ -1212,6 +1215,23 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1228,6 +1231,23 @@ int parse_arguments(int *argc_p, const char ***argv_p) } break; @@ -670,11 +674,11 @@ diff --git a/options.c b/options.c case OPT_HELP: usage(FINFO); exit_cleanup(0); -@@ -1311,6 +1331,9 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1332,6 +1352,9 @@ int parse_arguments(int *argc_p, const char ***argv_p) } #endif -+ if (checksum_files && !always_checksum) ++ if (!always_checksum) + checksum_files = CSF_IGNORE_FILES; + if (write_batch && read_batch) { @@ -683,7 +687,7 @@ diff --git a/options.c b/options.c diff --git a/rsync.h b/rsync.h --- a/rsync.h +++ b/rsync.h -@@ -680,6 +680,10 @@ extern int xattrs_ndx; +@@ -682,6 +682,10 @@ extern int xattrs_ndx; #define F_SUM(f) ((char*)OPT_EXTRA(f, LEN64_BUMP(f) + HLINK_BUMP(f) \ + SUM_EXTRA_CNT - 1)) @@ -694,7 +698,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) -@@ -858,6 +862,13 @@ typedef struct { +@@ -860,6 +864,13 @@ typedef struct { char fname[1]; /* has variable size */ } relnamecache; diff --git a/checksum-updating.diff b/checksum-updating.diff index 8a7a5ca..8666a12 100644 --- a/checksum-updating.diff +++ b/checksum-updating.diff @@ -28,7 +28,7 @@ diff --git a/flist.c b/flist.c extern int am_root; extern int am_server; extern int am_daemon; -@@ -93,6 +94,9 @@ extern iconv_t ic_send, ic_recv; +@@ -94,6 +95,9 @@ extern iconv_t ic_send, ic_recv; #define PTR_SIZE (sizeof (struct file_struct *)) @@ -38,7 +38,7 @@ diff --git a/flist.c b/flist.c int io_error; int checksum_len; dev_t filesystem_dev; /* used to implement -x */ -@@ -132,8 +136,13 @@ static char empty_sum[MAX_DIGEST_LEN]; +@@ -133,8 +137,13 @@ static char empty_sum[MAX_DIGEST_LEN]; static int flist_count_offset; /* for --delete --progress */ static int dir_count = 0; @@ -52,7 +52,7 @@ diff --git a/flist.c b/flist.c } *csum_cache = NULL; static void flist_sort_and_clean(struct file_list *flist, int flags); -@@ -327,7 +336,79 @@ static void flist_done_allocating(struct file_list *flist) +@@ -363,7 +372,79 @@ static void flist_done_allocating(struct file_list *flist) flist->pool_boundary = ptr; } @@ -133,7 +133,7 @@ diff --git a/flist.c b/flist.c { int slot, slots = am_sender ? 1 : basis_dir_cnt + 1; -@@ -341,6 +422,9 @@ void reset_checksum_cache() +@@ -377,6 +458,9 @@ void reset_checksum_cache() struct file_list *flist = csum_cache[slot].flist; if (flist) { @@ -143,7 +143,7 @@ diff --git a/flist.c b/flist.c /* Reset the pool memory and empty the file-list array. */ pool_free_old(flist->file_pool, pool_boundary(flist->file_pool, 0)); -@@ -351,6 +435,10 @@ void reset_checksum_cache() +@@ -387,6 +471,10 @@ void reset_checksum_cache() flist->low = 0; flist->high = -1; flist->next = NULL; @@ -154,7 +154,7 @@ diff --git a/flist.c b/flist.c } } -@@ -359,7 +447,7 @@ void reset_checksum_cache() +@@ -394,7 +482,7 @@ void reset_checksum_cache() static int add_checksum(struct file_list *flist, const char *dirname, const char *basename, int basename_len, OFF_T file_length, time_t mtime, uint32 ctime, uint32 inode, @@ -163,7 +163,7 @@ diff --git a/flist.c b/flist.c { struct file_struct *file; int alloc_len, extra_len; -@@ -375,7 +463,7 @@ static int add_checksum(struct file_list *flist, const char *dirname, +@@ -411,7 +499,7 @@ static int add_checksum(struct file_list *flist, const char *dirname, if (extra_len & (EXTRA_ROUNDING * EXTRA_LEN)) extra_len = (extra_len | (EXTRA_ROUNDING * EXTRA_LEN)) + EXTRA_LEN; #endif @@ -172,7 +172,7 @@ diff --git a/flist.c b/flist.c bp = pool_alloc(flist->file_pool, alloc_len, "add_checksum"); memset(bp, 0, extra_len + FILE_STRUCT_LEN); -@@ -384,7 +472,14 @@ static int add_checksum(struct file_list *flist, const char *dirname, +@@ -420,7 +508,14 @@ static int add_checksum(struct file_list *flist, const char *dirname, bp += FILE_STRUCT_LEN; memcpy(bp, basename, basename_len); @@ -187,7 +187,7 @@ diff --git a/flist.c b/flist.c file->mode = S_IFREG; file->modtime = mtime; file->len32 = (uint32)file_length; -@@ -413,10 +508,11 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam +@@ -449,10 +544,11 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam char line[MAXPATHLEN+1024], fbuf[MAXPATHLEN], sum[MAX_DIGEST_LEN]; FILE *fp; char *cp; @@ -199,8 +199,8 @@ diff --git a/flist.c b/flist.c + const char *alt_sum = NULL; int dlen = dirname ? strlcpy(fbuf, dirname, sizeof fbuf) : 0; - if (dlen >= (int)(sizeof fbuf - sizeof RSYNCSUMS_FILE)) -@@ -437,7 +533,7 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam + if (dlen >= (int)(sizeof fbuf - 1 - RSYNCSUMS_LEN)) +@@ -473,7 +569,7 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam while (fgets(line, sizeof line, fp)) { cp = line; if (protocol_version >= 30) { @@ -209,7 +209,7 @@ diff --git a/flist.c b/flist.c if (*cp == '=') while (*++cp == '=') {} else -@@ -448,7 +544,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam +@@ -484,7 +580,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam } if (*cp == '=') { @@ -225,7 +225,7 @@ diff --git a/flist.c b/flist.c } else { for (i = 0; i < checksum_len*2; i++, cp++) { int x; -@@ -466,13 +569,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam +@@ -502,13 +605,14 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam else sum[i/2] = x << 4; } @@ -241,7 +241,7 @@ diff --git a/flist.c b/flist.c if (*cp == '=') while (*++cp == '=') {} else -@@ -522,24 +626,112 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam +@@ -558,24 +662,112 @@ static void read_checksums(int slot, struct file_list *flist, const char *dirnam continue; strlcpy(fbuf+dlen, cp, sizeof fbuf - dlen); @@ -356,7 +356,7 @@ diff --git a/flist.c b/flist.c read_checksums(slot, flist, file->dirname); } -@@ -551,12 +743,31 @@ void get_cached_checksum(int slot, const char *fname, struct file_struct *file, +@@ -587,12 +779,31 @@ void get_cached_checksum(int slot, const char *fname, struct file_struct *file, && (checksum_files & CSF_LAX || (F_CTIME(fp) == (uint32)stp->st_ctime && F_INODE(fp) == (uint32)stp->st_ino))) { @@ -389,7 +389,7 @@ diff --git a/flist.c b/flist.c } int push_pathname(const char *dir, int len) -@@ -1343,6 +1554,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, +@@ -1378,6 +1589,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, if (is_excluded(thisname, S_ISDIR(st.st_mode) != 0, filter_level)) { if (ignore_perishable) non_perishable_cnt++; @@ -398,7 +398,7 @@ diff --git a/flist.c b/flist.c return NULL; } -@@ -1383,13 +1596,13 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, +@@ -1424,13 +1637,13 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, lastdir[len] = '\0'; lastdir_len = len; if (checksum_files && am_sender && flist) @@ -414,7 +414,7 @@ diff --git a/flist.c b/flist.c } } basename_len = strlen(basename) + 1; /* count the '\0' */ -@@ -1471,7 +1684,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, +@@ -1512,7 +1725,7 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, if (always_checksum && am_sender && S_ISREG(st.st_mode)) { if (flist && checksum_files) @@ -423,7 +423,7 @@ diff --git a/flist.c b/flist.c else file_checksum(thisname, st.st_size, tmp_sum); } -@@ -1768,6 +1981,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len, +@@ -1804,6 +2017,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len, closedir(d); @@ -433,7 +433,7 @@ diff --git a/flist.c b/flist.c if (f >= 0 && recurse && !divert_dirs) { int i, end = flist->used - 1; /* send_if_directory() bumps flist->used, so use "end". */ -@@ -2333,6 +2549,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) +@@ -2389,6 +2605,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) } } else flist_eof = 1; @@ -446,15 +446,15 @@ diff --git a/flist.c b/flist.c diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -114,6 +114,7 @@ static int lull_mod; - static int dir_tweaking; +@@ -114,6 +114,7 @@ static int dir_tweaking; + static int symlink_timeset_failed_flags; static int need_retouch_dir_times; static int need_retouch_dir_perms; +static int started_whole_dir, upcoming_whole_dir; static const char *solo_file = NULL; /* For calling delete_item() and delete_dir_contents(). */ -@@ -705,7 +706,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot +@@ -717,7 +718,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) @@ -463,7 +463,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; -@@ -1328,7 +1329,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1350,7 +1351,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, 1); } if (checksum_files) { @@ -473,15 +473,15 @@ diff --git a/generator.c b/generator.c } need_new_dirscan = 0; } -@@ -1457,9 +1459,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1488,9 +1490,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, DEV_MINOR(devp) = minor(real_sx.st.st_dev); } } -- else if (delete_during && f_out != -1 && !phase && dry_run < 2 -- && (file->flags & FLAG_CONTENT_DIR)) +- else if (delete_during && f_out != -1 && !phase +- && BITS_SETnUNSET(file->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR)) - delete_in_dir(fname, file, &real_sx.st.st_dev); + else if (file->flags & FLAG_CONTENT_DIR && f_out != -1) { -+ if (delete_during && !phase && dry_run < 2) ++ if (delete_during && !phase && !(file->flags & FLAG_MISSING_DIR)) + delete_in_dir(fname, file, &real_sx.st.st_dev); + upcoming_whole_dir = 1; + } else @@ -489,7 +489,7 @@ diff --git a/generator.c b/generator.c goto cleanup; } -@@ -1757,6 +1762,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1783,6 +1788,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); @@ -498,7 +498,7 @@ diff --git a/generator.c b/generator.c if (itemizing) itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL); #ifdef SUPPORT_HARD_LINKS -@@ -2132,6 +2139,7 @@ void generate_files(int f_out, const char *local_name) +@@ -2195,6 +2202,7 @@ void generate_files(int f_out, const char *local_name) delete_in_dir(f_name(fp, fbuf), fp, &dirdev); } } @@ -506,7 +506,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]; -@@ -2212,6 +2220,9 @@ void generate_files(int f_out, const char *local_name) +@@ -2275,6 +2283,9 @@ void generate_files(int f_out, const char *local_name) wait_for_receiver(); } @@ -519,7 +519,7 @@ diff --git a/generator.c b/generator.c diff --git a/io.c b/io.c --- a/io.c +++ b/io.c -@@ -49,6 +49,7 @@ extern int read_batch; +@@ -50,6 +50,7 @@ extern int read_batch; extern int csum_length; extern int protect_args; extern int checksum_seed; @@ -527,7 +527,7 @@ diff --git a/io.c b/io.c extern int protocol_version; extern int remove_source_files; extern int preserve_hard_links; -@@ -200,6 +201,9 @@ static void got_flist_entry_status(enum festatus status, const char *buf) +@@ -205,6 +206,9 @@ static void got_flist_entry_status(enum festatus status, const char *buf) flist_ndx_push(&hlink_list, ndx); flist->in_progress++; } @@ -554,7 +554,7 @@ diff --git a/loadparm.c b/loadparm.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -1217,7 +1217,15 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1233,7 +1233,15 @@ int parse_arguments(int *argc_p, const char ***argv_p) case OPT_SUMFILES: arg = poptGetOptArg(pc); @@ -603,7 +603,7 @@ diff --git a/receiver.c b/receiver.c diff --git a/rsync.h b/rsync.h --- a/rsync.h +++ b/rsync.h -@@ -864,6 +864,8 @@ typedef struct { +@@ -866,6 +866,8 @@ typedef struct { #define CSF_ENABLE (1<<1) #define CSF_LAX (1<<2) diff --git a/checksum-xattr.diff b/checksum-xattr.diff index b5020e6..d4eb3f8 100644 --- a/checksum-xattr.diff +++ b/checksum-xattr.diff @@ -11,8 +11,8 @@ To use this patch, run these commands for a successful build: diff --git a/flist.c b/flist.c --- a/flist.c +++ b/flist.c -@@ -1216,7 +1216,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, - } +@@ -1253,7 +1253,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, + memcpy(bp + basename_len, linkname, linkname_len); #endif - if (always_checksum && am_sender && S_ISREG(st.st_mode)) @@ -20,11 +20,11 @@ diff --git a/flist.c b/flist.c + && !get_sum_xattr(thisname, &st, tmp_sum)) file_checksum(thisname, tmp_sum, st.st_size); - F_PATHNAME(file) = pathname; + if (am_sender) diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -703,7 +703,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st) +@@ -715,7 +715,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]; @@ -169,16 +169,29 @@ diff --git a/xattrs.c b/xattrs.c #define RSYNC_XAL_INITIAL 5 #define RSYNC_XAL_LIST_INITIAL 100 -@@ -65,6 +67,8 @@ extern int checksum_seed; - #define XSTAT_ATTR RSYNC_PREFIX "%stat" - #define XACC_ACL_ATTR RSYNC_PREFIX "%aacl" - #define XDEF_ACL_ATTR RSYNC_PREFIX "%dacl" -+#define MD4_ATTR RSYNC_PREFIX "%md4" -+#define MD5_ATTR RSYNC_PREFIX "%md5" +@@ -68,6 +70,10 @@ extern int checksum_seed; + #define XACC_ACL_ATTR RSYNC_PREFIX "%" XACC_ACL_SUFFIX + #define XDEF_ACL_SUFFIX "dacl" + #define XDEF_ACL_ATTR RSYNC_PREFIX "%" XDEF_ACL_SUFFIX ++#define MD4_SUFFIX "md4" ++#define MD4_ATTR RSYNC_PREFIX "%" MD4_SUFFIX ++#define MD5_SUFFIX "md5" ++#define MD5_ATTR RSYNC_PREFIX "%" MD5_SUFFIX typedef struct { char *datum, *name; -@@ -829,6 +833,39 @@ int del_def_xattr_acl(const char *fname) +@@ -237,7 +243,9 @@ static int rsync_xal_get(const char *fname, item_list *xalp) + || (am_root < 0 + && (strcmp(name+RPRE_LEN+1, XSTAT_SUFFIX) == 0 + || strcmp(name+RPRE_LEN+1, XACC_ACL_SUFFIX) == 0 +- || strcmp(name+RPRE_LEN+1, XDEF_ACL_SUFFIX) == 0))) ++ || strcmp(name+RPRE_LEN+1, XDEF_ACL_SUFFIX) == 0 ++ || strcmp(name+RPRE_LEN+1, MD4_SUFFIX) == 0 ++ || strcmp(name+RPRE_LEN+1, MD5_SUFFIX) == 0))) + continue; + } + +@@ -844,6 +852,39 @@ int del_def_xattr_acl(const char *fname) } #endif diff --git a/copy-devices.diff b/copy-devices.diff index cd87197..f629701 100644 --- a/copy-devices.diff +++ b/copy-devices.diff @@ -11,7 +11,7 @@ To use this patch, run these commands for a successful build: diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -40,6 +40,7 @@ extern int preserve_acls; +@@ -39,6 +39,7 @@ extern int preserve_acls; extern int preserve_xattrs; extern int preserve_links; extern int preserve_devices; @@ -19,7 +19,7 @@ diff --git a/generator.c b/generator.c extern int preserve_specials; extern int preserve_hard_links; extern int preserve_executability; -@@ -1632,7 +1633,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1663,7 +1664,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } @@ -31,7 +31,7 @@ diff --git a/generator.c b/generator.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -47,6 +47,7 @@ int append_mode = 0; +@@ -48,6 +48,7 @@ int append_mode = 0; int keep_dirlinks = 0; int copy_dirlinks = 0; int copy_links = 0; @@ -39,7 +39,7 @@ diff --git a/options.c b/options.c int preserve_links = 0; int preserve_hard_links = 0; int preserve_acls = 0; -@@ -348,6 +349,7 @@ void usage(enum logcode F) +@@ -349,6 +350,7 @@ void usage(enum logcode F) rprintf(F," -o, --owner preserve owner (super-user only)\n"); rprintf(F," -g, --group preserve group\n"); rprintf(F," --devices preserve device files (super-user only)\n"); @@ -47,7 +47,7 @@ diff --git a/options.c b/options.c rprintf(F," --specials preserve special files\n"); rprintf(F," -D same as --devices --specials\n"); rprintf(F," -t, --times preserve modification times\n"); -@@ -504,6 +506,7 @@ static struct poptOption long_options[] = { +@@ -507,6 +509,7 @@ static struct poptOption long_options[] = { {"no-D", 0, POPT_ARG_NONE, 0, OPT_NO_D, 0, 0 }, {"devices", 0, POPT_ARG_VAL, &preserve_devices, 1, 0, 0 }, {"no-devices", 0, POPT_ARG_VAL, &preserve_devices, 0, 0, 0 }, @@ -55,7 +55,7 @@ diff --git a/options.c b/options.c {"specials", 0, POPT_ARG_VAL, &preserve_specials, 1, 0, 0 }, {"no-specials", 0, POPT_ARG_VAL, &preserve_specials, 0, 0, 0 }, {"links", 'l', POPT_ARG_VAL, &preserve_links, 1, 0, 0 }, -@@ -2022,6 +2025,9 @@ void server_options(char **args, int *argc_p) +@@ -2048,6 +2051,9 @@ void server_options(char **args, int *argc_p) else if (remove_source_files) args[ac++] = "--remove-sent-files"; @@ -76,7 +76,7 @@ diff --git a/rsync.c b/rsync.c extern int am_root; extern int am_server; extern int am_sender; -@@ -291,7 +292,8 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr, +@@ -326,7 +327,8 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr, if (iflags & ITEM_TRANSFER) { int i = ndx - cur_flist->ndx_start; diff --git a/crtimes.diff b/crtimes.diff index 5a989c8..06f6f58 100644 --- a/crtimes.diff +++ b/crtimes.diff @@ -48,7 +48,7 @@ diff --git a/flist.c b/flist.c extern int relative_paths; extern int implied_dirs; extern int file_extra_cnt; -@@ -345,7 +346,7 @@ int push_pathname(const char *dir, int len) +@@ -380,7 +381,7 @@ int push_pathname(const char *dir, int len) static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ndx) { @@ -57,7 +57,7 @@ diff --git a/flist.c b/flist.c static mode_t mode; #ifdef SUPPORT_FILEFLAGS static uint32 fileflags; -@@ -464,6 +465,13 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ +@@ -499,6 +500,13 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ xflags |= XMIT_SAME_TIME; else modtime = file->modtime; @@ -71,7 +71,7 @@ diff --git a/flist.c b/flist.c #ifdef SUPPORT_HARD_LINKS if (tmp_dev != 0) { -@@ -534,6 +542,8 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ +@@ -569,6 +577,8 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ else write_int(f, modtime); } @@ -80,7 +80,7 @@ diff --git a/flist.c b/flist.c if (!(xflags & XMIT_SAME_MODE)) write_int(f, to_wire_mode(mode)); #ifdef SUPPORT_FILEFLAGS -@@ -626,7 +636,7 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ +@@ -661,7 +671,7 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ static struct file_struct *recv_file_entry(struct file_list *flist, int xflags, int f) { @@ -89,7 +89,7 @@ diff --git a/flist.c b/flist.c static mode_t mode; #ifdef SUPPORT_FILEFLAGS static uint32 fileflags; -@@ -760,6 +770,19 @@ static struct file_struct *recv_file_entry(struct file_list *flist, +@@ -795,6 +805,19 @@ static struct file_struct *recv_file_entry(struct file_list *flist, } else modtime = read_int(f); } @@ -109,7 +109,7 @@ diff --git a/flist.c b/flist.c if (!(xflags & XMIT_SAME_MODE)) mode = from_wire_mode(read_int(f)); -@@ -900,6 +923,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist, +@@ -934,6 +957,8 @@ static struct file_struct *recv_file_entry(struct file_list *flist, F_GROUP(file) = gid; file->flags |= gid_flags; } @@ -118,7 +118,7 @@ diff --git a/flist.c b/flist.c if (unsort_ndx) F_NDX(file) = flist->used + flist->ndx_start; -@@ -1236,6 +1261,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, +@@ -1275,6 +1300,8 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, F_OWNER(file) = st.st_uid; if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */ F_GROUP(file) = st.st_gid; @@ -138,7 +138,7 @@ diff --git a/generator.c b/generator.c extern int verbose; extern int dry_run; -@@ -41,6 +42,7 @@ extern int preserve_xattrs; +@@ -40,6 +41,7 @@ extern int preserve_xattrs; extern int preserve_links; extern int preserve_devices; extern int preserve_specials; @@ -146,7 +146,7 @@ diff --git a/generator.c b/generator.c extern int preserve_hard_links; extern int preserve_executability; extern int preserve_fileflags; -@@ -612,6 +614,13 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) +@@ -617,6 +619,13 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file)) return 0; @@ -160,9 +160,9 @@ diff --git a/generator.c b/generator.c #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { if (!ACL_READY(*sxp)) -@@ -651,6 +660,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre +@@ -660,6 +669,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre + : iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED) && (!(iflags & ITEM_XNAME_FOLLOWS) || *xname)) - || (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0)) iflags |= ITEM_REPORT_TIME; + if (crtimes_ndx) { + if (sxp->crtime == 0) @@ -173,7 +173,7 @@ diff --git a/generator.c b/generator.c #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST if (S_ISLNK(file->mode)) { ; -@@ -1196,6 +1211,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx, +@@ -1207,6 +1222,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]; @@ -181,7 +181,7 @@ diff --git a/generator.c b/generator.c double len; if (!F_IS_ACTIVE(f)) { -@@ -1210,14 +1226,16 @@ static void list_file_entry(struct file_struct *f) +@@ -1221,14 +1237,16 @@ static void list_file_entry(struct file_struct *f) #ifdef SUPPORT_LINKS if (preserve_links && S_ISLNK(f->mode)) { @@ -200,19 +200,19 @@ diff --git a/generator.c b/generator.c f_name(f, NULL)); } } -@@ -1304,6 +1322,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1320,6 +1338,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, return; } } + sx.crtime = 0; + #ifdef SUPPORT_ACLS sx.acc_acl = sx.def_acl = NULL; - #endif diff --git a/ifuncs.h b/ifuncs.h --- a/ifuncs.h +++ b/ifuncs.h -@@ -57,6 +57,28 @@ from_wire_mode(int mode) - return mode; +@@ -67,6 +67,28 @@ d_name(struct dirent *di) + #endif } +static inline time_t @@ -243,7 +243,7 @@ diff --git a/ifuncs.h b/ifuncs.h diff --git a/log.c b/log.c --- a/log.c +++ b/log.c -@@ -647,7 +647,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op, +@@ -653,7 +653,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'; @@ -256,7 +256,7 @@ diff --git a/log.c b/log.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -59,6 +59,7 @@ int preserve_specials = 0; +@@ -60,6 +60,7 @@ int preserve_specials = 0; int preserve_uid = 0; int preserve_gid = 0; int preserve_times = 0; @@ -264,7 +264,7 @@ diff --git a/options.c b/options.c int update_only = 0; int cvs_exclude = 0; int dry_run = 0; -@@ -361,6 +362,7 @@ void usage(enum logcode F) +@@ -362,6 +363,7 @@ void usage(enum logcode F) rprintf(F," -D same as --devices --specials\n"); rprintf(F," -t, --times preserve modification times\n"); rprintf(F," -O, --omit-dir-times omit directories from --times\n"); @@ -272,7 +272,7 @@ diff --git a/options.c b/options.c rprintf(F," --super receiver attempts super-user activities\n"); #ifdef SUPPORT_XATTRS rprintf(F," --fake-super store/recover privileged attrs using xattrs\n"); -@@ -505,6 +507,9 @@ static struct poptOption long_options[] = { +@@ -508,6 +510,9 @@ static struct poptOption long_options[] = { {"times", 't', POPT_ARG_VAL, &preserve_times, 2, 0, 0 }, {"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 }, {"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 }, @@ -282,7 +282,7 @@ diff --git a/options.c b/options.c {"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 }, {"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 }, {"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 }, -@@ -1772,6 +1777,8 @@ void server_options(char **args, int *argc_p) +@@ -1799,6 +1804,8 @@ void server_options(char **args, int *argc_p) argstr[x++] = 'D'; if (preserve_times) argstr[x++] = 't'; @@ -294,8 +294,8 @@ diff --git a/options.c b/options.c diff --git a/rsync.c b/rsync.c --- a/rsync.c +++ b/rsync.c -@@ -437,6 +437,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, - else if (receiver_symlink_times) +@@ -472,6 +472,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, + else file->flags |= FLAG_TIME_FAILED; } + if (crtimes_ndx && !(flags & ATTRS_SKIP_CRTIME)) { @@ -309,7 +309,7 @@ diff --git a/rsync.c b/rsync.c change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file); change_gid = gid_ndx && !(file->flags & FLAG_SKIP_GROUP) -@@ -580,7 +588,7 @@ int finish_transfer(const char *fname, const char *fnametmp, +@@ -615,7 +623,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, ATTRS_DELAY_IMMUTABLE @@ -318,7 +318,7 @@ diff --git a/rsync.c b/rsync.c /* move tmp file over real file */ if (verbose > 2) -@@ -611,7 +619,7 @@ int finish_transfer(const char *fname, const char *fnametmp, +@@ -646,7 +654,7 @@ int finish_transfer(const char *fname, const char *fnametmp, do_set_file_attrs: set_file_attrs(fnametmp, file, NULL, fnamecmp, @@ -338,7 +338,7 @@ diff --git a/rsync.h b/rsync.h #define XMIT_SAME_FLAGS (1<<14) /* protocols ?? - now */ /* These flags are used in the live flist data. */ -@@ -151,6 +152,7 @@ +@@ -153,6 +154,7 @@ #define ATTRS_REPORT (1<<0) #define ATTRS_SKIP_MTIME (1<<1) #define ATTRS_DELAY_IMMUTABLE (1<<2) @@ -346,16 +346,16 @@ diff --git a/rsync.h b/rsync.h #define FULL_FLUSH 1 #define NORMAL_FLUSH 0 -@@ -167,7 +169,7 @@ +@@ -169,7 +171,7 @@ #define FNAMECMP_FUZZY 0x83 /* For use by the itemize_changes code */ -#define ITEM_REPORT_ATIME (1<<0) +#define ITEM_REPORT_CRTIME (1<<0) - #define ITEM_REPORT_CHECKSUM (1<<1) - #define ITEM_REPORT_SIZE (1<<2) - #define ITEM_REPORT_TIME (1<<3) -@@ -645,6 +647,7 @@ extern int file_extra_cnt; + #define ITEM_REPORT_CHANGE (1<<1) + #define ITEM_REPORT_SIZE (1<<2) /* regular files only */ + #define ITEM_REPORT_TIMEFAIL (1<<2) /* symlinks only */ +@@ -647,6 +649,7 @@ extern int file_extra_cnt; extern int inc_recurse; extern int uid_ndx; extern int gid_ndx; @@ -363,7 +363,7 @@ diff --git a/rsync.h b/rsync.h extern int fileflags_ndx; extern int acls_ndx; extern int xattrs_ndx; -@@ -652,6 +655,7 @@ extern int xattrs_ndx; +@@ -654,6 +657,7 @@ extern int xattrs_ndx; #define FILE_STRUCT_LEN (offsetof(struct file_struct, basename)) #define EXTRA_LEN (sizeof (union file_extras)) #define PTR_EXTRA_CNT ((sizeof (char *) + EXTRA_LEN - 1) / EXTRA_LEN) @@ -371,7 +371,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) -@@ -910,6 +914,7 @@ typedef struct { +@@ -912,6 +916,7 @@ typedef struct { typedef struct { STRUCT_STAT st; @@ -390,7 +390,7 @@ diff --git a/rsync.yo b/rsync.yo --super receiver attempts super-user activities --fake-super store/recover privileged attrs using xattrs -S, --sparse handle sparse files efficiently -@@ -1015,6 +1016,9 @@ it is preserving modification times (see bf(--times)). If NFS is sharing +@@ -1022,6 +1023,9 @@ it is preserving modification times (see bf(--times)). If NFS is sharing the directories on the receiving side, it is a good idea to use bf(-O). This option is inferred if you use bf(--backup) without bf(--backup-dir). @@ -400,7 +400,7 @@ diff --git a/rsync.yo b/rsync.yo dit(bf(--super)) This tells the receiving side to attempt super-user activities even if the receiving rsync wasn't run by the super-user. These activities include: preserving users via the bf(--owner) option, preserving -@@ -1667,7 +1671,7 @@ with older versions of rsync, but that also turns on the output of other +@@ -1674,7 +1678,7 @@ with older versions of rsync, but that also turns on the output of other verbose messages). The "%i" escape has a cryptic output that is 11 letters long. The general @@ -409,7 +409,7 @@ diff --git a/rsync.yo b/rsync.yo type of update being done, bf(X) is replaced by the file-type, and the other letters represent attributes that may be output if they are being modified. -@@ -1721,6 +1725,8 @@ quote(itemization( +@@ -1733,6 +1737,8 @@ quote(itemization( it() The bf(f) means that the fileflags information changed. it() The bf(a) means that the ACL information changed. it() The bf(x) means that the extended attribute information changed. @@ -433,8 +433,8 @@ diff --git a/syscall.c b/syscall.c #define RETURN_ERROR_IF(x,e) \ do { \ if (x) { \ -@@ -403,3 +408,33 @@ char *d_name(struct dirent *di) - return di->d_name; +@@ -394,3 +399,33 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence) + return lseek(fd, offset, whence); #endif } + diff --git a/cvs-entries.diff b/cvs-entries.diff index b022296..6791054 100644 --- a/cvs-entries.diff +++ b/cvs-entries.diff @@ -11,7 +11,7 @@ To use this patch, run these commands for a successful build: diff --git a/exclude.c b/exclude.c --- a/exclude.c +++ b/exclude.c -@@ -213,6 +213,8 @@ static void add_rule(struct filter_list_struct *listp, const char *pat, +@@ -239,6 +239,8 @@ static void add_rule(struct filter_list_struct *listp, const char *pat, if (!(lp = new_array(struct filter_list_struct, 1))) out_of_memory("add_rule"); lp->head = lp->tail = NULL; @@ -20,7 +20,7 @@ diff --git a/exclude.c b/exclude.c if (asprintf(&lp->debug_type, " [per-dir %s]", cp) < 0) out_of_memory("add_rule"); ret->u.mergelist = lp; -@@ -445,6 +447,14 @@ void *push_local_filters(const char *dir, unsigned int dirlen) +@@ -469,6 +471,14 @@ void *push_local_filters(const char *dir, unsigned int dirlen) set_filter_dir(dir, dirlen); } @@ -35,7 +35,7 @@ diff --git a/exclude.c b/exclude.c if (strlcpy(dirbuf + dirbuf_len, ex->pattern, MAXPATHLEN - dirbuf_len) < MAXPATHLEN - dirbuf_len) { parse_filter_file(lp, dirbuf, ex->match_flags, -@@ -1004,6 +1014,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname, +@@ -1029,6 +1039,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname, char line[BIGPATHBUFLEN]; char *eob = line + sizeof line - 1; int word_split = mflags & MATCHFLG_WORD_SPLIT; @@ -43,7 +43,7 @@ diff --git a/exclude.c b/exclude.c if (!fname || !*fname) return; -@@ -1050,6 +1061,24 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname, +@@ -1075,6 +1086,24 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname, } break; } @@ -68,7 +68,7 @@ diff --git a/exclude.c b/exclude.c if (word_split && isspace(ch)) break; if (eol_nulls? !ch : (ch == '\n' || ch == '\r')) -@@ -1059,13 +1088,15 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname, +@@ -1084,13 +1113,15 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname, else overflow = 1; } @@ -88,11 +88,11 @@ diff --git a/exclude.c b/exclude.c diff --git a/rsync.h b/rsync.h --- a/rsync.h +++ b/rsync.h -@@ -146,6 +146,7 @@ - #define XFLG_OLD_PREFIXES (1<<1) - #define XFLG_ANCHORED2ABS (1<<2) - #define XFLG_ABS_IF_SLASH (1<<3) -+#define XFLG_CVS_ENTRIES (1<<4) +@@ -148,6 +148,7 @@ + #define XFLG_ANCHORED2ABS (1<<2) /* leading slash indicates absolute */ + #define XFLG_ABS_IF_SLASH (1<<3) /* leading or interior slash is absolute */ + #define XFLG_DIR2WILD3 (1<<4) /* dir/ match gets trailing *** added */ ++#define XFLG_CVS_ENTRIES (1<<5) #define ATTRS_REPORT (1<<0) #define ATTRS_SKIP_MTIME (1<<1) diff --git a/date-only.diff b/date-only.diff index f9dcb98..a63f60d 100644 --- a/date-only.diff +++ b/date-only.diff @@ -17,7 +17,7 @@ To use this patch, run these commands for a successful build: diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -63,6 +63,7 @@ extern int append_mode; +@@ -62,6 +62,7 @@ extern int append_mode; extern int make_backups; extern int csum_length; extern int ignore_times; @@ -25,7 +25,7 @@ diff --git a/generator.c b/generator.c extern int size_only; extern OFF_T max_size; extern OFF_T min_size; -@@ -696,6 +697,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre +@@ -708,6 +709,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) { @@ -38,7 +38,7 @@ diff --git a/generator.c b/generator.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -105,6 +105,7 @@ int keep_partial = 0; +@@ -106,6 +106,7 @@ int keep_partial = 0; int safe_symlinks = 0; int copy_unsafe_links = 0; int size_only = 0; @@ -46,7 +46,7 @@ diff --git a/options.c b/options.c int daemon_bwlimit = 0; int bwlimit = 0; int fuzzy_basis = 0; -@@ -387,6 +388,7 @@ void usage(enum logcode F) +@@ -388,6 +389,7 @@ void usage(enum logcode F) rprintf(F," --contimeout=SECONDS set daemon connection timeout in seconds\n"); rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n"); rprintf(F," --size-only skip files that match in size\n"); @@ -54,7 +54,7 @@ diff --git a/options.c b/options.c rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n"); rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n"); rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n"); -@@ -527,6 +529,7 @@ static struct poptOption long_options[] = { +@@ -530,6 +532,7 @@ static struct poptOption long_options[] = { {"chmod", 0, POPT_ARG_STRING, 0, OPT_CHMOD, 0, 0 }, {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 }, {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 }, @@ -62,7 +62,7 @@ diff --git a/options.c b/options.c {"one-file-system", 'x', POPT_ARG_NONE, 0, 'x', 0, 0 }, {"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, {"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, -@@ -1927,6 +1930,9 @@ void server_options(char **args, int *argc_p) +@@ -1953,6 +1956,9 @@ void server_options(char **args, int *argc_p) } } diff --git a/detect-renamed-lax.diff b/detect-renamed-lax.diff index 7be49e2..6eab0df 100644 --- a/detect-renamed-lax.diff +++ b/detect-renamed-lax.diff @@ -23,7 +23,7 @@ switches to --detect-moved blindly accepts the staged file. diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -196,7 +196,9 @@ static int fattr_find(struct file_struct *f, char *fname) +@@ -200,7 +200,9 @@ static int fattr_find(struct file_struct *f, char *fname) continue; } } @@ -34,7 +34,7 @@ diff --git a/generator.c b/generator.c diff = u_strcmp(fmid->basename, f->basename); if (diff == 0) { good_match = mid; -@@ -1927,6 +1929,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1961,6 +1963,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, fnamecmp = partialptr; fnamecmp_type = FNAMECMP_PARTIAL_DIR; statret = 0; @@ -59,7 +59,7 @@ diff --git a/generator.c b/generator.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -392,6 +392,8 @@ void usage(enum logcode F) +@@ -393,6 +393,8 @@ void usage(enum logcode F) rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n"); rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n"); rprintf(F," --detect-renamed try to find renamed files to speed up the transfer\n"); @@ -68,7 +68,7 @@ diff --git a/options.c b/options.c rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n"); rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n"); rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n"); -@@ -572,7 +574,9 @@ static struct poptOption long_options[] = { +@@ -580,7 +582,9 @@ static struct poptOption long_options[] = { {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 }, {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 }, {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 }, @@ -76,10 +76,10 @@ diff --git a/options.c b/options.c + {"detect-renamed", 0, POPT_ARG_VAL, &detect_renamed, 1, 0, 0 }, + {"detect-renamed-lax",0, POPT_ARG_VAL, &detect_renamed, 2, 0, 0 }, + {"detect-moved", 0, POPT_ARG_VAL, &detect_renamed, 3, 0, 0 }, - {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 }, - {"compress", 'z', POPT_ARG_NONE, 0, 'z', 0, 0 }, - {"no-compress", 0, POPT_ARG_VAL, &do_compression, 0, 0, 0 }, -@@ -1923,8 +1927,14 @@ void server_options(char **args, int *argc_p) + {"fuzzy", 'y', POPT_ARG_VAL, &fuzzy_basis, 1, 0, 0 }, + {"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 }, + {"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 }, +@@ -1949,8 +1953,14 @@ void server_options(char **args, int *argc_p) args[ac++] = "--super"; if (size_only) args[ac++] = "--size-only"; @@ -108,7 +108,7 @@ diff --git a/rsync.yo b/rsync.yo --compare-dest=DIR also compare received files relative to DIR --copy-dest=DIR ... and include copies of unchanged files --link-dest=DIR hardlink to files in DIR when unchanged -@@ -1483,6 +1485,17 @@ the bf(--partial-dir) option, that directory will be used instead. These +@@ -1490,6 +1492,17 @@ the bf(--partial-dir) option, that directory will be used instead. These potential alternate-basis files will be removed as the transfer progresses. This option conflicts with bf(--inplace) and bf(--append). diff --git a/detect-renamed.diff b/detect-renamed.diff index 1243447..4a47233 100644 --- a/detect-renamed.diff +++ b/detect-renamed.diff @@ -71,7 +71,7 @@ diff --git a/flist.c b/flist.c static char empty_sum[MAX_DIGEST_LEN]; static int flist_count_offset; /* for --delete --progress */ static int dir_count = 0; -@@ -263,6 +266,45 @@ static int is_excluded(char *fname, int is_dir, int filter_level) +@@ -298,6 +301,45 @@ static int is_excluded(const char *fname, int is_dir, int filter_level) return 0; } @@ -117,7 +117,7 @@ diff --git a/flist.c b/flist.c static void send_directory(int f, struct file_list *flist, char *fbuf, int len, int flags); -@@ -2180,6 +2222,25 @@ struct file_list *recv_file_list(int f) +@@ -2235,6 +2277,25 @@ struct file_list *recv_file_list(int f) flist_sort_and_clean(flist, relative_paths); @@ -146,7 +146,7 @@ diff --git a/flist.c b/flist.c diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -81,6 +81,7 @@ extern char *basis_dir[]; +@@ -80,6 +80,7 @@ extern char *basis_dir[]; extern int compare_dest; extern int copy_dest; extern int link_dest; @@ -154,15 +154,15 @@ diff --git a/generator.c b/generator.c extern int whole_file; extern int list_only; extern int read_batch; -@@ -99,6 +100,7 @@ extern char *backup_suffix; +@@ -98,6 +99,7 @@ extern char *backup_suffix; extern int backup_suffix_len; extern struct file_list *cur_flist, *first_flist, *dir_flist; - extern struct filter_list_struct server_filter_list; + extern struct filter_list_struct daemon_filter_list; +extern struct file_list the_fattr_list; int ignore_perishable = 0; int non_perishable_cnt = 0; -@@ -106,6 +108,7 @@ int maybe_ATTRS_REPORT = 0; +@@ -105,6 +107,7 @@ int maybe_ATTRS_REPORT = 0; static dev_t dev_zero; static int deletion_count = 0; /* used to implement --max-delete */ @@ -187,7 +187,7 @@ diff --git a/generator.c b/generator.c #define DEL_MAKE_ROOM (DEL_FOR_FILE|DEL_FOR_DIR|DEL_FOR_SYMLINK|DEL_FOR_DEVICE|DEL_FOR_SPECIAL) -@@ -144,11 +148,121 @@ static int is_backup_file(char *fn) +@@ -148,11 +152,121 @@ static int is_backup_file(char *fn) return k > 0 && strcmp(fn+k, backup_suffix) == 0; } @@ -309,7 +309,7 @@ diff --git a/generator.c b/generator.c */ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) { -@@ -182,6 +296,8 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) +@@ -186,6 +300,8 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) goto check_ret; /* OK: try to delete the directory. */ } @@ -318,7 +318,7 @@ diff --git a/generator.c b/generator.c if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && ++deletion_count > max_delete) return DR_AT_LIMIT; -@@ -237,6 +353,8 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) +@@ -241,6 +357,8 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) * its contents, otherwise just checks for content. Returns DR_SUCCESS or * DR_NOT_EMPTY. Note that fname must point to a MAXPATHLEN buffer! (The * buffer is used for recursion, but returned unchanged.) @@ -327,7 +327,7 @@ diff --git a/generator.c b/generator.c */ static enum delret delete_dir_contents(char *fname, uint16 flags) { -@@ -256,7 +374,9 @@ static enum delret delete_dir_contents(char *fname, uint16 flags) +@@ -260,7 +378,9 @@ static enum delret delete_dir_contents(char *fname, uint16 flags) save_filters = push_local_filters(fname, dlen); non_perishable_cnt = 0; @@ -337,7 +337,7 @@ diff --git a/generator.c b/generator.c ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS; if (!dirlist->used) -@@ -296,7 +416,8 @@ static enum delret delete_dir_contents(char *fname, uint16 flags) +@@ -300,7 +420,8 @@ static enum delret delete_dir_contents(char *fname, uint16 flags) if (S_ISDIR(fp->mode)) { if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS) ret = DR_NOT_EMPTY; @@ -347,7 +347,7 @@ diff --git a/generator.c b/generator.c if (delete_item(fname, fp->mode, flags) != DR_SUCCESS) ret = DR_NOT_EMPTY; } -@@ -461,13 +582,18 @@ static void do_delayed_deletions(char *delbuf) +@@ -465,13 +586,18 @@ static void do_delayed_deletions(char *delbuf) * all the --delete-WHEN options. Note that the fbuf pointer must point to a * MAXPATHLEN buffer with the name of the directory in it (the functions we * call will append names onto the end, but the old dir value will be restored @@ -370,7 +370,7 @@ diff --git a/generator.c b/generator.c int save_uid_ndx = uid_ndx; if (!fbuf) { -@@ -482,17 +608,22 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) +@@ -486,17 +612,22 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) maybe_send_keepalive(); if (io_error && !ignore_errors) { @@ -398,7 +398,7 @@ diff --git a/generator.c b/generator.c if (one_file_system) { if (file->flags & FLAG_TOP_DIR) filesystem_dev = *fs_dev; -@@ -505,6 +636,14 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) +@@ -509,6 +640,14 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) dirlist = get_dirlist(fbuf, dlen, 0); @@ -413,7 +413,7 @@ diff --git a/generator.c b/generator.c /* If an item in dirlist is not found in flist, delete it * from the filesystem. */ for (i = dirlist->used; i--; ) { -@@ -517,19 +656,28 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) +@@ -521,19 +660,28 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) f_name(fp, NULL)); continue; } @@ -446,7 +446,7 @@ diff --git a/generator.c b/generator.c flist_free(dirlist); if (!save_uid_ndx) { -@@ -564,9 +712,9 @@ static void do_delete_pass(void) +@@ -568,9 +716,9 @@ static void do_delete_pass(void) || !S_ISDIR(st.st_mode)) continue; @@ -458,7 +458,7 @@ diff --git a/generator.c b/generator.c if (do_progress && !am_server) rprintf(FINFO, " \r"); -@@ -1199,6 +1347,7 @@ static void list_file_entry(struct file_struct *f) +@@ -1210,6 +1358,7 @@ static void list_file_entry(struct file_struct *f) } } @@ -466,13 +466,13 @@ diff --git a/generator.c b/generator.c static int phase = 0; static int dflt_perms; -@@ -1449,8 +1598,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1480,8 +1629,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } } - else if (delete_during && f_out != -1 && !phase && dry_run < 2 -- && (file->flags & FLAG_CONTENT_DIR)) + else if (delete_during && f_out != -1 && !phase +- && BITS_SETnUNSET(file->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR)) - delete_in_dir(fname, file, &real_sx.st.st_dev); -+ && (file->flags & FLAG_CONTENT_DIR)) { ++ && BITS_SETnUNSET(file->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR)) { + if (detect_renamed && real_ret != 0) + unexplored_dirs++; + delete_in_dir(fname, file, &real_sx.st.st_dev, @@ -481,7 +481,7 @@ diff --git a/generator.c b/generator.c goto cleanup; } -@@ -1728,8 +1881,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1757,8 +1910,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } #endif @@ -497,7 +497,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; -@@ -2072,6 +2231,12 @@ void generate_files(int f_out, const char *local_name) +@@ -2135,6 +2294,12 @@ void generate_files(int f_out, const char *local_name) if (verbose > 2) rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid()); @@ -510,7 +510,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) { -@@ -2082,7 +2247,7 @@ void generate_files(int f_out, const char *local_name) +@@ -2145,7 +2310,7 @@ void generate_files(int f_out, const char *local_name) } do_progress = 0; @@ -519,7 +519,7 @@ diff --git a/generator.c b/generator.c whole_file = 0; if (verbose >= 2) { rprintf(FINFO, "delta-transmission %s\n", -@@ -2120,7 +2285,7 @@ void generate_files(int f_out, const char *local_name) +@@ -2183,7 +2348,7 @@ void generate_files(int f_out, const char *local_name) dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); } else dirdev = MAKEDEV(0, 0); @@ -528,7 +528,7 @@ diff --git a/generator.c b/generator.c } } } -@@ -2163,7 +2328,21 @@ void generate_files(int f_out, const char *local_name) +@@ -2226,7 +2391,21 @@ void generate_files(int f_out, const char *local_name) } while ((cur_flist = cur_flist->next) != NULL); if (delete_during) @@ -554,7 +554,7 @@ diff --git a/generator.c b/generator.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -81,6 +81,7 @@ int am_generator = 0; +@@ -82,6 +82,7 @@ int am_generator = 0; int am_starting_up = 1; int relative_paths = -1; int implied_dirs = 1; @@ -562,7 +562,7 @@ diff --git a/options.c b/options.c int numeric_ids = 0; int allow_8bit_chars = 0; int force_delete = 0; -@@ -390,6 +391,7 @@ void usage(enum logcode F) +@@ -391,6 +392,7 @@ void usage(enum logcode F) rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n"); rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n"); rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n"); @@ -570,15 +570,15 @@ diff --git a/options.c b/options.c rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n"); rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n"); rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n"); -@@ -570,6 +572,7 @@ static struct poptOption long_options[] = { +@@ -578,6 +580,7 @@ static struct poptOption long_options[] = { {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 }, {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 }, {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 }, + {"detect-renamed", 0, POPT_ARG_NONE, &detect_renamed, 0, 0, 0 }, - {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 }, - {"compress", 'z', POPT_ARG_NONE, 0, 'z', 0, 0 }, - {"no-compress", 0, POPT_ARG_VAL, &do_compression, 0, 0, 0 }, -@@ -1564,7 +1567,7 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) + {"fuzzy", 'y', POPT_ARG_VAL, &fuzzy_basis, 1, 0, 0 }, + {"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 }, + {"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 }, +@@ -1590,7 +1593,7 @@ int parse_arguments(int *argc_p, const char ***argv_p) inplace = 1; } @@ -587,7 +587,7 @@ diff --git a/options.c b/options.c partial_dir = tmp_partialdir; if (inplace) { -@@ -1573,6 +1576,7 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1599,6 +1602,7 @@ int parse_arguments(int *argc_p, const char ***argv_p) snprintf(err_buf, sizeof err_buf, "--%s cannot be used with --%s\n", append_mode ? "append" : "inplace", @@ -595,7 +595,7 @@ diff --git a/options.c b/options.c delay_updates ? "delay-updates" : "partial-dir"); return 0; } -@@ -1919,6 +1923,8 @@ void server_options(char **args, int *argc_p) +@@ -1945,6 +1949,8 @@ void server_options(char **args, int *argc_p) args[ac++] = "--super"; if (size_only) args[ac++] = "--size-only"; @@ -615,7 +615,7 @@ diff --git a/rsync.yo b/rsync.yo --compare-dest=DIR also compare received files relative to DIR --copy-dest=DIR ... and include copies of unchanged files --link-dest=DIR hardlink to files in DIR when unchanged -@@ -1467,6 +1468,21 @@ Note that the use of the bf(--delete) option might get rid of any potential +@@ -1474,6 +1475,21 @@ Note that the use of the bf(--delete) option might get rid of any potential fuzzy-match files, so either use bf(--delete-after) or specify some filename exclusions if you need to prevent this. @@ -640,7 +640,7 @@ diff --git a/rsync.yo b/rsync.yo diff --git a/util.c b/util.c --- a/util.c +++ b/util.c -@@ -1022,6 +1022,32 @@ int handle_partial_dir(const char *fname, int create) +@@ -1112,6 +1112,32 @@ int handle_partial_dir(const char *fname, int create) return 1; } diff --git a/downdate.diff b/downdate.diff index 36683c0..e40213b 100644 --- a/downdate.diff +++ b/downdate.diff @@ -10,7 +10,7 @@ To use this patch, run these commands for a successful build: diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -56,6 +56,7 @@ extern int ignore_errors; +@@ -55,6 +55,7 @@ extern int ignore_errors; extern int remove_source_files; extern int delay_updates; extern int update_only; @@ -18,7 +18,7 @@ diff --git a/generator.c b/generator.c extern int ignore_existing; extern int ignore_non_existing; extern int inplace; -@@ -1669,6 +1670,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1698,6 +1699,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; } @@ -32,7 +32,7 @@ diff --git a/generator.c b/generator.c fnamecmp = fname; fnamecmp_type = FNAMECMP_FNAME; -@@ -1985,6 +1993,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) +@@ -2045,6 +2053,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; @@ -40,7 +40,7 @@ diff --git a/generator.c b/generator.c always_checksum = -always_checksum; size_only = -size_only; append_mode = -append_mode; -@@ -2010,6 +2019,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) +@@ -2070,6 +2079,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; @@ -51,7 +51,7 @@ diff --git a/generator.c b/generator.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -59,6 +59,7 @@ int preserve_uid = 0; +@@ -60,6 +60,7 @@ int preserve_uid = 0; int preserve_gid = 0; int preserve_times = 0; int update_only = 0; @@ -59,7 +59,7 @@ diff --git a/options.c b/options.c int cvs_exclude = 0; int dry_run = 0; int do_xfers = 1; -@@ -325,6 +326,7 @@ void usage(enum logcode F) +@@ -326,6 +327,7 @@ void usage(enum logcode F) rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n"); rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX); rprintf(F," -u, --update skip files that are newer on the receiver\n"); @@ -67,7 +67,7 @@ diff --git a/options.c b/options.c rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n"); rprintf(F," --append append data onto shorter files\n"); rprintf(F," --append-verify like --append, but with old data in file checksum\n"); -@@ -531,6 +533,7 @@ static struct poptOption long_options[] = { +@@ -534,6 +536,7 @@ static struct poptOption long_options[] = { {"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, {"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 }, diff --git a/drop-cache.diff b/drop-cache.diff index aca5d63..79177e7 100644 --- a/drop-cache.diff +++ b/drop-cache.diff @@ -97,7 +97,7 @@ diff --git a/cleanup.c b/cleanup.c diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in -@@ -552,7 +552,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \ +@@ -554,7 +554,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \ strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \ setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \ strerror putenv iconv_open locale_charset nl_langinfo getxattr \ @@ -139,7 +139,7 @@ diff --git a/generator.c b/generator.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -59,6 +59,7 @@ int preserve_uid = 0; +@@ -60,6 +60,7 @@ int preserve_uid = 0; int preserve_gid = 0; int preserve_times = 0; int update_only = 0; @@ -147,7 +147,7 @@ diff --git a/options.c b/options.c int cvs_exclude = 0; int dry_run = 0; int do_xfers = 1; -@@ -325,6 +326,9 @@ void usage(enum logcode F) +@@ -326,6 +327,9 @@ void usage(enum logcode F) rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n"); rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX); rprintf(F," -u, --update skip files that are newer on the receiver\n"); @@ -157,7 +157,7 @@ diff --git a/options.c b/options.c rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n"); rprintf(F," --append append data onto shorter files\n"); rprintf(F," --append-verify like --append, but with old data in file checksum\n"); -@@ -531,6 +535,9 @@ static struct poptOption long_options[] = { +@@ -534,6 +538,9 @@ static struct poptOption long_options[] = { {"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, {"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 }, @@ -167,7 +167,7 @@ diff --git a/options.c b/options.c {"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 }, {"ignore-non-existing",0,POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 }, {"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 }, -@@ -1693,6 +1700,11 @@ void server_options(char **args, int *argc_p) +@@ -1719,6 +1726,11 @@ void server_options(char **args, int *argc_p) if (!am_sender) args[ac++] = "--sender"; @@ -204,7 +204,7 @@ diff --git a/rsync.yo b/rsync.yo -n, --dry-run perform a trial run with no changes made -W, --whole-file copy files whole (w/o delta-xfer algorithm) -x, --one-file-system don't cross filesystem boundaries -@@ -1036,6 +1037,10 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs" +@@ -1043,6 +1044,10 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs" filesystem. It doesn't seem to handle seeks over null regions correctly and ends up corrupting the files. diff --git a/fileflags.diff b/fileflags.diff index eead498..1617794 100644 --- a/fileflags.diff +++ b/fileflags.diff @@ -20,7 +20,7 @@ diff --git a/Makefile.in b/Makefile.in # Programs we must have to run the test cases CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \ -@@ -105,7 +105,7 @@ getgroups$(EXEEXT): getgroups.o +@@ -107,7 +107,7 @@ getgroups$(EXEEXT): getgroups.o getfsdev$(EXEEXT): getfsdev.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ getfsdev.o $(LIBS) @@ -65,8 +65,8 @@ diff --git a/compat.c b/compat.c diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in -@@ -551,7 +551,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \ - memmove lchown vsnprintf snprintf vasprintf asprintf setsid glob strpbrk \ +@@ -553,7 +553,7 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \ + memmove lchown vsnprintf snprintf vasprintf asprintf setsid strpbrk \ strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \ setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \ - strerror putenv iconv_open locale_charset nl_langinfo getxattr \ @@ -85,7 +85,7 @@ diff --git a/flist.c b/flist.c extern int uid_ndx; extern int gid_ndx; extern int eol_nulls; -@@ -346,6 +347,9 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ +@@ -381,6 +382,9 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ { static time_t modtime; static mode_t mode; @@ -95,7 +95,7 @@ diff --git a/flist.c b/flist.c #ifdef SUPPORT_HARD_LINKS static int64 dev; #endif -@@ -405,6 +409,14 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ +@@ -440,6 +444,14 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ xflags |= XMIT_SAME_MODE; else mode = file->mode; @@ -110,7 +110,7 @@ diff --git a/flist.c b/flist.c if ((preserve_devices && IS_DEVICE(mode)) || (preserve_specials && IS_SPECIAL(mode))) { -@@ -524,6 +536,10 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ +@@ -559,6 +571,10 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ } if (!(xflags & XMIT_SAME_MODE)) write_int(f, to_wire_mode(mode)); @@ -121,7 +121,7 @@ diff --git a/flist.c b/flist.c if (preserve_uid && !(xflags & XMIT_SAME_UID)) { if (protocol_version < 30) write_int(f, uid); -@@ -612,6 +628,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist, +@@ -647,6 +663,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist, { static int64 modtime; static mode_t mode; @@ -131,7 +131,7 @@ diff --git a/flist.c b/flist.c #ifdef SUPPORT_HARD_LINKS static int64 dev; #endif -@@ -746,6 +765,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, +@@ -781,6 +800,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, if (chmod_modes && !S_ISLNK(mode)) mode = tweak_mode(mode, chmod_modes); @@ -142,7 +142,7 @@ diff --git a/flist.c b/flist.c if (preserve_uid && !(xflags & XMIT_SAME_UID)) { if (protocol_version < 30) -@@ -867,6 +890,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, +@@ -901,6 +924,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, OPT_EXTRA(file, 0)->unum = (uint32)(file_length >> 32); } file->mode = mode; @@ -153,7 +153,7 @@ diff --git a/flist.c b/flist.c if (preserve_uid) F_OWNER(file) = uid; if (preserve_gid) { -@@ -1201,6 +1228,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, +@@ -1240,6 +1267,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, OPT_EXTRA(file, 0)->unum = (uint32)(st.st_size >> 32); } file->mode = st.st_mode; @@ -167,7 +167,7 @@ diff --git a/flist.c b/flist.c diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -43,8 +43,10 @@ extern int preserve_devices; +@@ -42,8 +42,10 @@ extern int preserve_devices; extern int preserve_specials; extern int preserve_hard_links; extern int preserve_executability; @@ -178,7 +178,7 @@ diff --git a/generator.c b/generator.c extern int uid_ndx; extern int gid_ndx; extern int delete_mode; -@@ -162,7 +164,7 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) +@@ -166,7 +168,7 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) } if (flags & DEL_NO_UID_WRITE) @@ -187,7 +187,7 @@ diff --git a/generator.c b/generator.c if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) { int save_uid_ndx = uid_ndx; -@@ -170,6 +172,13 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) +@@ -174,6 +176,13 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) * delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */ if (!uid_ndx) uid_ndx = ++file_extra_cnt; @@ -201,7 +201,7 @@ diff --git a/generator.c b/generator.c ignore_perishable = 1; /* If DEL_RECURSE is not set, this just reports emptiness. */ ret = delete_dir_contents(fbuf, flags); -@@ -290,8 +299,12 @@ static enum delret delete_dir_contents(char *fname, uint16 flags) +@@ -294,8 +303,12 @@ static enum delret delete_dir_contents(char *fname, uint16 flags) } strlcpy(p, fp->basename, remainder); @@ -215,8 +215,8 @@ diff --git a/generator.c b/generator.c /* Save stack by recursing to ourself directly. */ if (S_ISDIR(fp->mode)) { if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS) -@@ -585,6 +598,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) - if (preserve_perms && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS)) +@@ -593,6 +606,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) + && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0))) return 0; +#ifdef SUPPORT_FILEFLAGS @@ -224,10 +224,10 @@ diff --git a/generator.c b/generator.c + return 0; +#endif + - if (preserve_executability && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0))) + if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file)) return 0; -@@ -646,6 +664,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre +@@ -658,6 +676,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file)) iflags |= ITEM_REPORT_GROUP; @@ -239,7 +239,7 @@ diff --git a/generator.c b/generator.c #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { if (!ACL_READY(*sxp)) -@@ -1391,6 +1414,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1423,6 +1446,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); } @@ -250,7 +250,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 +1454,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1458,10 +1485,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, /* We need to ensure that the dirs in the transfer have writable * permissions during the time we are putting files within them. * This is then fixed after the transfer is done. */ @@ -267,7 +267,7 @@ diff --git a/generator.c b/generator.c rsyserr(FERROR_XFER, errno, "failed to modify permissions on %s", full_fname(fname)); -@@ -1461,6 +1493,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1492,6 +1524,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); } @@ -278,15 +278,19 @@ diff --git a/generator.c b/generator.c #ifdef SUPPORT_HARD_LINKS if (preserve_hard_links && F_HLINK_NOT_FIRST(file) -@@ -1948,9 +1984,13 @@ static void touch_up_dirs(struct file_list *flist, int ndx) +@@ -2004,13 +2040,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx) continue; fname = f_name(file, NULL); if (!(file->mode & S_IWUSR)) - do_chmod(fname, file->mode); + do_chmod(fname, file->mode, 0); - if (need_retouch_dir_times) -- set_modtime(fname, file->modtime, file->mode); -+ set_modtime(fname, file->modtime, file->mode, 0); + if (need_retouch_dir_times) { + STRUCT_STAT st; + if (link_stat(fname, &st, 0) == 0 + && cmp_time(st.st_mtime, file->modtime) != 0) +- set_modtime(fname, file->modtime, file->mode); ++ set_modtime(fname, file->modtime, file->mode, 0); + } +#ifdef SUPPORT_FORCE_CHANGE + if (force_change && F_FFLAGS(file) & force_change) + undo_make_mutable(fname, F_FFLAGS(file)); @@ -297,7 +301,7 @@ diff --git a/generator.c b/generator.c diff --git a/log.c b/log.c --- a/log.c +++ b/log.c -@@ -644,7 +644,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op, +@@ -650,7 +650,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'; @@ -309,7 +313,7 @@ diff --git a/log.c b/log.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -52,6 +52,7 @@ int preserve_hard_links = 0; +@@ -53,6 +53,7 @@ int preserve_hard_links = 0; int preserve_acls = 0; int preserve_xattrs = 0; int preserve_perms = 0; @@ -317,7 +321,7 @@ diff --git a/options.c b/options.c int preserve_executability = 0; int preserve_devices = 0; int preserve_specials = 0; -@@ -84,6 +85,7 @@ int implied_dirs = 1; +@@ -85,6 +86,7 @@ int implied_dirs = 1; int numeric_ids = 0; int allow_8bit_chars = 0; int force_delete = 0; @@ -325,7 +329,7 @@ diff --git a/options.c b/options.c int io_timeout = 0; int allowed_lull = 0; int prune_empty_dirs = 0; -@@ -224,6 +226,7 @@ static void print_rsync_version(enum logcode f) +@@ -225,6 +227,7 @@ static void print_rsync_version(enum logcode f) char const *links = "no "; char const *iconv = "no "; char const *ipv6 = "no "; @@ -333,7 +337,7 @@ diff --git a/options.c b/options.c STRUCT_STAT *dumstat; #if SUBPROTOCOL_VERSION != 0 -@@ -256,6 +259,9 @@ static void print_rsync_version(enum logcode f) +@@ -257,6 +260,9 @@ static void print_rsync_version(enum logcode f) #if defined HAVE_LUTIMES && defined HAVE_UTIMES symtimes = ""; #endif @@ -343,7 +347,7 @@ diff --git a/options.c b/options.c rprintf(f, "%s version %s protocol version %d%s\n", RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol); -@@ -269,8 +275,8 @@ static void print_rsync_version(enum logcode f) +@@ -270,8 +276,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); @@ -354,7 +358,7 @@ diff --git a/options.c b/options.c #ifdef MAINTAINER_MODE rprintf(f, "Panic Action: \"%s\"\n", get_panic_action()); -@@ -337,6 +343,9 @@ void usage(enum logcode F) +@@ -338,6 +344,9 @@ void usage(enum logcode F) rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n"); rprintf(F," -H, --hard-links preserve hard links\n"); rprintf(F," -p, --perms preserve permissions\n"); @@ -364,7 +368,7 @@ diff --git a/options.c b/options.c rprintf(F," -E, --executability preserve the file's executability\n"); rprintf(F," --chmod=CHMOD affect file and/or directory permissions\n"); #ifdef SUPPORT_ACLS -@@ -374,7 +383,12 @@ void usage(enum logcode F) +@@ -375,7 +384,12 @@ void usage(enum logcode F) rprintf(F," --delete-after receiver deletes after transfer, not during\n"); rprintf(F," --delete-excluded also delete excluded files from destination dirs\n"); rprintf(F," --ignore-errors delete even if there are I/O errors\n"); @@ -378,7 +382,7 @@ diff --git a/options.c b/options.c rprintf(F," --max-delete=NUM don't delete more than NUM files\n"); rprintf(F," --max-size=SIZE don't transfer any file larger than SIZE\n"); rprintf(F," --min-size=SIZE don't transfer any file smaller than SIZE\n"); -@@ -477,6 +491,10 @@ static struct poptOption long_options[] = { +@@ -480,6 +494,10 @@ static struct poptOption long_options[] = { {"perms", 'p', POPT_ARG_VAL, &preserve_perms, 1, 0, 0 }, {"no-perms", 0, POPT_ARG_VAL, &preserve_perms, 0, 0, 0 }, {"no-p", 0, POPT_ARG_VAL, &preserve_perms, 0, 0, 0 }, @@ -389,21 +393,22 @@ diff --git a/options.c b/options.c {"executability", 'E', POPT_ARG_NONE, &preserve_executability, 0, 0, 0 }, {"acls", 'A', POPT_ARG_NONE, 0, 'A', 0, 0 }, {"no-acls", 0, POPT_ARG_VAL, &preserve_acls, 0, 0, 0 }, -@@ -551,6 +569,13 @@ static struct poptOption long_options[] = { - {"remove-sent-files",0, POPT_ARG_VAL, &remove_source_files, 2, 0, 0 }, /* deprecated */ +@@ -558,6 +576,14 @@ static struct poptOption long_options[] = { {"remove-source-files",0,POPT_ARG_VAL, &remove_source_files, 1, 0, 0 }, - {"force", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 }, -+ {"force-delete", 0, POPT_ARG_NONE, &force_delete, 0, 0, 0 }, + {"force", 0, POPT_ARG_VAL, &force_delete, 1, 0, 0 }, + {"no-force", 0, POPT_ARG_VAL, &force_delete, 0, 0, 0 }, ++ {"force-delete", 0, POPT_ARG_VAL, &force_delete, 1, 0, 0 }, ++ {"no-force-delete", 0, POPT_ARG_VAL, &force_delete, 0, 0, 0 }, +#ifdef SUPPORT_FORCE_CHANGE + {"force-change", 0, POPT_ARG_VAL, &force_change, ALL_IMMUTABLE, 0, 0 }, + {"no-force-change", 0, POPT_ARG_VAL, &force_change, 0, 0, 0 }, + {"force-uchange", 0, POPT_ARG_VAL, &force_change, USR_IMMUTABLE, 0, 0 }, + {"force-schange", 0, POPT_ARG_VAL, &force_change, SYS_IMMUTABLE, 0, 0 }, +#endif - {"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors, 0, 0, 0 }, + {"ignore-errors", 0, POPT_ARG_VAL, &ignore_errors, 1, 0, 0 }, + {"no-ignore-errors", 0, POPT_ARG_VAL, &ignore_errors, 0, 0, 0 }, {"max-delete", 0, POPT_ARG_INT, &max_delete, 0, 0, 0 }, - {0, 'F', POPT_ARG_NONE, 0, 'F', 0, 0 }, -@@ -1826,6 +1851,9 @@ void server_options(char **args, int *argc_p) +@@ -1852,6 +1878,9 @@ void server_options(char **args, int *argc_p) if (xfer_dirs && !recurse && delete_mode && am_sender) args[ac++] = "--no-r"; @@ -413,7 +418,7 @@ diff --git a/options.c b/options.c if (do_compression && def_compress_level != Z_DEFAULT_COMPRESSION) { if (asprintf(&arg, "--compress-level=%d", def_compress_level) < 0) goto oom; -@@ -1913,6 +1941,16 @@ void server_options(char **args, int *argc_p) +@@ -1939,6 +1968,16 @@ void server_options(char **args, int *argc_p) args[ac++] = "--delete-excluded"; if (force_delete) args[ac++] = "--force"; @@ -441,7 +446,7 @@ diff --git a/rsync.c b/rsync.c extern int preserve_executability; extern int preserve_times; extern int am_root; -@@ -339,6 +340,39 @@ mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms, +@@ -374,6 +375,39 @@ mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms, return new_mode; } @@ -481,7 +486,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) { -@@ -392,7 +426,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -427,7 +461,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) { @@ -490,7 +495,7 @@ diff --git a/rsync.c b/rsync.c if (ret < 0) { rsyserr(FERROR_XFER, errno, "failed to set times on %s", full_fname(fname)); -@@ -428,7 +462,8 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -463,7 +497,8 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, if (am_root >= 0) { if (do_lchown(fname, change_uid ? (uid_t)F_OWNER(file) : sxp->st.st_uid, @@ -500,7 +505,7 @@ 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", -@@ -460,7 +495,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -495,7 +530,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, #ifdef HAVE_CHMOD if (!BITS_EQUAL(sxp->st.st_mode, new_mode, CHMOD_BITS)) { @@ -509,7 +514,7 @@ diff --git a/rsync.c b/rsync.c if (ret < 0) { rsyserr(FERROR_XFER, errno, "failed to set permissions on %s", -@@ -472,6 +507,19 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -507,6 +542,19 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, } #endif @@ -529,7 +534,7 @@ diff --git a/rsync.c b/rsync.c if (verbose > 1 && flags & ATTRS_REPORT) { if (updated) rprintf(FCLIENT, "%s\n", fname); -@@ -531,7 +579,8 @@ int finish_transfer(const char *fname, const char *fnametmp, +@@ -566,7 +614,8 @@ int finish_transfer(const char *fname, const char *fnametmp, /* Change permissions before putting the file into place. */ set_file_attrs(fnametmp, file, NULL, fnamecmp, @@ -539,7 +544,7 @@ diff --git a/rsync.c b/rsync.c /* move tmp file over real file */ if (verbose > 2) -@@ -550,6 +599,10 @@ int finish_transfer(const char *fname, const char *fnametmp, +@@ -585,6 +634,10 @@ int finish_transfer(const char *fname, const char *fnametmp, } if (ret == 0) { /* The file was moved into place (not copied), so it's done. */ @@ -561,7 +566,7 @@ diff --git a/rsync.h b/rsync.h /* These flags are used in the live flist data. */ -@@ -149,6 +150,7 @@ +@@ -151,6 +152,7 @@ #define ATTRS_REPORT (1<<0) #define ATTRS_SKIP_MTIME (1<<1) @@ -569,7 +574,7 @@ diff --git a/rsync.h b/rsync.h #define FULL_FLUSH 1 #define NORMAL_FLUSH 0 -@@ -174,6 +176,7 @@ +@@ -177,6 +179,7 @@ #define ITEM_REPORT_GROUP (1<<6) #define ITEM_REPORT_ACL (1<<7) #define ITEM_REPORT_XATTR (1<<8) @@ -577,7 +582,7 @@ diff --git a/rsync.h b/rsync.h #define ITEM_BASIS_TYPE_FOLLOWS (1<<11) #define ITEM_XNAME_FOLLOWS (1<<12) #define ITEM_IS_NEW (1<<13) -@@ -452,6 +455,28 @@ typedef unsigned int size_t; +@@ -454,6 +457,28 @@ typedef unsigned int size_t; #endif #endif @@ -595,8 +600,8 @@ diff --git a/rsync.h b/rsync.h +#ifndef SF_NOUNLINK +#define SF_NOUNLINK 0 +#endif -+#define USR_IMMUTABLE (UF_IMMUTABLE|UF_NOUNLINK) -+#define SYS_IMMUTABLE (SF_IMMUTABLE|SF_NOUNLINK) ++#define USR_IMMUTABLE (UF_IMMUTABLE|UF_NOUNLINK|UF_APPEND) ++#define SYS_IMMUTABLE (SF_IMMUTABLE|SF_NOUNLINK|SF_APPEND) +#define ALL_IMMUTABLE (USR_IMMUTABLE|SYS_IMMUTABLE) +#define ST_FLAGS(st) (st.st_flags) +#else @@ -606,7 +611,7 @@ diff --git a/rsync.h b/rsync.h /* Find a variable that is either exactly 32-bits or longer. * If some code depends on 32-bit truncation, it will need to * take special action in a "#if SIZEOF_INT32 > 4" section. */ -@@ -620,6 +645,7 @@ extern int file_extra_cnt; +@@ -622,6 +647,7 @@ extern int file_extra_cnt; extern int inc_recurse; extern int uid_ndx; extern int gid_ndx; @@ -614,7 +619,7 @@ diff --git a/rsync.h b/rsync.h extern int acls_ndx; extern int xattrs_ndx; -@@ -657,6 +683,11 @@ extern int xattrs_ndx; +@@ -659,6 +685,11 @@ extern int xattrs_ndx; /* When the associated option is on, all entries will have these present: */ #define F_OWNER(f) REQ_EXTRA(f, uid_ndx)->unum #define F_GROUP(f) REQ_EXTRA(f, gid_ndx)->unum @@ -659,7 +664,7 @@ diff --git a/rsync.yo b/rsync.yo dit(--no-OPTION) You may turn off one or more implied options by prefixing the option name with "no-". Not all options may be prefixed with a "no-": -@@ -785,7 +790,7 @@ they would be using bf(--copy-links). +@@ -792,7 +797,7 @@ they would be using bf(--copy-links). Without this option, if the sending side has replaced a directory with a symlink to a directory, the receiving side will delete anything that is in the way of the new symlink, including a directory hierarchy (as long as @@ -668,7 +673,7 @@ diff --git a/rsync.yo b/rsync.yo See also bf(--keep-dirlinks) for an analogous option for the receiving side. -@@ -922,6 +927,29 @@ super-user copies all namespaces except system.*. A normal user only copies +@@ -929,6 +934,29 @@ super-user copies all namespaces except system.*. A normal user only copies the user.* namespace. To be able to backup and restore non-user namespaces as a normal user, see the bf(--fake-super) option. @@ -698,7 +703,7 @@ diff --git a/rsync.yo b/rsync.yo dit(bf(--chmod)) This option tells rsync to apply one or more comma-separated "chmod" strings to the permission of the files in the transfer. The resulting value is treated as though it was the permissions -@@ -1177,12 +1205,13 @@ See bf(--delete) (which is implied) for more details on file-deletion. +@@ -1184,12 +1212,13 @@ See bf(--delete) (which is implied) for more details on file-deletion. dit(bf(--ignore-errors)) Tells bf(--delete) to go ahead and delete files even when there are I/O errors. @@ -715,7 +720,7 @@ diff --git a/rsync.yo b/rsync.yo bf(--recursive) option was also enabled. dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM -@@ -1638,7 +1667,7 @@ with older versions of rsync, but that also turns on the output of other +@@ -1645,7 +1674,7 @@ with older versions of rsync, but that also turns on the output of other verbose messages). The "%i" escape has a cryptic output that is 11 letters long. The general @@ -724,7 +729,7 @@ diff --git a/rsync.yo b/rsync.yo type of update being done, bf(X) is replaced by the file-type, and the other letters represent attributes that may be output if they are being modified. -@@ -1689,7 +1718,7 @@ quote(itemization( +@@ -1701,7 +1730,7 @@ quote(itemization( sender's value (requires bf(--owner) and super-user privileges). it() A bf(g) means the group is different and is being updated to the sender's value (requires bf(--group) and the authority to set the group). @@ -854,7 +859,7 @@ diff --git a/syscall.c b/syscall.c @@ -168,17 +223,74 @@ int do_chmod(const char *path, mode_t mode) #endif } else - code = chmod(path, mode & CHMOD_BITS); + code = chmod(path, mode & CHMOD_BITS); /* DISCOURAGED FUNCTION */ +#ifdef SUPPORT_FORCE_CHANGE + if (code < 0 && force_change && errno == EPERM && !S_ISLNK(mode)) { + if (fileflags == NO_FFLAGS) { @@ -875,7 +880,7 @@ diff --git a/syscall.c b/syscall.c + fileflags = 0; /* avoid compiler warning */ +#endif if (code != 0 && (preserve_perms || preserve_executability)) - return code; + return code; return 0; } #endif @@ -938,7 +943,7 @@ diff --git a/t_stub.c b/t_stub.c mode_t orig_umask = 002; char *partial_dir; char *module_dir; -@@ -83,3 +84,23 @@ struct filter_list_struct server_filter_list; +@@ -83,3 +84,23 @@ struct filter_list_struct daemon_filter_list; { return "tester"; } @@ -1036,7 +1041,30 @@ diff --git a/util.c b/util.c diff --git a/xattrs.c b/xattrs.c --- a/xattrs.c +++ b/xattrs.c -@@ -915,7 +915,7 @@ int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) +@@ -280,6 +280,10 @@ int get_xattr(const char *fname, stat_x *sxp) + { + sxp->xattr = new(item_list); + *sxp->xattr = empty_xattr; ++ ++ if (IS_SPECIAL(sxp->st.st_mode) || IS_DEVICE(sxp->st.st_mode)) ++ return 0; ++ + if (rsync_xal_get(fname, sxp->xattr) < 0) { + free_xattr(sxp); + return -1; +@@ -814,6 +818,11 @@ int set_xattr(const char *fname, const struct file_struct *file, + return -1; + } + ++ if (IS_SPECIAL(sxp->st.st_mode) || IS_DEVICE(sxp->st.st_mode)) { ++ errno = ENOTSUP; ++ return -1; ++ } ++ + ndx = F_XATTR(file); + return rsync_xal_set(fname, lst + ndx, fnamecmp, sxp); + } +@@ -930,7 +939,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/fsync.diff b/fsync.diff index af3b80c..e0cdbbf 100644 --- a/fsync.diff +++ b/fsync.diff @@ -10,7 +10,7 @@ To use this patch, run these commands for a successful build: diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -47,6 +47,7 @@ int append_mode = 0; +@@ -48,6 +48,7 @@ int append_mode = 0; int keep_dirlinks = 0; int copy_dirlinks = 0; int copy_links = 0; @@ -18,7 +18,7 @@ diff --git a/options.c b/options.c int preserve_links = 0; int preserve_hard_links = 0; int preserve_acls = 0; -@@ -382,6 +383,7 @@ void usage(enum logcode F) +@@ -383,6 +384,7 @@ void usage(enum logcode F) rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n"); rprintf(F," --delay-updates put all updated files into place at transfer's end\n"); rprintf(F," -m, --prune-empty-dirs prune empty directory chains from the file-list\n"); @@ -26,15 +26,15 @@ diff --git a/options.c b/options.c rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n"); rprintf(F," --timeout=SECONDS set I/O timeout in seconds\n"); rprintf(F," --contimeout=SECONDS set daemon connection timeout in seconds\n"); -@@ -613,6 +615,7 @@ static struct poptOption long_options[] = { - {"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 }, +@@ -626,6 +628,7 @@ static struct poptOption long_options[] = { {"no-timeout", 0, POPT_ARG_VAL, &io_timeout, 0, 0, 0 }, {"contimeout", 0, POPT_ARG_INT, &connect_timeout, 0, 0, 0 }, + {"no-contimeout", 0, POPT_ARG_VAL, &connect_timeout, 0, 0, 0 }, + {"fsync", 0, POPT_ARG_NONE, &do_fsync, 0, 0, 0 }, {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 }, {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 }, {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 }, -@@ -1977,6 +1980,9 @@ void server_options(char **args, int *argc_p) +@@ -2003,6 +2006,9 @@ void server_options(char **args, int *argc_p) args[ac++] = tmpdir; } diff --git a/ignore-case.diff b/ignore-case.diff index 7fbcbc6..710abb3 100644 --- a/ignore-case.diff +++ b/ignore-case.diff @@ -23,7 +23,7 @@ diff --git a/exclude.c b/exclude.c extern int verbose; extern int am_server; -@@ -580,16 +581,15 @@ static int rule_matches(char *fname, struct filter_struct *ex, int name_is_dir) +@@ -604,16 +605,15 @@ static int rule_matches(const char *fname, struct filter_struct *ex, int name_is if (litmatch_array(pattern, strings, slash_handling)) return ret_match; } else if (anchored_match) { @@ -55,7 +55,7 @@ diff --git a/flist.c b/flist.c extern int ignore_errors; extern int numeric_ids; extern int recurse; -@@ -2617,6 +2618,7 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2) +@@ -2672,6 +2673,7 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2) { int dif; const uchar *c1, *c2; @@ -63,7 +63,7 @@ diff --git a/flist.c b/flist.c enum fnc_state state1, state2; enum fnc_type type1, type2; enum fnc_type t_path = protocol_version >= 29 ? t_PATH : t_ITEM; -@@ -2727,7 +2729,15 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2) +@@ -2782,7 +2784,15 @@ int f_name_cmp(const struct file_struct *f1, const struct file_struct *f2) if (type1 != type2) return type1 == t_PATH ? 1 : -1; } @@ -83,7 +83,7 @@ diff --git a/flist.c b/flist.c diff --git a/ifuncs.h b/ifuncs.h --- a/ifuncs.h +++ b/ifuncs.h -@@ -98,3 +98,38 @@ toUpper(const char *ptr) +@@ -108,3 +108,38 @@ toUpper(const char *ptr) { return toupper(*(unsigned char *)ptr); } @@ -211,7 +211,7 @@ diff --git a/lib/wildmatch.c b/lib/wildmatch.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -117,6 +117,7 @@ OFF_T max_size = 0; +@@ -118,6 +118,7 @@ OFF_T max_size = 0; OFF_T min_size = 0; int ignore_errors = 0; int modify_window = 0; @@ -219,7 +219,7 @@ diff --git a/options.c b/options.c int blocking_io = -1; int checksum_seed = 0; int inplace = 0; -@@ -407,6 +408,7 @@ void usage(enum logcode F) +@@ -408,6 +409,7 @@ void usage(enum logcode F) rprintf(F," --files-from=FILE read list of source-file names from FILE\n"); rprintf(F," -0, --from0 all *-from/filter files are delimited by 0s\n"); rprintf(F," -s, --protect-args no space-splitting; only wildcard special-chars\n"); @@ -227,7 +227,7 @@ diff --git a/options.c b/options.c rprintf(F," --address=ADDRESS bind address for outgoing socket to daemon\n"); rprintf(F," --port=PORT specify double-colon alternate port number\n"); rprintf(F," --sockopts=OPTIONS specify custom TCP options\n"); -@@ -602,6 +604,8 @@ static struct poptOption long_options[] = { +@@ -614,6 +616,8 @@ static struct poptOption long_options[] = { {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 }, {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 }, {"only-write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 }, @@ -236,7 +236,7 @@ diff --git a/options.c b/options.c {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 }, {"from0", '0', POPT_ARG_VAL, &eol_nulls, 1, 0, 0}, {"no-from0", 0, POPT_ARG_VAL, &eol_nulls, 0, 0, 0}, -@@ -1939,6 +1943,9 @@ void server_options(char **args, int *argc_p) +@@ -1965,6 +1969,9 @@ void server_options(char **args, int *argc_p) args[ac++] = arg; } @@ -257,7 +257,7 @@ diff --git a/rsync.yo b/rsync.yo --address=ADDRESS bind address for outgoing socket to daemon --port=PORT specify double-colon alternate port number --sockopts=OPTIONS specify custom TCP options -@@ -1425,6 +1426,10 @@ If you use this option with bf(--iconv), the args will also be translated +@@ -1432,6 +1433,10 @@ If you use this option with bf(--iconv), the args will also be translated from the local to the remote character-set. The translation happens before wild-cards are expanded. See also the bf(--files-from) option. diff --git a/link-by-hash.diff b/link-by-hash.diff index 8a934ba..b4e0848 100644 --- a/link-by-hash.diff +++ b/link-by-hash.diff @@ -35,8 +35,8 @@ diff --git a/flist.c b/flist.c extern char curr_dir[MAXPATHLEN]; -@@ -824,7 +825,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, - extra_len += (S_ISDIR(mode) ? 2 : 1) * EXTRA_LEN; +@@ -859,7 +860,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, + extra_len += EXTRA_LEN; #endif - if (always_checksum && S_ISREG(mode)) @@ -388,7 +388,7 @@ new file mode 100644 diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -156,6 +156,7 @@ char *backup_suffix = NULL; +@@ -157,6 +157,7 @@ char *backup_suffix = NULL; char *tmpdir = NULL; char *partial_dir = NULL; char *basis_dir[MAX_BASIS_DIRS+1]; @@ -396,7 +396,7 @@ diff --git a/options.c b/options.c char *config_file = NULL; char *shell_cmd = NULL; char *logfile_name = NULL; -@@ -393,6 +394,7 @@ void usage(enum logcode F) +@@ -394,6 +395,7 @@ void usage(enum logcode F) rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n"); rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n"); rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n"); @@ -404,7 +404,7 @@ diff --git a/options.c b/options.c rprintf(F," -z, --compress compress file data during the transfer\n"); rprintf(F," --compress-level=NUM explicitly set compression level\n"); rprintf(F," --skip-compress=LIST skip compressing files with a suffix in LIST\n"); -@@ -445,7 +447,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, +@@ -446,7 +448,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, @@ -413,15 +413,15 @@ diff --git a/options.c b/options.c OPT_SERVER, OPT_REFUSED_BASE = 9000}; static struct poptOption long_options[] = { -@@ -570,6 +572,7 @@ static struct poptOption long_options[] = { +@@ -578,6 +580,7 @@ static struct poptOption long_options[] = { {"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 }, {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 }, {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 }, + {"link-by-hash", 0, POPT_ARG_STRING, 0, OPT_LINK_BY_HASH, 0, 0}, - {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 }, - {"compress", 'z', POPT_ARG_NONE, 0, 'z', 0, 0 }, - {"no-compress", 0, POPT_ARG_VAL, &do_compression, 0, 0, 0 }, -@@ -1244,6 +1247,21 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) + {"fuzzy", 'y', POPT_ARG_VAL, &fuzzy_basis, 1, 0, 0 }, + {"no-fuzzy", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 }, + {"no-y", 0, POPT_ARG_VAL, &fuzzy_basis, 0, 0, 0 }, +@@ -1260,6 +1263,21 @@ int parse_arguments(int *argc_p, const char ***argv_p) return 0; #endif @@ -429,7 +429,7 @@ diff --git a/options.c b/options.c +#ifdef HAVE_LINK + arg = poptGetOptArg(pc); + if (sanitize_paths) -+ arg = sanitize_path(NULL, arg, NULL, 0); ++ arg = sanitize_path(NULL, arg, NULL, 0, SP_DEFAULT); + link_by_hash_dir = (char *)arg; + break; +#else @@ -443,7 +443,7 @@ diff --git a/options.c b/options.c default: /* A large opt value means that set_refuse_options() * turned this option off. */ -@@ -1997,6 +2015,11 @@ void server_options(char **args, int *argc_p) +@@ -2023,6 +2041,11 @@ void server_options(char **args, int *argc_p) } else if (inplace) args[ac++] = "--inplace"; @@ -532,7 +532,7 @@ diff --git a/receiver.c b/receiver.c diff --git a/rsync.c b/rsync.c --- a/rsync.c +++ b/rsync.c -@@ -49,6 +49,7 @@ extern int inplace; +@@ -48,6 +48,7 @@ extern int inplace; extern int flist_eof; extern int keep_dirlinks; extern int make_backups; @@ -540,7 +540,7 @@ diff --git a/rsync.c b/rsync.c extern struct file_list *cur_flist, *first_flist, *dir_flist; extern struct chmod_mode_struct *daemon_chmod_modes; #ifdef ICONV_OPTION -@@ -536,8 +537,15 @@ int finish_transfer(const char *fname, const char *fnametmp, +@@ -571,8 +572,15 @@ int finish_transfer(const char *fname, const char *fnametmp, /* move tmp file over real file */ if (verbose > 2) rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname); @@ -561,7 +561,7 @@ diff --git a/rsync.c b/rsync.c diff --git a/rsync.h b/rsync.h --- a/rsync.h +++ b/rsync.h -@@ -818,6 +818,14 @@ struct stats { +@@ -820,6 +820,14 @@ struct stats { int num_transferred_files; }; diff --git a/log-checksum.diff b/log-checksum.diff index f06824b..78f28f7 100644 --- a/log-checksum.diff +++ b/log-checksum.diff @@ -98,7 +98,7 @@ diff --git a/match.c b/match.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -1498,7 +1498,8 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1524,7 +1524,8 @@ int parse_arguments(int *argc_p, const char ***argv_p) else if (log_format_has(stdout_format, 'i')) stdout_format_has_i = itemize_changes | 1; if (!log_format_has(stdout_format, 'b') @@ -155,7 +155,7 @@ diff --git a/receiver.c b/receiver.c diff --git a/rsync.yo b/rsync.yo --- a/rsync.yo +++ b/rsync.yo -@@ -2075,7 +2075,7 @@ by the server and defaults to the current code(time()). This option +@@ -2087,7 +2087,7 @@ by the server and defaults to the current code(time()). This option is used to set a specific checksum seed, which is useful for applications that want repeatable block and file checksums, or in the case where the user wants a more random checksum seed. @@ -167,7 +167,7 @@ diff --git a/rsync.yo b/rsync.yo diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo --- a/rsyncd.conf.yo +++ b/rsyncd.conf.yo -@@ -511,7 +511,8 @@ quote(itemization( +@@ -509,7 +509,8 @@ quote(itemization( it() %a the remote IP address it() %b the number of bytes actually transferred it() %B the permission bits of the file (e.g. rwxrwxrwt) diff --git a/nameconverter.diff b/nameconverter.diff index 33a990c..bc3f941 100644 --- a/nameconverter.diff +++ b/nameconverter.diff @@ -23,7 +23,7 @@ To use this patch, run these commands for a successful build: diff --git a/clientserver.c b/clientserver.c --- a/clientserver.c +++ b/clientserver.c -@@ -64,6 +64,7 @@ char *auth_user; +@@ -67,6 +67,7 @@ char *auth_user; int read_only = 0; int module_id = -1; int munge_symlinks = 0; @@ -31,7 +31,7 @@ diff --git a/clientserver.c b/clientserver.c struct chmod_mode_struct *daemon_chmod_modes; /* module_dirlen is the length of the module_dir string when in daemon -@@ -73,6 +74,7 @@ char *module_dir = NULL; +@@ -76,6 +77,7 @@ char *module_dir = NULL; unsigned int module_dirlen = 0; static int rl_nulls = 0; @@ -39,7 +39,7 @@ diff --git a/clientserver.c b/clientserver.c #ifdef HAVE_SIGACTION static struct sigaction sigact; -@@ -539,7 +541,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host) +@@ -555,7 +557,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host) log_init(1); #ifdef HAVE_PUTENV @@ -48,7 +48,7 @@ diff --git a/clientserver.c b/clientserver.c char *modname, *modpath, *hostaddr, *hostname, *username; int status; -@@ -635,6 +637,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host) +@@ -651,6 +653,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host) set_blocking(fds[1]); pre_exec_fd = fds[1]; } @@ -93,7 +93,7 @@ diff --git a/clientserver.c b/clientserver.c umask(0); } #endif -@@ -848,6 +888,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host) +@@ -880,6 +920,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host) return 0; } @@ -273,10 +273,10 @@ diff --git a/t_stub.c b/t_stub.c char *partial_dir; char *module_dir; +pid_t namecvt_pid; - struct filter_list_struct server_filter_list; + struct filter_list_struct daemon_filter_list; void rprintf(UNUSED(enum logcode code), const char *format, ...) -@@ -69,6 +70,11 @@ struct filter_list_struct server_filter_list; +@@ -69,6 +70,11 @@ struct filter_list_struct daemon_filter_list; return -1; } @@ -341,7 +341,7 @@ diff --git a/util.c b/util.c extern char *partial_dir; +extern pid_t namecvt_pid; +extern unsigned int module_dirlen; - extern struct filter_list_struct server_filter_list; + extern struct filter_list_struct daemon_filter_list; int sanitize_paths = 0; @@ -468,24 +469,44 @@ void kill_all(int sig) diff --git a/omit-dir-changes.diff b/omit-dir-changes.diff index b750253..b07ac10 100644 --- a/omit-dir-changes.diff +++ b/omit-dir-changes.diff @@ -10,7 +10,7 @@ To use this patch, run these commands for a successful build: diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -45,6 +45,7 @@ extern int preserve_hard_links; +@@ -44,6 +44,7 @@ extern int preserve_hard_links; extern int preserve_executability; extern int preserve_perms; extern int preserve_times; @@ -18,17 +18,17 @@ diff --git a/generator.c b/generator.c extern int uid_ndx; extern int gid_ndx; extern int delete_mode; -@@ -625,6 +626,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre - (receiver_symlink_times && !(file->flags & FLAG_TIME_FAILED)) || - #endif - !S_ISLNK(file->mode); +@@ -624,6 +625,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre + const char *xname) + { + if (statret >= 0) { /* A from-dest-dir statret can == 1! */ + int omit_changes = omit_dir_changes && S_ISDIR(sxp->st.st_mode); - - if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size) - iflags |= ITEM_REPORT_SIZE; -@@ -641,10 +643,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre - if ((preserve_perms || preserve_executability) - && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS)) + int keep_time = !preserve_times ? 0 + : S_ISDIR(file->mode) ? preserve_times > 1 : + #if defined HAVE_LUTIMES && defined HAVE_UTIMES +@@ -653,10 +655,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre + } else if (preserve_executability + && ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0))) iflags |= ITEM_REPORT_PERMS; - if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid) + if (uid_ndx && am_root && !omit_changes @@ -41,7 +41,7 @@ diff --git a/generator.c b/generator.c iflags |= ITEM_REPORT_GROUP; #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { -@@ -1387,7 +1390,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, +@@ -1419,7 +1422,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, real_sx = sx; if (file->flags & FLAG_DIR_CREATED) statret = -1; @@ -53,7 +53,7 @@ diff --git a/generator.c b/generator.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -58,6 +58,7 @@ int preserve_specials = 0; +@@ -59,6 +59,7 @@ int preserve_specials = 0; int preserve_uid = 0; int preserve_gid = 0; int preserve_times = 0; @@ -61,7 +61,7 @@ diff --git a/options.c b/options.c int update_only = 0; int cvs_exclude = 0; int dry_run = 0; -@@ -352,6 +353,7 @@ void usage(enum logcode F) +@@ -353,6 +354,7 @@ void usage(enum logcode F) rprintf(F," -D same as --devices --specials\n"); rprintf(F," -t, --times preserve modification times\n"); rprintf(F," -O, --omit-dir-times omit directories from --times\n"); @@ -69,7 +69,7 @@ diff --git a/options.c b/options.c rprintf(F," --super receiver attempts super-user activities\n"); #ifdef SUPPORT_XATTRS rprintf(F," --fake-super store/recover privileged attrs using xattrs\n"); -@@ -490,6 +492,7 @@ static struct poptOption long_options[] = { +@@ -493,6 +495,7 @@ static struct poptOption long_options[] = { {"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 }, {"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 }, {"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 }, @@ -77,7 +77,7 @@ diff --git a/options.c b/options.c {"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 }, {"super", 0, POPT_ARG_VAL, &am_root, 2, 0, 0 }, {"no-super", 0, POPT_ARG_VAL, &am_root, 0, 0, 0 }, -@@ -1483,6 +1486,8 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1509,6 +1512,8 @@ int parse_arguments(int *argc_p, const char ***argv_p) parse_rule(&filter_list, backup_dir_buf, 0, 0); } @@ -86,7 +86,7 @@ diff --git a/options.c b/options.c if (make_backups && !backup_dir) { omit_dir_times = 0; /* Implied, so avoid -O to sender. */ if (preserve_times > 1) -@@ -1721,6 +1726,8 @@ void server_options(char **args, int *argc_p) +@@ -1747,6 +1752,8 @@ void server_options(char **args, int *argc_p) argstr[x++] = 'm'; if (omit_dir_times) argstr[x++] = 'O'; @@ -106,7 +106,7 @@ diff --git a/rsync.c b/rsync.c extern int am_root; extern int am_server; extern int am_sender; -@@ -404,9 +405,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, +@@ -439,9 +440,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp, file->flags |= FLAG_TIME_FAILED; } @@ -131,7 +131,7 @@ diff --git a/rsync.yo b/rsync.yo --super receiver attempts super-user activities --fake-super store/recover privileged attrs using xattrs -S, --sparse handle sparse files efficiently -@@ -987,6 +988,10 @@ it is preserving modification times (see bf(--times)). If NFS is sharing +@@ -994,6 +995,10 @@ it is preserving modification times (see bf(--times)). If NFS is sharing the directories on the receiving side, it is a good idea to use bf(-O). This option is inferred if you use bf(--backup) without bf(--backup-dir). diff --git a/openssl-support.diff b/openssl-support.diff index 2974811..c1ad7f6 100644 --- a/openssl-support.diff +++ b/openssl-support.diff @@ -78,7 +78,7 @@ diff --git a/cleanup.c b/cleanup.c diff --git a/clientserver.c b/clientserver.c --- a/clientserver.c +++ b/clientserver.c -@@ -30,6 +30,9 @@ extern int am_sender; +@@ -31,6 +31,9 @@ extern int am_sender; extern int am_server; extern int am_daemon; extern int am_root; @@ -86,9 +86,9 @@ diff --git a/clientserver.c b/clientserver.c +extern int use_ssl; +#endif extern int rsync_port; + extern int protect_args; extern int ignore_errors; - extern int kluge_around_eof; -@@ -125,8 +128,18 @@ int start_socket_client(char *host, int remote_argc, char *remote_argv[], +@@ -128,8 +131,18 @@ int start_socket_client(char *host, int remote_argc, char *remote_argv[], #endif ret = start_inband_exchange(fd, fd, user, remote_argc, remote_argv); @@ -108,7 +108,7 @@ diff --git a/clientserver.c b/clientserver.c } static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int am_client) -@@ -269,6 +282,32 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char +@@ -272,6 +285,32 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char if (verbose > 1) print_child_argv("sending daemon args:", sargs); @@ -141,7 +141,7 @@ diff --git a/clientserver.c b/clientserver.c io_printf(f_out, "%.*s\n", modlen, modname); /* Old servers may just drop the connection here, -@@ -294,6 +333,10 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char +@@ -297,6 +336,10 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char * server to terminate the listing of modules. * We don't want to go on and transfer * anything; just exit. */ @@ -152,7 +152,7 @@ diff --git a/clientserver.c b/clientserver.c exit(0); } -@@ -301,6 +344,10 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char +@@ -304,6 +347,10 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char rprintf(FERROR, "%s\n", line); /* This is always fatal; the server will now * close the socket. */ @@ -163,7 +163,7 @@ diff --git a/clientserver.c b/clientserver.c return -1; } -@@ -898,6 +945,9 @@ int start_daemon(int f_in, int f_out) +@@ -941,6 +988,9 @@ int start_daemon(int f_in, int f_out) if (exchange_protocols(f_in, f_out, line, sizeof line, 0) < 0) return -1; @@ -173,7 +173,7 @@ diff --git a/clientserver.c b/clientserver.c line[0] = 0; if (!read_line_old(f_in, line, sizeof line)) return -1; -@@ -909,6 +959,20 @@ int start_daemon(int f_in, int f_out) +@@ -952,6 +1002,20 @@ int start_daemon(int f_in, int f_out) return -1; } @@ -222,7 +222,7 @@ diff --git a/configure.in b/configure.in diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -184,6 +184,14 @@ int logfile_format_has_o_or_i = 0; +@@ -185,6 +185,14 @@ int logfile_format_has_o_or_i = 0; int always_checksum = 0; int list_only = 0; @@ -237,7 +237,7 @@ diff --git a/options.c b/options.c #define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */ char *batch_name = NULL; -@@ -224,6 +232,7 @@ static void print_rsync_version(enum logcode f) +@@ -225,6 +233,7 @@ static void print_rsync_version(enum logcode f) char const *links = "no "; char const *iconv = "no "; char const *ipv6 = "no "; @@ -245,7 +245,7 @@ diff --git a/options.c b/options.c STRUCT_STAT *dumstat; #if SUBPROTOCOL_VERSION != 0 -@@ -256,6 +265,9 @@ static void print_rsync_version(enum logcode f) +@@ -257,6 +266,9 @@ static void print_rsync_version(enum logcode f) #if defined HAVE_LUTIMES && defined HAVE_UTIMES symtimes = ""; #endif @@ -255,7 +255,7 @@ diff --git a/options.c b/options.c rprintf(f, "%s version %s protocol version %d%s\n", RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol); -@@ -269,8 +281,8 @@ static void print_rsync_version(enum logcode f) +@@ -270,8 +282,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); @@ -266,7 +266,7 @@ diff --git a/options.c b/options.c #ifdef MAINTAINER_MODE rprintf(f, "Panic Action: \"%s\"\n", get_panic_action()); -@@ -432,6 +444,13 @@ void usage(enum logcode F) +@@ -433,6 +445,13 @@ void usage(enum logcode F) #endif rprintf(F," -4, --ipv4 prefer IPv4\n"); rprintf(F," -6, --ipv6 prefer IPv6\n"); @@ -280,7 +280,7 @@ diff --git a/options.c b/options.c rprintf(F," --version print version number\n"); rprintf(F,"(-h) --help show this help (-h works with no other options)\n"); -@@ -445,7 +464,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, +@@ -446,7 +465,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, @@ -289,7 +289,7 @@ diff --git a/options.c b/options.c OPT_SERVER, OPT_REFUSED_BASE = 9000}; static struct poptOption long_options[] = { -@@ -634,6 +653,13 @@ static struct poptOption long_options[] = { +@@ -649,6 +668,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 }, @@ -303,7 +303,7 @@ diff --git a/options.c b/options.c /* 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 }, -@@ -659,6 +685,13 @@ static void daemon_usage(enum logcode F) +@@ -674,6 +700,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"); @@ -317,7 +317,7 @@ diff --git a/options.c b/options.c rprintf(F," --help show this help screen\n"); rprintf(F,"\n"); -@@ -683,6 +716,13 @@ static struct poptOption long_daemon_options[] = { +@@ -698,6 +731,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 }, @@ -331,7 +331,7 @@ diff --git a/options.c b/options.c {"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 }, -@@ -962,6 +1002,12 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -979,6 +1019,12 @@ int parse_arguments(int *argc_p, const char ***argv_p) verbose++; break; @@ -344,7 +344,7 @@ diff --git a/options.c b/options.c default: rprintf(FERROR, "rsync: %s: %s (in daemon mode)\n", -@@ -985,6 +1031,17 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1002,6 +1048,17 @@ int parse_arguments(int *argc_p, const char ***argv_p) exit_cleanup(RERR_SYNTAX); } @@ -362,7 +362,7 @@ diff --git a/options.c b/options.c *argv_p = argv = poptGetArgs(pc); *argc_p = argc = count_args(argv); am_starting_up = 0; -@@ -1244,6 +1301,12 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1260,6 +1317,12 @@ int parse_arguments(int *argc_p, const char ***argv_p) return 0; #endif @@ -375,7 +375,7 @@ diff --git a/options.c b/options.c default: /* A large opt value means that set_refuse_options() * turned this option off. */ -@@ -1567,6 +1630,17 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1593,6 +1656,17 @@ int parse_arguments(int *argc_p, const char ***argv_p) if (delay_updates && !partial_dir) partial_dir = tmp_partialdir; @@ -393,7 +393,7 @@ diff --git a/options.c b/options.c if (inplace) { #ifdef HAVE_FTRUNCATE if (partial_dir) { -@@ -2041,10 +2115,27 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr) +@@ -2067,10 +2141,27 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr) char *p; int not_host; int hostlen; @@ -435,7 +435,7 @@ diff --git a/rsync.h b/rsync.h #define SYMLINK_PREFIX "/rsyncd-munged/" #define SYMLINK_PREFIX_LEN ((int)sizeof SYMLINK_PREFIX - 1) -@@ -537,6 +538,11 @@ typedef unsigned int size_t; +@@ -539,6 +540,11 @@ typedef unsigned int size_t; # define SIZEOF_INT64 SIZEOF_OFF_T #endif diff --git a/osx-create-time.diff b/osx-create-time.diff deleted file mode 100644 index d868a7c..0000000 --- a/osx-create-time.diff +++ /dev/null @@ -1,133 +0,0 @@ -This patch handles the creation time on OS X by putting it into an -extended attribute. This is a modified version of a patch that was -provided by Wesley W. Terpstra. - -To use this patch, run these commands for a successful build: - - patch -p1 -+ -+#define CRTIME_XATTR "com.apple.crtime96" -+#define IS_CRTIME(name) (*(name) == *CRTIME_XATTR && strcmp(name, CRTIME_XATTR) == 0) -+#define CRTIME_XATTR_LEN (8+4) -+ -+struct CreationTime { -+ unsigned long length; -+ struct timespec crtime; -+}; -+ -+static struct timespec *getCreationTime(const char *path) -+{ -+ static struct CreationTime attrBuf; -+ struct attrlist attrList; -+ -+ memset(&attrList, 0, sizeof attrList); -+ attrList.bitmapcount = ATTR_BIT_MAP_COUNT; -+ attrList.commonattr = ATTR_CMN_CRTIME; -+ if (getattrlist(path, &attrList, &attrBuf, sizeof attrBuf, FSOPT_NOFOLLOW) < 0) -+ return NULL; -+ return &attrBuf.crtime; -+} -+ -+static ssize_t get_crtime_xattr(const char *path, char *buf, size_t size) -+{ -+ struct timespec *crtime_p; -+ -+ if (buf == NULL) -+ return CRTIME_XATTR_LEN; -+ if (size < CRTIME_XATTR_LEN) -+ return -1; /* Doesn't happen with rsync code... */ -+ -+ if ((crtime_p = getCreationTime(path)) == NULL) -+ return -1; -+ -+ SIVAL(buf, 0, crtime_p->tv_sec); -+#if SIZEOF_TIME_T > 4 -+ SIVAL(buf, 4, crtime_p->tv_sec >> 32); -+#else -+ SIVAL(buf, 4, 0); -+#endif -+ SIVAL(buf, 8, crtime_p->tv_nsec); -+ -+ return CRTIME_XATTR_LEN; -+} -+ -+static int set_crtime_xattr(const char *path, const char *buf, size_t size) -+{ -+ struct attrlist attrList; -+ struct timespec crtime; -+ -+ if (size != CRTIME_XATTR_LEN) -+ return -1; -+ -+ crtime.tv_sec = IVAL(buf, 0); -+#if SIZEOF_TIME_T > 4 -+ crtime.tv_sec += (time_t)IVAL(buf, 4) << 32; -+#endif -+ crtime.tv_nsec = IVAL(buf, 8); -+ -+ memset(&attrList, 0, sizeof attrList); -+ attrList.bitmapcount = ATTR_BIT_MAP_COUNT; -+ attrList.commonattr = ATTR_CMN_CRTIME; -+ return setattrlist(path, &attrList, &crtime, sizeof crtime, FSOPT_NOFOLLOW); -+} -+ - ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size) - { -+ if (IS_CRTIME(name)) -+ return get_crtime_xattr(path, value, size); - return getxattr(path, name, value, size, 0, XATTR_NOFOLLOW); - } - - ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size) - { -+ /* XXX Figure out how to get creation time from an open filedes? */ - return fgetxattr(filedes, name, value, size, 0, 0); - } - - int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size) - { -+ if (IS_CRTIME(name)) -+ return set_crtime_xattr(path, value, size); - return setxattr(path, name, value, size, 0, XATTR_NOFOLLOW); - } - - int sys_lremovexattr(const char *path, const char *name) - { -+ /* Every file on hfs+ has this; you can't remove it... */ -+ if (IS_CRTIME(name)) -+ return 0; - return removexattr(path, name, XATTR_NOFOLLOW); - } - - ssize_t sys_llistxattr(const char *path, char *list, size_t size) - { -- return listxattr(path, list, size, XATTR_NOFOLLOW); -+ ssize_t ret = listxattr(path, list, size, XATTR_NOFOLLOW); -+ if (ret < 0) -+ return ret; -+ if (getCreationTime(path) != NULL) { -+ ret += sizeof CRTIME_XATTR; -+ if (list) { -+ if ((size_t)ret > size) { -+ errno = ERANGE; -+ return -1; -+ } -+ memcpy(list + ret - sizeof CRTIME_XATTR, -+ CRTIME_XATTR, sizeof CRTIME_XATTR); -+ } -+ } -+ return ret; - } - - #elif HAVE_FREEBSD_XATTRS diff --git a/preallocate.diff b/preallocate.diff index 97c0b96..d910772 100644 --- a/preallocate.diff +++ b/preallocate.diff @@ -39,7 +39,7 @@ diff --git a/compat.c b/compat.c diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in -@@ -552,13 +552,40 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \ +@@ -554,13 +554,40 @@ AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \ strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \ setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \ strerror putenv iconv_open locale_charset nl_langinfo getxattr \ @@ -84,7 +84,7 @@ diff --git a/configure.in b/configure.in diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -72,6 +72,7 @@ int remove_source_files = 0; +@@ -73,6 +73,7 @@ int remove_source_files = 0; int one_file_system = 0; int protocol_version = PROTOCOL_VERSION; int sparse_files = 0; @@ -92,7 +92,7 @@ diff --git a/options.c b/options.c int do_compression = 0; int def_compress_level = Z_DEFAULT_COMPRESSION; int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */ -@@ -224,6 +225,7 @@ static void print_rsync_version(enum logcode f) +@@ -225,6 +226,7 @@ static void print_rsync_version(enum logcode f) char const *links = "no "; char const *iconv = "no "; char const *ipv6 = "no "; @@ -100,7 +100,7 @@ diff --git a/options.c b/options.c STRUCT_STAT *dumstat; #if SUBPROTOCOL_VERSION != 0 -@@ -256,6 +258,9 @@ static void print_rsync_version(enum logcode f) +@@ -257,6 +259,9 @@ static void print_rsync_version(enum logcode f) #if defined HAVE_LUTIMES && defined HAVE_UTIMES symtimes = ""; #endif @@ -110,7 +110,7 @@ diff --git a/options.c b/options.c rprintf(f, "%s version %s protocol version %d%s\n", RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol); -@@ -269,8 +274,8 @@ static void print_rsync_version(enum logcode f) +@@ -270,8 +275,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); @@ -121,7 +121,7 @@ diff --git a/options.c b/options.c #ifdef MAINTAINER_MODE rprintf(f, "Panic Action: \"%s\"\n", get_panic_action()); -@@ -357,6 +362,9 @@ void usage(enum logcode F) +@@ -358,6 +363,9 @@ void usage(enum logcode F) rprintf(F," --fake-super store/recover privileged attrs using xattrs\n"); #endif rprintf(F," -S, --sparse handle sparse files efficiently\n"); @@ -131,15 +131,15 @@ diff --git a/options.c b/options.c rprintf(F," -n, --dry-run perform a trial run with no changes made\n"); rprintf(F," -W, --whole-file copy files whole (without delta-xfer algorithm)\n"); rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n"); -@@ -537,6 +545,7 @@ static struct poptOption long_options[] = { - {"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 }, - {"min-size", 0, POPT_ARG_STRING, &min_size_arg, OPT_MIN_SIZE, 0, 0 }, - {"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 }, +@@ -542,6 +550,7 @@ static struct poptOption long_options[] = { + {"sparse", 'S', POPT_ARG_VAL, &sparse_files, 1, 0, 0 }, + {"no-sparse", 0, POPT_ARG_VAL, &sparse_files, 0, 0, 0 }, + {"no-S", 0, POPT_ARG_VAL, &sparse_files, 0, 0, 0 }, + {"preallocate", 0, POPT_ARG_NONE, &preallocate_files, 0, 0, 0}, - {"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 }, + {"inplace", 0, POPT_ARG_VAL, &inplace, 1, 0, 0 }, + {"no-inplace", 0, POPT_ARG_VAL, &inplace, 0, 0, 0 }, {"append", 0, POPT_ARG_NONE, 0, OPT_APPEND, 0, 0 }, - {"append-verify", 0, POPT_ARG_VAL, &append_mode, 2, 0, 0 }, -@@ -2022,6 +2031,9 @@ void server_options(char **args, int *argc_p) +@@ -2048,6 +2057,9 @@ void server_options(char **args, int *argc_p) else if (remove_source_files) args[ac++] = "--remove-sent-files"; @@ -203,7 +203,7 @@ diff --git a/receiver.c b/receiver.c diff --git a/rsync.h b/rsync.h --- a/rsync.h +++ b/rsync.h -@@ -602,6 +602,13 @@ struct ht_int64_node { +@@ -604,6 +604,13 @@ struct ht_int64_node { #define ACLS_NEED_MASK 1 #endif @@ -228,7 +228,7 @@ diff --git a/rsync.yo b/rsync.yo -n, --dry-run perform a trial run with no changes made -W, --whole-file copy files whole (w/o delta-xfer algorithm) -x, --one-file-system don't cross filesystem boundaries -@@ -1036,6 +1037,18 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs" +@@ -1043,6 +1044,18 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs" filesystem. It doesn't seem to handle seeks over null regions correctly and ends up corrupting the files. @@ -261,8 +261,8 @@ diff --git a/syscall.c b/syscall.c extern int dry_run; extern int am_root; extern int read_only; -@@ -291,3 +295,21 @@ char *d_name(struct dirent *di) - return di->d_name; +@@ -282,3 +286,21 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence) + return lseek(fd, offset, whence); #endif } + diff --git a/remote-option.diff b/remote-option.diff new file mode 100644 index 0000000..16975c0 --- /dev/null +++ b/remote-option.diff @@ -0,0 +1,239 @@ +This patch implements a new --remote-option (-M) option that allows the +user to override certain settings on the remote system. For instance, it +is now easier to pass -M--fake-super or "-M --log-file=/tmp/foo" instead of +kluging up an --rsync-path setting. This also solves the case where we +want local --one-file-system (-x) but not remote ("-x -M--no-x"), or visa +versa ("-M-x"). + +To use this patch, run these commands for a successful build: + + patch -p1 = MAX_REMOTE_ARGS) { ++ rprintf(FERROR, "too many remote options specified.\n"); ++ exit_cleanup(RERR_SYNTAX); ++ } ++ remote_options[++remote_option_cnt] = arg; ++ break; ++ + case OPT_WRITE_BATCH: + /* batch_name is already set */ + write_batch = 1; +@@ -1826,6 +1846,11 @@ void server_options(char **args, int *argc_p) + #endif + argstr[x] = '\0'; + ++ if (x > (int)sizeof argstr) { /* Not possible... */ ++ rprintf(FERROR, "argstr overflow in server_options().\n"); ++ exit_cleanup(RERR_MALLOC); ++ } ++ + args[ac++] = argstr; + + #ifdef ICONV_OPTION +@@ -2048,6 +2073,21 @@ void server_options(char **args, int *argc_p) + else if (remove_source_files) + args[ac++] = "--remove-sent-files"; + ++ if (ac > MAX_SERVER_ARGS) { /* Not possible... */ ++ rprintf(FERROR, "argc overflow in server_options().\n"); ++ exit_cleanup(RERR_MALLOC); ++ } ++ ++ if (remote_option_cnt) { ++ int j; ++ if (ac + remote_option_cnt > MAX_SERVER_ARGS) { ++ rprintf(FERROR, "too many remote options specified.\n"); ++ exit_cleanup(RERR_SYNTAX); ++ } ++ for (j = 1; j <= remote_option_cnt; j++) ++ args[ac++] = (char*)remote_options[j]; ++ } ++ + *argc_p = ac; + return; + +diff --git a/pipe.c b/pipe.c +--- a/pipe.c ++++ b/pipe.c +@@ -22,12 +22,15 @@ + + #include "rsync.h" + ++extern int am_root; + extern int am_sender; + extern int am_server; + extern int blocking_io; + extern int filesfrom_fd; + extern mode_t orig_umask; + extern char *logfile_name; ++extern int remote_option_cnt; ++extern const char *remote_options[]; + extern struct chmod_mode_struct *chmod_modes; + + /** +@@ -139,6 +142,18 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out, + logfile_close(); + } + ++ if (am_root < 0) ++ am_root = 0; ++ ++ if (remote_option_cnt) { ++ int rc = remote_option_cnt + 1; ++ const char **rv = remote_options; ++ if (!parse_arguments(&rc, &rv)) { ++ option_error(); ++ exit_cleanup(RERR_SYNTAX); ++ } ++ } ++ + if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 || + close(to_child_pipe[1]) < 0 || + close(from_child_pipe[0]) < 0 || +diff --git a/rsync.yo b/rsync.yo +--- a/rsync.yo ++++ b/rsync.yo +@@ -412,6 +412,7 @@ to the detailed description below for a complete description. verb( + --progress show progress during transfer + -P same as --partial --progress + -i, --itemize-changes output a change-summary for all updates ++ -M, --remote-option=OPTION send OPTION to the remote side only + --out-format=FORMAT output updates using the specified FORMAT + --log-file=FILE log what we're doing to the specified FILE + --log-file-format=FMT log updates using the specified FMT +@@ -1020,16 +1021,13 @@ This is a good way to backup data without using a super-user, and to store + ACLs from incompatible systems. + + The bf(--fake-super) option only affects the side where the option is used. +-To affect the remote side of a remote-shell connection, specify an rsync +-path: ++To affect the remote side of a remote-shell connection, use the ++bf(--remote-option) (bf(-M)) option: + +-quote(tt( rsync -av --rsync-path="rsync --fake-super" /src/ host:/dest/)) ++quote(tt( rsync -av -M--fake-super /src/ host:/dest/)) + +-Since there is only one "side" in a local copy, this option affects both +-the sending and receiving of files. You'll need to specify a copy using +-"localhost" if you need to avoid this, possibly using the "lsh" shell +-script (from the support directory) as a substitute for an actual remote +-shell (see bf(--rsh)). ++For a local copy, this option affects only the source. Specify a ++bf(--remote-option) to affect the destination. + + This option is overridden by both bf(--super) and bf(--no-super). + +@@ -1275,6 +1273,36 @@ machine for use with the bf(--relative) option. For instance: + + quote(tt( rsync -avR --rsync-path="cd /a/b && rsync" host:c/d /e/)) + ++dit(bf(-M, --remote-option=OPTION)) This option is used for more advanced ++situations where you want certain effects to be limited to one side of the ++transfer only. For instance, if you want to pass bf(--log-file=FILE) and ++bf(--fake-super) to the remote system, specify it like this: ++ ++quote(tt( rsync -av -M --log-file=foo -M--fake-super src/ dest/)) ++ ++If you want to have an option affect only the local side of a transfer when ++it normally affects both sides, send its negation to the remote side. Like ++this: ++ ++quote(tt( rsync -av -x -M--no-x src/ dest/)) ++ ++Be cautious using this, as it is possible to toggle an option that will cause ++rsync to have a different idea about what data to expect next over the socket, ++and that will make it fail in a cryptic fashion. ++ ++Note that it is best to use a separate bf(--remote-option) for each option you ++want to pass. This makes your useage compatible with the bf(--preserve-spaces) ++option. If that option is off, any spaces in your remote options will be split ++by the remote shell unless you take steps to protect them. ++ ++When performing a local transfer, the "local" side is the sender and the ++"remote" side is the receiver. ++ ++Note some versions of the popt option-parsing library have a bug in them that ++prevents you from using an adjacent arg with an equal in it next to a short ++option letter (e.g. tt(-M--log-file=/tmp/foo). If this bug affects your ++version of popt, you can use the version of popt that is included with rsync. ++ + dit(bf(-C, --cvs-exclude)) This is a useful shorthand for excluding a + broad range of files that you often don't want to transfer between + systems. It uses a similar algorithm to CVS to determine if +@@ -1746,7 +1774,7 @@ option if you wish to override this. + Here's a example command that requests the remote side to log what is + happening: + +-verb( rsync -av --rsync-path="rsync --log-file=/tmp/rlog" src/ dest/) ++verb( rsync -av --remote-option=--log-file=/tmp/rlog src/ dest/) + + This is very useful if you need to debug why a connection is closing + unexpectedly. +diff --git a/testsuite/chown.test b/testsuite/chown.test +--- a/testsuite/chown.test ++++ b/testsuite/chown.test +@@ -16,7 +16,7 @@ + case $0 in + *fake*) + $RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync needs xattrs for fake device tests" +- RSYNC="$RSYNC --fake-super" ++ RSYNC="$RSYNC --fake-super -M--fake-super" + TLS_ARGS=--fake-super + case "`xattr 2>&1`" in + *--list:*) +diff --git a/testsuite/devices.test b/testsuite/devices.test +--- a/testsuite/devices.test ++++ b/testsuite/devices.test +@@ -17,7 +17,7 @@ outfile="$scratchdir/rsync.out" + case $0 in + *fake*) + $RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync needs xattrs for fake device tests" +- RSYNC="$RSYNC --fake-super" ++ RSYNC="$RSYNC --fake-super -M--fake-super" + TLS_ARGS=--fake-super + case "`xattr 2>&1`" in + *--list:*) diff --git a/slow-down.diff b/slow-down.diff index a889f7d..5855d5b 100644 --- a/slow-down.diff +++ b/slow-down.diff @@ -25,7 +25,7 @@ diff --git a/flist.c b/flist.c extern struct stats stats; extern char *filesfrom_host; -@@ -1502,6 +1503,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len, +@@ -1537,6 +1538,9 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len, } send_file_name(f, flist, fbuf, NULL, flags, filter_level); @@ -38,7 +38,7 @@ diff --git a/flist.c b/flist.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -108,6 +108,7 @@ int size_only = 0; +@@ -109,6 +109,7 @@ int size_only = 0; int daemon_bwlimit = 0; int bwlimit = 0; int fuzzy_basis = 0; @@ -46,7 +46,7 @@ diff --git a/options.c b/options.c size_t bwlimit_writemax = 0; int ignore_existing = 0; int ignore_non_existing = 0; -@@ -423,6 +424,7 @@ void usage(enum logcode F) +@@ -424,6 +425,7 @@ void usage(enum logcode F) rprintf(F," --password-file=FILE read daemon-access password from FILE\n"); rprintf(F," --list-only list the files instead of copying them\n"); rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n"); @@ -54,7 +54,7 @@ diff --git a/options.c b/options.c rprintf(F," --write-batch=FILE write a batched update to FILE\n"); rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n"); rprintf(F," --read-batch=FILE read a batched update from FILE\n"); -@@ -592,6 +594,7 @@ static struct poptOption long_options[] = { +@@ -604,6 +606,7 @@ static struct poptOption long_options[] = { {"itemize-changes", 'i', POPT_ARG_NONE, 0, 'i', 0, 0 }, {"no-itemize-changes",0, POPT_ARG_VAL, &itemize_changes, 0, 0, 0 }, {"no-i", 0, POPT_ARG_VAL, &itemize_changes, 0, 0, 0 }, diff --git a/slp.diff b/slp.diff index f509693..9832370 100644 --- a/slp.diff +++ b/slp.diff @@ -43,7 +43,7 @@ diff --git a/Makefile.in b/Makefile.in diff --git a/clientserver.c b/clientserver.c --- a/clientserver.c +++ b/clientserver.c -@@ -1032,6 +1032,13 @@ int daemon_main(void) +@@ -1068,6 +1068,13 @@ int daemon_main(void) * address too. In fact, why not just do inet_ntop on the * local address??? */ @@ -60,7 +60,7 @@ diff --git a/clientserver.c b/clientserver.c diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in -@@ -637,6 +637,29 @@ if test $rsync_cv_can_hardlink_special = yes; then +@@ -639,6 +639,29 @@ if test $rsync_cv_can_hardlink_special = yes; then AC_DEFINE(CAN_HARDLINK_SPECIAL, 1, [Define to 1 if link() can hard-link special files.]) fi @@ -126,7 +126,7 @@ diff --git a/loadparm.c b/loadparm.c diff --git a/main.c b/main.c --- a/main.c +++ b/main.c -@@ -1146,6 +1146,18 @@ static int start_client(int argc, char *argv[]) +@@ -1112,6 +1112,18 @@ static int start_client(int argc, char *argv[]) if (!read_batch) { /* for read_batch, NO source is specified */ char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port); @@ -148,7 +148,7 @@ diff --git a/main.c b/main.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -224,6 +224,7 @@ static void print_rsync_version(enum logcode f) +@@ -225,6 +225,7 @@ static void print_rsync_version(enum logcode f) char const *links = "no "; char const *iconv = "no "; char const *ipv6 = "no "; @@ -156,7 +156,7 @@ diff --git a/options.c b/options.c STRUCT_STAT *dumstat; #if SUBPROTOCOL_VERSION != 0 -@@ -256,6 +257,9 @@ static void print_rsync_version(enum logcode f) +@@ -257,6 +258,9 @@ static void print_rsync_version(enum logcode f) #if defined HAVE_LUTIMES && defined HAVE_UTIMES symtimes = ""; #endif @@ -166,7 +166,7 @@ diff --git a/options.c b/options.c rprintf(f, "%s version %s protocol version %d%s\n", RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol); -@@ -269,8 +273,8 @@ static void print_rsync_version(enum logcode f) +@@ -270,8 +274,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); @@ -180,7 +180,7 @@ diff --git a/options.c b/options.c diff --git a/rsync.h b/rsync.h --- a/rsync.h +++ b/rsync.h -@@ -187,6 +187,10 @@ +@@ -190,6 +190,10 @@ #define SIGNIFICANT_ITEM_FLAGS (~(\ ITEM_BASIS_TYPE_FOLLOWS | ITEM_XNAME_FOLLOWS | ITEM_LOCAL_CHANGE)) @@ -188,7 +188,7 @@ diff --git a/rsync.h b/rsync.h +/* definately don't set to less than about 30 seconds */ +#define SLP_MIN_TIMEOUT 120 + - #define CFN_KEEP_LEADING_DOT_DIR (1<<0) + #define CFN_KEEP_DOT_DIRS (1<<0) #define CFN_KEEP_TRAILING_SLASH (1<<1) #define CFN_DROP_TRAILING_DOT_DIR (1<<2) diff --git a/rsync.yo b/rsync.yo @@ -235,7 +235,7 @@ diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo enddit() -@@ -654,6 +663,7 @@ use chroot = yes +@@ -652,6 +661,7 @@ use chroot = yes max connections = 4 syslog facility = local5 pid file = /var/run/rsyncd.pid diff --git a/source-backup.diff b/source-backup.diff index 6356351..367a816 100644 --- a/source-backup.diff +++ b/source-backup.diff @@ -12,15 +12,15 @@ To use this patch, run these commands for a successful build: diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -32,6 +32,7 @@ extern struct filter_list_struct filter_list; - extern struct filter_list_struct server_filter_list; +@@ -33,6 +33,7 @@ extern struct filter_list_struct filter_list; + extern struct filter_list_struct daemon_filter_list; int make_backups = 0; +int make_source_backups = 0; /** * If 1, send the whole file as literal data rather than trying to -@@ -366,6 +367,7 @@ void usage(enum logcode F) +@@ -367,6 +368,7 @@ void usage(enum logcode F) rprintf(F," --existing skip creating new files on receiver\n"); rprintf(F," --ignore-existing skip updating files that already exist on receiver\n"); rprintf(F," --remove-source-files sender removes synchronized files (non-dirs)\n"); @@ -28,7 +28,7 @@ diff --git a/options.c b/options.c rprintf(F," --del an alias for --delete-during\n"); rprintf(F," --delete delete extraneous files from destination dirs\n"); rprintf(F," --delete-before receiver deletes before transfer, not during\n"); -@@ -595,6 +597,7 @@ static struct poptOption long_options[] = { +@@ -607,6 +609,7 @@ static struct poptOption long_options[] = { {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 }, {"no-bwlimit", 0, POPT_ARG_VAL, &bwlimit, 0, 0, 0 }, {"backup", 'b', POPT_ARG_VAL, &make_backups, 1, 0, 0 }, @@ -36,7 +36,7 @@ diff --git a/options.c b/options.c {"no-backup", 0, POPT_ARG_VAL, &make_backups, 0, 0, 0 }, {"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 }, {"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 }, -@@ -1925,6 +1928,8 @@ void server_options(char **args, int *argc_p) +@@ -1951,6 +1954,8 @@ void server_options(char **args, int *argc_p) goto oom; args[ac++] = arg; } @@ -56,7 +56,7 @@ diff --git a/rsync.yo b/rsync.yo --del an alias for --delete-during --delete delete extraneous files from dest dirs --delete-before receiver deletes before transfer (default) -@@ -1098,6 +1099,14 @@ dit(bf(--remove-source-files)) This tells rsync to remove from the sending +@@ -1105,6 +1106,14 @@ dit(bf(--remove-source-files)) This tells rsync to remove from the sending side the files (meaning non-directories) that are a part of the transfer and have been successfully duplicated on the receiving side. diff --git a/source-filter_dest-filter.diff b/source-filter_dest-filter.diff index cd6d0c7..45c51f1 100644 --- a/source-filter_dest-filter.diff +++ b/source-filter_dest-filter.diff @@ -33,7 +33,7 @@ To use this patch, run these commands for a successful build: diff --git a/generator.c b/generator.c --- a/generator.c +++ b/generator.c -@@ -63,6 +63,7 @@ extern int append_mode; +@@ -62,6 +62,7 @@ extern int append_mode; extern int make_backups; extern int csum_length; extern int ignore_times; @@ -41,7 +41,7 @@ diff --git a/generator.c b/generator.c extern int size_only; extern OFF_T max_size; extern OFF_T min_size; -@@ -696,7 +697,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre +@@ -708,7 +709,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) { @@ -53,7 +53,7 @@ diff --git a/generator.c b/generator.c diff --git a/main.c b/main.c --- a/main.c +++ b/main.c -@@ -139,7 +139,7 @@ pid_t wait_process(pid_t pid, int *status_ptr, int flags) +@@ -136,7 +136,7 @@ pid_t wait_process(pid_t pid, int *status_ptr, int flags) } /* Wait for a process to exit, calling io_flush while waiting. */ @@ -65,7 +65,7 @@ diff --git a/main.c b/main.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -105,6 +105,7 @@ int keep_partial = 0; +@@ -106,6 +106,7 @@ int keep_partial = 0; int safe_symlinks = 0; int copy_unsafe_links = 0; int size_only = 0; @@ -73,7 +73,7 @@ diff --git a/options.c b/options.c int daemon_bwlimit = 0; int bwlimit = 0; int fuzzy_basis = 0; -@@ -162,6 +163,8 @@ char *logfile_name = NULL; +@@ -163,6 +164,8 @@ char *logfile_name = NULL; char *logfile_format = NULL; char *stdout_format = NULL; char *password_file = NULL; @@ -82,7 +82,7 @@ diff --git a/options.c b/options.c char *rsync_path = RSYNC_PATH; char *backup_dir = NULL; char backup_dir_buf[MAXPATHLEN]; -@@ -387,6 +390,7 @@ void usage(enum logcode F) +@@ -388,6 +391,7 @@ void usage(enum logcode F) rprintf(F," --contimeout=SECONDS set daemon connection timeout in seconds\n"); rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n"); rprintf(F," --size-only skip files that match in size\n"); @@ -90,7 +90,7 @@ diff --git a/options.c b/options.c rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n"); rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n"); rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n"); -@@ -426,6 +430,8 @@ void usage(enum logcode F) +@@ -427,6 +431,8 @@ void usage(enum logcode F) rprintf(F," --write-batch=FILE write a batched update to FILE\n"); rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n"); rprintf(F," --read-batch=FILE read a batched update from FILE\n"); @@ -99,7 +99,7 @@ diff --git a/options.c b/options.c rprintf(F," --protocol=NUM force an older protocol version to be used\n"); #ifdef ICONV_OPTION rprintf(F," --iconv=CONVERT_SPEC request charset conversion of filenames\n"); -@@ -527,6 +533,7 @@ static struct poptOption long_options[] = { +@@ -530,6 +536,7 @@ static struct poptOption long_options[] = { {"chmod", 0, POPT_ARG_STRING, 0, OPT_CHMOD, 0, 0 }, {"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 }, {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 }, @@ -107,7 +107,7 @@ diff --git a/options.c b/options.c {"one-file-system", 'x', POPT_ARG_NONE, 0, 'x', 0, 0 }, {"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, {"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, -@@ -630,6 +637,8 @@ static struct poptOption long_options[] = { +@@ -645,6 +652,8 @@ static struct poptOption long_options[] = { {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 }, {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 }, {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 }, @@ -116,7 +116,7 @@ diff --git a/options.c b/options.c {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 }, {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 }, {"server", 0, POPT_ARG_NONE, 0, OPT_SERVER, 0, 0 }, -@@ -1608,6 +1617,16 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1634,6 +1643,16 @@ int parse_arguments(int *argc_p, const char ***argv_p) } } @@ -133,7 +133,7 @@ diff --git a/options.c b/options.c if (files_from) { char *h, *p; int q; -@@ -1927,6 +1946,25 @@ void server_options(char **args, int *argc_p) +@@ -1953,6 +1972,25 @@ void server_options(char **args, int *argc_p) } } @@ -314,7 +314,7 @@ diff --git a/receiver.c b/receiver.c diff --git a/rsync.h b/rsync.h --- a/rsync.h +++ b/rsync.h -@@ -133,6 +133,7 @@ +@@ -134,6 +134,7 @@ #define IOERR_DEL_LIMIT (1<<2) #define MAX_ARGS 1000 @@ -342,7 +342,7 @@ diff --git a/rsync.yo b/rsync.yo --protocol=NUM force an older protocol version to be used --iconv=CONVERT_SPEC request charset conversion of filenames --checksum-seed=NUM set block/file checksum seed (advanced) -@@ -2021,6 +2024,33 @@ file previously generated by bf(--write-batch). +@@ -2033,6 +2036,33 @@ file previously generated by bf(--write-batch). If em(FILE) is bf(-), the batch data will be read from standard input. See the "BATCH MODE" section for details. diff --git a/sparse-block.diff b/sparse-block.diff new file mode 100644 index 0000000..ba5da97 --- /dev/null +++ b/sparse-block.diff @@ -0,0 +1,107 @@ +This patch adds the --sparse-block option. Andrea Righi writes: + + In some filesystems, typically optimized for large I/O throughputs (like + IBM GPFS, IBM SAN FS, or distributed filesystems in general) a lot of + lseek() operations can strongly impact on performances. In this cases it + can be helpful to enlarge the block size used to handle sparse files + directly from a command line parameter. + + For example, using a sparse write size of 32KB, I've been able to + increase the transfer rate of an order of magnitude copying the output + files of scientific applications from GPFS to GPFS or GPFS to SAN FS. + + -Andrea + +To use this patch, run these commands for a successful build: + + patch -p1 0) { + int r1; + if (sparse_files > 0) { +- int len1 = MIN(len, SPARSE_WRITE_SIZE); ++ int len1 = MIN(len, (size_t)sparse_files_block_size); + r1 = write_sparse(f, buf, len1); + } else { + if (!wf_writeBuf) { +diff --git a/options.c b/options.c +--- a/options.c ++++ b/options.c +@@ -73,6 +73,7 @@ int remove_source_files = 0; + int one_file_system = 0; + int protocol_version = PROTOCOL_VERSION; + int sparse_files = 0; ++long sparse_files_block_size = SPARSE_WRITE_SIZE; + int do_compression = 0; + int def_compress_level = Z_DEFAULT_COMPRESSION; + int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */ +@@ -358,6 +359,7 @@ void usage(enum logcode F) + rprintf(F," --fake-super store/recover privileged attrs using xattrs\n"); + #endif + rprintf(F," -S, --sparse handle sparse files efficiently\n"); ++ rprintf(F," --sparse-block=SIZE set the block size used to handle sparse files\n"); + rprintf(F," -n, --dry-run perform a trial run with no changes made\n"); + rprintf(F," -W, --whole-file copy files whole (without delta-xfer algorithm)\n"); + rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n"); +@@ -542,6 +544,7 @@ static struct poptOption long_options[] = { + {"sparse", 'S', POPT_ARG_VAL, &sparse_files, 1, 0, 0 }, + {"no-sparse", 0, POPT_ARG_VAL, &sparse_files, 0, 0, 0 }, + {"no-S", 0, POPT_ARG_VAL, &sparse_files, 0, 0, 0 }, ++ {"sparse-block", 0, POPT_ARG_LONG, &sparse_files_block_size, 0, 0, 0 }, + {"inplace", 0, POPT_ARG_VAL, &inplace, 1, 0, 0 }, + {"no-inplace", 0, POPT_ARG_VAL, &inplace, 0, 0, 0 }, + {"append", 0, POPT_ARG_NONE, 0, OPT_APPEND, 0, 0 }, +@@ -1885,6 +1888,12 @@ void server_options(char **args, int *argc_p) + args[ac++] = arg; + } + ++ if (sparse_files_block_size) { ++ if (asprintf(&arg, "--sparse-block=%lu", sparse_files_block_size) < 0) ++ goto oom; ++ args[ac++] = arg; ++ } ++ + if (io_timeout) { + if (asprintf(&arg, "--timeout=%d", io_timeout) < 0) + goto oom; +diff --git a/rsync.yo b/rsync.yo +--- a/rsync.yo ++++ b/rsync.yo +@@ -352,6 +352,7 @@ to the detailed description below for a complete description. verb( + --super receiver attempts super-user activities + --fake-super store/recover privileged attrs using xattrs + -S, --sparse handle sparse files efficiently ++ --sparse-block=SIZE set block size used to handle sparse files + -n, --dry-run perform a trial run with no changes made + -W, --whole-file copy files whole (w/o delta-xfer algorithm) + -x, --one-file-system don't cross filesystem boundaries +@@ -1043,6 +1044,15 @@ NOTE: Don't use this option when the destination is a Solaris "tmpfs" + filesystem. It doesn't seem to handle seeks over null regions + correctly and ends up corrupting the files. + ++dit(bf(--sparse-block=SIZE)) Change the block size used to handle sparse files ++to SIZE bytes. This option only has an effect if the bf(--sparse) (bf(-S)) ++option was also specified. The default block size used by rsync to detect a ++file hole is 1024 bytes; when the receiver writes data to the destination file ++and option bf(--sparse) is used, rsync checks every 1024-bytes chunk to detect ++if they are actually filled with data or not. With certain filesystems, ++optimized to receive data streams for example, enlarging this block size can ++strongly increase performance. The option can be used to tune this block size. ++ + dit(bf(-n, --dry-run)) This makes rsync perform a trial run that doesn't + make any changes (and produces mostly the same output as a real run). It + is most commonly used in combination with the bf(-v, --verbose) and/or diff --git a/stdout.diff b/stdout.diff index 9a7280c..1ce8ab9 100644 --- a/stdout.diff +++ b/stdout.diff @@ -10,7 +10,7 @@ To use this patch, run these commands for a successful build: diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -203,6 +203,7 @@ static int refused_delete, refused_archive_part, refused_compress; +@@ -204,6 +204,7 @@ static int refused_delete, refused_archive_part, refused_compress; static int refused_partial, refused_progress, refused_delete_before; static int refused_delete_during; static int refused_inplace, refused_no_iconv; @@ -18,7 +18,7 @@ diff --git a/options.c b/options.c static char *max_size_arg, *min_size_arg; static char tmp_partialdir[] = ".~tmp~"; -@@ -423,6 +424,7 @@ void usage(enum logcode F) +@@ -424,6 +425,7 @@ void usage(enum logcode F) rprintf(F," --password-file=FILE read daemon-access password from FILE\n"); rprintf(F," --list-only list the files instead of copying them\n"); rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n"); @@ -26,7 +26,7 @@ diff --git a/options.c b/options.c rprintf(F," --write-batch=FILE write a batched update to FILE\n"); rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n"); rprintf(F," --read-batch=FILE read a batched update from FILE\n"); -@@ -630,6 +632,7 @@ static struct poptOption long_options[] = { +@@ -645,6 +647,7 @@ static struct poptOption long_options[] = { {"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 }, {"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 }, {"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 }, @@ -34,7 +34,7 @@ diff --git a/options.c b/options.c {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 }, {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 }, {"server", 0, POPT_ARG_NONE, 0, OPT_SERVER, 0, 0 }, -@@ -1259,6 +1262,13 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1275,6 +1278,13 @@ int parse_arguments(int *argc_p, const char ***argv_p) } } diff --git a/time-limit.diff b/time-limit.diff index fb6c36c..0c76ec2 100644 --- a/time-limit.diff +++ b/time-limit.diff @@ -12,7 +12,7 @@ To use this patch, run these commands for a successful build: diff --git a/io.c b/io.c --- a/io.c +++ b/io.c -@@ -53,6 +53,7 @@ extern int protocol_version; +@@ -54,6 +54,7 @@ extern int protocol_version; extern int remove_source_files; extern int preserve_hard_links; extern struct stats stats; @@ -20,7 +20,7 @@ diff --git a/io.c b/io.c extern struct file_list *cur_flist; #ifdef ICONV_OPTION extern int filesfrom_convert; -@@ -216,16 +217,24 @@ static void check_timeout(void) +@@ -221,16 +222,24 @@ static void check_timeout(void) { time_t t; @@ -51,7 +51,7 @@ diff --git a/io.c b/io.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -112,6 +112,7 @@ size_t bwlimit_writemax = 0; +@@ -113,6 +113,7 @@ size_t bwlimit_writemax = 0; int ignore_existing = 0; int ignore_non_existing = 0; int need_messages_from_generator = 0; @@ -59,7 +59,7 @@ diff --git a/options.c b/options.c int max_delete = INT_MIN; OFF_T max_size = 0; OFF_T min_size = 0; -@@ -423,6 +424,8 @@ void usage(enum logcode F) +@@ -424,6 +425,8 @@ void usage(enum logcode F) rprintf(F," --password-file=FILE read daemon-access password from FILE\n"); rprintf(F," --list-only list the files instead of copying them\n"); rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n"); @@ -68,7 +68,7 @@ diff --git a/options.c b/options.c rprintf(F," --write-batch=FILE write a batched update to FILE\n"); rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n"); rprintf(F," --read-batch=FILE read a batched update from FILE\n"); -@@ -445,7 +448,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, +@@ -446,7 +449,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, @@ -77,16 +77,16 @@ diff --git a/options.c b/options.c OPT_SERVER, OPT_REFUSED_BASE = 9000}; static struct poptOption long_options[] = { -@@ -613,6 +616,8 @@ static struct poptOption long_options[] = { - {"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 }, +@@ -626,6 +629,8 @@ static struct poptOption long_options[] = { {"no-timeout", 0, POPT_ARG_VAL, &io_timeout, 0, 0, 0 }, {"contimeout", 0, POPT_ARG_INT, &connect_timeout, 0, 0, 0 }, + {"no-contimeout", 0, POPT_ARG_VAL, &connect_timeout, 0, 0, 0 }, + {"stop-at", 0, POPT_ARG_STRING, 0, OPT_STOP_AT, 0, 0 }, + {"time-limit", 0, POPT_ARG_STRING, 0, OPT_TIME_LIMIT, 0, 0 }, {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 }, {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 }, {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 }, -@@ -1244,6 +1249,36 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) +@@ -1260,6 +1265,36 @@ int parse_arguments(int *argc_p, const char ***argv_p) return 0; #endif @@ -123,7 +123,7 @@ diff --git a/options.c b/options.c default: /* A large opt value means that set_refuse_options() * turned this option off. */ -@@ -1871,6 +1906,15 @@ void server_options(char **args, int *argc_p) +@@ -1897,6 +1932,15 @@ void server_options(char **args, int *argc_p) args[ac++] = arg; } @@ -151,7 +151,7 @@ diff --git a/rsync.yo b/rsync.yo --write-batch=FILE write a batched update to FILE --only-write-batch=FILE like --write-batch but w/o updating dest --read-batch=FILE read a batched update from FILE -@@ -1995,6 +1997,19 @@ transfer was too fast, it will wait before sending the next data block. The +@@ -2007,6 +2009,19 @@ transfer was too fast, it will wait before sending the next data block. The result is an average transfer rate equaling the specified limit. A value of zero specifies no limit. diff --git a/transliterate.diff b/transliterate.diff index 47f5f00..eeb12cc 100644 --- a/transliterate.diff +++ b/transliterate.diff @@ -26,7 +26,7 @@ diff --git a/flist.c b/flist.c #define PTR_SIZE (sizeof (struct file_struct *)) int io_error; -@@ -607,6 +610,24 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ +@@ -642,6 +645,24 @@ static void send_file_entry(int f, struct file_struct *file, int ndx, int first_ stats.total_size += F_LENGTH(file); } @@ -51,7 +51,7 @@ diff --git a/flist.c b/flist.c static struct file_struct *recv_file_entry(struct file_list *flist, int xflags, int f) { -@@ -675,6 +696,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist, +@@ -710,6 +731,9 @@ static struct file_struct *recv_file_entry(struct file_list *flist, } #endif @@ -64,7 +64,7 @@ diff --git a/flist.c b/flist.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -183,6 +183,8 @@ int logfile_format_has_i = 0; +@@ -184,6 +184,8 @@ int logfile_format_has_i = 0; int logfile_format_has_o_or_i = 0; int always_checksum = 0; int list_only = 0; @@ -73,7 +73,7 @@ diff --git a/options.c b/options.c #define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */ char *batch_name = NULL; -@@ -430,6 +432,7 @@ void usage(enum logcode F) +@@ -431,6 +433,7 @@ void usage(enum logcode F) #ifdef ICONV_OPTION rprintf(F," --iconv=CONVERT_SPEC request charset conversion of filenames\n"); #endif @@ -81,15 +81,15 @@ diff --git a/options.c b/options.c rprintf(F," -4, --ipv4 prefer IPv4\n"); rprintf(F," -6, --ipv6 prefer IPv6\n"); rprintf(F," --version print version number\n"); -@@ -620,6 +623,7 @@ static struct poptOption long_options[] = { +@@ -633,6 +636,7 @@ static struct poptOption long_options[] = { {"iconv", 0, POPT_ARG_STRING, &iconv_opt, 0, 0, 0 }, {"no-iconv", 0, POPT_ARG_NONE, 0, OPT_NO_ICONV, 0, 0 }, #endif + {"tr", 0, POPT_ARG_STRING, &tr_opt, 0, 0, 0 }, {"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 }, {"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 }, - {"8-bit-output", '8', POPT_ARG_NONE, &allow_8bit_chars, 0, 0, 0 }, -@@ -1654,6 +1658,31 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain) + {"8-bit-output", '8', POPT_ARG_VAL, &allow_8bit_chars, 1, 0, 0 }, +@@ -1680,6 +1684,31 @@ int parse_arguments(int *argc_p, const char ***argv_p) } } @@ -121,7 +121,7 @@ diff --git a/options.c b/options.c am_starting_up = 0; return 1; -@@ -2022,6 +2051,12 @@ void server_options(char **args, int *argc_p) +@@ -2048,6 +2077,12 @@ void server_options(char **args, int *argc_p) else if (remove_source_files) args[ac++] = "--remove-sent-files"; @@ -145,7 +145,7 @@ diff --git a/rsync.yo b/rsync.yo --checksum-seed=NUM set block/file checksum seed (advanced) -4, --ipv4 prefer IPv4 -6, --ipv6 prefer IPv6 -@@ -2059,6 +2060,22 @@ daemon uses the charset specified in its "charset" configuration parameter +@@ -2071,6 +2072,22 @@ daemon uses the charset specified in its "charset" configuration parameter regardless of the remote charset you actually pass. Thus, you may feel free to specify just the local charset for a daemon transfer (e.g. bf(--iconv=utf8)). diff --git a/usermap.diff b/usermap.diff index a6128a0..f5d2b1c 100644 --- a/usermap.diff +++ b/usermap.diff @@ -18,7 +18,7 @@ diff --git a/flist.c b/flist.c extern char curr_dir[MAXPATHLEN]; -@@ -754,7 +755,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, +@@ -789,7 +790,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, uid = (uid_t)read_varint(f); if (xflags & XMIT_USER_NAME_FOLLOWS) uid = recv_user_name(f, uid); @@ -27,7 +27,7 @@ diff --git a/flist.c b/flist.c uid = match_uid(uid); } } -@@ -766,7 +767,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, +@@ -801,7 +802,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, gid_flags = 0; if (xflags & XMIT_GROUP_NAME_FOLLOWS) gid = recv_group_name(f, gid, &gid_flags); @@ -36,7 +36,7 @@ diff --git a/flist.c b/flist.c gid = match_gid(gid, &gid_flags); } } -@@ -2087,8 +2088,13 @@ struct file_list *recv_file_list(int f) +@@ -2142,8 +2143,13 @@ struct file_list *recv_file_list(int f) int dstart, flags; int64 start_read; @@ -54,7 +54,7 @@ diff --git a/flist.c b/flist.c diff --git a/options.c b/options.c --- a/options.c +++ b/options.c -@@ -166,6 +166,8 @@ char *rsync_path = RSYNC_PATH; +@@ -167,6 +167,8 @@ char *rsync_path = RSYNC_PATH; char *backup_dir = NULL; char backup_dir_buf[MAXPATHLEN]; char *sockopts = NULL; @@ -63,7 +63,7 @@ diff --git a/options.c b/options.c int rsync_port = 0; int compare_dest = 0; int copy_dest = 0; -@@ -383,6 +385,8 @@ void usage(enum logcode F) +@@ -384,6 +386,8 @@ void usage(enum logcode F) rprintf(F," --delay-updates put all updated files into place at transfer's end\n"); rprintf(F," -m, --prune-empty-dirs prune empty directory chains from the file-list\n"); rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n"); @@ -72,7 +72,7 @@ diff --git a/options.c b/options.c rprintf(F," --timeout=SECONDS set I/O timeout in seconds\n"); rprintf(F," --contimeout=SECONDS set daemon connection timeout in seconds\n"); rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n"); -@@ -610,6 +614,8 @@ static struct poptOption long_options[] = { +@@ -622,6 +626,8 @@ static struct poptOption long_options[] = { {"no-s", 0, POPT_ARG_VAL, &protect_args, 0, 0, 0}, {"numeric-ids", 0, POPT_ARG_VAL, &numeric_ids, 1, 0, 0 }, {"no-numeric-ids", 0, POPT_ARG_VAL, &numeric_ids, 0, 0, 0 }, @@ -81,7 +81,7 @@ diff --git a/options.c b/options.c {"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 }, {"no-timeout", 0, POPT_ARG_VAL, &io_timeout, 0, 0, 0 }, {"contimeout", 0, POPT_ARG_INT, &connect_timeout, 0, 0, 0 }, -@@ -1965,6 +1971,18 @@ void server_options(char **args, int *argc_p) +@@ -1991,6 +1997,18 @@ void server_options(char **args, int *argc_p) args[ac++] = "--use-qsort"; if (am_sender) { @@ -112,7 +112,7 @@ diff --git a/rsync.yo b/rsync.yo --timeout=SECONDS set I/O timeout in seconds --contimeout=SECONDS set daemon connection timeout in seconds -I, --ignore-times don't skip files that match size and time -@@ -1595,6 +1597,46 @@ from the source system is used instead. See also the comments on the +@@ -1602,6 +1604,46 @@ from the source system is used instead. See also the comments on the the chroot setting affects rsync's ability to look up the names of the users and groups and what you can do about it. diff --git a/xattrs.diff b/xattrs.diff index c9465e7..1fd2934 100644 --- a/xattrs.diff +++ b/xattrs.diff @@ -46,7 +46,7 @@ diff --git a/xattrs.c b/xattrs.c #define RSYNC_XAL_INITIAL 5 #define RSYNC_XAL_LIST_INITIAL 100 -@@ -239,7 +241,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp) +@@ -245,7 +247,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp) if (!(ptr = get_xattr_data(fname, name, &datum_len, 0))) return -1; @@ -55,7 +55,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); -@@ -307,7 +309,7 @@ static int find_matching_xattr(item_list *xalp) +@@ -305,7 +307,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; @@ -64,7 +64,7 @@ diff --git a/xattrs.c b/xattrs.c if (memcmp(rxas1[j].datum + 1, rxas2[j].datum + 1, MAX_DIGEST_LEN) != 0) -@@ -344,34 +346,43 @@ int send_xattr(stat_x *sxp, int f) +@@ -342,13 +344,22 @@ int send_xattr(stat_x *sxp, int f) { int ndx = find_matching_xattr(sxp->xattr); @@ -88,37 +88,29 @@ diff --git a/xattrs.c b/xattrs.c - write_varint(f, count); + write_varint30(f, count); for (rxa = sxp->xattr->items; count--; rxa++) { - #ifdef HAVE_LINUX_XATTRS -- write_varint(f, rxa->name_len); + size_t name_len = rxa->name_len; + const char *name = rxa->name; +@@ -367,8 +378,8 @@ int send_xattr(stat_x *sxp, int f) + name_len += UPRE_LEN; + } + #endif +- write_varint(f, name_len); - write_varint(f, rxa->datum_len); -+ write_varint30(f, rxa->name_len); ++ write_varint30(f, name_len); + write_varint30(f, rxa->datum_len); - write_buf(f, rxa->name, rxa->name_len); - #else - /* We strip the rsync prefix from disguised namespaces - * and put everything else in the user namespace. */ - if (HAS_PREFIX(rxa->name, RSYNC_PREFIX) - && rxa->name[RPRE_LEN] != '%') { -- write_varint(f, rxa->name_len - RPRE_LEN); -- write_varint(f, rxa->datum_len); -+ write_varint30(f, rxa->name_len - RPRE_LEN); -+ write_varint30(f, rxa->datum_len); - write_buf(f, rxa->name + RPRE_LEN, rxa->name_len - RPRE_LEN); - } else { -- write_varint(f, rxa->name_len + UPRE_LEN); -- write_varint(f, rxa->datum_len); -+ write_varint30(f, rxa->name_len + UPRE_LEN); -+ write_varint30(f, rxa->datum_len); + #ifndef HAVE_LINUX_XATTRS + if (name_len > rxa->name_len) { write_buf(f, USER_PREFIX, UPRE_LEN); - write_buf(f, rxa->name, rxa->name_len); +@@ -376,7 +387,7 @@ int send_xattr(stat_x *sxp, int f) } #endif + write_buf(f, name, name_len); - if (rxa->datum_len > MAX_FULL_DATUM) + 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); -@@ -421,7 +432,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all) +@@ -426,7 +437,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; @@ -127,7 +119,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; -@@ -464,6 +475,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out) +@@ -469,6 +480,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out) int cnt, prior_req = 0; rsync_xa *rxa; @@ -137,7 +129,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) -@@ -518,6 +532,9 @@ int recv_xattr_request(struct file_struct *file, int f_in) +@@ -523,6 +537,9 @@ int recv_xattr_request(struct file_struct *file, int f_in) rsync_xa *rxa; int rel_pos, cnt, num, got_xattr_data = 0; @@ -147,10 +139,10 @@ 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_STREAMIO); -@@ -574,7 +591,22 @@ void receive_xattr(struct file_struct *file, int f) - { - static item_list temp_xattr = EMPTY_ITEM_LIST; - int count, num; +@@ -584,7 +601,22 @@ void receive_xattr(struct file_struct *file, int f) + #else + int need_sort = 1; + #endif - int ndx = read_varint(f); + int ndx; + @@ -171,7 +163,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" -@@ -587,7 +619,7 @@ void receive_xattr(struct file_struct *file, int f) +@@ -597,7 +629,7 @@ void receive_xattr(struct file_struct *file, int f) return; } @@ -180,7 +172,7 @@ diff --git a/xattrs.c b/xattrs.c (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count); temp_xattr.count = 0; } -@@ -595,9 +627,10 @@ void receive_xattr(struct file_struct *file, int f) +@@ -605,9 +637,10 @@ void receive_xattr(struct file_struct *file, int f) for (num = 1; num <= count; num++) { char *ptr, *name; rsync_xa *rxa; -- 2.34.1