X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/16edf86595a5a990a942fa045dfb523dae1fe6cb..ae87c43452b2b2d81d4e9c66153948d4ba334b5d:/generator.c diff --git a/generator.c b/generator.c index 09c6b7d2..05022cf1 100644 --- a/generator.c +++ b/generator.c @@ -97,6 +97,9 @@ 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; +#ifdef ICONV_OPTION +extern int ic_ndx; +#endif int ignore_perishable = 0; int non_perishable_cnt = 0; @@ -415,15 +418,14 @@ static void do_delayed_deletions(char *delbuf) * 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 * on exit). */ -static void delete_in_dir(struct file_list *flist, char *fbuf, - struct file_struct *file, dev_t *fs_dev) +static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) { static int already_warned = 0; struct file_list *dirlist; char delbuf[MAXPATHLEN]; int dlen, i; - if (!flist) { + if (!fbuf) { change_local_filter_dir(NULL, 0, 0); return; } @@ -467,7 +469,7 @@ static void delete_in_dir(struct file_list *flist, char *fbuf, f_name(fp, NULL)); continue; } - if (flist_find(flist, fp) < 0) { + if (flist_find(cur_flist, fp) < 0) { f_name(fp, delbuf); if (delete_during == 2) { if (!remember_delete(fp, delbuf)) @@ -482,7 +484,7 @@ static void delete_in_dir(struct file_list *flist, char *fbuf, /* This deletes any files on the receiving side that are not present on the * sending side. This is used by --delete-before and --delete-after. */ -static void do_delete_pass(struct file_list *flist) +static void do_delete_pass(void) { char fbuf[MAXPATHLEN]; STRUCT_STAT st; @@ -492,8 +494,8 @@ static void do_delete_pass(struct file_list *flist) if (dry_run > 1 || list_only) return; - for (j = 0; j < flist->count; j++) { - struct file_struct *file = flist->files[j]; + for (j = 0; j < cur_flist->count; j++) { + struct file_struct *file = cur_flist->sorted[j]; if (!(file->flags & FLAG_XFER_DIR)) continue; @@ -506,9 +508,9 @@ static void do_delete_pass(struct file_list *flist) || !S_ISDIR(st.st_mode)) continue; - delete_in_dir(flist, fbuf, file, &st.st_dev); + delete_in_dir(fbuf, file, &st.st_dev); } - delete_in_dir(NULL, NULL, NULL, &dev_zero); + delete_in_dir(NULL, NULL, &dev_zero); if (do_progress && !am_server) rprintf(FINFO, " \r"); @@ -519,10 +521,10 @@ int unchanged_attrs(const char *fname, struct file_struct *file, statx *sxp) if (preserve_perms && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS)) return 0; - if (am_root && preserve_uid && sxp->st.st_uid != F_UID(file)) + if (am_root && preserve_uid && sxp->st.st_uid != (uid_t)F_OWNER(file)) return 0; - if (preserve_gid && F_GID(file) != GID_NONE && sxp->st.st_gid != F_GID(file)) + if (preserve_gid && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file)) return 0; #ifdef SUPPORT_ACLS @@ -563,10 +565,10 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre iflags |= ITEM_REPORT_TIME; if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS)) iflags |= ITEM_REPORT_PERMS; - if (preserve_uid && am_root && F_UID(file) != sxp->st.st_uid) + if (preserve_uid && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid) iflags |= ITEM_REPORT_OWNER; - if (preserve_gid && F_GID(file) != GID_NONE - && sxp->st.st_gid != F_GID(file)) + if (preserve_gid && !(file->flags & FLAG_SKIP_GROUP) + && sxp->st.st_gid != (gid_t)F_GROUP(file)) iflags |= ITEM_REPORT_GROUP; #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { @@ -1271,7 +1273,7 @@ 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_XFER_DIR)) - delete_in_dir(cur_flist, fname, file, &real_sx.st.st_dev); + delete_in_dir(fname, file, &real_sx.st.st_dev); goto cleanup; } @@ -1827,7 +1829,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) void generate_files(int f_out, const char *local_name) { - int i; + int i, ndx; char fbuf[MAXPATHLEN]; int itemizing; enum logcode code; @@ -1860,7 +1862,7 @@ void generate_files(int f_out, const char *local_name) rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid()); if (delete_before && !solo_file && cur_flist->count > 0) - do_delete_pass(cur_flist); + do_delete_pass(); if (delete_during == 2) { deldelay_size = BIGPATHBUFLEN * 4; deldelay_buf = new_array(char, deldelay_size); @@ -1896,21 +1898,27 @@ void generate_files(int f_out, const char *local_name) dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); } else dirdev = MAKEDEV(0, 0); - delete_in_dir(cur_flist, f_name(fp, fbuf), fp, &dirdev); + delete_in_dir(f_name(fp, fbuf), fp, &dirdev); } } for (i = cur_flist->low; i <= cur_flist->high; i++) { - struct file_struct *file = cur_flist->files[i]; + struct file_struct *file = cur_flist->sorted[i]; if (!F_IS_ACTIVE(file)) continue; +#ifdef ICONV_OPTION + if (ic_ndx) + ndx = F_NDX(file); + else +#endif + ndx = i + cur_flist->ndx_start; + if (solo_file) strlcpy(fbuf, solo_file, sizeof fbuf); else f_name(file, fbuf); - recv_generator(fbuf, file, i + cur_flist->ndx_start, - itemizing, code, f_out); + recv_generator(fbuf, file, ndx, itemizing, code, f_out); /* We need to ensure that any dirs we create have * writeable permissions during the time we are putting @@ -1952,7 +1960,7 @@ void generate_files(int f_out, const char *local_name) } while ((cur_flist = cur_flist->next) != NULL); if (delete_during) - delete_in_dir(NULL, NULL, NULL, &dev_zero); + delete_in_dir(NULL, NULL, &dev_zero); phase++; if (verbose > 2) rprintf(FINFO, "generate_files phase=%d\n", phase); @@ -1996,11 +2004,11 @@ void generate_files(int f_out, const char *local_name) if (delete_during == 2) do_delayed_deletions(fbuf); if (delete_after && !solo_file && file_total > 0) - do_delete_pass(cur_flist); + do_delete_pass(); if ((need_retouch_dir_perms || need_retouch_dir_times) && dir_tweaking && (!inc_recurse || delete_during == 2)) - touch_up_dirs(inc_recurse ? dir_flist : cur_flist, -1); + touch_up_dirs(dir_flist, -1); if (max_delete >= 0 && deletion_count > max_delete) { rprintf(FINFO,