Remove obsolete xbps-{bin,repo} utils.
This commit is contained in:
parent
e57e6669fb
commit
e21cdc68df
@ -1,9 +1,6 @@
|
|||||||
-include ../config.mk
|
-include ../config.mk
|
||||||
|
|
||||||
SUBDIRS += xbps-bin
|
SUBDIRS = xbps-create
|
||||||
SUBDIRS += xbps-repo
|
|
||||||
|
|
||||||
SUBDIRS += xbps-create
|
|
||||||
SUBDIRS += xbps-dgraph
|
SUBDIRS += xbps-dgraph
|
||||||
SUBDIRS += xbps-install
|
SUBDIRS += xbps-install
|
||||||
SUBDIRS += xbps-pkgdb
|
SUBDIRS += xbps-pkgdb
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
TOPDIR = ../..
|
|
||||||
-include $(TOPDIR)/config.mk
|
|
||||||
|
|
||||||
BIN = xbps-bin
|
|
||||||
OBJS = transaction.o main.o show-deps.o
|
|
||||||
OBJS += show-info-files.o util.o find-files.o
|
|
||||||
OBJS += question.o fetch_cb.o state_cb.o
|
|
||||||
OBJS += check.o check_pkg_automatic.o check_pkg_files.o
|
|
||||||
OBJS += check_pkg_rundeps.o check_pkg_symlinks.o
|
|
||||||
OBJS += check_pkg_requiredby.o check_pkg_unneeded.o
|
|
||||||
OBJS += show-orphans.o unpack_cb.o list.o
|
|
||||||
MAN = $(BIN).8
|
|
||||||
|
|
||||||
include $(TOPDIR)/mk/prog.mk
|
|
@ -1,188 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <unistd.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
struct checkpkg {
|
|
||||||
size_t totalpkgs;
|
|
||||||
size_t npkgs;
|
|
||||||
size_t nbrokenpkgs;
|
|
||||||
bool flush;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
cb_pkg_integrity(struct xbps_handle *xhp,
|
|
||||||
prop_object_t obj,
|
|
||||||
void *arg,
|
|
||||||
bool *done)
|
|
||||||
{
|
|
||||||
struct checkpkg *cpkg = arg;
|
|
||||||
const char *pkgname, *version;
|
|
||||||
bool flush = false;
|
|
||||||
|
|
||||||
(void)done;
|
|
||||||
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "version", &version);
|
|
||||||
printf("[%zu/%zu] checking %s-%s ...\n",
|
|
||||||
cpkg->npkgs, cpkg->totalpkgs, pkgname, version);
|
|
||||||
if (check_pkg_integrity(xhp, obj, pkgname, false, &flush) != 0)
|
|
||||||
cpkg->nbrokenpkgs++;
|
|
||||||
else
|
|
||||||
printf("\033[1A\033[K");
|
|
||||||
|
|
||||||
|
|
||||||
if (flush && !cpkg->flush)
|
|
||||||
cpkg->flush = flush;
|
|
||||||
cpkg->npkgs++;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
check_pkg_integrity_all(struct xbps_handle *xhp)
|
|
||||||
{
|
|
||||||
struct checkpkg cpkg;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
memset(&cpkg, 0, sizeof(cpkg));
|
|
||||||
/* force an update to get total pkg count */
|
|
||||||
(void)xbps_pkgdb_update(xhp, false);
|
|
||||||
cpkg.totalpkgs = prop_array_count(xhp->pkgdb);
|
|
||||||
|
|
||||||
(void)xbps_pkgdb_foreach_cb(xhp, cb_pkg_integrity, &cpkg);
|
|
||||||
if (cpkg.flush) {
|
|
||||||
if ((rv = xbps_pkgdb_update(xhp, true)) != 0) {
|
|
||||||
xbps_error_printf("failed to write pkgdb: %s\n",
|
|
||||||
strerror(rv));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("%zu package%s processed: %zu broken.\n", cpkg.npkgs,
|
|
||||||
cpkg.npkgs == 1 ? "" : "s", cpkg.nbrokenpkgs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
check_pkg_integrity(struct xbps_handle *xhp,
|
|
||||||
prop_dictionary_t pkgd,
|
|
||||||
const char *pkgname,
|
|
||||||
bool flush,
|
|
||||||
bool *setflush)
|
|
||||||
{
|
|
||||||
prop_dictionary_t opkgd, propsd, filesd;
|
|
||||||
int rv = 0;
|
|
||||||
bool pkgdb_update = false, broken = false;
|
|
||||||
|
|
||||||
propsd = filesd = opkgd = NULL;
|
|
||||||
|
|
||||||
/* find real pkg by name */
|
|
||||||
if (pkgd == NULL) {
|
|
||||||
opkgd = xbps_find_pkg_dict_installed(xhp, pkgname, false);
|
|
||||||
if (opkgd == NULL) {
|
|
||||||
/* find virtual pkg by name */
|
|
||||||
opkgd = xbps_find_virtualpkg_dict_installed(xhp,
|
|
||||||
pkgname, false);
|
|
||||||
}
|
|
||||||
if (opkgd == NULL) {
|
|
||||||
printf("Package %s is not installed.\n", pkgname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Check for props.plist metadata file.
|
|
||||||
*/
|
|
||||||
propsd = xbps_dictionary_from_metadata_plist(xhp, pkgname, XBPS_PKGPROPS);
|
|
||||||
if (propsd == NULL) {
|
|
||||||
xbps_error_printf("%s: unexistent %s or invalid metadata "
|
|
||||||
"file.\n", pkgname, XBPS_PKGPROPS);
|
|
||||||
broken = true;
|
|
||||||
goto out;
|
|
||||||
} else if (prop_dictionary_count(propsd) == 0) {
|
|
||||||
xbps_error_printf("%s: incomplete %s metadata file.\n",
|
|
||||||
pkgname, XBPS_PKGPROPS);
|
|
||||||
broken = true;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Check for files.plist metadata file.
|
|
||||||
*/
|
|
||||||
filesd = xbps_dictionary_from_metadata_plist(xhp, pkgname, XBPS_PKGFILES);
|
|
||||||
if (filesd == NULL) {
|
|
||||||
xbps_error_printf("%s: unexistent %s or invalid metadata "
|
|
||||||
"file.\n", pkgname, XBPS_PKGFILES);
|
|
||||||
broken = true;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define RUN_PKG_CHECK(x, name, arg, arg2) \
|
|
||||||
do { \
|
|
||||||
rv = check_pkg_##name(x, pkgname, arg, arg2); \
|
|
||||||
if (rv) \
|
|
||||||
broken = true; \
|
|
||||||
else if (rv == -1) { \
|
|
||||||
xbps_error_printf("%s: the %s test " \
|
|
||||||
"returned error!\n", pkgname, #name); \
|
|
||||||
goto out; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Execute pkg checks */
|
|
||||||
RUN_PKG_CHECK(xhp, files, filesd, &pkgdb_update);
|
|
||||||
RUN_PKG_CHECK(xhp, symlinks, filesd, &pkgdb_update);
|
|
||||||
RUN_PKG_CHECK(xhp, rundeps, propsd, &pkgdb_update);
|
|
||||||
RUN_PKG_CHECK(xhp, requiredby, pkgd ? pkgd : opkgd, &pkgdb_update);
|
|
||||||
RUN_PKG_CHECK(xhp, autoinstall, pkgd ? pkgd : opkgd, &pkgdb_update);
|
|
||||||
RUN_PKG_CHECK(xhp, unneeded, pkgd ? pkgd : opkgd, &pkgdb_update);
|
|
||||||
|
|
||||||
if (flush && pkgdb_update) {
|
|
||||||
if (!xbps_pkgdb_replace_pkgd(xhp, opkgd, pkgname, false, true)) {
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (setflush && pkgdb_update)
|
|
||||||
*setflush = true;
|
|
||||||
|
|
||||||
#undef RUN_PKG_CHECK
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (prop_object_type(filesd) == PROP_TYPE_DICTIONARY)
|
|
||||||
prop_object_release(filesd);
|
|
||||||
if (prop_object_type(propsd) == PROP_TYPE_DICTIONARY)
|
|
||||||
prop_object_release(propsd);
|
|
||||||
if (broken)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2011-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 <unistd.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks package integrity of an installed package.
|
|
||||||
* The following task is accomplished in this file:
|
|
||||||
*
|
|
||||||
* o Check if package was installed manually, but currently
|
|
||||||
* other packages are depending on it. This package shall be
|
|
||||||
* changed to automatic mode, i.e installed as dependency of
|
|
||||||
* those packages.
|
|
||||||
*
|
|
||||||
* Returns 0 if test ran successfully, 1 otherwise and -1 on error.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
check_pkg_autoinstall(struct xbps_handle *xhp,
|
|
||||||
const char *pkgname,
|
|
||||||
void *arg,
|
|
||||||
bool *pkgdb_update)
|
|
||||||
{
|
|
||||||
prop_dictionary_t pkgd = arg;
|
|
||||||
prop_array_t reqby;
|
|
||||||
bool autoinst = false;
|
|
||||||
|
|
||||||
(void)xhp;
|
|
||||||
/*
|
|
||||||
* Check if package has been installed manually but any other
|
|
||||||
* package is currently depending on it; in that case the package
|
|
||||||
* must be in automatic mode.
|
|
||||||
*/
|
|
||||||
if (prop_dictionary_get_bool(pkgd, "automatic-install", &autoinst)) {
|
|
||||||
reqby = prop_dictionary_get(pkgd, "requiredby");
|
|
||||||
if (reqby != NULL && prop_array_count(reqby) && !autoinst) {
|
|
||||||
/* pkg has reversedeps and was installed manually */
|
|
||||||
prop_dictionary_set_bool(pkgd,
|
|
||||||
"automatic-install", true);
|
|
||||||
*pkgdb_update = true;
|
|
||||||
printf("%s: changed to automatic install mode.\n",
|
|
||||||
pkgname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,153 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2011-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 <unistd.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks package integrity of an installed package.
|
|
||||||
* The following tasks are processed in that order:
|
|
||||||
*
|
|
||||||
* o Check for missing installed files.
|
|
||||||
*
|
|
||||||
* o Check the hash for all installed files, except
|
|
||||||
* configuration files (which is expected if they are modified).
|
|
||||||
*
|
|
||||||
* Return 0 if test ran successfully, 1 otherwise and -1 on error.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
check_pkg_files(struct xbps_handle *xhp,
|
|
||||||
const char *pkgname,
|
|
||||||
void *arg,
|
|
||||||
bool *pkgdb_update)
|
|
||||||
{
|
|
||||||
prop_array_t array;
|
|
||||||
prop_object_t obj;
|
|
||||||
prop_object_iterator_t iter;
|
|
||||||
prop_dictionary_t pkg_filesd = arg;
|
|
||||||
const char *file, *sha256;
|
|
||||||
char *path;
|
|
||||||
int rv = 0;
|
|
||||||
bool mutable, broken = false, test_broken = false;
|
|
||||||
|
|
||||||
(void)pkgdb_update;
|
|
||||||
|
|
||||||
array = prop_dictionary_get(pkg_filesd, "files");
|
|
||||||
if (array != NULL && prop_array_count(array) > 0) {
|
|
||||||
iter = xbps_array_iter_from_dict(pkg_filesd, "files");
|
|
||||||
if (iter == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter))) {
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "file", &file);
|
|
||||||
path = xbps_xasprintf("%s/%s", xhp->rootdir, file);
|
|
||||||
if (path == NULL) {
|
|
||||||
prop_object_iterator_release(iter);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj,
|
|
||||||
"sha256", &sha256);
|
|
||||||
rv = xbps_file_hash_check(path, sha256);
|
|
||||||
switch (rv) {
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case ENOENT:
|
|
||||||
xbps_error_printf("%s: unexistent file %s.\n",
|
|
||||||
pkgname, file);
|
|
||||||
test_broken = true;
|
|
||||||
break;
|
|
||||||
case ERANGE:
|
|
||||||
mutable = false;
|
|
||||||
prop_dictionary_get_bool(obj,
|
|
||||||
"mutable", &mutable);
|
|
||||||
if (!mutable) {
|
|
||||||
xbps_error_printf("%s: hash mismatch "
|
|
||||||
"for %s.\n", pkgname, file);
|
|
||||||
test_broken = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
xbps_error_printf(
|
|
||||||
"%s: can't check `%s' (%s)\n",
|
|
||||||
pkgname, file, strerror(rv));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(path);
|
|
||||||
}
|
|
||||||
prop_object_iterator_release(iter);
|
|
||||||
}
|
|
||||||
if (test_broken) {
|
|
||||||
xbps_error_printf("%s: files check FAILED.\n", pkgname);
|
|
||||||
test_broken = false;
|
|
||||||
broken = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for missing configuration files.
|
|
||||||
*/
|
|
||||||
array = prop_dictionary_get(pkg_filesd, "conf_files");
|
|
||||||
if (array != NULL && prop_array_count(array) > 0) {
|
|
||||||
iter = xbps_array_iter_from_dict(pkg_filesd, "conf_files");
|
|
||||||
if (iter == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter))) {
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "file", &file);
|
|
||||||
path = xbps_xasprintf("%s/%s", xhp->rootdir, file);
|
|
||||||
if (path == NULL) {
|
|
||||||
prop_object_iterator_release(iter);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if ((rv = access(path, R_OK)) == -1) {
|
|
||||||
if (errno == ENOENT) {
|
|
||||||
xbps_error_printf(
|
|
||||||
"%s: unexistent file %s\n",
|
|
||||||
pkgname, file);
|
|
||||||
test_broken = true;
|
|
||||||
} else
|
|
||||||
xbps_error_printf(
|
|
||||||
"%s: can't check `%s' (%s)\n",
|
|
||||||
pkgname, file,
|
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
free(path);
|
|
||||||
}
|
|
||||||
prop_object_iterator_release(iter);
|
|
||||||
}
|
|
||||||
if (test_broken) {
|
|
||||||
xbps_error_printf("%s: conf files check FAILED.\n", pkgname);
|
|
||||||
broken = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return broken;
|
|
||||||
}
|
|
@ -1,222 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2011-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 <unistd.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
struct check_reqby_data {
|
|
||||||
prop_dictionary_t pkgd;
|
|
||||||
prop_array_t pkgd_reqby;
|
|
||||||
const char *pkgname;
|
|
||||||
const char *pkgver;
|
|
||||||
bool pkgd_reqby_alloc;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
|
||||||
check_reqby_pkg_cb(struct xbps_handle *xhp,
|
|
||||||
prop_object_t obj,
|
|
||||||
void *arg,
|
|
||||||
bool *done)
|
|
||||||
{
|
|
||||||
struct check_reqby_data *crd = arg;
|
|
||||||
prop_array_t curpkg_rdeps, provides;
|
|
||||||
prop_dictionary_t curpkg_propsd;
|
|
||||||
prop_string_t curpkgver;
|
|
||||||
const char *curpkgn;
|
|
||||||
|
|
||||||
(void)done;
|
|
||||||
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &curpkgn);
|
|
||||||
/* skip same pkg */
|
|
||||||
if (strcmp(curpkgn, crd->pkgname) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internalize current pkg props dictionary from its
|
|
||||||
* installed metadata directory.
|
|
||||||
*/
|
|
||||||
curpkg_propsd =
|
|
||||||
xbps_dictionary_from_metadata_plist(xhp, curpkgn, XBPS_PKGPROPS);
|
|
||||||
if (curpkg_propsd == NULL) {
|
|
||||||
xbps_error_printf("%s: missing %s metadata file!\n",
|
|
||||||
curpkgn, XBPS_PKGPROPS);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
curpkg_rdeps =
|
|
||||||
prop_dictionary_get(curpkg_propsd, "run_depends");
|
|
||||||
if (curpkg_rdeps == NULL) {
|
|
||||||
/* package has no rundeps, skip */
|
|
||||||
prop_object_release(curpkg_propsd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Check for pkgpattern match with real packages...
|
|
||||||
*/
|
|
||||||
if (!xbps_match_pkgdep_in_array(curpkg_rdeps, crd->pkgver)) {
|
|
||||||
/*
|
|
||||||
* ... otherwise check if package provides any virtual
|
|
||||||
* package and is matched against any object in
|
|
||||||
* run_depends.
|
|
||||||
*/
|
|
||||||
provides = prop_dictionary_get(obj, "provides");
|
|
||||||
if (provides == NULL) {
|
|
||||||
/* doesn't provide any virtual pkg */
|
|
||||||
prop_object_release(curpkg_propsd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!xbps_match_any_virtualpkg_in_rundeps(curpkg_rdeps,
|
|
||||||
provides)) {
|
|
||||||
/* doesn't match any virtual pkg */
|
|
||||||
prop_object_release(curpkg_propsd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
crd->pkgd_reqby = prop_dictionary_get(crd->pkgd, "requiredby");
|
|
||||||
curpkgver = prop_dictionary_get(curpkg_propsd, "pkgver");
|
|
||||||
if (crd->pkgd_reqby != NULL) {
|
|
||||||
/*
|
|
||||||
* Now check that current pkgver has been registered into
|
|
||||||
* its requiredby array.
|
|
||||||
*/
|
|
||||||
if (xbps_match_string_in_array(crd->pkgd_reqby,
|
|
||||||
prop_string_cstring_nocopy(curpkgver))) {
|
|
||||||
/*
|
|
||||||
* Current package already requires our package,
|
|
||||||
* this is good so skip it.
|
|
||||||
*/
|
|
||||||
prop_object_release(curpkg_propsd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* Missing requiredby array object, create it.
|
|
||||||
*/
|
|
||||||
crd->pkgd_reqby = prop_array_create();
|
|
||||||
if (crd->pkgd_reqby == NULL) {
|
|
||||||
prop_object_release(curpkg_propsd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
crd->pkgd_reqby_alloc = true;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Added pkgdep into pkg's requiredby array.
|
|
||||||
*/
|
|
||||||
if (!prop_array_add(crd->pkgd_reqby, curpkgver)) {
|
|
||||||
prop_object_release(curpkg_propsd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
printf("%s: added missing requiredby entry for %s.\n\n",
|
|
||||||
crd->pkgver, prop_string_cstring_nocopy(curpkgver));
|
|
||||||
prop_object_release(curpkg_propsd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Removes unused entries in pkg's requiredby array.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
remove_stale_entries_in_reqby(struct xbps_handle *xhp,
|
|
||||||
struct check_reqby_data *crd)
|
|
||||||
{
|
|
||||||
prop_array_t reqby;
|
|
||||||
prop_dictionary_t pkgd;
|
|
||||||
const char *str;
|
|
||||||
size_t i;
|
|
||||||
bool needs_update = false;
|
|
||||||
|
|
||||||
reqby = prop_dictionary_get(crd->pkgd, "requiredby");
|
|
||||||
if (reqby == NULL || prop_array_count(reqby) == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
crd->pkgd_reqby = prop_dictionary_get(crd->pkgd, "requiredby");
|
|
||||||
|
|
||||||
for (i = 0; i < prop_array_count(reqby); i++) {
|
|
||||||
prop_array_get_cstring_nocopy(reqby, i, &str);
|
|
||||||
if ((pkgd = xbps_pkgdb_get_pkgd_by_pkgver(xhp, str)) != NULL)
|
|
||||||
continue;
|
|
||||||
printf("%s: found stale entry in requiredby `%s' (fixed)\n",
|
|
||||||
crd->pkgver, str);
|
|
||||||
if (xbps_remove_string_from_array(xhp, crd->pkgd_reqby, str))
|
|
||||||
needs_update = true;
|
|
||||||
}
|
|
||||||
if (needs_update) {
|
|
||||||
prop_dictionary_set(crd->pkgd, "requiredby", crd->pkgd_reqby);
|
|
||||||
printf("%s: requiredby fix done!\n\n", crd->pkgver);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks package integrity of an installed package.
|
|
||||||
* The following task is accomplished in this file:
|
|
||||||
*
|
|
||||||
* o Check for missing reverse dependencies (aka requiredby)
|
|
||||||
* entries in pkg's pkgdb dictionary.
|
|
||||||
*
|
|
||||||
* Returns 0 if test ran successfully, 1 otherwise and -1 on error.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
check_pkg_requiredby(struct xbps_handle *xhp,
|
|
||||||
const char *pkgname,
|
|
||||||
void *arg,
|
|
||||||
bool *pkgdb_update)
|
|
||||||
{
|
|
||||||
prop_dictionary_t pkgd = arg;
|
|
||||||
struct check_reqby_data crd;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
crd.pkgd = pkgd;
|
|
||||||
crd.pkgd_reqby = NULL;
|
|
||||||
crd.pkgd_reqby_alloc = false;
|
|
||||||
crd.pkgname = pkgname;
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &crd.pkgver);
|
|
||||||
|
|
||||||
/* missing reqby entries in pkgs */
|
|
||||||
rv = xbps_pkgdb_foreach_cb(xhp, check_reqby_pkg_cb, &crd);
|
|
||||||
if (rv < 0) {
|
|
||||||
return rv;
|
|
||||||
} else if (rv == 1) {
|
|
||||||
*pkgdb_update = true;
|
|
||||||
prop_dictionary_set(pkgd, "requiredby", crd.pkgd_reqby);
|
|
||||||
if (crd.pkgd_reqby_alloc)
|
|
||||||
prop_object_release(crd.pkgd_reqby);
|
|
||||||
|
|
||||||
printf("%s: requiredby fix done!\n\n", crd.pkgver);
|
|
||||||
}
|
|
||||||
/* remove stale entries in pkg's reqby */
|
|
||||||
if (remove_stale_entries_in_reqby(xhp, &crd))
|
|
||||||
*pkgdb_update = true;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2011-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 <unistd.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks package integrity of an installed package.
|
|
||||||
* The following task is accomplished in this file:
|
|
||||||
*
|
|
||||||
* o Check for missing run time dependencies.
|
|
||||||
*
|
|
||||||
* Returns 0 if test ran successfully, 1 otherwise and -1 on error.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
check_pkg_rundeps(struct xbps_handle *xhp,
|
|
||||||
const char *pkgname,
|
|
||||||
void *arg,
|
|
||||||
bool *pkgdb_update)
|
|
||||||
{
|
|
||||||
prop_dictionary_t pkg_propsd = arg;
|
|
||||||
prop_object_t obj;
|
|
||||||
prop_object_iterator_t iter;
|
|
||||||
const char *reqpkg;
|
|
||||||
bool test_broken = false;
|
|
||||||
|
|
||||||
(void)pkgdb_update;
|
|
||||||
|
|
||||||
if (!xbps_pkg_has_rundeps(pkg_propsd))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
iter = xbps_array_iter_from_dict(pkg_propsd, "run_depends");
|
|
||||||
if (iter == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter))) {
|
|
||||||
reqpkg = prop_string_cstring_nocopy(obj);
|
|
||||||
if (reqpkg == NULL) {
|
|
||||||
prop_object_iterator_release(iter);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (xbps_check_is_installed_pkg_by_pattern(xhp, reqpkg) <= 0) {
|
|
||||||
xbps_error_printf("%s: dependency not satisfied: %s\n",
|
|
||||||
pkgname, reqpkg);
|
|
||||||
test_broken = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prop_object_iterator_release(iter);
|
|
||||||
return test_broken;
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2011-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 <unistd.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks package integrity of an installed package.
|
|
||||||
* The following task is accomplished in this file:
|
|
||||||
*
|
|
||||||
* o Check for target file in symlinks, so that we can check that
|
|
||||||
* they have not been modified.
|
|
||||||
*
|
|
||||||
* returns 0 if test ran successfully, 1 otherwise and -1 on error.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
check_pkg_symlinks(struct xbps_handle *xhp,
|
|
||||||
const char *pkgname,
|
|
||||||
void *arg,
|
|
||||||
bool *pkgdb_update)
|
|
||||||
{
|
|
||||||
prop_array_t array;
|
|
||||||
prop_object_t obj;
|
|
||||||
prop_object_iterator_t iter;
|
|
||||||
prop_dictionary_t pkg_filesd = arg;
|
|
||||||
const char *file, *tgt = NULL;
|
|
||||||
char *path, *buf, *buf2, *buf3, *dname, *path_target;
|
|
||||||
bool broken = false, test_broken = false;
|
|
||||||
|
|
||||||
(void)pkgdb_update;
|
|
||||||
|
|
||||||
array = prop_dictionary_get(pkg_filesd, "links");
|
|
||||||
if ((prop_object_type(array) == PROP_TYPE_ARRAY) &&
|
|
||||||
prop_array_count(array) > 0) {
|
|
||||||
iter = xbps_array_iter_from_dict(pkg_filesd, "links");
|
|
||||||
if (iter == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter))) {
|
|
||||||
if (!prop_dictionary_get_cstring_nocopy(obj, "target", &tgt))
|
|
||||||
continue;
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "file", &file);
|
|
||||||
if (strcmp(tgt, "") == 0) {
|
|
||||||
xbps_warn_printf("%s: `%s' symlink with "
|
|
||||||
"empty target object!\n", pkgname, file);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
path = xbps_xasprintf("%s/%s", xhp->rootdir, file);
|
|
||||||
if (path == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((buf = realpath(path, NULL)) == NULL) {
|
|
||||||
xbps_error_printf("%s: broken symlink `%s': "
|
|
||||||
"%s\n", pkgname, file, strerror(errno));
|
|
||||||
test_broken = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (strncmp(tgt, "../", 3) == 0) {
|
|
||||||
/* relative symlink target */
|
|
||||||
dname = dirname(path);
|
|
||||||
buf2 = xbps_xasprintf("%s/%s", dname, tgt);
|
|
||||||
assert(buf2);
|
|
||||||
buf3 = realpath(buf2, NULL);
|
|
||||||
assert(buf3);
|
|
||||||
free(buf2);
|
|
||||||
path_target = buf3;
|
|
||||||
} else {
|
|
||||||
path_target = buf;
|
|
||||||
}
|
|
||||||
if (strcmp(buf, path_target)) {
|
|
||||||
xbps_error_printf("%s: modified symlink `%s' "
|
|
||||||
"points to: `%s' (shall be: `%s')\n",
|
|
||||||
pkgname, file, buf, path_target);
|
|
||||||
test_broken = true;
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
free(path);
|
|
||||||
if (buf3)
|
|
||||||
free(buf3);
|
|
||||||
|
|
||||||
path = buf = buf2 = buf3 = NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
prop_object_iterator_release(iter);
|
|
||||||
}
|
|
||||||
if (test_broken) {
|
|
||||||
xbps_error_printf("%s: symlinks check FAILED.\n", pkgname);
|
|
||||||
broken = true;
|
|
||||||
}
|
|
||||||
return broken;
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <stdio.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks package integrity of an installed package.
|
|
||||||
* The following task is accomplished in this file:
|
|
||||||
*
|
|
||||||
* o Check if pkg dictionary from pkgdb contains "unneeded" objects,
|
|
||||||
* and remove them if that was true.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
check_pkg_unneeded(struct xbps_handle *xhp,
|
|
||||||
const char *pkgname,
|
|
||||||
void *arg,
|
|
||||||
bool *pkgdb_update)
|
|
||||||
{
|
|
||||||
prop_dictionary_t pkgd = arg;
|
|
||||||
|
|
||||||
(void)pkgname;
|
|
||||||
(void)xhp;
|
|
||||||
|
|
||||||
if (prop_dictionary_get(pkgd, "remove-and-update")) {
|
|
||||||
*pkgdb_update = true;
|
|
||||||
prop_dictionary_remove(pkgd, "remove-and-update");
|
|
||||||
}
|
|
||||||
if (prop_dictionary_get(pkgd, "transaction")) {
|
|
||||||
*pkgdb_update = true;
|
|
||||||
prop_dictionary_remove(pkgd, "transaction");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,129 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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_BIN_DEFS_H_
|
|
||||||
#define _XBPS_BIN_DEFS_H_
|
|
||||||
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <xbps_api.h>
|
|
||||||
|
|
||||||
#ifndef __UNCONST
|
|
||||||
#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct xferstat {
|
|
||||||
struct timeval start;
|
|
||||||
struct timeval last;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct list_pkgver_cb {
|
|
||||||
pkg_state_t state;
|
|
||||||
size_t pkgver_len;
|
|
||||||
size_t maxcols;
|
|
||||||
bool check_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* from transaction.c */
|
|
||||||
int install_new_pkg(struct xbps_handle *, const char *, bool);
|
|
||||||
int update_pkg(struct xbps_handle *, const char *);
|
|
||||||
int remove_pkg(struct xbps_handle *, const char *, size_t, bool);
|
|
||||||
int remove_pkg_orphans(struct xbps_handle *, size_t, bool, bool);
|
|
||||||
int dist_upgrade(struct xbps_handle *, size_t, bool, bool, bool);
|
|
||||||
int exec_transaction(struct xbps_handle *, size_t, bool, bool, bool);
|
|
||||||
|
|
||||||
/* from remove.c */
|
|
||||||
int remove_installed_pkgs(int, char **, bool, bool, bool, bool);
|
|
||||||
|
|
||||||
/* from check.c */
|
|
||||||
int check_pkg_integrity(struct xbps_handle *,
|
|
||||||
prop_dictionary_t,
|
|
||||||
const char *,
|
|
||||||
bool,
|
|
||||||
bool *);
|
|
||||||
int check_pkg_integrity_all(struct xbps_handle *);
|
|
||||||
|
|
||||||
#define CHECK_PKG_DECL(type) \
|
|
||||||
int check_pkg_##type (struct xbps_handle *, const char *, void *, bool *)
|
|
||||||
|
|
||||||
CHECK_PKG_DECL(autoinstall);
|
|
||||||
CHECK_PKG_DECL(unneeded);
|
|
||||||
CHECK_PKG_DECL(files);
|
|
||||||
CHECK_PKG_DECL(rundeps);
|
|
||||||
CHECK_PKG_DECL(symlinks);
|
|
||||||
CHECK_PKG_DECL(requiredby);
|
|
||||||
|
|
||||||
/* from show-deps.c */
|
|
||||||
int show_pkg_deps(struct xbps_handle *, const char *);
|
|
||||||
int show_pkg_reverse_deps(struct xbps_handle *, const char *);
|
|
||||||
|
|
||||||
/* from show-info-files.c */
|
|
||||||
int show_pkg_info_from_metadir(struct xbps_handle *, const char *, const char *);
|
|
||||||
int show_pkg_files_from_metadir(struct xbps_handle *, const char *);
|
|
||||||
|
|
||||||
/* from show-orphans.c */
|
|
||||||
int show_orphans(struct xbps_handle *);
|
|
||||||
|
|
||||||
/* from find-files.c */
|
|
||||||
int find_files_in_packages(struct xbps_handle *, int, char **);
|
|
||||||
|
|
||||||
/* from question.c */
|
|
||||||
bool yesno(const char *, ...);
|
|
||||||
bool noyes(const char *, ...);
|
|
||||||
|
|
||||||
/* from fetch_cb.c */
|
|
||||||
void fetch_file_progress_cb(struct xbps_handle *,
|
|
||||||
struct xbps_fetch_cb_data *,
|
|
||||||
void *);
|
|
||||||
|
|
||||||
/* from state_cb.c */
|
|
||||||
void state_cb(struct xbps_handle *,
|
|
||||||
struct xbps_state_cb_data *,
|
|
||||||
void *);
|
|
||||||
|
|
||||||
/* from unpack_cb.c */
|
|
||||||
void unpack_progress_cb_verbose(struct xbps_handle *,
|
|
||||||
struct xbps_unpack_cb_data *,
|
|
||||||
void *);
|
|
||||||
void unpack_progress_cb(struct xbps_handle *,
|
|
||||||
struct xbps_unpack_cb_data *,
|
|
||||||
void *);
|
|
||||||
|
|
||||||
/* From util.c */
|
|
||||||
int show_pkg_files(prop_dictionary_t);
|
|
||||||
void show_pkg_info(prop_dictionary_t);
|
|
||||||
void show_pkg_info_one(prop_dictionary_t, const char *);
|
|
||||||
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);
|
|
||||||
void print_package_line(const char *, size_t, bool);
|
|
||||||
size_t get_maxcols(void);
|
|
||||||
|
|
||||||
/* from list.c */
|
|
||||||
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 *);
|
|
||||||
|
|
||||||
#endif /* !_XBPS_BIN_DEFS_H_ */
|
|
@ -1,176 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2009-2012 Juan Romero Pardines
|
|
||||||
* Copyright (c) 2000-2004 Dag-Erling Coïdan Smørgrav
|
|
||||||
* 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
|
|
||||||
* in this position and unchanged.
|
|
||||||
* 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.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* From FreeBSD fetch(8):
|
|
||||||
* $FreeBSD: src/usr.bin/fetch/fetch.c,v 1.84.2.1 2009/08/03 08:13:06 kensmith Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
static void
|
|
||||||
get_time(struct timeval *tvp)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_CLOCK_GETTIME
|
|
||||||
struct timespec ts;
|
|
||||||
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
||||||
tvp->tv_sec = ts.tv_sec;
|
|
||||||
tvp->tv_usec = ts.tv_nsec / 1000;
|
|
||||||
#else
|
|
||||||
(void)gettimeofday(tvp, NULL);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute and display ETA
|
|
||||||
*/
|
|
||||||
static const char *
|
|
||||||
stat_eta(struct xbps_fetch_cb_data *xfpd, void *cbdata)
|
|
||||||
{
|
|
||||||
struct xferstat *xfer = cbdata;
|
|
||||||
static char str[16];
|
|
||||||
long elapsed, eta;
|
|
||||||
off_t received, expected;
|
|
||||||
|
|
||||||
if (xfpd->file_size == -1)
|
|
||||||
return "unknown";
|
|
||||||
|
|
||||||
elapsed = xfer->last.tv_sec - xfer->start.tv_sec;
|
|
||||||
received = xfpd->file_dloaded - xfpd->file_offset;
|
|
||||||
expected = xfpd->file_size - xfpd->file_dloaded;
|
|
||||||
eta = (long)(elapsed * (long)expected / (long)received);
|
|
||||||
if (eta > 3600)
|
|
||||||
snprintf(str, sizeof str, "%02ldh%02ldm",
|
|
||||||
eta / 3600, (eta % 3600) / 60);
|
|
||||||
else
|
|
||||||
snprintf(str, sizeof str, "%02ldm%02lds",
|
|
||||||
eta / 60, eta % 60);
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
compare_double(const double a, const double b)
|
|
||||||
{
|
|
||||||
const double precision = 0.00001;
|
|
||||||
|
|
||||||
if ((a - precision) < b && (a + precision) > b)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute and display transfer rate
|
|
||||||
*/
|
|
||||||
static const char *
|
|
||||||
stat_bps(struct xbps_fetch_cb_data *xfpd, void *cbdata)
|
|
||||||
{
|
|
||||||
struct xferstat *xfer = cbdata;
|
|
||||||
static char str[16];
|
|
||||||
char size[8];
|
|
||||||
double delta, bps;
|
|
||||||
|
|
||||||
delta = (xfer->last.tv_sec + (xfer->last.tv_usec / 1.e6))
|
|
||||||
- (xfer->start.tv_sec + (xfer->start.tv_usec / 1.e6));
|
|
||||||
if (compare_double(delta, 0.0001)) {
|
|
||||||
snprintf(str, sizeof str, "-- stalled --");
|
|
||||||
} else {
|
|
||||||
bps =
|
|
||||||
((double)(xfpd->file_dloaded - xfpd->file_offset) / delta);
|
|
||||||
(void)xbps_humanize_number(size, (int64_t)bps);
|
|
||||||
snprintf(str, sizeof str, "%s/s", size);
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update the stats display
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
stat_display(struct xbps_fetch_cb_data *xfpd, void *cbdata)
|
|
||||||
{
|
|
||||||
struct xferstat *xfer = cbdata;
|
|
||||||
struct timeval now;
|
|
||||||
char totsize[8], recvsize[8];
|
|
||||||
int percentage;
|
|
||||||
|
|
||||||
get_time(&now);
|
|
||||||
if (now.tv_sec <= xfer->last.tv_sec)
|
|
||||||
return;
|
|
||||||
xfer->last = now;
|
|
||||||
|
|
||||||
if (xfpd->file_size == -1) {
|
|
||||||
percentage = 0;
|
|
||||||
snprintf(totsize, 3, "0B");
|
|
||||||
} else {
|
|
||||||
percentage = (int)((double)(100.0 *
|
|
||||||
(double)xfpd->file_dloaded) / (double)xfpd->file_size);
|
|
||||||
(void)xbps_humanize_number(totsize, (int64_t)xfpd->file_size);
|
|
||||||
}
|
|
||||||
(void)xbps_humanize_number(recvsize, (int64_t)xfpd->file_dloaded);
|
|
||||||
fprintf(stderr, "%s: %s [%d%% of %s] %s ETA: %s\033[K\r",
|
|
||||||
xfpd->file_name, recvsize, percentage, totsize,
|
|
||||||
stat_bps(xfpd, xfer), stat_eta(xfpd, xfer));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fetch_file_progress_cb(struct xbps_handle *xhp,
|
|
||||||
struct xbps_fetch_cb_data *xfpd,
|
|
||||||
void *cbdata)
|
|
||||||
{
|
|
||||||
struct xferstat *xfer = cbdata;
|
|
||||||
char size[8];
|
|
||||||
|
|
||||||
(void)xhp;
|
|
||||||
|
|
||||||
if (xfpd->cb_start) {
|
|
||||||
/* start transfer stats */
|
|
||||||
get_time(&xfer->start);
|
|
||||||
xfer->last.tv_sec = xfer->last.tv_usec = 0;
|
|
||||||
} else if (xfpd->cb_update) {
|
|
||||||
/* update transfer stats */
|
|
||||||
stat_display(xfpd, xfer);
|
|
||||||
} else if (xfpd->cb_end) {
|
|
||||||
/* end transfer stats */
|
|
||||||
(void)xbps_humanize_number(size, (int64_t)xfpd->file_dloaded);
|
|
||||||
fprintf(stderr,"Downloaded %s for %s [avg rate: %s]\033[K\n",
|
|
||||||
size, xfpd->file_name, stat_bps(xfpd, xfer));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,128 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 "../xbps-repo/defs.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 = 1; i < npatterns; i++) {
|
|
||||||
if ((strcmp(filestr, patterns[i]) == 0) ||
|
|
||||||
(xbps_pkgpattern_match(filestr, patterns[i]) == 1))
|
|
||||||
printf("%s: %s (%s)\n", pkgname, filestr, typestr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prop_object_iterator_release(iter);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
find_files_in_packages(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;
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 "defs.h"
|
|
||||||
|
|
||||||
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;
|
|
||||||
pkg_state_t curstate;
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (lpc->check_state) {
|
|
||||||
if (xbps_pkg_state_dictionary(obj, &curstate))
|
|
||||||
return EINVAL;
|
|
||||||
if (lpc->state == 0) {
|
|
||||||
/* Only list packages that are fully installed */
|
|
||||||
if (curstate != XBPS_PKG_STATE_INSTALLED)
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
/* Only list packages with specified state */
|
|
||||||
if (curstate != lpc->state)
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,473 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <strings.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "compat.h"
|
|
||||||
#include "defs.h"
|
|
||||||
#include "../xbps-repo/defs.h"
|
|
||||||
|
|
||||||
static struct xbps_handle xh;
|
|
||||||
|
|
||||||
static void __attribute__((noreturn))
|
|
||||||
usage(bool fail)
|
|
||||||
{
|
|
||||||
fprintf(stdout,
|
|
||||||
"Usage: xbps-bin [options] target [arguments]\n\n"
|
|
||||||
"[options]\n"
|
|
||||||
" -A Enable Automatic installation (shown as orphan)\n"
|
|
||||||
" -B repo Set <repo> as default repository if xbps.conf not found.\n"
|
|
||||||
" -C file Full path to configuration file\n"
|
|
||||||
" -c cachedir Full path to cachedir, to store downloaded binpkgs\n"
|
|
||||||
" -d Debug mode shown to stderr\n"
|
|
||||||
" -D Print URLs when packages need to be downloaded\n"
|
|
||||||
" -F Force package removal even if there are reverse dependencies\n"
|
|
||||||
" -f Force package installation, configuration or removal\n"
|
|
||||||
" -h Print usage help\n"
|
|
||||||
" -M Enable Manual installation\n"
|
|
||||||
" -n Dry-run mode\n"
|
|
||||||
" -o key[,key] Print package metadata keys in show target\n"
|
|
||||||
" -R Remove recursively packages\n"
|
|
||||||
" -r rootdir Full path to rootdir\n"
|
|
||||||
" -S Sync repository index\n"
|
|
||||||
" -v Verbose messages\n"
|
|
||||||
" -y Assume yes to all questions\n"
|
|
||||||
" -V Show XBPS version\n\n"
|
|
||||||
"[targets]\n"
|
|
||||||
" check <pkgname|all>\n"
|
|
||||||
" Package integrity check for `pkgname' or `all' packages.\n"
|
|
||||||
" dist-upgrade\n"
|
|
||||||
" Update all currently installed packages to newest versions.\n"
|
|
||||||
" find-files <pattern> [patterns]\n"
|
|
||||||
" Print package name/version for any pattern matched.\n"
|
|
||||||
" install <pattern> [patterns]\n"
|
|
||||||
" Install package by specifying pkgnames or package patterns.\n"
|
|
||||||
" list [state]\n"
|
|
||||||
" List installed packages, and optionally matching `state'.\n"
|
|
||||||
" Possible states: half-removed, half-unpacked, installed, unpacked.\n"
|
|
||||||
" reconfigure <pkgname|all>\n"
|
|
||||||
" Reconfigure `pkgname' or `all' packages.\n"
|
|
||||||
" remove <pkgname> [pkgnames]\n"
|
|
||||||
" Remove a list of packages.\n"
|
|
||||||
" remove-orphans\n"
|
|
||||||
" Remove all package orphans from system.\n"
|
|
||||||
" show <pkgname>\n"
|
|
||||||
" Print package information for `pkgname'.\n"
|
|
||||||
" show-deps <pkgname>\n"
|
|
||||||
" Print package's required dependencies for `pkgname'.\n"
|
|
||||||
" show-files <pkgname>\n"
|
|
||||||
" Print package's files list for `pkgname'.\n"
|
|
||||||
" show-orphans\n"
|
|
||||||
" List all package orphans currently installed.\n"
|
|
||||||
" show-revdeps <pkgname>\n"
|
|
||||||
" Print package's reverse dependencies for `pkgname'.\n"
|
|
||||||
" update <pkgname> [pkgnames]\n"
|
|
||||||
" Update a list of packages by specifing its names.\n\n"
|
|
||||||
"Refer to xbps-bin(8) for a more detailed description.\n");
|
|
||||||
|
|
||||||
exit(fail ? EXIT_FAILURE : EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((noreturn))
|
|
||||||
cleanup(int signum)
|
|
||||||
{
|
|
||||||
xbps_end(&xh);
|
|
||||||
exit(signum);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
struct xferstat xfer;
|
|
||||||
struct list_pkgver_cb lpc;
|
|
||||||
struct sigaction sa;
|
|
||||||
const char *rootdir, *cachedir, *conffile, *option, *defrepo;
|
|
||||||
int i, c, flags, rv;
|
|
||||||
bool rsync, yes, reqby_force, force_rm_with_deps, recursive_rm;
|
|
||||||
bool reinstall, show_download_pkglist_url, dry_run;
|
|
||||||
size_t maxcols;
|
|
||||||
|
|
||||||
rootdir = cachedir = conffile = option = defrepo = NULL;
|
|
||||||
flags = rv = 0;
|
|
||||||
reqby_force = rsync = yes = dry_run = force_rm_with_deps = false;
|
|
||||||
recursive_rm = reinstall = show_download_pkglist_url = false;
|
|
||||||
|
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "AB:C:c:dDFfhMno:Rr:SVvy")) != -1) {
|
|
||||||
switch (c) {
|
|
||||||
case 'A':
|
|
||||||
flags |= XBPS_FLAG_INSTALL_AUTO;
|
|
||||||
break;
|
|
||||||
case 'B':
|
|
||||||
defrepo = optarg;
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
conffile = optarg;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
cachedir = optarg;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
flags |= XBPS_FLAG_DEBUG;
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
show_download_pkglist_url = true;
|
|
||||||
break;
|
|
||||||
case 'F':
|
|
||||||
force_rm_with_deps = true;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
reinstall = true;
|
|
||||||
flags |= XBPS_FLAG_FORCE_CONFIGURE;
|
|
||||||
flags |= XBPS_FLAG_FORCE_REMOVE_FILES;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
usage(false);
|
|
||||||
break;
|
|
||||||
case 'M':
|
|
||||||
flags |= XBPS_FLAG_INSTALL_MANUAL;
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
dry_run = true;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
option = optarg;
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
recursive_rm = true;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
/* To specify the root directory */
|
|
||||||
rootdir = optarg;
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
rsync = true;
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
flags |= XBPS_FLAG_VERBOSE;
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
printf("%s\n", XBPS_RELVER);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
case 'y':
|
|
||||||
yes = true;
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
default:
|
|
||||||
usage(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (argc < 1)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
/* Specifying -A and -M is illegal */
|
|
||||||
if ((flags & XBPS_FLAG_INSTALL_AUTO) &&
|
|
||||||
(flags & XBPS_FLAG_INSTALL_MANUAL)) {
|
|
||||||
xbps_error_printf("xbps-bin: -A and -M options cannot be "
|
|
||||||
"used together!\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize libxbps.
|
|
||||||
*/
|
|
||||||
memset(&xh, 0, sizeof(xh));
|
|
||||||
xh.state_cb = state_cb;
|
|
||||||
xh.fetch_cb = fetch_file_progress_cb;
|
|
||||||
xh.fetch_cb_data = &xfer;
|
|
||||||
xh.rootdir = rootdir;
|
|
||||||
xh.cachedir = cachedir;
|
|
||||||
xh.conffile = conffile;
|
|
||||||
xh.flags = flags;
|
|
||||||
xh.repository = defrepo;
|
|
||||||
if (flags & XBPS_FLAG_VERBOSE)
|
|
||||||
xh.unpack_cb = unpack_progress_cb_verbose;
|
|
||||||
else
|
|
||||||
xh.unpack_cb = unpack_progress_cb;
|
|
||||||
|
|
||||||
if ((rv = xbps_init(&xh)) != 0) {
|
|
||||||
xbps_error_printf("xbps-bin: couldn't initialize library: %s\n",
|
|
||||||
strerror(rv));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Register a signal handler to clean up resources used by libxbps.
|
|
||||||
*/
|
|
||||||
memset(&sa, 0, sizeof(sa));
|
|
||||||
sa.sa_handler = cleanup;
|
|
||||||
sigaction(SIGHUP, &sa, NULL);
|
|
||||||
sigaction(SIGINT, &sa, NULL);
|
|
||||||
sigaction(SIGTERM, &sa, NULL);
|
|
||||||
|
|
||||||
maxcols = get_maxcols();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check that we have write permission on rootdir, metadir and cachedir.
|
|
||||||
*/
|
|
||||||
if (((strcasecmp(argv[0], "install") == 0) ||
|
|
||||||
(strcasecmp(argv[0], "update") == 0) ||
|
|
||||||
(strcasecmp(argv[0], "remove") == 0) ||
|
|
||||||
(strcasecmp(argv[0], "dist-upgrade") == 0) ||
|
|
||||||
(strcasecmp(argv[0], "remove-orphans") == 0)) && !dry_run) {
|
|
||||||
if ((access(xh.rootdir, W_OK) == -1) ||
|
|
||||||
(access(xh.metadir, W_OK) == -1) ||
|
|
||||||
(access(xh.cachedir, W_OK) == -1)) {
|
|
||||||
if (errno != ENOENT) {
|
|
||||||
xbps_error_printf("xbps-bin: cannot write to "
|
|
||||||
"rootdir/cachedir/metadir: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
xbps_end(&xh);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcasecmp(argv[0], "list") == 0) {
|
|
||||||
/* Lists packages currently registered in database. */
|
|
||||||
if (argc < 1 || argc > 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
lpc.check_state = true;
|
|
||||||
lpc.state = 0;
|
|
||||||
if (argv[1]) {
|
|
||||||
if (strcmp(argv[1], "installed") == 0)
|
|
||||||
lpc.state = XBPS_PKG_STATE_INSTALLED;
|
|
||||||
if (strcmp(argv[1], "half-unpacked") == 0)
|
|
||||||
lpc.state = XBPS_PKG_STATE_HALF_UNPACKED;
|
|
||||||
else if (strcmp(argv[1], "unpacked") == 0)
|
|
||||||
lpc.state = XBPS_PKG_STATE_UNPACKED;
|
|
||||||
else if (strcmp(argv[1], "half-removed") == 0)
|
|
||||||
lpc.state = XBPS_PKG_STATE_HALF_REMOVED;
|
|
||||||
else {
|
|
||||||
xbps_error_printf(
|
|
||||||
"invalid state `%s'. Accepted values: "
|
|
||||||
"half-removed, unpacked, half-unpacked, "
|
|
||||||
"installed [default]\n", argv[1]);
|
|
||||||
rv = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Find the longest pkgver string to pretty print the output.
|
|
||||||
*/
|
|
||||||
lpc.pkgver_len = find_longest_pkgver(&xh, NULL);
|
|
||||||
lpc.maxcols = maxcols;
|
|
||||||
rv = xbps_pkgdb_foreach_cb(&xh, list_pkgs_in_dict, &lpc);
|
|
||||||
if (rv == ENOENT) {
|
|
||||||
printf("No packages currently registered.\n");
|
|
||||||
rv = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "install") == 0) {
|
|
||||||
/* Installs a binary package and required deps. */
|
|
||||||
if (argc < 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
if (rsync && ((rv = xbps_rpool_sync(&xh, NULL)) != 0))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
|
||||||
if ((rv = install_new_pkg(&xh, argv[i], reinstall)) != 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rv = exec_transaction(&xh, maxcols, yes, dry_run,
|
|
||||||
show_download_pkglist_url);
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "update") == 0) {
|
|
||||||
/* Update an installed package. */
|
|
||||||
if (argc < 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
if (rsync && ((rv = xbps_rpool_sync(&xh, NULL)) != 0))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
|
||||||
if ((rv = update_pkg(&xh, argv[i])) != 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rv = exec_transaction(&xh, yes, maxcols, dry_run,
|
|
||||||
show_download_pkglist_url);
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "remove") == 0) {
|
|
||||||
/* Removes a package. */
|
|
||||||
if (argc < 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
rv = remove_pkg(&xh, argv[i], maxcols, recursive_rm);
|
|
||||||
if (rv == 0)
|
|
||||||
continue;
|
|
||||||
else if (rv != EEXIST)
|
|
||||||
goto out;
|
|
||||||
else
|
|
||||||
reqby_force = true;
|
|
||||||
}
|
|
||||||
if (reqby_force && !force_rm_with_deps) {
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
rv = exec_transaction(&xh, maxcols, yes, dry_run, false);
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "show") == 0) {
|
|
||||||
/* Shows info about an installed binary package. */
|
|
||||||
if (argc != 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = show_pkg_info_from_metadir(&xh, argv[1], option);
|
|
||||||
if (rv != 0) {
|
|
||||||
printf("Package %s not installed.\n", argv[1]);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "show-files") == 0) {
|
|
||||||
/* Shows files installed by a binary package. */
|
|
||||||
if (argc != 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = show_pkg_files_from_metadir(&xh, argv[1]);
|
|
||||||
if (rv != 0) {
|
|
||||||
printf("Package %s not installed.\n", argv[1]);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "check") == 0) {
|
|
||||||
/* Checks the integrity of an installed package. */
|
|
||||||
if (argc != 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
if (strcasecmp(argv[1], "all") == 0)
|
|
||||||
rv = check_pkg_integrity_all(&xh);
|
|
||||||
else
|
|
||||||
rv = check_pkg_integrity(&xh, NULL, argv[1], true, NULL);
|
|
||||||
|
|
||||||
} else if ((strcasecmp(argv[0], "dist-upgrade") == 0) ||
|
|
||||||
(strcasecmp(argv[0], "autoupdate") == 0)) {
|
|
||||||
/*
|
|
||||||
* To update all packages currently installed.
|
|
||||||
*/
|
|
||||||
if (argc != 1)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
if (rsync && ((rv = xbps_rpool_sync(&xh, NULL)) != 0))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rv = dist_upgrade(&xh, maxcols, yes, dry_run,
|
|
||||||
show_download_pkglist_url);
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "show-orphans") == 0) {
|
|
||||||
/*
|
|
||||||
* Only show the package name of all currently package
|
|
||||||
* orphans.
|
|
||||||
*/
|
|
||||||
if (argc != 1)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = show_orphans(&xh);
|
|
||||||
|
|
||||||
} else if ((strcasecmp(argv[0], "remove-orphans") == 0) ||
|
|
||||||
(strcasecmp(argv[0], "autoremove") == 0)) {
|
|
||||||
/*
|
|
||||||
* Removes orphan pkgs. These packages were installed
|
|
||||||
* as dependency and any installed package does not depend
|
|
||||||
* on it currently.
|
|
||||||
*/
|
|
||||||
if (argc != 1)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = remove_pkg_orphans(&xh, maxcols, yes, dry_run);
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "reconfigure") == 0) {
|
|
||||||
/*
|
|
||||||
* Reconfigure a package.
|
|
||||||
*/
|
|
||||||
if (argc != 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
if (strcasecmp(argv[1], "all") == 0)
|
|
||||||
rv = xbps_configure_packages(&xh, true);
|
|
||||||
else
|
|
||||||
rv = xbps_configure_pkg(&xh, argv[1], true, false, true);
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "show-deps") == 0) {
|
|
||||||
/*
|
|
||||||
* Show dependencies for a package.
|
|
||||||
*/
|
|
||||||
if (argc != 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = show_pkg_deps(&xh, argv[1]);
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "list-manual") == 0) {
|
|
||||||
/*
|
|
||||||
* List packages that were installed manually, not as
|
|
||||||
* dependencies.
|
|
||||||
*/
|
|
||||||
if (argc != 1)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = xbps_pkgdb_foreach_cb(&xh, list_manual_pkgs, NULL);
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "show-revdeps") == 0) {
|
|
||||||
/*
|
|
||||||
* Show reverse dependencies for a package.
|
|
||||||
*/
|
|
||||||
if (argc != 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = show_pkg_reverse_deps(&xh, argv[1]);
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "find-files") == 0) {
|
|
||||||
/*
|
|
||||||
* Find files matched by a pattern from installed
|
|
||||||
* packages.
|
|
||||||
*/
|
|
||||||
if (argc < 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = find_files_in_packages(&xh, argc, argv);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
usage(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
xbps_end(&xh);
|
|
||||||
exit(rv);
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2008-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 <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
static char *
|
|
||||||
strtrim(char *str)
|
|
||||||
{
|
|
||||||
char *pch = str;
|
|
||||||
|
|
||||||
if (str == NULL || *str == '\0')
|
|
||||||
return str;
|
|
||||||
|
|
||||||
while (isspace((unsigned char)*pch))
|
|
||||||
pch++;
|
|
||||||
|
|
||||||
if (pch != str)
|
|
||||||
memmove(str, pch, (strlen(pch) + 1));
|
|
||||||
|
|
||||||
if (*str == '\0')
|
|
||||||
return str;
|
|
||||||
|
|
||||||
pch = (str + (strlen(str) - 1));
|
|
||||||
while (isspace((unsigned char)*pch))
|
|
||||||
pch--;
|
|
||||||
|
|
||||||
*++pch = '\0';
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
question(bool preset, const char *fmt, va_list ap)
|
|
||||||
{
|
|
||||||
char response[32];
|
|
||||||
|
|
||||||
vfprintf(stderr, fmt, ap);
|
|
||||||
if (preset)
|
|
||||||
fprintf(stderr, " %s ", "[YES/no]");
|
|
||||||
else
|
|
||||||
fprintf(stderr, " %s ", "[yes/NO]");
|
|
||||||
|
|
||||||
if (fgets(response, sizeof(response), stdin)) {
|
|
||||||
(void)strtrim(response);
|
|
||||||
if (strlen(response) == 0)
|
|
||||||
return preset;
|
|
||||||
|
|
||||||
if (strcasecmp(response, "yes") == 0)
|
|
||||||
return true;
|
|
||||||
else if (strcasecmp(response, "no") == 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
yesno(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
bool res;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
res = question(1, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
noyes(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
bool res;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
res = question(0, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2009-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 <assert.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
#include "../xbps-repo/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) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: unexistent %s metadata file.\n", pkgname,
|
|
||||||
XBPS_PKGPROPS);
|
|
||||||
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_reverse_deps(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) {
|
|
||||||
printf("Package %s is not installed.\n", pkgname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rv = xbps_callback_array_iter_in_dict(xhp, pkgd, "requiredby",
|
|
||||||
list_strings_sep_in_array, NULL);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2008-2011 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 <xbps_api.h>
|
|
||||||
#include "../xbps-repo/defs.h"
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2008-2011 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 <errno.h>
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
show_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;
|
|
||||||
}
|
|
@ -1,160 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2011-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 <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
state_cb(struct xbps_handle *xhp,
|
|
||||||
struct xbps_state_cb_data *xscd,
|
|
||||||
void *cbdata)
|
|
||||||
{
|
|
||||||
prop_dictionary_t pkgd;
|
|
||||||
const char *version;
|
|
||||||
bool syslog_enabled = false;
|
|
||||||
|
|
||||||
(void)cbdata;
|
|
||||||
|
|
||||||
if (xhp->flags & XBPS_FLAG_SYSLOG) {
|
|
||||||
syslog_enabled = true;
|
|
||||||
openlog("xbps-bin", LOG_CONS, LOG_USER);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (xscd->state) {
|
|
||||||
/* notifications */
|
|
||||||
case XBPS_STATE_TRANS_DOWNLOAD:
|
|
||||||
printf("[*] Downloading binary packages\n");
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_TRANS_VERIFY:
|
|
||||||
printf("[*] Verifying binary package integrity\n");
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_TRANS_RUN:
|
|
||||||
printf("[*] Running transaction tasks\n");
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_TRANS_CONFIGURE:
|
|
||||||
printf("[*] Configuring unpacked packages\n");
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_REPOSYNC:
|
|
||||||
case XBPS_STATE_DOWNLOAD:
|
|
||||||
case XBPS_STATE_VERIFY:
|
|
||||||
case XBPS_STATE_CONFIG_FILE:
|
|
||||||
if (xscd->desc != NULL)
|
|
||||||
printf("%s\n", xscd->desc);
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_REMOVE:
|
|
||||||
printf("Removing `%s-%s' ...\n", xscd->pkgname, xscd->version);
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_CONFIGURE:
|
|
||||||
printf("Configuring `%s-%s' ...\n", xscd->pkgname,
|
|
||||||
xscd->version);
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_REGISTER:
|
|
||||||
case XBPS_STATE_UNREGISTER:
|
|
||||||
/* empty */
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_UNPACK:
|
|
||||||
printf("Unpacking `%s-%s' ...\n", xscd->pkgname, xscd->version);
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_INSTALL:
|
|
||||||
printf("Installing `%s-%s' ...\n",
|
|
||||||
xscd->pkgname, xscd->version);
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_UPDATE:
|
|
||||||
pkgd = xbps_find_pkg_dict_installed(xhp,
|
|
||||||
xscd->pkgname, false);
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgd, "version", &version);
|
|
||||||
printf("Updating `%s' (`%s' to `%s') ...\n", xscd->pkgname,
|
|
||||||
version, xscd->version);
|
|
||||||
break;
|
|
||||||
/* success */
|
|
||||||
case XBPS_STATE_REMOVE_FILE:
|
|
||||||
case XBPS_STATE_REMOVE_FILE_OBSOLETE:
|
|
||||||
if (xhp->flags & XBPS_FLAG_VERBOSE)
|
|
||||||
printf("%s\n", xscd->desc);
|
|
||||||
else {
|
|
||||||
printf("%s\n", xscd->desc);
|
|
||||||
printf("\033[1A\033[K");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_INSTALL_DONE:
|
|
||||||
printf("Installed `%s-%s' successfully.\n",
|
|
||||||
xscd->pkgname, xscd->version);
|
|
||||||
if (syslog_enabled)
|
|
||||||
syslog(LOG_NOTICE, "Installed `%s-%s' successfully "
|
|
||||||
"(rootdir: %s).", xscd->pkgname, xscd->version,
|
|
||||||
xhp->rootdir);
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_UPDATE_DONE:
|
|
||||||
printf("Updated `%s' to `%s' successfully.\n",
|
|
||||||
xscd->pkgname, xscd->version);
|
|
||||||
if (syslog_enabled)
|
|
||||||
syslog(LOG_NOTICE, "Updated `%s' to `%s' successfully "
|
|
||||||
"(rootdir: %s).", xscd->pkgname, xscd->version,
|
|
||||||
xhp->rootdir);
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_REMOVE_DONE:
|
|
||||||
printf("Removed `%s-%s' successfully.\n",
|
|
||||||
xscd->pkgname, xscd->version);
|
|
||||||
if (syslog_enabled)
|
|
||||||
syslog(LOG_NOTICE, "Removed `%s-%s' successfully "
|
|
||||||
"(rootdir: %s).", xscd->pkgname, xscd->version,
|
|
||||||
xhp->rootdir);
|
|
||||||
break;
|
|
||||||
/* errors */
|
|
||||||
case XBPS_STATE_UNPACK_FAIL:
|
|
||||||
case XBPS_STATE_UPDATE_FAIL:
|
|
||||||
case XBPS_STATE_CONFIGURE_FAIL:
|
|
||||||
case XBPS_STATE_REGISTER_FAIL:
|
|
||||||
case XBPS_STATE_UNREGISTER_FAIL:
|
|
||||||
case XBPS_STATE_REMOVE_FAIL:
|
|
||||||
case XBPS_STATE_VERIFY_FAIL:
|
|
||||||
case XBPS_STATE_DOWNLOAD_FAIL:
|
|
||||||
case XBPS_STATE_REPOSYNC_FAIL:
|
|
||||||
case XBPS_STATE_CONFIG_FILE_FAIL:
|
|
||||||
xbps_error_printf("%s\n", xscd->desc);
|
|
||||||
if (syslog_enabled)
|
|
||||||
syslog(LOG_ERR, "%s", xscd->desc);
|
|
||||||
break;
|
|
||||||
case XBPS_STATE_REMOVE_FILE_FAIL:
|
|
||||||
case XBPS_STATE_REMOVE_FILE_HASH_FAIL:
|
|
||||||
case XBPS_STATE_REMOVE_FILE_OBSOLETE_FAIL:
|
|
||||||
/* Ignore errors due to not empty directories */
|
|
||||||
if (xscd->err == ENOTEMPTY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
xbps_error_printf("%s\n", xscd->desc);
|
|
||||||
if (syslog_enabled)
|
|
||||||
syslog(LOG_ERR, "%s", xscd->desc);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
xbps_dbg_printf(xhp,
|
|
||||||
"unknown state %d\n", xscd->state);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,451 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <ctype.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "compat.h"
|
|
||||||
#include "defs.h"
|
|
||||||
#include "../xbps-repo/defs.h"
|
|
||||||
|
|
||||||
struct transaction {
|
|
||||||
prop_dictionary_t d;
|
|
||||||
prop_object_iterator_t iter;
|
|
||||||
uint32_t inst_pkgcnt;
|
|
||||||
uint32_t up_pkgcnt;
|
|
||||||
uint32_t cf_pkgcnt;
|
|
||||||
uint32_t rm_pkgcnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
show_missing_deps(prop_array_t a)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
const char *str;
|
|
||||||
|
|
||||||
fprintf(stderr, "xbps-bin: unable to locate some required packages:\n");
|
|
||||||
for (i = 0; i < prop_array_count(a); i++) {
|
|
||||||
prop_array_get_cstring_nocopy(a, i, &str);
|
|
||||||
fprintf(stderr, " * Missing binary package for: %s\n", str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
show_conflicts(prop_array_t a)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
const char *str;
|
|
||||||
|
|
||||||
fprintf(stderr, "xbps-bin: conflicting packages were found:\n");
|
|
||||||
for (i = 0; i < prop_array_count(a); i++) {
|
|
||||||
prop_array_get_cstring_nocopy(a, i, &str);
|
|
||||||
fprintf(stderr, " %s\n", str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
show_actions(prop_object_iterator_t iter)
|
|
||||||
{
|
|
||||||
prop_object_t obj;
|
|
||||||
const char *repoloc, *trans, *pkgname, *version, *fname, *arch;
|
|
||||||
|
|
||||||
repoloc = trans = pkgname = version = fname = arch = NULL;
|
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "transaction", &trans);
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "version", &version);
|
|
||||||
printf("%s %s %s", pkgname, trans, version);
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc);
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "filename", &fname);
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "architecture", &arch);
|
|
||||||
if (repoloc && fname && arch)
|
|
||||||
printf(" %s %s %s", repoloc, fname, arch);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
show_binpkgs_url(struct xbps_handle *xhp, prop_object_iterator_t iter)
|
|
||||||
{
|
|
||||||
prop_object_t obj;
|
|
||||||
const char *repoloc, *trans;
|
|
||||||
char *binfile;
|
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "transaction", &trans);
|
|
||||||
if ((strcmp(trans, "remove") == 0) ||
|
|
||||||
(strcmp(trans, "configure") == 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!prop_dictionary_get_cstring_nocopy(obj,
|
|
||||||
"repository", &repoloc))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore pkgs from local repositories */
|
|
||||||
if (!xbps_check_is_repository_uri_remote(repoloc))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
binfile = xbps_path_from_repository_uri(xhp, obj, repoloc);
|
|
||||||
if (binfile == NULL)
|
|
||||||
return errno;
|
|
||||||
/*
|
|
||||||
* If downloaded package is in cachedir, ignore it.
|
|
||||||
*/
|
|
||||||
if (access(binfile, R_OK) == 0) {
|
|
||||||
free(binfile);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
printf("%s\n", binfile);
|
|
||||||
free(binfile);
|
|
||||||
}
|
|
||||||
prop_object_iterator_reset(iter);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
show_package_list(prop_object_iterator_t iter, const char *match, size_t cols)
|
|
||||||
{
|
|
||||||
prop_object_t obj;
|
|
||||||
const char *pkgver, *tract;
|
|
||||||
|
|
||||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract);
|
|
||||||
if (strcmp(match, tract))
|
|
||||||
continue;
|
|
||||||
print_package_line(pkgver, cols, false);
|
|
||||||
}
|
|
||||||
prop_object_iterator_reset(iter);
|
|
||||||
print_package_line(NULL, cols, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
show_transaction_sizes(struct transaction *trans, size_t cols)
|
|
||||||
{
|
|
||||||
uint64_t dlsize = 0, instsize = 0, rmsize = 0;
|
|
||||||
char size[8];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Show the list of packages that will be installed.
|
|
||||||
*/
|
|
||||||
if (prop_dictionary_get_uint32(trans->d, "total-install-pkgs",
|
|
||||||
&trans->inst_pkgcnt)) {
|
|
||||||
printf("%u package%s will be installed:\n",
|
|
||||||
trans->inst_pkgcnt, trans->inst_pkgcnt == 1 ? "" : "s");
|
|
||||||
show_package_list(trans->iter, "install", cols);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
if (prop_dictionary_get_uint32(trans->d, "total-update-pkgs",
|
|
||||||
&trans->up_pkgcnt)) {
|
|
||||||
printf("%u package%s will be updated:\n",
|
|
||||||
trans->up_pkgcnt, trans->up_pkgcnt == 1 ? "" : "s");
|
|
||||||
show_package_list(trans->iter, "update", cols);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
if (prop_dictionary_get_uint32(trans->d, "total-configure-pkgs",
|
|
||||||
&trans->cf_pkgcnt)) {
|
|
||||||
printf("%u package%s will be configured:\n",
|
|
||||||
trans->cf_pkgcnt, trans->cf_pkgcnt == 1 ? "" : "s");
|
|
||||||
show_package_list(trans->iter, "configure", cols);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
if (prop_dictionary_get_uint32(trans->d, "total-remove-pkgs",
|
|
||||||
&trans->rm_pkgcnt)) {
|
|
||||||
printf("%u package%s will be removed:\n",
|
|
||||||
trans->rm_pkgcnt, trans->rm_pkgcnt == 1 ? "" : "s");
|
|
||||||
show_package_list(trans->iter, "remove", cols);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Show total download/installed/removed size for all required packages.
|
|
||||||
*/
|
|
||||||
printf("\n");
|
|
||||||
prop_dictionary_get_uint64(trans->d, "total-download-size", &dlsize);
|
|
||||||
if (dlsize > 0) {
|
|
||||||
if (xbps_humanize_number(size, (int64_t)dlsize) == -1) {
|
|
||||||
xbps_error_printf("xbps-bin: error: humanize_number returns "
|
|
||||||
"%s\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
printf("Total download size:\t%6s\n", size);
|
|
||||||
}
|
|
||||||
prop_dictionary_get_uint64(trans->d, "total-installed-size",
|
|
||||||
&instsize);
|
|
||||||
if (instsize > 0) {
|
|
||||||
if (xbps_humanize_number(size, (int64_t)instsize) == -1) {
|
|
||||||
xbps_error_printf("xbps-bin: error: humanize_number2 returns "
|
|
||||||
"%s\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
printf("Total installed size:\t%6s\n", size);
|
|
||||||
}
|
|
||||||
prop_dictionary_get_uint64(trans->d, "total-removed-size", &rmsize);
|
|
||||||
if (rmsize > 0) {
|
|
||||||
if (xbps_humanize_number(size, (int64_t)rmsize) == -1) {
|
|
||||||
xbps_error_printf("xbps-bin: error: humanize_number3 returns "
|
|
||||||
"%s\n", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
printf("Total freed size:\t%6s\n", size);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
dist_upgrade(struct xbps_handle *xhp,
|
|
||||||
size_t cols,
|
|
||||||
bool yes,
|
|
||||||
bool dry_run,
|
|
||||||
bool show_download_pkglist_url)
|
|
||||||
{
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update all currently installed packages, aka
|
|
||||||
* "xbps-bin autoupdate".
|
|
||||||
*/
|
|
||||||
if ((rv = xbps_transaction_update_packages(xhp)) != 0) {
|
|
||||||
if (rv == ENOENT) {
|
|
||||||
printf("No packages currently registered.\n");
|
|
||||||
return 0;
|
|
||||||
} else if (rv == EEXIST) {
|
|
||||||
printf("All packages are up-to-date.\n");
|
|
||||||
return 0;
|
|
||||||
} else if (rv == ENOTSUP) {
|
|
||||||
xbps_error_printf("xbps-bin: no repositories currently "
|
|
||||||
"registered!\n");
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
xbps_error_printf("xbps-bin: unexpected error %s\n",
|
|
||||||
strerror(rv));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return exec_transaction(xhp, cols, yes, dry_run,
|
|
||||||
show_download_pkglist_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
remove_pkg_orphans(struct xbps_handle *xhp, size_t cols, bool yes, bool dry_run)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if ((rv = xbps_transaction_autoremove_pkgs(xhp)) != 0) {
|
|
||||||
if (rv == ENOENT) {
|
|
||||||
printf("No package orphans were found.\n");
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
printf("Failed to remove package orphans: %s\n",
|
|
||||||
strerror(rv));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return exec_transaction(xhp, cols, yes, dry_run, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
install_new_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if ((rv = xbps_transaction_install_pkg(xhp, pkg, reinstall)) != 0) {
|
|
||||||
if (rv == EEXIST) {
|
|
||||||
printf("Package `%s' already installed.\n", pkg);
|
|
||||||
} else if (rv == ENOENT) {
|
|
||||||
xbps_error_printf("xbps-bin: unable to locate '%s' in "
|
|
||||||
"repository pool.\n", pkg);
|
|
||||||
} else if (rv == ENOTSUP) {
|
|
||||||
xbps_error_printf("xbps-bin: no repositories "
|
|
||||||
"currently registered!\n");
|
|
||||||
} else {
|
|
||||||
xbps_error_printf("xbps-bin: unexpected error: %s\n",
|
|
||||||
strerror(rv));
|
|
||||||
rv = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
update_pkg(struct xbps_handle *xhp, const char *pkgname)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv = xbps_transaction_update_pkg(xhp, pkgname);
|
|
||||||
if (rv == EEXIST)
|
|
||||||
printf("Package '%s' is up to date.\n", pkgname);
|
|
||||||
else if (rv == ENOENT)
|
|
||||||
fprintf(stderr, "Package '%s' not found in "
|
|
||||||
"repository pool.\n", pkgname);
|
|
||||||
else if (rv == ENODEV)
|
|
||||||
printf("Package '%s' not installed.\n", pkgname);
|
|
||||||
else if (rv == ENOTSUP)
|
|
||||||
xbps_error_printf("xbps-bin: no repositories currently "
|
|
||||||
"registered!\n");
|
|
||||||
else if (rv != 0) {
|
|
||||||
xbps_error_printf("xbps-bin: unexpected error %s\n",
|
|
||||||
strerror(rv));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
remove_pkg(struct xbps_handle *xhp, const char *pkgname, size_t cols,
|
|
||||||
bool recursive)
|
|
||||||
{
|
|
||||||
prop_dictionary_t pkgd;
|
|
||||||
prop_array_t reqby;
|
|
||||||
const char *pkgver;
|
|
||||||
size_t x;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv = xbps_transaction_remove_pkg(xhp, pkgname, recursive);
|
|
||||||
if (rv == EEXIST) {
|
|
||||||
/* pkg has revdeps */
|
|
||||||
pkgd = xbps_find_pkg_dict_installed(xhp, pkgname, false);
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
|
|
||||||
reqby = prop_dictionary_get(pkgd, "requiredby");
|
|
||||||
printf("WARNING: %s IS REQUIRED BY %u PACKAGE%s:\n\n",
|
|
||||||
pkgver, prop_array_count(reqby),
|
|
||||||
prop_array_count(reqby) > 1 ? "S" : "");
|
|
||||||
for (x = 0; x < prop_array_count(reqby); x++) {
|
|
||||||
prop_array_get_cstring_nocopy(reqby, x, &pkgver);
|
|
||||||
print_package_line(pkgver, cols, false);
|
|
||||||
}
|
|
||||||
printf("\n\n");
|
|
||||||
print_package_line(NULL, cols, true);
|
|
||||||
return rv;
|
|
||||||
} else if (rv == ENOENT) {
|
|
||||||
printf("Package `%s' is not currently installed.\n", pkgname);
|
|
||||||
return 0;
|
|
||||||
} else if (rv != 0) {
|
|
||||||
xbps_error_printf("Failed to queue `%s' for removing: %s\n",
|
|
||||||
pkgname, strerror(rv));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
exec_transaction(struct xbps_handle *xhp,
|
|
||||||
size_t maxcols,
|
|
||||||
bool yes,
|
|
||||||
bool dry_run,
|
|
||||||
bool show_download_urls)
|
|
||||||
{
|
|
||||||
prop_array_t mdeps, cflicts;
|
|
||||||
struct transaction *trans;
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
trans = calloc(1, sizeof(*trans));
|
|
||||||
if (trans == NULL)
|
|
||||||
return ENOMEM;
|
|
||||||
|
|
||||||
if ((rv = xbps_transaction_prepare(xhp)) != 0) {
|
|
||||||
if (rv == ENODEV) {
|
|
||||||
mdeps =
|
|
||||||
prop_dictionary_get(xhp->transd, "missing_deps");
|
|
||||||
/* missing packages */
|
|
||||||
show_missing_deps(mdeps);
|
|
||||||
goto out;
|
|
||||||
} else if (rv == EAGAIN) {
|
|
||||||
/* conflicts */
|
|
||||||
cflicts = prop_dictionary_get(xhp->transd, "conflicts");
|
|
||||||
show_conflicts(cflicts);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
xbps_dbg_printf(xhp, "Empty transaction dictionary: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
xbps_dbg_printf(xhp, "Dictionary before transaction happens:\n");
|
|
||||||
xbps_dbg_printf_append(xhp, "%s",
|
|
||||||
prop_dictionary_externalize(xhp->transd));
|
|
||||||
|
|
||||||
trans->d = xhp->transd;
|
|
||||||
trans->iter = xbps_array_iter_from_dict(xhp->transd, "packages");
|
|
||||||
if (trans->iter == NULL) {
|
|
||||||
rv = errno;
|
|
||||||
xbps_error_printf("xbps-bin: error allocating array mem! (%s)\n",
|
|
||||||
strerror(errno));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* dry-run mode, show what would be done but don't run anything.
|
|
||||||
*/
|
|
||||||
if (dry_run) {
|
|
||||||
show_actions(trans->iter);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Only show URLs to download binary packages.
|
|
||||||
*/
|
|
||||||
if (show_download_urls) {
|
|
||||||
rv = show_binpkgs_url(xhp, trans->iter);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Show download/installed size for the transaction.
|
|
||||||
*/
|
|
||||||
if ((rv = show_transaction_sizes(trans, maxcols)) != 0)
|
|
||||||
goto out;
|
|
||||||
/*
|
|
||||||
* Ask interactively (if -y not set).
|
|
||||||
*/
|
|
||||||
if (!yes && !yesno("Do you want to continue?")) {
|
|
||||||
printf("Aborting!\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* It's time to run the transaction!
|
|
||||||
*/
|
|
||||||
if ((rv = xbps_transaction_commit(xhp)) == 0) {
|
|
||||||
printf("\nxbps-bin: %u installed, %u updated, "
|
|
||||||
"%u configured, %u removed.\n", trans->inst_pkgcnt,
|
|
||||||
trans->up_pkgcnt, trans->cf_pkgcnt + trans->inst_pkgcnt,
|
|
||||||
trans->rm_pkgcnt);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
if (trans->iter)
|
|
||||||
prop_object_iterator_release(trans->iter);
|
|
||||||
if (trans)
|
|
||||||
free(trans);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2008-2011 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 <errno.h>
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
unpack_progress_cb_verbose(struct xbps_handle *xhp,
|
|
||||||
struct xbps_unpack_cb_data *xpd,
|
|
||||||
void *cbdata)
|
|
||||||
{
|
|
||||||
(void)xhp;
|
|
||||||
(void)cbdata;
|
|
||||||
|
|
||||||
if (xpd->entry == NULL || xpd->entry_total_count <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
printf("%s: unpacked %sfile `%s' (%" PRIi64 " bytes)\n",
|
|
||||||
xpd->pkgver,
|
|
||||||
xpd->entry_is_conf ? "configuration " : "", xpd->entry,
|
|
||||||
xpd->entry_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
unpack_progress_cb(struct xbps_handle *xhp,
|
|
||||||
struct xbps_unpack_cb_data *xpd,
|
|
||||||
void *cbdata)
|
|
||||||
{
|
|
||||||
(void)xhp;
|
|
||||||
(void)cbdata;
|
|
||||||
|
|
||||||
if (xpd->entry_total_count <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
printf("%s: unpacked %zd of %zd files...\n",
|
|
||||||
xpd->pkgver, xpd->entry_extract_count, xpd->entry_total_count);
|
|
||||||
printf("\033[1A\033[K");
|
|
||||||
}
|
|
@ -1,252 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <fnmatch.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
#include "../xbps-repo/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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
get_maxcols(void)
|
|
||||||
{
|
|
||||||
struct winsize ws;
|
|
||||||
|
|
||||||
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) == 0)
|
|
||||||
return ws.ws_col;
|
|
||||||
|
|
||||||
return 80;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
print_package_line(const char *str, size_t maxcols, bool reset)
|
|
||||||
{
|
|
||||||
static size_t cols;
|
|
||||||
static bool first;
|
|
||||||
|
|
||||||
if (reset) {
|
|
||||||
cols = 0;
|
|
||||||
first = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cols += strlen(str) + 4;
|
|
||||||
if (cols <= maxcols) {
|
|
||||||
if (first == false) {
|
|
||||||
printf(" ");
|
|
||||||
first = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("\n ");
|
|
||||||
cols = strlen(str) + 4;
|
|
||||||
}
|
|
||||||
printf("%s ", str);
|
|
||||||
}
|
|
@ -1,355 +0,0 @@
|
|||||||
.Dd September 24, 2012
|
|
||||||
.Os Void GNU/Linux
|
|
||||||
.Dt xbps-bin 8
|
|
||||||
.Sh NAME
|
|
||||||
.Nm xbps-bin
|
|
||||||
.Nd XBPS command for binary packages
|
|
||||||
.Sh SYNOPSYS
|
|
||||||
.Nm xbps-bin
|
|
||||||
.Op options
|
|
||||||
.Op target
|
|
||||||
.Op pkgname(s)|pkgpattern(s)
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
command is used to handle binary packages created for the XBPS binary
|
|
||||||
package system. You can use it to install, remove, update, list or show information
|
|
||||||
about any binary package. Binary packages can be installed from
|
|
||||||
.Em local
|
|
||||||
(directories)
|
|
||||||
or
|
|
||||||
.Em remote
|
|
||||||
repositories (http, https or ftp), see
|
|
||||||
.Xr xbps-repo 8
|
|
||||||
for information about repositories.
|
|
||||||
.Sh OPTIONS
|
|
||||||
.Bl -tag -width Fl
|
|
||||||
.It Fl A
|
|
||||||
Sets the
|
|
||||||
.Em automatic-install
|
|
||||||
boolean object for a package, therefore explicitly
|
|
||||||
setting that the package was installed as if it were a dependency, even if it is not.
|
|
||||||
Use of this option takes effect in the
|
|
||||||
.Em dist-upgrade ,
|
|
||||||
.Em install
|
|
||||||
and
|
|
||||||
.Em update
|
|
||||||
targets.
|
|
||||||
Targetted packages and its required dependencies will be matched.
|
|
||||||
.It Fl B Ar repository
|
|
||||||
If a configuration file cannot be found, this repository will be used as
|
|
||||||
as primary source to install packages.
|
|
||||||
.It Fl C Ar conffile
|
|
||||||
Full path to the XBPS configuration file. By default set to
|
|
||||||
.Pa /etc/xbps/xbps.conf .
|
|
||||||
.It Fl c Ar cachedir
|
|
||||||
Sets the
|
|
||||||
.Em cache
|
|
||||||
directory to store downloaded binary packages from remote
|
|
||||||
repositories. By default set to
|
|
||||||
.Pa /var/cache/xbps .
|
|
||||||
.It Fl d
|
|
||||||
Enables extra debugging output to be shown to stderr.
|
|
||||||
.It Fl D
|
|
||||||
Only show the URLs to download the binary packages from repositories. This is
|
|
||||||
useful if you want to download them by other means, and later you can move
|
|
||||||
them to the cachedir to start the installation. This option can be used for
|
|
||||||
the install, update and dist-upgrade targets.
|
|
||||||
.It Fl F
|
|
||||||
Used currently in the
|
|
||||||
.Em remove
|
|
||||||
target. If set, package will be removed even if other packages are currently
|
|
||||||
depending on it, i.e package is a dependency of any other installed package.
|
|
||||||
.It Fl f
|
|
||||||
Used currently in the
|
|
||||||
.Em install ,
|
|
||||||
.Em reconfigure
|
|
||||||
and
|
|
||||||
.Em remove
|
|
||||||
targets. If set, package(s) will be reconfigured regardless of its state in
|
|
||||||
.Em reconfigure
|
|
||||||
target, or to
|
|
||||||
.Em force
|
|
||||||
removal of package files even if its hash does not match in the
|
|
||||||
.Em remove
|
|
||||||
target. If set, package(s) will be reinstalled even if its state is
|
|
||||||
.Em installed
|
|
||||||
when used with the
|
|
||||||
.Em install
|
|
||||||
target.
|
|
||||||
.It Fl M
|
|
||||||
Sets the
|
|
||||||
.Em automatic-install
|
|
||||||
boolean object for package to false, therefore
|
|
||||||
explicitly setting that package was installed manually by the user. Use of this
|
|
||||||
option takes effect in the
|
|
||||||
.Em dist-upgrade ,
|
|
||||||
.Em install
|
|
||||||
and
|
|
||||||
.Em update
|
|
||||||
targets
|
|
||||||
and target packages and its required dependencies will be matched.
|
|
||||||
.It Fl n
|
|
||||||
Enables dry-run mode.
|
|
||||||
To show the actions that would be executed in a transaction.
|
|
||||||
This mode takes effect in the
|
|
||||||
.Em remove-orphans ,
|
|
||||||
.Em dist-upgrade ,
|
|
||||||
.Em install ,
|
|
||||||
.Rm remove
|
|
||||||
and
|
|
||||||
.Em update
|
|
||||||
targets.
|
|
||||||
.It Fl o Ar key Op key2,...
|
|
||||||
Used currently in the
|
|
||||||
.Em show
|
|
||||||
target. Prints the value of specified key(s) from
|
|
||||||
package's properties dictionary. Multiple keys can be specified delimited by
|
|
||||||
the comma character.
|
|
||||||
.It Fl R
|
|
||||||
Used currently in the
|
|
||||||
.Em remove
|
|
||||||
target. If set, recursively removes packages that
|
|
||||||
are not required by any other installed package and that were installed by
|
|
||||||
the package that we want to remove.
|
|
||||||
.It Fl r Ar rootdir
|
|
||||||
Sets the
|
|
||||||
.Em root
|
|
||||||
directory. By default the root directory is set to
|
|
||||||
.Em / .
|
|
||||||
Please note that the database directory is always set to
|
|
||||||
.Pa /var/db/xbps
|
|
||||||
independently of rootdir setting. So if you use a rootdir of
|
|
||||||
.Pa /blah ,
|
|
||||||
metadata stuff will go into
|
|
||||||
.Pa /blah/var/db/xbps .
|
|
||||||
.It Fl S
|
|
||||||
Sync remote repository index files before executing the target.
|
|
||||||
Used currently in the
|
|
||||||
.Em dist-upgrade ,
|
|
||||||
.Em install
|
|
||||||
and
|
|
||||||
.Em update
|
|
||||||
targets.
|
|
||||||
.It Fl v
|
|
||||||
Shows verbose messages. Useful while installing and removing packages.
|
|
||||||
.It Fl y
|
|
||||||
Assume
|
|
||||||
.Em yes
|
|
||||||
to all questions. This will bypass all questions and immediately proceed
|
|
||||||
with the task.
|
|
||||||
.It Fl V
|
|
||||||
Shows the current XBPS release version (version, API, index).
|
|
||||||
.Sh TARGETS
|
|
||||||
Please note that all targets are case insensitive.
|
|
||||||
.Pp
|
|
||||||
.Bl -tag -width ident
|
|
||||||
.It Sy check Ar pkgname | Ar all
|
|
||||||
Checks for integrity errors in installed packages. The checks are to find
|
|
||||||
missing run-time dependencies, missing and modified package files and
|
|
||||||
metadata files. If the
|
|
||||||
.Em all
|
|
||||||
keyword is used, all packages currently installed
|
|
||||||
will be checked, otherwise just pkgname.
|
|
||||||
.It Sy dist-upgrade
|
|
||||||
Updates all currently installed packages to the newest version available in
|
|
||||||
all repositories.
|
|
||||||
.It Sy find-files Ar pattern Ar [patterns ...]
|
|
||||||
Prints the name of the installed
|
|
||||||
.Em package(s)
|
|
||||||
matching the pattern on its file list. Multiple patterns can be specified
|
|
||||||
as arguments.
|
|
||||||
.It Sy install Ar pattern Ar [patterns ...]
|
|
||||||
Install binary package(s) from repository pool by specifying a
|
|
||||||
.Em pattern .
|
|
||||||
Three different ways exist to install packages: by specifying just the
|
|
||||||
.Em package name ,
|
|
||||||
the best available version from repositories will be installed; by specifying a
|
|
||||||
.Em package pattern
|
|
||||||
with '>' '<' '>=' or '<='
|
|
||||||
.Em ( foo>=2.0 )
|
|
||||||
or by specifying an exact package version, i.e
|
|
||||||
.Em ( foo-1.0_1) .
|
|
||||||
The first repository matching
|
|
||||||
.Em pattern
|
|
||||||
will be used. The package(s) will be
|
|
||||||
.Em downloaded
|
|
||||||
(if found in a remote repository),
|
|
||||||
.Em unpacked
|
|
||||||
and
|
|
||||||
.Em configured .
|
|
||||||
The
|
|
||||||
.Em unpack
|
|
||||||
stage will execute the pre-install action on its INSTALL script, and unpack its files.
|
|
||||||
The
|
|
||||||
.Em configure
|
|
||||||
stage will run the post-install action set on its INSTALL script and will change its
|
|
||||||
.Em state
|
|
||||||
to installed in the package database.
|
|
||||||
.It Sy list Op state
|
|
||||||
Lists all currently installed packages. Optionally another argument can be specified
|
|
||||||
to list only packages with the specified
|
|
||||||
.Op state .
|
|
||||||
By default only packages fully installed will be listed if
|
|
||||||
.Em state
|
|
||||||
has not been specified. Accepted states are:
|
|
||||||
.Em half-removed ,
|
|
||||||
.Em half-unpacked ,
|
|
||||||
.Em installed
|
|
||||||
and
|
|
||||||
.Em unpacked .
|
|
||||||
.It Sy list-manual
|
|
||||||
Lists packages that were installed manually by the user, i.e not as dependencies
|
|
||||||
of any other package.
|
|
||||||
.It Sy reconfigure Ar pkgname | Ar all
|
|
||||||
Reconfigure an unpacked package. Packages in this state are not fully installed,
|
|
||||||
because they were not configured for whatever reason. The configure stage will
|
|
||||||
run the post-install action set on its INSTALL script and will change its state
|
|
||||||
to installed in the package database. The
|
|
||||||
.Em all
|
|
||||||
keyword can be used to reconfigure all not configured packages. If
|
|
||||||
.Ql -f
|
|
||||||
option is used, the package will be reconfigured even if its state is already installed.
|
|
||||||
.It Sy remove Ar pkgname Ar [pkgnames ...]
|
|
||||||
Removes the installed package
|
|
||||||
.Em pkgname(s) .
|
|
||||||
Files not matching the original SHA256 hash will be preserved. If
|
|
||||||
.Ql -f
|
|
||||||
option is used, package files will be
|
|
||||||
.Em removed even if its SHA256 hash doesn't match .
|
|
||||||
If
|
|
||||||
.Ql -F
|
|
||||||
option is used, package will be removed even if there are
|
|
||||||
.Em installed reverse dependencies .
|
|
||||||
.It Sy remove-orphans
|
|
||||||
Removes package orphans. These packages were installed as dependencies and
|
|
||||||
currently there is not any package depending on it, directly or indirectly.
|
|
||||||
Usually it is safe to always answer yes.
|
|
||||||
.It Sy show Ar pkgname
|
|
||||||
Shows information for installed package
|
|
||||||
.Em pkgname .
|
|
||||||
This will print the size it takes in filesystem, description, maintainer,
|
|
||||||
architecture and other useful information.
|
|
||||||
.It Sy show-deps Ar pkgname
|
|
||||||
Shows the list of dependencies that
|
|
||||||
.Em pkgname
|
|
||||||
requires at run time.
|
|
||||||
.It Sy show-files Ar pkgname
|
|
||||||
Shows the list of files that
|
|
||||||
.Em pkgname
|
|
||||||
contains.
|
|
||||||
.It Sy show-orphans
|
|
||||||
Shows the list of package orphans currently installed. Package orphans are
|
|
||||||
packages that were installed as dependencies of another package, but no other
|
|
||||||
package currently depends on.
|
|
||||||
.It Sy show-revdeps Ar pkgname
|
|
||||||
Shows the reverse dependencies for
|
|
||||||
.Em pkgname .
|
|
||||||
Reverse dependencies are packages that are currently depending in
|
|
||||||
.Em pkgname
|
|
||||||
directly.
|
|
||||||
.It Sy update Ar pkgname Ar [pkgnames ...]
|
|
||||||
Updates
|
|
||||||
.Em pkgname
|
|
||||||
to the newest version available in repository pool. This can be used if only
|
|
||||||
.Em pkgname
|
|
||||||
needs to be updated, unlike the
|
|
||||||
.Em dist-upgrade
|
|
||||||
target that will update all currently installed packages.
|
|
||||||
.Sh PACKAGE STATES
|
|
||||||
A package can be in a different state while it is being
|
|
||||||
.Em installed ,
|
|
||||||
.Em removed ,
|
|
||||||
.Em unpacked
|
|
||||||
or
|
|
||||||
.Em configured .
|
|
||||||
The following states are available:
|
|
||||||
.Bl -tag -width ident
|
|
||||||
.It Sy installed
|
|
||||||
The package is fully installed, that means it was unpacked and configured correctly.
|
|
||||||
.It Sy half-unpacked
|
|
||||||
The package was being unpacked but didn't finish properly for unknown reasons.
|
|
||||||
.It Sy unpacked
|
|
||||||
The package has been unpacked in destination root directory, but it is not fully
|
|
||||||
installed because it was not yet configured. Please note that some packages will
|
|
||||||
not work if they are only unpacked.
|
|
||||||
.It Sy half-removed
|
|
||||||
The package removal did not finish for unknown reasons (power outage, process killed, etc).
|
|
||||||
The
|
|
||||||
.Em purge
|
|
||||||
action in its metadata REMOVE script has not been yet executed. The package
|
|
||||||
metadata directory is still available and it is registered in package database.
|
|
||||||
Packages in this state can still be removed.
|
|
||||||
.Sh FILES
|
|
||||||
.Bl -tag -width /var/db/xbps/metadata/<pkgname>/props.plist -compact
|
|
||||||
.It Pa /etc/xbps/xbps.conf
|
|
||||||
Default XBPS configuration file.
|
|
||||||
.It Pa /var/db/xbps
|
|
||||||
XBPS global metadata directory.
|
|
||||||
.It Pa /var/db/xbps/metadata/<pkgname>/files.plist
|
|
||||||
Installed package metadata list of files.
|
|
||||||
.It Pa /var/db/xbps/metadata/<pkgname>/props.plist
|
|
||||||
Installed package metadata properties.
|
|
||||||
.It Pa /var/db/xbps/pkgdb.plist
|
|
||||||
XBPS master package database plist file.
|
|
||||||
.It Pa /var/cache/xbps
|
|
||||||
XBPS cache directory for downloaded binary packages.
|
|
||||||
.Sh EXAMPLES
|
|
||||||
Install best package version by specifying a
|
|
||||||
.Em pkgname :
|
|
||||||
.Pp
|
|
||||||
.Dl $ xbps-bin install foo
|
|
||||||
.Pp
|
|
||||||
Install a package by specifying a
|
|
||||||
.Em package pattern :
|
|
||||||
.Pp
|
|
||||||
.Dl $ xbps-bin install \*qfoo>=3.0\*q
|
|
||||||
.Pp
|
|
||||||
Install an exact
|
|
||||||
.Em package version :
|
|
||||||
.Pp
|
|
||||||
.Dl $ xbps-bin install foo-1.0_1
|
|
||||||
.Pp
|
|
||||||
Install multiple packages by specifying
|
|
||||||
.Em pkgnames
|
|
||||||
and
|
|
||||||
.Em package patterns
|
|
||||||
and
|
|
||||||
.Em exact package versions :
|
|
||||||
.Pp
|
|
||||||
.Dl $ xbps-bin install foo \*qblah<=4.0\*q baz-2.0_1 \*qblob>1.0<1.8\*q
|
|
||||||
.Pp
|
|
||||||
Find the package that owns the file
|
|
||||||
.Pa /bin/mount :
|
|
||||||
.Pp
|
|
||||||
.Dl $ xbps-bin find-files /bin/mount
|
|
||||||
.Pp
|
|
||||||
Find the packages that match the pattern
|
|
||||||
.Pa "/usr/lib/libav*" :
|
|
||||||
.Pp
|
|
||||||
.Dl $ xbps-bin find-files \*q/usr/lib/libav*\*q
|
|
||||||
.Pp
|
|
||||||
Remove the package
|
|
||||||
.Em proplib-devel
|
|
||||||
without confirmation:
|
|
||||||
.Pp
|
|
||||||
.Dl $ xbps-bin -y remove proplib-devel
|
|
||||||
.Pp
|
|
||||||
Remove the package
|
|
||||||
.Em bsdtar
|
|
||||||
and
|
|
||||||
.Em recursively
|
|
||||||
all packages that were installed automatically by it:
|
|
||||||
.Pp
|
|
||||||
.Dl $ xbps-bin -Ry remove bsdtar
|
|
||||||
.Pp
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr xbps-repo 8 ,
|
|
||||||
.Xr http://code.google.com/p/xbps
|
|
||||||
.Sh AUTHORS
|
|
||||||
.An Juan Romero Pardines <xtraeme@gmail.com>
|
|
||||||
.Sh BUGS
|
|
||||||
Probably, but I try to make this not happen. Use it under your own
|
|
||||||
responsability and enjoy your life.
|
|
||||||
.Pp
|
|
||||||
Report bugs in http://code.google.com/p/xbps.
|
|
@ -1,12 +0,0 @@
|
|||||||
TOPDIR = ../..
|
|
||||||
-include $(TOPDIR)/config.mk
|
|
||||||
|
|
||||||
BIN = xbps-repo
|
|
||||||
OBJS = main.o index.o show.o find-files.o list.o
|
|
||||||
OBJS += index-files.o clean.o common.o
|
|
||||||
OBJS += remove-obsoletes.o
|
|
||||||
OBJS += ../xbps-bin/fetch_cb.o ../xbps-bin/util.o
|
|
||||||
OBJS += ../xbps-bin/state_cb.o ../xbps-bin/list.o
|
|
||||||
MAN = $(BIN).8
|
|
||||||
|
|
||||||
include $(TOPDIR)/mk/prog.mk
|
|
@ -1,101 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
cachedir_clean(struct xbps_handle *xhp)
|
|
||||||
{
|
|
||||||
prop_dictionary_t pkg_propsd, repo_pkgd;
|
|
||||||
DIR *dirp;
|
|
||||||
struct dirent *dp;
|
|
||||||
const char *pkgver, *rsha256;
|
|
||||||
char *binpkg, *ext;
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
if ((dirp = opendir(xhp->cachedir)) == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
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 ((ext = strrchr(dp->d_name, '.')) == NULL)
|
|
||||||
continue;
|
|
||||||
if (strcmp(ext, ".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,
|
|
||||||
"./props.plist");
|
|
||||||
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_rpool_find_pkg_exact(xhp, 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);
|
|
||||||
if (unlink(binpkg) == -1)
|
|
||||||
fprintf(stderr, "Failed to remove "
|
|
||||||
"`%s': %s\n", binpkg,
|
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
free(binpkg);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
printf("Removed %s from cachedir (obsolete)\n", dp->d_name);
|
|
||||||
if (unlink(binpkg) == -1)
|
|
||||||
fprintf(stderr, "Failed to remove `%s': %s\n",
|
|
||||||
binpkg, strerror(errno));
|
|
||||||
free(binpkg);
|
|
||||||
}
|
|
||||||
closedir(dirp);
|
|
||||||
return rv;
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
repo_remove_pkg(const char *repodir, const char *arch, const char *file)
|
|
||||||
{
|
|
||||||
char *filepath;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
/* Remove real binpkg */
|
|
||||||
filepath = xbps_xasprintf("%s/%s/%s", repodir, arch, file);
|
|
||||||
assert(filepath);
|
|
||||||
if (remove(filepath) == -1) {
|
|
||||||
rv = errno;
|
|
||||||
xbps_error_printf("failed to remove old binpkg `%s': %s\n",
|
|
||||||
file, strerror(rv));
|
|
||||||
free(filepath);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
free(filepath);
|
|
||||||
|
|
||||||
/* Remove symlink to binpkg */
|
|
||||||
filepath = xbps_xasprintf("%s/%s", repodir, file);
|
|
||||||
assert(filepath);
|
|
||||||
if (remove(filepath) == -1) {
|
|
||||||
rv = errno;
|
|
||||||
xbps_error_printf("failed to remove old binpkg `%s': %s\n",
|
|
||||||
file, strerror(rv));
|
|
||||||
free(filepath);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
free(filepath);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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_REPO_DEFS_H_
|
|
||||||
#define _XBPS_REPO_DEFS_H_
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
|
|
||||||
struct repo_search_data {
|
|
||||||
int npatterns;
|
|
||||||
char **patterns;
|
|
||||||
void *arg;
|
|
||||||
size_t pkgver_len;
|
|
||||||
size_t maxcols;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* From common.c */
|
|
||||||
int repo_remove_pkg(const char *, const char *, const char *);
|
|
||||||
|
|
||||||
/* From index.c */
|
|
||||||
int repo_index_add(struct xbps_handle *, int, char **);
|
|
||||||
int repo_index_clean(struct xbps_handle *, const char *);
|
|
||||||
|
|
||||||
/* From index-files.c */
|
|
||||||
int repo_index_files_add(struct xbps_handle *, int, char **);
|
|
||||||
int repo_index_files_clean(struct xbps_handle *, const char *);
|
|
||||||
|
|
||||||
/* From index-lock.c */
|
|
||||||
int acquire_repo_lock(const char *, char **);
|
|
||||||
void release_repo_lock(char **, int);
|
|
||||||
|
|
||||||
/* From find-files.c */
|
|
||||||
int repo_find_files_in_packages(struct xbps_handle *, int, char **);
|
|
||||||
|
|
||||||
/* From list.c */
|
|
||||||
size_t repo_find_longest_pkgver(struct xbps_handle *);
|
|
||||||
int repo_pkg_list_cb(struct xbps_handle *,
|
|
||||||
struct xbps_rpool_index *,
|
|
||||||
void *,
|
|
||||||
bool *);
|
|
||||||
int repo_list_uri_cb(struct xbps_handle *,
|
|
||||||
struct xbps_rpool_index *,
|
|
||||||
void *,
|
|
||||||
bool *);
|
|
||||||
int repo_search_pkgs_cb(struct xbps_handle *,
|
|
||||||
struct xbps_rpool_index *,
|
|
||||||
void *,
|
|
||||||
bool *);
|
|
||||||
|
|
||||||
/* From remove-obsoletes.c */
|
|
||||||
int repo_remove_obsoletes(struct xbps_handle *, const char *);
|
|
||||||
|
|
||||||
/* From show.c */
|
|
||||||
int show_pkg_info_from_repolist(struct xbps_handle *,
|
|
||||||
const char *,
|
|
||||||
const char *);
|
|
||||||
int show_pkg_deps_from_repolist(struct xbps_handle *, const char *);
|
|
||||||
int show_pkg_namedesc(struct xbps_handle *, prop_object_t, void *, bool *);
|
|
||||||
|
|
||||||
/* From clean.c */
|
|
||||||
int cachedir_clean(struct xbps_handle *);
|
|
||||||
|
|
||||||
#endif /* !_XBPS_REPO_DEFS_H_ */
|
|
@ -1,116 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
struct ffdata {
|
|
||||||
int npatterns;
|
|
||||||
char **patterns;
|
|
||||||
const char *repouri;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
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 = 1; x < ffd->npatterns; x++) {
|
|
||||||
if ((xbps_pkgpattern_match(filestr, ffd->patterns[x])) ||
|
|
||||||
(strstr(filestr, ffd->patterns[x]))) {
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkg_filesd,
|
|
||||||
"pkgver", &pkgver);
|
|
||||||
printf("%s: %s (%s)\n",
|
|
||||||
pkgver, filestr, ffd->repouri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
find_files_in_package(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++)
|
|
||||||
match_files_by_pattern(xhp, prop_array_get(idxfiles, i), ffd);
|
|
||||||
|
|
||||||
prop_object_release(idxfiles);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
repo_find_files_in_packages(struct xbps_handle *xhp,
|
|
||||||
int npatterns,
|
|
||||||
char **patterns)
|
|
||||||
{
|
|
||||||
struct ffdata ffd;
|
|
||||||
|
|
||||||
ffd.npatterns = npatterns;
|
|
||||||
ffd.patterns = patterns;
|
|
||||||
|
|
||||||
return xbps_rpool_foreach(xhp, find_files_in_package, &ffd);
|
|
||||||
}
|
|
@ -1,359 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
repo_index_files_clean(struct xbps_handle *xhp, const char *repodir)
|
|
||||||
{
|
|
||||||
prop_object_t obj;
|
|
||||||
prop_array_t idx, idxfiles, obsoletes;
|
|
||||||
char *plist, *plistf, *pkgver, *str;
|
|
||||||
const char *p, *arch, *ipkgver, *iarch;
|
|
||||||
size_t x, i;
|
|
||||||
int rv = 0;
|
|
||||||
bool flush = false;
|
|
||||||
|
|
||||||
plist = plistf = pkgver = str = NULL;
|
|
||||||
idx = idxfiles = obsoletes = NULL;
|
|
||||||
|
|
||||||
/* Internalize index-files.plist if found */
|
|
||||||
if ((plistf = xbps_pkg_index_files_plist(xhp, repodir)) == NULL)
|
|
||||||
return EINVAL;
|
|
||||||
if ((idxfiles = prop_array_internalize_from_zfile(plistf)) == NULL) {
|
|
||||||
free(plistf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* Internalize index.plist */
|
|
||||||
if ((plist = xbps_pkg_index_plist(xhp, repodir)) == NULL) {
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if ((idx = prop_array_internalize_from_zfile(plist)) == NULL) {
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
printf("Cleaning `%s' index-files, please wait...\n", repodir);
|
|
||||||
/*
|
|
||||||
* Iterate over index-files array to find obsolete entries.
|
|
||||||
*/
|
|
||||||
obsoletes = prop_array_create();
|
|
||||||
assert(obsoletes);
|
|
||||||
|
|
||||||
for (x = 0; x < prop_array_count(idxfiles); x++) {
|
|
||||||
obj = prop_array_get(idxfiles, x);
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &ipkgver);
|
|
||||||
prop_dictionary_get_cstring_nocopy(obj, "architecture", &iarch);
|
|
||||||
if (xbps_find_pkg_in_array_by_pkgver(xhp, idx, ipkgver, iarch)) {
|
|
||||||
/* pkg found, do nothing */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((str = xbps_xasprintf("%s,%s", ipkgver, iarch)) == NULL) {
|
|
||||||
rv = ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (!prop_array_add_cstring(obsoletes, str)) {
|
|
||||||
free(str);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
free(str);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Iterate over the obsoletes and array and remove entries
|
|
||||||
* from index-files array.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < prop_array_count(obsoletes); i++) {
|
|
||||||
prop_array_get_cstring_nocopy(obsoletes, i, &p);
|
|
||||||
pkgver = strdup(p);
|
|
||||||
for (x = 0; x < strlen(p); x++) {
|
|
||||||
if ((pkgver[x] = p[x]) == ',') {
|
|
||||||
pkgver[x] = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
arch = strchr(p, ',') + 1;
|
|
||||||
if (!xbps_remove_pkg_from_array_by_pkgver(
|
|
||||||
xhp, idxfiles, pkgver, arch)) {
|
|
||||||
free(pkgver);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
printf("index-files: removed obsolete entry `%s' "
|
|
||||||
"(%s)\n", pkgver, arch);
|
|
||||||
free(pkgver);
|
|
||||||
flush = true;
|
|
||||||
}
|
|
||||||
/* Externalize index-files array to plist when necessary */
|
|
||||||
if (flush && !prop_array_externalize_to_zfile(idxfiles, plistf))
|
|
||||||
rv = errno;
|
|
||||||
|
|
||||||
printf("index-files: %u packages registered.\n",
|
|
||||||
prop_array_count(idxfiles));
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (obsoletes)
|
|
||||||
prop_object_release(obsoletes);
|
|
||||||
if (idx)
|
|
||||||
prop_object_release(idx);
|
|
||||||
if (idxfiles)
|
|
||||||
prop_object_release(idxfiles);
|
|
||||||
if (plist)
|
|
||||||
free(plist);
|
|
||||||
if (plistf)
|
|
||||||
free(plistf);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
repo_index_files_add(struct xbps_handle *xhp, int argc, char **argv)
|
|
||||||
{
|
|
||||||
prop_array_t idxfiles = NULL;
|
|
||||||
prop_object_t obj, fileobj;
|
|
||||||
prop_dictionary_t pkgprops, pkg_filesd, pkgd;
|
|
||||||
prop_array_t files, pkg_cffiles, pkg_files, pkg_links;
|
|
||||||
const char *binpkg, *pkgver, *arch;
|
|
||||||
char *plist, *repodir, *p;
|
|
||||||
size_t x;
|
|
||||||
int i, rv = 0;
|
|
||||||
bool found, flush;
|
|
||||||
|
|
||||||
found = flush = false;
|
|
||||||
plist = repodir = p = NULL;
|
|
||||||
obj = fileobj = NULL;
|
|
||||||
pkgprops = pkg_filesd = pkgd = NULL;
|
|
||||||
files = NULL;
|
|
||||||
|
|
||||||
if ((p = strdup(argv[1])) == NULL) {
|
|
||||||
rv = ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
repodir = dirname(p);
|
|
||||||
if ((plist = xbps_pkg_index_files_plist(xhp, repodir)) == NULL) {
|
|
||||||
rv = ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Internalize index-files.plist if found and process argv.
|
|
||||||
*/
|
|
||||||
if ((idxfiles = prop_array_internalize_from_zfile(plist)) == NULL) {
|
|
||||||
if (errno == ENOENT) {
|
|
||||||
idxfiles = prop_array_create();
|
|
||||||
assert(idxfiles);
|
|
||||||
} else {
|
|
||||||
rv = errno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
found = false;
|
|
||||||
pkgprops = xbps_dictionary_metadata_plist_by_url(argv[i],
|
|
||||||
"./props.plist");
|
|
||||||
if (pkgprops == NULL) {
|
|
||||||
fprintf(stderr, "index-files: cannot internalize "
|
|
||||||
"%s props.plist: %s\n", argv[i], strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgprops,
|
|
||||||
"filename", &binpkg);
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgprops,
|
|
||||||
"pkgver", &pkgver);
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgprops,
|
|
||||||
"architecture", &arch);
|
|
||||||
|
|
||||||
if (xbps_find_pkg_in_array_by_pkgver(xhp, idxfiles,
|
|
||||||
pkgver, arch)) {
|
|
||||||
fprintf(stderr, "index-files: skipping `%s' (%s), "
|
|
||||||
"already registered.\n", pkgver, arch);
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
pkgprops = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* internalize files.plist from binary package archive */
|
|
||||||
pkg_filesd = xbps_dictionary_metadata_plist_by_url(argv[i],
|
|
||||||
"./files.plist");
|
|
||||||
if (pkg_filesd == NULL) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find out if binary pkg stored in index contain any file */
|
|
||||||
pkg_cffiles = prop_dictionary_get(pkg_filesd, "conf_files");
|
|
||||||
if (pkg_cffiles != NULL && prop_array_count(pkg_cffiles))
|
|
||||||
found = true;
|
|
||||||
else
|
|
||||||
pkg_cffiles = NULL;
|
|
||||||
|
|
||||||
pkg_files = prop_dictionary_get(pkg_filesd, "files");
|
|
||||||
if (pkg_files != NULL && prop_array_count(pkg_files))
|
|
||||||
found = true;
|
|
||||||
else
|
|
||||||
pkg_files = NULL;
|
|
||||||
|
|
||||||
pkg_links = prop_dictionary_get(pkg_filesd, "links");
|
|
||||||
if (pkg_links != NULL && prop_array_count(pkg_links))
|
|
||||||
found = true;
|
|
||||||
else
|
|
||||||
pkg_links = NULL;
|
|
||||||
|
|
||||||
/* If pkg does not contain any file, ignore it */
|
|
||||||
if (!found) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* create pkg dictionary */
|
|
||||||
if ((pkgd = prop_dictionary_create()) == NULL) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* add pkgver and architecture objects into pkg dictionary */
|
|
||||||
if (!prop_dictionary_set_cstring(pkgd, "architecture", arch)) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (!prop_dictionary_set_cstring(pkgd, "pkgver", pkgver)) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* add files array obj into pkg dictionary */
|
|
||||||
if ((files = prop_array_create()) == NULL) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (!prop_dictionary_set(pkgd, "files", files)) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
prop_object_release(files);
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* add conf_files in pkgd */
|
|
||||||
if (pkg_cffiles != NULL) {
|
|
||||||
for (x = 0; x < prop_array_count(pkg_cffiles); x++) {
|
|
||||||
obj = prop_array_get(pkg_cffiles, x);
|
|
||||||
fileobj = prop_dictionary_get(obj, "file");
|
|
||||||
if (!prop_array_add(files, fileobj)) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
prop_object_release(files);
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* add files array in pkgd */
|
|
||||||
if (pkg_files != NULL) {
|
|
||||||
for (x = 0; x < prop_array_count(pkg_files); x++) {
|
|
||||||
obj = prop_array_get(pkg_files, x);
|
|
||||||
fileobj = prop_dictionary_get(obj, "file");
|
|
||||||
if (!prop_array_add(files, fileobj)) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
prop_object_release(files);
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* add links array in pkgd */
|
|
||||||
if (pkg_links != NULL) {
|
|
||||||
for (x = 0; x < prop_array_count(pkg_links); x++) {
|
|
||||||
obj = prop_array_get(pkg_links, x);
|
|
||||||
fileobj = prop_dictionary_get(obj, "file");
|
|
||||||
if (!prop_array_add(files, fileobj)) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
prop_object_release(files);
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* add pkgd into the index-files array */
|
|
||||||
if (!prop_array_add(idxfiles, pkgd)) {
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
prop_object_release(files);
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
flush = true;
|
|
||||||
printf("index-files: added `%s' (%s)\n", pkgver, arch);
|
|
||||||
prop_object_release(pkgprops);
|
|
||||||
prop_object_release(pkg_filesd);
|
|
||||||
prop_object_release(files);
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
pkgprops = pkg_filesd = pkgd = NULL;
|
|
||||||
files = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flush && !prop_array_externalize_to_zfile(idxfiles, plist)) {
|
|
||||||
fprintf(stderr, "failed to externalize %s: %s\n",
|
|
||||||
plist, strerror(errno));
|
|
||||||
rv = errno;
|
|
||||||
}
|
|
||||||
printf("index-files: %u packages registered.\n",
|
|
||||||
prop_array_count(idxfiles));
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (p)
|
|
||||||
free(p);
|
|
||||||
if (plist)
|
|
||||||
free(plist);
|
|
||||||
if (idxfiles)
|
|
||||||
prop_object_release(idxfiles);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
@ -1,325 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Removes stalled pkg entries in repository's index.plist file, if any
|
|
||||||
* binary package cannot be read (unavailable, not enough perms, etc).
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
repo_index_clean(struct xbps_handle *xhp, const char *repodir)
|
|
||||||
{
|
|
||||||
prop_array_t array;
|
|
||||||
prop_dictionary_t pkgd;
|
|
||||||
const char *filen, *pkgver, *arch;
|
|
||||||
char *plist;
|
|
||||||
size_t i, idx = 0;
|
|
||||||
int rv = 0;
|
|
||||||
bool flush = false;
|
|
||||||
|
|
||||||
if ((plist = xbps_pkg_index_plist(xhp, repodir)) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
array = prop_array_internalize_from_zfile(plist);
|
|
||||||
if (array == NULL) {
|
|
||||||
if (errno != ENOENT) {
|
|
||||||
xbps_error_printf("xbps-repo: cannot read `%s': %s\n",
|
|
||||||
plist, strerror(errno));
|
|
||||||
free(plist);
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
free(plist);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (chdir(repodir) == -1) {
|
|
||||||
fprintf(stderr, "cannot chdir to %s: %s\n",
|
|
||||||
repodir, strerror(errno));
|
|
||||||
rv = errno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
printf("Cleaning `%s' index, please wait...\n", repodir);
|
|
||||||
|
|
||||||
again:
|
|
||||||
for (i = idx; i < prop_array_count(array); i++) {
|
|
||||||
pkgd = prop_array_get(array, i);
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgd, "filename", &filen);
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgd, "architecture", &arch);
|
|
||||||
if (access(filen, R_OK) == -1) {
|
|
||||||
printf("index: removed obsolete entry `%s' (%s)\n",
|
|
||||||
pkgver, arch);
|
|
||||||
prop_array_remove(array, i);
|
|
||||||
flush = true;
|
|
||||||
idx = i;
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (flush && !prop_array_externalize_to_zfile(array, plist)) {
|
|
||||||
rv = errno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
printf("index: %u packages registered.\n", prop_array_count(array));
|
|
||||||
out:
|
|
||||||
free(plist);
|
|
||||||
prop_object_release(array);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Adds a binary package into the index and removes old binary package
|
|
||||||
* and entry when it's necessary.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
repo_index_add(struct xbps_handle *xhp, int argc, char **argv)
|
|
||||||
{
|
|
||||||
prop_array_t idx = NULL;
|
|
||||||
prop_dictionary_t newpkgd = NULL, curpkgd;
|
|
||||||
struct stat st;
|
|
||||||
const char *pkgname, *version, *regver, *oldfilen, *oldpkgver;
|
|
||||||
const char *arch, *oldarch;
|
|
||||||
char *sha256, *filen, *repodir, *buf, *buf2;
|
|
||||||
char *tmpfilen = NULL, *tmprepodir = NULL, *plist = NULL;
|
|
||||||
int i, ret = 0, rv = 0;
|
|
||||||
bool flush = false;
|
|
||||||
|
|
||||||
if ((tmprepodir = strdup(argv[1])) == NULL) {
|
|
||||||
rv = ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
repodir = dirname(tmprepodir);
|
|
||||||
|
|
||||||
/* Internalize plist file or create it if doesn't exist */
|
|
||||||
if ((plist = xbps_pkg_index_plist(xhp, repodir)) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((idx = prop_array_internalize_from_zfile(plist)) == NULL) {
|
|
||||||
if (errno != ENOENT) {
|
|
||||||
xbps_error_printf("xbps-repo: cannot read `%s': %s\n",
|
|
||||||
plist, strerror(errno));
|
|
||||||
rv = -1;
|
|
||||||
goto out;
|
|
||||||
} else {
|
|
||||||
idx = prop_array_create();
|
|
||||||
assert(idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Process all packages specified in argv.
|
|
||||||
*/
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
if ((tmpfilen = strdup(argv[i])) == NULL) {
|
|
||||||
rv = ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
filen = basename(tmpfilen);
|
|
||||||
/*
|
|
||||||
* Read metadata props plist dictionary from binary package.
|
|
||||||
*/
|
|
||||||
newpkgd = xbps_dictionary_metadata_plist_by_url(argv[i],
|
|
||||||
"./props.plist");
|
|
||||||
if (newpkgd == NULL) {
|
|
||||||
xbps_error_printf("failed to read %s metadata for `%s',"
|
|
||||||
" skipping!\n", XBPS_PKGPROPS, argv[i]);
|
|
||||||
free(tmpfilen);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
prop_dictionary_get_cstring_nocopy(newpkgd, "pkgname",
|
|
||||||
&pkgname);
|
|
||||||
prop_dictionary_get_cstring_nocopy(newpkgd, "version",
|
|
||||||
&version);
|
|
||||||
prop_dictionary_get_cstring_nocopy(newpkgd, "architecture",
|
|
||||||
&arch);
|
|
||||||
/*
|
|
||||||
* Check if this package exists already in the index, but first
|
|
||||||
* checking the version. If current package version is greater
|
|
||||||
* than current registered package, update the index; otherwise
|
|
||||||
* pass to the next one.
|
|
||||||
*/
|
|
||||||
curpkgd =
|
|
||||||
xbps_find_pkg_in_array_by_name(xhp, idx, pkgname, arch);
|
|
||||||
if (curpkgd == NULL) {
|
|
||||||
if (errno && errno != ENOENT) {
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
rv = errno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
prop_dictionary_get_cstring_nocopy(curpkgd,
|
|
||||||
"filename", &oldfilen);
|
|
||||||
prop_dictionary_get_cstring_nocopy(curpkgd,
|
|
||||||
"pkgver", &oldpkgver);
|
|
||||||
prop_dictionary_get_cstring_nocopy(curpkgd,
|
|
||||||
"architecture", &oldarch);
|
|
||||||
prop_dictionary_get_cstring_nocopy(curpkgd,
|
|
||||||
"version", ®ver);
|
|
||||||
ret = xbps_cmpver(version, regver);
|
|
||||||
if (ret == 0) {
|
|
||||||
/* Same version */
|
|
||||||
fprintf(stderr, "index: skipping `%s-%s' "
|
|
||||||
"(%s), already registered.\n",
|
|
||||||
pkgname, version, arch);
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
continue;
|
|
||||||
} else if (ret == -1) {
|
|
||||||
/*
|
|
||||||
* Index version is greater, remove current
|
|
||||||
* package.
|
|
||||||
*/
|
|
||||||
buf = xbps_xasprintf("`%s' (%s)",
|
|
||||||
oldpkgver, oldarch);
|
|
||||||
assert(buf);
|
|
||||||
rv = repo_remove_pkg(repodir,
|
|
||||||
oldarch, oldfilen);
|
|
||||||
if (rv != 0) {
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
free(buf);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
printf("index: removed obsolete binpkg %s.\n", buf);
|
|
||||||
free(buf);
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Current package version is greater than
|
|
||||||
* index version.
|
|
||||||
*/
|
|
||||||
buf = xbps_xasprintf("`%s' (%s)", oldpkgver, oldarch);
|
|
||||||
assert(buf);
|
|
||||||
buf2 = strdup(oldpkgver);
|
|
||||||
assert(buf2);
|
|
||||||
rv = repo_remove_pkg(repodir, oldarch, oldfilen);
|
|
||||||
if (rv != 0) {
|
|
||||||
free(buf);
|
|
||||||
free(buf2);
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (!xbps_remove_pkg_from_array_by_pkgver(xhp, idx,
|
|
||||||
buf2, oldarch)) {
|
|
||||||
xbps_error_printf("failed to remove %s "
|
|
||||||
"from plist index: %s\n", buf,
|
|
||||||
strerror(errno));
|
|
||||||
rv = errno;
|
|
||||||
free(buf);
|
|
||||||
free(buf2);
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
free(buf2);
|
|
||||||
printf("index: removed obsolete entry/binpkg %s.\n", buf);
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* We have the dictionary now, add the required
|
|
||||||
* objects for the index.
|
|
||||||
*/
|
|
||||||
if (!prop_dictionary_set_cstring(newpkgd, "filename", filen)) {
|
|
||||||
rv = errno;
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if ((sha256 = xbps_file_hash(argv[i])) == NULL) {
|
|
||||||
rv = errno;
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (!prop_dictionary_set_cstring(newpkgd, "filename-sha256",
|
|
||||||
sha256)) {
|
|
||||||
free(sha256);
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
rv = errno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
free(sha256);
|
|
||||||
if (stat(argv[i], &st) == -1) {
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
rv = errno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (!prop_dictionary_set_uint64(newpkgd, "filename-size",
|
|
||||||
(uint64_t)st.st_size)) {
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
rv = errno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Add new pkg dictionary into the index.
|
|
||||||
*/
|
|
||||||
if (!prop_array_add(idx, newpkgd)) {
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
free(tmpfilen);
|
|
||||||
rv = EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
flush = true;
|
|
||||||
printf("index: added `%s-%s' (%s).\n", pkgname, version, arch);
|
|
||||||
free(tmpfilen);
|
|
||||||
prop_object_release(newpkgd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flush && !prop_array_externalize_to_zfile(idx, plist)) {
|
|
||||||
xbps_error_printf("failed to externalize plist: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
rv = errno;
|
|
||||||
}
|
|
||||||
printf("index: %u packages registered.\n", prop_array_count(idx));
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (tmprepodir)
|
|
||||||
free(tmprepodir);
|
|
||||||
if (plist)
|
|
||||||
free(plist);
|
|
||||||
if (idx)
|
|
||||||
prop_object_release(idx);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
/*-
|
|
||||||
* Copyright (c) 2011-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 <strings.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
#include "../xbps-bin/defs.h"
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
repo_find_longest_pkgver(struct xbps_handle *xhp)
|
|
||||||
{
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
xbps_rpool_foreach(xhp, repo_longest_pkgver, &len);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
repo_pkg_list_cb(struct xbps_handle *xhp,
|
|
||||||
struct xbps_rpool_index *rpi,
|
|
||||||
void *arg,
|
|
||||||
bool *done)
|
|
||||||
{
|
|
||||||
struct list_pkgver_cb lpc;
|
|
||||||
struct repo_search_data *rsd = arg;
|
|
||||||
|
|
||||||
(void)done;
|
|
||||||
if (rsd->arg && strcmp(rpi->uri, rsd->arg))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
lpc.check_state = false;
|
|
||||||
lpc.state = 0;
|
|
||||||
lpc.pkgver_len = rsd->pkgver_len;
|
|
||||||
lpc.maxcols = rsd->maxcols;
|
|
||||||
|
|
||||||
(void)xbps_callback_array_iter(xhp, rpi->repo, list_pkgs_in_dict, &lpc);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_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;
|
|
||||||
}
|
|
@ -1,340 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <strings.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
#include "../xbps-bin/defs.h"
|
|
||||||
|
|
||||||
static void __attribute__((noreturn))
|
|
||||||
usage(bool fail)
|
|
||||||
{
|
|
||||||
fprintf(stdout,
|
|
||||||
"Usage: xbps-repo [options] target [arguments]\n\n"
|
|
||||||
"[options]\n"
|
|
||||||
" -B repo Set <repo> as default repository if xbps.conf not found.\n"
|
|
||||||
" -C file Full path to configuration file\n"
|
|
||||||
" -c cachedir Full path to cachedir to store downloaded binpkgs\n"
|
|
||||||
" -d Debug mode shown to stderr\n"
|
|
||||||
" -h Print usage help\n"
|
|
||||||
" -o key[,key] Print package metadata keys in show target\n"
|
|
||||||
" -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 <pattern> [patterns]\n"
|
|
||||||
" Print package name/version for any pattern matched.\n"
|
|
||||||
" index-add <repository>/foo-1.0.xbps ...\n"
|
|
||||||
" Registers specified package(s) to the local repository's index.\n"
|
|
||||||
" Multiple packages can be specified. An absolute path is expected.\n"
|
|
||||||
" index-clean <repository>\n"
|
|
||||||
" Removes obsolete entries from repository's index files.\n"
|
|
||||||
" list\n"
|
|
||||||
" List registered repositories.\n"
|
|
||||||
" pkg-list [repo]\n"
|
|
||||||
" Print packages in repository matching `repo' URI.\n"
|
|
||||||
" If `repo' not specified, all registered repositories will be used.\n"
|
|
||||||
" remove-obsoletes <repository>\n"
|
|
||||||
" Removes obsolete packages (not registered in index any longer) from\n"
|
|
||||||
" local repository \"<repository>\".\n"
|
|
||||||
" search <pattern> [patterns]\n"
|
|
||||||
" Search for packages in repositories matching the patterns.\n"
|
|
||||||
" show <pkgname|pkgpattern>\n"
|
|
||||||
" Print package information for `pkgname' or `pkgpattern'.\n"
|
|
||||||
" show-deps <pkgname|pkgpattern>\n"
|
|
||||||
" Print package's required dependencies for `pkgname' or `pkgpattern'.\n"
|
|
||||||
" show-files <pkgname|pkgpattern>\n"
|
|
||||||
" Print package's files list for `pkgname' or `pkgpattern'.\n"
|
|
||||||
" sync [repo]\n"
|
|
||||||
" Synchronize package index file for `repo'.\n"
|
|
||||||
" If `repo' not specified, all remote repositories will be used. \n\n"
|
|
||||||
"Refer to xbps-repo(8) for a more detailed description.\n");
|
|
||||||
|
|
||||||
exit(fail ? EXIT_FAILURE : EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
struct xbps_handle xh;
|
|
||||||
struct xferstat xfer;
|
|
||||||
struct repo_search_data rsd;
|
|
||||||
prop_dictionary_t pkgd;
|
|
||||||
const char *rootdir, *cachedir, *conffile, *option, *defrepo;
|
|
||||||
int flags = 0, c, rv = 0;
|
|
||||||
|
|
||||||
rootdir = cachedir = conffile = option = defrepo = NULL;
|
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "B:C:c:dho:r:V")) != -1) {
|
|
||||||
switch (c) {
|
|
||||||
case 'B':
|
|
||||||
defrepo = optarg;
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
conffile = optarg;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
cachedir = optarg;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
flags |= XBPS_FLAG_DEBUG;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
usage(false);
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
option = optarg;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
/* To specify the root directory */
|
|
||||||
rootdir = optarg;
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
printf("%s\n", XBPS_RELVER);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
case '?':
|
|
||||||
default:
|
|
||||||
usage(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (argc < 1)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize XBPS subsystems.
|
|
||||||
*/
|
|
||||||
memset(&xh, 0, sizeof(xh));
|
|
||||||
xh.flags = flags;
|
|
||||||
xh.state_cb = state_cb;
|
|
||||||
xh.fetch_cb = fetch_file_progress_cb;
|
|
||||||
xh.fetch_cb_data = &xfer;
|
|
||||||
xh.rootdir = rootdir;
|
|
||||||
xh.cachedir = cachedir;
|
|
||||||
xh.conffile = conffile;
|
|
||||||
xh.repository = defrepo;
|
|
||||||
|
|
||||||
if ((rv = xbps_init(&xh)) != 0) {
|
|
||||||
xbps_error_printf("xbps-repo: couldn't initialize library: %s\n",
|
|
||||||
strerror(rv));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check that we have write permission on cachedir/metadir.
|
|
||||||
*/
|
|
||||||
if ((strcasecmp(argv[0], "sync") == 0) ||
|
|
||||||
(strcasecmp(argv[0], "clean") == 0)) {
|
|
||||||
if ((access(xh.metadir, W_OK) == -1) ||
|
|
||||||
(access(xh.cachedir, W_OK) == -1)) {
|
|
||||||
if (errno != ENOENT) {
|
|
||||||
xbps_error_printf("xbps-repo: cannot write to "
|
|
||||||
"cachedir/metadir: %s\n", strerror(errno));
|
|
||||||
xbps_end(&xh);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcasecmp(argv[0], "list") == 0) {
|
|
||||||
/* Lists all repositories registered in pool. */
|
|
||||||
if (argc != 1)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = xbps_rpool_foreach(&xh, repo_list_uri_cb, NULL);
|
|
||||||
if (rv == ENOTSUP)
|
|
||||||
xbps_error_printf("xbps-repo: no repositories "
|
|
||||||
"currently registered!\n");
|
|
||||||
else if (rv != 0 && rv != ENOTSUP)
|
|
||||||
xbps_error_printf("xbps-repo: failed to initialize "
|
|
||||||
"rpool: %s\n", strerror(rv));
|
|
||||||
} else if (strcasecmp(argv[0], "pkg-list") == 0) {
|
|
||||||
/*
|
|
||||||
* Only list packages for the target repository.
|
|
||||||
*/
|
|
||||||
if (argc < 1 || argc > 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rsd.arg = argv[1];
|
|
||||||
rsd.pkgver_len = repo_find_longest_pkgver(&xh);
|
|
||||||
rsd.maxcols = get_maxcols();
|
|
||||||
|
|
||||||
rv = xbps_rpool_foreach(&xh, repo_pkg_list_cb, &rsd);
|
|
||||||
if (rv == ENOTSUP)
|
|
||||||
xbps_error_printf("xbps-repo: no repositories "
|
|
||||||
"currently registered!\n");
|
|
||||||
else if (rv != 0)
|
|
||||||
xbps_error_printf("xbps-repo: failed to initialize "
|
|
||||||
"rpool: %s\n", strerror(rv));
|
|
||||||
} else if (strcasecmp(argv[0], "search") == 0) {
|
|
||||||
/*
|
|
||||||
* Search for a package by looking at pkgname/short_desc
|
|
||||||
* by using shell style match patterns (fnmatch(3)).
|
|
||||||
*/
|
|
||||||
if (argc < 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rsd.npatterns = argc;
|
|
||||||
rsd.patterns = argv;
|
|
||||||
rsd.pkgver_len = repo_find_longest_pkgver(&xh);
|
|
||||||
rsd.maxcols = get_maxcols();
|
|
||||||
|
|
||||||
rv = xbps_rpool_foreach(&xh, repo_search_pkgs_cb, &rsd);
|
|
||||||
if (rv == ENOTSUP)
|
|
||||||
xbps_error_printf("xbps-repo: no repositories "
|
|
||||||
"currently registered!\n");
|
|
||||||
else if (rv != 0 && rv != ENOTSUP)
|
|
||||||
xbps_error_printf("xbps-repo: failed to initialize "
|
|
||||||
"rpool: %s\n", strerror(rv));
|
|
||||||
} else if (strcasecmp(argv[0], "show") == 0) {
|
|
||||||
/* Shows info about a binary package. */
|
|
||||||
if (argc != 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = show_pkg_info_from_repolist(&xh, argv[1], option);
|
|
||||||
if (rv == ENOENT) {
|
|
||||||
xbps_error_printf("Unable to locate package "
|
|
||||||
"`%s' in repository pool.\n", argv[1]);
|
|
||||||
} else if (rv == ENOTSUP) {
|
|
||||||
xbps_error_printf("xbps-repo: no repositories "
|
|
||||||
"currently registered!\n");
|
|
||||||
} else if (rv != 0 && rv != ENOENT) {
|
|
||||||
xbps_error_printf("xbps-repo: unexpected error '%s' ",
|
|
||||||
"searching for '%s'\n", strerror(rv), argv[1]);
|
|
||||||
}
|
|
||||||
} else if (strcasecmp(argv[0], "show-deps") == 0) {
|
|
||||||
/* Shows the required run dependencies for a package. */
|
|
||||||
if (argc != 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = show_pkg_deps_from_repolist(&xh, argv[1]);
|
|
||||||
if (rv == ENOENT) {
|
|
||||||
xbps_error_printf("Unable to locate package "
|
|
||||||
"`%s' in repository pool.\n", argv[1]);
|
|
||||||
} else if (rv == ENOTSUP) {
|
|
||||||
xbps_error_printf("xbps-repo: no repositories "
|
|
||||||
"currently registered!\n");
|
|
||||||
} else if (rv != 0 && rv != ENOENT) {
|
|
||||||
xbps_error_printf("xbps-repo: unexpected error '%s' "
|
|
||||||
"searching for '%s'\n", strerror(errno), argv[1]);
|
|
||||||
}
|
|
||||||
} else if (strcasecmp(argv[0], "show-files") == 0) {
|
|
||||||
/* Shows the package files in a binary package */
|
|
||||||
if (argc != 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
pkgd = xbps_rpool_dictionary_metadata_plist(&xh, argv[1],
|
|
||||||
"./files.plist");
|
|
||||||
if (pkgd == NULL) {
|
|
||||||
if (errno == ENOTSUP) {
|
|
||||||
xbps_error_printf("xbps-repo: no repositories "
|
|
||||||
"currently registered!\n");
|
|
||||||
} else if (errno == ENOENT) {
|
|
||||||
xbps_error_printf("Unable to locate package `%s' "
|
|
||||||
"in repository pool.\n", argv[1]);
|
|
||||||
} else {
|
|
||||||
xbps_error_printf("xbps-repo: unexpected "
|
|
||||||
"error '%s' searching for '%s'\n",
|
|
||||||
strerror(errno), argv[1]);
|
|
||||||
}
|
|
||||||
rv = errno;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
rv = show_pkg_files(pkgd);
|
|
||||||
} else if (strcasecmp(argv[0], "find-files") == 0) {
|
|
||||||
/* Finds files by patterns, exact matches and components. */
|
|
||||||
if (argc < 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = repo_find_files_in_packages(&xh, argc, argv);
|
|
||||||
if (rv == ENOTSUP) {
|
|
||||||
xbps_error_printf("xbps-repo: no repositories "
|
|
||||||
"currently registered!\n");
|
|
||||||
}
|
|
||||||
} else if (strcasecmp(argv[0], "remove-obsoletes") == 0) {
|
|
||||||
if (argc < 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
if ((rv = repo_remove_obsoletes(&xh, argv[1])) != 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "index-add") == 0) {
|
|
||||||
/* Registers a binary package into the repository's index. */
|
|
||||||
if (argc < 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
if ((rv = repo_index_add(&xh, argc, argv)) != 0)
|
|
||||||
goto out;
|
|
||||||
if ((rv = repo_index_files_add(&xh, argc, argv)) != 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "index-clean") == 0) {
|
|
||||||
/* Removes obsolete pkg entries from index in a repository */
|
|
||||||
if (argc != 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
if ((rv = repo_index_clean(&xh, argv[1])) != 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rv = repo_index_files_clean(&xh, argv[1]);
|
|
||||||
|
|
||||||
} else if (strcasecmp(argv[0], "sync") == 0) {
|
|
||||||
/* Syncs the pkg index for all registered remote repos */
|
|
||||||
if (argc < 1 || argc > 2)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
rv = xbps_rpool_sync(&xh, argv[1]);
|
|
||||||
if (rv == ENOTSUP) {
|
|
||||||
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(&xh);
|
|
||||||
} else {
|
|
||||||
usage(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
xbps_end(&xh);
|
|
||||||
exit(rv ? EXIT_FAILURE : EXIT_SUCCESS);
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <xbps_api.h>
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
repo_remove_obsoletes(struct xbps_handle *xhp, const char *repodir)
|
|
||||||
{
|
|
||||||
prop_dictionary_t pkgd;
|
|
||||||
prop_array_t idx;
|
|
||||||
DIR *dirp;
|
|
||||||
struct dirent *dp;
|
|
||||||
const char *pkgver, *arch;
|
|
||||||
char *plist, *ext;
|
|
||||||
int rv = 0;
|
|
||||||
|
|
||||||
if ((plist = xbps_pkg_index_plist(xhp, repodir)) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
idx = prop_array_internalize_from_zfile(plist);
|
|
||||||
if (idx == NULL) {
|
|
||||||
if (errno != ENOENT) {
|
|
||||||
xbps_error_printf("xbps-repo: cannot read `%s': %s\n",
|
|
||||||
plist, strerror(errno));
|
|
||||||
free(plist);
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
free(plist);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (chdir(repodir) == -1) {
|
|
||||||
fprintf(stderr, "cannot chdir to %s: %s\n",
|
|
||||||
repodir, strerror(errno));
|
|
||||||
prop_object_release(idx);
|
|
||||||
return errno;
|
|
||||||
}
|
|
||||||
if ((dirp = opendir(repodir)) == NULL) {
|
|
||||||
fprintf(stderr, "failed to open %s: %s\n",
|
|
||||||
repodir, strerror(errno));
|
|
||||||
prop_object_release(idx);
|
|
||||||
return errno;
|
|
||||||
}
|
|
||||||
while ((dp = readdir(dirp))) {
|
|
||||||
if (strcmp(dp->d_name, "..") == 0)
|
|
||||||
continue;
|
|
||||||
if ((ext = strrchr(dp->d_name, '.')) == NULL)
|
|
||||||
continue;
|
|
||||||
if (strcmp(ext, ".xbps"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pkgd = xbps_dictionary_metadata_plist_by_url(dp->d_name,
|
|
||||||
"./props.plist");
|
|
||||||
if (pkgd == NULL) {
|
|
||||||
rv = repo_remove_pkg(repodir, arch, dp->d_name);
|
|
||||||
if (rv != 0) {
|
|
||||||
fprintf(stderr, "index: failed to remove "
|
|
||||||
"package `%s': %s\n", dp->d_name,
|
|
||||||
strerror(rv));
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("Removed broken package `%s'.\n", dp->d_name);
|
|
||||||
}
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
|
|
||||||
prop_dictionary_get_cstring_nocopy(pkgd, "architecture", &arch);
|
|
||||||
/*
|
|
||||||
* If binpkg is not registered in index, remove binpkg.
|
|
||||||
*/
|
|
||||||
if (!xbps_find_pkg_in_array_by_pkgver(xhp, idx, pkgver, arch)) {
|
|
||||||
rv = repo_remove_pkg(repodir, arch, dp->d_name);
|
|
||||||
if (rv != 0) {
|
|
||||||
fprintf(stderr, "index: failed to remove "
|
|
||||||
"package `%s': %s\n", dp->d_name,
|
|
||||||
strerror(rv));
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("Removed obsolete package `%s'.\n", dp->d_name);
|
|
||||||
}
|
|
||||||
prop_object_release(pkgd);
|
|
||||||
}
|
|
||||||
(void)closedir(dirp);
|
|
||||||
prop_object_release(idx);
|
|
||||||
return rv;
|
|
||||||
}
|
|
@ -1,145 +0,0 @@
|
|||||||
/*-
|
|
||||||
* 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 <xbps_api.h>
|
|
||||||
#include "../xbps-bin/defs.h"
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
show_pkg_info_from_repolist(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
|
|
||||||
show_pkg_deps_from_repolist(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 i, x, len;
|
|
||||||
|
|
||||||
(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 = 1; i < (size_t)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;
|
|
||||||
}
|
|
@ -1,159 +0,0 @@
|
|||||||
.Dd September 24, 2012
|
|
||||||
.Os Void GNU/Linux
|
|
||||||
.Dt xbps-repo 8
|
|
||||||
.Sh NAME
|
|
||||||
.Nm xbps-repo
|
|
||||||
.Nd XBPS command for binary package repositories
|
|
||||||
.Sh SYNOPSYS
|
|
||||||
.Nm xbps-repo
|
|
||||||
.Op options
|
|
||||||
.Ar target
|
|
||||||
.Op arguments
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
command is able to interact with binary packages stored in local or
|
|
||||||
remote repositories. It is able to create a package index for local
|
|
||||||
repositories, list repositories, search for packages and show information
|
|
||||||
of a binary package in repository pool, among other things.
|
|
||||||
.Sh OPTIONS
|
|
||||||
.Bl -tag -width Fl
|
|
||||||
.It Fl B Ar repository
|
|
||||||
If a configuration file cannot be found, this repository will be used as
|
|
||||||
as the primary source to install packages.
|
|
||||||
.It Fl C Ar conffile
|
|
||||||
Full path to the XBPS configuration file. By default set to
|
|
||||||
.Pa /etc/xbps/xbps.conf .
|
|
||||||
.It Fl c Ar cachedir
|
|
||||||
Sets the
|
|
||||||
.Em cache
|
|
||||||
directory to store downloaded binary packages from remote
|
|
||||||
repositories. By default set to
|
|
||||||
.Pa /var/cache/xbps .
|
|
||||||
.It Fl d
|
|
||||||
Enables extra debugging output to be shown to stderr.
|
|
||||||
.It Fl o Ar key Op key2,...
|
|
||||||
Used currently in the
|
|
||||||
.Em show
|
|
||||||
target. Prints the value of specified key(s) from
|
|
||||||
package's properties dictionary. Multiple keys can be specified delimited by
|
|
||||||
the comma character.
|
|
||||||
.It Fl r Ar rootdir
|
|
||||||
Sets the
|
|
||||||
.Em root
|
|
||||||
directory. By default the root directory is set to
|
|
||||||
.Em / .
|
|
||||||
Please note that the database directory is always set to
|
|
||||||
.Pa /var/db/xbps
|
|
||||||
independently of rootdir setting. So if you use a rootdir of
|
|
||||||
.Pa /blah ,
|
|
||||||
metadata stuff will go into
|
|
||||||
.Pa /blah/var/db/xbps .
|
|
||||||
.It Fl v
|
|
||||||
Shows verbose messages. Useful while installing and removing packages.
|
|
||||||
.It Fl V
|
|
||||||
Shows the current XBPS release version (version, API, index).
|
|
||||||
.Sh TARGETS
|
|
||||||
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 the 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)
|
|
||||||
matching the pattern on its file list by looking in all repositories index files.
|
|
||||||
Multiple patterns can be specified as arguments.
|
|
||||||
.It Sy index-add Ar /path/to/local/repository/foo-1.0.arch.xbps
|
|
||||||
This will register the binary package into the local repository's index files, and remove
|
|
||||||
old entry and binary package if any old version exists.
|
|
||||||
Multiple binary packages can be specified.
|
|
||||||
.It Sy index-clean Ar /path/to/local/repository
|
|
||||||
This will remove any obsolete entry found in the local repository's index files.
|
|
||||||
.It Sy list
|
|
||||||
Lists all working repositories in repository pool.
|
|
||||||
.It Sy pkg-list Op repository
|
|
||||||
Lists all currently registered packages from all repositories, or just from
|
|
||||||
.Ar repository .
|
|
||||||
If argument is not specified, any package contained in all repositories
|
|
||||||
will be shown. The argument expects the repository URI.
|
|
||||||
matching the output of the
|
|
||||||
.Ar list
|
|
||||||
target.
|
|
||||||
.It Sy search Ar pattern Ar [patterns ...]
|
|
||||||
Search for packages containing the shell
|
|
||||||
.Em pattern
|
|
||||||
(see
|
|
||||||
.Xr fnmatch 3 )
|
|
||||||
in its
|
|
||||||
.Em pkgname
|
|
||||||
or
|
|
||||||
.Em description
|
|
||||||
values in repository pool. Please note that patterns are matched in case
|
|
||||||
insensitive mode. Multiple patterns can be specified as arguments. Packages that
|
|
||||||
have the
|
|
||||||
.Sy *
|
|
||||||
character as prefix are currently installed.
|
|
||||||
.It Sy remove-obsoletes Ar /path/to/local/repository
|
|
||||||
Removes obsolete packages from
|
|
||||||
.Ar repository .
|
|
||||||
Packages that are not currently registered in repository's index will
|
|
||||||
be removed.
|
|
||||||
.It Sy show Ar pkgname | pkgpattern
|
|
||||||
Shows information for binary package
|
|
||||||
.Ar pkgname
|
|
||||||
or a package matching
|
|
||||||
.Ar pkgpattern .
|
|
||||||
This will print the size it takes in filesystem, description, maintainer,
|
|
||||||
architecture and other information. If specifying a pkgname, the newest
|
|
||||||
version available in repositories will be shown, otherwise the first
|
|
||||||
repository matching the pkgpattern will be used.
|
|
||||||
.It Sy show-deps Ar pkgname | pkgpattern
|
|
||||||
Shows run time dependencies for binary package
|
|
||||||
.Ar pkgname
|
|
||||||
or a package matching
|
|
||||||
.Ar pkgpattern .
|
|
||||||
The same rules than in the
|
|
||||||
.Em show
|
|
||||||
target also apply here.
|
|
||||||
.It Sy show-files Ar pkgname | pkgpattern
|
|
||||||
Shows the file list for the binary package
|
|
||||||
.Ar pkgname
|
|
||||||
or a package matching
|
|
||||||
.Ar pkgpattern .
|
|
||||||
The same rules than in the
|
|
||||||
.Em show
|
|
||||||
target also apply here.
|
|
||||||
.Em NOTE :
|
|
||||||
if a remote repository is the winner and binary package is not available in
|
|
||||||
.Em cachedir ,
|
|
||||||
it will fetch remotely and
|
|
||||||
.Em on the fly
|
|
||||||
the info from target repository.
|
|
||||||
.It Sy sync Op repository
|
|
||||||
Syncs the package index file for all remote repositories or just for
|
|
||||||
.Ar repository .
|
|
||||||
The index file will be fetched if local and remote size/mtime do not match.
|
|
||||||
.Sh FILES
|
|
||||||
.Bl -tag -width /var/db/xbps/<repodir>/index-files.plist -compact
|
|
||||||
.It Pa /etc/xbps/xbps.conf
|
|
||||||
Default XBPS configuration file.
|
|
||||||
.It Pa /var/db/xbps/<repodir>/index.plist
|
|
||||||
Repository package index file.
|
|
||||||
.It Pa /var/db/xbps/<repodir>/index-files.plist
|
|
||||||
Repository package files index ile.
|
|
||||||
.It Pa /var/cache/xbps
|
|
||||||
XBPS cache directory for downloaded binary packages.
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr xbps-bin 8 ,
|
|
||||||
.Xr http://code.google.com/p/xbps
|
|
||||||
.Sh AUTHORS
|
|
||||||
.An Juan Romero Pardines <xtraeme@gmail.com>
|
|
||||||
.Sh BUGS
|
|
||||||
Probably, but I try to make this not happen. Use it under your own
|
|
||||||
responsability and enjoy your life.
|
|
||||||
.Pp
|
|
||||||
Report bugs in http://code.google.com/p/xbps.
|
|
@ -2,6 +2,6 @@ TOPDIR = ../..
|
|||||||
-include $(TOPDIR)/config.mk
|
-include $(TOPDIR)/config.mk
|
||||||
|
|
||||||
BIN = xbps-uhelper
|
BIN = xbps-uhelper
|
||||||
OBJS = main.o ../xbps-bin/fetch_cb.o
|
OBJS = main.o ../xbps-install/fetch_cb.o
|
||||||
|
|
||||||
include $(TOPDIR)/mk/prog.mk
|
include $(TOPDIR)/mk/prog.mk
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <xbps_api.h>
|
#include <xbps_api.h>
|
||||||
#include "../xbps-bin/defs.h"
|
#include "../xbps-install/defs.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_plist_file(prop_dictionary_t dict, const char *file)
|
write_plist_file(prop_dictionary_t dict, const char *file)
|
||||||
|
Loading…
Reference in New Issue
Block a user