--- embedaddon/rsync/flist.c 2012/02/17 15:09:30 1.1 +++ embedaddon/rsync/flist.c 2013/07/22 00:20:20 1.1.1.1.2.1 @@ -60,6 +60,7 @@ extern int non_perishable_cnt; extern int prune_empty_dirs; extern int copy_links; extern int copy_unsafe_links; +extern int detect_renamed; extern int protocol_version; extern int sanitize_paths; extern int munge_symlinks; @@ -120,6 +121,8 @@ static int64 tmp_dev = -1, tmp_ino; #endif static char tmp_sum[MAX_DIGEST_LEN]; +struct file_list the_fattr_list; + static char empty_sum[MAX_DIGEST_LEN]; static int flist_count_offset; /* for --delete --progress */ static int dir_count = 0; @@ -287,6 +290,45 @@ static int is_excluded(const char *fname, int is_dir, return 0; } +static int fattr_compare(struct file_struct **file1, struct file_struct **file2) +{ + struct file_struct *f1 = *file1; + struct file_struct *f2 = *file2; + int64 len1 = F_LENGTH(f1), len2 = F_LENGTH(f2); + int diff; + + if (!f1->basename || !S_ISREG(f1->mode) || !len1) { + if (!f2->basename || !S_ISREG(f2->mode) || !len2) + return 0; + return 1; + } + if (!f2->basename || !S_ISREG(f2->mode) || !len2) + return -1; + + /* Don't use diff for values that are longer than an int. */ + if (len1 != len2) + return len1 < len2 ? -1 : 1; + + if (always_checksum) { + diff = u_memcmp(F_SUM(f1), F_SUM(f2), checksum_len); + if (diff) + return diff; + } else if (f1->modtime != f2->modtime) + return f1->modtime < f2->modtime ? -1 : 1; + + diff = u_strcmp(f1->basename, f2->basename); + if (diff) + return diff; + + if (f1->dirname == f2->dirname) + return 0; + if (!f1->dirname) + return -1; + if (!f2->dirname) + return 1; + return u_strcmp(f1->dirname, f2->dirname); +} + static void send_directory(int f, struct file_list *flist, char *fbuf, int len, int flags); @@ -2426,6 +2468,25 @@ struct file_list *recv_file_list(int f) recv_id_list(f, flist); flist_sort_and_clean(flist, relative_paths); + + if (detect_renamed) { + int j = flist->used; + the_fattr_list.used = j; + the_fattr_list.files = new_array(struct file_struct *, j); + if (!the_fattr_list.files) + out_of_memory("recv_file_list"); + memcpy(the_fattr_list.files, flist->files, + j * sizeof (struct file_struct *)); + qsort(the_fattr_list.files, j, + sizeof the_fattr_list.files[0], (int (*)())fattr_compare); + the_fattr_list.low = 0; + while (j-- > 0) { + struct file_struct *fp = the_fattr_list.files[j]; + if (fp->basename && S_ISREG(fp->mode) && F_LENGTH(fp)) + break; + } + the_fattr_list.high = j; + } if (protocol_version < 30) { /* Recv the io_error flag */