xbps-bin(8): added a new target "find-files".

This new target 'find-files' can be used to find which installed
package(s) own a file. Exact matches like "/bin/mount" or patterns
like "/usr/lib/libb[ao]b\*" can be specified.
This commit is contained in:
Juan RP 2010-10-27 00:25:02 +02:00
parent 992583311b
commit ef7da88db1
6 changed files with 163 additions and 3 deletions

4
NEWS
View File

@ -1,5 +1,9 @@
xbps-0.6.2 (???):
* xbps-bin(8): added a new target 'find-files' to find which installed
package(s) own a file. Exact matches "/bin/mount" or patterns
"/usr/lib/libb[ao]b\*" can be specified.
* When updating a package and removing obsolete files, don't forget to
remove those directories if they were empty.

View File

@ -3,7 +3,7 @@ TOPDIR = ../..
BIN = xbps-bin
OBJS = check.o install.o main.o remove.o show-deps.o
OBJS += show-info-files.o ../xbps-repo/util.o
OBJS += show-info-files.o ../xbps-repo/util.o find-files.o
MAN = $(BIN).8
include $(TOPDIR)/prog.mk

View File

@ -38,5 +38,6 @@ int xbps_show_pkg_deps(const char *);
int xbps_show_pkg_reverse_deps(const char *);
int show_pkg_info_from_metadir(const char *);
int show_pkg_files_from_metadir(const char *);
int find_files_in_packages(const char *);
#endif /* !_XBPS_BIN_DEFS_H_ */

129
bin/xbps-bin/find-files.c Normal file
View File

@ -0,0 +1,129 @@
/*-
* 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 <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fnmatch.h>
#include <dirent.h>
#include <xbps_api.h>
#include "../xbps-repo/defs.h"
#include "defs.h"
static int
match_files_by_pattern(prop_dictionary_t pkg_filesd, prop_dictionary_keysym_t key,
const char *pattern, const char *pkgname)
{
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 (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) ||
(xbps_pkgpattern_match(filestr, __UNCONST(pattern)) == 1))
printf("%s: %s (%s)\n", pkgname, filestr, typestr);
}
prop_object_iterator_release(iter);
return 0;
}
int
find_files_in_packages(const char *pattern)
{
prop_dictionary_t pkg_filesd;
prop_array_t files_keys;
DIR *dirp;
struct dirent *dp;
char *path, *filesplist;
int rv = 0;
unsigned int i, count;
path = xbps_xasprintf("%s/%s/metadata", xbps_get_rootdir(),
XBPS_META_PATH);
if (path == NULL)
return -1;
if ((dirp = opendir(path)) == NULL) {
free(path);
return -1;
}
while ((dp = readdir(dirp)) != NULL) {
if ((strcmp(dp->d_name, ".") == 0) ||
(strcmp(dp->d_name, "..") == 0))
continue;
filesplist = xbps_xasprintf("%s/%s/%s", path, dp->d_name,
XBPS_PKGFILES);
if (filesplist == NULL) {
rv = -1;
break;
}
pkg_filesd = prop_dictionary_internalize_from_zfile(filesplist);
if (pkg_filesd == NULL) {
free(filesplist);
if (errno == ENOENT)
continue;
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, dp->d_name);
if (rv == -1)
break;
}
prop_object_release(pkg_filesd);
free(filesplist);
if (rv == -1)
break;
}
(void)closedir(dirp);
free(path);
return rv;
}

View File

@ -43,6 +43,7 @@ usage(void)
" autoremove\n"
" autoupdate\n"
" check\t\t[<pkgname>|<all>]\n"
" find-files\t<pattern>\n"
" install\t\t[<pkgname(s)>|<pkgpattern(s)>]\n"
" list\n"
" list-manual\n"
@ -343,6 +344,16 @@ main(int argc, char **argv)
rv = xbps_show_pkg_reverse_deps(argv[1]);
} else if (strcasecmp(argv[0], "find-files") == 0) {
/*
* Find files matched by a pattern from installed
* packages.
*/
if (argc != 2)
usage();
rv = find_files_in_packages(argv[1]);
} else {
usage();
}

View File

@ -2,12 +2,12 @@
.\" Title: xbps-bin
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: 05/03/2010
.\" Date: 26/10/2010
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
.TH "XBPS\-BIN" "8" "05/03/2010" "\ \&" "\ \&"
.TH "XBPS\-BIN" "8" "26/10/2010" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@ -122,6 +122,11 @@ packages currently installed will be checked, otherwise only
\fBpkgname\fR\&.
.RE
.PP
\fBfind-files\fR \fR\fB\fIpattern\fR\fR
.RS 4
Prints the name of the installed "\fBpackage(s)\fR" matching the \fBpattern\fR on its file list.
.RE
.PP
\fBinstall \fR\fB\fIpkgname(s)\fR\fR\fB | \fR\fB\fIpkgpattern(s)\fR\fR
.RS 4
Install binary package(s) from repository pool by specifying "\fBpkgname(s)\fR" or "\fBpackage pattern(s)\fR"\&. The first repository matching the arguments will be used\&. The package(s) will be
@ -324,6 +329,16 @@ $ xbps\-bin install "\fBfoo>=3\&.0\fR"
.RS 4
$ xbps\-bin install foo "\fBblah⇐4\&.0\fR" baz\-2\&.0 "\fBblob>4\&.[0\-9]\fR"
.RE
.PP
\fBFind the package that owns the file \fB/bin/mount\fR:\fR
.RS 4
$ xbps\-bin find\-files /bin/mount
.RE
.PP
\fBFind the packages that match the pattern "\fB/usr/lib/libav\&*\fR":
.RS 4
$ xbps\-bin find\-files "/usr/lib/libav\&*"
.RE
.SH "BUGS"
.sp
Probably, but I try to make this not happen\&. Use it under your own responsability and enjoy your life\&.