diff options
Diffstat (limited to 'lib/libalpm')
| -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[]);  | 
