From ece608a080733be056dacdf2003fbd6cb5cc37f0 Mon Sep 17 00:00:00 2001 From: Juan RP Date: Wed, 15 Dec 2010 15:14:44 +0100 Subject: [PATCH] xbps-repo(8): implemented 'find-files' target. --- NEWS | 4 ++ bin/xbps-repo/Makefile | 2 +- bin/xbps-repo/defs.h | 6 ++ bin/xbps-repo/find-files.c | 132 +++++++++++++++++++++++++++++++++++++ bin/xbps-repo/main.c | 7 ++ bin/xbps-repo/xbps-repo.8 | 21 +++--- 6 files changed, 161 insertions(+), 11 deletions(-) create mode 100644 bin/xbps-repo/find-files.c diff --git a/NEWS b/NEWS index 5734dc2d..8d17d51c 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,8 @@ xbps-0.7.0 (?) + + * xbps-repo(8): implemented the 'find-files' target to print which packages + own a file, link, directory, etc. Analogue to the one implemented in + xbps-bin(8). Works for local and remote repository, fetching info on-the-fly. * xbps-bin(8): added -F flag for the remove target. Unless it's set, packages that are dependencies of other installed packages won't be removed. diff --git a/bin/xbps-repo/Makefile b/bin/xbps-repo/Makefile index 15015bae..59fdb3f6 100644 --- a/bin/xbps-repo/Makefile +++ b/bin/xbps-repo/Makefile @@ -2,7 +2,7 @@ TOPDIR = ../.. -include $(TOPDIR)/config.mk BIN = xbps-repo -OBJS = main.o util.o index.o repository.o +OBJS = main.o util.o index.o repository.o find-files.o MAN = $(BIN).8 include $(TOPDIR)/prog.mk diff --git a/bin/xbps-repo/defs.h b/bin/xbps-repo/defs.h index 68668a08..1d67005c 100644 --- a/bin/xbps-repo/defs.h +++ b/bin/xbps-repo/defs.h @@ -26,6 +26,10 @@ #ifndef _XBPS_REPO_DEFS_H_ #define _XBPS_REPO_DEFS_H_ +#ifndef __UNCONST +#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) +#endif + /* From index.c */ int xbps_repo_genindex(const char *); /* From repository.c */ @@ -43,6 +47,8 @@ int list_strings_in_array(prop_object_t, void *, bool *); int list_strings_sep_in_array(prop_object_t, void *, bool *); size_t find_longest_pkgver(prop_dictionary_t); void print_package_line(const char *); +/* From find-files.c */ +int repo_find_files_in_packages(const char *); struct repo_search_data { char *pattern; diff --git a/bin/xbps-repo/find-files.c b/bin/xbps-repo/find-files.c new file mode 100644 index 00000000..ddc1c304 --- /dev/null +++ b/bin/xbps-repo/find-files.c @@ -0,0 +1,132 @@ +/*- + * Copyright (c) 2010 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 "defs.h" + +static int +match_files_by_pattern(prop_dictionary_t pkg_filesd, prop_dictionary_keysym_t key, + const char *pattern, const char *pkgver) +{ + prop_object_iterator_t iter; + prop_array_t array; + prop_object_t obj; + const char *keyname, *filestr, *typestr; + + keyname = prop_dictionary_keysym_cstring_nocopy(key); + array = prop_dictionary_get_keysym(pkg_filesd, key); + if (prop_object_type(array) != PROP_TYPE_ARRAY) + return 0; + + if (strcmp(keyname, "files") == 0) + typestr = "regular file"; + else if (strcmp(keyname, "dirs") == 0) + typestr = "directory"; + else if (strcmp(keyname, "links") == 0) + typestr = "link"; + else + typestr = "configuration file"; + + iter = prop_array_iterator(array); + while ((obj = prop_object_iterator_next(iter))) { + prop_dictionary_get_cstring_nocopy(obj, "file", &filestr); + if ((strcmp(filestr, pattern) == 0) || + (strstr(filestr, pattern)) || + (xbps_pkgpattern_match(filestr, __UNCONST(pattern)) == 1)) + printf(" %s: %s (%s)\n", pkgver, filestr, typestr); + } + prop_object_iterator_release(iter); + return 0; +} + +static int +find_files_in_package(struct repository_pool_index *rpi, void *arg, bool *done) +{ + prop_dictionary_t pkg_filesd; + prop_array_t repo_pkgs, files_keys; + prop_object_t obj; + prop_object_iterator_t iter; + const char *pkgname, *pkgver, *pattern = arg; + char *url; + int rv = 0; + unsigned int i, count; + + (void)done; + + repo_pkgs = prop_dictionary_get(rpi->rpi_repod, "packages"); + if (repo_pkgs == NULL) + return -1; + + iter = prop_array_iterator(repo_pkgs); + if (iter == NULL) + return -1; + + printf("Looking in repository '%s', please wait...\n", rpi->rpi_uri); + while ((obj = prop_object_iterator_next(iter))) { + url = xbps_repository_get_path_from_pkg_dict(obj, rpi->rpi_uri); + if (url == NULL) { + rv = -1; + break; + } + prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); + prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); + pkg_filesd = xbps_repository_get_pkg_plist_dict_from_url(url, + XBPS_PKGFILES); + free(url); + if (pkg_filesd == NULL) { + fprintf(stderr, "E: couldn't get '%s' from '%s' " + "in repo '%s: %s'\n", XBPS_PKGFILES, pkgname, rpi->rpi_uri, + strerror(errno)); + rv = -1; + break; + } + files_keys = prop_dictionary_all_keys(pkg_filesd); + count = prop_array_count(files_keys); + for (i = 0; i < count; i++) { + rv = match_files_by_pattern(pkg_filesd, + prop_array_get(files_keys, i), pattern, pkgver); + if (rv == -1) + break; + } + prop_object_release(pkg_filesd); + if (rv == -1) + break; + } + prop_object_iterator_release(iter); + return rv; +} + +int +repo_find_files_in_packages(const char *pattern) +{ + return xbps_repository_pool_foreach(find_files_in_package, + __UNCONST(pattern)); +} diff --git a/bin/xbps-repo/main.c b/bin/xbps-repo/main.c index da5e4b3e..5d590a61 100644 --- a/bin/xbps-repo/main.c +++ b/bin/xbps-repo/main.c @@ -200,6 +200,13 @@ main(int argc, char **argv) rv = show_pkg_files(pkgd); prop_object_release(pkgd); + } else if (strcasecmp(argv[0], "find-files") == 0) { + /* Finds files by patterns, exact matches and components. */ + if (argc != 2) + usage(); + + rv = repo_find_files_in_packages(argv[1]); + } else if (strcasecmp(argv[0], "genindex") == 0) { /* Generates a package repository index plist file. */ if (argc != 2) diff --git a/bin/xbps-repo/xbps-repo.8 b/bin/xbps-repo/xbps-repo.8 index bcf6e584..92642486 100644 --- a/bin/xbps-repo/xbps-repo.8 +++ b/bin/xbps-repo/xbps-repo.8 @@ -1,13 +1,4 @@ -'\" t -.\" Title: xbps-repo -.\" Author: [see the "AUTHORS" section] -.\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 18/11/2010 -.\" Manual: \ \& -.\" Source: \ \& -.\" Language: English -.\" -.TH "XBPS\-REPO" "8" "18/11/2010" "\ \&" "\ \&" +.TH "XBPS\-REPO" "8" "15/12/2010" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -80,6 +71,16 @@ to the repository pool\&. Local (by specifying a \fBHTTP/HTTPS/FTP URL\fR) repositories can be specified\&. .RE .PP +\fBfind\-files\fR \fIpattern\fR +.RS 4 +Prints the name for any package registered in the repository pool, that owns +the file matched by \fIpattern\fR\&. Exact matches and wildcards can be +specified\&. Please note that this will look in all packages registered +from all repositories currently registered, so if packages are not in \fIcachedir\fR +it will have to connect remotely to the repository to fetch the information +\fIon the fly\fR. +.RE +.PP \fBgenindex\fR \fI/path/to/local/repo\fR .RS 4 Generates a package index for a local repository as specified in its argument\&. It will look for archives with