X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/19b2a5d9fdd54c37d90610ccec89e54eedd7b4ed..42f23f479d3e5beb8275d5dd8f4bb2f905f54f4d:/flist.c diff --git a/flist.c b/flist.c index 0d896dc2..ed26bb8b 100644 --- a/flist.c +++ b/flist.c @@ -522,7 +522,7 @@ void receive_file_entry(struct file_struct **fptr, unsigned short flags, static gid_t gid; static char lastname[MAXPATHLEN], *lastdir; static int lastdir_depth, lastdir_len = -1; - static unsigned int del_heir_name_len = 0; + static unsigned int del_hier_name_len = 0; static int in_del_hier = 0; char thisname[MAXPATHLEN]; unsigned int l1 = 0, l2 = 0; @@ -646,11 +646,11 @@ void receive_file_entry(struct file_struct **fptr, unsigned short flags, if (S_ISDIR(mode)) { if (flags & XMIT_DEL_START) { in_del_hier = 1; - del_heir_name_len = l1 + l2; + del_hier_name_len = l1 + l2; file->flags |= FLAG_DEL_START; } else if (delete_during && in_del_hier) { - if (!relative_paths || (l1 >= del_heir_name_len - && thisname[del_heir_name_len] == '/')) + if (!relative_paths || (l1 >= del_hier_name_len + && thisname[del_hier_name_len] == '/')) file->flags |= FLAG_DEL_START; else in_del_hier = 0; @@ -1670,6 +1670,7 @@ static int is_backup_file(char *fn) void delete_in_dir(struct file_list *flist, char *fname) { static void *filt_array[MAXPATHLEN/2]; + static BOOL need_first_push = True; static int fa_lvl = 0; static char fbuf[MAXPATHLEN]; struct file_list *dir_list; @@ -1679,6 +1680,7 @@ void delete_in_dir(struct file_list *flist, char *fname) if (!flist) { while (fa_lvl) pop_local_filters(filt_array[--fa_lvl]); + need_first_push = True; *fbuf = '\0'; return; } @@ -1688,17 +1690,11 @@ void delete_in_dir(struct file_list *flist, char *fname) if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) { rprintf(FINFO, - "IO error encountered - skipping file deletion\n"); + "IO error encountered -- skipping file deletion\n"); max_delete = -1; /* avoid duplicating the above warning */ return; } - if (link_stat(fname, &st, keep_dirlinks) < 0) - return; - - if (one_file_system) - filesystem_dev = st.st_dev; - for (j = 0; fbuf[j]; j++) { if (fbuf[j] != fname[j]) { while (fa_lvl) { @@ -1712,11 +1708,33 @@ void delete_in_dir(struct file_list *flist, char *fname) } dlen = strlcpy(fbuf, fname, MAXPATHLEN); + if (need_first_push) { + if (dlen != 1 || fbuf[0] != '.') { + char *s = strrchr(fbuf, '/'); + int first_dlen; + if (s) + first_dlen = s - fbuf; + else + first_dlen = 0; + if (!s || s[1] != '.' || s[2] != '\0') { + filt_array[fa_lvl++] = push_local_filters(fbuf, + first_dlen); + } + } + need_first_push = False; + } + if (dlen >= MAXPATHLEN - 1) return; if (fa_lvl >= MAXPATHLEN/2) return; /* impossible... */ + if (link_stat(fname, &st, keep_dirlinks) < 0) + return; + + if (one_file_system) + filesystem_dev = st.st_dev; + dir_list = flist_new(WITHOUT_HLINK, "delete_in_dir"); recurse = 0;