extern int verbose;
extern int recurse;
extern int delete_after;
-extern int max_delete;
extern int csum_length;
extern struct stats stats;
extern int dry_run;
extern int keep_dirlinks;
extern int preserve_hard_links;
extern int preserve_perms;
-extern int cvs_exclude;
extern int io_error;
extern char *tmpdir;
extern char *partial_dir;
extern int basis_dir_cnt;
extern int make_backups;
extern int do_progress;
-extern char *backup_dir;
-extern char *backup_suffix;
-extern int backup_suffix_len;
extern int cleanup_got_literal;
extern int module_id;
extern int ignore_errors;
extern int keep_partial;
extern int checksum_seed;
extern int inplace;
+extern int delay_updates;
-extern struct exclude_list_struct server_exclude_list;
+extern struct filter_list_struct server_filter_list;
-static void delete_one(char *fn, int is_dir)
-{
- if (!is_dir) {
- if (robust_unlink(fn) != 0) {
- rsyserr(FERROR, errno, "delete_one: unlink %s failed",
- full_fname(fn));
- } else if (verbose)
- rprintf(FINFO, "deleting %s\n", safe_fname(fn));
- } else {
- if (do_rmdir(fn) != 0) {
- if (errno != ENOTEMPTY && errno != EEXIST) {
- rsyserr(FERROR, errno,
- "delete_one: rmdir %s failed",
- full_fname(fn));
- }
- } else if (verbose) {
- rprintf(FINFO, "deleting directory %s\n",
- safe_fname(fn));
- }
- }
-}
-
-
-static int is_backup_file(char *fn)
-{
- int k = strlen(fn) - backup_suffix_len;
- return k > 0 && strcmp(fn+k, backup_suffix) == 0;
-}
-
-
-/* This deletes any files on the receiving side that are not present
- * on the sending side. */
+/* 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. */
void delete_files(struct file_list *flist)
{
- struct file_list *local_file_list;
- int i, j;
- char *argv[1], fbuf[MAXPATHLEN];
- static int deletion_count;
-
- if (cvs_exclude)
- add_cvs_excludes();
-
- if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
- rprintf(FINFO,"IO error encountered - skipping file deletion\n");
- return;
- }
+ char fbuf[MAXPATHLEN];
+ int j;
for (j = 0; j < flist->count; j++) {
- if (!(flist->files[j]->flags & FLAG_TOP_DIR)
+ if (!(flist->files[j]->flags & FLAG_DEL_START)
|| !S_ISDIR(flist->files[j]->mode))
continue;
- argv[0] = f_name_to(flist->files[j], fbuf);
-
- if (!(local_file_list = send_file_list(-1, 1, argv)))
- continue;
-
- if (verbose > 1)
- rprintf(FINFO, "deleting in %s\n", safe_fname(fbuf));
-
- for (i = local_file_list->count-1; i >= 0; i--) {
- if (max_delete && deletion_count >= max_delete)
- break;
- if (!local_file_list->files[i]->basename)
- continue;
- if (flist_find(flist,local_file_list->files[i]) < 0) {
- char *f = f_name(local_file_list->files[i]);
- int mode = local_file_list->files[i]->mode;
- if (make_backups && (backup_dir || !is_backup_file(f))
- && !S_ISDIR(mode)) {
- make_backup(f);
- if (verbose) {
- rprintf(FINFO, "deleting %s\n",
- safe_fname(f));
- }
- } else
- delete_one(f, S_ISDIR(mode) != 0);
- deletion_count++;
- }
- }
- flist_free(local_file_list);
+ delete_in_dir(flist, f_name_to(flist->files[j], fbuf));
}
}
read_sum_head(f_in, &sum);
if (fd_r >= 0 && size_r > 0) {
- OFF_T map_size = MAX((OFF_T)sum.blength * 2, 16*1024);
- mapbuf = map_file(fd_r, size_r, map_size, sum.blength);
+ int32 read_size = MAX(sum.blength * 2, 16*1024);
+ mapbuf = map_file(fd_r, size_r, read_size, sum.blength);
if (verbose > 2) {
rprintf(FINFO, "recv mapped %s of size %.0f\n",
safe_fname(fname_r), (double)size_r);
if (flush_write_file(fd) < 0)
goto report_write_error;
-#ifdef HAVE_FTRUNCATE
+#if HAVE_FTRUNCATE
if (inplace && fd != -1)
ftruncate(fd, offset);
#endif
char fnametmp[MAXPATHLEN];
char *fnamecmp, *partialptr;
char fnamecmpbuf[MAXPATHLEN];
+ uchar *delayed_bits = NULL;
struct file_struct *file;
struct stats initial_stats;
int save_make_backups = make_backups;
flist->hlink_pool = NULL;
}
+ if (delay_updates) {
+ int sz = (flist->count + 7) / 8;
+ if (!(delayed_bits = new_array(uchar, sz)))
+ out_of_memory("recv_files");
+ memset(delayed_bits, 0, sz);
+ }
+
while (1) {
cleanup_disable();
next_gen_i = -1;
}
- if (server_exclude_list.head
- && check_exclude(&server_exclude_list, fname,
+ if (server_filter_list.head
+ && check_filter(&server_filter_list, fname,
S_ISDIR(file->mode)) < 0) {
rprintf(FERROR, "attempt to hack rsync failed.\n");
exit_cleanup(RERR_PROTOCOL);
exit_cleanup(RERR_FILEIO);
}
- if (recv_ok || inplace) {
+ if ((recv_ok && !delay_updates) || inplace) {
finish_transfer(fname, fnametmp, file, recv_ok, 1);
if (partialptr != fname && fnamecmp == partialptr) {
do_unlink(partialptr);
&& handle_partial_dir(partialptr, PDIR_CREATE)) {
finish_transfer(partialptr, fnametmp, file, recv_ok,
!partial_dir);
+ if (delay_updates && recv_ok)
+ delayed_bits[i/8] |= 1 << (i % 8);
} else {
partialptr = NULL;
do_unlink(fnametmp);
}
make_backups = save_make_backups;
+ if (delay_updates) {
+ for (i = 0; i < flist->count; i++) {
+ struct file_struct *file = flist->files[i];
+ if (!file->basename
+ || !(delayed_bits[i/8] & (1 << (i % 8))))
+ continue;
+ fname = local_name ? local_name : f_name(file);
+ partialptr = partial_dir_fname(fname);
+ if (partialptr) {
+ if (make_backups && !make_backup(fname))
+ continue;
+ if (verbose > 2) {
+ rprintf(FINFO, "renaming %s to %s\n",
+ partialptr, fname);
+ }
+ if (do_rename(partialptr, fname) < 0) {
+ rsyserr(FERROR, errno,
+ "rename failed for %s (from %s)",
+ fname, partialptr);
+ } else {
+ handle_partial_dir(partialptr,
+ PDIR_DELETE);
+ }
+ }
+ }
+ }
+
if (delete_after && recurse && !local_name && flist->count > 0)
delete_files(flist);