2 * Deletion routines used in rsync.
4 * Copyright (C) 1996-2000 Andrew Tridgell
5 * Copyright (C) 1996 Paul Mackerras
6 * Copyright (C) 2002 Martin Pool <mbp@samba.org>
7 * Copyright (C) 2003-2020 Wayne Davison
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, visit the http://fsf.org website.
26 extern int make_backups
;
27 extern int max_delete
;
28 extern char *backup_dir
;
29 extern char *backup_suffix
;
30 extern int backup_suffix_len
;
31 extern struct stats stats
;
33 int ignore_perishable
= 0;
34 int non_perishable_cnt
= 0;
35 int skipped_deletes
= 0;
37 static inline int is_backup_file(char *fn
)
39 int k
= strlen(fn
) - backup_suffix_len
;
40 return k
> 0 && strcmp(fn
+k
, backup_suffix
) == 0;
43 /* The directory is about to be deleted: if DEL_RECURSE is given, delete all
44 * its contents, otherwise just checks for content. Returns DR_SUCCESS or
45 * DR_NOT_EMPTY. Note that fname must point to a MAXPATHLEN buffer! (The
46 * buffer is used for recursion, but returned unchanged.)
48 static enum delret
delete_dir_contents(char *fname
, uint16 flags
)
50 struct file_list
*dirlist
;
57 if (DEBUG_GTE(DEL
, 3)) {
58 rprintf(FINFO
, "delete_dir_contents(%s) flags=%d\n",
63 save_filters
= push_local_filters(fname
, dlen
);
65 non_perishable_cnt
= 0;
66 dirlist
= get_dirlist(fname
, dlen
, 0);
67 ret
= non_perishable_cnt
? DR_NOT_EMPTY
: DR_SUCCESS
;
72 if (!(flags
& DEL_RECURSE
)) {
78 if (dlen
!= 1 || *fname
!= '/')
80 remainder
= MAXPATHLEN
- (p
- fname
);
82 /* We do our own recursion, so make delete_item() non-recursive. */
83 flags
= (flags
& ~(DEL_RECURSE
|DEL_MAKE_ROOM
|DEL_NO_UID_WRITE
))
86 for (j
= dirlist
->used
; j
--; ) {
87 struct file_struct
*fp
= dirlist
->files
[j
];
89 if (fp
->flags
& FLAG_MOUNT_DIR
&& S_ISDIR(fp
->mode
)) {
90 if (DEBUG_GTE(DEL
, 1)) {
92 "mount point, %s, pins parent directory\n",
99 strlcpy(p
, fp
->basename
, remainder
);
100 if (!(fp
->mode
& S_IWUSR
) && !am_root
&& fp
->flags
& FLAG_OWNED_BY_US
)
101 do_chmod(fname
, fp
->mode
| S_IWUSR
);
102 /* Save stack by recursing to ourself directly. */
103 if (S_ISDIR(fp
->mode
)) {
104 if (delete_dir_contents(fname
, flags
| DEL_RECURSE
) != DR_SUCCESS
)
107 if (delete_item(fname
, fp
->mode
, flags
) != DR_SUCCESS
)
115 pop_local_filters(save_filters
);
117 if (ret
== DR_NOT_EMPTY
) {
118 rprintf(FINFO
, "cannot delete non-empty directory: %s\n",
124 /* Delete a file or directory. If DEL_RECURSE is set in the flags, this will
125 * delete recursively.
127 * Note that fbuf must point to a MAXPATHLEN buffer if the mode indicates it's
128 * a directory! (The buffer is used for recursion, but returned unchanged.)
130 enum delret
delete_item(char *fbuf
, uint16 mode
, uint16 flags
)
136 if (DEBUG_GTE(DEL
, 2)) {
137 rprintf(FINFO
, "delete_item(%s) mode=%o flags=%d\n",
138 fbuf
, (int)mode
, (int)flags
);
141 if (flags
& DEL_NO_UID_WRITE
)
142 do_chmod(fbuf
, mode
| S_IWUSR
);
144 if (S_ISDIR(mode
) && !(flags
& DEL_DIR_IS_EMPTY
)) {
145 /* This only happens on the first call to delete_item() since
146 * delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */
147 ignore_perishable
= 1;
148 /* If DEL_RECURSE is not set, this just reports emptiness. */
149 ret
= delete_dir_contents(fbuf
, flags
);
150 ignore_perishable
= 0;
151 if (ret
== DR_NOT_EMPTY
|| ret
== DR_AT_LIMIT
)
153 /* OK: try to delete the directory. */
156 if (!(flags
& DEL_MAKE_ROOM
) && max_delete
>= 0 && stats
.deleted_files
>= max_delete
) {
163 ok
= do_rmdir(fbuf
) == 0;
165 if (make_backups
> 0 && !(flags
& DEL_FOR_BACKUP
) && (backup_dir
|| !is_backup_file(fbuf
))) {
166 what
= "make_backup";
167 ok
= make_backup(fbuf
, True
);
170 ok
= robust_unlink(fbuf
) == 0;
174 ok
= robust_unlink(fbuf
) == 0;
179 if (!(flags
& DEL_MAKE_ROOM
)) {
180 log_delete(fbuf
, mode
);
181 stats
.deleted_files
++;
183 /* Nothing more to count */
184 } else if (S_ISDIR(mode
))
185 stats
.deleted_dirs
++;
187 else if (S_ISLNK(mode
))
188 stats
.deleted_symlinks
++;
190 else if (IS_DEVICE(mode
))
191 stats
.deleted_symlinks
++;
193 stats
.deleted_specials
++;
197 if (S_ISDIR(mode
) && errno
== ENOTEMPTY
) {
198 rprintf(FINFO
, "cannot delete non-empty directory: %s\n",
201 } else if (errno
!= ENOENT
) {
202 rsyserr(FERROR_XFER
, errno
, "delete_file: %s(%s) failed",
210 if (ret
!= DR_SUCCESS
&& flags
& DEL_MAKE_ROOM
) {
212 switch (flags
& DEL_MAKE_ROOM
) {
213 case DEL_FOR_FILE
: desc
= "regular file"; break;
214 case DEL_FOR_DIR
: desc
= "directory"; break;
215 case DEL_FOR_SYMLINK
: desc
= "symlink"; break;
216 case DEL_FOR_DEVICE
: desc
= "device file"; break;
217 case DEL_FOR_SPECIAL
: desc
= "special file"; break;
218 default: exit_cleanup(RERR_UNSUPPORTED
); /* IMPOSSIBLE */
220 rprintf(FERROR_XFER
, "could not make way for %s %s: %s\n",
221 flags
& DEL_FOR_BACKUP
? "backup" : "new",
227 uint16
get_del_for_flag(uint16 mode
)
234 return DEL_FOR_SYMLINK
;
236 return DEL_FOR_DEVICE
;
237 if (IS_SPECIAL(mode
))
238 return DEL_FOR_SPECIAL
;
239 exit_cleanup(RERR_UNSUPPORTED
); /* IMPOSSIBLE */