Implement support to update required_by objs when removing a pkg.

--HG--
extra : convert_revision : 405986d806ff23ce6348b22a2d7c48e0820ab1b9
This commit is contained in:
Juan RP 2009-02-27 16:03:25 +01:00
parent a711ace8f7
commit d9cc1d6b8f
8 changed files with 169 additions and 96 deletions

View file

@ -35,7 +35,8 @@ int xbps_register_pkg(prop_dictionary_t, const char *, const char *,
const char *, bool);
int xbps_unpack_binary_pkg(prop_dictionary_t, prop_dictionary_t,
const char *, int);
int xbps_update_pkg_requiredby(prop_array_t, prop_dictionary_t);
int xbps_requiredby_pkg_add(prop_array_t, prop_dictionary_t);
int xbps_requiredby_pkg_remove(const char *);
int xbps_find_deps_in_pkg(prop_dictionary_t);
prop_dictionary_t xbps_get_pkg_deps_dictionary(void);

View file

@ -64,6 +64,9 @@ xbps_find_pkg_in_dict(prop_dictionary_t, const char *, const char *);
prop_dictionary_t
xbps_find_pkg_from_plist(const char *, const char *);
prop_dictionary_t
xbps_find_pkg_installed_from_plist(const char *);
/*
* Finds a string object in an array.
*

View file

@ -83,10 +83,10 @@ xbps_install_binary_pkg(const char *pkgname, const char *destdir, int flags)
assert(pkgname != NULL);
if (destdir) {
if ((rv = chdir(destdir)) != 0)
if (chdir(destdir) == -1)
return errno;
} else {
if ((rv = chdir("/")) != 0)
if (chdir("/") == -1)
return errno;
destdir = "NOTSET";
}
@ -138,6 +138,10 @@ install_binpkg_repo_cb(prop_object_t obj, void *arg, bool *cbloop_done)
return 0;
}
/*
* Check SHA256 hash for binary package before anything else.
*/
/*
* Check if this package needs dependencies.
*/
@ -167,7 +171,6 @@ install_binpkg_repo_cb(prop_object_t obj, void *arg, bool *cbloop_done)
if ((rv = xbps_install_pkg_deps(pkgname, destdir, cb->flags)) == 0) {
rv = xbps_install_binary_pkg_fini(repod, pkgrd, destdir,
cb->flags);
prop_object_release(repod);
if (rv == 0)
*cbloop_done = true;
}
@ -176,6 +179,8 @@ install_binpkg_repo_cb(prop_object_t obj, void *arg, bool *cbloop_done)
if (rv == 0)
errno = 0;
prop_object_release(repod);
return rv;
}
@ -263,7 +268,7 @@ xbps_register_pkg(prop_dictionary_t pkgrd, const char *pkgname,
automatic);
if (pkgrd && xbps_pkg_has_rundeps(pkgrd)) {
rv = xbps_update_pkg_requiredby(array, pkgrd);
rv = xbps_requiredby_pkg_add(array, pkgrd);
if (rv != 0) {
prop_object_release(pkgd);
goto out;

View file

@ -130,8 +130,7 @@ xbps_callback_array_iter_in_dict(prop_dictionary_t dict, const char *key,
prop_dictionary_t
xbps_find_pkg_from_plist(const char *plist, const char *pkgname)
{
prop_dictionary_t dict;
prop_dictionary_t obj, res;
prop_dictionary_t dict, obj, res;
assert(plist != NULL);
assert(pkgname != NULL);
@ -155,6 +154,22 @@ xbps_find_pkg_from_plist(const char *plist, const char *pkgname)
return res;
}
prop_dictionary_t
xbps_find_pkg_installed_from_plist(const char *pkgname)
{
prop_dictionary_t pkgd;
char *plist;
plist = xbps_append_full_path(true, NULL, XBPS_REGPKGDB);
if (plist == NULL)
return NULL;
pkgd = xbps_find_pkg_from_plist(plist, pkgname);
free(plist);
return prop_dictionary_copy(pkgd);
}
prop_dictionary_t
xbps_find_pkg_in_dict(prop_dictionary_t dict, const char *key,
const char *pkgname)

View file

@ -172,7 +172,7 @@ out:
int
xbps_remove_binary_pkg(const char *pkgname, const char *destdir, int flags)
{
prop_dictionary_t fdict;
prop_dictionary_t dict;
struct rm_cbarg rmcbarg;
char path[PATH_MAX - 1], *buf;
int fd, rv = 0;
@ -202,18 +202,22 @@ xbps_remove_binary_pkg(const char *pkgname, const char *destdir, int flags)
return -1;
}
/* Find out if the REMOVE file exists */
/*
* Find out if the REMOVE file exists.
*/
if ((fd = open(buf, O_RDONLY)) == -1) {
if (errno != ENOENT) {
free(buf);
return errno;
}
} else {
/* Run the preremove action */
/*
* Run the pre remove action.
*/
(void)close(fd);
prepostf = true;
if ((rv = xbps_file_exec(buf, destdir, "pre", pkgname,
NULL)) != 0) {
rv = xbps_file_exec(buf, destdir, "pre", pkgname, NULL);
if (rv != 0) {
printf("%s: prerm action target error (%s)\n", pkgname,
strerror(errno));
free(buf);
@ -228,8 +232,8 @@ xbps_remove_binary_pkg(const char *pkgname, const char *destdir, int flags)
(void)snprintf(path, sizeof(path), "%s%s/metadata/%s/files.plist",
destdir, XBPS_META_PATH, pkgname);
fdict = prop_dictionary_internalize_from_file(path);
if (fdict == NULL) {
dict = prop_dictionary_internalize_from_file(path);
if (dict == NULL) {
free(buf);
return errno;
}
@ -237,18 +241,19 @@ xbps_remove_binary_pkg(const char *pkgname, const char *destdir, int flags)
rmcbarg.destdir = destdir;
rmcbarg.flags = flags;
rv = xbps_callback_array_iter_in_dict(fdict, "filelist",
rv = xbps_callback_array_iter_in_dict(dict, "filelist",
remove_pkg_files, (void *)&rmcbarg);
if (rv != 0) {
free(buf);
prop_object_release(fdict);
prop_object_release(dict);
return rv;
}
prop_object_release(fdict);
prop_object_release(dict);
/* If successful, unregister pkg from db */
if (((rv = xbps_unregister_pkg(pkgname)) == 0) && prepostf) {
/* Run the postremove action target */
/*
* Run the post remove action if REMOVE file is there.
*/
if (prepostf) {
if ((rv = xbps_file_exec(buf, destdir, "post",
pkgname, NULL)) != 0) {
printf("%s: postrm action target error (%s)\n",
@ -257,9 +262,24 @@ xbps_remove_binary_pkg(const char *pkgname, const char *destdir, int flags)
return rv;
}
}
free(buf);
rv = xbps_remove_binary_pkg_meta(pkgname, destdir, flags);
return rv;
/*
* Update the required_by array of all required dependencies.
*/
rv = xbps_requiredby_pkg_remove(pkgname);
if (rv != 0)
return rv;
/*
* Unregister pkg from database.
*/
rv = xbps_unregister_pkg(pkgname);
if (rv != 0)
return rv;
/*
* Remove pkg metadata directory.
*/
return xbps_remove_binary_pkg_meta(pkgname, destdir, flags);
}

View file

@ -35,7 +35,7 @@
#include <xbps_api.h>
static int
add_pkg_into_requiredby(prop_dictionary_t pkgd, const char *reqname)
add_pkg_into_reqby(prop_dictionary_t pkgd, const char *reqname)
{
prop_array_t array;
prop_string_t reqstr;
@ -80,8 +80,77 @@ add_pkg_into_requiredby(prop_dictionary_t pkgd, const char *reqname)
return 0;
}
static int
remove_pkg_from_reqby(prop_object_t obj, void *arg, bool *loop_done)
{
prop_array_t array;
prop_object_t obj2;
prop_object_iterator_t iter;
const char *pkgname = arg;
char *curpkgname;
size_t idx = 0;
bool found = false;
(void)loop_done;
array = prop_dictionary_get(obj, "requiredby");
if (array == NULL || prop_array_count(array) == 0)
return 0;
iter = prop_array_iterator(array);
if (iter == NULL)
return ENOMEM;
while ((obj2 = prop_object_iterator_next(iter)) != NULL) {
curpkgname =
xbps_get_pkg_name(prop_string_cstring_nocopy(obj2));
if (strcmp(curpkgname, pkgname) == 0) {
free(curpkgname);
found = true;
break;
}
free(curpkgname);
idx++;
}
prop_object_iterator_release(iter);
if (found)
prop_array_remove(array, idx);
return 0;
}
int
xbps_update_pkg_requiredby(prop_array_t regar, prop_dictionary_t pkg)
xbps_requiredby_pkg_remove(const char *pkgname)
{
prop_dictionary_t dict;
char *plist;
int rv = 0;
plist = xbps_append_full_path(true, NULL, XBPS_REGPKGDB);
if (plist == NULL)
return EINVAL;
dict = prop_dictionary_internalize_from_file(plist);
if (dict == NULL) {
free(plist);
return errno;
}
rv = xbps_callback_array_iter_in_dict(dict, "packages",
remove_pkg_from_reqby, (void *)pkgname);
if (rv == 0) {
if (!prop_dictionary_externalize_to_file(dict, plist))
rv = errno;
}
prop_object_release(dict);
free(plist);
return rv;
}
int
xbps_requiredby_pkg_add(prop_array_t regar, prop_dictionary_t pkg)
{
prop_array_t rdeps;
prop_object_t obj, obj2;
@ -114,13 +183,11 @@ xbps_update_pkg_requiredby(prop_array_t regar, prop_dictionary_t pkg)
while ((obj = prop_object_iterator_next(iter)) != NULL) {
rdepname = xbps_get_pkg_name(prop_string_cstring_nocopy(obj));
iter2 = prop_array_iterator(regar);
if (iter2 == NULL) {
free(fpkgn);
free(rdepname);
prop_object_iterator_release(iter);
return ENOMEM;
rv = ENOMEM;
goto out;
}
/*
@ -131,7 +198,7 @@ xbps_update_pkg_requiredby(prop_array_t regar, prop_dictionary_t pkg)
prop_dictionary_get_cstring_nocopy(obj2, "pkgname",
&reqname);
if (strcmp(rdepname, reqname) == 0) {
rv = add_pkg_into_requiredby(obj2, fpkgn);
rv = add_pkg_into_reqby(obj2, fpkgn);
if (rv != 0) {
free(rdepname);
prop_object_iterator_release(iter2);
@ -140,8 +207,8 @@ xbps_update_pkg_requiredby(prop_array_t regar, prop_dictionary_t pkg)
break;
}
}
free(rdepname);
prop_object_iterator_release(iter2);
free(rdepname);
}
out:

View file

@ -123,7 +123,7 @@ unpack_archive_init(prop_dictionary_t pkg, const char *destdir,
* is really on storage (if possible).
*/
if (rv == 0)
if ((rv = fdatasync(pkg_fd)) == -1)
if (fdatasync(pkg_fd) == -1)
rv = errno;
archive_read_finish(ar);
@ -149,11 +149,10 @@ unpack_archive_fini(struct archive *ar, const char *destdir, int flags,
prop_dictionary_t pkg)
{
struct archive_entry *entry;
struct stat st;
size_t len;
const char *prepost = "./INSTALL";
const char *pkgname, *version;
char *buf, *path;
char *buf;
int rv = 0, lflags = 0;
bool actgt = false;
@ -183,23 +182,6 @@ unpack_archive_fini(struct archive *ar, const char *destdir, int flags,
}
while (archive_read_next_header(ar, &entry) == ARCHIVE_OK) {
/*
* Check that entry doesn't already exist.
*/
path = xbps_append_full_path(false, destdir,
archive_entry_pathname(entry));
if (path == NULL) {
rv = ENOMEM;
break;
}
rv = stat(path, &st);
if (rv == 0) {
free(path);
continue;
}
free(path);
/*
* Run the pre installation action target if there's a script
* before writing data to disk.
@ -211,9 +193,10 @@ unpack_archive_fini(struct archive *ar, const char *destdir, int flags,
archive_entry_set_pathname(entry, buf);
rv = archive_read_extract(ar, entry, lflags);
if (rv != 0 && errno != EEXIST)
break;
if (archive_read_extract(ar, entry, lflags) != 0) {
if ((rv = archive_errno(ar)) != EEXIST)
break;
}
if ((rv = xbps_file_exec(buf, destdir, "pre",
pkgname, version, NULL)) != 0) {
@ -229,19 +212,24 @@ unpack_archive_fini(struct archive *ar, const char *destdir, int flags,
/*
* Extract all data from the archive now.
*/
rv = archive_read_extract(ar, entry, lflags);
if (rv != 0 && errno != EEXIST) {
printf("ERROR: couldn't unpack %s (%s), exiting!\n",
archive_entry_pathname(entry), strerror(errno));
(void)fflush(stdout);
break;
} else if (rv != 0 && errno == EEXIST) {
if (flags & XBPS_UNPACK_VERBOSE) {
printf("WARNING: ignoring existent path: %s.\n",
archive_entry_pathname(entry));
if (archive_read_extract(ar, entry, lflags) != 0) {
rv = archive_errno(ar);
if (rv != EEXIST) {
printf("ERROR: couldn't unpack %s (%s), "
"exiting!\n", archive_entry_pathname(entry),
archive_error_string(ar));
(void)fflush(stdout);
break;
} else if (rv == EEXIST) {
if (flags & XBPS_UNPACK_VERBOSE) {
printf("WARNING: ignoring existent "
"path: %s\n",
archive_entry_pathname(entry));
(void)fflush(stdout);
}
rv = 0;
continue;
}
continue;
}
if (flags & XBPS_UNPACK_VERBOSE) {

View file

@ -64,49 +64,29 @@ xbps_check_file_hash(const char *path, const char *sha256)
int
xbps_check_is_installed_pkg(const char *pkg)
{
prop_dictionary_t dict, pkgdict;
prop_object_t obj;
prop_dictionary_t dict;
const char *reqver, *instver;
char *plist, *pkgname;
char *pkgname;
int rv = 0;
assert(pkg != NULL);
plist = xbps_append_full_path(true, NULL, XBPS_REGPKGDB);
if (plist == NULL)
return -1;
pkgname = xbps_get_pkg_name(pkg);
reqver = xbps_get_pkg_version(pkg);
/* Get package dictionary from plist */
dict = prop_dictionary_internalize_from_file(plist);
dict = xbps_find_pkg_installed_from_plist(pkgname);
if (dict == NULL) {
free(pkgname);
free(plist);
return 1; /* not installed */
}
pkgdict = xbps_find_pkg_in_dict(dict, "packages", pkgname);
if (pkgdict == NULL) {
prop_object_release(dict);
free(pkgname);
free(plist);
return 1; /* not installed */
}
/* Get version from installed package */
obj = prop_dictionary_get(pkgdict, "version");
assert(obj != NULL);
assert(prop_object_type(obj) == PROP_TYPE_STRING);
instver = prop_string_cstring_nocopy(obj);
assert(instver != NULL);
prop_dictionary_get_cstring_nocopy(dict, "version", &instver);
/* Compare installed and required version. */
rv = xbps_cmpver_versions(instver, reqver);
free(pkgname);
free(plist);
prop_object_release(dict);
return rv;
@ -116,16 +96,10 @@ bool
xbps_check_is_installed_pkgname(const char *pkgname)
{
prop_dictionary_t pkgd;
char *plist;
assert(pkgname != NULL);
plist = xbps_append_full_path(true, NULL, XBPS_REGPKGDB);
if (plist == NULL)
return false;
pkgd = xbps_find_pkg_from_plist(plist, pkgname);
free(plist);
pkgd = xbps_find_pkg_installed_from_plist(pkgname);
if (pkgd) {
prop_object_release(pkgd);
return true;