- Moved delete_file() here from rsync.c and improved it to avoid
[rsync/rsync.git] / rsync.c
diff --git a/rsync.c b/rsync.c
index 4c34deb..d9e55c7 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -24,7 +24,7 @@
 
 extern int verbose;
 extern int dry_run;
-extern int itemize_changes;
+extern int daemon_log_format_has_i;
 extern int preserve_times;
 extern int omit_dir_times;
 extern int am_root;
@@ -36,11 +36,21 @@ extern int preserve_gid;
 extern int force_delete;
 extern int inplace;
 extern int recurse;
+extern int max_delete;
 extern int keep_dirlinks;
 extern int make_backups;
 extern struct stats stats;
 extern char *backup_dir;
 extern char *log_format;
+extern char *backup_suffix;
+extern int backup_suffix_len;
+
+
+static int is_backup_file(char *fn)
+{
+       int k = strlen(fn) - backup_suffix_len;
+       return k > 0 && strcmp(fn+k, backup_suffix) == 0;
+}
 
 
 /*
@@ -53,6 +63,8 @@ void free_sums(struct sum_struct *s)
 }
 
 
+int deletion_count = 0; /* used to implement --max-delete */
+
 /*
  * delete a file or directory. If force_delete is set then delete
  * recursively
@@ -65,10 +77,19 @@ int delete_file(char *fname, int mode, int flags)
        STRUCT_STAT st;
        int zap_dir;
 
+       if (max_delete && deletion_count >= max_delete)
+               return -1;
+
        if (!S_ISDIR(mode)) {
-               if (robust_unlink(fname) == 0) {
+               int ok;
+               if (make_backups && (backup_dir || !is_backup_file(fname)))
+                       ok = make_backup(fname);
+               else
+                       ok = robust_unlink(fname) == 0;
+               if (ok) {
                        if ((verbose || log_format) && !(flags & DEL_TERSE))
                                log_delete(fname, mode);
+                       deletion_count++;
                        return 0;
                }
                if (errno == ENOENT)
@@ -85,6 +106,7 @@ int delete_file(char *fname, int mode, int flags)
        else if (do_rmdir(fname) == 0) {
                if ((verbose || log_format) && !(flags & DEL_TERSE))
                        log_delete(fname, mode);
+               deletion_count++;
                return 0;
        }
        if (errno == ENOENT)
@@ -133,11 +155,14 @@ int delete_file(char *fname, int mode, int flags)
 
        closedir(d);
 
+       if (max_delete && deletion_count >= max_delete)
+               return -1;
        if (do_rmdir(fname) != 0 && errno != ENOENT) {
                rsyserr(FERROR, errno, "delete_file: rmdir %s failed",
                        full_fname(fname));
                return -1;
        }
+       deletion_count++;
 
        return 0;
 }
@@ -231,10 +256,12 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
 #endif
 
        if (verbose > 1 && flags & PERMS_REPORT) {
+               enum logcode code = daemon_log_format_has_i || dry_run
+                                 ? FCLIENT : FINFO;
                if (updated)
-                       rprintf(FINFO, "%s\n", safe_fname(fname));
+                       rprintf(code, "%s\n", safe_fname(fname));
                else
-                       rprintf(FINFO, "%s is uptodate\n", safe_fname(fname));
+                       rprintf(code, "%s is uptodate\n", safe_fname(fname));
        }
        return updated;
 }