Major API/ABI cleanup bringing performance improvements and fixes.
These are the core interfaces in the new API: rpool - Interface to interact with the repository pool. rindex - Interface to interact with repository indexes. pkgdb - Interface to interact with local packages. transaction - Interface to interact with a transaction. This also brings new repository index format, making the index file per architecture and being incompatible with previous versions. The transaction frequency flush option has been removed, and due to the nature of package states it was causing more harm than good. More changes coming soon, but the API shall remain stable from now on.
This commit is contained in:
@@ -44,14 +44,14 @@ EXTOBJS += external/mkpath.o
|
||||
OBJS = package_configure.o package_config_files.o package_orphans.o
|
||||
OBJS += package_remove.o package_remove_obsoletes.o package_state.o
|
||||
OBJS += package_unpack.o package_requiredby.o package_register.o
|
||||
OBJS += package_script.o package_metadir.o
|
||||
OBJS += package_script.o
|
||||
OBJS += transaction_commit.o transaction_package_replace.o
|
||||
OBJS += transaction_dictionary.o transaction_sortdeps.o transaction_ops.o
|
||||
OBJS += download.o initend.o pkgdb.o package_conflicts.o
|
||||
OBJS += plist.o plist_archive_entry.o plist_find.o plist_match.o
|
||||
OBJS += plist_remove.o plist_fetch.o util.o util_hash.o
|
||||
OBJS += repository_finddeps.o cb_util.o
|
||||
OBJS += repository_pool.o repository_pool_find.o repository_sync_index.o
|
||||
OBJS += rindex_pkgdeps.o rindex_sync.o rindex_get.o
|
||||
OBJS += rpool.o rpool_get.o cb_util.o
|
||||
OBJS += $(EXTOBJS) $(COMPAT_SRCS)
|
||||
|
||||
.PHONY: all
|
||||
|
||||
@@ -55,6 +55,7 @@ xbps_set_cb_fetch(struct xbps_handle *xhp,
|
||||
if (xhp->fetch_cb == NULL)
|
||||
return;
|
||||
|
||||
xfcd.xhp = xhp;
|
||||
xfcd.file_size = file_size;
|
||||
xfcd.file_offset = file_offset;
|
||||
xfcd.file_dloaded = file_dloaded;
|
||||
@@ -62,7 +63,7 @@ xbps_set_cb_fetch(struct xbps_handle *xhp,
|
||||
xfcd.cb_start = cb_start;
|
||||
xfcd.cb_update = cb_update;
|
||||
xfcd.cb_end = cb_end;
|
||||
(*xhp->fetch_cb)(xhp, &xfcd, xhp->fetch_cb_data);
|
||||
(*xhp->fetch_cb)(&xfcd, xhp->fetch_cb_data);
|
||||
}
|
||||
|
||||
void HIDDEN
|
||||
@@ -82,6 +83,7 @@ xbps_set_cb_state(struct xbps_handle *xhp,
|
||||
if (xhp->state_cb == NULL)
|
||||
return;
|
||||
|
||||
xscd.xhp = xhp;
|
||||
xscd.state = state;
|
||||
xscd.err = err;
|
||||
xscd.arg0 = arg0;
|
||||
@@ -95,7 +97,7 @@ xbps_set_cb_state(struct xbps_handle *xhp,
|
||||
else
|
||||
xscd.desc = buf;
|
||||
}
|
||||
(*xhp->state_cb)(xhp, &xscd, xhp->state_cb_data);
|
||||
(*xhp->state_cb)(&xscd, xhp->state_cb_data);
|
||||
if (buf != NULL)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
@@ -150,8 +150,6 @@ xbps_init(struct xbps_handle *xhp)
|
||||
XBPS_FETCH_CACHECONN_HOST, CFGF_NONE),
|
||||
CFG_INT(__UNCONST("FetchTimeoutConnection"),
|
||||
XBPS_FETCH_TIMEOUT, CFGF_NONE),
|
||||
CFG_INT(__UNCONST("TransactionFrequencyFlush"),
|
||||
XBPS_TRANS_FLUSH, CFGF_NONE),
|
||||
CFG_BOOL(__UNCONST("syslog"), true, CFGF_NONE),
|
||||
CFG_STR_LIST(__UNCONST("repositories"), NULL, CFGF_MULTI),
|
||||
CFG_STR_LIST(__UNCONST("PackagesOnHold"), NULL, CFGF_MULTI),
|
||||
@@ -249,7 +247,6 @@ xbps_init(struct xbps_handle *xhp)
|
||||
if (xhp->cfg == NULL) {
|
||||
xhp->flags |= XBPS_FLAG_SYSLOG;
|
||||
xhp->fetch_timeout = XBPS_FETCH_TIMEOUT;
|
||||
xhp->transaction_frequency_flush = XBPS_TRANS_FLUSH;
|
||||
cc = XBPS_FETCH_CACHECONN;
|
||||
cch = XBPS_FETCH_CACHECONN_HOST;
|
||||
} else {
|
||||
@@ -258,8 +255,6 @@ xbps_init(struct xbps_handle *xhp)
|
||||
xhp->fetch_timeout = cfg_getint(xhp->cfg, "FetchTimeoutConnection");
|
||||
cc = cfg_getint(xhp->cfg, "FetchCacheConnections");
|
||||
cch = cfg_getint(xhp->cfg, "FetchCacheConnectionsPerHost");
|
||||
xhp->transaction_frequency_flush =
|
||||
cfg_getint(xhp->cfg, "TransactionFrequencyFlush");
|
||||
}
|
||||
if (xhp->flags & XBPS_FLAG_SYSLOG)
|
||||
syslog_enabled = true;
|
||||
@@ -276,8 +271,6 @@ xbps_init(struct xbps_handle *xhp)
|
||||
xbps_dbg_printf(xhp, "FetchCacheconn=%u\n", cc);
|
||||
xbps_dbg_printf(xhp, "FetchCacheconnHost=%u\n", cch);
|
||||
xbps_dbg_printf(xhp, "Syslog=%u\n", syslog_enabled);
|
||||
xbps_dbg_printf(xhp, "TransactionFrequencyFlush=%u\n",
|
||||
xhp->transaction_frequency_flush);
|
||||
xbps_dbg_printf(xhp, "Architecture: %s\n", xhp->un_machine);
|
||||
|
||||
xhp->initialized = true;
|
||||
@@ -295,7 +288,6 @@ xbps_end(struct xbps_handle *xhp)
|
||||
|
||||
xbps_pkgdb_release(xhp);
|
||||
xbps_rpool_release(xhp);
|
||||
xbps_metadir_release(xhp);
|
||||
xbps_fetch_unset_cache_connection();
|
||||
|
||||
cfg_free(xhp->cfg);
|
||||
|
||||
@@ -91,7 +91,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
|
||||
xbps_dbg_printf(xhp, "%s-%s: processing conf_file %s\n",
|
||||
pkgname, version, entry_pname);
|
||||
|
||||
forigd = xbps_metadir_get_pkgd(xhp, pkgname);
|
||||
forigd = xbps_pkgdb_get_pkg_metadata(xhp, pkgname);
|
||||
if (forigd == NULL) {
|
||||
xbps_dbg_printf(xhp, "%s-%s: conf_file %s not currently "
|
||||
"installed\n", pkgname, version, entry_pname);
|
||||
|
||||
@@ -85,7 +85,7 @@ xbps_configure_pkg(struct xbps_handle *xhp,
|
||||
|
||||
assert(pkgname != NULL);
|
||||
|
||||
pkgd = xbps_pkgdb_get_pkgd(xhp, pkgname, false);
|
||||
pkgd = xbps_pkgdb_get_pkg(xhp, pkgname);
|
||||
if (pkgd == NULL)
|
||||
return ENOENT;
|
||||
|
||||
@@ -125,8 +125,10 @@ xbps_configure_pkg(struct xbps_handle *xhp,
|
||||
"the post ACTION: %s", pkgver, strerror(rv));
|
||||
return rv;
|
||||
}
|
||||
if (state == XBPS_PKG_STATE_INSTALLED)
|
||||
if (state == XBPS_PKG_STATE_INSTALLED) {
|
||||
prop_object_release(pkgmetad);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = xbps_set_pkg_state_installed(xhp, pkgname, version,
|
||||
XBPS_PKG_STATE_INSTALLED);
|
||||
@@ -144,5 +146,7 @@ xbps_configure_pkg(struct xbps_handle *xhp,
|
||||
pkgver, strerror(rv));
|
||||
}
|
||||
}
|
||||
prop_object_release(pkgmetad);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
#include "xbps_api_impl.h"
|
||||
|
||||
void HIDDEN
|
||||
xbps_pkg_find_conflicts(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
|
||||
xbps_pkg_find_conflicts(struct xbps_handle *xhp,
|
||||
prop_array_t unsorted,
|
||||
prop_dictionary_t pkg_repod)
|
||||
{
|
||||
prop_array_t pkg_cflicts, trans_cflicts;
|
||||
prop_dictionary_t pkgd;
|
||||
@@ -52,7 +54,8 @@ xbps_pkg_find_conflicts(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
|
||||
/*
|
||||
* Check if current pkg conflicts with an installed package.
|
||||
*/
|
||||
if ((pkgd = xbps_pkgdb_get_pkgd(xhp, cfpkg, true))) {
|
||||
if ((pkgd = xbps_pkgdb_get_pkg(xhp, cfpkg)) ||
|
||||
(pkgd = xbps_pkgdb_get_virtualpkg(xhp, cfpkg))) {
|
||||
prop_dictionary_get_cstring_nocopy(pkgd,
|
||||
"pkgver", &pkgver);
|
||||
buf = xbps_xasprintf("%s conflicts with "
|
||||
@@ -64,9 +67,8 @@ xbps_pkg_find_conflicts(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
|
||||
/*
|
||||
* Check if current pkg conflicts with any pkg in transaction.
|
||||
*/
|
||||
pkgd = xbps_find_pkg_in_dict_by_pattern(xhp, xhp->transd,
|
||||
"unsorted_deps", cfpkg);
|
||||
if (pkgd != NULL) {
|
||||
if ((pkgd = xbps_find_pkg_in_array(unsorted, cfpkg)) ||
|
||||
(pkgd = xbps_find_virtualpkg_in_array(xhp, unsorted, cfpkg))) {
|
||||
prop_dictionary_get_cstring_nocopy(pkgd,
|
||||
"pkgver", &pkgver);
|
||||
buf = xbps_xasprintf("%s conflicts with "
|
||||
|
||||
@@ -1,86 +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 "xbps_api_impl.h"
|
||||
|
||||
void HIDDEN
|
||||
xbps_metadir_release(struct xbps_handle *xhp)
|
||||
{
|
||||
if (prop_object_type(xhp->pkg_metad) == PROP_TYPE_DICTIONARY)
|
||||
prop_object_release(xhp->pkg_metad);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_metadir_get_pkgd(struct xbps_handle *xhp, const char *name)
|
||||
{
|
||||
prop_dictionary_t pkgd, d;
|
||||
const char *savedpkgname;
|
||||
char *plistf;
|
||||
|
||||
assert(xhp);
|
||||
assert(name);
|
||||
|
||||
if ((pkgd = prop_dictionary_get(xhp->pkg_metad, name)) != NULL)
|
||||
return pkgd;
|
||||
|
||||
savedpkgname = name;
|
||||
plistf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, name);
|
||||
|
||||
if (access(plistf, R_OK) == -1) {
|
||||
pkgd = xbps_pkgdb_get_virtualpkgd(xhp, name, false);
|
||||
if (pkgd == NULL)
|
||||
pkgd = xbps_pkgdb_get_pkgd(xhp, name, false);
|
||||
|
||||
if (pkgd != NULL) {
|
||||
free(plistf);
|
||||
prop_dictionary_get_cstring_nocopy(pkgd,
|
||||
"pkgname", &savedpkgname);
|
||||
plistf = xbps_xasprintf("%s/.%s.plist",
|
||||
xhp->metadir, savedpkgname);
|
||||
}
|
||||
}
|
||||
|
||||
d = prop_dictionary_internalize_from_zfile(plistf);
|
||||
free(plistf);
|
||||
if (d == NULL) {
|
||||
xbps_dbg_printf(xhp, "cannot read %s metadata: %s\n",
|
||||
savedpkgname, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (xhp->pkg_metad == NULL)
|
||||
xhp->pkg_metad = prop_dictionary_create();
|
||||
|
||||
prop_dictionary_set(xhp->pkg_metad, name, d);
|
||||
prop_object_release(d);
|
||||
|
||||
return d;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ find_orphan_pkg(struct xbps_handle *xhp,
|
||||
prop_object_iterator_release(iter);
|
||||
return EINVAL;
|
||||
}
|
||||
if (xbps_find_pkg_in_array_by_pattern(xhp, od->array, pkgdep, NULL))
|
||||
if (xbps_find_pkg_in_array(od->array, pkgdep))
|
||||
ndep++;
|
||||
if (od->orphans_user == NULL)
|
||||
continue;
|
||||
|
||||
@@ -70,7 +70,7 @@ xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd, bool flush)
|
||||
assert(desc != NULL);
|
||||
assert(pkgver != NULL);
|
||||
|
||||
pkgd = xbps_pkgdb_get_pkgd(xhp, pkgname, false);
|
||||
pkgd = xbps_pkgdb_get_pkg(xhp, pkgname);
|
||||
if (pkgd == NULL) {
|
||||
rv = ENOENT;
|
||||
goto out;
|
||||
@@ -172,7 +172,7 @@ xbps_register_pkg(struct xbps_handle *xhp, prop_dictionary_t pkgrd, bool flush)
|
||||
prop_dictionary_remove(pkgd, "remove-and-update");
|
||||
prop_dictionary_remove(pkgd, "transaction");
|
||||
|
||||
if (!xbps_pkgdb_replace_pkgd(xhp, pkgd, pkgname, false, flush)) {
|
||||
if (!xbps_pkgdb_replace_pkg(xhp, pkgd, pkgname, flush)) {
|
||||
xbps_dbg_printf(xhp,
|
||||
"%s: failed to replace pkgd dict for %s\n",
|
||||
__func__, pkgname);
|
||||
@@ -190,20 +190,18 @@ out:
|
||||
}
|
||||
|
||||
int
|
||||
xbps_unregister_pkg(struct xbps_handle *xhp,
|
||||
const char *pkgname,
|
||||
const char *version,
|
||||
bool flush)
|
||||
xbps_unregister_pkg(struct xbps_handle *xhp, const char *pkgver, bool flush)
|
||||
{
|
||||
assert(pkgname != NULL);
|
||||
assert(xhp);
|
||||
assert(pkgver);
|
||||
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_UNREGISTER, 0, pkgname, version, NULL);
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_UNREGISTER, 0, pkgver, NULL, NULL);
|
||||
|
||||
if (!xbps_pkgdb_remove_pkgd(xhp, pkgname, false, flush)) {
|
||||
if (!xbps_pkgdb_remove_pkg(xhp, pkgver, flush)) {
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_UNREGISTER_FAIL,
|
||||
errno, pkgname, version,
|
||||
errno, pkgver, NULL,
|
||||
"%s: failed to unregister package: %s",
|
||||
pkgname, strerror(errno));
|
||||
pkgver, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -208,25 +208,29 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
|
||||
|
||||
int
|
||||
xbps_remove_pkg(struct xbps_handle *xhp,
|
||||
const char *pkgname,
|
||||
const char *version,
|
||||
const char *pkgver,
|
||||
bool update,
|
||||
bool soft_replace)
|
||||
{
|
||||
prop_dictionary_t pkgd = NULL;
|
||||
char *tmpname, *buf = NULL, *pkgver = NULL;
|
||||
const char *tmpver = NULL;
|
||||
char *pkgname, *buf = NULL;
|
||||
const char *version;
|
||||
int rv = 0;
|
||||
pkg_state_t state = 0;
|
||||
|
||||
assert(pkgname != NULL);
|
||||
assert(version != NULL);
|
||||
assert(xhp);
|
||||
assert(pkgver);
|
||||
|
||||
pkgname = xbps_pkg_name(pkgver);
|
||||
assert(pkgname);
|
||||
version = xbps_pkg_version(pkgver);
|
||||
assert(version);
|
||||
|
||||
if ((rv = xbps_pkg_state_installed(xhp, pkgname, &state)) != 0)
|
||||
goto out;
|
||||
|
||||
xbps_dbg_printf(xhp, "attempting to remove %s state %d\n",
|
||||
pkgname, state);
|
||||
pkgver, state);
|
||||
|
||||
if (!update)
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE, 0, pkgname, version, NULL);
|
||||
@@ -274,7 +278,9 @@ xbps_remove_pkg(struct xbps_handle *xhp,
|
||||
* continue. Its files will be overwritten later in unpack phase.
|
||||
*/
|
||||
if (update) {
|
||||
free(pkgver);
|
||||
if (pkgd)
|
||||
prop_object_release(pkgd);
|
||||
free(pkgname);
|
||||
return xbps_requiredby_pkg_remove(xhp, pkgname);
|
||||
} else if (soft_replace) {
|
||||
/*
|
||||
@@ -349,8 +355,8 @@ purge:
|
||||
"purge ACTION: %s", pkgver, strerror(rv));
|
||||
goto out;
|
||||
}
|
||||
prop_object_release(pkgd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove package metadata plist.
|
||||
*/
|
||||
@@ -366,25 +372,18 @@ purge:
|
||||
/*
|
||||
* Unregister package from pkgdb.
|
||||
*/
|
||||
if ((rv = xbps_unregister_pkg(xhp, pkgname, version, true)) != 0)
|
||||
if ((rv = xbps_unregister_pkg(xhp, pkgver, true)) != 0)
|
||||
goto out;
|
||||
|
||||
xbps_dbg_printf(xhp, "[remove] unregister %s returned %d\n", pkgver, rv);
|
||||
|
||||
tmpname = xbps_pkg_name(pkgver);
|
||||
assert(tmpname);
|
||||
tmpver = xbps_pkg_version(pkgver);
|
||||
assert(tmpver);
|
||||
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_DONE,
|
||||
0, tmpname, tmpver, NULL);
|
||||
free(tmpname);
|
||||
|
||||
0, pkgname, version, NULL);
|
||||
out:
|
||||
if (buf != NULL)
|
||||
free(buf);
|
||||
if (pkgver != NULL)
|
||||
free(pkgver);
|
||||
if (pkgname != NULL)
|
||||
free(pkgname);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -66,8 +66,11 @@ again:
|
||||
for (i = 0; i < prop_array_count(array); i++) {
|
||||
found = false;
|
||||
obj = prop_array_get(array, i);
|
||||
if (prop_object_type(obj) != PROP_TYPE_DICTIONARY)
|
||||
continue;
|
||||
oldstr = prop_dictionary_get(obj, "file");
|
||||
assert(oldstr);
|
||||
if (oldstr == NULL)
|
||||
continue;
|
||||
|
||||
file = xbps_xasprintf(".%s",
|
||||
prop_string_cstring_nocopy(oldstr));
|
||||
|
||||
@@ -63,7 +63,7 @@ add_pkg_into_reqby(struct xbps_handle *xhp,
|
||||
return ENOMEM;
|
||||
|
||||
if (xbps_match_pkgname_in_array(reqby, pkgname)) {
|
||||
if (!xbps_remove_pkgname_from_array(xhp, reqby, pkgname)) {
|
||||
if (!xbps_remove_pkgname_from_array(reqby, pkgname)) {
|
||||
xbps_dbg_printf(xhp, "%s: failed to remove %s reqby entry: "
|
||||
"%s\n", __func__, pkgname, strerror(errno));
|
||||
free(pkgname);
|
||||
@@ -120,10 +120,9 @@ remove_pkg_from_reqby(struct xbps_handle *xhp,
|
||||
if (reqby == NULL || prop_array_count(reqby) == 0)
|
||||
return 0;
|
||||
|
||||
if (xbps_match_pkgname_in_array(reqby, pkgname)) {
|
||||
if (!xbps_remove_pkgname_from_array(xhp, reqby, pkgname))
|
||||
if (xbps_match_pkgname_in_array(reqby, pkgname))
|
||||
if (!xbps_remove_pkgname_from_array(reqby, pkgname))
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -139,7 +138,7 @@ int HIDDEN
|
||||
xbps_requiredby_pkg_add(struct xbps_handle *xhp, prop_dictionary_t pkgd)
|
||||
{
|
||||
prop_array_t pkg_rdeps;
|
||||
prop_object_t obj, pkgd_pkgdb;
|
||||
prop_object_t obj, pkgdbd;
|
||||
prop_object_iterator_t iter;
|
||||
const char *pkgver, *str;
|
||||
int rv = 0;
|
||||
@@ -161,25 +160,14 @@ xbps_requiredby_pkg_add(struct xbps_handle *xhp, prop_dictionary_t pkgd)
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
pkgd_pkgdb = xbps_find_virtualpkg_conf_in_array_by_pattern(
|
||||
xhp, xhp->pkgdb, str);
|
||||
if (pkgd_pkgdb == NULL) {
|
||||
pkgd_pkgdb =
|
||||
xbps_find_virtualpkg_in_array_by_pattern(
|
||||
xhp, xhp->pkgdb, str);
|
||||
if (pkgd_pkgdb == NULL) {
|
||||
pkgd_pkgdb = xbps_find_pkg_in_array_by_pattern(
|
||||
xhp, xhp->pkgdb, str, NULL);
|
||||
if (pkgd_pkgdb == NULL) {
|
||||
rv = ENOENT;
|
||||
xbps_dbg_printf(xhp,
|
||||
"%s: couldnt find `%s' "
|
||||
"entry in pkgdb\n", __func__, str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (((pkgdbd = xbps_find_pkg_in_array(xhp->pkgdb, str)) == NULL) &&
|
||||
((pkgdbd = xbps_find_virtualpkg_in_array(xhp, xhp->pkgdb, str)) == NULL)) {
|
||||
rv = ENOENT;
|
||||
xbps_dbg_printf(xhp, "%s: couldnt find `%s' "
|
||||
"entry in pkgdb\n", __func__, str);
|
||||
break;
|
||||
}
|
||||
rv = add_pkg_into_reqby(xhp, pkgd_pkgdb, pkgver);
|
||||
rv = add_pkg_into_reqby(xhp, pkgdbd, pkgver);
|
||||
if (rv != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ xbps_pkg_state_installed(struct xbps_handle *xhp,
|
||||
assert(pkgname != NULL);
|
||||
assert(state != NULL);
|
||||
|
||||
pkgd = xbps_pkgdb_get_pkgd(xhp, pkgname, false);
|
||||
pkgd = xbps_pkgdb_get_pkg(xhp, pkgname);
|
||||
if (pkgd == NULL)
|
||||
return ENOENT;
|
||||
|
||||
@@ -166,7 +166,7 @@ xbps_set_pkg_state_installed(struct xbps_handle *xhp,
|
||||
|
||||
assert(pkgname != NULL);
|
||||
|
||||
pkgd = xbps_pkgdb_get_pkgd(xhp, pkgname, false);
|
||||
pkgd = xbps_pkgdb_get_pkg(xhp, pkgname);
|
||||
if (pkgd == NULL) {
|
||||
pkgd = prop_dictionary_create();
|
||||
if (pkgd == NULL)
|
||||
|
||||
@@ -80,7 +80,7 @@ unpack_archive(struct xbps_handle *xhp,
|
||||
prop_dictionary_t pkg_repod,
|
||||
struct archive *ar)
|
||||
{
|
||||
prop_dictionary_t filesd = NULL, old_filesd = NULL;
|
||||
prop_dictionary_t pkg_metad = NULL, filesd = NULL, old_filesd = NULL;
|
||||
prop_array_t array, obsoletes;
|
||||
prop_object_t obj;
|
||||
prop_data_t data;
|
||||
@@ -170,6 +170,7 @@ unpack_archive(struct xbps_handle *xhp,
|
||||
* Prepare unpack callback ops.
|
||||
*/
|
||||
if (xhp->unpack_cb != NULL) {
|
||||
xucd.xhp = xhp;
|
||||
xucd.pkgver = pkgver;
|
||||
xucd.entry = entry_pname;
|
||||
xucd.entry_size = entry_size;
|
||||
@@ -457,7 +458,7 @@ unpack_archive(struct xbps_handle *xhp,
|
||||
} else {
|
||||
if (xhp->unpack_cb != NULL) {
|
||||
xucd.entry_extract_count++;
|
||||
(*xhp->unpack_cb)(xhp, &xucd, xhp->unpack_cb_data);
|
||||
(*xhp->unpack_cb)(&xucd, xhp->unpack_cb_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -485,7 +486,7 @@ unpack_archive(struct xbps_handle *xhp,
|
||||
* - Package upgrade.
|
||||
* - Package with "softreplace" keyword.
|
||||
*/
|
||||
old_filesd = xbps_metadir_get_pkgd(xhp, pkgname);
|
||||
old_filesd = xbps_pkgdb_get_pkg_metadata(xhp, pkgname);
|
||||
assert(prop_object_type(old_filesd) == PROP_TYPE_DICTIONARY);
|
||||
|
||||
obsoletes = xbps_find_pkg_obsoletes(xhp, old_filesd, filesd);
|
||||
@@ -508,39 +509,42 @@ unpack_archive(struct xbps_handle *xhp,
|
||||
}
|
||||
|
||||
out1:
|
||||
prop_dictionary_make_immutable(pkg_repod);
|
||||
pkg_metad = prop_dictionary_copy_mutable(pkg_repod);
|
||||
|
||||
/* Add objects from XBPS_PKGFILES */
|
||||
array = prop_dictionary_get(filesd, "files");
|
||||
if (array && prop_array_count(array))
|
||||
prop_dictionary_set(pkg_repod, "files", array);
|
||||
prop_dictionary_set(pkg_metad, "files", array);
|
||||
array = prop_dictionary_get(filesd, "conf_files");
|
||||
if (array && prop_array_count(array))
|
||||
prop_dictionary_set(pkg_repod, "conf_files", array);
|
||||
prop_dictionary_set(pkg_metad, "conf_files", array);
|
||||
array = prop_dictionary_get(filesd, "links");
|
||||
if (array && prop_array_count(array))
|
||||
prop_dictionary_set(pkg_repod, "links", array);
|
||||
prop_dictionary_set(pkg_metad, "links", array);
|
||||
array = prop_dictionary_get(filesd, "dirs");
|
||||
if (array && prop_array_count(array))
|
||||
prop_dictionary_set(pkg_repod, "dirs", array);
|
||||
prop_dictionary_set(pkg_metad, "dirs", array);
|
||||
|
||||
/* Add install/remove scripts data objects */
|
||||
if (instbuf != NULL) {
|
||||
data = prop_data_create_data(instbuf, instbufsiz);
|
||||
assert(data);
|
||||
prop_dictionary_set(pkg_repod, "install-script", data);
|
||||
prop_dictionary_set(pkg_metad, "install-script", data);
|
||||
prop_object_release(data);
|
||||
free(instbuf);
|
||||
}
|
||||
if (rembuf != NULL) {
|
||||
data = prop_data_create_data(rembuf, rembufsiz);
|
||||
assert(data);
|
||||
prop_dictionary_set(pkg_repod, "remove-script", data);
|
||||
prop_dictionary_set(pkg_metad, "remove-script", data);
|
||||
prop_object_release(data);
|
||||
free(rembuf);
|
||||
}
|
||||
/* Remove unneeded objs from transaction */
|
||||
prop_dictionary_remove(pkg_repod, "remove-and-update");
|
||||
prop_dictionary_remove(pkg_repod, "transaction");
|
||||
prop_dictionary_remove(pkg_repod, "state");
|
||||
prop_dictionary_remove(pkg_metad, "remove-and-update");
|
||||
prop_dictionary_remove(pkg_metad, "transaction");
|
||||
prop_dictionary_remove(pkg_metad, "state");
|
||||
|
||||
/*
|
||||
* Externalize pkg dictionary to metadir.
|
||||
@@ -554,7 +558,7 @@ out1:
|
||||
}
|
||||
}
|
||||
buf = xbps_xasprintf("%s/.%s.plist", XBPS_META_PATH, pkgname);
|
||||
if (!prop_dictionary_externalize_to_file(pkg_repod, buf)) {
|
||||
if (!prop_dictionary_externalize_to_file(pkg_metad, buf)) {
|
||||
rv = errno;
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
|
||||
errno, pkgname, version,
|
||||
@@ -565,6 +569,8 @@ out1:
|
||||
}
|
||||
free(buf);
|
||||
out:
|
||||
if (prop_object_type(pkg_metad) == PROP_TYPE_DICTIONARY)
|
||||
prop_object_release(pkg_metad);
|
||||
if (prop_object_type(filesd) == PROP_TYPE_DICTIONARY)
|
||||
prop_object_release(filesd);
|
||||
|
||||
@@ -575,7 +581,7 @@ int HIDDEN
|
||||
xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
|
||||
{
|
||||
struct archive *ar = NULL;
|
||||
const char *pkgname, *version, *repoloc, *pkgver, *fname;
|
||||
const char *pkgname, *version, *pkgver;
|
||||
char *bpkg;
|
||||
int rv = 0;
|
||||
|
||||
@@ -584,17 +590,15 @@ xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
|
||||
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname);
|
||||
prop_dictionary_get_cstring_nocopy(pkg_repod, "version", &version);
|
||||
prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &pkgver);
|
||||
prop_dictionary_get_cstring_nocopy(pkg_repod, "repository", &repoloc);
|
||||
prop_dictionary_get_cstring_nocopy(pkg_repod, "filename", &fname);
|
||||
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK, 0, pkgname, version, NULL);
|
||||
|
||||
bpkg = xbps_path_from_repository_uri(xhp, pkg_repod, repoloc);
|
||||
bpkg = xbps_repository_pkg_path(xhp, pkg_repod);
|
||||
if (bpkg == NULL) {
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
|
||||
errno, pkgname, version,
|
||||
"%s: [unpack] cannot determine binary package "
|
||||
"file for `%s': %s", pkgver, fname, strerror(errno));
|
||||
"file for `%s': %s", pkgver, bpkg, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
|
||||
@@ -615,7 +619,7 @@ xbps_unpack_binary_pkg(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
|
||||
rv, pkgname, version,
|
||||
"%s: [unpack] failed to open binary package `%s': %s",
|
||||
pkgver, fname, strerror(rv));
|
||||
pkgver, bpkg, strerror(rv));
|
||||
free(bpkg);
|
||||
archive_read_free(ar);
|
||||
return rv;
|
||||
|
||||
101
lib/pkgdb.c
101
lib/pkgdb.c
@@ -125,6 +125,9 @@ xbps_pkgdb_release(struct xbps_handle *xhp)
|
||||
if (xhp->pkgdb == NULL)
|
||||
return;
|
||||
|
||||
if (prop_object_type(xhp->pkg_metad) == PROP_TYPE_DICTIONARY)
|
||||
prop_object_release(xhp->pkg_metad);
|
||||
|
||||
prop_object_release(xhp->pkgdb);
|
||||
xhp->pkgdb = NULL;
|
||||
xbps_dbg_printf(xhp, "[pkgdb] released ok.\n");
|
||||
@@ -166,81 +169,72 @@ xbps_pkgdb_foreach_cb(struct xbps_handle *xhp,
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_pkgdb_get_pkgd(struct xbps_handle *xhp, const char *pkg, bool bypattern)
|
||||
xbps_pkgdb_get_pkg(struct xbps_handle *xhp, const char *pkg)
|
||||
{
|
||||
prop_dictionary_t pkgd = NULL;
|
||||
|
||||
if (xbps_pkgdb_init(xhp) != 0)
|
||||
return NULL;
|
||||
|
||||
if (bypattern)
|
||||
pkgd = xbps_find_pkg_in_array_by_pattern(xhp, xhp->pkgdb, pkg, NULL);
|
||||
else
|
||||
pkgd = xbps_find_pkg_in_array_by_name(xhp, xhp->pkgdb, pkg, NULL);
|
||||
|
||||
return pkgd;
|
||||
return xbps_find_pkg_in_array(xhp->pkgdb, pkg);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_pkgdb_get_virtualpkgd(struct xbps_handle *xhp,
|
||||
const char *vpkg,
|
||||
bool bypattern)
|
||||
xbps_pkgdb_get_virtualpkg(struct xbps_handle *xhp, const char *vpkg)
|
||||
{
|
||||
prop_dictionary_t pkgd = NULL;
|
||||
|
||||
if (xbps_pkgdb_init(xhp) != 0)
|
||||
return NULL;
|
||||
|
||||
if (bypattern) {
|
||||
/* first return vpkg from matching a conf file */
|
||||
pkgd = xbps_find_virtualpkg_conf_in_array_by_pattern(xhp,
|
||||
xhp->pkgdb, vpkg);
|
||||
if (pkgd != NULL)
|
||||
return pkgd;
|
||||
return xbps_find_virtualpkg_in_array(xhp, xhp->pkgdb, vpkg);
|
||||
}
|
||||
|
||||
/* ... otherwise the first one in array */
|
||||
pkgd = xbps_find_virtualpkg_in_array_by_pattern(xhp,
|
||||
xhp->pkgdb, vpkg);
|
||||
} else {
|
||||
/* first return vpkg from matching a conf file */
|
||||
pkgd = xbps_find_virtualpkg_conf_in_array_by_name(xhp,
|
||||
xhp->pkgdb, vpkg);
|
||||
if (pkgd != NULL)
|
||||
return pkgd;
|
||||
prop_dictionary_t
|
||||
xbps_pkgdb_get_pkg_metadata(struct xbps_handle *xhp, const char *pkg)
|
||||
{
|
||||
prop_dictionary_t pkgd, pkg_metad;
|
||||
const char *pkgname;
|
||||
char *plist;
|
||||
|
||||
pkgd = xbps_find_virtualpkg_in_array_by_name(xhp,
|
||||
xhp->pkgdb, vpkg);
|
||||
pkgd = xbps_pkgdb_get_pkg(xhp, pkg);
|
||||
if (pkgd == NULL)
|
||||
return NULL;
|
||||
|
||||
prop_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname);
|
||||
|
||||
if ((pkg_metad = prop_dictionary_get(xhp->pkg_metad, pkgname)) != NULL)
|
||||
return pkg_metad;
|
||||
|
||||
plist = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
|
||||
pkg_metad = prop_dictionary_internalize_from_zfile(plist);
|
||||
free(plist);
|
||||
|
||||
if (pkg_metad == NULL) {
|
||||
xbps_dbg_printf(xhp, "[pkgdb] cannot read %s metadata: %s\n",
|
||||
pkgname, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pkgd;
|
||||
}
|
||||
if (xhp->pkg_metad == NULL)
|
||||
xhp->pkg_metad = prop_dictionary_create();
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_pkgdb_get_pkgd_by_pkgver(struct xbps_handle *xhp, const char *pkgver)
|
||||
{
|
||||
if (xbps_pkgdb_init(xhp) != 0)
|
||||
return NULL;
|
||||
prop_dictionary_set(xhp->pkg_metad, pkgname, pkg_metad);
|
||||
prop_object_release(pkg_metad);
|
||||
|
||||
return xbps_find_pkg_in_array_by_pkgver(xhp, xhp->pkgdb, pkgver, NULL);
|
||||
return pkg_metad;
|
||||
}
|
||||
|
||||
bool
|
||||
xbps_pkgdb_remove_pkgd(struct xbps_handle *xhp,
|
||||
const char *pkg,
|
||||
bool bypattern,
|
||||
bool flush)
|
||||
xbps_pkgdb_remove_pkg(struct xbps_handle *xhp, const char *pkg, bool flush)
|
||||
{
|
||||
bool rv = false;
|
||||
|
||||
if (xbps_pkgdb_init(xhp) != 0)
|
||||
return false;
|
||||
|
||||
if (bypattern)
|
||||
rv = xbps_remove_pkg_from_array_by_pattern(xhp,
|
||||
xhp->pkgdb, pkg, NULL);
|
||||
if (xbps_pkgpattern_version(pkg))
|
||||
rv = xbps_remove_pkg_from_array_by_pattern(xhp->pkgdb, pkg);
|
||||
else if (xbps_pkg_version(pkg))
|
||||
rv = xbps_remove_pkg_from_array_by_pkgver(xhp->pkgdb, pkg);
|
||||
else
|
||||
rv = xbps_remove_pkg_from_array_by_name(xhp,
|
||||
xhp->pkgdb, pkg, NULL);
|
||||
rv = xbps_remove_pkg_from_array_by_name(xhp->pkgdb, pkg);
|
||||
|
||||
if (!flush || !rv)
|
||||
return rv;
|
||||
@@ -252,18 +246,17 @@ xbps_pkgdb_remove_pkgd(struct xbps_handle *xhp,
|
||||
}
|
||||
|
||||
bool
|
||||
xbps_pkgdb_replace_pkgd(struct xbps_handle *xhp,
|
||||
prop_dictionary_t pkgd,
|
||||
const char *pkg,
|
||||
bool bypattern,
|
||||
bool flush)
|
||||
xbps_pkgdb_replace_pkg(struct xbps_handle *xhp,
|
||||
prop_dictionary_t pkgd,
|
||||
const char *pkg,
|
||||
bool flush)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (xbps_pkgdb_init(xhp) != 0)
|
||||
return false;
|
||||
|
||||
if (bypattern)
|
||||
if (xbps_pkgpattern_version(pkg))
|
||||
rv = xbps_array_replace_dict_by_pattern(xhp->pkgdb, pkgd, pkg);
|
||||
else
|
||||
rv = xbps_array_replace_dict_by_name(xhp->pkgdb, pkgd, pkg);
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
* These functions manipulate plist files and objects shared by almost
|
||||
* all library functions.
|
||||
*/
|
||||
bool
|
||||
bool HIDDEN
|
||||
xbps_add_obj_to_dict(prop_dictionary_t dict, prop_object_t obj,
|
||||
const char *key)
|
||||
{
|
||||
@@ -57,7 +57,7 @@ xbps_add_obj_to_dict(prop_dictionary_t dict, prop_object_t obj,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
bool HIDDEN
|
||||
xbps_add_obj_to_array(prop_array_t array, prop_object_t obj)
|
||||
{
|
||||
assert(prop_object_type(array) == PROP_TYPE_ARRAY);
|
||||
@@ -249,7 +249,7 @@ array_replace_dict(prop_array_t array,
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
int
|
||||
int HIDDEN
|
||||
xbps_array_replace_dict_by_name(prop_array_t array,
|
||||
prop_dictionary_t dict,
|
||||
const char *pkgname)
|
||||
@@ -257,7 +257,7 @@ xbps_array_replace_dict_by_name(prop_array_t array,
|
||||
return array_replace_dict(array, dict, pkgname, false);
|
||||
}
|
||||
|
||||
int
|
||||
int HIDDEN
|
||||
xbps_array_replace_dict_by_pattern(prop_array_t array,
|
||||
prop_dictionary_t dict,
|
||||
const char *pattern)
|
||||
|
||||
@@ -119,7 +119,7 @@ open_archive(const char *url)
|
||||
struct url *u;
|
||||
struct archive *a;
|
||||
|
||||
if (!xbps_check_is_repository_uri_remote(url)) {
|
||||
if (!xbps_repository_is_remote(url)) {
|
||||
if ((a = archive_read_new()) == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -146,7 +146,7 @@ open_archive(const char *url)
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_dictionary_metadata_plist_by_url(const char *url, const char *plistf)
|
||||
xbps_get_pkg_plist_from_binpkg(const char *fname, const char *plistf)
|
||||
{
|
||||
prop_dictionary_t plistd = NULL;
|
||||
struct archive *a;
|
||||
@@ -154,10 +154,10 @@ xbps_dictionary_metadata_plist_by_url(const char *url, const char *plistf)
|
||||
const char *curpath, *comptype;
|
||||
int i = 0;
|
||||
|
||||
assert(url != NULL);
|
||||
assert(fname != NULL);
|
||||
assert(plistf != NULL);
|
||||
|
||||
if ((a = open_archive(url)) == NULL)
|
||||
if ((a = open_archive(fname)) == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
|
||||
389
lib/plist_find.c
389
lib/plist_find.c
@@ -31,378 +31,89 @@
|
||||
|
||||
#include "xbps_api_impl.h"
|
||||
|
||||
/**
|
||||
* @file lib/plist_find.c
|
||||
* @brief PropertyList generic routines
|
||||
* @defgroup plist PropertyList generic functions
|
||||
*
|
||||
* These functions manipulate plist files and objects shared by almost
|
||||
* all library functions.
|
||||
*/
|
||||
static prop_dictionary_t
|
||||
find_pkg_in_array(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *str,
|
||||
bool bypattern,
|
||||
bool virtual,
|
||||
const char *targetarch)
|
||||
get_pkg_in_array(prop_array_t array, const char *str, bool virtual)
|
||||
{
|
||||
prop_object_iterator_t iter;
|
||||
prop_object_t obj = NULL;
|
||||
const char *pkgver, *dpkgn, *arch;
|
||||
bool chkarch;
|
||||
|
||||
assert(prop_object_type(array) == PROP_TYPE_ARRAY);
|
||||
assert(str != NULL);
|
||||
|
||||
iter = prop_array_iterator(array);
|
||||
if (iter == NULL)
|
||||
return NULL;
|
||||
|
||||
while ((obj = prop_object_iterator_next(iter))) {
|
||||
chkarch = prop_dictionary_get_cstring_nocopy(obj,
|
||||
"architecture", &arch);
|
||||
if (chkarch && !xbps_pkg_arch_match(xhp, arch, targetarch))
|
||||
continue;
|
||||
const char *pkgver, *dpkgn;
|
||||
size_t i;
|
||||
bool found = false;
|
||||
|
||||
for (i = 0; i < prop_array_count(array); i++) {
|
||||
obj = prop_array_get(array, i);
|
||||
if (virtual) {
|
||||
/*
|
||||
* Check if package pattern matches
|
||||
* any virtual package version in dictionary.
|
||||
*/
|
||||
if (xbps_match_virtual_pkg_in_dict(obj, str, bypattern))
|
||||
if (xbps_pkgpattern_version(str))
|
||||
found = xbps_match_virtual_pkg_in_dict(obj, str, true);
|
||||
else
|
||||
found = xbps_match_virtual_pkg_in_dict(obj, str, false);
|
||||
|
||||
if (found)
|
||||
break;
|
||||
} else if (bypattern) {
|
||||
/*
|
||||
* Check if package pattern matches the
|
||||
* pkgver string object in dictionary.
|
||||
*/
|
||||
} else if (xbps_pkgpattern_version(str)) {
|
||||
/* ,atch by pattern against pkgver */
|
||||
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||
"pkgver", &pkgver))
|
||||
continue;
|
||||
if (xbps_pkgpattern_match(pkgver, str))
|
||||
if (xbps_pkgpattern_match(pkgver, str)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
} else if (xbps_pkg_version(str)) {
|
||||
/* match by exact pkgver */
|
||||
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||
"pkgver", &pkgver))
|
||||
continue;
|
||||
if (strcmp(str, pkgver) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* match by pkgname */
|
||||
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||
"pkgname", &dpkgn))
|
||||
continue;
|
||||
if (strcmp(dpkgn, str) == 0)
|
||||
if (strcmp(dpkgn, str) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prop_object_iterator_release(iter);
|
||||
if (obj == NULL) {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_pkg_in_array_by_name(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *name,
|
||||
const char *targetarch)
|
||||
{
|
||||
return find_pkg_in_array(xhp, array, name, false, false, targetarch);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_pkg_in_array_by_pattern(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *pattern,
|
||||
const char *targetarch)
|
||||
{
|
||||
return find_pkg_in_array(xhp, array, pattern, true, false, targetarch);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_pkg_in_array_by_pkgver(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *pkgver,
|
||||
const char *targetarch)
|
||||
{
|
||||
prop_object_iterator_t iter;
|
||||
prop_object_t obj = NULL;
|
||||
const char *rpkgver, *arch;
|
||||
bool chkarch, found = false;
|
||||
|
||||
assert(prop_object_type(array) == PROP_TYPE_ARRAY);
|
||||
assert(pkgver != NULL);
|
||||
|
||||
iter = prop_array_iterator(array);
|
||||
if (iter == NULL)
|
||||
return NULL;
|
||||
|
||||
while ((obj = prop_object_iterator_next(iter))) {
|
||||
chkarch = prop_dictionary_get_cstring_nocopy(obj,
|
||||
"architecture", &arch);
|
||||
if (!prop_dictionary_get_cstring_nocopy(obj,
|
||||
"pkgver", &rpkgver))
|
||||
continue;
|
||||
if (chkarch && !xbps_pkg_arch_match(xhp, arch, targetarch))
|
||||
continue;
|
||||
if (strcmp(pkgver, rpkgver) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prop_object_iterator_release(iter);
|
||||
if (found)
|
||||
return obj;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_virtualpkg_in_array_by_name(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *name)
|
||||
{
|
||||
return find_pkg_in_array(xhp, array, name, false, true, NULL);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_virtualpkg_in_array_by_pattern(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *pattern)
|
||||
{
|
||||
return find_pkg_in_array(xhp, array, pattern, true, true, NULL);
|
||||
}
|
||||
|
||||
static const char *
|
||||
find_virtualpkg_user_in_conf(struct xbps_handle *xhp,
|
||||
const char *vpkg,
|
||||
bool bypattern)
|
||||
{
|
||||
const char *vpkgver, *pkg = NULL;
|
||||
char *vpkgname = NULL, *tmp;
|
||||
size_t i, j, cnt;
|
||||
|
||||
if (xhp->cfg == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((cnt = cfg_size(xhp->cfg, "virtual-package")) == 0) {
|
||||
/* no virtual packages configured */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
cfg_t *sec = cfg_getnsec(xhp->cfg, "virtual-package", i);
|
||||
for (j = 0; j < cfg_size(sec, "targets"); j++) {
|
||||
tmp = NULL;
|
||||
vpkgver = cfg_getnstr(sec, "targets", j);
|
||||
if (strchr(vpkgver, '_') == NULL) {
|
||||
tmp = xbps_xasprintf("%s_1", vpkgver);
|
||||
vpkgname = xbps_pkg_name(tmp);
|
||||
free(tmp);
|
||||
} else {
|
||||
vpkgname = xbps_pkg_name(vpkgver);
|
||||
}
|
||||
if (vpkgname == NULL)
|
||||
break;
|
||||
if (bypattern) {
|
||||
if (!xbps_pkgpattern_match(vpkgver, vpkg)) {
|
||||
free(vpkgname);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(vpkg, vpkgname)) {
|
||||
free(vpkgname);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* virtual package matched in conffile */
|
||||
pkg = cfg_title(sec);
|
||||
xbps_dbg_printf(xhp,
|
||||
"matched vpkg in conf `%s' for %s\n",
|
||||
pkg, vpkg);
|
||||
free(vpkgname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
static prop_dictionary_t
|
||||
find_virtualpkg_user_in_array(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *str,
|
||||
bool bypattern)
|
||||
{
|
||||
const char *vpkgname;
|
||||
|
||||
assert(prop_object_type(array) == PROP_TYPE_ARRAY);
|
||||
assert(str != NULL);
|
||||
|
||||
vpkgname = find_virtualpkg_user_in_conf(xhp, str, bypattern);
|
||||
if (vpkgname == NULL)
|
||||
return NULL;
|
||||
|
||||
return find_pkg_in_array(xhp, array, vpkgname, false, false, NULL);
|
||||
return found ? obj : NULL;
|
||||
}
|
||||
|
||||
prop_dictionary_t HIDDEN
|
||||
xbps_find_virtualpkg_conf_in_array_by_name(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *name)
|
||||
xbps_find_pkg_in_array(prop_array_t a, const char *s)
|
||||
{
|
||||
return find_virtualpkg_user_in_array(xhp, array, name, false);
|
||||
assert(prop_object_type(a) == PROP_TYPE_ARRAY);
|
||||
assert(s);
|
||||
|
||||
return get_pkg_in_array(a, s, false);
|
||||
}
|
||||
|
||||
prop_dictionary_t HIDDEN
|
||||
xbps_find_virtualpkg_conf_in_array_by_pattern(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *p)
|
||||
xbps_find_virtualpkg_in_array(struct xbps_handle *x,
|
||||
prop_array_t a,
|
||||
const char *s)
|
||||
{
|
||||
return find_virtualpkg_user_in_array(xhp, array, p, true);
|
||||
}
|
||||
prop_dictionary_t pkgd;
|
||||
const char *vpkg;
|
||||
bool bypattern = false;
|
||||
|
||||
static prop_dictionary_t
|
||||
find_pkg_in_dict(struct xbps_handle *xhp,
|
||||
prop_dictionary_t d,
|
||||
const char *key,
|
||||
const char *str,
|
||||
bool bypattern,
|
||||
bool virtual)
|
||||
{
|
||||
prop_array_t array;
|
||||
assert(x);
|
||||
assert(prop_object_type(a) == PROP_TYPE_ARRAY);
|
||||
assert(s);
|
||||
|
||||
assert(prop_object_type(d) == PROP_TYPE_DICTIONARY);
|
||||
assert(str != NULL);
|
||||
assert(key != NULL);
|
||||
if (xbps_pkgpattern_version(s))
|
||||
bypattern = true;
|
||||
|
||||
array = prop_dictionary_get(d, key);
|
||||
if (prop_object_type(array) != PROP_TYPE_ARRAY)
|
||||
return NULL;
|
||||
|
||||
return find_pkg_in_array(xhp, array, str, bypattern, virtual, NULL);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_pkg_in_dict_by_name(struct xbps_handle *xhp,
|
||||
prop_dictionary_t d,
|
||||
const char *key,
|
||||
const char *pkgname)
|
||||
{
|
||||
return find_pkg_in_dict(xhp, d, key, pkgname, false, false);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_pkg_in_dict_by_pattern(struct xbps_handle *xhp,
|
||||
prop_dictionary_t d,
|
||||
const char *key,
|
||||
const char *pattern)
|
||||
{
|
||||
return find_pkg_in_dict(xhp, d, key, pattern, true, false);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_pkg_in_dict_by_pkgver(struct xbps_handle *xhp,
|
||||
prop_dictionary_t d,
|
||||
const char *key,
|
||||
const char *pkgver)
|
||||
{
|
||||
prop_array_t array;
|
||||
|
||||
assert(d != NULL);
|
||||
assert(key != NULL);
|
||||
assert(pkgver != NULL);
|
||||
|
||||
array = prop_dictionary_get(d, key);
|
||||
if (array == NULL)
|
||||
return NULL;
|
||||
|
||||
return xbps_find_pkg_in_array_by_pkgver(xhp, array, pkgver, NULL);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_virtualpkg_in_dict_by_name(struct xbps_handle *xhp,
|
||||
prop_dictionary_t d,
|
||||
const char *key,
|
||||
const char *name)
|
||||
{
|
||||
return find_pkg_in_dict(xhp, d, key, name, false, true);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_virtualpkg_in_dict_by_pattern(struct xbps_handle *xhp,
|
||||
prop_dictionary_t d,
|
||||
const char *key,
|
||||
const char *pattern)
|
||||
{
|
||||
return find_pkg_in_dict(xhp, d, key, pattern, true, true);
|
||||
}
|
||||
|
||||
static prop_dictionary_t
|
||||
find_pkgd_installed(struct xbps_handle *xhp,
|
||||
const char *str,
|
||||
bool bypattern,
|
||||
bool virtual)
|
||||
{
|
||||
prop_dictionary_t pkgd = NULL;
|
||||
pkg_state_t state = 0;
|
||||
int rv;
|
||||
|
||||
assert(str != NULL);
|
||||
|
||||
if ((rv = xbps_pkgdb_init(xhp)) != 0) {
|
||||
if (rv != ENOENT) {
|
||||
xbps_dbg_printf(xhp, "%s: couldn't initialize "
|
||||
"pkgdb: %s\n", strerror(rv));
|
||||
return NULL;
|
||||
} else if (rv == ENOENT)
|
||||
return NULL;
|
||||
if ((vpkg = vpkg_user_conf(x, s, bypattern))) {
|
||||
if ((pkgd = get_pkg_in_array(a, vpkg, true)))
|
||||
return pkgd;
|
||||
}
|
||||
|
||||
/* try normal pkg */
|
||||
if (virtual == false) {
|
||||
pkgd = find_pkg_in_array(xhp, xhp->pkgdb, str,
|
||||
bypattern, false, NULL);
|
||||
} else {
|
||||
/* virtual pkg set by user in conf */
|
||||
pkgd = find_virtualpkg_user_in_array(xhp, xhp->pkgdb,
|
||||
str, bypattern);
|
||||
if (pkgd == NULL) {
|
||||
/* any virtual pkg in array matching pattern */
|
||||
pkgd = find_pkg_in_array(xhp, xhp->pkgdb,
|
||||
str, bypattern, true, NULL);
|
||||
}
|
||||
}
|
||||
/* pkg not found */
|
||||
if (pkgd == NULL)
|
||||
return NULL;
|
||||
|
||||
if (xbps_pkg_state_dictionary(pkgd, &state) != 0)
|
||||
return NULL;
|
||||
|
||||
switch (state) {
|
||||
case XBPS_PKG_STATE_INSTALLED:
|
||||
case XBPS_PKG_STATE_UNPACKED:
|
||||
return pkgd;
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
/* not fully installed */
|
||||
errno = ENOENT;
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_pkg_dict_installed(struct xbps_handle *xhp,
|
||||
const char *str,
|
||||
bool bypattern)
|
||||
{
|
||||
return find_pkgd_installed(xhp, str, bypattern, false);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_find_virtualpkg_dict_installed(struct xbps_handle *xhp,
|
||||
const char *str,
|
||||
bool bypattern)
|
||||
{
|
||||
return find_pkgd_installed(xhp, str, bypattern, true);
|
||||
return get_pkg_in_array(a, s, true);
|
||||
}
|
||||
|
||||
@@ -31,27 +31,15 @@
|
||||
|
||||
#include "xbps_api_impl.h"
|
||||
|
||||
/**
|
||||
* @file lib/plist_remove.c
|
||||
* @brief PropertyList generic routines
|
||||
* @defgroup plist PropertyList generic functions
|
||||
*
|
||||
* These functions manipulate plist files and objects shared by almost
|
||||
* all library functions.
|
||||
*/
|
||||
static bool
|
||||
remove_obj_from_array(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *str,
|
||||
int mode,
|
||||
const char *targetarch)
|
||||
remove_obj_from_array(prop_array_t array, const char *str, int mode)
|
||||
{
|
||||
prop_object_iterator_t iter;
|
||||
prop_object_t obj;
|
||||
const char *curname, *pkgdep, *arch;
|
||||
const char *curname, *pkgdep;
|
||||
char *curpkgname;
|
||||
size_t idx = 0;
|
||||
bool found = false, chkarch;
|
||||
bool found = false;
|
||||
|
||||
assert(prop_object_type(array) == PROP_TYPE_ARRAY);
|
||||
|
||||
@@ -80,13 +68,6 @@ remove_obj_from_array(struct xbps_handle *xhp,
|
||||
free(curpkgname);
|
||||
} else if (mode == 2) {
|
||||
/* match by pkgname, obj is a dictionary */
|
||||
chkarch = prop_dictionary_get_cstring_nocopy(obj,
|
||||
"architecture", &arch);
|
||||
if (chkarch && !xbps_pkg_arch_match(xhp, arch,
|
||||
targetarch)) {
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
prop_dictionary_get_cstring_nocopy(obj,
|
||||
"pkgname", &curname);
|
||||
if (strcmp(curname, str) == 0) {
|
||||
@@ -94,13 +75,6 @@ remove_obj_from_array(struct xbps_handle *xhp,
|
||||
break;
|
||||
}
|
||||
} else if (mode == 3) {
|
||||
chkarch = prop_dictionary_get_cstring_nocopy(obj,
|
||||
"architecture", &arch);
|
||||
if (chkarch && !xbps_pkg_arch_match(xhp, arch,
|
||||
targetarch)) {
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
/* match by pkgver, obj is a dictionary */
|
||||
prop_dictionary_get_cstring_nocopy(obj,
|
||||
"pkgver", &curname);
|
||||
@@ -109,13 +83,6 @@ remove_obj_from_array(struct xbps_handle *xhp,
|
||||
break;
|
||||
}
|
||||
} else if (mode == 4) {
|
||||
chkarch = prop_dictionary_get_cstring_nocopy(obj,
|
||||
"architecture", &arch);
|
||||
if (chkarch && !xbps_pkg_arch_match(xhp, arch,
|
||||
targetarch)) {
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
/* match by pattern, obj is a dictionary */
|
||||
prop_dictionary_get_cstring_nocopy(obj,
|
||||
"pkgver", &curname);
|
||||
@@ -137,45 +104,32 @@ remove_obj_from_array(struct xbps_handle *xhp,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
xbps_remove_string_from_array(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *str)
|
||||
bool HIDDEN
|
||||
xbps_remove_string_from_array(prop_array_t array, const char *str)
|
||||
{
|
||||
return remove_obj_from_array(xhp, array, str, 0, NULL);
|
||||
return remove_obj_from_array(array, str, 0);
|
||||
}
|
||||
|
||||
bool
|
||||
xbps_remove_pkgname_from_array(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *name)
|
||||
bool HIDDEN
|
||||
xbps_remove_pkgname_from_array(prop_array_t array, const char *str)
|
||||
{
|
||||
return remove_obj_from_array(xhp, array, name, 1, NULL);
|
||||
return remove_obj_from_array(array, str, 1);
|
||||
}
|
||||
|
||||
bool
|
||||
xbps_remove_pkg_from_array_by_name(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *name,
|
||||
const char *targetarch)
|
||||
bool HIDDEN
|
||||
xbps_remove_pkg_from_array_by_name(prop_array_t array, const char *str)
|
||||
{
|
||||
return remove_obj_from_array(xhp, array, name, 2, targetarch);
|
||||
return remove_obj_from_array(array, str, 2);
|
||||
}
|
||||
|
||||
bool
|
||||
xbps_remove_pkg_from_array_by_pkgver(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *pkgver,
|
||||
const char *targetarch)
|
||||
bool HIDDEN
|
||||
xbps_remove_pkg_from_array_by_pkgver(prop_array_t array, const char *str)
|
||||
{
|
||||
return remove_obj_from_array(xhp, array, pkgver, 3, targetarch);
|
||||
return remove_obj_from_array(array, str, 3);
|
||||
}
|
||||
|
||||
bool
|
||||
xbps_remove_pkg_from_array_by_pattern(struct xbps_handle *xhp,
|
||||
prop_array_t array,
|
||||
const char *p,
|
||||
const char *targetarch)
|
||||
bool HIDDEN
|
||||
xbps_remove_pkg_from_array_by_pattern(prop_array_t array, const char *str)
|
||||
{
|
||||
return remove_obj_from_array(xhp, array, p, 4, targetarch);
|
||||
return remove_obj_from_array(array, str, 4);
|
||||
}
|
||||
|
||||
@@ -1,345 +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 "xbps_api_impl.h"
|
||||
|
||||
/**
|
||||
* @file lib/repository_pool_find.c
|
||||
* @brief Repository pool routines
|
||||
* @defgroup repopool Repository pool functions
|
||||
*/
|
||||
struct repo_pool_fpkg {
|
||||
prop_dictionary_t pkgd;
|
||||
const char *pattern;
|
||||
const char *bestpkgver;
|
||||
bool bypattern;
|
||||
bool exact;
|
||||
};
|
||||
|
||||
static int
|
||||
repo_find_virtualpkg_cb(struct xbps_handle *xhp,
|
||||
struct xbps_rpool_index *rpi,
|
||||
void *arg,
|
||||
bool *done)
|
||||
{
|
||||
struct repo_pool_fpkg *rpf = arg;
|
||||
|
||||
(void)xhp;
|
||||
|
||||
if (rpf->bypattern) {
|
||||
rpf->pkgd =
|
||||
xbps_find_virtualpkg_in_array_by_pattern(xhp, rpi->repo,
|
||||
rpf->pattern);
|
||||
} else {
|
||||
rpf->pkgd =
|
||||
xbps_find_virtualpkg_in_array_by_name(xhp, rpi->repo,
|
||||
rpf->pattern);
|
||||
}
|
||||
if (rpf->pkgd) {
|
||||
prop_dictionary_set_cstring_nocopy(rpf->pkgd,
|
||||
"repository", rpi->uri);
|
||||
*done = true;
|
||||
return 0;
|
||||
}
|
||||
/* not found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
repo_find_virtualpkg_conf_cb(struct xbps_handle *xhp,
|
||||
struct xbps_rpool_index *rpi,
|
||||
void *arg,
|
||||
bool *done)
|
||||
{
|
||||
struct repo_pool_fpkg *rpf = arg;
|
||||
|
||||
if (rpf->bypattern) {
|
||||
rpf->pkgd =
|
||||
xbps_find_virtualpkg_conf_in_array_by_pattern(xhp,
|
||||
rpi->repo, rpf->pattern);
|
||||
} else {
|
||||
rpf->pkgd =
|
||||
xbps_find_virtualpkg_conf_in_array_by_name(xhp,
|
||||
rpi->repo, rpf->pattern);
|
||||
}
|
||||
if (rpf->pkgd) {
|
||||
prop_dictionary_set_cstring_nocopy(rpf->pkgd,
|
||||
"repository", rpi->uri);
|
||||
*done = true;
|
||||
return 0;
|
||||
}
|
||||
/* not found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
repo_find_pkg_cb(struct xbps_handle *xhp,
|
||||
struct xbps_rpool_index *rpi,
|
||||
void *arg,
|
||||
bool *done)
|
||||
{
|
||||
struct repo_pool_fpkg *rpf = arg;
|
||||
|
||||
(void)xhp;
|
||||
|
||||
if (rpf->exact) {
|
||||
/* exact match by pkgver */
|
||||
rpf->pkgd = xbps_find_pkg_in_array_by_pkgver(xhp, rpi->repo,
|
||||
rpf->pattern, NULL);
|
||||
} else if (rpf->bypattern) {
|
||||
/* match by pkgpattern in pkgver*/
|
||||
rpf->pkgd = xbps_find_pkg_in_array_by_pattern(xhp, rpi->repo,
|
||||
rpf->pattern, NULL);
|
||||
} else {
|
||||
/* match by pkgname */
|
||||
rpf->pkgd = xbps_find_pkg_in_array_by_name(xhp, rpi->repo,
|
||||
rpf->pattern, NULL);
|
||||
}
|
||||
if (rpf->pkgd) {
|
||||
/*
|
||||
* Package dictionary found, add the "repository"
|
||||
* object with the URI.
|
||||
*/
|
||||
prop_dictionary_set_cstring_nocopy(rpf->pkgd,
|
||||
"repository", rpi->uri);
|
||||
*done = true;
|
||||
return 0;
|
||||
}
|
||||
/* Not found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
repo_find_best_pkg_cb(struct xbps_handle *xhp,
|
||||
struct xbps_rpool_index *rpi,
|
||||
void *arg,
|
||||
bool *done)
|
||||
{
|
||||
struct repo_pool_fpkg *rpf = arg;
|
||||
const char *repopkgver;
|
||||
prop_dictionary_t pkgd;
|
||||
|
||||
(void)done;
|
||||
(void)xhp;
|
||||
|
||||
if (rpf->bypattern) {
|
||||
pkgd = xbps_find_pkg_in_array_by_pattern(xhp, rpi->repo,
|
||||
rpf->pattern, NULL);
|
||||
} else {
|
||||
pkgd = xbps_find_pkg_in_array_by_name(xhp, rpi->repo,
|
||||
rpf->pattern, NULL);
|
||||
}
|
||||
if (pkgd == NULL) {
|
||||
if (errno && errno != ENOENT)
|
||||
return errno;
|
||||
|
||||
xbps_dbg_printf(xhp,
|
||||
"[rpool] Package '%s' not found in repository "
|
||||
"'%s'.\n", rpf->pattern, rpi->uri);
|
||||
return 0;
|
||||
}
|
||||
prop_dictionary_get_cstring_nocopy(pkgd,
|
||||
"pkgver", &repopkgver);
|
||||
if (rpf->bestpkgver == NULL) {
|
||||
xbps_dbg_printf(xhp,
|
||||
"[rpool] Found best match '%s' (%s).\n",
|
||||
repopkgver, rpi->uri);
|
||||
rpf->pkgd = pkgd;
|
||||
prop_dictionary_set_cstring_nocopy(rpf->pkgd,
|
||||
"repository", rpi->uri);
|
||||
rpf->bestpkgver = repopkgver;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Compare current stored version against new
|
||||
* version from current package in repository.
|
||||
*/
|
||||
if (xbps_cmpver(repopkgver, rpf->bestpkgver) == 1) {
|
||||
xbps_dbg_printf(xhp,
|
||||
"[rpool] Found best match '%s' (%s).\n",
|
||||
repopkgver, rpi->uri);
|
||||
rpf->pkgd = pkgd;
|
||||
prop_dictionary_set_cstring_nocopy(rpf->pkgd,
|
||||
"repository", rpi->uri);
|
||||
rpf->bestpkgver = repopkgver;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
BEST_PKG = 1,
|
||||
EXACT_PKG,
|
||||
VIRTUAL_PKG,
|
||||
VIRTUAL_CONF_PKG,
|
||||
REAL_PKG
|
||||
} pkg_repo_type_t;
|
||||
|
||||
static prop_dictionary_t
|
||||
repo_find_pkg(struct xbps_handle *xhp,
|
||||
const char *pkg,
|
||||
bool bypattern,
|
||||
pkg_repo_type_t type)
|
||||
{
|
||||
struct repo_pool_fpkg rpf;
|
||||
int rv = 0;
|
||||
|
||||
rpf.pattern = pkg;
|
||||
rpf.bypattern = bypattern;
|
||||
rpf.exact = false;
|
||||
rpf.pkgd = NULL;
|
||||
rpf.bestpkgver = NULL;
|
||||
|
||||
switch (type) {
|
||||
case EXACT_PKG:
|
||||
/*
|
||||
* Find exact pkg version.
|
||||
*/
|
||||
rpf.exact = true;
|
||||
rv = xbps_rpool_foreach(xhp, repo_find_pkg_cb, &rpf);
|
||||
break;
|
||||
case BEST_PKG:
|
||||
/*
|
||||
* Find best pkg version.
|
||||
*/
|
||||
rv = xbps_rpool_foreach(xhp, repo_find_best_pkg_cb, &rpf);
|
||||
break;
|
||||
case VIRTUAL_PKG:
|
||||
/*
|
||||
* Find virtual pkg.
|
||||
*/
|
||||
rv = xbps_rpool_foreach(xhp, repo_find_virtualpkg_cb, &rpf);
|
||||
break;
|
||||
case VIRTUAL_CONF_PKG:
|
||||
/*
|
||||
* Find virtual pkg as specified in configuration file.
|
||||
*/
|
||||
rv = xbps_rpool_foreach(xhp, repo_find_virtualpkg_conf_cb, &rpf);
|
||||
break;
|
||||
case REAL_PKG:
|
||||
/*
|
||||
* Find real pkg.
|
||||
*/
|
||||
rv = xbps_rpool_foreach(xhp, repo_find_pkg_cb, &rpf);
|
||||
break;
|
||||
}
|
||||
if (rv != 0) {
|
||||
errno = rv;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rpf.pkgd;
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_rpool_find_virtualpkg(struct xbps_handle *xhp,
|
||||
const char *pkg,
|
||||
bool bypattern)
|
||||
{
|
||||
assert(pkg != NULL);
|
||||
|
||||
return repo_find_pkg(xhp, pkg, bypattern, VIRTUAL_PKG);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_rpool_find_virtualpkg_conf(struct xbps_handle *xhp,
|
||||
const char *pkg,
|
||||
bool bypattern)
|
||||
{
|
||||
assert(pkg != NULL);
|
||||
|
||||
return repo_find_pkg(xhp, pkg, bypattern, VIRTUAL_CONF_PKG);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_rpool_find_pkg(struct xbps_handle *xhp,
|
||||
const char *pkg,
|
||||
bool bypattern,
|
||||
bool best)
|
||||
{
|
||||
assert(pkg != NULL);
|
||||
|
||||
if (best)
|
||||
return repo_find_pkg(xhp, pkg, bypattern, BEST_PKG);
|
||||
|
||||
return repo_find_pkg(xhp, pkg, bypattern, REAL_PKG);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_rpool_find_pkg_exact(struct xbps_handle *xhp, const char *pkgver)
|
||||
{
|
||||
assert(pkgver != NULL);
|
||||
|
||||
return repo_find_pkg(xhp, pkgver, false, EXACT_PKG);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_rpool_dictionary_metadata_plist(struct xbps_handle *xhp,
|
||||
const char *pattern,
|
||||
const char *plistf)
|
||||
{
|
||||
prop_dictionary_t pkgd = NULL, plistd = NULL;
|
||||
const char *repoloc;
|
||||
char *url;
|
||||
|
||||
assert(pattern != NULL);
|
||||
assert(plistf != NULL);
|
||||
/*
|
||||
* Iterate over the the repository pool and search for a plist file
|
||||
* in the binary package matching `pattern'. The plist file will be
|
||||
* internalized to a proplib dictionary.
|
||||
*
|
||||
* The first repository that has it wins and the loop is stopped.
|
||||
* This will work locally and remotely, thanks to libarchive and
|
||||
* libfetch!
|
||||
*/
|
||||
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)
|
||||
goto out;
|
||||
|
||||
prop_dictionary_get_cstring_nocopy(pkgd, "repository", &repoloc);
|
||||
url = xbps_path_from_repository_uri(xhp, pkgd, repoloc);
|
||||
if (url == NULL) {
|
||||
errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
plistd = xbps_dictionary_metadata_plist_by_url(url, plistf);
|
||||
free(url);
|
||||
|
||||
out:
|
||||
if (plistd == NULL)
|
||||
errno = ENOENT;
|
||||
|
||||
return plistd;
|
||||
}
|
||||
211
lib/rindex_get.c
Normal file
211
lib/rindex_get.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/*-
|
||||
* 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 "xbps_api_impl.h"
|
||||
|
||||
/**
|
||||
* @file lib/rindex_get.c
|
||||
* @brief Repository index get routines
|
||||
* @defgroup rindex_get Repository index get routines
|
||||
*/
|
||||
static prop_dictionary_t
|
||||
match_pkg_by_pkgver(prop_dictionary_t repod, const char *p)
|
||||
{
|
||||
prop_dictionary_t d = NULL;
|
||||
const char *pkgver;
|
||||
char *pkgname;
|
||||
|
||||
/* exact match by pkgver */
|
||||
if ((pkgname = xbps_pkg_name(p)) == NULL)
|
||||
return NULL;
|
||||
|
||||
d = prop_dictionary_get(repod, pkgname);
|
||||
if (d) {
|
||||
prop_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver);
|
||||
if (strcmp(pkgver, p))
|
||||
d = NULL;
|
||||
}
|
||||
|
||||
free(pkgname);
|
||||
return d;
|
||||
}
|
||||
|
||||
static prop_dictionary_t
|
||||
match_pkg_by_pattern(prop_dictionary_t repod, const char *p)
|
||||
{
|
||||
prop_dictionary_t d = NULL;
|
||||
const char *pkgver;
|
||||
char *pkgname;
|
||||
|
||||
/* match by pkgpattern in pkgver */
|
||||
if ((pkgname = xbps_pkgpattern_name(p)) == NULL) {
|
||||
if ((pkgname = xbps_pkg_name(p)))
|
||||
return match_pkg_by_pkgver(repod, p);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
d = prop_dictionary_get(repod, pkgname);
|
||||
if (d) {
|
||||
prop_dictionary_get_cstring_nocopy(d, "pkgver", &pkgver);
|
||||
assert(pkgver);
|
||||
if (!xbps_pkgpattern_match(pkgver, p))
|
||||
d = NULL;
|
||||
}
|
||||
|
||||
free(pkgname);
|
||||
return d;
|
||||
}
|
||||
|
||||
const char HIDDEN *
|
||||
vpkg_user_conf(struct xbps_handle *xhp,
|
||||
const char *vpkg,
|
||||
bool bypattern)
|
||||
{
|
||||
const char *vpkgver, *pkg = NULL;
|
||||
char *vpkgname = NULL, *tmp;
|
||||
size_t i, j, cnt;
|
||||
|
||||
if (xhp->cfg == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((cnt = cfg_size(xhp->cfg, "virtual-package")) == 0) {
|
||||
/* no virtual packages configured */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
cfg_t *sec = cfg_getnsec(xhp->cfg, "virtual-package", i);
|
||||
for (j = 0; j < cfg_size(sec, "targets"); j++) {
|
||||
tmp = NULL;
|
||||
vpkgver = cfg_getnstr(sec, "targets", j);
|
||||
if (strchr(vpkgver, '_') == NULL) {
|
||||
tmp = xbps_xasprintf("%s_1", vpkgver);
|
||||
vpkgname = xbps_pkg_name(tmp);
|
||||
free(tmp);
|
||||
} else {
|
||||
vpkgname = xbps_pkg_name(vpkgver);
|
||||
}
|
||||
if (vpkgname == NULL)
|
||||
break;
|
||||
if (bypattern) {
|
||||
if (!xbps_pkgpattern_match(vpkgver, vpkg)) {
|
||||
free(vpkgname);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(vpkg, vpkgname)) {
|
||||
free(vpkgname);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* virtual package matched in conffile */
|
||||
pkg = cfg_title(sec);
|
||||
xbps_dbg_printf(xhp,
|
||||
"matched vpkg in conf `%s' for %s\n",
|
||||
pkg, vpkg);
|
||||
free(vpkgname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_rindex_get_virtualpkg(struct xbps_rindex *rpi, const char *pkg)
|
||||
{
|
||||
prop_array_t allkeys;
|
||||
prop_dictionary_keysym_t ksym;
|
||||
prop_dictionary_t pkgd = NULL;
|
||||
const char *vpkg;
|
||||
size_t i;
|
||||
bool found = false, bypattern = false;
|
||||
|
||||
if (xbps_pkgpattern_version(pkg))
|
||||
bypattern = true;
|
||||
|
||||
/* Try matching vpkg from configuration files */
|
||||
vpkg = vpkg_user_conf(rpi->xhp, pkg, bypattern);
|
||||
if (vpkg != NULL) {
|
||||
if (xbps_pkgpattern_version(vpkg))
|
||||
pkgd = match_pkg_by_pattern(rpi->repod, vpkg);
|
||||
else if (xbps_pkg_version(vpkg))
|
||||
pkgd = match_pkg_by_pkgver(rpi->repod, vpkg);
|
||||
else
|
||||
pkgd = prop_dictionary_get(rpi->repod, vpkg);
|
||||
|
||||
if (pkgd) {
|
||||
found = true;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* ... otherwise match the first one in dictionary */
|
||||
allkeys = prop_dictionary_all_keys(rpi->repod);
|
||||
for (i = 0; i < prop_array_count(allkeys); i++) {
|
||||
ksym = prop_array_get(allkeys, i);
|
||||
pkgd = prop_dictionary_get_keysym(rpi->repod, ksym);
|
||||
if (xbps_match_virtual_pkg_in_dict(pkgd, pkg, bypattern)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prop_object_release(allkeys);
|
||||
|
||||
out:
|
||||
if (found) {
|
||||
prop_dictionary_set_cstring_nocopy(pkgd,
|
||||
"repository", rpi->uri);
|
||||
return pkgd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_rindex_get_pkg(struct xbps_rindex *rpi, const char *pkg)
|
||||
{
|
||||
prop_dictionary_t pkgd = NULL;
|
||||
|
||||
if (xbps_pkgpattern_version(pkg))
|
||||
pkgd = match_pkg_by_pattern(rpi->repod, pkg);
|
||||
else if (xbps_pkg_version(pkg))
|
||||
pkgd = match_pkg_by_pkgver(rpi->repod, pkg);
|
||||
else
|
||||
pkgd = prop_dictionary_get(rpi->repod, pkg);
|
||||
|
||||
if (pkgd) {
|
||||
prop_dictionary_set_cstring_nocopy(pkgd,
|
||||
"repository", rpi->uri);
|
||||
return pkgd;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -32,11 +32,10 @@
|
||||
|
||||
static int
|
||||
store_dependency(struct xbps_handle *xhp,
|
||||
prop_array_t unsorted,
|
||||
prop_dictionary_t repo_pkgd,
|
||||
pkg_state_t repo_pkg_state,
|
||||
size_t *depth)
|
||||
pkg_state_t repo_pkg_state)
|
||||
{
|
||||
prop_array_t unsorted;
|
||||
int rv;
|
||||
/*
|
||||
* Overwrite package state in dictionary with same state than the
|
||||
@@ -50,27 +49,11 @@ store_dependency(struct xbps_handle *xhp,
|
||||
if (!prop_dictionary_set_bool(repo_pkgd, "automatic-install", true))
|
||||
return EINVAL;
|
||||
/*
|
||||
* Add the dictionary into the array.
|
||||
* Add the dictionary into the unsorted queue.
|
||||
*/
|
||||
unsorted = prop_dictionary_get(xhp->transd, "unsorted_deps");
|
||||
if (!prop_array_add(unsorted, repo_pkgd))
|
||||
return EINVAL;
|
||||
prop_array_add(unsorted, repo_pkgd);
|
||||
xbps_dbg_printf_append(xhp, "(added)\n");
|
||||
|
||||
if (xhp->flags & XBPS_FLAG_DEBUG) {
|
||||
size_t x;
|
||||
const char *repo, *pkgver;
|
||||
|
||||
prop_dictionary_get_cstring_nocopy(repo_pkgd,
|
||||
"repository", &repo);
|
||||
prop_dictionary_get_cstring_nocopy(repo_pkgd,
|
||||
"pkgver", &pkgver);
|
||||
xbps_dbg_printf(xhp, " ");
|
||||
for (x = 0; x < *depth; x++)
|
||||
xbps_dbg_printf_append(xhp, " ");
|
||||
|
||||
xbps_dbg_printf_append(xhp, "%s: added into "
|
||||
"the transaction (%s).\n", pkgver, repo);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -164,16 +147,16 @@ out:
|
||||
|
||||
static int
|
||||
find_repo_deps(struct xbps_handle *xhp,
|
||||
prop_array_t unsorted, /* array of unsorted deps */
|
||||
prop_array_t pkg_rdeps_array, /* current pkg rundeps array */
|
||||
const char *curpkg, /* current pkgver */
|
||||
size_t *depth) /* max recursion depth */
|
||||
{
|
||||
prop_dictionary_t curpkgd, tmpd;
|
||||
prop_array_t curpkgrdeps, unsorted;
|
||||
prop_array_t curpkgrdeps;
|
||||
pkg_state_t state;
|
||||
size_t i, x;
|
||||
const char *reqpkg, *pkgver_q, *reason = NULL;
|
||||
char *pkgname;
|
||||
int rv = 0;
|
||||
|
||||
if (*depth >= MAX_DEPTH)
|
||||
@@ -196,17 +179,10 @@ find_repo_deps(struct xbps_handle *xhp,
|
||||
* Pass 1: check if required dependency is already installed
|
||||
* and its version is fully matched.
|
||||
*/
|
||||
if (((pkgname = xbps_pkgpattern_name(reqpkg)) == NULL) &&
|
||||
((pkgname = xbps_pkg_name(reqpkg)) == NULL)) {
|
||||
rv = EINVAL;
|
||||
xbps_dbg_printf(xhp, "failed to get "
|
||||
"pkgname from `%s'!", reqpkg);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Look for a real package installed...
|
||||
*/
|
||||
tmpd = xbps_find_pkg_dict_installed(xhp, pkgname, false);
|
||||
tmpd = xbps_pkgdb_get_pkg(xhp, reqpkg);
|
||||
if (tmpd == NULL) {
|
||||
if (errno && errno != ENOENT) {
|
||||
/* error */
|
||||
@@ -220,11 +196,7 @@ find_repo_deps(struct xbps_handle *xhp,
|
||||
* real package not installed, try looking for
|
||||
* a virtual package instead.
|
||||
*/
|
||||
tmpd = xbps_find_virtualpkg_dict_installed(xhp,
|
||||
pkgname, false);
|
||||
}
|
||||
free(pkgname);
|
||||
if (tmpd == NULL) {
|
||||
tmpd = xbps_pkgdb_get_virtualpkg(xhp, reqpkg);
|
||||
if (errno && errno != ENOENT) {
|
||||
/* error */
|
||||
rv = errno;
|
||||
@@ -233,8 +205,10 @@ find_repo_deps(struct xbps_handle *xhp,
|
||||
reqpkg, strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tmpd == NULL) {
|
||||
/* Required pkgdep not installed */
|
||||
xbps_dbg_printf_append(xhp, "not installed. ");
|
||||
xbps_dbg_printf_append(xhp, "not installed ");
|
||||
reason = "install";
|
||||
state = XBPS_PKG_STATE_NOT_INSTALLED;
|
||||
} else {
|
||||
@@ -282,7 +256,7 @@ find_repo_deps(struct xbps_handle *xhp,
|
||||
", must be configured.\n",
|
||||
pkgver_q);
|
||||
reason = "configure";
|
||||
} else {
|
||||
} else if (state == XBPS_PKG_STATE_INSTALLED) {
|
||||
/*
|
||||
* Package matches the dependency
|
||||
* pattern and is fully installed,
|
||||
@@ -304,20 +278,11 @@ find_repo_deps(struct xbps_handle *xhp,
|
||||
* Pass 2: check if required dependency has been already
|
||||
* added in the transaction dictionary.
|
||||
*/
|
||||
unsorted = prop_dictionary_get(xhp->transd, "unsorted_deps");
|
||||
if (((curpkgd = xbps_find_pkg_in_array_by_pattern(xhp, unsorted, reqpkg, NULL)) == NULL) &&
|
||||
((curpkgd = xbps_find_virtualpkg_conf_in_array_by_pattern(xhp, unsorted, reqpkg)) == NULL) &&
|
||||
((curpkgd = xbps_find_virtualpkg_in_array_by_pattern(xhp, unsorted, reqpkg)) == NULL)) {
|
||||
/* error matching required pkgdep */
|
||||
if (errno && errno != ENOENT) {
|
||||
rv = errno;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if ((curpkgd = xbps_find_pkg_in_array(unsorted, reqpkg)) ||
|
||||
(curpkgd = xbps_find_virtualpkg_in_array(xhp, unsorted, reqpkg))) {
|
||||
prop_dictionary_get_cstring_nocopy(curpkgd,
|
||||
"pkgver", &pkgver_q);
|
||||
xbps_dbg_printf_append(xhp, " (%s queued "
|
||||
"in transaction).\n", pkgver_q);
|
||||
xbps_dbg_printf_append(xhp, " (%s queued)\n", pkgver_q);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@@ -325,9 +290,8 @@ find_repo_deps(struct xbps_handle *xhp,
|
||||
* If dependency does not match add pkg into the missing
|
||||
* deps array and pass to next one.
|
||||
*/
|
||||
if (((curpkgd = xbps_rpool_find_virtualpkg_conf(xhp, reqpkg, true)) == NULL) &&
|
||||
((curpkgd = xbps_rpool_find_pkg(xhp, reqpkg, true, true)) == NULL) &&
|
||||
((curpkgd = xbps_rpool_find_virtualpkg(xhp, reqpkg, true)) == NULL)) {
|
||||
if (((curpkgd = xbps_rpool_get_pkg(xhp, reqpkg)) == NULL) &&
|
||||
((curpkgd = xbps_rpool_get_virtualpkg(xhp, reqpkg)) == NULL)) {
|
||||
/* pkg not found, there was some error */
|
||||
if (errno && errno != ENOENT) {
|
||||
xbps_dbg_printf(xhp, "failed to find pkg "
|
||||
@@ -359,12 +323,12 @@ find_repo_deps(struct xbps_handle *xhp,
|
||||
/*
|
||||
* Check if package has matched conflicts.
|
||||
*/
|
||||
xbps_pkg_find_conflicts(xhp, curpkgd);
|
||||
xbps_pkg_find_conflicts(xhp, unsorted, curpkgd);
|
||||
/*
|
||||
* Package is on repo, add it into the transaction dictionary.
|
||||
*/
|
||||
prop_dictionary_set_cstring_nocopy(curpkgd, "transaction", reason);
|
||||
rv = store_dependency(xhp, curpkgd, state, depth);
|
||||
rv = store_dependency(xhp, unsorted, curpkgd, state);
|
||||
if (rv != 0) {
|
||||
xbps_dbg_printf(xhp, "store_dependency failed for "
|
||||
"`%s': %s\n", reqpkg, strerror(rv));
|
||||
@@ -389,7 +353,8 @@ find_repo_deps(struct xbps_handle *xhp,
|
||||
* Recursively find rundeps for current pkg dictionary.
|
||||
*/
|
||||
(*depth)++;
|
||||
rv = find_repo_deps(xhp, curpkgrdeps, pkgver_q, depth);
|
||||
rv = find_repo_deps(xhp, unsorted, curpkgrdeps,
|
||||
pkgver_q, depth);
|
||||
if (rv != 0) {
|
||||
xbps_dbg_printf(xhp, "Error checking %s for rundeps: %s\n",
|
||||
reqpkg, strerror(rv));
|
||||
@@ -402,8 +367,9 @@ find_repo_deps(struct xbps_handle *xhp,
|
||||
}
|
||||
|
||||
int HIDDEN
|
||||
xbps_repository_find_pkg_deps(struct xbps_handle *xhp,
|
||||
prop_dictionary_t repo_pkgd)
|
||||
xbps_repository_find_deps(struct xbps_handle *xhp,
|
||||
prop_array_t unsorted,
|
||||
prop_dictionary_t repo_pkgd)
|
||||
{
|
||||
prop_array_t pkg_rdeps;
|
||||
const char *pkgver;
|
||||
@@ -421,5 +387,5 @@ xbps_repository_find_pkg_deps(struct xbps_handle *xhp,
|
||||
* This will find direct and indirect deps, if any of them is not
|
||||
* there it will be added into the missing_deps array.
|
||||
*/
|
||||
return find_repo_deps(xhp, pkg_rdeps, pkgver, &depth);
|
||||
return find_repo_deps(xhp, unsorted, pkg_rdeps, pkgver, &depth);
|
||||
}
|
||||
@@ -59,7 +59,6 @@ xbps_get_remote_repo_string(const char *uri)
|
||||
* becomes:
|
||||
*
|
||||
* http___nocturno_local_8080_repo_x86_64
|
||||
*
|
||||
*/
|
||||
if (url->port != 0)
|
||||
p = xbps_xasprintf("%s://%s:%u%s", url->scheme,
|
||||
@@ -81,10 +80,8 @@ xbps_get_remote_repo_string(const char *uri)
|
||||
* Returns -1 on error, 0 if transfer was not necessary (local/remote
|
||||
* size and/or mtime match) and 1 if downloaded successfully.
|
||||
*/
|
||||
int
|
||||
xbps_repository_sync_pkg_index(struct xbps_handle *xhp,
|
||||
const char *uri,
|
||||
const char *plistf)
|
||||
int HIDDEN
|
||||
xbps_rindex_sync(struct xbps_handle *xhp, const char *uri, const char *plistf)
|
||||
{
|
||||
prop_array_t array;
|
||||
const char *fetchstr = NULL;
|
||||
@@ -95,7 +92,7 @@ xbps_repository_sync_pkg_index(struct xbps_handle *xhp,
|
||||
rpidx = uri_fixedp = lrepodir = lrepofile = NULL;
|
||||
|
||||
/* ignore non remote repositories */
|
||||
if (!xbps_check_is_repository_uri_remote(uri))
|
||||
if (!xbps_repository_is_remote(uri))
|
||||
return 0;
|
||||
|
||||
uri_fixedp = xbps_get_remote_repo_string(uri);
|
||||
@@ -42,8 +42,7 @@
|
||||
int HIDDEN
|
||||
xbps_rpool_init(struct xbps_handle *xhp)
|
||||
{
|
||||
prop_dictionary_t d = NULL;
|
||||
prop_array_t array;
|
||||
prop_dictionary_t repod, d = NULL;
|
||||
size_t i, ntotal = 0, nmissing = 0;
|
||||
const char *repouri;
|
||||
char *plist;
|
||||
@@ -75,30 +74,30 @@ xbps_rpool_init(struct xbps_handle *xhp)
|
||||
nmissing++;
|
||||
continue;
|
||||
}
|
||||
array = prop_array_internalize_from_zfile(plist);
|
||||
repod = prop_dictionary_internalize_from_zfile(plist);
|
||||
free(plist);
|
||||
assert(array);
|
||||
assert(repod);
|
||||
/*
|
||||
* Register repository into the array.
|
||||
*/
|
||||
if ((d = prop_dictionary_create()) == NULL) {
|
||||
rv = ENOMEM;
|
||||
prop_object_release(array);
|
||||
prop_object_release(repod);
|
||||
goto out;
|
||||
}
|
||||
if (!prop_dictionary_set_cstring_nocopy(d, "uri", repouri)) {
|
||||
rv = EINVAL;
|
||||
prop_object_release(array);
|
||||
prop_object_release(repod);
|
||||
prop_object_release(d);
|
||||
goto out;
|
||||
}
|
||||
if (!prop_dictionary_set(d, "index", array)) {
|
||||
if (!prop_dictionary_set(d, "index", repod)) {
|
||||
rv = EINVAL;
|
||||
prop_object_release(array);
|
||||
prop_object_release(repod);
|
||||
prop_object_release(d);
|
||||
goto out;
|
||||
}
|
||||
prop_object_release(array);
|
||||
prop_object_release(repod);
|
||||
if (!prop_array_add(xhp->repo_pool, d)) {
|
||||
rv = EINVAL;
|
||||
prop_object_release(d);
|
||||
@@ -115,7 +114,7 @@ xbps_rpool_init(struct xbps_handle *xhp)
|
||||
prop_array_make_immutable(xhp->repo_pool);
|
||||
xbps_dbg_printf(xhp, "[rpool] initialized ok.\n");
|
||||
out:
|
||||
if (rv != 0)
|
||||
if (rv != 0)
|
||||
xbps_rpool_release(xhp);
|
||||
|
||||
return rv;
|
||||
@@ -161,7 +160,7 @@ xbps_rpool_sync(struct xbps_handle *xhp, const char *file, const char *uri)
|
||||
if (uri && strcmp(repouri, uri))
|
||||
continue;
|
||||
|
||||
if (xbps_repository_sync_pkg_index(xhp, repouri, file) == -1) {
|
||||
if (xbps_rindex_sync(xhp, repouri, file) == -1) {
|
||||
xbps_dbg_printf(xhp,
|
||||
"[rpool] `%s' failed to fetch `%s': %s\n",
|
||||
repouri, file,
|
||||
@@ -175,11 +174,11 @@ xbps_rpool_sync(struct xbps_handle *xhp, const char *file, const char *uri)
|
||||
|
||||
int
|
||||
xbps_rpool_foreach(struct xbps_handle *xhp,
|
||||
int (*fn)(struct xbps_handle *, struct xbps_rpool_index *, void *, bool *),
|
||||
int (*fn)(struct xbps_rindex *, void *, bool *),
|
||||
void *arg)
|
||||
{
|
||||
prop_dictionary_t d;
|
||||
struct xbps_rpool_index rpi;
|
||||
struct xbps_rindex rpi;
|
||||
size_t i;
|
||||
int rv = 0;
|
||||
bool done = false;
|
||||
@@ -201,8 +200,9 @@ xbps_rpool_foreach(struct xbps_handle *xhp,
|
||||
for (i = 0; i < prop_array_count(xhp->repo_pool); i++) {
|
||||
d = prop_array_get(xhp->repo_pool, i);
|
||||
prop_dictionary_get_cstring_nocopy(d, "uri", &rpi.uri);
|
||||
rpi.repo = prop_dictionary_get(d, "index");
|
||||
rv = (*fn)(xhp, &rpi, arg, &done);
|
||||
rpi.repod = prop_dictionary_get(d, "index");
|
||||
rpi.xhp = xhp;
|
||||
rv = (*fn)(&rpi, arg, &done);
|
||||
if (rv != 0 || done)
|
||||
break;
|
||||
}
|
||||
226
lib/rpool_get.c
Normal file
226
lib/rpool_get.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/*-
|
||||
* 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 "xbps_api_impl.h"
|
||||
|
||||
/**
|
||||
* @file lib/rpool_get.c
|
||||
* @brief Repository pool functions
|
||||
* @defgroup repopool Repository pool functions
|
||||
*/
|
||||
struct rpool_fpkg {
|
||||
prop_dictionary_t pkgd;
|
||||
const char *pattern;
|
||||
const char *bestpkgver;
|
||||
bool best;
|
||||
};
|
||||
|
||||
static int
|
||||
find_virtualpkg_cb(struct xbps_rindex *rpi, void *arg, bool *done)
|
||||
{
|
||||
struct rpool_fpkg *rpf = arg;
|
||||
|
||||
rpf->pkgd = xbps_rindex_get_virtualpkg(rpi, rpf->pattern);
|
||||
if (rpf->pkgd) {
|
||||
/* found */
|
||||
*done = true;
|
||||
return 0;
|
||||
}
|
||||
/* not found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
find_pkg_cb(struct xbps_rindex *rpi, void *arg, bool *done)
|
||||
{
|
||||
struct rpool_fpkg *rpf = arg;
|
||||
|
||||
rpf->pkgd = xbps_rindex_get_pkg(rpi, rpf->pattern);
|
||||
if (rpf->pkgd) {
|
||||
/* found */
|
||||
*done = true;
|
||||
return 0;
|
||||
}
|
||||
/* Not found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
find_best_pkg_cb(struct xbps_rindex *rpi, void *arg, bool *done)
|
||||
{
|
||||
struct rpool_fpkg *rpf = arg;
|
||||
prop_dictionary_t pkgd;
|
||||
const char *repopkgver;
|
||||
|
||||
(void)done;
|
||||
|
||||
pkgd = xbps_rindex_get_pkg(rpi, rpf->pattern);
|
||||
if (pkgd == NULL) {
|
||||
if (errno && errno != ENOENT)
|
||||
return errno;
|
||||
|
||||
xbps_dbg_printf(rpi->xhp,
|
||||
"[rpool] Package '%s' not found in repository "
|
||||
"'%s'.\n", rpf->pattern, rpi->uri);
|
||||
return 0;
|
||||
}
|
||||
prop_dictionary_get_cstring_nocopy(pkgd,
|
||||
"pkgver", &repopkgver);
|
||||
if (rpf->bestpkgver == NULL) {
|
||||
xbps_dbg_printf(rpi->xhp,
|
||||
"[rpool] Found best match '%s' (%s).\n",
|
||||
repopkgver, rpi->uri);
|
||||
rpf->pkgd = pkgd;
|
||||
prop_dictionary_set_cstring_nocopy(rpf->pkgd,
|
||||
"repository", rpi->uri);
|
||||
rpf->bestpkgver = repopkgver;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Compare current stored version against new
|
||||
* version from current package in repository.
|
||||
*/
|
||||
if (xbps_cmpver(repopkgver, rpf->bestpkgver) == 1) {
|
||||
xbps_dbg_printf(rpi->xhp,
|
||||
"[rpool] Found best match '%s' (%s).\n",
|
||||
repopkgver, rpi->uri);
|
||||
rpf->pkgd = pkgd;
|
||||
prop_dictionary_set_cstring_nocopy(rpf->pkgd,
|
||||
"repository", rpi->uri);
|
||||
rpf->bestpkgver = repopkgver;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
BEST_PKG = 1,
|
||||
VIRTUAL_PKG,
|
||||
REAL_PKG
|
||||
} pkg_repo_type_t;
|
||||
|
||||
static prop_dictionary_t
|
||||
repo_find_pkg(struct xbps_handle *xhp,
|
||||
const char *pkg,
|
||||
pkg_repo_type_t type)
|
||||
{
|
||||
struct rpool_fpkg rpf;
|
||||
int rv = 0;
|
||||
|
||||
rpf.pattern = pkg;
|
||||
rpf.pkgd = NULL;
|
||||
rpf.bestpkgver = NULL;
|
||||
|
||||
switch (type) {
|
||||
case BEST_PKG:
|
||||
/*
|
||||
* Find best pkg version.
|
||||
*/
|
||||
rv = xbps_rpool_foreach(xhp, find_best_pkg_cb, &rpf);
|
||||
break;
|
||||
case VIRTUAL_PKG:
|
||||
/*
|
||||
* Find virtual pkg.
|
||||
*/
|
||||
rv = xbps_rpool_foreach(xhp, find_virtualpkg_cb, &rpf);
|
||||
break;
|
||||
case REAL_PKG:
|
||||
/*
|
||||
* Find real pkg.
|
||||
*/
|
||||
rv = xbps_rpool_foreach(xhp, find_pkg_cb, &rpf);
|
||||
break;
|
||||
}
|
||||
if (rv != 0) {
|
||||
errno = rv;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rpf.pkgd;
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_rpool_get_virtualpkg(struct xbps_handle *xhp, const char *pkg)
|
||||
{
|
||||
assert(xhp);
|
||||
assert(pkg);
|
||||
|
||||
return repo_find_pkg(xhp, pkg, VIRTUAL_PKG);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_rpool_get_pkg(struct xbps_handle *xhp, const char *pkg)
|
||||
{
|
||||
assert(xhp);
|
||||
assert(pkg);
|
||||
|
||||
if (!xbps_pkgpattern_version(pkg) && !xbps_pkg_version(pkg))
|
||||
return repo_find_pkg(xhp, pkg, BEST_PKG);
|
||||
|
||||
return repo_find_pkg(xhp, pkg, REAL_PKG);
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
xbps_rpool_get_pkg_plist(struct xbps_handle *xhp,
|
||||
const char *pkg,
|
||||
const char *plistf)
|
||||
{
|
||||
prop_dictionary_t pkgd = NULL, plistd = NULL;
|
||||
char *url;
|
||||
|
||||
assert(pkg != NULL);
|
||||
assert(plistf != NULL);
|
||||
/*
|
||||
* Iterate over the the repository pool and search for a plist file
|
||||
* in the binary package matching `pattern'. The plist file will be
|
||||
* internalized to a proplib dictionary.
|
||||
*
|
||||
* The first repository that has it wins and the loop is stopped.
|
||||
* This will work locally and remotely, thanks to libarchive and
|
||||
* libfetch!
|
||||
*/
|
||||
pkgd = xbps_rpool_get_pkg(xhp, pkg);
|
||||
if (pkgd == NULL)
|
||||
goto out;
|
||||
|
||||
url = xbps_repository_pkg_path(xhp, pkgd);
|
||||
if (url == NULL) {
|
||||
errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
plistd = xbps_get_pkg_plist_from_binpkg(url, plistf);
|
||||
free(url);
|
||||
|
||||
out:
|
||||
if (plistd == NULL)
|
||||
errno = ENOENT;
|
||||
|
||||
return plistd;
|
||||
}
|
||||
@@ -79,7 +79,7 @@ check_binpkgs_hash(struct xbps_handle *xhp, prop_object_iterator_t iter)
|
||||
prop_dictionary_get_cstring_nocopy(obj,
|
||||
"filename-sha256", &sha256);
|
||||
|
||||
binfile = xbps_path_from_repository_uri(xhp, obj, repoloc);
|
||||
binfile = xbps_repository_pkg_path(xhp, obj);
|
||||
if (binfile == NULL) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
@@ -124,7 +124,7 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter)
|
||||
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
|
||||
prop_dictionary_get_cstring_nocopy(obj, "filename", &filen);
|
||||
|
||||
binfile = xbps_path_from_repository_uri(xhp, obj, repoloc);
|
||||
binfile = xbps_repository_pkg_path(xhp, obj);
|
||||
if (binfile == NULL) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
@@ -199,7 +199,6 @@ xbps_transaction_commit(struct xbps_handle *xhp)
|
||||
{
|
||||
prop_object_t obj;
|
||||
prop_object_iterator_t iter;
|
||||
size_t i;
|
||||
const char *pkgname, *version, *pkgver, *tract;
|
||||
int rv = 0;
|
||||
bool update, install, sr;
|
||||
@@ -227,16 +226,7 @@ xbps_transaction_commit(struct xbps_handle *xhp)
|
||||
*/
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_TRANS_RUN, 0, NULL, NULL, NULL);
|
||||
|
||||
i = 0;
|
||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||
if ((xhp->transaction_frequency_flush > 0) &&
|
||||
(++i >= xhp->transaction_frequency_flush)) {
|
||||
rv = xbps_pkgdb_update(xhp, true);
|
||||
if (rv != 0 && rv != ENOENT)
|
||||
goto out;
|
||||
|
||||
i = 0;
|
||||
}
|
||||
update = false;
|
||||
prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract);
|
||||
prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
|
||||
@@ -252,7 +242,7 @@ xbps_transaction_commit(struct xbps_handle *xhp)
|
||||
prop_dictionary_get_bool(obj, "remove-and-update",
|
||||
&update);
|
||||
prop_dictionary_get_bool(obj, "softreplace", &sr);
|
||||
rv = xbps_remove_pkg(xhp, pkgname, version, update, sr);
|
||||
rv = xbps_remove_pkg(xhp, pkgver, update, sr);
|
||||
if (rv != 0) {
|
||||
xbps_dbg_printf(xhp, "[trans] failed to "
|
||||
"remove %s-%s\n", pkgname, version);
|
||||
@@ -281,8 +271,7 @@ xbps_transaction_commit(struct xbps_handle *xhp)
|
||||
*/
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_UPDATE, 0,
|
||||
pkgname, version, NULL);
|
||||
rv = xbps_remove_pkg(xhp, pkgname, version,
|
||||
true, false);
|
||||
rv = xbps_remove_pkg(xhp, pkgver, true, false);
|
||||
if (rv != 0) {
|
||||
xbps_set_cb_state(xhp,
|
||||
XBPS_STATE_UPDATE_FAIL,
|
||||
@@ -305,34 +294,22 @@ xbps_transaction_commit(struct xbps_handle *xhp)
|
||||
/*
|
||||
* Register package.
|
||||
*/
|
||||
if ((rv = xbps_register_pkg(xhp, obj, false)) != 0)
|
||||
if ((rv = xbps_register_pkg(xhp, obj, true)) != 0)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
prop_object_iterator_reset(iter);
|
||||
|
||||
/* force a flush now packages were removed/unpacked */
|
||||
if ((rv = xbps_pkgdb_update(xhp, true)) != 0)
|
||||
goto out;
|
||||
|
||||
/* if there are no packages to install or update we are done */
|
||||
if (!update && !install)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Configure all unpacked packages.
|
||||
*/
|
||||
xbps_set_cb_state(xhp, XBPS_STATE_TRANS_CONFIGURE, 0, NULL, NULL, NULL);
|
||||
|
||||
i = 0;
|
||||
while ((obj = prop_object_iterator_next(iter)) != NULL) {
|
||||
if (xhp->transaction_frequency_flush > 0 &&
|
||||
++i >= xhp->transaction_frequency_flush) {
|
||||
if ((rv = xbps_pkgdb_update(xhp, true)) != 0)
|
||||
goto out;
|
||||
|
||||
i = 0;
|
||||
}
|
||||
|
||||
prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract);
|
||||
if ((strcmp(tract, "remove") == 0) ||
|
||||
(strcmp(tract, "configure") == 0))
|
||||
@@ -344,9 +321,12 @@ xbps_transaction_commit(struct xbps_handle *xhp)
|
||||
if (strcmp(tract, "update") == 0)
|
||||
update = true;
|
||||
|
||||
rv = xbps_configure_pkg(xhp, pkgname, false, update, false);
|
||||
if (rv != 0)
|
||||
rv = xbps_configure_pkg(xhp, pkgname, false, update, true);
|
||||
if (rv != 0) {
|
||||
xbps_dbg_printf(xhp, "%s: configure failed for "
|
||||
"%s-%s: %s\n", pkgname, version, strerror(rv));
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Notify client callback when a package has been
|
||||
* installed or updated.
|
||||
@@ -360,8 +340,6 @@ xbps_transaction_commit(struct xbps_handle *xhp)
|
||||
}
|
||||
}
|
||||
|
||||
/* Force a flush now that packages are configured */
|
||||
rv = xbps_pkgdb_update(xhp, true);
|
||||
out:
|
||||
prop_object_iterator_release(iter);
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ compute_transaction_stats(struct xbps_handle *xhp)
|
||||
*/
|
||||
if ((strcmp(tract, "remove") == 0) ||
|
||||
(strcmp(tract, "update") == 0)) {
|
||||
pkg_metad = xbps_metadir_get_pkgd(xhp, pkgname);
|
||||
pkg_metad = xbps_pkgdb_get_pkg_metadata(xhp, pkgname);
|
||||
if (pkg_metad == NULL)
|
||||
continue;
|
||||
prop_dictionary_get_uint64(pkg_metad,
|
||||
@@ -109,7 +109,7 @@ compute_transaction_stats(struct xbps_handle *xhp)
|
||||
prop_dictionary_get_uint64(obj,
|
||||
"installed_size", &tsize);
|
||||
instsize += tsize;
|
||||
if (xbps_check_is_repository_uri_remote(repo)) {
|
||||
if (xbps_repository_is_remote(repo)) {
|
||||
prop_dictionary_get_uint64(obj,
|
||||
"filename-size", &tsize);
|
||||
dlsize += tsize;
|
||||
@@ -263,7 +263,7 @@ xbps_transaction_prepare(struct xbps_handle *xhp)
|
||||
/*
|
||||
* Sort package dependencies if necessary.
|
||||
*/
|
||||
if ((rv = xbps_transaction_sort_pkg_deps(xhp)) != 0) {
|
||||
if ((rv = xbps_transaction_sort(xhp)) != 0) {
|
||||
prop_object_release(xhp->transd);
|
||||
xhp->transd = NULL;
|
||||
return rv;
|
||||
|
||||
@@ -58,8 +58,7 @@ enum {
|
||||
};
|
||||
|
||||
static int
|
||||
trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool bypattern,
|
||||
bool best, bool exact, int action)
|
||||
trans_find_pkg(struct xbps_handle *xhp, const char *pkg, int action)
|
||||
{
|
||||
prop_dictionary_t pkg_pkgdb, pkg_repod;
|
||||
prop_array_t unsorted;
|
||||
@@ -74,27 +73,17 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool bypattern,
|
||||
*/
|
||||
if (action == TRANS_INSTALL) {
|
||||
reason = "install";
|
||||
if (exact) {
|
||||
pkg_repod = xbps_rpool_find_pkg_exact(xhp, pkg);
|
||||
if (pkg_repod == NULL) {
|
||||
/* not found */
|
||||
return ENOENT;
|
||||
}
|
||||
} else {
|
||||
if (((pkg_repod = xbps_rpool_find_pkg(xhp, pkg, bypattern, best)) == NULL) &&
|
||||
((pkg_repod = xbps_rpool_find_virtualpkg_conf(xhp, pkg, bypattern)) == NULL) &&
|
||||
((pkg_repod = xbps_rpool_find_virtualpkg(xhp, pkg, bypattern)) == NULL)) {
|
||||
/* not found */
|
||||
return ENOENT;
|
||||
}
|
||||
if (((pkg_repod = xbps_rpool_get_pkg(xhp, pkg)) == NULL) &&
|
||||
((pkg_repod = xbps_rpool_get_virtualpkg(xhp, pkg)) == NULL)) {
|
||||
/* not found */
|
||||
return ENOENT;
|
||||
}
|
||||
} else {
|
||||
if ((pkg_pkgdb = xbps_pkgdb_get_pkgd(xhp, pkg, false)) == NULL)
|
||||
if ((pkg_pkgdb = xbps_pkgdb_get_pkg(xhp, pkg)) == NULL)
|
||||
return ENODEV;
|
||||
|
||||
reason = "update";
|
||||
pkg_repod = xbps_rpool_find_pkg(xhp, pkg, false, true);
|
||||
if (pkg_repod == NULL) {
|
||||
if ((pkg_repod = xbps_rpool_get_pkg(xhp, pkg)) == NULL) {
|
||||
/* not found */
|
||||
return ENOENT;
|
||||
}
|
||||
@@ -123,32 +112,25 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool bypattern,
|
||||
if ((rv = xbps_transaction_init(xhp)) != 0)
|
||||
return rv;
|
||||
|
||||
unsorted = prop_dictionary_get(xhp->transd, "unsorted_deps");
|
||||
/*
|
||||
* Find out if package has matched conflicts.
|
||||
*/
|
||||
xbps_pkg_find_conflicts(xhp, pkg_repod);
|
||||
xbps_pkg_find_conflicts(xhp, unsorted, pkg_repod);
|
||||
|
||||
unsorted = prop_dictionary_get(xhp->transd, "unsorted_deps");
|
||||
if (unsorted == NULL)
|
||||
return EINVAL;
|
||||
/*
|
||||
* Find out if package being updated matches the one already
|
||||
* in transaction, in that case ignore it.
|
||||
*/
|
||||
if (action == TRANS_UPDATE) {
|
||||
if (xbps_find_pkg_in_array_by_pkgver(xhp,
|
||||
unsorted, repopkgver, NULL)) {
|
||||
if (xbps_find_pkg_in_array(unsorted, repopkgver)) {
|
||||
xbps_dbg_printf(xhp, "[update] `%s' already queued in "
|
||||
"transaction.\n", repopkgver);
|
||||
return EEXIST;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare required package dependencies and add them into the
|
||||
* "unsorted" array in transaction dictionary.
|
||||
*/
|
||||
if ((rv = xbps_repository_find_pkg_deps(xhp, pkg_repod)) != 0)
|
||||
if ((rv = xbps_repository_find_deps(xhp, unsorted, pkg_repod)) != 0)
|
||||
return rv;
|
||||
/*
|
||||
* Set package state in dictionary with same state than the
|
||||
@@ -178,7 +160,7 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool bypattern,
|
||||
|
||||
/*
|
||||
* Add the pkg dictionary from repository's index dictionary into
|
||||
* the "unsorted" array in transaction dictionary.
|
||||
* the "unsorted" queue.
|
||||
*/
|
||||
if (!prop_array_add(unsorted, pkg_repod))
|
||||
return EINVAL;
|
||||
@@ -219,8 +201,7 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
|
||||
foundhold = false;
|
||||
continue;
|
||||
}
|
||||
rv = trans_find_pkg(xhp, pkgname, false, true,
|
||||
false, TRANS_UPDATE);
|
||||
rv = trans_find_pkg(xhp, pkgname, TRANS_UPDATE);
|
||||
if (rv == 0)
|
||||
newpkg_found = true;
|
||||
else if (rv == ENOENT || rv == EEXIST || rv == ENODEV) {
|
||||
@@ -236,42 +217,20 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
|
||||
}
|
||||
|
||||
int
|
||||
xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkgname)
|
||||
xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg)
|
||||
{
|
||||
return trans_find_pkg(xhp, pkgname, false, true, false, TRANS_UPDATE);
|
||||
return trans_find_pkg(xhp, pkg, TRANS_UPDATE);
|
||||
}
|
||||
|
||||
int
|
||||
xbps_transaction_install_pkg(struct xbps_handle *xhp,
|
||||
const char *pkg,
|
||||
xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg,
|
||||
bool reinstall)
|
||||
{
|
||||
prop_dictionary_t pkgd = NULL;
|
||||
pkg_state_t state;
|
||||
char *pkgname;
|
||||
bool bypattern, best, exact;
|
||||
|
||||
if (xbps_pkgpattern_version(pkg)) {
|
||||
bypattern = true;
|
||||
best = false;
|
||||
exact = false;
|
||||
} else if ((pkgname = xbps_pkg_name(pkg)) != NULL) {
|
||||
exact = true;
|
||||
bypattern = false;
|
||||
best = false;
|
||||
} else {
|
||||
exact = false;
|
||||
bypattern = false;
|
||||
best = true;
|
||||
}
|
||||
|
||||
if (exact) {
|
||||
pkgd = xbps_pkgdb_get_pkgd(xhp, pkgname, false);
|
||||
free(pkgname);
|
||||
} else
|
||||
pkgd = xbps_pkgdb_get_pkgd(xhp, pkg, bypattern);
|
||||
|
||||
if (pkgd) {
|
||||
if ((pkgd = xbps_pkgdb_get_pkg(xhp, pkg)) ||
|
||||
(pkgd = xbps_pkgdb_get_virtualpkg(xhp, pkg))) {
|
||||
if (xbps_pkg_state_dictionary(pkgd, &state) != 0)
|
||||
return EINVAL;
|
||||
if ((state == XBPS_PKG_STATE_INSTALLED) && !reinstall) {
|
||||
@@ -280,7 +239,7 @@ xbps_transaction_install_pkg(struct xbps_handle *xhp,
|
||||
}
|
||||
}
|
||||
|
||||
return trans_find_pkg(xhp, pkg, bypattern, best, exact, TRANS_INSTALL);
|
||||
return trans_find_pkg(xhp, pkg, TRANS_INSTALL);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -289,7 +248,7 @@ xbps_transaction_remove_pkg(struct xbps_handle *xhp,
|
||||
bool recursive)
|
||||
{
|
||||
prop_dictionary_t pkgd;
|
||||
prop_array_t orphans, orphans_pkg, unsorted, reqby;
|
||||
prop_array_t unsorted, orphans, orphans_pkg, reqby;
|
||||
prop_object_t obj;
|
||||
const char *pkgver;
|
||||
size_t count;
|
||||
@@ -297,7 +256,7 @@ xbps_transaction_remove_pkg(struct xbps_handle *xhp,
|
||||
|
||||
assert(pkgname != NULL);
|
||||
|
||||
if ((pkgd = xbps_pkgdb_get_pkgd(xhp, pkgname, false)) == NULL) {
|
||||
if ((pkgd = xbps_pkgdb_get_pkg(xhp, pkgname)) == NULL) {
|
||||
/* pkg not installed */
|
||||
return ENOENT;
|
||||
}
|
||||
@@ -308,6 +267,7 @@ xbps_transaction_remove_pkg(struct xbps_handle *xhp,
|
||||
return rv;
|
||||
|
||||
unsorted = prop_dictionary_get(xhp->transd, "unsorted_deps");
|
||||
|
||||
if (!recursive)
|
||||
goto rmpkg;
|
||||
/*
|
||||
@@ -334,7 +294,7 @@ xbps_transaction_remove_pkg(struct xbps_handle *xhp,
|
||||
prop_object_release(orphans);
|
||||
rmpkg:
|
||||
/*
|
||||
* Add pkg dictionary into the unsorted_deps array.
|
||||
* Add pkg dictionary into the transaction unsorted queue.
|
||||
*/
|
||||
prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver);
|
||||
prop_dictionary_set_cstring_nocopy(pkgd, "transaction", "remove");
|
||||
@@ -376,21 +336,22 @@ xbps_transaction_autoremove_pkgs(struct xbps_handle *xhp)
|
||||
*/
|
||||
if ((rv = xbps_transaction_init(xhp)) != 0)
|
||||
goto out;
|
||||
/*
|
||||
* Add pkg orphan dictionary into the unsorted_deps array.
|
||||
*/
|
||||
|
||||
unsorted = prop_dictionary_get(xhp->transd, "unsorted_deps");
|
||||
/*
|
||||
* Add pkg orphan dictionary into the transaction unsorted queue.
|
||||
*/
|
||||
while (count--) {
|
||||
obj = prop_array_get(orphans, count);
|
||||
prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
|
||||
prop_dictionary_set_cstring_nocopy(obj,
|
||||
"transaction", "remove");
|
||||
prop_array_add(unsorted, obj);
|
||||
xbps_dbg_printf(xhp, "%s: added into transaction (remove).\n",
|
||||
pkgver);
|
||||
xbps_dbg_printf(xhp, "%s: added (remove).\n", pkgver);
|
||||
}
|
||||
out:
|
||||
if (orphans != NULL)
|
||||
prop_object_release(orphans);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
int HIDDEN
|
||||
xbps_transaction_package_replace(struct xbps_handle *xhp)
|
||||
{
|
||||
prop_array_t replaces, instd_reqby, transd_unsorted;
|
||||
prop_array_t replaces, instd_reqby, unsorted;
|
||||
prop_dictionary_t instd, pkg_repod, reppkgd, filesd;
|
||||
prop_object_t obj;
|
||||
prop_object_iterator_t iter;
|
||||
@@ -45,10 +45,10 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
|
||||
bool instd_auto, sr;
|
||||
size_t idx;
|
||||
|
||||
transd_unsorted = prop_dictionary_get(xhp->transd, "unsorted_deps");
|
||||
unsorted = prop_dictionary_get(xhp->transd, "unsorted_deps");
|
||||
|
||||
for (idx = 0; idx < prop_array_count(transd_unsorted); idx++) {
|
||||
pkg_repod = prop_array_get(transd_unsorted, idx);
|
||||
for (idx = 0; idx < prop_array_count(unsorted); idx++) {
|
||||
pkg_repod = prop_array_get(unsorted, idx);
|
||||
replaces = prop_dictionary_get(pkg_repod, "replaces");
|
||||
if (replaces == NULL || prop_array_count(replaces) == 0)
|
||||
continue;
|
||||
@@ -64,15 +64,13 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
|
||||
* Find the installed package that matches the pattern
|
||||
* to be replaced.
|
||||
*/
|
||||
instd =
|
||||
xbps_find_pkg_dict_installed(xhp, pattern, true);
|
||||
instd = xbps_pkgdb_get_pkg(xhp, pattern);
|
||||
if (instd == NULL) {
|
||||
/*
|
||||
* No package installed has been matched,
|
||||
* try looking for a virtual package.
|
||||
*/
|
||||
instd = xbps_find_virtualpkg_dict_installed(
|
||||
xhp, pattern, true);
|
||||
instd = xbps_pkgdb_get_virtualpkg(xhp, pattern);
|
||||
if (instd == NULL)
|
||||
continue;
|
||||
}
|
||||
@@ -103,9 +101,8 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
|
||||
* package that should be replaced is also in the
|
||||
* transaction and it's going to be updated.
|
||||
*/
|
||||
reppkgd = xbps_find_pkg_in_array_by_name(
|
||||
xhp, transd_unsorted, curpkgname, NULL);
|
||||
if (reppkgd) {
|
||||
if ((reppkgd = xbps_find_pkg_in_array(unsorted, curpkgname)) ||
|
||||
(reppkgd = xbps_find_virtualpkg_in_array(xhp, unsorted, curpkgname))) {
|
||||
xbps_dbg_printf(xhp,
|
||||
"found replaced pkg "
|
||||
"in transaction\n");
|
||||
@@ -120,7 +117,7 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
|
||||
"automatic-install", instd_auto);
|
||||
prop_dictionary_set_bool(reppkgd,
|
||||
"skip-obsoletes", true);
|
||||
xbps_array_replace_dict_by_name(transd_unsorted,
|
||||
xbps_array_replace_dict_by_name(unsorted,
|
||||
reppkgd, curpkgname);
|
||||
}
|
||||
/*
|
||||
@@ -182,10 +179,7 @@ xbps_transaction_package_replace(struct xbps_handle *xhp)
|
||||
*/
|
||||
prop_dictionary_set_cstring_nocopy(instd,
|
||||
"transaction", "remove");
|
||||
if (!xbps_add_obj_to_array(transd_unsorted, instd)) {
|
||||
prop_object_iterator_release(iter);
|
||||
return EINVAL;
|
||||
}
|
||||
prop_array_add(unsorted, instd);
|
||||
}
|
||||
prop_object_iterator_release(iter);
|
||||
}
|
||||
|
||||
@@ -50,31 +50,37 @@ struct pkgdep {
|
||||
TAILQ_ENTRY(pkgdep) pkgdep_entries;
|
||||
prop_dictionary_t d;
|
||||
char *name;
|
||||
const char *trans;
|
||||
};
|
||||
|
||||
static TAILQ_HEAD(pkgdep_head, pkgdep) pkgdep_list =
|
||||
TAILQ_HEAD_INITIALIZER(pkgdep_list);
|
||||
|
||||
static struct pkgdep *
|
||||
pkgdep_find(const char *name, const char *trans)
|
||||
pkgdep_find(const char *pkg)
|
||||
{
|
||||
struct pkgdep *pd = NULL, *pd_new = NULL;
|
||||
const char *pkgver, *tract;
|
||||
|
||||
TAILQ_FOREACH_SAFE(pd, &pkgdep_list, pkgdep_entries, pd_new) {
|
||||
if (strcmp(pd->name, name) == 0) {
|
||||
if (trans == NULL)
|
||||
return pd;
|
||||
if (strcmp(pd->trans, trans) == 0)
|
||||
return pd;
|
||||
}
|
||||
if (pd->d == NULL)
|
||||
if (pd->d == NULL) {
|
||||
/* ignore entries without dictionary */
|
||||
continue;
|
||||
if (xbps_match_virtual_pkg_in_dict(pd->d, name, false)) {
|
||||
if (trans && pd->trans &&
|
||||
(strcmp(trans, pd->trans) == 0))
|
||||
return pd;
|
||||
}
|
||||
prop_dictionary_get_cstring_nocopy(pd->d,
|
||||
"transaction", &tract);
|
||||
/* ignore pkgs to be removed */
|
||||
if (strcmp(tract, "remove") == 0)
|
||||
continue;
|
||||
/* simple match */
|
||||
prop_dictionary_get_cstring_nocopy(pd->d, "pkgver", &pkgver);
|
||||
if (strcmp(pkgver, pkg) == 0)
|
||||
return pd;
|
||||
/* pkg expression match */
|
||||
if (xbps_pkgpattern_match(pkgver, pkg))
|
||||
return pd;
|
||||
/* virtualpkg expression match */
|
||||
if (xbps_match_virtual_pkg_in_dict(pd->d, pkg, true))
|
||||
return pd;
|
||||
}
|
||||
|
||||
/* not found */
|
||||
@@ -82,25 +88,35 @@ pkgdep_find(const char *name, const char *trans)
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
pkgdep_find_idx(const char *name, const char *trans)
|
||||
pkgdep_find_idx(const char *pkg)
|
||||
{
|
||||
struct pkgdep *pd, *pd_new;
|
||||
ssize_t idx = 0;
|
||||
const char *pkgver, *tract;
|
||||
|
||||
TAILQ_FOREACH_SAFE(pd, &pkgdep_list, pkgdep_entries, pd_new) {
|
||||
if (strcmp(pd->name, name) == 0) {
|
||||
if (trans == NULL)
|
||||
return idx;
|
||||
if (strcmp(pd->trans, trans) == 0)
|
||||
return idx;
|
||||
}
|
||||
if (pd->d == NULL)
|
||||
if (pd->d == NULL) {
|
||||
/* ignore entries without dictionary */
|
||||
idx++;
|
||||
continue;
|
||||
if (xbps_match_virtual_pkg_in_dict(pd->d, name, false)) {
|
||||
if (trans && pd->trans &&
|
||||
(strcmp(trans, pd->trans) == 0))
|
||||
return idx;
|
||||
}
|
||||
prop_dictionary_get_cstring_nocopy(pd->d,
|
||||
"transaction", &tract);
|
||||
/* ignore pkgs to be removed */
|
||||
if (strcmp(tract, "remove") == 0) {
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
/* simple match */
|
||||
prop_dictionary_get_cstring_nocopy(pd->d, "pkgver", &pkgver);
|
||||
if (strcmp(pkgver, pkg) == 0)
|
||||
return idx;
|
||||
/* pkg expression match */
|
||||
if (xbps_pkgpattern_match(pkgver, pkg))
|
||||
return idx;
|
||||
/* virtualpkg expression match */
|
||||
if (xbps_match_virtual_pkg_in_dict(pd->d, pkg, true))
|
||||
return idx;
|
||||
|
||||
idx++;
|
||||
}
|
||||
@@ -117,58 +133,28 @@ pkgdep_release(struct pkgdep *pd)
|
||||
}
|
||||
|
||||
static struct pkgdep *
|
||||
pkgdep_alloc(prop_dictionary_t d, const char *name, const char *trans)
|
||||
pkgdep_alloc(prop_dictionary_t d, const char *pkg)
|
||||
{
|
||||
struct pkgdep *pd;
|
||||
size_t len;
|
||||
|
||||
if ((pd = malloc(sizeof(*pd))) == NULL)
|
||||
return NULL;
|
||||
|
||||
len = strlen(name) + 1;
|
||||
if ((pd->name = malloc(len)) == NULL) {
|
||||
free(pd);
|
||||
return NULL;
|
||||
}
|
||||
pd = malloc(sizeof(*pd));
|
||||
assert(pd);
|
||||
pd->d = d;
|
||||
memcpy(pd->name, name, len-1);
|
||||
pd->name[len-1] = '\0';
|
||||
pd->trans = trans;
|
||||
pd->name = strdup(pkg);
|
||||
|
||||
return pd;
|
||||
}
|
||||
|
||||
static void
|
||||
pkgdep_end(struct xbps_handle *xhp, prop_array_t sorted)
|
||||
pkgdep_end(prop_array_t sorted)
|
||||
{
|
||||
prop_dictionary_t d;
|
||||
struct pkgdep *pd;
|
||||
const char *trans;
|
||||
|
||||
while ((pd = TAILQ_FIRST(&pkgdep_list)) != NULL) {
|
||||
TAILQ_REMOVE(&pkgdep_list, pd, pkgdep_entries);
|
||||
if (sorted != NULL && pd->d != NULL) {
|
||||
/* do not add duplicates due to vpkgs */
|
||||
d = xbps_find_pkg_in_array_by_name(xhp, sorted,
|
||||
pd->name, NULL);
|
||||
if (d == NULL) {
|
||||
/* find a virtual pkg otherwise */
|
||||
d = xbps_find_virtualpkg_in_array_by_name(
|
||||
xhp, sorted, pd->name);
|
||||
if (d == NULL) {
|
||||
prop_array_add(sorted, pd->d);
|
||||
pkgdep_release(pd);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
prop_dictionary_get_cstring_nocopy(d,
|
||||
"transaction", &trans);
|
||||
if (strcmp(trans, pd->trans) == 0) {
|
||||
pkgdep_release(pd);
|
||||
continue;
|
||||
}
|
||||
if (sorted != NULL && pd->d != NULL)
|
||||
prop_array_add(sorted, pd->d);
|
||||
}
|
||||
|
||||
pkgdep_release(pd);
|
||||
}
|
||||
}
|
||||
@@ -176,31 +162,26 @@ pkgdep_end(struct xbps_handle *xhp, prop_array_t sorted)
|
||||
static int
|
||||
sort_pkg_rundeps(struct xbps_handle *xhp,
|
||||
struct pkgdep *pd,
|
||||
prop_array_t pkg_rundeps)
|
||||
prop_array_t pkg_rundeps,
|
||||
prop_array_t unsorted)
|
||||
{
|
||||
prop_dictionary_t curpkgd;
|
||||
struct pkgdep *lpd, *pdn;
|
||||
const char *str, *tract;
|
||||
char *pkgnamedep;
|
||||
ssize_t pkgdepidx, curpkgidx;
|
||||
size_t i, idx = 0;
|
||||
int rv = 0;
|
||||
|
||||
xbps_dbg_printf_append(xhp, "\n");
|
||||
curpkgidx = pkgdep_find_idx(pd->name, pd->trans);
|
||||
curpkgidx = pkgdep_find_idx(pd->name);
|
||||
|
||||
again:
|
||||
for (i = idx; i < prop_array_count(pkg_rundeps); i++) {
|
||||
prop_array_get_cstring_nocopy(pkg_rundeps, i, &str);
|
||||
if (((pkgnamedep = xbps_pkgpattern_name(str)) == NULL) &&
|
||||
((pkgnamedep = xbps_pkg_name(str)) == NULL)) {
|
||||
rv = ENOMEM;
|
||||
break;
|
||||
}
|
||||
xbps_dbg_printf(xhp, " Required dependency '%s': ", str);
|
||||
pdn = pkgdep_find(pkgnamedep, NULL);
|
||||
if ((pdn == NULL) &&
|
||||
xbps_check_is_installed_pkg_by_pattern(xhp, str)) {
|
||||
|
||||
pdn = pkgdep_find(str);
|
||||
if ((pdn == NULL) && xbps_pkg_is_installed(xhp, str)) {
|
||||
/*
|
||||
* Package dependency is installed, just add to
|
||||
* the list but just mark it as "installed", to avoid
|
||||
@@ -208,12 +189,7 @@ again:
|
||||
* which is expensive.
|
||||
*/
|
||||
xbps_dbg_printf_append(xhp, "installed.\n");
|
||||
lpd = pkgdep_alloc(NULL, pkgnamedep, "installed");
|
||||
if (lpd == NULL) {
|
||||
rv = ENOMEM;
|
||||
break;
|
||||
}
|
||||
free(pkgnamedep);
|
||||
lpd = pkgdep_alloc(NULL, str);
|
||||
TAILQ_INSERT_TAIL(&pkgdep_list, lpd, pkgdep_entries);
|
||||
continue;
|
||||
} else if (pdn != NULL && pdn->d == NULL) {
|
||||
@@ -222,31 +198,18 @@ again:
|
||||
* and is installed, skip.
|
||||
*/
|
||||
xbps_dbg_printf_append(xhp, "installed.\n");
|
||||
free(pkgnamedep);
|
||||
continue;
|
||||
}
|
||||
/* Find pkg by name */
|
||||
curpkgd = xbps_find_pkg_in_dict_by_name(xhp, xhp->transd,
|
||||
"unsorted_deps", pkgnamedep);
|
||||
if (curpkgd == NULL) {
|
||||
/* find virtualpkg by name if no match */
|
||||
curpkgd =
|
||||
xbps_find_virtualpkg_in_dict_by_name(xhp,
|
||||
xhp->transd, "unsorted_deps", pkgnamedep);
|
||||
}
|
||||
if (curpkgd == NULL) {
|
||||
free(pkgnamedep);
|
||||
if (((curpkgd = xbps_find_pkg_in_array(unsorted, str)) == NULL) &&
|
||||
((curpkgd = xbps_find_virtualpkg_in_array(xhp, unsorted, str)) == NULL)) {
|
||||
rv = EINVAL;
|
||||
break;
|
||||
}
|
||||
prop_dictionary_get_cstring_nocopy(curpkgd,
|
||||
"transaction", &tract);
|
||||
lpd = pkgdep_alloc(curpkgd, pkgnamedep, tract);
|
||||
if (lpd == NULL) {
|
||||
free(pkgnamedep);
|
||||
rv = ENOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
lpd = pkgdep_alloc(curpkgd, str);
|
||||
|
||||
if (pdn == NULL) {
|
||||
/*
|
||||
* If package is not in the list, add to the tail
|
||||
@@ -256,18 +219,16 @@ again:
|
||||
idx = i;
|
||||
xbps_dbg_printf_append(xhp, "added into the tail, "
|
||||
"checking again...\n");
|
||||
free(pkgnamedep);
|
||||
goto again;
|
||||
}
|
||||
/*
|
||||
* Find package dependency index.
|
||||
*/
|
||||
pkgdepidx = pkgdep_find_idx(pkgnamedep, tract);
|
||||
pkgdepidx = pkgdep_find_idx(str);
|
||||
/*
|
||||
* If package dependency index is less than current
|
||||
* package index, it's already sorted.
|
||||
*/
|
||||
free(pkgnamedep);
|
||||
if (pkgdepidx < curpkgidx) {
|
||||
xbps_dbg_printf_append(xhp, "already sorted.\n");
|
||||
pkgdep_release(lpd);
|
||||
@@ -288,13 +249,12 @@ again:
|
||||
}
|
||||
|
||||
int HIDDEN
|
||||
xbps_transaction_sort_pkg_deps(struct xbps_handle *xhp)
|
||||
xbps_transaction_sort(struct xbps_handle *xhp)
|
||||
{
|
||||
prop_array_t provides, sorted, unsorted, rundeps;
|
||||
prop_object_t obj;
|
||||
struct pkgdep *pd;
|
||||
size_t i, j, ndeps = 0, cnt = 0;
|
||||
char *vpkg, *vpkgname;
|
||||
const char *pkgname, *pkgver, *tract, *vpkgdep;
|
||||
int rv = 0;
|
||||
bool vpkg_found;
|
||||
@@ -339,21 +299,12 @@ xbps_transaction_sort_pkg_deps(struct xbps_handle *xhp)
|
||||
/*
|
||||
* If current pkgdep provides any virtual pkg check
|
||||
* if any of them was previously added. If true, don't
|
||||
* add it into the list again just order its deps.
|
||||
* add it into the list again, just order its deps.
|
||||
*/
|
||||
for (j = 0; j < prop_array_count(provides); j++) {
|
||||
prop_array_get_cstring_nocopy(provides,
|
||||
j, &vpkgdep);
|
||||
if (strchr(vpkgdep, '_') == NULL) {
|
||||
vpkg = xbps_xasprintf("%s_1", vpkgdep);
|
||||
vpkgname = xbps_pkg_name(vpkg);
|
||||
free(vpkg);
|
||||
} else {
|
||||
vpkgname = xbps_pkg_name(vpkgdep);
|
||||
}
|
||||
assert(vpkgname);
|
||||
pd = pkgdep_find(vpkgname, tract);
|
||||
free(vpkgname);
|
||||
pd = pkgdep_find(vpkgdep);
|
||||
if (pd != NULL) {
|
||||
xbps_dbg_printf_append(xhp, "already "
|
||||
"sorted via `%s' vpkg.", vpkgdep);
|
||||
@@ -362,17 +313,17 @@ xbps_transaction_sort_pkg_deps(struct xbps_handle *xhp)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!vpkg_found && (pd = pkgdep_find(pkgname, tract)) == NULL) {
|
||||
if (!vpkg_found && (pd = pkgdep_find(pkgver)) == NULL) {
|
||||
/*
|
||||
* If package not in list, just add to the tail.
|
||||
*/
|
||||
pd = pkgdep_alloc(obj, pkgname, tract);
|
||||
pd = pkgdep_alloc(obj, pkgver);
|
||||
if (pd == NULL) {
|
||||
pkgdep_end(xhp, NULL);
|
||||
pkgdep_end(NULL);
|
||||
rv = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (strcmp(pd->trans, "remove") == 0) {
|
||||
if (strcmp(tract, "remove") == 0) {
|
||||
xbps_dbg_printf_append(xhp, "added into head.");
|
||||
TAILQ_INSERT_HEAD(&pkgdep_list, pd,
|
||||
pkgdep_entries);
|
||||
@@ -395,8 +346,8 @@ xbps_transaction_sort_pkg_deps(struct xbps_handle *xhp)
|
||||
/*
|
||||
* Sort package run-time dependencies for this package.
|
||||
*/
|
||||
if ((rv = sort_pkg_rundeps(xhp, pd, rundeps)) != 0) {
|
||||
pkgdep_end(xhp, NULL);
|
||||
if ((rv = sort_pkg_rundeps(xhp, pd, rundeps, unsorted)) != 0) {
|
||||
pkgdep_end(NULL);
|
||||
goto out;
|
||||
}
|
||||
cnt++;
|
||||
@@ -406,7 +357,7 @@ xbps_transaction_sort_pkg_deps(struct xbps_handle *xhp)
|
||||
* from the sorted list into the "packages" array, and at
|
||||
* the same time freeing memory used for temporary sorting.
|
||||
*/
|
||||
pkgdep_end(xhp, sorted);
|
||||
pkgdep_end(sorted);
|
||||
/*
|
||||
* Sanity check that the array contains the same number of
|
||||
* objects than the total number of required dependencies.
|
||||
|
||||
76
lib/util.c
76
lib/util.c
@@ -47,7 +47,7 @@
|
||||
* @defgroup util Utility functions
|
||||
*/
|
||||
bool
|
||||
xbps_check_is_repository_uri_remote(const char *uri)
|
||||
xbps_repository_is_remote(const char *uri)
|
||||
{
|
||||
assert(uri != NULL);
|
||||
|
||||
@@ -60,23 +60,17 @@ xbps_check_is_repository_uri_remote(const char *uri)
|
||||
}
|
||||
|
||||
int
|
||||
xbps_check_is_installed_pkg_by_pattern(struct xbps_handle *xhp,
|
||||
const char *pattern)
|
||||
xbps_pkg_is_installed(struct xbps_handle *xhp, const char *pkg)
|
||||
{
|
||||
prop_dictionary_t dict;
|
||||
pkg_state_t state;
|
||||
|
||||
assert(pattern != NULL);
|
||||
assert(xhp);
|
||||
assert(pkg);
|
||||
|
||||
dict = xbps_find_virtualpkg_dict_installed(xhp, pattern, true);
|
||||
if (dict == NULL) {
|
||||
dict = xbps_find_pkg_dict_installed(xhp, pattern, true);
|
||||
if (dict == NULL) {
|
||||
if (errno == ENOENT)
|
||||
return 0; /* not installed */
|
||||
return -1; /* error */
|
||||
}
|
||||
}
|
||||
if (((dict = xbps_pkgdb_get_virtualpkg(xhp, pkg)) == NULL) &&
|
||||
((dict = xbps_pkgdb_get_pkg(xhp, pkg)) == NULL))
|
||||
return 0; /* not installed */
|
||||
/*
|
||||
* Check that package state is fully installed, not
|
||||
* unpacked or something else.
|
||||
@@ -89,21 +83,6 @@ xbps_check_is_installed_pkg_by_pattern(struct xbps_handle *xhp,
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool
|
||||
xbps_check_is_installed_pkg_by_name(struct xbps_handle *xhp,
|
||||
const char *pkgname)
|
||||
{
|
||||
prop_dictionary_t pkgd;
|
||||
|
||||
assert(pkgname != NULL);
|
||||
|
||||
if (((pkgd = xbps_find_pkg_dict_installed(xhp, pkgname, false)) == NULL) &&
|
||||
((pkgd = xbps_find_virtualpkg_dict_installed(xhp, pkgname, false)) == NULL))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *
|
||||
xbps_pkg_version(const char *pkg)
|
||||
{
|
||||
@@ -208,47 +187,54 @@ get_pkg_index_remote_plist(struct xbps_handle *xhp,
|
||||
char *
|
||||
xbps_pkg_index_plist(struct xbps_handle *xhp, const char *uri)
|
||||
{
|
||||
assert(xhp);
|
||||
assert(uri != NULL);
|
||||
|
||||
if (xbps_check_is_repository_uri_remote(uri))
|
||||
if (xbps_repository_is_remote(uri))
|
||||
return get_pkg_index_remote_plist(xhp, uri, XBPS_PKGINDEX);
|
||||
|
||||
return xbps_xasprintf("%s/%s", uri, XBPS_PKGINDEX);
|
||||
return xbps_xasprintf("%s/%s-%s", uri, xhp->un_machine, XBPS_PKGINDEX);
|
||||
}
|
||||
|
||||
char *
|
||||
xbps_pkg_index_files_plist(struct xbps_handle *xhp, const char *uri)
|
||||
{
|
||||
assert(xhp);
|
||||
assert(uri != NULL);
|
||||
if (xbps_check_is_repository_uri_remote(uri))
|
||||
|
||||
if (xbps_repository_is_remote(uri))
|
||||
return get_pkg_index_remote_plist(xhp, uri, XBPS_PKGINDEX_FILES);
|
||||
|
||||
return xbps_xasprintf("%s/%s", uri, XBPS_PKGINDEX_FILES);
|
||||
return xbps_xasprintf("%s/%s-%s", uri,
|
||||
xhp->un_machine, XBPS_PKGINDEX_FILES);
|
||||
}
|
||||
|
||||
char *
|
||||
xbps_path_from_repository_uri(struct xbps_handle *xhp,
|
||||
prop_dictionary_t pkg_repod,
|
||||
const char *repoloc)
|
||||
char HIDDEN *
|
||||
xbps_repository_pkg_path(struct xbps_handle *xhp, prop_dictionary_t pkg_repod)
|
||||
{
|
||||
const char *filen;
|
||||
const char *filen, *repoloc;
|
||||
char *lbinpkg = NULL;
|
||||
|
||||
assert(xhp);
|
||||
assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY);
|
||||
assert(repoloc != NULL);
|
||||
|
||||
if (!prop_dictionary_get_cstring_nocopy(pkg_repod,
|
||||
"filename", &filen))
|
||||
return NULL;
|
||||
if (!prop_dictionary_get_cstring_nocopy(pkg_repod,
|
||||
"repository", &repoloc))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* First check if binpkg is available in cachedir.
|
||||
*/
|
||||
lbinpkg = xbps_xasprintf("%s/%s", xhp->cachedir, filen);
|
||||
if (access(lbinpkg, R_OK) == 0)
|
||||
return lbinpkg;
|
||||
if (xbps_repository_is_remote(repoloc)) {
|
||||
/*
|
||||
* First check if binpkg is available in cachedir.
|
||||
*/
|
||||
lbinpkg = xbps_xasprintf("%s/%s", xhp->cachedir, filen);
|
||||
if (access(lbinpkg, R_OK) == 0)
|
||||
return lbinpkg;
|
||||
|
||||
free(lbinpkg);
|
||||
free(lbinpkg);
|
||||
}
|
||||
/*
|
||||
* Local and remote repositories use the same path.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2011 Juan Romero Pardines.
|
||||
* Copyright (c) 2008-2012 Juan Romero Pardines.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -136,10 +136,8 @@ xbps_file_hash_check(const char *file, const char *sha256)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
xbps_file_hash_dictionary(prop_dictionary_t d,
|
||||
const char *key,
|
||||
const char *file)
|
||||
static const char *
|
||||
file_hash_dictionary(prop_dictionary_t d, const char *key, const char *file)
|
||||
{
|
||||
prop_object_t obj;
|
||||
prop_object_iterator_t iter;
|
||||
@@ -171,7 +169,7 @@ xbps_file_hash_dictionary(prop_dictionary_t d,
|
||||
return sha256;
|
||||
}
|
||||
|
||||
int
|
||||
int HIDDEN
|
||||
xbps_file_hash_check_dictionary(struct xbps_handle *xhp,
|
||||
prop_dictionary_t d,
|
||||
const char *key,
|
||||
@@ -185,7 +183,7 @@ xbps_file_hash_check_dictionary(struct xbps_handle *xhp,
|
||||
assert(key != NULL);
|
||||
assert(file != NULL);
|
||||
|
||||
if ((sha256d = xbps_file_hash_dictionary(d, key, file)) == NULL) {
|
||||
if ((sha256d = file_hash_dictionary(d, key, file)) == NULL) {
|
||||
if (errno == ENOENT)
|
||||
return 1; /* no match, file not found */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user