#!/bin/bash
# restore.sh - Restore files from a backup archive
#
# Copyright (C) 2025 LINUXexpert.org
#
# 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, version 3 of the License.
#
# 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 .
#
# Usage: restore.sh [target_directory]
# Description: Extracts the tar.gz archive into the target directory (current dir if not specified).
#
# Extraction options are deliberately conservative -- see the tar call.
set -euo pipefail
ARCHIVE="${1:-}"
TARGET="${2:-}"
if [ -z "$ARCHIVE" ]; then
echo "Usage: $0 [target_directory]"
exit 1
fi
if [ ! -f "$ARCHIVE" ]; then
echo "Backup archive '$ARCHIVE' not found!"; exit 1
fi
if [ -z "$TARGET" ]; then
TARGET="."
else
if [ ! -d "$TARGET" ]; then
mkdir -p "$TARGET" || { echo "Failed to create target directory '$TARGET'"; exit 1; }
fi
fi
# An archive is untrusted input: whoever produced it chooses the paths,
# the ownership and the modes inside it.
# --no-same-owner do not let the archive pick uid/gid. Extracting
# as root previously handed files to whatever
# owner the tarball named.
# --no-same-permissions apply the umask rather than restoring setuid
# bits straight out of the archive.
# -P is NOT used, so tar strips leading "/" and refuses ".." members.
echo "Contents to be extracted into $TARGET:"
tar -tzf "$ARCHIVE" | head -n 20
total="$(tar -tzf "$ARCHIVE" | grep -c . || true)"
[ "$total" -gt 20 ] && echo " ... and $((total - 20)) more entries"
if [ "${ASSUME_YES:-}" != "1" ]; then
if [ ! -t 0 ]; then
echo "Refusing to extract without confirmation; set ASSUME_YES=1 for unattended use." >&2
exit 1
fi
read -r -p "Extract $total entries into $TARGET, overwriting existing files? (yes/NO): " reply
[ "$reply" = "yes" ] || { echo "Cancelled."; exit 0; }
fi
if tar -xzf "$ARCHIVE" -C "$TARGET" --no-same-owner --no-same-permissions; then
echo "Restore successful to directory: $TARGET"
else
echo "Restore failed" >&2
exit 1
fi