diff --git a/NEWS b/NEWS index 3913b956..76704548 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,14 @@ xbps-0.16 (???): + * libxbps: change the order in which package files are removed: + + current: files, conf_files, links, directories. + previous: links, files, conf_files, directories. + + This is required to avoid removing working symlinks, which could be + owned by another installed package. Now only dangling symlinks are now + removed. + * libxbps: when removing package files and if metadata files.plist wasn't found, do not error out and rather just continue until the package is fully removed. diff --git a/include/xbps_api.h b/include/xbps_api.h index 2d032a52..b4de93b4 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -56,7 +56,7 @@ */ #define XBPS_PKGINDEX_VERSION "1.4" -#define XBPS_API_VERSION "20120521" +#define XBPS_API_VERSION "20120525" #define XBPS_VERSION "0.16" /** diff --git a/lib/package_remove.c b/lib/package_remove.c index 45cf0053..d6cdd331 100644 --- a/lib/package_remove.c +++ b/lib/package_remove.c @@ -131,11 +131,13 @@ xbps_remove_pkg_files(prop_dictionary_t dict, const char *pkgver) { struct xbps_handle *xhp; + struct stat st; prop_array_t array; prop_object_iterator_t iter; prop_object_t obj; const char *file, *sha256, *version, *curobj = NULL; char *path = NULL, *pkgname = NULL; + char buf[PATH_MAX]; int rv = 0; assert(prop_object_type(dict) == PROP_TYPE_DICTIONARY); @@ -220,6 +222,22 @@ xbps_remove_pkg_files(prop_dictionary_t dict, free(path); break; } + } else if (strcmp(key, "links") == 0) { + /* + * All regular files from package were removed at this + * point, so we will only remove dangling symlinks. + */ + if (realpath(path, buf) == NULL) { + if (errno != ENOENT) { + free(path); + rv = errno; + break; + } + } + if (stat(buf, &st) == 0) { + free(path); + continue; + } } /* * Remove the object if possible. @@ -329,15 +347,15 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update) pkgd = xbps_dictionary_from_metadata_plist(pkgname, XBPS_PKGFILES); if (pkgd) { - /* Remove links */ - if ((rv = xbps_remove_pkg_files(pkgd, "links", pkgver)) != 0) - goto out; /* Remove regular files */ if ((rv = xbps_remove_pkg_files(pkgd, "files", pkgver)) != 0) goto out; /* Remove configuration files */ if ((rv = xbps_remove_pkg_files(pkgd, "conf_files", pkgver)) != 0) goto out; + /* Remove links */ + if ((rv = xbps_remove_pkg_files(pkgd, "links", pkgver)) != 0) + goto out; /* Remove dirs */ if ((rv = xbps_remove_pkg_files(pkgd, "dirs", pkgver)) != 0) goto out;