unlink_file: restore trailing slash on directory before checking mountpoint

The dir_is_mountpoint() function has the explicit requirement that the
trailing slash of the directory is present.  We strip the trailing slash
in unlink_file() to handle directories replaced with symlinks, but that
then affects the dir_is_mountpoint() check.

Add the trailing slash when we have established we are dealing with a
directory. Note this may fail in the case of a file managed by pacmane
with name length of PATH_MAX that has been replaced by a directory on the
file system. Bail on this unlikely scenario.

In addtion, be less fancy with adjusting length of the file char array.

Signed-off-by: Allan McRae <allan@archlinux.org>
(cherry picked from commit f86c15e780)
This commit is contained in:
Allan McRae 2024-04-03 01:48:31 +10:00
parent 78f17bae4d
commit ff139a7eb8

View file

@ -451,10 +451,11 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *oldpkg,
_alpm_log(handle, ALPM_LOG_DEBUG, "path too long to unlink %s%s\n",
handle->root, fileobj->name);
return -1;
} else if(file[file_len-1] == '/') {
} else if(file[file_len - 1] == '/') {
/* trailing slashes cause errors and confusing messages if the user has
* replaced a directory with a symlink */
file[--file_len] = '\0';
file[file_len - 1] = '\0';
file_len--;
}
if(llstat(file, &buf)) {
@ -463,9 +464,22 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *oldpkg,
}
if(S_ISDIR(buf.st_mode)) {
ssize_t files = _alpm_files_in_directory(handle, file, 0);
/* if we have files, no need to remove the directory */
ssize_t files;
/* restore/add trailing slash */
if(file_len < PATH_MAX - 1) {
file[file_len] = '/';
file_len++;
file[file_len] = '\0';
} else {
_alpm_log(handle, ALPM_LOG_DEBUG, "path too long to unlink %s%s\n",
handle->root, fileobj->name);
return -1;
}
files = _alpm_files_in_directory(handle, file, 0);
if(files > 0) {
/* if we have files, no need to remove the directory */
_alpm_log(handle, ALPM_LOG_DEBUG, "keeping directory %s (contains files)\n",
file);
} else if(files < 0) {