#!/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/>. #
+# #
+###############################################################################
-COMPRESSOR=xz
-COMPRESS_EXT=.xz
-
-echo "Compressing man pages..."
-
-BUILDROOT=${1}
-shift
-
-dir="${BUILDROOT}/usr/share/man"
-
-for file in $(find ${dir} -type f 2>/dev/null); do
- [ -f "${file}" ] || continue
-
- case "${file}" in
- *.gz)
- gzip -d ${file}
- file=${file%*.gz}
- ;;
- *.bz2)
- bzip2 -d ${file}
- file=${file%*.bz2}
- ;;
- esac
-
- echo " Compressing man page ${file//${BUILDROOT}/}..."
- ${COMPRESSOR} ${file} </dev/null 2>/dev/null || {
- # Handle files with hardlinks.
- others=$(find ${dir} -type f -samefile ${file})
- if [ -n "${others}" ]; then
- for afile in ${others}; do
- [ "${afile}" != "${file}" ] && rm -f ${afile}
- done
- ${COMPRESSOR} -f ${file}
- for afile in ${others}; do
- [ "${afile}" != "${file}" ] && ln ${file}${COMPRESS_EXT} ${afile}${COMPRESS_EXT}
+error() {
+ echo "${0#/}: $@" >&2
+}
+
+compress() {
+ local file="${1}"
+
+ # Compress with XZ as best as we can
+ xz -9e "${file}" </dev/null 2>/dev/null
+}
+
+main() {
+ local buildroot="${1}"
+ shift
+
+ # Check if BUILDROOT exists
+ if [ ! -d "${buildroot}" ]; then
+ error "BUILDROOT does not exist"
+ return 1
+ fi
+
+ # Process these directories
+ local directories=(
+ "${buildroot}/usr/share/man"
+ )
+
+ echo "Compressing man pages..."
+
+ # Walk through all files...
+ local file
+ for file in $(find "${directories[@]}" -type f 2>/dev/null); do
+ # Uncompress all files that are already compressed
+ case "${file}" in
+ *.bz2)
+ if bzip2 -d "${file}"; then
+ file="${file%*.bz2}"
+ fi
+ ;;
+ *.gz)
+ if gzip -d "${file}"; then
+ file="${file%*.gz}"
+ fi
+ ;;
+ esac
+
+ # Say what we are doing...
+ echo " ${file/${buildroot}/}"
+
+ # Attempt to compress the file
+ # This might fail if the file has any hardlinks
+ if ! compress "${file}"; then
+ local hardlinks=(
+ $(find "${directories[@]}" -type f -not -path "${file}" -samefile "${file}" 2>/dev/null)
+ )
+
+ # Delete all hardlinks
+ rm -f "${hardlinks[@]}"
+
+ # Compress
+ compress "${file}"
+
+ # Re-create all hardlinks
+ local hardlink
+ for hardlink in ${hardlinks[@]}; do
+ ln "${file}.xz" "${hardlink}.xz"
done
- else
- ${COMPRESSOR} -f ${file}
fi
- }
-done
+ done
+
+ local link
+ for link in $(find "${directories[@]}" -type l 2>/dev/null); do
+ local target="$(readlink -m "${link}")"
+
+ # Remove link
+ rm -f "${link}"
+
+ # Strip any previous compression from link
+ case "${link}" in
+ *.bz2|*.gz)
+ link="${link%.*}"
+ ;;
+ esac
+
+ # Strip any previous compression from target
+ case "${target}" in
+ *.bz2|*.gz)
+ target="${target%.*}"
+ ;;
+ esac
+
+ # Append the new compression suffix
+ link="${link}.xz"
+ target="${target}.xz"
+
+ # Create the new symlink
+ if ! ln -s --relative "${target}" "${link}"; then
+ error "Could not create symlink from ${link} to ${target}"
+ return 1
+ fi
+ done
-for file in $(find ${dir} -type l 2>/dev/null); do
- link=$(ls -l ${file} | sed -e 's/.* -> //' -e 's/\.\(gz\|Z\|bz2\|xz\|lzma\)$//')
- rm -f ${file}
- b=$(echo ${file} | sed -e 's/\.\(gz\|Z\|bz2\|xz\|lzma\)$//')
- ln -sf ${link}${COMPRESS_EXT} ${b}${COMPRESS_EXT}
-done
+ return 0
+}
-exit 0
+main "$@" || exit $?