diff options
-rw-r--r-- | lib/libalpm/be_local.c | 40 | ||||
-rw-r--r-- | lib/libalpm/util.c | 46 | ||||
-rw-r--r-- | lib/libalpm/util.h | 2 |
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[]); |