/*-1* Copyright (c) 2015 Baptiste Daroussin <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer9* in this position and unchanged.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR15* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES16* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.17* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,18* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT19* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,20* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY21* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT22* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF23* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.24*/2526#include <sys/stat.h>2728#include <assert.h>29#include <dirent.h>30#include <unistd.h>31#include <fcntl.h>32#include "pkg.h"33#include "private/pkg.h"34#include "private/event.h"3536static void37rm_rf(int basefd, const char *path)38{39int dirfd;40DIR *d;41struct dirent *e;42struct stat st;4344if (basefd != -1) {45while (*path == '/')46path++;4748dirfd = openat(basefd, path, O_DIRECTORY|O_CLOEXEC);49if (dirfd == -1) {50pkg_emit_errno("openat", path);51return;52}53} else {54dirfd = dup(pkg_get_cachedirfd());55if (dirfd == -1) {56pkg_emit_error("Cannot open the cache directory");57return;58}59}6061d = fdopendir(dirfd);62while ((e = readdir(d)) != NULL) {63if (STREQ(e->d_name, ".") || STREQ(e->d_name, ".."))64continue;65if (fstatat(dirfd, e->d_name, &st, AT_SYMLINK_NOFOLLOW) != 0) {66pkg_emit_errno("fstatat", path);67continue;68}69if (S_ISDIR(st.st_mode))70rm_rf(dirfd, e->d_name);71else72unlinkat(dirfd, e->d_name, 0);73}74closedir(d);75if (basefd == -1)76return;77if (fstatat(basefd, path, &st, AT_SYMLINK_NOFOLLOW) != 0)78return;79unlinkat(basefd, path, S_ISDIR(st.st_mode) ? AT_REMOVEDIR : 0);80}8182void83pkg_cache_full_clean(void)84{8586if (!pkg_object_bool(pkg_config_get("AUTOCLEAN")))87return;8889pkg_debug(1, "Cleaning up cachedir");90rm_rf(-1, NULL);91}929394