Welcome pkgdb-0.38.

This commit is contained in:
Juan RP
2014-09-11 00:12:12 +02:00
parent fb9c94fab9
commit 01dbb968dd
30 changed files with 480 additions and 477 deletions

View File

@@ -36,7 +36,7 @@ EXTOBJS = external/dewey.o external/fexec.o external/mkpath.o
OBJS = package_configure.o package_config_files.o package_orphans.o
OBJS += package_remove.o package_find_obsoletes.o package_state.o
OBJS += package_unpack.o package_register.o package_script.o verifysig.o
OBJS += package_msg.o transaction_shlibs.o
OBJS += package_msg.o pkgdb_conversion.o transaction_shlibs.o
OBJS += transaction_commit.o transaction_package_replace.o
OBJS += transaction_dictionary.o transaction_sortdeps.o transaction_ops.o
OBJS += transaction_revdeps.o pubkey2fp.o

View File

@@ -59,26 +59,26 @@ xbps_entry_is_a_conf_file(xbps_dictionary_t filesd,
*/
int HIDDEN
xbps_entry_install_conf_file(struct xbps_handle *xhp,
xbps_dictionary_t filesd,
xbps_dictionary_t binpkg_filesd,
xbps_dictionary_t pkg_filesd,
struct archive_entry *entry,
const char *entry_pname,
const char *pkgver,
const char *pkgname)
{
xbps_dictionary_t forigd;
xbps_object_t obj, obj2;
xbps_object_iterator_t iter, iter2;
const char *version = NULL, *cffile, *sha256_new = NULL;
char buf[PATH_MAX], *sha256_cur = NULL, *sha256_orig = NULL;
int rv = 0;
assert(xbps_object_type(filesd) == XBPS_TYPE_DICTIONARY);
assert(xbps_object_type(binpkg_filesd) == XBPS_TYPE_DICTIONARY);
assert(entry);
assert(entry_pname);
assert(pkgver);
assert(pkgname);
iter = xbps_array_iter_from_dict(filesd, "conf_files");
iter = xbps_array_iter_from_dict(binpkg_filesd, "conf_files");
if (iter == NULL)
return -1;
@@ -89,8 +89,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
xbps_dbg_printf(xhp, "%s: processing conf_file %s\n",
pkgver, entry_pname);
forigd = xbps_pkgdb_get_pkg_metadata(xhp, pkgname);
if (forigd == NULL) {
if (pkg_filesd == NULL) {
/*
* File exists on disk but it's not managed by the same package.
* Install it as file.new-<version>.
@@ -107,7 +106,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
goto out;
}
iter2 = xbps_array_iter_from_dict(forigd, "conf_files");
iter2 = xbps_array_iter_from_dict(pkg_filesd, "conf_files");
if (iter2 != NULL) {
while ((obj2 = xbps_object_iterator_next(iter2))) {
xbps_dictionary_get_cstring_nocopy(obj2,

View File

@@ -80,8 +80,8 @@ xbps_configure_pkg(struct xbps_handle *xhp,
bool check_state,
bool update)
{
xbps_dictionary_t pkgd, pkgmetad;
char *pkgname, *plist;
xbps_dictionary_t pkgd;
char *pkgname;
int rv = 0;
pkg_state_t state = 0;
@@ -125,23 +125,7 @@ xbps_configure_pkg(struct xbps_handle *xhp,
xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE, 0, pkgver, NULL);
plist = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
free(pkgname);
pkgmetad = xbps_dictionary_internalize_from_file(plist);
if (pkgmetad == NULL) {
rv = errno;
xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL,
errno, pkgver,
"%s: [configure] cannot read metadata plist: %s",
pkgver, strerror(rv));
return errno;
}
free(plist);
assert(pkgmetad);
rv = xbps_pkg_exec_script(xhp, pkgmetad, "install-script", "post", update);
rv = xbps_pkg_exec_script(xhp, pkgd, "install-script", "post", update);
if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL,
errno, pkgver,
@@ -149,11 +133,6 @@ xbps_configure_pkg(struct xbps_handle *xhp,
"the post ACTION: %s", pkgver, strerror(rv));
return rv;
}
if (state == XBPS_PKG_STATE_INSTALLED) {
xbps_object_release(pkgmetad);
return rv;
}
rv = xbps_set_pkg_state_dictionary(pkgd, XBPS_PKG_STATE_INSTALLED);
if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_FAIL, rv,
@@ -165,10 +144,5 @@ xbps_configure_pkg(struct xbps_handle *xhp,
xbps_set_cb_state(xhp, XBPS_STATE_CONFIGURE_DONE, 0, pkgver, NULL);
/* show install-msg if exists */
rv = xbps_cb_message(xhp, pkgmetad, "install-msg");
if (pkgmetad != NULL)
xbps_object_release(pkgmetad);
return rv;
return xbps_cb_message(xhp, pkgd, "install-msg");
}

View File

@@ -34,12 +34,10 @@
int HIDDEN
xbps_register_pkg(struct xbps_handle *xhp, xbps_dictionary_t pkgrd)
{
xbps_dictionary_t pkgd;
xbps_array_t provides, rundeps;
char outstr[64];
time_t t;
struct tm *tmp;
const char *desc, *pkgver, *repo;
const char *pkgver;
char *pkgname = NULL, *buf, *sha256;
int rv = 0;
bool autoinst = false;
@@ -47,41 +45,17 @@ xbps_register_pkg(struct xbps_handle *xhp, xbps_dictionary_t pkgrd)
assert(xbps_object_type(pkgrd) == XBPS_TYPE_DICTIONARY);
xbps_dictionary_get_cstring_nocopy(pkgrd, "pkgver", &pkgver);
xbps_dictionary_get_cstring_nocopy(pkgrd, "short_desc", &desc);
xbps_dictionary_get_cstring_nocopy(pkgrd, "repository", &repo);
xbps_dictionary_get_bool(pkgrd, "automatic-install", &autoinst);
provides = xbps_dictionary_get(pkgrd, "provides");
rundeps = xbps_dictionary_get(pkgrd, "run_depends");
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
assert(pkgver != NULL);
assert(desc != NULL);
pkgd = xbps_pkgdb_get_pkg(xhp, pkgver);
if (pkgd == NULL) {
rv = ENOENT;
goto out;
}
if (!xbps_dictionary_set_cstring_nocopy(pkgd,
"pkgver", pkgver)) {
xbps_dbg_printf(xhp, "%s: invalid pkgver for %s\n",
__func__, pkgver);
rv = EINVAL;
goto out;
}
if (!xbps_dictionary_set_cstring_nocopy(pkgd,
"short_desc", desc)) {
xbps_dbg_printf(xhp, "%s: invalid short_desc for %s\n",
__func__, pkgver);
rv = EINVAL;
goto out;
}
if (xhp->flags & XBPS_FLAG_INSTALL_AUTO)
autoinst = true;
if (!xbps_dictionary_set_bool(pkgd,
"automatic-install", autoinst)) {
xbps_dbg_printf(xhp, "%s: invalid autoinst for %s\n",
__func__, pkgver);
/*
* Set automatic-install to true, iff it was explicitly set; otherwise
* preserve its value.
*/
if (autoinst && !xbps_dictionary_set_bool(pkgrd, "automatic-install", true)) {
xbps_dbg_printf(xhp, "%s: invalid autoinst for %s\n", __func__, pkgver);
rv = EINVAL;
goto out;
}
@@ -101,50 +75,31 @@ xbps_register_pkg(struct xbps_handle *xhp, xbps_dictionary_t pkgrd)
rv = EINVAL;
goto out;
}
if (!xbps_dictionary_set_cstring(pkgd, "install-date", outstr)) {
if (!xbps_dictionary_set_cstring(pkgrd, "install-date", outstr)) {
xbps_dbg_printf(xhp, "%s: install-date set failed!\n", pkgver);
rv = EINVAL;
goto out;
}
if (provides && !xbps_dictionary_set(pkgd, "provides", provides)) {
xbps_dbg_printf(xhp, "%s: failed to set provides for %s\n",
__func__, pkgver);
rv = EINVAL;
goto out;
}
if (rundeps && !xbps_dictionary_set(pkgd, "run_depends", rundeps)) {
xbps_dbg_printf(xhp, "%s: failed to set rundeps for %s\n",
__func__, pkgver);
rv = EINVAL;
goto out;
}
/* Save the repository origin which was used to install the pkg from */
if (!xbps_dictionary_set_cstring(pkgd, "repository-origin", repo)) {
xbps_dbg_printf(xhp, "%s: repository-origin set failed!\n", pkgver);
rv = EINVAL;
goto out;
}
/*
* Create a hash for the pkg's metafile.
*/
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
buf = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
buf = xbps_xasprintf("%s/.%s-files.plist", xhp->metadir, pkgname);
sha256 = xbps_file_hash(buf);
assert(sha256);
xbps_dictionary_set_cstring(pkgd, "metafile-sha256", sha256);
xbps_dictionary_set_cstring(pkgrd, "metafile-sha256", sha256);
free(sha256);
free(buf);
/*
* Remove unneeded objs from pkg dictionary.
*/
xbps_dictionary_remove(pkgd, "remove-and-update");
xbps_dictionary_remove(pkgd, "transaction");
xbps_dictionary_remove(pkgd, "skip-obsoletes");
xbps_dictionary_remove(pkgrd, "download");
xbps_dictionary_remove(pkgrd, "remove-and-update");
xbps_dictionary_remove(pkgrd, "transaction");
xbps_dictionary_remove(pkgrd, "skip-obsoletes");
xbps_dictionary_remove(pkgrd, "pkgname");
xbps_dictionary_remove(pkgrd, "version");
if (!xbps_dictionary_set(xhp->pkgdb, pkgname, pkgd)) {
if (!xbps_dictionary_set(xhp->pkgdb, pkgname, pkgrd)) {
xbps_dbg_printf(xhp,
"%s: failed to set pkgd for %s\n", __func__, pkgver);
}

View File

@@ -215,7 +215,7 @@ remove_pkg_files(struct xbps_handle *xhp,
int HIDDEN
xbps_remove_pkg(struct xbps_handle *xhp, const char *pkgver, bool update)
{
xbps_dictionary_t pkgd = NULL;
xbps_dictionary_t pkgd = NULL, pkgfilesd = NULL;
char *pkgname, metafile[PATH_MAX];
int rv = 0;
pkg_state_t state = 0;
@@ -226,7 +226,13 @@ xbps_remove_pkg(struct xbps_handle *xhp, const char *pkgver, bool update)
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
if ((rv = xbps_pkg_state_installed(xhp, pkgname, &state)) != 0) {
if ((pkgd = xbps_pkgdb_get_pkg(xhp, pkgname)) == NULL) {
rv = errno;
xbps_dbg_printf(xhp, "[remove] cannot find %s in pkgdb: %s\n",
pkgver, strerror(rv));
goto out;
}
if ((rv = xbps_pkg_state_dictionary(pkgd, &state)) != 0) {
xbps_dbg_printf(xhp, "[remove] cannot find %s in pkgdb: %s\n",
pkgver, strerror(rv));
goto out;
@@ -245,10 +251,10 @@ xbps_remove_pkg(struct xbps_handle *xhp, const char *pkgver, bool update)
goto out;
}
/* internalize pkg dictionary from metadir */
snprintf(metafile, sizeof(metafile), "%s/.%s.plist", xhp->metadir, pkgname);
pkgd = xbps_dictionary_internalize_from_file(metafile);
if (pkgd == NULL)
/* internalize pkg files dictionary from metadir */
snprintf(metafile, sizeof(metafile), "%s/.%s-files.plist", xhp->metadir, pkgname);
pkgfilesd = xbps_dictionary_internalize_from_file(metafile);
if (pkgfilesd == NULL)
xbps_dbg_printf(xhp, "WARNING: metaplist for %s "
"doesn't exist!\n", pkgver);
@@ -258,70 +264,64 @@ xbps_remove_pkg(struct xbps_handle *xhp, const char *pkgver, bool update)
/*
* Run the pre remove action and show pre-remove message if exists.
*/
if (pkgd) {
rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script",
"pre", update);
if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
errno, pkgver,
"%s: [remove] REMOVE script failed to "
"execute pre ACTION: %s",
pkgver, strerror(rv));
goto out;
}
/* show remove-msg if exists */
rv = xbps_cb_message(xhp, pkgd, "remove-msg");
if (rv != 0)
goto out;
rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script", "pre", update);
if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
errno, pkgver,
"%s: [remove] REMOVE script failed to "
"execute pre ACTION: %s",
pkgver, strerror(rv));
goto out;
}
/* show remove-msg if exists */
if ((rv = xbps_cb_message(xhp, pkgd, "remove-msg")) != 0)
goto out;
/*
* If updating a package, we just need to execute the current
* pre-remove action target and we are done. Its files will be
* overwritten later in unpack phase.
*/
if (update) {
if (pkgd)
xbps_object_release(pkgd);
free(pkgname);
return 0;
}
if (pkgd) {
if (pkgfilesd) {
/*
* Do the removal in 2 phases:
* 1- check if user has enough perms to remove all entries
* 2- perform removal
*/
if (check_remove_pkg_files(xhp, pkgd, pkgver)) {
if (check_remove_pkg_files(xhp, pkgfilesd, pkgver)) {
rv = EPERM;
goto out;
}
/* Remove regular files */
if ((rv = remove_pkg_files(xhp, pkgd, "files", pkgver)) != 0)
if ((rv = remove_pkg_files(xhp, pkgfilesd, "files", pkgver)) != 0)
goto out;
/* Remove configuration files */
if ((rv = remove_pkg_files(xhp, pkgd, "conf_files", pkgver)) != 0)
if ((rv = remove_pkg_files(xhp, pkgfilesd, "conf_files", pkgver)) != 0)
goto out;
/* Remove links */
if ((rv = remove_pkg_files(xhp, pkgd, "links", pkgver)) != 0)
if ((rv = remove_pkg_files(xhp, pkgfilesd, "links", pkgver)) != 0)
goto out;
/* Remove dirs */
if ((rv = remove_pkg_files(xhp, pkgd, "dirs", pkgver)) != 0)
if ((rv = remove_pkg_files(xhp, pkgfilesd, "dirs", pkgver)) != 0)
goto out;
/*
* Execute the post REMOVE action if file exists and we aren't
* updating the package.
*/
rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script", "post", false);
if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
rv, pkgver,
"%s: [remove] REMOVE script failed to execute "
"post ACTION: %s", pkgver, strerror(rv));
goto out;
}
}
/*
* Execute the post REMOVE action if file exists and we aren't
* updating the package.
*/
rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script", "post", false);
if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
rv, pkgver,
"%s: [remove] REMOVE script failed to execute "
"post ACTION: %s", pkgver, strerror(rv));
goto out;
}
/*
* Set package state to "half-removed".
*/
@@ -339,16 +339,13 @@ purge:
/*
* Execute the purge REMOVE action if file exists.
*/
if (pkgd) {
rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script", "purge", false);
if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
rv, pkgver,
"%s: REMOVE script failed to execute "
"purge ACTION: %s", pkgver, strerror(rv));
goto out;
}
xbps_object_release(pkgd);
rv = xbps_pkg_exec_script(xhp, pkgd, "remove-script", "purge", false);
if (rv != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL,
rv, pkgver,
"%s: REMOVE script failed to execute "
"purge ACTION: %s", pkgver, strerror(rv));
goto out;
}
/*
* Remove package metadata plist.

View File

@@ -78,79 +78,6 @@ find_pkg_symlink_target(xbps_dictionary_t d, const char *file)
return tgt;
}
static int
create_pkg_metaplist(struct xbps_handle *xhp, const char *pkgname, const char *pkgver,
xbps_dictionary_t propsd, xbps_dictionary_t filesd,
const void *instbuf, const size_t instbufsiz,
const void *rembuf, const size_t rembufsiz)
{
xbps_array_t array;
xbps_dictionary_t pkg_metad;
xbps_data_t data;
char *buf;
int rv = 0;
xbps_dictionary_make_immutable(propsd);
pkg_metad = xbps_dictionary_copy_mutable(propsd);
/* Add objects from XBPS_PKGFILES */
array = xbps_dictionary_get(filesd, "files");
if (xbps_array_count(array))
xbps_dictionary_set(pkg_metad, "files", array);
array = xbps_dictionary_get(filesd, "conf_files");
if (xbps_array_count(array))
xbps_dictionary_set(pkg_metad, "conf_files", array);
array = xbps_dictionary_get(filesd, "links");
if (xbps_array_count(array))
xbps_dictionary_set(pkg_metad, "links", array);
array = xbps_dictionary_get(filesd, "dirs");
if (xbps_array_count(array))
xbps_dictionary_set(pkg_metad, "dirs", array);
/* Add install/remove scripts data objects */
if (instbuf != NULL) {
data = xbps_data_create_data(instbuf, instbufsiz);
assert(data);
xbps_dictionary_set(pkg_metad, "install-script", data);
xbps_object_release(data);
}
if (rembuf != NULL) {
data = xbps_data_create_data(rembuf, rembufsiz);
assert(data);
xbps_dictionary_set(pkg_metad, "remove-script", data);
xbps_object_release(data);
}
/* Remove unneeded objs from transaction */
xbps_dictionary_remove(pkg_metad, "remove-and-update");
xbps_dictionary_remove(pkg_metad, "transaction");
xbps_dictionary_remove(pkg_metad, "state");
xbps_dictionary_remove(pkg_metad, "pkgname");
xbps_dictionary_remove(pkg_metad, "version");
/*
* Externalize pkg dictionary to metadir.
*/
if (access(xhp->metadir, R_OK|X_OK) == -1) {
if (errno == ENOENT) {
xbps_mkpath(xhp->metadir, 0755);
} else {
return errno;
}
}
buf = xbps_xasprintf("%s/.%s.plist", XBPS_META_PATH, pkgname);
if (!xbps_dictionary_externalize_to_file(pkg_metad, buf)) {
rv = errno;
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
errno, pkgver,
"%s: [unpack] failed to write metadata file `%s': %s",
pkgver, buf, strerror(errno));
}
free(buf);
xbps_object_release(pkg_metad);
return rv;
}
static bool
match_preserved_file(struct xbps_handle *xhp, const char *entry)
{
@@ -176,9 +103,10 @@ unpack_archive(struct xbps_handle *xhp,
const char *fname,
struct archive *ar)
{
xbps_dictionary_t propsd, filesd, metapropsd;
xbps_dictionary_t binpkg_propsd, binpkg_filesd, pkg_filesd;
xbps_array_t array, obsoletes;
xbps_object_t obj;
xbps_data_t data;
const struct stat *entry_statp;
void *instbuf = NULL, *rembuf = NULL;
struct stat st;
@@ -193,7 +121,7 @@ unpack_archive(struct xbps_handle *xhp,
bool skip_extract, force, xucd_stats;
uid_t euid;
propsd = filesd = metapropsd = NULL;
binpkg_propsd = binpkg_filesd = pkg_filesd = NULL;
force = preserve = update = conf_file = file_exists = false;
skip_obsoletes = xucd_stats = false;
ar_rv = rv = entry_type = flags = 0;
@@ -258,19 +186,19 @@ unpack_archive(struct xbps_handle *xhp,
goto out;
}
} else if (strcmp("./props.plist", entry_pname) == 0) {
propsd = xbps_archive_get_dictionary(ar, entry);
if (propsd == NULL) {
binpkg_propsd = xbps_archive_get_dictionary(ar, entry);
if (binpkg_propsd == NULL) {
rv = EINVAL;
goto out;
}
} else if (strcmp("./files.plist", entry_pname) == 0) {
filesd = xbps_archive_get_dictionary(ar, entry);
if (filesd == NULL) {
binpkg_filesd = xbps_archive_get_dictionary(ar, entry);
if (binpkg_filesd == NULL) {
rv = EINVAL;
goto out;
}
}
if (propsd && filesd)
if (binpkg_propsd && binpkg_filesd)
break;
}
/*
@@ -286,24 +214,40 @@ unpack_archive(struct xbps_handle *xhp,
/*
* Bail out if required metadata files are not in archive.
*/
if (propsd == NULL || filesd == NULL) {
if (binpkg_propsd == NULL || binpkg_filesd == NULL) {
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, ENODEV, pkgver,
"%s: [unpack] invalid binary package `%s'.", pkgver, fname);
rv = ENODEV;
goto out;
}
/*
* Create new metaplist file before unpacking any real file.
* Internalize current pkg metadata files plist.
*/
metapropsd = xbps_pkgdb_get_pkg_metadata(xhp, pkgname);
rv = create_pkg_metaplist(xhp, pkgname, pkgver,
propsd, filesd, instbuf, instbufsiz, rembuf, rembufsiz);
if (rv != 0) {
pkg_filesd = xbps_pkgdb_get_pkg_files(xhp, pkgname);
/* Add pkg install/remove scripts data objects into our dictionary */
if (instbuf != NULL) {
data = xbps_data_create_data(instbuf, instbufsiz);
assert(data);
xbps_dictionary_set(pkg_repod, "install-script", data);
xbps_object_release(data);
}
if (rembuf != NULL) {
data = xbps_data_create_data(rembuf, rembufsiz);
assert(data);
xbps_dictionary_set(pkg_repod, "remove-script", data);
xbps_object_release(data);
}
buf = xbps_xasprintf("%s/.%s-files.plist", xhp->metadir, pkgname);
if (!xbps_dictionary_externalize_to_file(binpkg_filesd, buf)) {
free(buf);
rv = errno;
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL, rv, pkgver,
"%s: [unpack] failed to create metaplist file: %s",
"%s: [unpack] failed to externalize pkg metadata files: %s",
pkgver, strerror(rv));
goto out;
}
free(buf);
/*
* Execute INSTALL "pre" ACTION before unpacking files.
*/
@@ -350,14 +294,14 @@ unpack_archive(struct xbps_handle *xhp,
* Compute total entries in progress data, if set.
* total_entries = files + conf_files + links.
*/
if (filesd && !xucd_stats) {
array = xbps_dictionary_get(filesd, "files");
if (binpkg_filesd && !xucd_stats) {
array = xbps_dictionary_get(binpkg_filesd, "files");
xucd.entry_total_count +=
(ssize_t)xbps_array_count(array);
array = xbps_dictionary_get(filesd, "conf_files");
array = xbps_dictionary_get(binpkg_filesd, "conf_files");
xucd.entry_total_count +=
(ssize_t)xbps_array_count(array);
array = xbps_dictionary_get(filesd, "links");
array = xbps_dictionary_get(binpkg_filesd, "links");
xucd.entry_total_count +=
(ssize_t)xbps_array_count(array);
xucd_stats = true;
@@ -401,14 +345,14 @@ unpack_archive(struct xbps_handle *xhp,
* "conf_files" array on its XBPS_PKGPROPS
* dictionary.
*/
if (xbps_entry_is_a_conf_file(filesd, buf)) {
if (xbps_entry_is_a_conf_file(binpkg_filesd, buf)) {
conf_file = true;
if (xhp->unpack_cb != NULL)
xucd.entry_is_conf = true;
rv = xbps_entry_install_conf_file(xhp,
filesd, entry, entry_pname, pkgver,
pkgname);
binpkg_filesd, pkg_filesd, entry,
entry_pname, pkgver, pkgname);
if (rv == -1) {
/* error */
goto out;
@@ -421,7 +365,7 @@ unpack_archive(struct xbps_handle *xhp,
rv = 0;
} else {
rv = xbps_file_hash_check_dictionary(
xhp, filesd, "files", buf);
xhp, binpkg_filesd, "files", buf);
if (rv == -1) {
/* error */
xbps_dbg_printf(xhp,
@@ -456,7 +400,7 @@ unpack_archive(struct xbps_handle *xhp,
p += strlen(xhp->rootdir);
} else
p = buf;
tgtlnk = find_pkg_symlink_target(filesd,
tgtlnk = find_pkg_symlink_target(binpkg_filesd,
entry_pname);
assert(tgtlnk);
if (strncmp(tgtlnk, "./", 2) == 0) {
@@ -573,10 +517,10 @@ unpack_archive(struct xbps_handle *xhp,
* - Package reinstall.
* - Package upgrade.
*/
if (metapropsd == NULL || !xbps_dictionary_count(metapropsd))
if (pkg_filesd == NULL || !xbps_dictionary_count(pkg_filesd))
goto out;
obsoletes = xbps_find_pkg_obsoletes(xhp, metapropsd, filesd);
obsoletes = xbps_find_pkg_obsoletes(xhp, pkg_filesd, binpkg_filesd);
for (unsigned int i = 0; i < xbps_array_count(obsoletes); i++) {
obj = xbps_array_get(obsoletes, i);
file = xbps_string_cstring_nocopy(obj);
@@ -593,13 +537,13 @@ unpack_archive(struct xbps_handle *xhp,
0, pkgver, "%s: removed obsolete entry: %s", pkgver, file);
xbps_object_release(obj);
}
xbps_object_release(metapropsd);
xbps_object_release(pkg_filesd);
out:
if (xbps_object_type(filesd) == XBPS_TYPE_DICTIONARY)
xbps_object_release(filesd);
if (xbps_object_type(propsd) == XBPS_TYPE_DICTIONARY)
xbps_object_release(propsd);
if (xbps_object_type(binpkg_filesd) == XBPS_TYPE_DICTIONARY)
xbps_object_release(binpkg_filesd);
if (xbps_object_type(binpkg_propsd) == XBPS_TYPE_DICTIONARY)
xbps_object_release(binpkg_propsd);
if (pkgname != NULL)
free(pkgname);
if (instbuf != NULL)
@@ -670,6 +614,19 @@ xbps_unpack_binary_pkg(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod)
pkgver, bpkg, strerror(rv));
goto out;
}
/*
* Externalize pkg files dictionary to metadir.
*/
if (access(xhp->metadir, R_OK|X_OK) == -1) {
rv = errno;
if (rv != ENOENT)
goto out;
if (xbps_mkpath(xhp->metadir, 0755) == -1) {
rv = errno;
goto out;
}
}
/*
* Extract archive files.
*/
@@ -682,7 +639,7 @@ xbps_unpack_binary_pkg(struct xbps_handle *xhp, xbps_dictionary_t pkg_repod)
/*
* Set package state to unpacked.
*/
if ((rv = xbps_set_pkg_state_installed(xhp, pkgver,
if ((rv = xbps_set_pkg_state_dictionary(pkg_repod,
XBPS_PKG_STATE_UNPACKED)) != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_UNPACK_FAIL,
rv, pkgver,

View File

@@ -124,11 +124,15 @@ xbps_pkgdb_init(struct xbps_handle *xhp)
assert(xhp != NULL);
if (xhp->pkgdb != NULL)
return 0;
if (xhp->pkgdb_plist == NULL)
xhp->pkgdb_plist = xbps_xasprintf("%s/%s", xhp->metadir, XBPS_PKGDB);
if ((rv = xbps_pkgdb_conversion(xhp)) != 0)
return rv;
if (xhp->pkgdb != NULL)
return 0;
if ((rv = xbps_pkgdb_update(xhp, false)) != 0) {
if (rv != ENOENT)
xbps_dbg_printf(xhp, "[pkgdb] cannot internalize "
@@ -190,9 +194,6 @@ xbps_pkgdb_release(struct xbps_handle *xhp)
/* write pkgdb to storage in case it was modified */
(void)xbps_pkgdb_update(xhp, true);
if (xbps_object_type(xhp->pkg_metad) == XBPS_TYPE_DICTIONARY)
xbps_object_release(xhp->pkg_metad);
xbps_object_release(xhp->pkgdb);
xhp->pkgdb = NULL;
xbps_dbg_printf(xhp, "[pkgdb] released ok.\n");
@@ -327,9 +328,9 @@ xbps_pkgdb_get_pkg_revdeps(struct xbps_handle *xhp, const char *pkg)
}
xbps_dictionary_t
xbps_pkgdb_get_pkg_metadata(struct xbps_handle *xhp, const char *pkg)
xbps_pkgdb_get_pkg_files(struct xbps_handle *xhp, const char *pkg)
{
xbps_dictionary_t pkgd, pkg_metad;
xbps_dictionary_t pkgd, pkgfilesd;
const char *pkgver;
char *pkgname, *plist;
@@ -344,27 +345,16 @@ xbps_pkgdb_get_pkg_metadata(struct xbps_handle *xhp, const char *pkg)
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
if ((pkg_metad = xbps_dictionary_get(xhp->pkg_metad, pkgname)) != NULL) {
free(pkgname);
return pkg_metad;
}
plist = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
pkg_metad = xbps_dictionary_internalize_from_file(plist);
plist = xbps_xasprintf("%s/.%s-files.plist", xhp->metadir, pkgname);
free(pkgname);
pkgfilesd = xbps_dictionary_internalize_from_file(plist);
free(plist);
if (pkg_metad == NULL) {
if (pkgfilesd == NULL) {
xbps_dbg_printf(xhp, "[pkgdb] cannot read %s metadata: %s\n",
pkgver, strerror(errno));
free(pkgname);
return NULL;
}
if (xhp->pkg_metad == NULL)
xhp->pkg_metad = xbps_dictionary_create();
xbps_dictionary_set(xhp->pkg_metad, pkgname, pkg_metad);
xbps_object_release(pkg_metad);
free(pkgname);
return pkg_metad;
return pkgfilesd;
}

211
lib/pkgdb_conversion.c Normal file
View File

@@ -0,0 +1,211 @@
/*-
* Copyright (c) 2014 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 <sys/stat.h>
#include <fcntl.h>
#include "xbps_api_impl.h"
static int
pkgdb038(struct xbps_handle *xhp, const char *opkgdb_plist)
{
xbps_dictionary_t pkgdb, opkgdb;
xbps_object_iterator_t iter;
xbps_object_t obj;
int rv = 0;
/*
* The pkgdb-0.38.plist format contains all pkg metadata objects,
* except its files list. To avoid a broken conversion, the old
* pkg metadata plists are kept, and the converted ones are written
* to another path.
*
* - <metadir>/pkgdb-0.38.plist
* - <metadir>/.<pkgname>-files.plist
*/
opkgdb = xbps_dictionary_internalize_from_file(opkgdb_plist);
if (opkgdb == NULL)
return EINVAL;
pkgdb = xbps_dictionary_create();
assert(pkgdb);
/*
* Iterate over the old pkgdb dictionary and copy all pkg objects
* into the new pkgdb dictionary.
*/
iter = xbps_dictionary_iterator(opkgdb);
assert(iter);
while ((obj = xbps_object_iterator_next(iter))) {
xbps_dictionary_t pkgd, pkgfilesd, pkgmetad;
xbps_object_iterator_t iter2;
xbps_object_t obj2;
const char *pkgname;
char *pkgmeta;
pkgname = xbps_dictionary_keysym_cstring_nocopy(obj);
pkgd = xbps_dictionary_get_keysym(opkgdb, obj);
/*
* Copy old pkgdb objects to the new pkgdb.
*/
if (!xbps_dictionary_set(pkgdb, pkgname, pkgd)) {
xbps_dbg_printf(xhp, "%s: failed to copy %s pkgd "
"for pkgdb conversion\n", __func__, pkgname);
rv = EINVAL;
goto out;
}
/*
* Copy pkg metadata objs to the new pkgdb.
*/
pkgmeta = xbps_xasprintf("%s/.%s.plist", xhp->metadir, pkgname);
pkgmetad = xbps_dictionary_internalize_from_file(pkgmeta);
if (pkgmetad == NULL) {
rv = EINVAL;
xbps_dbg_printf(xhp, "%s: cannot open %s: %s\n",
__func__, pkgmeta, strerror(errno));
goto out;
}
pkgfilesd = xbps_dictionary_create();
assert(pkgfilesd);
iter2 = xbps_dictionary_iterator(pkgmetad);
assert(iter2);
while ((obj2 = xbps_object_iterator_next(iter2))) {
xbps_object_t curobj;
const char *key, *excluded[] = {
"conf_files", "dirs", "files", "links"
};
bool skip = false;
key = xbps_dictionary_keysym_cstring_nocopy(obj2);
curobj = xbps_dictionary_get_keysym(pkgmetad, obj2);
for (uint8_t i = 0; i < __arraycount(excluded); i++) {
if (strcmp(excluded[i], key) == 0) {
skip = true;
break;
}
}
if (skip) {
assert(xbps_object_type(curobj) == XBPS_TYPE_ARRAY);
if (xbps_array_count(curobj))
xbps_dictionary_set(pkgfilesd, key, curobj);
continue;
}
if (!xbps_dictionary_set(pkgd, key, curobj)) {
xbps_dbg_printf(xhp, "%s: failed to copy %s "
"pkgd for pkgdb conversion\n", pkgname, key);
xbps_object_iterator_release(iter2);
xbps_object_release(pkgmetad);
free(pkgmeta);
rv = EINVAL;
goto out;
}
}
xbps_object_iterator_release(iter2);
/*
* Externalize <pkgname>-files.plist if pkg contains any file.
*/
if (xbps_dictionary_count(pkgfilesd)) {
char *pkgfiles, *sha256;
pkgfiles = xbps_xasprintf("%s/.%s-files.plist", xhp->metadir, pkgname);
if (!xbps_dictionary_externalize_to_file(pkgfilesd, pkgfiles)) {
xbps_dbg_printf(xhp, "%s: failed to "
"externalize %s: %s\n", __func__, pkgfiles, strerror(errno));
rv = EINVAL;
goto out;
}
xbps_dbg_printf(xhp, "%s: externalized %s successfully\n", __func__, pkgfiles);
/*
* Update SHA56 hash for the pkg files plist.
*/
sha256 = xbps_file_hash(pkgfiles);
assert(sha256);
xbps_dictionary_set_cstring(pkgd, "metafile-sha256", sha256);
free(sha256);
free(pkgfiles);
}
xbps_object_release(pkgfilesd);
xbps_object_release(pkgmetad);
free(pkgmeta);
}
/*
* Externalize the new pkgdb plist.
*/
if (!xbps_dictionary_externalize_to_file(pkgdb, xhp->pkgdb_plist)) {
xbps_dbg_printf(xhp, "%s: failed to externalize %s: "
"%s!\n", __func__, xhp->pkgdb_plist, strerror(errno));
rv = EINVAL;
goto out;
}
out:
if (iter)
xbps_object_iterator_release(iter);
if (pkgdb)
xbps_object_release(pkgdb);
if (opkgdb)
xbps_object_release(opkgdb);
return rv;
}
int HIDDEN
xbps_pkgdb_conversion(struct xbps_handle *xhp)
{
char *opkgdb = NULL;
int rv = 0;
/*
* If pkgdb-0.38.plist exists there's nothing to do.
*/
if (xhp && xhp->pkgdb_plist && (access(xhp->pkgdb_plist, R_OK) == 0))
return 0;
/*
* If pkgdb-0.21.plist does not exist there's nothing to do.
*/
opkgdb = xbps_xasprintf("%s/pkgdb-0.21.plist", xhp->metadir);
if (access(opkgdb, R_OK) == 0) {
/*
* Make the conversion and exit on success. It's just
* better to make the upgrade in two steps.
*/
xbps_set_cb_state(xhp, XBPS_STATE_PKGDB, 0, NULL, NULL);
if ((rv = pkgdb038(xhp, opkgdb)) == 0) {
xbps_set_cb_state(xhp, XBPS_STATE_PKGDB_DONE, 0, NULL, NULL);
xbps_end(xhp);
exit(EXIT_SUCCESS);
}
}
free(opkgdb);
return rv;
}

View File

@@ -49,7 +49,8 @@ store_dependency(struct xbps_handle *xhp,
/*
* Add required objects into package dep's dictionary.
*/
if (!xbps_dictionary_set_bool(repo_pkgd, "automatic-install", true))
if (!xbps_dictionary_get(repo_pkgd, "automatic-install") &&
!xbps_dictionary_set_bool(repo_pkgd, "automatic-install", true))
return EINVAL;
xbps_dictionary_get_cstring_nocopy(repo_pkgd, "pkgver", &pkgver);

View File

@@ -121,7 +121,7 @@ compute_transaction_stats(struct xbps_handle *xhp)
pkgname = xbps_pkg_name(pkgver);
assert(pkgname);
pkg_metad = xbps_pkgdb_get_pkg_metadata(xhp, pkgname);
pkg_metad = xbps_pkgdb_get_pkg(xhp, pkgname);
free(pkgname);
if (pkg_metad == NULL)
continue;
@@ -220,6 +220,18 @@ xbps_transaction_init(struct xbps_handle *xhp)
}
xbps_object_release(array);
if ((array = xbps_array_create()) == NULL) {
xbps_object_release(xhp->transd);
xhp->transd = NULL;
return ENOMEM;
}
if (!xbps_dictionary_set(xhp->transd, "missing_shlibs", array)) {
xbps_object_release(xhp->transd);
xhp->transd = NULL;
return EINVAL;
}
xbps_object_release(array);
if ((array = xbps_array_create()) == NULL) {
xbps_object_release(xhp->transd);
xhp->transd = NULL;
@@ -270,7 +282,6 @@ xbps_transaction_prepare(struct xbps_handle *xhp)
array = xbps_dictionary_get(xhp->transd, "conflicts");
if (xbps_array_count(array))
return EAGAIN;
/*
* Check for packages to be replaced.
*/
@@ -301,9 +312,10 @@ xbps_transaction_prepare(struct xbps_handle *xhp)
return rv;
}
/*
* The missing deps and conflicts arrays are not necessary anymore.
* Remove now unneeded objects.
*/
xbps_dictionary_remove(xhp->transd, "unsorted");
xbps_dictionary_remove(xhp->transd, "missing_shlibs");
xbps_dictionary_remove(xhp->transd, "missing_deps");
xbps_dictionary_remove(xhp->transd, "conflicts");
xbps_dictionary_make_immutable(xhp->transd);

View File

@@ -136,8 +136,8 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall)
* If pkg is already installed, respect its automatic-install
* property.
*/
xbps_dictionary_get_bool(pkg_pkgdb, "automatic-install", &autoinst);
xbps_dictionary_set_bool(pkg_repod, "automatic-install", autoinst);
if (xbps_dictionary_get_bool(pkg_pkgdb, "automatic-install", &autoinst))
xbps_dictionary_set_bool(pkg_repod, "automatic-install", autoinst);
}
/*
* Prepare transaction dictionary.

View File

@@ -57,18 +57,16 @@ shlib_in_pkgdb(struct xbps_handle *xhp, const char *pkgver, const char *shlib)
while ((obj = xbps_object_iterator_next(iter))) {
xbps_array_t shprovides;
xbps_dictionary_t pkgd, pkgmetad;
xbps_dictionary_t pkgd;
const char *curpkgver;
pkgd = xbps_dictionary_get_keysym(xhp->pkgdb, obj);
xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &curpkgver);
pkgmetad = xbps_pkgdb_get_pkg_metadata(xhp, curpkgver);
assert(pkgmetad);
shprovides = xbps_dictionary_get(pkgmetad, "shlib-provides");
shprovides = xbps_dictionary_get(pkgd, "shlib-provides");
if (!shprovides)
continue;
if (xbps_match_string_in_array(shprovides, shlib)) {
/* shlib matched */
xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &curpkgver);
xbps_dbg_printf(xhp, "[trans] %s requires `%s': "
"matched by `%s' (pkgdb)\n", pkgver, shlib, curpkgver);
found = true;
@@ -109,9 +107,10 @@ shlib_in_transaction(struct xbps_handle *xhp, const char *pkgver, const char *sh
bool HIDDEN
xbps_transaction_shlibs(struct xbps_handle *xhp)
{
xbps_array_t unsorted;
xbps_array_t unsorted, mshlibs;
bool unmatched = false;
mshlibs = xbps_dictionary_get(xhp->transd, "missing_shlibs");
unsorted = xbps_dictionary_get(xhp->transd, "unsorted_deps");
for (unsigned int i = 0; i < xbps_array_count(unsorted); i++) {
xbps_array_t shrequires;
@@ -142,8 +141,13 @@ xbps_transaction_shlibs(struct xbps_handle *xhp)
xbps_array_get_cstring_nocopy(shrequires, x, &shlib);
if ((!shlib_in_pkgdb(xhp, pkgver, shlib)) &&
(!shlib_in_transaction(xhp, pkgver, shlib))) {
xbps_dbg_printf(xhp, "[trans] %s: needs `%s' "
"not provided by any pkg!\n", pkgver, shlib);
char *buf;
buf = xbps_xasprintf("%s: needs `%s' shlib, not"
" provided by any pkg!", pkgver, shlib);
xbps_dbg_printf(xhp, "%s\n", buf);
xbps_array_add_cstring(mshlibs, buf);
free(buf);
unmatched = true;
}
}