From: Michael Tremer Date: Sun, 5 Mar 2023 13:43:23 +0000 (+0000) Subject: build: Move checking for broken symlinks into C X-Git-Tag: 0.9.29~363 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7434fa90b37a6b1ef215ce78794662bd1891d27c;p=pakfire.git build: Move checking for broken symlinks into C Fixes: #13057 - Broken symlink check seems to fail if spaces are in filename Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 9f6777562..b7396e3df 100644 --- a/Makefile.am +++ b/Makefile.am @@ -723,7 +723,6 @@ dist_scripts_SCRIPTS = \ src/scripts/check-interpreters \ src/scripts/check-libraries \ src/scripts/check-rpaths \ - src/scripts/check-symlinks \ src/scripts/check-unsafe-files \ src/scripts/compress-man-pages \ src/scripts/find-prerequires \ diff --git a/src/libpakfire/build.c b/src/libpakfire/build.c index b0ba23f02..956d486d8 100644 --- a/src/libpakfire/build.c +++ b/src/libpakfire/build.c @@ -1086,6 +1086,62 @@ static int pakfire_build_post_remove_libtool_archives( "Removing libtool archives...", __pakfire_build_remove_libtool_archives); } +static int __pakfire_build_check_broken_symlinks( + struct pakfire* pakfire, struct pakfire_file* file, void* data) { + struct pakfire_filelist* broken = (struct pakfire_filelist*)data; + int r; + + // Ignore anything that isn't a symlink + switch (pakfire_file_get_type(file)) { + case S_IFLNK: + if (!pakfire_file_symlink_target_exists(file)) { + r = pakfire_filelist_add(broken, file); + if (r) + return r; + } + + break; + + // Ignore anything that isn't a symlink + default: + break; + } + + return 0; +} + +static int pakfire_build_post_check_broken_symlinks( + struct pakfire_build* build, struct pakfire_filelist* filelist) { + struct pakfire_filelist* broken = NULL; + int r; + + // Create a new filelist + r = pakfire_filelist_create(&broken, build->pakfire); + if (r) + goto ERROR; + + // Find any broken symlinks + r = pakfire_filelist_walk(filelist, __pakfire_build_check_broken_symlinks, broken); + if (r) + goto ERROR; + + if (!pakfire_filelist_is_empty(broken)) { + INFO(build->pakfire, "Broken symlinks have been found:\n"); + + // Show all files + pakfire_filelist_dump(broken, 0); + + // Check failed + r = 1; + } + +ERROR: + if (broken) + pakfire_filelist_unref(broken); + + return r; +} + static int pakfire_build_run_post_build_checks(struct pakfire_build* build) { struct pakfire_filelist* filelist = NULL; int r; @@ -1119,6 +1175,11 @@ static int pakfire_build_run_post_build_checks(struct pakfire_build* build) { if (r) goto ERROR; + // Check for any broken symlinks + r = pakfire_build_post_check_broken_symlinks(build, filelist); + if (r) + goto ERROR; + ERROR: if (filelist) pakfire_filelist_unref(filelist); @@ -1127,7 +1188,6 @@ ERROR: } static const char* post_build_scripts[] = { - "check-symlinks", "check-unsafe-files", "check-libraries", "check-rpaths", diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index 017686580..1ea290428 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -920,6 +920,16 @@ int pakfire_file_remove(struct pakfire_file* file) { return r; } +int pakfire_file_symlink_target_exists(struct pakfire_file* file) { + // Fail if this got called for anything that isn't a symlink + if (!S_ISLNK(file->st.st_mode)) { + errno = EINVAL; + return -1; + } + + return pakfire_path_exists(file->abspath); +} + /* Classification */ diff --git a/src/libpakfire/include/pakfire/file.h b/src/libpakfire/include/pakfire/file.h index 0dd1a9a1e..183661807 100644 --- a/src/libpakfire/include/pakfire/file.h +++ b/src/libpakfire/include/pakfire/file.h @@ -127,6 +127,8 @@ int pakfire_file_compute_digests(struct pakfire_file* file, const int types); int pakfire_file_remove(struct pakfire_file* file); int pakfire_file_cleanup(struct pakfire_file* file); +int pakfire_file_symlink_target_exists(struct pakfire_file* file); + int pakfire_file_classify(struct pakfire_file* file); int pakfire_file_matches_class(struct pakfire_file* file, const int class); diff --git a/src/scripts/check-symlinks b/src/scripts/check-symlinks deleted file mode 100644 index 51e067e2c..000000000 --- a/src/scripts/check-symlinks +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -############################################################################### -# # -# Pakfire - The IPFire package management system # -# Copyright (C) 2021 Pakfire development team # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -############################################################################### - -error() { - echo "$@" >&2 -} - -main() { - local buildroot="${1}" - shift - - # Check if BUILDROOT exists - if [ ! -d "${buildroot}" ]; then - error "BUILDROOT does not exist" - return 1 - fi - - local broken_links=() - - local file - for file in $(find "${buildroot}" -type l); do - if [ ! -e "${file}" ]; then - broken_links+=( "${file}" ) - fi - done - - if [ "${#broken_links[@]}" -gt 0 ]; then - error "The following broken symlinks have been found:" - - local link - for link in ${broken_links[@]}; do - error " ${link/${buildroot}/} -> $(readlink "${link}")" - done - - return 1 - fi - - return 0 -} - -main "$@" || exit $?