Get the "dev" suffix right.
[rsync.git] / delete.c
index 4d7220e238b1ceaed12aed378d88c7333f99de0b..89c1f8d672f4d7bb4b5ccbbbf600cc67bc3f7662 100644 (file)
--- a/delete.c
+++ b/delete.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1996-2000 Andrew Tridgell
  * Copyright (C) 1996 Paul Mackerras
  * Copyright (C) 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2009 Wayne Davison
+ * Copyright (C) 2003-2024 Wayne Davison
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,7 +28,6 @@ extern int max_delete;
 extern char *backup_dir;
 extern char *backup_suffix;
 extern int backup_suffix_len;
-extern uid_t our_uid;
 extern struct stats stats;
 
 int ignore_perishable = 0;
@@ -90,15 +89,15 @@ static enum delret delete_dir_contents(char *fname, uint16 flags)
                if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) {
                        if (DEBUG_GTE(DEL, 1)) {
                                rprintf(FINFO,
-                                   "mount point, %s, pins parent directory\n",
-                                   f_name(fp, NULL));
+                                       "mount point, %s, pins parent directory\n",
+                                       f_name(fp, NULL));
                        }
                        ret = DR_NOT_EMPTY;
                        continue;
                }
 
                strlcpy(p, fp->basename, remainder);
-               if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid)
+               if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
                        do_chmod(fname, fp->mode | S_IWUSR);
                /* Save stack by recursing to ourself directly. */
                if (S_ISDIR(fp->mode)) {
@@ -143,19 +142,12 @@ enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
                do_chmod(fbuf, mode | S_IWUSR);
 
        if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) {
-               int save_uid_ndx = uid_ndx;
                /* This only happens on the first call to delete_item() since
                 * delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */
-               if (!uid_ndx)
-                       uid_ndx = ++file_extra_cnt;
                ignore_perishable = 1;
                /* If DEL_RECURSE is not set, this just reports emptiness. */
                ret = delete_dir_contents(fbuf, flags);
                ignore_perishable = 0;
-               if (!save_uid_ndx) {
-                       --file_extra_cnt;
-                       uid_ndx = 0;
-               }
                if (ret == DR_NOT_EMPTY || ret == DR_AT_LIMIT)
                        goto check_ret;
                /* OK: try to delete the directory. */
@@ -169,12 +161,18 @@ enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
        if (S_ISDIR(mode)) {
                what = "rmdir";
                ok = do_rmdir(fbuf) == 0;
-       } else if (make_backups > 0 && (backup_dir || !is_backup_file(fbuf))) {
-               what = "make_backup";
-               ok = make_backup(fbuf);
        } else {
-               what = "unlink";
-               ok = robust_unlink(fbuf) == 0;
+               if (make_backups > 0 && !(flags & DEL_FOR_BACKUP) && (backup_dir || !is_backup_file(fbuf))) {
+                       what = "make_backup";
+                       ok = make_backup(fbuf, True);
+                       if (ok == 2) {
+                               what = "unlink";
+                               ok = robust_unlink(fbuf) == 0;
+                       }
+               } else {
+                       what = "unlink";
+                       ok = robust_unlink(fbuf) == 0;
+               }
        }
 
        if (ok) {
@@ -190,7 +188,7 @@ enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
                                stats.deleted_symlinks++;
 #endif
                        else if (IS_DEVICE(mode))
-                               stats.deleted_symlinks++;
+                               stats.deleted_devices++;
                        else
                                stats.deleted_specials++;
                }
@@ -201,7 +199,7 @@ enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
                                fbuf);
                        ret = DR_NOT_EMPTY;
                } else if (errno != ENOENT) {
-                       rsyserr(FERROR, errno, "delete_file: %s(%s) failed",
+                       rsyserr(FERROR_XFER, errno, "delete_file: %s(%s) failed",
                                what, fbuf);
                        ret = DR_FAILURE;
                } else
@@ -219,8 +217,24 @@ enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
                case DEL_FOR_SPECIAL: desc = "special file"; break;
                default: exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE */
                }
-               rprintf(FERROR_XFER, "could not make way for new %s: %s\n",
+               rprintf(FERROR_XFER, "could not make way for %s %s: %s\n",
+                       flags & DEL_FOR_BACKUP ? "backup" : "new",
                        desc, fbuf);
        }
        return ret;
 }
+
+uint16 get_del_for_flag(uint16 mode)
+{
+       if (S_ISREG(mode))
+               return DEL_FOR_FILE;
+       if (S_ISDIR(mode))
+               return DEL_FOR_DIR;
+       if (S_ISLNK(mode))
+               return DEL_FOR_SYMLINK;
+       if (IS_DEVICE(mode))
+               return DEL_FOR_DEVICE;
+       if (IS_SPECIAL(mode))
+               return DEL_FOR_SPECIAL;
+       exit_cleanup(RERR_UNSUPPORTED); /* IMPOSSIBLE */
+}