Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/libpkg/clean_cache.c
2065 views
1
/*-
2
* Copyright (c) 2015 Baptiste Daroussin <[email protected]>
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer
10
* in this position and unchanged.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
*/
26
27
#include <sys/stat.h>
28
29
#include <assert.h>
30
#include <dirent.h>
31
#include <unistd.h>
32
#include <fcntl.h>
33
#include "pkg.h"
34
#include "private/pkg.h"
35
#include "private/event.h"
36
37
static void
38
rm_rf(int basefd, const char *path)
39
{
40
int dirfd;
41
DIR *d;
42
struct dirent *e;
43
struct stat st;
44
45
if (basefd != -1) {
46
while (*path == '/')
47
path++;
48
49
dirfd = openat(basefd, path, O_DIRECTORY|O_CLOEXEC);
50
if (dirfd == -1) {
51
pkg_emit_errno("openat", path);
52
return;
53
}
54
} else {
55
dirfd = dup(pkg_get_cachedirfd());
56
if (dirfd == -1) {
57
pkg_emit_error("Cannot open the cache directory");
58
return;
59
}
60
}
61
62
d = fdopendir(dirfd);
63
while ((e = readdir(d)) != NULL) {
64
if (STREQ(e->d_name, ".") || STREQ(e->d_name, ".."))
65
continue;
66
if (fstatat(dirfd, e->d_name, &st, AT_SYMLINK_NOFOLLOW) != 0) {
67
pkg_emit_errno("fstatat", path);
68
continue;
69
}
70
if (S_ISDIR(st.st_mode))
71
rm_rf(dirfd, e->d_name);
72
else
73
unlinkat(dirfd, e->d_name, 0);
74
}
75
closedir(d);
76
if (basefd == -1)
77
return;
78
if (fstatat(basefd, path, &st, AT_SYMLINK_NOFOLLOW) != 0)
79
return;
80
unlinkat(basefd, path, S_ISDIR(st.st_mode) ? AT_REMOVEDIR : 0);
81
}
82
83
void
84
pkg_cache_full_clean(void)
85
{
86
87
if (!pkg_object_bool(pkg_config_get("AUTOCLEAN")))
88
return;
89
90
pkg_debug(1, "Cleaning up cachedir");
91
rm_rf(-1, NULL);
92
}
93
94