Remove rmrf implementation from backend

This moves the code for removal of local database entries right into
be_local.c, which was the last user of the rmrf() function we had in our
utility source file. We can simplify the implementation and make it
non-recursive as we know the structure of the local database entries.

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2012-01-18 21:43:00 -06:00
parent ac239c54d0
commit be038f9cb2
3 changed files with 36 additions and 52 deletions

View file

@ -907,14 +907,44 @@ cleanup:
int _alpm_local_db_remove(alpm_db_t *db, alpm_pkg_t *info) int _alpm_local_db_remove(alpm_db_t *db, alpm_pkg_t *info)
{ {
int ret = 0; 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? */ pkgpath = _alpm_local_db_pkgpath(db, info, NULL);
ret = _alpm_rmrf(pkgpath); if(!pkgpath) {
free(pkgpath); return -1;
if(ret != 0) { }
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; ret = -1;
} }
}
}
}
closedir(dirp);
/* after removing all enclosed files, we can remove the directory itself. */
if(rmdir(pkgpath)) {
ret = -1;
}
free(pkgpath);
return ret; return ret;
} }

View file

@ -397,52 +397,6 @@ cleanup:
return ret; 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. /** Determine if there are files in a directory.
* @param handle the context handle * @param handle the context handle
* @param path the full absolute directory path * @param path the full absolute directory path

View file

@ -121,7 +121,7 @@ int _alpm_unpack_single(alpm_handle_t *handle, const char *archive,
const char *prefix, const char *filename); const char *prefix, const char *filename);
int _alpm_unpack(alpm_handle_t *handle, const char *archive, const char *prefix, int _alpm_unpack(alpm_handle_t *handle, const char *archive, const char *prefix,
alpm_list_t *list, int breakfirst); 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); 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_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[]); int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[]);