# # Copyright (C) 2026 Danilo M. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # 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. # # Shared helpers for the image builder. Source, do not execute. # Sourcing must have no side effects beyond defining functions. _log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] [${LOG_TAG:-image-builder}] $*"; } _warn() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] [${LOG_TAG:-image-builder}] WARNING: $*" >&2; } _err() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] [${LOG_TAG:-image-builder}] ERROR: $*" >&2; exit 1; } # mirror_path MIRROR RELPATH # Join a MIRROR (file:///... or http(s)://...) with a relative path. mirror_path() { local mirror="$1" rel="$2" printf '%s/%s' "${mirror%/}" "${rel#/}" } # is_local_mirror MIRROR -> 0 if file:// or bare absolute path, else 1 is_local_mirror() { case "$1" in file://*) return 0 ;; http://*|https://*) return 1 ;; /*) return 0 ;; *) return 1 ;; esac } # strip_scheme URL -> filesystem path for a file:// or bare-local URL strip_scheme() { local u="$1" case "$u" in file://*) printf '%s' "${u#file://}" ;; *) printf '%s' "$u" ;; esac } # fetch SRC DEST # Copy SRC (a full mirror URL) to DEST. Local mirror -> cp, http -> curl. # Returns non-zero on failure; caller decides whether that is fatal. fetch() { local src="$1" dest="$2" if is_local_mirror "$src"; then local path; path="$(strip_scheme "$src")" [[ -f "$path" ]] || return 1 cp "$path" "$dest" else curl -sSfL --connect-timeout 60 "$src" -o "$dest" fi } # txz_hash DIR # Stable hash of the set of Slackware package files (*.t?z) in DIR (names + # contents), order # independent. Empty/absent dir -> empty string. txz_hash() { local dir="$1" [[ -d "$dir" ]] || { printf ''; return 0; } local files; files=$(find "$dir" -maxdepth 1 -name '*.t?z' -type f | sort) [[ -n "$files" ]] || { printf ''; return 0; } # Hash sorted "name sha256" lines so reordering does not change output. while IFS= read -r f; do printf '%s %s\n' "$(basename "$f")" "$(sha256sum "$f" | cut -d' ' -f1)" done <<< "$files" | sha256sum | cut -d' ' -f1 } # require_mount VERSION # Assert the NAS tree for VERSION is mounted (file:// mirror only). # x86_64 tree dir is slackware64-${VERSION}. require_mount() { local version="$1" is_local_mirror "$MIRROR" || return 0 # http mirror: nothing to check local base; base="$(strip_scheme "$MIRROR")" local dir="${base}/slackware64-${version}" [[ -d "$dir" ]] || _err "NAS tree not mounted: ${dir}" }