diff --git a/NEWS b/NEWS index 10853360..924b85f1 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,12 @@ +xbps-0.16 (???): + + * xbps-repo(8): new target: 'clean'. This removes obsolete binpkgs + from cachedir, either because the binpkg is not available in repository + pool anymore or because its sha256 hash that doesn't match with the + one matched in repository index file. + + * Miscellanous API cleanups (API/ABI incompat changes). + xbps-0.15 (2012-04-06): * xbps-bin(8): a new test for the 'check' target to find stale entries diff --git a/bin/xbps-repo/Makefile b/bin/xbps-repo/Makefile index a6af0cc1..cb15c324 100644 --- a/bin/xbps-repo/Makefile +++ b/bin/xbps-repo/Makefile @@ -3,7 +3,7 @@ TOPDIR = ../.. BIN = xbps-repo OBJS = main.o index.o show.o find-files.o list.o -OBJS += index-files.o +OBJS += index-files.o clean.o OBJS += ../xbps-bin/fetch_cb.o ../xbps-bin/util.o OBJS += ../xbps-bin/state_cb.o ../xbps-bin/list.o MAN = $(BIN).8 diff --git a/bin/xbps-repo/clean.c b/bin/xbps-repo/clean.c new file mode 100644 index 00000000..28007fff --- /dev/null +++ b/bin/xbps-repo/clean.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2012 Juan Romero Pardines. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "defs.h" + +int +cachedir_clean(void) +{ + prop_dictionary_t pkg_propsd, repo_pkgd; + struct xbps_handle *xhp = xbps_handle_get(); + DIR *dirp; + struct dirent *dp; + const char *pkgver, *rsha256; + char *binpkg; + int rv = 0; + + dirp = opendir(xhp->cachedir); + if (dirp == NULL) { + xbps_error_printf("cannot access to cachedir %s: %s\n", + xhp->cachedir, strerror(errno)); + return errno; + } + + while ((dp = readdir(dirp)) != NULL) { + if ((strcmp(dp->d_name, ".") == 0) || + (strcmp(dp->d_name, "..") == 0)) + continue; + + /* only process xbps binary packages, ignore something else */ + if (!strstr(dp->d_name, ".xbps")) { + printf("ignoring unknown file: %s\n", dp->d_name); + continue; + } + /* Internalize props.plist dictionary from binary pkg */ + binpkg = xbps_xasprintf("%s/%s", xhp->cachedir, dp->d_name); + assert(binpkg != NULL); + pkg_propsd = + xbps_dictionary_metadata_plist_by_url(binpkg, XBPS_PKGPROPS); + if (pkg_propsd == NULL) { + xbps_error_printf("Failed to read from %s: %s\n", + dp->d_name, strerror(errno)); + free(binpkg); + rv = errno; + break; + } + prop_dictionary_get_cstring_nocopy(pkg_propsd, "pkgver", &pkgver); + /* + * Remove binary pkg if it's not registered in any repository + * or if hash doesn't match. + */ + repo_pkgd = xbps_repository_pool_find_pkg_exact(pkgver); + if (repo_pkgd) { + prop_dictionary_get_cstring_nocopy(repo_pkgd, + "filename-sha256", &rsha256); + if (xbps_file_hash_check(binpkg, rsha256) == ERANGE) { + printf("Removed %s from cachedir (sha256 mismatch)\n", + dp->d_name); + unlink(binpkg); + } + prop_object_release(repo_pkgd); + free(binpkg); + continue; + } + printf("Removed %s from cachedir (obsolete)\n", dp->d_name); + unlink(binpkg); + free(binpkg); + } + closedir(dirp); + return rv; +} diff --git a/bin/xbps-repo/defs.h b/bin/xbps-repo/defs.h index bcbd906a..a0963750 100644 --- a/bin/xbps-repo/defs.h +++ b/bin/xbps-repo/defs.h @@ -53,4 +53,7 @@ int show_pkg_info_from_repolist(const char *, const char *); int show_pkg_deps_from_repolist(const char *); int show_pkg_namedesc(prop_object_t, void *, bool *); +/* From clean.c */ +int cachedir_clean(void); + #endif /* !_XBPS_REPO_DEFS_H_ */ diff --git a/bin/xbps-repo/main.c b/bin/xbps-repo/main.c index b7e86069..85889796 100644 --- a/bin/xbps-repo/main.c +++ b/bin/xbps-repo/main.c @@ -53,6 +53,8 @@ usage(bool fail) " -r rootdir Full path to rootdir\n" " -V Show XBPS version\n\n" "[targets]\n" + " clean\n" + " Removes obsolete binary packages from cachedir.\n" " find-files [patterns]\n" " Print package name/version for any pattern matched.\n" " genindex \n" @@ -277,6 +279,12 @@ main(int argc, char **argv) xbps_error_printf("xbps-repo: no repositories " "currently registered!\n"); } + } else if (strcasecmp(argv[0], "clean") == 0) { + /* Cleans up cache directory */ + if (argc != 1) + usage(true); + + rv = cachedir_clean(); } else { usage(true); } diff --git a/bin/xbps-repo/xbps-repo.8 b/bin/xbps-repo/xbps-repo.8 index c182b493..8e0faa91 100644 --- a/bin/xbps-repo/xbps-repo.8 +++ b/bin/xbps-repo/xbps-repo.8 @@ -1,4 +1,4 @@ -.Dd February 20, 2012 +.Dd May 5, 2012 .Os Void GNU/Linux .Dt xbps-repo 8 .Sh NAME @@ -54,6 +54,11 @@ Shows the current XBPS release version (version, API, index). Please note that all targets are case insensitive. .Pp .Bl -tag -width ident +.It Sy clean +Cleans the +.Em cachedir +and removes obsolete binary packages, either because they are not available +anymore in repository pool or because its sha256 hash doesn't match. .It Sy find-files Ar pattern Ar [patterns ...] Prints the name of .Em package(s)