+ zap_dir = (flags & DEL_FORCE_RECURSE || (force_delete && recurse))
+ && !(flags & DEL_NO_RECURSE);
+ if (dry_run && zap_dir) {
+ ok = 0;
+ errno = ENOTEMPTY;
+ } else if (make_backups && !backup_dir && !is_backup_file(fname)
+ && !(flags & DEL_FORCE_RECURSE))
+ ok = make_backup(fname);
+ else
+ ok = do_rmdir(fname) == 0;
+ if (ok) {
+ if ((verbose || log_format) && !(flags & DEL_TERSE))
+ log_delete(fname, mode);
+ deletion_count++;
+ return 0;
+ }
+ if (errno == ENOENT)
+ return 0;
+ if (!zap_dir || (errno != ENOTEMPTY && errno != EEXIST)) {
+ rsyserr(FERROR, errno, "delete_file: rmdir %s failed",
+ full_fname(fname));
+ return -1;
+ }
+ flags |= DEL_FORCE_RECURSE;
+
+ save_filters = push_local_filters(fname, strlen(fname));
+
+ dirlist = get_dirlist(fname, 0);
+ for (j = dirlist->count; j--; ) {
+ struct file_struct *fp = dirlist->files[j];
+ f_name_to(fp, buf);
+ if (delete_file(buf, fp->mode, flags & ~DEL_TERSE) != 0) {
+ flist_free(dirlist);
+ return -1;
+ }
+ }
+ flist_free(dirlist);
+
+ pop_local_filters(save_filters);
+
+ if (max_delete && deletion_count >= max_delete)
+ return -1;
+
+ if (do_rmdir(fname) == 0) {
+ if ((verbose || log_format) && !(flags & DEL_TERSE))
+ log_delete(fname, mode);
+ deletion_count++;
+ } else if (errno != ENOTEMPTY && errno != ENOENT) {
+ rsyserr(FERROR, errno, "delete_file: rmdir %s failed",
+ full_fname(fname));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* If an item in dir_list is not found in full_list, delete it from the
+ * filesystem. */
+static void delete_missing(struct file_list *full_list,
+ struct file_list *dir_list, const char *dirname)
+{
+ char fbuf[MAXPATHLEN];
+ int i;
+
+ if (max_delete && deletion_count >= max_delete)
+ return;
+
+ if (verbose > 2)
+ rprintf(FINFO, "delete_missing(%s)\n", safe_fname(dirname));
+
+ for (i = dir_list->count; i--; ) {
+ if (!dir_list->files[i]->basename)
+ continue;
+ if (flist_find(full_list, dir_list->files[i]) < 0) {
+ char *fn = f_name_to(dir_list->files[i], fbuf);
+ int mode = dir_list->files[i]->mode;
+ if (delete_file(fn, mode, DEL_FORCE_RECURSE) < 0)
+ break;
+ }
+ }