| version 1.1, 2012/02/17 15:09:30 | version 1.1.1.1.2.1, 2013/07/22 00:20:20 | 
| Line 78  extern char *basis_dir[MAX_BASIS_DIRS+1]; | Line 78  extern char *basis_dir[MAX_BASIS_DIRS+1]; | 
 | extern int compare_dest; | extern int compare_dest; | 
 | extern int copy_dest; | extern int copy_dest; | 
 | extern int link_dest; | extern int link_dest; | 
 |  | extern int detect_renamed; | 
 | extern int whole_file; | extern int whole_file; | 
 | extern int list_only; | extern int list_only; | 
 | extern int read_batch; | extern int read_batch; | 
| Line 96  extern char *backup_suffix; | Line 97  extern char *backup_suffix; | 
 | extern int backup_suffix_len; | extern int backup_suffix_len; | 
 | extern struct file_list *cur_flist, *first_flist, *dir_flist; | extern struct file_list *cur_flist, *first_flist, *dir_flist; | 
 | extern struct filter_list_struct daemon_filter_list; | extern struct filter_list_struct daemon_filter_list; | 
 |  | extern struct file_list the_fattr_list; | 
 |  |  | 
 | int ignore_perishable = 0; | int ignore_perishable = 0; | 
 | int non_perishable_cnt = 0; | int non_perishable_cnt = 0; | 
| Line 103  int maybe_ATTRS_REPORT = 0; | Line 105  int maybe_ATTRS_REPORT = 0; | 
 |  |  | 
 | static dev_t dev_zero; | static dev_t dev_zero; | 
 | static int deletion_count = 0; /* used to implement --max-delete */ | static int deletion_count = 0; /* used to implement --max-delete */ | 
 |  | static int unexplored_dirs = 1; | 
 | static int deldelay_size = 0, deldelay_cnt = 0; | static int deldelay_size = 0, deldelay_cnt = 0; | 
 | static char *deldelay_buf = NULL; | static char *deldelay_buf = NULL; | 
 | static int deldelay_fd = -1; | static int deldelay_fd = -1; | 
| Line 113  static int need_retouch_dir_times; | Line 116  static int need_retouch_dir_times; | 
 | static int need_retouch_dir_perms; | static int need_retouch_dir_perms; | 
 | static const char *solo_file = NULL; | static const char *solo_file = NULL; | 
 |  |  | 
| /* For calling delete_item() and delete_dir_contents(). */ | /* For calling delete_item(), delete_dir_contents(), and delete_in_dir(). */ | 
 | #define DEL_NO_UID_WRITE        (1<<0) /* file/dir has our uid w/o write perm */ | #define DEL_NO_UID_WRITE        (1<<0) /* file/dir has our uid w/o write perm */ | 
 | #define DEL_RECURSE             (1<<1) /* if dir, delete all contents */ | #define DEL_RECURSE             (1<<1) /* if dir, delete all contents */ | 
 | #define DEL_DIR_IS_EMPTY        (1<<2) /* internal delete_FUNCTIONS use only */ | #define DEL_DIR_IS_EMPTY        (1<<2) /* internal delete_FUNCTIONS use only */ | 
| Line 122  static const char *solo_file = NULL; | Line 125  static const char *solo_file = NULL; | 
 | #define DEL_FOR_SYMLINK         (1<<5) /* making room for a replacement symlink */ | #define DEL_FOR_SYMLINK         (1<<5) /* making room for a replacement symlink */ | 
 | #define DEL_FOR_DEVICE          (1<<6) /* making room for a replacement device */ | #define DEL_FOR_DEVICE          (1<<6) /* making room for a replacement device */ | 
 | #define DEL_FOR_SPECIAL         (1<<7) /* making room for a replacement special */ | #define DEL_FOR_SPECIAL         (1<<7) /* making room for a replacement special */ | 
 |  | #define DEL_NO_DELETIONS        (1<<9) /* just check for renames w/o deleting */ | 
 |  |  | 
 | #define DEL_MAKE_ROOM (DEL_FOR_FILE|DEL_FOR_DIR|DEL_FOR_SYMLINK|DEL_FOR_DEVICE|DEL_FOR_SPECIAL) | #define DEL_MAKE_ROOM (DEL_FOR_FILE|DEL_FOR_DIR|DEL_FOR_SYMLINK|DEL_FOR_DEVICE|DEL_FOR_SPECIAL) | 
 |  |  | 
| Line 146  static int is_backup_file(char *fn) | Line 150  static int is_backup_file(char *fn) | 
 | return k > 0 && strcmp(fn+k, backup_suffix) == 0; | return k > 0 && strcmp(fn+k, backup_suffix) == 0; | 
 | } | } | 
 |  |  | 
 |  | /* Search for a regular file that matches either (1) the size & modified | 
 |  | * time (plus the basename, if possible) or (2) the size & checksum.  If | 
 |  | * we find an exact match down to the dirname, return -1 because we found | 
 |  | * an up-to-date file in the transfer, not a renamed file. */ | 
 |  | static int fattr_find(struct file_struct *f, char *fname) | 
 |  | { | 
 |  | int low = the_fattr_list.low, high = the_fattr_list.high; | 
 |  | int mid, ok_match = -1, good_match = -1; | 
 |  | struct file_struct *fmid; | 
 |  | int diff; | 
 |  |  | 
 |  | while (low <= high) { | 
 |  | mid = (low + high) / 2; | 
 |  | fmid = the_fattr_list.files[mid]; | 
 |  | if (F_LENGTH(fmid) != F_LENGTH(f)) { | 
 |  | if (F_LENGTH(fmid) < F_LENGTH(f)) | 
 |  | low = mid + 1; | 
 |  | else | 
 |  | high = mid - 1; | 
 |  | continue; | 
 |  | } | 
 |  | if (always_checksum) { | 
 |  | /* We use the FLAG_FILE_SENT flag to indicate when we | 
 |  | * have computed the checksum for an entry. */ | 
 |  | if (!(f->flags & FLAG_FILE_SENT)) { | 
 |  | if (fmid->modtime == f->modtime | 
 |  | && f_name_cmp(fmid, f) == 0) | 
 |  | return -1; /* assume we can't help */ | 
 |  | file_checksum(fname, F_SUM(f), F_LENGTH(f)); | 
 |  | f->flags |= FLAG_FILE_SENT; | 
 |  | } | 
 |  | diff = u_memcmp(F_SUM(fmid), F_SUM(f), checksum_len); | 
 |  | if (diff) { | 
 |  | if (diff < 0) | 
 |  | low = mid + 1; | 
 |  | else | 
 |  | high = mid - 1; | 
 |  | continue; | 
 |  | } | 
 |  | } else { | 
 |  | if (fmid->modtime != f->modtime) { | 
 |  | if (fmid->modtime < f->modtime) | 
 |  | low = mid + 1; | 
 |  | else | 
 |  | high = mid - 1; | 
 |  | continue; | 
 |  | } | 
 |  | } | 
 |  | ok_match = mid; | 
 |  | diff = u_strcmp(fmid->basename, f->basename); | 
 |  | if (diff == 0) { | 
 |  | good_match = mid; | 
 |  | if (fmid->dirname == f->dirname) | 
 |  | return -1; /* file is up-to-date */ | 
 |  | if (!fmid->dirname) { | 
 |  | low = mid + 1; | 
 |  | continue; | 
 |  | } | 
 |  | if (!f->dirname) { | 
 |  | high = mid - 1; | 
 |  | continue; | 
 |  | } | 
 |  | diff = u_strcmp(fmid->dirname, f->dirname); | 
 |  | if (diff == 0) | 
 |  | return -1; /* file is up-to-date */ | 
 |  | } | 
 |  | if (diff < 0) | 
 |  | low = mid + 1; | 
 |  | else | 
 |  | high = mid - 1; | 
 |  | } | 
 |  |  | 
 |  | return good_match >= 0 ? good_match : ok_match; | 
 |  | } | 
 |  |  | 
 |  | static void look_for_rename(struct file_struct *file, char *fname) | 
 |  | { | 
 |  | struct file_struct *fp; | 
 |  | char *partialptr, *fn; | 
 |  | STRUCT_STAT st; | 
 |  | int ndx; | 
 |  |  | 
 |  | if (!partial_dir || (ndx = fattr_find(file, fname)) < 0) | 
 |  | return; | 
 |  |  | 
 |  | fp = the_fattr_list.files[ndx]; | 
 |  | fn = f_name(fp, NULL); | 
 |  | /* We don't provide an alternate-basis file if there is a basis file. */ | 
 |  | if (link_stat(fn, &st, 0) == 0) | 
 |  | return; | 
 |  |  | 
 |  | if (!dry_run) { | 
 |  | if ((partialptr = partial_dir_fname(fn)) == NULL | 
 |  | || !handle_partial_dir(partialptr, PDIR_CREATE)) | 
 |  | return; | 
 |  | /* We only use the file if we can hard-link it into our tmp dir. */ | 
 |  | if (link(fname, partialptr) != 0) { | 
 |  | if (errno != EEXIST) | 
 |  | handle_partial_dir(partialptr, PDIR_DELETE); | 
 |  | return; | 
 |  | } | 
 |  | } | 
 |  |  | 
 |  | /* I think this falls into the -vv category with "%s is uptodate", etc. */ | 
 |  | if (verbose > 1) | 
 |  | rprintf(FINFO, "found renamed: %s => %s\n", fname, fn); | 
 |  | } | 
 |  |  | 
 | /* Delete a file or directory.  If DEL_RECURSE is set in the flags, this will | /* Delete a file or directory.  If DEL_RECURSE is set in the flags, this will | 
 | * delete recursively. | * delete recursively. | 
 | * | * | 
 | * Note that fbuf must point to a MAXPATHLEN buffer if the mode indicates it's | * Note that fbuf must point to a MAXPATHLEN buffer if the mode indicates it's | 
 | * a directory! (The buffer is used for recursion, but returned unchanged.) | * a directory! (The buffer is used for recursion, but returned unchanged.) | 
 |  | * | 
 |  | * Also note: --detect-rename may use this routine with DEL_NO_DELETIONS set! | 
 | */ | */ | 
 | static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) | static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags) | 
 | { | { | 
| Line 177  static enum delret delete_item(char *fbuf, uint16 mode | Line 291  static enum delret delete_item(char *fbuf, uint16 mode | 
 | goto check_ret; | goto check_ret; | 
 | /* OK: try to delete the directory. */ | /* OK: try to delete the directory. */ | 
 | } | } | 
 |  | if (flags & DEL_NO_DELETIONS) | 
 |  | return DR_SUCCESS; | 
 |  |  | 
 | if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && ++deletion_count > max_delete) | if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && ++deletion_count > max_delete) | 
 | return DR_AT_LIMIT; | return DR_AT_LIMIT; | 
| Line 232  static enum delret delete_item(char *fbuf, uint16 mode | Line 348  static enum delret delete_item(char *fbuf, uint16 mode | 
 | * its contents, otherwise just checks for content.  Returns DR_SUCCESS or | * its contents, otherwise just checks for content.  Returns DR_SUCCESS or | 
 | * DR_NOT_EMPTY.  Note that fname must point to a MAXPATHLEN buffer!  (The | * DR_NOT_EMPTY.  Note that fname must point to a MAXPATHLEN buffer!  (The | 
 | * buffer is used for recursion, but returned unchanged.) | * buffer is used for recursion, but returned unchanged.) | 
 |  | * | 
 |  | * Note: --detect-rename may use this routine with DEL_NO_DELETIONS set! | 
 | */ | */ | 
 | static enum delret delete_dir_contents(char *fname, uint16 flags) | static enum delret delete_dir_contents(char *fname, uint16 flags) | 
 | { | { | 
| Line 251  static enum delret delete_dir_contents(char *fname, ui | Line 369  static enum delret delete_dir_contents(char *fname, ui | 
 | save_filters = push_local_filters(fname, dlen); | save_filters = push_local_filters(fname, dlen); | 
 |  |  | 
 | non_perishable_cnt = 0; | non_perishable_cnt = 0; | 
 |  | file_extra_cnt += SUM_EXTRA_CNT; | 
 | dirlist = get_dirlist(fname, dlen, 0); | dirlist = get_dirlist(fname, dlen, 0); | 
 |  | file_extra_cnt -= SUM_EXTRA_CNT; | 
 | ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS; | ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS; | 
 |  |  | 
 | if (!dirlist->used) | if (!dirlist->used) | 
| Line 291  static enum delret delete_dir_contents(char *fname, ui | Line 411  static enum delret delete_dir_contents(char *fname, ui | 
 | if (S_ISDIR(fp->mode)) { | if (S_ISDIR(fp->mode)) { | 
 | if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS) | if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS) | 
 | ret = DR_NOT_EMPTY; | ret = DR_NOT_EMPTY; | 
| } | } else if (detect_renamed && S_ISREG(fp->mode)) | 
|  | look_for_rename(fp, fname); | 
 | if (delete_item(fname, fp->mode, flags) != DR_SUCCESS) | if (delete_item(fname, fp->mode, flags) != DR_SUCCESS) | 
 | ret = DR_NOT_EMPTY; | ret = DR_NOT_EMPTY; | 
 | } | } | 
| Line 456  static void do_delayed_deletions(char *delbuf) | Line 577  static void do_delayed_deletions(char *delbuf) | 
 | * all the --delete-WHEN options.  Note that the fbuf pointer must point to a | * 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 | * 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 | * call will append names onto the end, but the old dir value will be restored | 
| * on exit). */ | * on exit). | 
| static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev) | * | 
|  | * Note:  --detect-rename may use this routine with DEL_NO_DELETIONS set! | 
|  | */ | 
|  | static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev, | 
|  | int del_flags) | 
 | { | { | 
 | static int already_warned = 0; | static int already_warned = 0; | 
 | struct file_list *dirlist; | struct file_list *dirlist; | 
| char delbuf[MAXPATHLEN]; | char *p, delbuf[MAXPATHLEN]; | 
| int dlen, i; | unsigned remainder; | 
|  | int dlen, i, restore_dot = 0; | 
 |  |  | 
 | if (!fbuf) { | if (!fbuf) { | 
 | change_local_filter_dir(NULL, 0, 0); | change_local_filter_dir(NULL, 0, 0); | 
| Line 476  static void delete_in_dir(char *fbuf, struct file_stru | Line 602  static void delete_in_dir(char *fbuf, struct file_stru | 
 | maybe_send_keepalive(); | maybe_send_keepalive(); | 
 |  |  | 
 | if (io_error && !ignore_errors) { | if (io_error && !ignore_errors) { | 
| if (already_warned) | if (!already_warned) { | 
|  | rprintf(FINFO, | 
|  | "IO error encountered -- skipping file deletion\n"); | 
|  | already_warned = 1; | 
|  | } | 
|  | if (!detect_renamed) | 
 | return; | return; | 
| rprintf(FINFO, | del_flags |= DEL_NO_DELETIONS; | 
| "IO error encountered -- skipping file deletion\n"); |  | 
| already_warned = 1; |  | 
| return; |  | 
 | } | } | 
 |  |  | 
 | dlen = strlen(fbuf); | dlen = strlen(fbuf); | 
 | change_local_filter_dir(fbuf, dlen, F_DEPTH(file)); | change_local_filter_dir(fbuf, dlen, F_DEPTH(file)); | 
 |  |  | 
 |  | if (detect_renamed) | 
 |  | unexplored_dirs--; | 
 |  |  | 
 | if (one_file_system) { | if (one_file_system) { | 
 | if (file->flags & FLAG_TOP_DIR) | if (file->flags & FLAG_TOP_DIR) | 
 | filesystem_dev = *fs_dev; | filesystem_dev = *fs_dev; | 
| Line 496  static void delete_in_dir(char *fbuf, struct file_stru | Line 627  static void delete_in_dir(char *fbuf, struct file_stru | 
 |  |  | 
 | dirlist = get_dirlist(fbuf, dlen, 0); | dirlist = get_dirlist(fbuf, dlen, 0); | 
 |  |  | 
 |  | p = fbuf + dlen; | 
 |  | if (dlen == 1 && *fbuf == '.') { | 
 |  | restore_dot = 1; | 
 |  | p = fbuf; | 
 |  | } else if (dlen != 1 || *fbuf != '/') | 
 |  | *p++ = '/'; | 
 |  | remainder = MAXPATHLEN - (p - fbuf); | 
 |  |  | 
 | /* If an item in dirlist is not found in flist, delete it | /* If an item in dirlist is not found in flist, delete it | 
 | * from the filesystem. */ | * from the filesystem. */ | 
 | for (i = dirlist->used; i--; ) { | for (i = dirlist->used; i--; ) { | 
| Line 508  static void delete_in_dir(char *fbuf, struct file_stru | Line 647  static void delete_in_dir(char *fbuf, struct file_stru | 
 | f_name(fp, NULL)); | f_name(fp, NULL)); | 
 | continue; | continue; | 
 | } | } | 
 |  | if (detect_renamed && S_ISREG(fp->mode)) { | 
 |  | strlcpy(p, fp->basename, remainder); | 
 |  | look_for_rename(fp, fbuf); | 
 |  | } | 
 | /* Here we want to match regardless of file type.  Replacement | /* Here we want to match regardless of file type.  Replacement | 
 | * of a file with one of another type is handled separately by | * of a file with one of another type is handled separately by | 
 | * a delete_item call with a DEL_MAKE_ROOM flag. */ | * a delete_item call with a DEL_MAKE_ROOM flag. */ | 
| Line 516  static void delete_in_dir(char *fbuf, struct file_stru | Line 659  static void delete_in_dir(char *fbuf, struct file_stru | 
 | if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US) | if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US) | 
 | flags |= DEL_NO_UID_WRITE; | flags |= DEL_NO_UID_WRITE; | 
 | f_name(fp, delbuf); | f_name(fp, delbuf); | 
| if (delete_during == 2) { | if (delete_during == 2 && !(del_flags & DEL_NO_DELETIONS)) { | 
| if (!remember_delete(fp, delbuf, flags)) | if (!remember_delete(fp, delbuf, del_flags | flags)) | 
 | break; | break; | 
 | } else | } else | 
| delete_item(delbuf, fp->mode, flags); | delete_item(delbuf, fp->mode, del_flags | flags); | 
| } | } else if (detect_renamed && S_ISDIR(fp->mode)) | 
|  | unexplored_dirs++; | 
 | } | } | 
 |  |  | 
 |  | if (restore_dot) | 
 |  | fbuf[0] = '.'; | 
 |  | fbuf[dlen] = '\0'; | 
 |  |  | 
 | flist_free(dirlist); | flist_free(dirlist); | 
 | } | } | 
 |  |  | 
| Line 556  static void do_delete_pass(void) | Line 704  static void do_delete_pass(void) | 
 | || !S_ISDIR(st.st_mode)) | || !S_ISDIR(st.st_mode)) | 
 | continue; | continue; | 
 |  |  | 
| delete_in_dir(fbuf, file, &st.st_dev); | delete_in_dir(fbuf, file, &st.st_dev, 0); | 
 | } | } | 
| delete_in_dir(NULL, NULL, &dev_zero); | delete_in_dir(NULL, NULL, &dev_zero, 0); | 
 |  |  | 
 | if (do_progress && !am_server) | if (do_progress && !am_server) | 
 | rprintf(FINFO, "                    \r"); | rprintf(FINFO, "                    \r"); | 
| Line 1269  static void list_file_entry(struct file_struct *f) | Line 1417  static void list_file_entry(struct file_struct *f) | 
 | } | } | 
 | } | } | 
 |  |  | 
 |  | static struct bitbag *delayed_bits = NULL; | 
 | static int phase = 0; | static int phase = 0; | 
 | static int dflt_perms; | static int dflt_perms; | 
 |  |  | 
| Line 1558  static void recv_generator(char *fname, struct file_st | Line 1707  static void recv_generator(char *fname, struct file_st | 
 | } | } | 
 | else if (delete_during && f_out != -1 && !phase | else if (delete_during && f_out != -1 && !phase | 
 | && !(file->flags & FLAG_MISSING_DIR)) { | && !(file->flags & FLAG_MISSING_DIR)) { | 
| if (file->flags & FLAG_CONTENT_DIR) | if (file->flags & FLAG_CONTENT_DIR) { | 
| delete_in_dir(fname, file, &real_sx.st.st_dev); | if (detect_renamed && real_ret != 0) | 
| else | unexplored_dirs++; | 
|  | delete_in_dir(fname, file, &real_sx.st.st_dev, | 
|  | delete_during < 0 ? DEL_NO_DELETIONS : 0); | 
|  | } else | 
 | change_local_filter_dir(fname, strlen(fname), F_DEPTH(file)); | change_local_filter_dir(fname, strlen(fname), F_DEPTH(file)); | 
 | } | } | 
 | goto cleanup; | goto cleanup; | 
| Line 1844  static void recv_generator(char *fname, struct file_st | Line 1996  static void recv_generator(char *fname, struct file_st | 
 | goto cleanup; | goto cleanup; | 
 | } | } | 
 | #endif | #endif | 
| if (stat_errno == ENOENT) | if (stat_errno == ENOENT) { | 
|  | if (detect_renamed && unexplored_dirs > 0 | 
|  | && F_LENGTH(file)) { | 
|  | bitbag_set_bit(delayed_bits, ndx); | 
|  | return; | 
|  | } | 
 | goto notify_others; | goto notify_others; | 
 |  | } | 
 | rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s", | rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s", | 
 | full_fname(fname)); | full_fname(fname)); | 
 | goto cleanup; | goto cleanup; | 
| Line 2254  void generate_files(int f_out, const char *local_name) | Line 2412  void generate_files(int f_out, const char *local_name) | 
 | if (verbose > 2) | if (verbose > 2) | 
 | rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid()); | rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid()); | 
 |  |  | 
 |  | if (detect_renamed) { | 
 |  | delayed_bits = bitbag_create(cur_flist->used); | 
 |  | if (!delete_before && !delete_during) | 
 |  | delete_during = -1; | 
 |  | } | 
 |  |  | 
 | if (delete_before && !solo_file && cur_flist->used > 0) | if (delete_before && !solo_file && cur_flist->used > 0) | 
 | do_delete_pass(); | do_delete_pass(); | 
 | if (delete_during == 2) { | if (delete_during == 2) { | 
| Line 2264  void generate_files(int f_out, const char *local_name) | Line 2428  void generate_files(int f_out, const char *local_name) | 
 | } | } | 
 | do_progress = 0; | do_progress = 0; | 
 |  |  | 
| if (append_mode > 0 || whole_file < 0) | if (append_mode > 0 || detect_renamed || whole_file < 0) | 
 | whole_file = 0; | whole_file = 0; | 
 | if (verbose >= 2) { | if (verbose >= 2) { | 
 | rprintf(FINFO, "delta-transmission %s\n", | rprintf(FINFO, "delta-transmission %s\n", | 
| Line 2306  void generate_files(int f_out, const char *local_name) | Line 2470  void generate_files(int f_out, const char *local_name) | 
 | dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); | dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp)); | 
 | } else | } else | 
 | dirdev = MAKEDEV(0, 0); | dirdev = MAKEDEV(0, 0); | 
| delete_in_dir(fbuf, fp, &dirdev); | delete_in_dir(fbuf, fp, &dirdev, 0); | 
 | } else | } else | 
 | change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp)); | change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp)); | 
 | } | } | 
| Line 2353  void generate_files(int f_out, const char *local_name) | Line 2517  void generate_files(int f_out, const char *local_name) | 
 | } while ((cur_flist = cur_flist->next) != NULL); | } while ((cur_flist = cur_flist->next) != NULL); | 
 |  |  | 
 | if (delete_during) | if (delete_during) | 
| delete_in_dir(NULL, NULL, &dev_zero); | delete_in_dir(NULL, NULL, &dev_zero, 0); | 
|  | if (detect_renamed) { | 
|  | if (delete_during < 0) | 
|  | delete_during = 0; | 
|  | detect_renamed = 0; | 
|  |  | 
|  | for (i = -1; (i = bitbag_next_bit(delayed_bits, i)) >= 0; ) { | 
|  | struct file_struct *file = cur_flist->files[i]; | 
|  | if (local_name) | 
|  | strlcpy(fbuf, local_name, sizeof fbuf); | 
|  | else | 
|  | f_name(file, fbuf); | 
|  | recv_generator(fbuf, file, i, itemizing, code, f_out); | 
|  | } | 
|  | } | 
 | phase++; | phase++; | 
 | if (verbose > 2) | if (verbose > 2) | 
 | rprintf(FINFO, "generate_files phase=%d\n", phase); | rprintf(FINFO, "generate_files phase=%d\n", phase); |