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

View file

@ -130,8 +130,7 @@ xbps_callback_array_iter_in_dict(prop_dictionary_t dict, const char *key,
prop_dictionary_t prop_dictionary_t
xbps_find_pkg_from_plist(const char *plist, const char *pkgname) xbps_find_pkg_from_plist(const char *plist, const char *pkgname)
{ {
prop_dictionary_t dict; prop_dictionary_t dict, obj, res;
prop_dictionary_t obj, res;
assert(plist != NULL); assert(plist != NULL);
assert(pkgname != NULL); assert(pkgname != NULL);
@ -155,6 +154,22 @@ xbps_find_pkg_from_plist(const char *plist, const char *pkgname)
return res; 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 prop_dictionary_t
xbps_find_pkg_in_dict(prop_dictionary_t dict, const char *key, xbps_find_pkg_in_dict(prop_dictionary_t dict, const char *key,
const char *pkgname) const char *pkgname)

View file

@ -172,7 +172,7 @@ out:
int int
xbps_remove_binary_pkg(const char *pkgname, const char *destdir, int flags) xbps_remove_binary_pkg(const char *pkgname, const char *destdir, int flags)
{ {
prop_dictionary_t fdict; prop_dictionary_t dict;
struct rm_cbarg rmcbarg; struct rm_cbarg rmcbarg;
char path[PATH_MAX - 1], *buf; char path[PATH_MAX - 1], *buf;
int fd, rv = 0; int fd, rv = 0;
@ -202,18 +202,22 @@ xbps_remove_binary_pkg(const char *pkgname, const char *destdir, int flags)
return -1; return -1;
} }
/* Find out if the REMOVE file exists */ /*
* Find out if the REMOVE file exists.
*/
if ((fd = open(buf, O_RDONLY)) == -1) { if ((fd = open(buf, O_RDONLY)) == -1) {
if (errno != ENOENT) { if (errno != ENOENT) {
free(buf); free(buf);
return errno; return errno;
} }
} else { } else {
/* Run the preremove action */ /*
* Run the pre remove action.
*/
(void)close(fd); (void)close(fd);
prepostf = true; prepostf = true;
if ((rv = xbps_file_exec(buf, destdir, "pre", pkgname, rv = xbps_file_exec(buf, destdir, "pre", pkgname, NULL);
NULL)) != 0) { if (rv != 0) {
printf("%s: prerm action target error (%s)\n", pkgname, printf("%s: prerm action target error (%s)\n", pkgname,
strerror(errno)); strerror(errno));
free(buf); 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", (void)snprintf(path, sizeof(path), "%s%s/metadata/%s/files.plist",
destdir, XBPS_META_PATH, pkgname); destdir, XBPS_META_PATH, pkgname);
fdict = prop_dictionary_internalize_from_file(path); dict = prop_dictionary_internalize_from_file(path);
if (fdict == NULL) { if (dict == NULL) {
free(buf); free(buf);
return errno; return errno;
} }
@ -237,18 +241,19 @@ xbps_remove_binary_pkg(const char *pkgname, const char *destdir, int flags)
rmcbarg.destdir = destdir; rmcbarg.destdir = destdir;
rmcbarg.flags = flags; 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); remove_pkg_files, (void *)&rmcbarg);
if (rv != 0) { if (rv != 0) {
free(buf); free(buf);
prop_object_release(fdict); prop_object_release(dict);
return rv; 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 post remove action if REMOVE file is there.
/* Run the postremove action target */ */
if (prepostf) {
if ((rv = xbps_file_exec(buf, destdir, "post", if ((rv = xbps_file_exec(buf, destdir, "post",
pkgname, NULL)) != 0) { pkgname, NULL)) != 0) {
printf("%s: postrm action target error (%s)\n", 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; return rv;
} }
} }
free(buf); 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> #include <xbps_api.h>
static int 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_array_t array;
prop_string_t reqstr; prop_string_t reqstr;
@ -80,8 +80,77 @@ add_pkg_into_requiredby(prop_dictionary_t pkgd, const char *reqname)
return 0; 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 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_array_t rdeps;
prop_object_t obj, obj2; 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) { while ((obj = prop_object_iterator_next(iter)) != NULL) {
rdepname = xbps_get_pkg_name(prop_string_cstring_nocopy(obj)); rdepname = xbps_get_pkg_name(prop_string_cstring_nocopy(obj));
iter2 = prop_array_iterator(regar); iter2 = prop_array_iterator(regar);
if (iter2 == NULL) { if (iter2 == NULL) {
free(fpkgn);
free(rdepname); free(rdepname);
prop_object_iterator_release(iter); rv = ENOMEM;
return 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", prop_dictionary_get_cstring_nocopy(obj2, "pkgname",
&reqname); &reqname);
if (strcmp(rdepname, reqname) == 0) { if (strcmp(rdepname, reqname) == 0) {
rv = add_pkg_into_requiredby(obj2, fpkgn); rv = add_pkg_into_reqby(obj2, fpkgn);
if (rv != 0) { if (rv != 0) {
free(rdepname); free(rdepname);
prop_object_iterator_release(iter2); prop_object_iterator_release(iter2);
@ -140,8 +207,8 @@ xbps_update_pkg_requiredby(prop_array_t regar, prop_dictionary_t pkg)
break; break;
} }
} }
free(rdepname);
prop_object_iterator_release(iter2); prop_object_iterator_release(iter2);
free(rdepname);
} }
out: out:

View file

@ -123,7 +123,7 @@ unpack_archive_init(prop_dictionary_t pkg, const char *destdir,
* is really on storage (if possible). * is really on storage (if possible).
*/ */
if (rv == 0) if (rv == 0)
if ((rv = fdatasync(pkg_fd)) == -1) if (fdatasync(pkg_fd) == -1)
rv = errno; rv = errno;
archive_read_finish(ar); archive_read_finish(ar);
@ -149,11 +149,10 @@ unpack_archive_fini(struct archive *ar, const char *destdir, int flags,
prop_dictionary_t pkg) prop_dictionary_t pkg)
{ {
struct archive_entry *entry; struct archive_entry *entry;
struct stat st;
size_t len; size_t len;
const char *prepost = "./INSTALL"; const char *prepost = "./INSTALL";
const char *pkgname, *version; const char *pkgname, *version;
char *buf, *path; char *buf;
int rv = 0, lflags = 0; int rv = 0, lflags = 0;
bool actgt = false; 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) { 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 * Run the pre installation action target if there's a script
* before writing data to disk. * 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); archive_entry_set_pathname(entry, buf);
rv = archive_read_extract(ar, entry, lflags); if (archive_read_extract(ar, entry, lflags) != 0) {
if (rv != 0 && errno != EEXIST) if ((rv = archive_errno(ar)) != EEXIST)
break; break;
}
if ((rv = xbps_file_exec(buf, destdir, "pre", if ((rv = xbps_file_exec(buf, destdir, "pre",
pkgname, version, NULL)) != 0) { 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. * Extract all data from the archive now.
*/ */
rv = archive_read_extract(ar, entry, lflags); if (archive_read_extract(ar, entry, lflags) != 0) {
if (rv != 0 && errno != EEXIST) { rv = archive_errno(ar);
printf("ERROR: couldn't unpack %s (%s), exiting!\n", if (rv != EEXIST) {
archive_entry_pathname(entry), strerror(errno)); printf("ERROR: couldn't unpack %s (%s), "
(void)fflush(stdout); "exiting!\n", archive_entry_pathname(entry),
break; archive_error_string(ar));
} else if (rv != 0 && errno == EEXIST) {
if (flags & XBPS_UNPACK_VERBOSE) {
printf("WARNING: ignoring existent path: %s.\n",
archive_entry_pathname(entry));
(void)fflush(stdout); (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) { if (flags & XBPS_UNPACK_VERBOSE) {

View file

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