#!/bin/sh set -eu if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then echo "usage: $0 [metadata-source]" >&2 exit 64 fi src="$1" dst="$2" metadata_source=${3:-} dst_dir=$(dirname "$dst") dst_name=$(basename "$dst") dst_ext="" case "$dst_name" in *.*) dst_ext=${dst_name##*.} ;; esac test -f "$src" || { echo "source file not found: $src" >&2 exit 66 } owner="" group="" mode="" sample="" if [ -e "$dst" ]; then owner=$(stat -f '%Su' "$dst") group=$(stat -f '%Sg' "$dst") mode=$(stat -f '%Lp' "$dst") else if [ -n "$metadata_source" ]; then test -e "$metadata_source" || { echo "metadata source not found: $metadata_source" >&2 exit 66 } sample=$metadata_source elif [ -n "$dst_ext" ]; then for candidate in "$dst_dir"/*."$dst_ext"; do [ -e "$candidate" ] || continue sample=$candidate break done fi if [ -z "$sample" ]; then for candidate in "$dst_dir"/*; do [ -f "$candidate" ] || continue sample=$candidate break done fi if [ -n "$sample" ]; then owner=$(stat -f '%Su' "$sample") group=$(stat -f '%Sg' "$sample") mode=$(stat -f '%Lp' "$sample") else owner=$(stat -f '%Su' "$dst_dir") group=$(stat -f '%Sg' "$dst_dir") mode=644 fi fi cp "$src" "$dst" chown "$owner":"$group" "$dst" chmod "$mode" "$dst" printf 'copied %s -> %s\n' "$src" "$dst" printf 'restored owner=%s group=%s mode=%s\n' "$owner" "$group" "$mode" if [ -n "$sample" ]; then printf 'metadata source=%s\n' "$sample" fi