diff -Naur rsync-3.0.3_base/acls.c rsync-3.0.3/acls.c --- rsync-3.0.3_base/acls.c 2008-03-01 14:01:41.000000000 -0600 +++ rsync-3.0.3/acls.c 2008-07-06 21:20:28.000000000 -0500 @@ -929,8 +929,11 @@ } else { mode_t cur_mode = sxp->st.st_mode; if (!duo_item->sacl - && !pack_smb_acl(&duo_item->sacl, &duo_item->racl)) + && !pack_smb_acl(&duo_item->sacl, &duo_item->racl)) { + // BOMBICH + rprintf(FERROR, "Failed to set ACL for: %s\n", fname); return -1; + } #ifdef HAVE_OSX_ACLS mode = 0; /* eliminate compiler warning */ #else diff -Naur rsync-3.0.3_base/backup.c rsync-3.0.3/backup.c --- rsync-3.0.3_base/backup.c 2008-06-30 20:27:28.000000000 -0500 +++ rsync-3.0.3/backup.c 2008-06-30 20:39:11.000000000 -0500 @@ -293,26 +293,11 @@ do_unlink(fname); } + // BOMBICH if (!kept && S_ISDIR(file->mode)) { - /* make an empty directory */ - if (do_mkdir(buf, file->mode) < 0) { - int save_errno = errno ? errno : EINVAL; /* 0 paranoia */ - if (errno == ENOENT && make_bak_dir(buf) == 0) { - if (do_mkdir(buf, file->mode) < 0) - save_errno = errno ? errno : save_errno; - else - save_errno = 0; - } - if (save_errno) { - rsyserr(FINFO, save_errno, "mkdir %s failed", - full_fname(buf)); - } - } - - ret_code = do_rmdir(fname); - if (verbose > 2) { - rprintf(FINFO, "make_backup: RMDIR %s returns %i\n", - full_fname(fname), ret_code); + if (robust_move(fname, buf) != 0) { + rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"", + full_fname(fname), full_fname(buf)); } kept = 1; } diff -Naur rsync-3.0.3_base/byteorder.h rsync-3.0.3/byteorder.h --- rsync-3.0.3_base/byteorder.h 2008-03-01 14:01:41.000000000 -0600 +++ rsync-3.0.3/byteorder.h 2008-06-30 20:39:11.000000000 -0500 @@ -18,10 +18,9 @@ * with this program; if not, visit the http://fsf.org website. */ -#undef CAREFUL_ALIGNMENT - /* We know that the x86 can handle misalignment and has the same * byte order (LSB-first) as the 32-bit numbers we transmit. */ +/* #ifdef __i386__ #define CAREFUL_ALIGNMENT 0 #endif @@ -29,6 +28,9 @@ #ifndef CAREFUL_ALIGNMENT #define CAREFUL_ALIGNMENT 1 #endif +*/ + +#define CAREFUL_ALIGNMENT 1 #define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) #define UVAL(buf,pos) ((uint32)CVAL(buf,pos)) diff -Naur rsync-3.0.3_base/config.h rsync-3.0.3/config.h --- rsync-3.0.3_base/config.h 2008-06-30 20:29:08.000000000 -0500 +++ rsync-3.0.3/config.h 2008-06-30 20:39:11.000000000 -0500 @@ -169,7 +169,7 @@ #define HAVE_LANGINFO_H 1 /* Define to 1 if you have the `lchmod' function. */ -#define HAVE_LCHMOD 1 +/* #undef HAVE_LCHMOD */ /* Define to 1 if you have the `lchown' function. */ #define HAVE_LCHOWN 1 @@ -228,7 +228,7 @@ /* #undef HAVE_LSEEK64 */ /* Define to 1 if you have the `lutimes' function. */ -#define HAVE_LUTIMES 1 +/* #undef HAVE_LUTIMES */ /* Define to 1 if you have the `mallinfo' function. */ /* #undef HAVE_MALLINFO */ @@ -672,3 +672,6 @@ /* Define to `int' if doesn't define. */ /* #undef uid_t */ + +// BOMBICH +#define PARSEABLE_OUTPUT 1 \ No newline at end of file diff -Naur rsync-3.0.3_base/flist.c rsync-3.0.3/flist.c --- rsync-3.0.3_base/flist.c 2008-06-30 20:27:24.000000000 -0500 +++ rsync-3.0.3/flist.c 2008-09-29 09:47:34.000000000 -0500 @@ -160,18 +160,30 @@ static void maybe_emit_filelist_progress(int count) { +// BOMBICH +#ifdef PARSEABLE_OUTPUT + if (!inc_recurse && xfer_dirs && !am_server && (count % 100) == 0 && count > 0) + rprintf(FINFO, "S;;;BFL;;;NOF;;;%d\n", count); +#else if (do_progress && show_filelist_p() && (count % 100) == 0) emit_filelist_progress(count); +#endif } static void finish_filelist_progress(const struct file_list *flist) { +// BOMBICH +#ifdef PARSEABLE_OUTPUT + if (!inc_recurse) + rprintf(FINFO, "S;;;FTC;;;NOF;;;%d;;;BT;;;%.3f\n", flist->used, (double)stats.flist_buildtime/1000); +#else if (do_progress) { /* This overwrites the progress line */ rprintf(FINFO, "%d file%sto consider\n", flist->used, flist->used == 1 ? " " : "s "); } else rprintf(FINFO, "done\n"); +#endif } void show_flist_stats(void) @@ -540,8 +552,11 @@ if (first_hlink_ndx >= 0) { write_varint(f, first_hlink_ndx); - if (first_hlink_ndx >= first_ndx) - goto the_end; + if (first_hlink_ndx >= first_ndx) { + // BOMBICH + stats.hard_links_not_copied++; + goto the_end; + } } write_varlong30(f, F_LENGTH(file), 3); @@ -640,6 +655,20 @@ if (S_ISREG(mode) || S_ISLNK(mode)) stats.total_size += F_LENGTH(file); + + // BOMBICH + // Maintain stats on the sender side + if (S_ISDIR(mode)) + stats.num_dirs++; + else if (S_ISREG(mode)) + stats.num_reg_files++; + else if (S_ISLNK(mode)) + stats.num_symlinks++; + else if (IS_DEVICE(mode)) + stats.num_devices++; + else if (IS_SPECIAL(mode)) + stats.num_special++; + } static struct file_struct *recv_file_entry(struct file_list *flist, @@ -746,6 +775,7 @@ struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start]; file_length = F_LENGTH(first); modtime = first->modtime; + if (crtimes_ndx) crtime=f_crtime(first); mode = first->mode; if (preserve_uid) uid = F_OWNER(first); @@ -1067,6 +1097,16 @@ if (S_ISREG(mode) || S_ISLNK(mode)) stats.total_size += file_length; + if (who_am_i() == "generator") { + // Maintain stats on the receiver side. This is for the benefit of the + // generator -- the receive generator prints out non-transfer related + // progress info several times a second. Having the number of reg_files + // is helpful for progess indication + // BOMBICH + if (S_ISDIR(mode)) + stats.num_dirs++; + } + return file; } @@ -1363,6 +1403,19 @@ if (!file) return NULL; +// rprintf(FINFO, "make_file (%s): %s\n", who_am_i()); +// // BOMBICH +// if (S_ISDIR(file->mode)) +// stats.num_dirs++; +// else if (S_ISREG(file->mode)) +// stats.num_reg_files++; +// else if (S_ISLNK(file->mode)) +// stats.num_symlinks++; +// else if (IS_DEVICE(file->mode)) +// stats.num_devices++; +// else if (IS_SPECIAL(file->mode)) +// stats.num_special++; +// if (chmod_modes && !S_ISLNK(file->mode)) file->mode = tweak_mode(file->mode, chmod_modes); @@ -1942,6 +1995,14 @@ else if (inc_recurse && verbose && !am_server) rprintf(FCLIENT, "sending incremental file list\n"); + // BOMBICH + stats.num_dirs = 0; + stats.num_reg_files = 0; + stats.num_symlinks = 0; + stats.num_devices = 0; + stats.num_special = 0; + stats.hard_links_not_copied = 0; + start_write = stats.total_written; gettimeofday(&start_tv, NULL); @@ -2174,7 +2235,10 @@ idev_destroy(); #endif +// BOMBICH +#ifndef PARSEABLE_OUTPUT if (show_filelist_p()) +#endif finish_filelist_progress(flist); gettimeofday(&end_tv, NULL); @@ -2254,6 +2318,10 @@ else if (inc_recurse && verbose && !am_server && !first_flist) rprintf(FCLIENT, "receiving incremental file list\n"); + // BOMBICH + if (!first_flist) + stats.num_dirs = 0; + start_read = stats.total_read; #ifdef SUPPORT_HARD_LINKS diff -Naur rsync-3.0.3_base/generator.c rsync-3.0.3/generator.c --- rsync-3.0.3_base/generator.c 2008-06-30 20:27:28.000000000 -0500 +++ rsync-3.0.3/generator.c 2008-09-28 21:25:58.000000000 -0500 @@ -121,6 +121,14 @@ static int need_retouch_dir_times; static int need_retouch_dir_perms; static const char *solo_file = NULL; + +// BOMBICH +struct timeval last_update; +static unsigned long msdiff(struct timeval *t1, struct timeval *t2) +{ + return (t2->tv_sec - t1->tv_sec) * 1000L + + (t2->tv_usec - t1->tv_usec) / 1000; +} /* For calling delete_item() and delete_dir_contents(). */ #define DEL_NO_UID_WRITE (1<<0) /* file/dir has our uid w/o write perm */ @@ -177,6 +185,12 @@ fbuf, (int)mode, (int)flags); } + // BOMBICH + if (S_ISDIR(mode) && make_backups > 0) { + ret = make_backup(fbuf); + goto check_ret; + } + if (flags & DEL_NO_UID_WRITE) do_chmod(fbuf, mode | S_IWUSR, NO_FFLAGS); @@ -534,7 +548,8 @@ /* If an item in dirlist is not found in flist, delete it * from the filesystem. */ - for (i = dirlist->used; i--; ) { + // BOMBICH + for (i = 0; i < dirlist->used; i++ ) { struct file_struct *fp = dirlist->files[i]; if (!F_IS_ACTIVE(fp)) continue; @@ -1789,6 +1804,28 @@ fnamecmp = fname; fnamecmp_type = FNAMECMP_FNAME; +// BOMBICH +#ifdef PARSEABLE_OUTPUT + struct timeval now; + gettimeofday(&now, NULL); + + // The Recv generator gets a list of every single file sent by the sender whether it will + // eventually be copied or not. Here we optionally print out the current file that is being + // received for consideration to give the user a general idea of where rsync is within their fs + + // Print update information every fifth of a second. If a file changed, print update + // information as long as the file is larger than 32K or time since last update > tenth of a second + unsigned long time_diff = msdiff(&last_update, &now); + int fileUnchanged = unchanged_file(fnamecmpbuf, file, &sx.st); + if ((fileUnchanged && time_diff > 200) || (!fileUnchanged && (file->len32 > 32768 || time_diff > 100))) { + last_update = now; + if (inc_recurse) + rprintf(FINFO, "S;;;CP;;;NOI;;;%d;;;CF;;;%s\n", stats.num_files - stats.num_dirs, fname); + else + rprintf(FINFO, "S;;;CP;;;PROG;;;%d;;;CF;;;%s\n", (ndx * 100) / stats.num_files, fname); + } +#endif + if (statret == 0 && !S_ISREG(sx.st.st_mode)) { if (delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_FILE) != 0) goto cleanup; diff -Naur rsync-3.0.3_base/hlink.c rsync-3.0.3/hlink.c --- rsync-3.0.3_base/hlink.c 2008-04-28 23:17:36.000000000 -0500 +++ rsync-3.0.3/hlink.c 2008-09-27 16:14:20.000000000 -0500 @@ -30,6 +30,7 @@ extern int do_xfers; extern int link_dest; extern int preserve_acls; +extern int preserve_xattrs; extern int make_backups; extern int protocol_version; extern int remove_source_files; @@ -367,6 +368,9 @@ #ifdef SUPPORT_ACLS alt_sx.acc_acl = alt_sx.def_acl = NULL; #endif +#ifdef SUPPORT_XATTRS + alt_sx.xattr = NULL; +#endif do { pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname); if (link_stat(cmpbuf, &alt_sx.st, 0) < 0) @@ -395,19 +399,37 @@ sxp->st = alt_sx.st; #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { - if (!ACL_READY(*sxp)) + free_acl(sxp); + if (!ACL_READY(alt_sx)) get_acl(cmpbuf, sxp); else { sxp->acc_acl = alt_sx.acc_acl; sxp->def_acl = alt_sx.def_acl; + alt_sx.acc_acl = alt_sx.def_acl = NULL; } } #endif - } +#ifdef SUPPORT_XATTRS + if (preserve_xattrs) { + free_xattr(sxp); + if (!XATTR_READY(alt_sx)) + get_xattr(cmpbuf, sxp); + else { + sxp->xattr = alt_sx.xattr; + alt_sx.xattr = NULL; + } + } +#endif + } else { #ifdef SUPPORT_ACLS - else if (preserve_acls) - free_acl(&alt_sx); + if (preserve_acls) + free_acl(&alt_sx); +#endif +#ifdef SUPPORT_XATTRS + if (preserve_xattrs) + free_xattr(&alt_sx); #endif + } } if (maybe_hard_link(file, ndx, fname, statret, sxp, prev_name, &prev_st, @@ -474,6 +496,9 @@ #ifdef SUPPORT_ACLS prev_sx.acc_acl = prev_sx.def_acl = NULL; #endif +#ifdef SUPPORT_XATTRS + prev_sx.xattr = NULL; +#endif while ((ndx = prev_ndx) >= 0) { int val; @@ -499,6 +524,10 @@ if (preserve_acls) free_acl(&prev_sx); #endif +#ifdef SUPPORT_XATTRS + if (preserve_xattrs) + free_xattr(&prev_sx); +#endif if (val < 0) continue; if (remove_source_files == 1 && do_xfers) diff -Naur rsync-3.0.3_base/main.c rsync-3.0.3/main.c --- rsync-3.0.3_base/main.c 2008-05-31 16:51:38.000000000 -0500 +++ rsync-3.0.3/main.c 2008-06-30 20:39:11.000000000 -0500 @@ -242,6 +242,13 @@ if (do_stats) { rprintf(FCLIENT, "\n"); rprintf(FINFO,"Number of files: %d\n", stats.num_files); + // BOMBICH + rprintf(FINFO,"Number of directories: %d\n", stats.num_dirs); + rprintf(FINFO,"Number of regular files: %d\n", stats.num_reg_files); + rprintf(FINFO,"Number of symlinks: %d\n", stats.num_symlinks); + rprintf(FINFO,"Number of devices: %d\n", stats.num_devices); + rprintf(FINFO,"Number of special files: %d\n", stats.num_special); + rprintf(FINFO,"Number of re-linked hard links: %d\n", stats.hard_links_not_copied); rprintf(FINFO,"Number of files transferred: %d\n", stats.num_transferred_files); rprintf(FINFO,"Total file size: %s bytes\n", diff -Naur rsync-3.0.3_base/match.c rsync-3.0.3/match.c --- rsync-3.0.3_base/match.c 2008-03-01 14:01:41.000000000 -0600 +++ rsync-3.0.3/match.c 2008-06-30 20:39:11.000000000 -0500 @@ -39,6 +39,15 @@ extern struct stats stats; +// BOMBICH +struct timeval last_update; +static unsigned long msdiff(struct timeval *t1, struct timeval *t2) +{ + return (t2->tv_sec - t1->tv_sec) * 1000L + + (t2->tv_usec - t1->tv_usec) / 1000; +} + + #define TRADITIONAL_TABLESIZE (1<<16) static uint32 tablesize; @@ -135,6 +144,20 @@ if (buf && do_progress) show_progress(last_match, buf->file_size); + +// BOMBICH +#ifdef PARSEABLE_OUTPUT + // This provides updates when we're in the middle of copying a single file + if (buf) { + struct timeval now; + gettimeofday(&now, NULL); + unsigned long time_diff = msdiff(&last_update, &now); + if (time_diff > 1000) { + last_update = now; + rprintf(FINFO, "S;;;STATS;;;TTS;;;%.0llu\n", stats.total_transferred_size - buf->file_size + offset); + } + } +#endif } diff -Naur rsync-3.0.3_base/rounding.h rsync-3.0.3/rounding.h --- rsync-3.0.3_base/rounding.h 1969-12-31 18:00:00.000000000 -0600 +++ rsync-3.0.3/rounding.h 2008-06-30 20:39:11.000000000 -0500 @@ -0,0 +1 @@ +#define EXTRA_ROUNDING 0 diff -Naur rsync-3.0.3_base/rsync.c rsync-3.0.3/rsync.c --- rsync-3.0.3_base/rsync.c 2008-06-30 20:27:24.000000000 -0500 +++ rsync-3.0.3/rsync.c 2008-09-28 22:52:39.000000000 -0500 @@ -31,6 +31,7 @@ extern int dry_run; extern int preserve_acls; extern int preserve_xattrs; +extern int force_change; extern int preserve_perms; extern int preserve_fileflags; extern int preserve_executability; @@ -425,6 +426,7 @@ full_fname(fname)); return 0; } + sx2.crtime = 0; #ifdef SUPPORT_ACLS sx2.acc_acl = sx2.def_acl = NULL; #endif @@ -445,6 +447,11 @@ if (daemon_chmod_modes && !S_ISLNK(new_mode)) new_mode = tweak_mode(new_mode, daemon_chmod_modes); +#ifdef SUPPORT_FORCE_CHANGE + if (force_change) + make_mutable(fname, sxp->st.st_mode, sxp->st.st_flags, force_change); +#endif + #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode) && !ACL_READY(*sxp)) get_acl(fname, sxp); diff -Naur rsync-3.0.3_base/rsync.h rsync-3.0.3/rsync.h --- rsync-3.0.3_base/rsync.h 2008-06-30 20:27:24.000000000 -0500 +++ rsync-3.0.3/rsync.h 2008-06-30 20:39:11.000000000 -0500 @@ -861,6 +861,13 @@ int64 flist_size; int num_files; int num_transferred_files; + // BOMBICH + int num_dirs; + int num_reg_files; + int num_symlinks; + int num_devices; + int num_special; + int hard_links_not_copied; }; struct chmod_mode_struct; diff -Naur rsync-3.0.3_base/sender.c rsync-3.0.3/sender.c --- rsync-3.0.3_base/sender.c 2008-03-30 17:44:46.000000000 -0500 +++ rsync-3.0.3/sender.c 2008-09-27 21:23:21.000000000 -0500 @@ -46,6 +46,16 @@ extern struct stats stats; extern struct file_list *cur_flist, *first_flist, *dir_flist; +// BOMBICH +#ifdef PARSEABLE_OUTPUT +struct timeval last_update; +static unsigned long msdiff(struct timeval *t1, struct timeval *t2) +{ + return (t2->tv_sec - t1->tv_sec) * 1000L + + (t2->tv_usec - t1->tv_usec) / 1000; +} +#endif + /** * @file * @@ -269,6 +279,21 @@ set_current_file_index(file, ndx); stats.num_transferred_files++; stats.total_transferred_size += F_LENGTH(file); +// BOMBICH +// Update the user on total transfer size, number of files copied, number of non-folder "items" discovered, and the name +// of the file we're currently copying. To limit CPU usage, do this only 10 times per second +#ifdef PARSEABLE_OUTPUT + if (inc_recurse) { + struct timeval now; + gettimeofday(&now, NULL); + unsigned long time_diff = msdiff(&last_update, &now); + if (time_diff > 100) { + last_update = now; +// rprintf(FINFO, "S;;;STATS;;;TTS;;;%.0llu;;;FC;;;%d;;;CF;;;%s\n", stats.total_transferred_size, stats.num_transferred_files, fname); + rprintf(FINFO, "S;;;STATS;;;TTS;;;%.0llu;;;CF;;;%s\n", stats.total_transferred_size, fname); + } + } +#endif if (!do_xfers) { /* log the transfer */ log_item(FCLIENT, file, &stats, iflags, NULL); @@ -373,5 +398,11 @@ match_report(); +// BOMBICH +#ifdef PARSEABLE_OUTPUT + // Print the grand total + rprintf(FINFO, "S;;;SUM_STATS;;;TTS;;;%.0llu;;;FC;;;%d;;;DIRS;;;%d;;;REG;;;%d;;;SYM;;;%d;;;DEV;;;%d;;;SPEC;;;%d;;;HLNK;;;%d\n", stats.total_transferred_size, stats.num_transferred_files, stats.num_dirs, stats.num_reg_files, stats.num_symlinks, stats.num_devices, stats.num_special, stats.hard_links_not_copied); +#endif + write_ndx(f_out, NDX_DONE); } diff -Naur rsync-3.0.3_base/util.c rsync-3.0.3/util.c --- rsync-3.0.3_base/util.c 2008-06-30 20:27:20.000000000 -0500 +++ rsync-3.0.3/util.c 2008-09-28 15:48:35.000000000 -0500 @@ -1327,7 +1327,7 @@ int cmp_time(time_t file1, time_t file2) { if (file2 > file1) { - if (file2 - file1 <= modify_window) + if (file2 - file1 <= modify_window && file2 - file1 > 0) return 0; return -1; } diff -Naur rsync-3.0.3_base/xattrs.c rsync-3.0.3/xattrs.c --- rsync-3.0.3_base/xattrs.c 2008-06-30 20:27:20.000000000 -0500 +++ rsync-3.0.3/xattrs.c 2008-10-03 15:52:51.000000000 -0500 @@ -810,7 +810,7 @@ if (sys_lsetxattr(fname, name, rxas[i].datum, rxas[i].datum_len) < 0) { rsyserr(FERROR_XFER, errno, "rsync_xal_set: lsetxattr(\"%s\",\"%s\") failed", - fname, name); + full_fname(fname), name); ret = -1; } else /* make sure caller sets mtime */ sxp->st.st_mtime = (time_t)-1; @@ -840,7 +840,7 @@ if (sys_lremovexattr(fname, name) < 0) { rsyserr(FERROR_XFER, errno, "rsync_xal_clear: lremovexattr(\"%s\",\"%s\") failed", - fname, name); + full_fname(fname), name); ret = -1; } else /* make sure caller sets mtime */ sxp->st.st_mtime = (time_t)-1;