78 lines
1.5 KiB
Bash
78 lines
1.5 KiB
Bash
|
|
#!/bin/sh
|
||
|
|
set -eu
|
||
|
|
|
||
|
|
if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then
|
||
|
|
echo "usage: $0 <source> <destination> [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
|