]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
build: Move checking for broken symlinks into C
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 5 Mar 2023 13:43:23 +0000 (13:43 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 5 Mar 2023 13:46:46 +0000 (13:46 +0000)
Fixes: #13057 - Broken symlink check seems to fail if spaces are in filename
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/libpakfire/build.c
src/libpakfire/file.c
src/libpakfire/include/pakfire/file.h
src/scripts/check-symlinks [deleted file]

index 9f6777562446ccf31c33990a3fb1ae63639f6ced..b7396e3df34604e1742e982f50903339844288c1 100644 (file)
@@ -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 \
index b0ba23f02772e64ec664c2c460a682c86726c9f6..956d486d828a486372c0a13e8761082ad309ab72 100644 (file)
@@ -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",
index 01768658063c725c0ec46bf1cb752edc494c80ab..1ea290428abd614ed7d4043771f194f4e9ae269b 100644 (file)
@@ -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
 */
index 0dd1a9a1e1e4b9953e2b677fea82412c11180529..18366180722d7c5a911c04c1432d6f7fc91f0849 100644 (file)
@@ -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 (file)
index 51e067e..0000000
+++ /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 <http://www.gnu.org/licenses/>.       #
-#                                                                             #
-###############################################################################
-
-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 $?