New utilities: xbps-{install,pkgdb,query,reconfigure,rindex} (WIP).

This commit is contained in:
Juan RP
2012-11-02 15:04:25 +01:00
parent 7fa8207cf3
commit b05ce9fe57
40 changed files with 5188 additions and 5 deletions

9
bin/xbps-query/Makefile Normal file
View File

@ -0,0 +1,9 @@
TOPDIR = ../..
-include $(TOPDIR)/config.mk
BIN = xbps-query
OBJS = main.o list.o show-deps.o show-info-files.o
OBJS += ownedby.o search.o
#MAN = $(BIN).8
include $(TOPDIR)/mk/prog.mk

68
bin/xbps-query/defs.h Normal file
View File

@ -0,0 +1,68 @@
/*-
* Copyright (c) 2009-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.
*/
#ifndef _XBPS_QUERY_DEFS_H_
#define _XBPS_QUERY_DEFS_H_
#include <xbps_api.h>
/* from show-deps.c */
int show_pkg_deps(struct xbps_handle *, const char *);
int show_pkg_revdeps(struct xbps_handle *, const char *);
int repo_show_pkg_deps(struct xbps_handle *, const char *);
/* from show-info-files.c */
void show_pkg_info(prop_dictionary_t);
void show_pkg_info_one(prop_dictionary_t, const char *);
int show_pkg_info_from_metadir(struct xbps_handle *, const char *,
const char *);
int show_pkg_files(prop_dictionary_t);
int show_pkg_files_from_metadir(struct xbps_handle *, const char *);
int repo_show_pkg_files(struct xbps_handle *, const char *);
int repo_show_pkg_info(struct xbps_handle *, const char *, const char *);
int repo_show_pkg_namedesc(struct xbps_handle *, prop_object_t, void *,
bool *);
/* from ownedby.c */
int ownedby(struct xbps_handle *, int, char **);
int repo_ownedby(struct xbps_handle *, int, char **);
/* From list.c */
size_t get_maxcols(void);
int list_strings_sep_in_array(struct xbps_handle *,
prop_object_t, void *, bool *);
size_t find_longest_pkgver(struct xbps_handle *, prop_object_t);
int list_pkgs_in_dict(struct xbps_handle *, prop_object_t, void *, bool *);
int list_manual_pkgs(struct xbps_handle *, prop_object_t, void *, bool *);
int list_orphans(struct xbps_handle *);
int list_pkgs_pkgdb(struct xbps_handle *);
int repo_list(struct xbps_handle *);
/* from search.c */
int repo_search(struct xbps_handle *, int, char **);
#endif /* !_XBPS_QUERY_DEFS_H_ */

238
bin/xbps-query/list.c Normal file
View File

@ -0,0 +1,238 @@
/*-
* Copyright (c) 2008-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 <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <sys/ioctl.h>
#include "defs.h"
struct list_pkgver_cb {
size_t pkgver_len;
size_t maxcols;
};
size_t
get_maxcols(void)
{
struct winsize ws;
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) == 0)
return ws.ws_col;
return 80;
}
int
list_pkgs_in_dict(struct xbps_handle *xhp,
prop_object_t obj,
void *arg,
bool *loop_done)
{
struct list_pkgver_cb *lpc = arg;
const char *pkgver, *short_desc, *arch;
char *tmp = NULL, *out = NULL;
size_t i, len = 0;
bool chkarch;
(void)xhp;
(void)loop_done;
chkarch = prop_dictionary_get_cstring_nocopy(obj, "architecture", &arch);
if (chkarch && !xbps_pkg_arch_match(xhp, arch, NULL))
return 0;
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(obj, "short_desc", &short_desc);
if (!pkgver && !short_desc)
return EINVAL;
tmp = calloc(1, lpc->pkgver_len + 1);
assert(tmp);
memcpy(tmp, pkgver, lpc->pkgver_len);
for (i = strlen(tmp); i < lpc->pkgver_len; i++)
tmp[i] = ' ';
tmp[i] = '\0';
len = strlen(tmp) + strlen(short_desc) + 1;
if (len > lpc->maxcols) {
out = malloc(lpc->maxcols);
assert(out);
snprintf(out, lpc->maxcols-2, "%s %s", tmp, short_desc);
strncat(out, "...", lpc->maxcols);
printf("%s\n", out);
free(out);
} else {
printf("%s %s\n", tmp, short_desc);
}
free(tmp);
return 0;
}
int
list_manual_pkgs(struct xbps_handle *xhp,
prop_object_t obj,
void *arg,
bool *loop_done)
{
const char *pkgver;
bool automatic = false;
(void)xhp;
(void)arg;
(void)loop_done;
prop_dictionary_get_bool(obj, "automatic-install", &automatic);
if (automatic == false) {
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
printf("%s\n", pkgver);
}
return 0;
}
int
list_orphans(struct xbps_handle *xhp)
{
prop_array_t orphans;
prop_object_iterator_t iter;
prop_object_t obj;
const char *pkgver;
orphans = xbps_find_pkg_orphans(xhp, NULL);
if (orphans == NULL)
return EINVAL;
if (prop_array_count(orphans) == 0)
return 0;
iter = prop_array_iterator(orphans);
if (iter == NULL)
return ENOMEM;
while ((obj = prop_object_iterator_next(iter)) != NULL) {
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
printf("%s\n", pkgver);
}
prop_object_iterator_release(iter);
return 0;
}
int
list_pkgs_pkgdb(struct xbps_handle *xhp)
{
struct list_pkgver_cb lpc;
lpc.pkgver_len = find_longest_pkgver(xhp, NULL);
lpc.maxcols = get_maxcols();
return xbps_pkgdb_foreach_cb(xhp, list_pkgs_in_dict, &lpc);
}
static int
repo_list_uri_cb(struct xbps_handle *xhp,
struct xbps_rpool_index *rpi,
void *arg,
bool *done)
{
(void)xhp;
(void)arg;
(void)done;
printf("%s (%zu packages)\n", rpi->uri,
(size_t)prop_array_count(rpi->repo));
return 0;
}
int
repo_list(struct xbps_handle *xhp)
{
int rv;
rv = xbps_rpool_foreach(xhp, repo_list_uri_cb, NULL);
if (rv != 0 && rv != ENOTSUP) {
fprintf(stderr, "Failed to initialize rpool: %s\n",
strerror(rv));
return rv;
}
return 0;
}
static int
_find_longest_pkgver_cb(struct xbps_handle *xhp,
prop_object_t obj,
void *arg,
bool *loop_done)
{
size_t *len = arg;
const char *pkgver;
(void)xhp;
(void)loop_done;
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
if (*len == 0 || strlen(pkgver) > *len)
*len = strlen(pkgver);
return 0;
}
size_t
find_longest_pkgver(struct xbps_handle *xhp, prop_object_t o)
{
size_t len = 0;
if (prop_object_type(o) == PROP_TYPE_ARRAY)
(void)xbps_callback_array_iter(xhp, o,
_find_longest_pkgver_cb, &len);
else
(void)xbps_pkgdb_foreach_cb(xhp,
_find_longest_pkgver_cb, &len);
return len;
}
int
list_strings_sep_in_array(struct xbps_handle *xhp,
prop_object_t obj,
void *arg,
bool *loop_done)
{
const char *sep = arg;
(void)xhp;
(void)loop_done;
printf("%s%s\n", sep ? sep : "", prop_string_cstring_nocopy(obj));
return 0;
}

247
bin/xbps-query/main.c Normal file
View File

@ -0,0 +1,247 @@
/*-
* Copyright (c) 2008-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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <xbps_api.h>
#include "defs.h"
static void __attribute__((noreturn))
usage(bool fail)
{
fprintf(stdout,
"Usage: xbps-query [OPTIONS...] [PKGNAME]\n"
"\nOPTIONS\n"
" -C --config <file> Full path to configuration file\n"
" -c --cachedir <dir> Full path to cachedir\n"
" -D --defrepo <uri> Default repository to be used if config not set\n"
" -d --debug Debug mode shown to stderr\n"
" -h --help Print help usage\n"
" -R --repository Enable repository mode\n"
" -r --rootdir <dir> Full path to rootdir\n"
" -V --version Show XBPS version\n"
" -v --verbose Verbose messages\n"
"\nMODE [only one mode may be specified]\n"
" -l --list-pkgs List available packages\n"
" -L --list-repos List working repositories\n"
" -m --list-manual-pkgs List packages installed explicitly\n"
" -M --list-orphans List package orphans\n"
" -o --ownedby PATTERN(s) Search for packages owning PATTERN(s)\n"
" -s --search PATTERN(s) Search for packages matching PATTERN(s)\n"
" -f --files Show files for PKGNAME\n"
" -p --property PROP,... Show properties for PKGNAME\n"
" -x --deps Show dependencies for PKGNAME\n"
" -X --revdeps Show reverse dependencies for PKGNAME\n");
exit(fail ? EXIT_FAILURE : EXIT_SUCCESS);
}
int
main(int argc, char **argv)
{
const char *shortopts = "C:c:D:dfhLlmMop:Rr:sVvXx";
const struct option longopts[] = {
{ "config", required_argument, NULL, 'C' },
{ "cachedir", required_argument, NULL, 'c' },
{ "defrepo", required_argument, NULL, 'D' },
{ "debug", no_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{ "list-repos", no_argument, NULL, 'L' },
{ "list-pkgs", no_argument, NULL, 'l' },
{ "list-manual-pkgs", no_argument, NULL, 'm' },
{ "list-orphans", no_argument, NULL, 'M' },
{ "ownedby", no_argument, NULL, 'o' },
{ "property", required_argument, NULL, 'p' },
{ "repository-mode", no_argument, NULL, 'R' },
{ "rootdir", required_argument, NULL, 'r' },
{ "search", no_argument, NULL, 's' },
{ "version", no_argument, NULL, 'V' },
{ "verbose", no_argument, NULL, 'v' },
{ "files", no_argument, NULL, 'f' },
{ "deps", no_argument, NULL, 'x' },
{ "revdeps", no_argument, NULL, 'X' },
{ NULL, 0, NULL, 0 },
};
struct xbps_handle xh;
const char *rootdir, *cachedir, *conffile, *props, *defrepo;
int c, flags, rv;
bool list_pkgs, list_repos, orphans, own;
bool list_manual, show_prop, show_files, show_deps, show_rdeps;
bool show, search, repo_mode, opmode;
rootdir = cachedir = conffile = defrepo = props = NULL;
flags = rv = c = 0;
list_pkgs = list_repos = orphans = search = own = false;
list_manual = show_prop = show_files = search = false;
show = show_deps = show_rdeps = false;
repo_mode = opmode = false;
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
switch (c) {
case 'C':
conffile = optarg;
break;
case 'c':
cachedir = optarg;
break;
case 'D':
defrepo = optarg;
break;
case 'd':
flags |= XBPS_FLAG_DEBUG;
break;
case 'f':
show_files = opmode = true;
break;
case 'h':
usage(false);
/* NOTREACHED */
case 'L':
list_repos = opmode = true;
break;
case 'l':
list_pkgs = opmode = true;
break;
case 'm':
list_manual = opmode = true;
break;
case 'M':
orphans = opmode = true;
break;
case 'o':
own = opmode = true;
break;
case 'p':
props = optarg;
show_prop = opmode = true;
break;
case 'R':
repo_mode = true;
break;
case 'r':
rootdir = optarg;
break;
case 's':
search = opmode = true;
break;
case 'v':
flags |= XBPS_FLAG_VERBOSE;
break;
case 'V':
printf("%s\n", XBPS_RELVER);
exit(EXIT_SUCCESS);
case 'x':
show_deps = opmode = true;
break;
case 'X':
show_rdeps = opmode = true;
break;
case '?':
usage(true);
/* NOTREACHED */
}
}
if (!opmode && argc > optind)
show = true;
else if (!opmode && argc == optind)
usage(true);
/*
* Initialize libxbps.
*/
memset(&xh, 0, sizeof(xh));
xh.rootdir = rootdir;
xh.cachedir = cachedir;
xh.conffile = conffile;
xh.flags = flags;
xh.repository = defrepo;
if ((rv = xbps_init(&xh)) != 0) {
xbps_error_printf("Failed to initialize libxbps: %s\n",
strerror(rv));
exit(EXIT_FAILURE);
}
if (list_repos) {
/* list repositories */
rv = repo_list(&xh);
} else if (list_manual) {
/* list manual pkgs */
rv = xbps_pkgdb_foreach_cb(&xh, list_manual_pkgs, NULL);
} else if (list_pkgs) {
/* list available pkgs */
rv = list_pkgs_pkgdb(&xh);
} else if (orphans) {
/* list pkg orphans */
rv = list_orphans(&xh);
} else if (own) {
/* ownedby mode */
if (repo_mode)
rv = repo_ownedby(&xh, argc - optind, argv + optind);
else
rv = ownedby(&xh, argc - optind, argv + optind);
} else if (search) {
/* search mode */
rv = repo_search(&xh, argc - optind, argv + optind);
} else if (show || show_prop) {
/* show mode */
if (repo_mode)
rv = repo_show_pkg_info(&xh, argv[optind], props);
else
rv = show_pkg_info_from_metadir(&xh,
argv[optind], props);
} else if (show_files) {
/* show-files mode */
if (repo_mode)
rv = repo_show_pkg_files(&xh, argv[optind]);
else
rv = show_pkg_files_from_metadir(&xh, argv[optind]);
} else if (show_deps) {
/* show-deps mode */
if (repo_mode)
rv = repo_show_pkg_deps(&xh, argv[optind]);
else
rv = show_pkg_deps(&xh, argv[optind]);
} else if (show_rdeps) {
/* show-rdeps mode */
rv = show_pkg_revdeps(&xh, argv[optind]);
}
xbps_end(&xh);
exit(rv);
}

209
bin/xbps-query/ownedby.c Normal file
View File

@ -0,0 +1,209 @@
/*-
* Copyright (c) 2010-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 <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 "defs.h"
static int
match_files_by_pattern(prop_dictionary_t pkg_filesd,
prop_dictionary_keysym_t key,
int npatterns,
char **patterns,
const char *pkgname)
{
prop_object_iterator_t iter;
prop_array_t array;
prop_object_t obj;
const char *keyname, *filestr, *typestr;
int i;
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);
for (i = 0; i < npatterns; i++) {
if ((xbps_pkgpattern_match(filestr, patterns[i])) ||
(strcmp(filestr, patterns[i]) == 0))
printf("%s: %s (%s)\n", pkgname, filestr, typestr);
}
}
prop_object_iterator_release(iter);
return 0;
}
int
ownedby(struct xbps_handle *xhp, int npatterns, char **patterns)
{
prop_dictionary_t pkg_filesd;
prop_array_t files_keys;
DIR *dirp;
struct dirent *dp;
char *path;
int rv = 0;
unsigned int i, count;
path = xbps_xasprintf("%s/metadata", xhp->metadir);
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;
pkg_filesd = xbps_dictionary_from_metadata_plist(xhp,
dp->d_name, XBPS_PKGFILES);
if (pkg_filesd == NULL) {
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),
npatterns, patterns, dp->d_name);
if (rv == -1)
break;
}
prop_object_release(files_keys);
prop_object_release(pkg_filesd);
if (rv == -1)
break;
}
(void)closedir(dirp);
free(path);
return rv;
}
struct ffdata {
int npatterns;
char **patterns;
const char *repouri;
};
static void
repo_match_files_by_pattern(struct xbps_handle *xhp,
prop_dictionary_t pkg_filesd,
struct ffdata *ffd)
{
prop_array_t array;
const char *filestr, *pkgver, *arch;
size_t i;
int x;
prop_dictionary_get_cstring_nocopy(pkg_filesd, "architecture", &arch);
if (!xbps_pkg_arch_match(xhp, arch, NULL))
return;
array = prop_dictionary_get(pkg_filesd, "files");
for (i = 0; i < prop_array_count(array); i++) {
prop_array_get_cstring_nocopy(array, i, &filestr);
for (x = 0; x < ffd->npatterns; x++) {
if ((xbps_pkgpattern_match(filestr, ffd->patterns[x])) ||
(strcmp(filestr, ffd->patterns[x]) == 0)) {
prop_dictionary_get_cstring_nocopy(pkg_filesd,
"pkgver", &pkgver);
printf("%s: %s (%s)\n",
pkgver, filestr, ffd->repouri);
}
}
}
}
static int
repo_ownedby_cb(struct xbps_handle *xhp,
struct xbps_rpool_index *rpi,
void *arg,
bool *done)
{
prop_array_t idxfiles;
struct ffdata *ffd = arg;
char *plist;
unsigned int i;
(void)done;
if ((plist = xbps_pkg_index_files_plist(xhp, rpi->uri)) == NULL)
return ENOMEM;
if ((idxfiles = prop_array_internalize_from_zfile(plist)) == NULL) {
free(plist);
if (errno == ENOENT) {
fprintf(stderr, "%s: index-files missing! "
"ignoring...\n", rpi->uri);
return 0;
}
return errno;
}
free(plist);
ffd->repouri = rpi->uri;
for (i = 0; i < prop_array_count(idxfiles); i++)
repo_match_files_by_pattern(xhp,
prop_array_get(idxfiles, i), ffd);
prop_object_release(idxfiles);
return 0;
}
int
repo_ownedby(struct xbps_handle *xhp, int npatterns, char **patterns)
{
struct ffdata ffd;
ffd.npatterns = npatterns;
ffd.patterns = patterns;
return xbps_rpool_foreach(xhp, repo_ownedby_cb, &ffd);
}

175
bin/xbps-query/search.c Normal file
View File

@ -0,0 +1,175 @@
/*-
* Copyright (c) 2008-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.
*/
#ifdef HAVE_STRCASESTR
# define _GNU_SOURCE /* for strcasestr(3) */
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <libgen.h>
#include <fnmatch.h>
#include <xbps_api.h>
#include "defs.h"
struct repo_search_data {
int npatterns;
char **patterns;
void *arg;
size_t pkgver_len;
size_t maxcols;
};
static int
repo_longest_pkgver(struct xbps_handle *xhp,
struct xbps_rpool_index *rpi,
void *arg,
bool *done)
{
size_t *len = arg, olen = 0;
(void)done;
if (*len == 0) {
*len = find_longest_pkgver(xhp, rpi->repo);
return 0;
}
olen = find_longest_pkgver(xhp, rpi->repo);
if (olen > *len)
*len = olen;
return 0;
}
static size_t
repo_find_longest_pkgver(struct xbps_handle *xhp)
{
size_t len = 0;
xbps_rpool_foreach(xhp, repo_longest_pkgver, &len);
return len;
}
static int
show_pkg_namedesc(struct xbps_handle *xhp,
prop_object_t obj,
void *arg,
bool *loop_done)
{
struct repo_search_data *rsd = arg;
const char *pkgver, *pkgname, *desc, *arch, *inststr;
char *tmp = NULL, *out = NULL;
size_t x, len;
int i;
(void)xhp;
(void)loop_done;
prop_dictionary_get_cstring_nocopy(obj, "architecture", &arch);
if (!xbps_pkg_arch_match(xhp, arch, NULL))
return 0;
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
prop_dictionary_get_cstring_nocopy(obj, "short_desc", &desc);
for (i = 0; i < rsd->npatterns; i++) {
if ((xbps_pkgpattern_match(pkgver, rsd->patterns[i]) == 1) ||
(xbps_pkgpattern_match(desc, rsd->patterns[i]) == 1) ||
(strcasecmp(pkgname, rsd->patterns[i]) == 0) ||
(strcasestr(pkgver, rsd->patterns[i])) ||
(strcasestr(desc, rsd->patterns[i]))) {
tmp = calloc(1, rsd->pkgver_len + 1);
assert(tmp);
memcpy(tmp, pkgver, rsd->pkgver_len);
for (x = strlen(tmp); x < rsd->pkgver_len; x++)
tmp[x] = ' ';
tmp[x] = '\0';
if (xbps_pkgdb_get_pkgd_by_pkgver(xhp, pkgver))
inststr = "[*]";
else
inststr = "[-]";
len = strlen(inststr) + strlen(tmp) + strlen(desc) + 1;
if (len > rsd->maxcols) {
out = malloc(rsd->maxcols+1);
assert(out);
snprintf(out, rsd->maxcols-3, "%s %s %s",
inststr, tmp, desc);
strncat(out, "...", rsd->maxcols);
out[rsd->maxcols+1] = '\0';
printf("%s\n", out);
free(out);
} else {
printf("%s %s %s\n", inststr, tmp, desc);
}
}
}
return 0;
}
static int
repo_search_pkgs_cb(struct xbps_handle *xhp,
struct xbps_rpool_index *rpi,
void *arg,
bool *done)
{
struct repo_search_data *rsd = arg;
(void)done;
(void)xbps_callback_array_iter(xhp, rpi->repo, show_pkg_namedesc, rsd);
return 0;
}
int
repo_search(struct xbps_handle *xhp, int npatterns, char **patterns)
{
struct repo_search_data rsd;
int rv;
rsd.npatterns = npatterns;
rsd.patterns = patterns;
rsd.pkgver_len = repo_find_longest_pkgver(xhp);
rsd.maxcols = get_maxcols();
rv = xbps_rpool_foreach(xhp, repo_search_pkgs_cb, &rsd);
if (rv != 0 && rv != ENOTSUP)
fprintf(stderr, "Failed to initialize rpool: %s\n",
strerror(rv));
return rv;
}

View File

@ -0,0 +1,94 @@
/*-
* Copyright (c) 2009-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 <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <xbps_api.h>
#include "defs.h"
int
show_pkg_deps(struct xbps_handle *xhp, const char *pkgname)
{
prop_dictionary_t propsd;
int rv = 0;
assert(pkgname != NULL);
/*
* Check for props.plist metadata file.
*/
propsd = xbps_dictionary_from_metadata_plist(xhp,
pkgname, XBPS_PKGPROPS);
if (propsd == NULL)
return errno;
rv = xbps_callback_array_iter_in_dict(xhp, propsd, "run_depends",
list_strings_sep_in_array, NULL);
prop_object_release(propsd);
return rv;
}
int
show_pkg_revdeps(struct xbps_handle *xhp, const char *pkgname)
{
prop_dictionary_t pkgd;
int rv = 0;
pkgd = xbps_find_virtualpkg_dict_installed(xhp, pkgname, false);
if (pkgd == NULL) {
pkgd = xbps_find_pkg_dict_installed(xhp, pkgname, false);
if (pkgd == NULL)
return 0;
}
rv = xbps_callback_array_iter_in_dict(xhp, pkgd, "requiredby",
list_strings_sep_in_array, NULL);
return rv;
}
int
repo_show_pkg_deps(struct xbps_handle *xhp, const char *pattern)
{
prop_dictionary_t pkgd;
if (xbps_pkgpattern_version(pattern))
pkgd = xbps_rpool_find_pkg(xhp, pattern, true, false);
else
pkgd = xbps_rpool_find_pkg(xhp, pattern, false, true);
if (pkgd == NULL)
return errno;
(void)xbps_callback_array_iter_in_dict(xhp, pkgd,
"run_depends", list_strings_sep_in_array, NULL);
return 0;
}

View File

@ -0,0 +1,259 @@
/*-
* Copyright (c) 2008-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 <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <libgen.h>
#include <fnmatch.h>
#include <xbps_api.h>
#include "defs.h"
static void
print_value_obj(const char *keyname, prop_object_t obj, bool raw)
{
const char *value;
size_t i;
char size[8];
switch (prop_object_type(obj)) {
case PROP_TYPE_STRING:
if (!raw)
printf("%s: ", keyname);
printf("%s\n", prop_string_cstring_nocopy(obj));
break;
case PROP_TYPE_NUMBER:
if (!raw)
printf("%s: ", keyname);
if (xbps_humanize_number(size,
(int64_t)prop_number_unsigned_integer_value(obj)) == -1)
printf("%ju\n",
prop_number_unsigned_integer_value(obj));
else
printf("%s\n", size);
break;
case PROP_TYPE_BOOL:
if (!raw)
printf("%s: ", keyname);
printf("%s\n", prop_bool_true(obj) ? "yes" : "no");
break;
case PROP_TYPE_ARRAY:
if (!raw)
printf("%s:\n", keyname);
for (i = 0; i < prop_array_count(obj); i++) {
prop_array_get_cstring_nocopy(obj, i, &value);
printf("%s%s%s", !raw ? "\t" : "", value,
!raw ? "\n" : " ");
}
if (raw)
printf("\n");
break;
default:
xbps_warn_printf("unknown obj type (key %s)\n",
keyname);
break;
}
}
void
show_pkg_info_one(prop_dictionary_t d, const char *keys)
{
prop_object_t obj;
char *key, *p, *saveptr;
if (strchr(keys, ',') == NULL) {
obj = prop_dictionary_get(d, keys);
if (obj == NULL)
return;
print_value_obj(keys, obj, true);
return;
}
key = strdup(keys);
if (key == NULL)
abort();
for ((p = strtok_r(key, ",", &saveptr)); p;
(p = strtok_r(NULL, ",", &saveptr))) {
obj = prop_dictionary_get(d, p);
if (obj == NULL)
continue;
print_value_obj(p, obj, true);
}
free(key);
}
void
show_pkg_info(prop_dictionary_t dict)
{
prop_array_t all_keys;
prop_object_t obj, keysym;
const char *keyname;
size_t i;
all_keys = prop_dictionary_all_keys(dict);
for (i = 0; i < prop_array_count(all_keys); i++) {
keysym = prop_array_get(all_keys, i);
keyname = prop_dictionary_keysym_cstring_nocopy(keysym);
obj = prop_dictionary_get_keysym(dict, keysym);
/* ignore run_depends, it's shown via 'show-deps' */
if (strcmp(keyname, "run_depends") == 0)
continue;
print_value_obj(keyname, obj, false);
}
prop_object_release(all_keys);
}
int
show_pkg_files(prop_dictionary_t filesd)
{
prop_array_t array, allkeys;
prop_object_t obj;
prop_dictionary_keysym_t ksym;
const char *keyname, *file;
size_t i, x;
allkeys = prop_dictionary_all_keys(filesd);
for (i = 0; i < prop_array_count(allkeys); i++) {
ksym = prop_array_get(allkeys, i);
keyname = prop_dictionary_keysym_cstring_nocopy(ksym);
if (strcmp(keyname, "dirs") == 0)
continue;
array = prop_dictionary_get(filesd, keyname);
if (array == NULL || prop_array_count(array) == 0)
continue;
for (x = 0; x < prop_array_count(array); x++) {
obj = prop_array_get(array, x);
prop_dictionary_get_cstring_nocopy(obj, "file", &file);
printf("%s", file);
if (prop_dictionary_get_cstring_nocopy(obj,
"target", &file))
printf(" -> %s", file);
printf("\n");
}
}
prop_object_release(allkeys);
return 0;
}
int
show_pkg_info_from_metadir(struct xbps_handle *xhp,
const char *pkgname,
const char *option)
{
prop_dictionary_t d, pkgdb_d;
const char *instdate, *pname;
bool autoinst;
d = xbps_dictionary_from_metadata_plist(xhp, pkgname, XBPS_PKGPROPS);
if (d == NULL)
return EINVAL;
prop_dictionary_get_cstring_nocopy(d, "pkgname", &pname);
pkgdb_d = xbps_pkgdb_get_pkgd(xhp, pname, false);
if (pkgdb_d == NULL) {
prop_object_release(d);
return EINVAL;
}
if (prop_dictionary_get_cstring_nocopy(pkgdb_d,
"install-date", &instdate))
prop_dictionary_set_cstring_nocopy(d, "install-date",
instdate);
if (prop_dictionary_get_bool(pkgdb_d, "automatic-install", &autoinst))
prop_dictionary_set_bool(d, "automatic-install", autoinst);
if (option == NULL)
show_pkg_info(d);
else
show_pkg_info_one(d, option);
prop_object_release(d);
return 0;
}
int
show_pkg_files_from_metadir(struct xbps_handle *xhp, const char *pkgname)
{
prop_dictionary_t d;
int rv = 0;
d = xbps_dictionary_from_metadata_plist(xhp, pkgname, XBPS_PKGFILES);
if (d == NULL)
return EINVAL;
rv = show_pkg_files(d);
prop_object_release(d);
return rv;
}
int
repo_show_pkg_info(struct xbps_handle *xhp,
const char *pattern,
const char *option)
{
prop_dictionary_t pkgd;
if (xbps_pkgpattern_version(pattern))
pkgd = xbps_rpool_find_pkg(xhp, pattern, true, false);
else
pkgd = xbps_rpool_find_pkg(xhp, pattern, false, true);
if (pkgd == NULL)
return errno;
if (option)
show_pkg_info_one(pkgd, option);
else
show_pkg_info(pkgd);
return 0;
}
int
repo_show_pkg_files(struct xbps_handle *xhp, const char *pkg)
{
prop_dictionary_t pkgd;
pkgd = xbps_rpool_dictionary_metadata_plist(xhp, pkg,
"./files.plist");
if (pkgd == NULL) {
if (errno != ENOTSUP && errno != ENOENT) {
fprintf(stderr, "Unexpected error: %s\n",
strerror(errno));
return errno;
}
}
return show_pkg_files(pkgd);
}