Improve package removal by using a two phase approach: check and removal.
This commit is contained in:
parent
f97ea2b915
commit
61fa9b8c7e
4
NEWS
4
NEWS
@ -1,5 +1,9 @@
|
|||||||
xbps-0.32 (???):
|
xbps-0.32 (???):
|
||||||
|
|
||||||
|
* Do the package removal in two phases: the first phase checks the
|
||||||
|
user has write permission to the entries being removed, if this
|
||||||
|
succeeds then the package removal is performed.
|
||||||
|
|
||||||
* xbps-remove(8): -O now also remove obsolete pkg signatures from
|
* xbps-remove(8): -O now also remove obsolete pkg signatures from
|
||||||
cachedir, and ignores pkgs of other architectures.
|
cachedir, and ignores pkgs of other architectures.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2009-2013 Juan Romero Pardines.
|
* Copyright (c) 2009-2014 Juan Romero Pardines.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -82,6 +82,33 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
|
|||||||
else if (strcmp(key, "dirs") == 0)
|
else if (strcmp(key, "dirs") == 0)
|
||||||
curobj = "directory";
|
curobj = "directory";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the removal in 2 phases:
|
||||||
|
* 1- check if user has enough perms to remove entry
|
||||||
|
* 2- perform removal
|
||||||
|
*/
|
||||||
|
while ((obj = xbps_object_iterator_next(iter))) {
|
||||||
|
xbps_dictionary_get_cstring_nocopy(obj, "file", &file);
|
||||||
|
path = xbps_xasprintf("%s/%s", xhp->rootdir, file);
|
||||||
|
if (access(path, W_OK)) {
|
||||||
|
if (errno == ENOENT) {
|
||||||
|
/* ignore ENOENT, file might have dissapeared */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* only bail out if something else than ENOENT
|
||||||
|
* is returned.
|
||||||
|
*/
|
||||||
|
rv = errno;
|
||||||
|
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_FAIL, rv, pkgver,
|
||||||
|
"%s: cannot remove %s `%s': %s", pkgver, curobj, file, strerror(rv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rv != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
xbps_object_iterator_reset(iter);
|
||||||
|
|
||||||
while ((obj = xbps_object_iterator_next(iter))) {
|
while ((obj = xbps_object_iterator_next(iter))) {
|
||||||
xbps_dictionary_get_cstring_nocopy(obj, "file", &file);
|
xbps_dictionary_get_cstring_nocopy(obj, "file", &file);
|
||||||
path = xbps_xasprintf("%s/%s", xhp->rootdir, file);
|
path = xbps_xasprintf("%s/%s", xhp->rootdir, file);
|
||||||
@ -160,7 +187,13 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
|
|||||||
errno, pkgver,
|
errno, pkgver,
|
||||||
"%s: failed to remove %s `%s': %s", pkgver,
|
"%s: failed to remove %s `%s': %s", pkgver,
|
||||||
curobj, file, strerror(errno));
|
curobj, file, strerror(errno));
|
||||||
errno = 0;
|
if (errno != ENOENT) {
|
||||||
|
/*
|
||||||
|
* only bail out if something else than ENOENT
|
||||||
|
* is returned.
|
||||||
|
*/
|
||||||
|
rv = errno;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* success */
|
/* success */
|
||||||
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE,
|
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE,
|
||||||
@ -168,6 +201,8 @@ xbps_remove_pkg_files(struct xbps_handle *xhp,
|
|||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
xbps_object_iterator_release(iter);
|
xbps_object_iterator_release(iter);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@ -326,6 +361,10 @@ purge:
|
|||||||
out:
|
out:
|
||||||
if (pkgname != NULL)
|
if (pkgname != NULL)
|
||||||
free(pkgname);
|
free(pkgname);
|
||||||
|
if (rv != 0) {
|
||||||
|
xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FAIL, rv, pkgver,
|
||||||
|
"%s: failed to remove package: %s", pkgver, strerror(rv));
|
||||||
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user