summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libalpm/be_local.c40
-rw-r--r--lib/libalpm/util.c46
-rw-r--r--lib/libalpm/util.h2
3 files changed, 36 insertions, 52 deletions
diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
index 36b2c5dc..137da1a8 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -907,14 +907,44 @@ cleanup:
int _alpm_local_db_remove(alpm_db_t *db, alpm_pkg_t *info)
{
int ret = 0;
- char *pkgpath = _alpm_local_db_pkgpath(db, info, NULL);
+ DIR *dirp;
+ struct dirent *dp;
+ char *pkgpath;
+ size_t pkgpath_len;
- /* TODO explicit file removes and then an rmdir? */
- ret = _alpm_rmrf(pkgpath);
- free(pkgpath);
- if(ret != 0) {
+ pkgpath = _alpm_local_db_pkgpath(db, info, NULL);
+ if(!pkgpath) {
+ return -1;
+ }
+ pkgpath_len = strlen(pkgpath);
+
+ dirp = opendir(pkgpath);
+ if(!dirp) {
+ return -1;
+ }
+ /* go through the local DB entry, removing the files within, which we know
+ * are not nested directories of any kind. */
+ for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if(strcmp(dp->d_name, "..") != 0 && strcmp(dp->d_name, ".") != 0) {
+ char name[PATH_MAX];
+ if(pkgpath_len + strlen(dp->d_name) + 2 > PATH_MAX) {
+ /* file path is too long to remove, hmm. */
+ ret = -1;
+ } else {
+ sprintf(name, "%s/%s", pkgpath, dp->d_name);
+ if(unlink(name)) {
+ ret = -1;
+ }
+ }
+ }
+ }
+ closedir(dirp);
+
+ /* after removing all enclosed files, we can remove the directory itself. */
+ if(rmdir(pkgpath)) {
ret = -1;
}
+ free(pkgpath);
return ret;
}
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 3cc4bbf7..24bf1fc0 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -397,52 +397,6 @@ cleanup:
return ret;
}
-/** Recursively removes a path similar to 'rm -rf'.
- * @param path path to remove
- * @return 0 on success, number of paths that could not be removed on error
- */
-int _alpm_rmrf(const char *path)
-{
- int errflag = 0;
- struct dirent *dp;
- DIR *dirp;
- struct stat st;
-
- if(_alpm_lstat(path, &st) == 0) {
- if(!S_ISDIR(st.st_mode)) {
- if(!unlink(path)) {
- return 0;
- } else {
- if(errno == ENOENT) {
- return 0;
- } else {
- return 1;
- }
- }
- } else {
- dirp = opendir(path);
- if(!dirp) {
- return 1;
- }
- for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- if(dp->d_name) {
- if(strcmp(dp->d_name, "..") != 0 && strcmp(dp->d_name, ".") != 0) {
- char name[PATH_MAX];
- sprintf(name, "%s/%s", path, dp->d_name);
- errflag += _alpm_rmrf(name);
- }
- }
- }
- closedir(dirp);
- if(rmdir(path)) {
- errflag++;
- }
- }
- return errflag;
- }
- return 0;
-}
-
/** Determine if there are files in a directory.
* @param handle the context handle
* @param path the full absolute directory path
diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h
index 6d5c0c35..d5cf0127 100644
--- a/lib/libalpm/util.h
+++ b/lib/libalpm/util.h
@@ -121,7 +121,7 @@ int _alpm_unpack_single(alpm_handle_t *handle, const char *archive,
const char *prefix, const char *filename);
int _alpm_unpack(alpm_handle_t *handle, const char *archive, const char *prefix,
alpm_list_t *list, int breakfirst);
-int _alpm_rmrf(const char *path);
+
ssize_t _alpm_files_in_directory(alpm_handle_t *handle, const char *path, int full_count);
int _alpm_logaction(alpm_handle_t *handle, const char *fmt, va_list args);
int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[]);