autoshare/modules/archive.sh

91 lines
2.3 KiB
Bash

#!/bin/bash
# This script packs a file or directory into a 7z archive with the given password.
# It can (optionally) split the archives into volumes of a fixed size in megabytes.
source colors.sh
source functions.sh
trap 'cleanup' ERR INT
cleanup() {
if [[ -n "$archive" ]]; then
rm -f "${archive}"*
log "INFO" "Cleaning up $(basename $archive) remains before exit"
fi
}
check_input() {
if [[ ! -e "${input_file}" ]]; then
echo "ERROR: Input file '${input_file}' does not exist"
exit 2
elif [[ -z "${archive_pwd}" ]]; then
echo "ERROR: No password given"
exit 2
elif [[ ! "$size" =~ ^([1-9][0-9]*)?$ ]]; then
echo "Invalid size $size, must be empty or a positive number"
exit 2
fi
echo "Archiving file/directory '${input_file}' with password '${archive_pwd}' and size '$size'" >&2
}
# Calculates a "smart" volume size so that each volume (including the final part) will be approximately the same size
calc_smart_volumes() {
total_size=$(du -s -BM "${input_file}" | grep -oP '^\d+') || return 0
# If total file size is smaller than volume size, don't pack it into volumes
(( total_size < size )) && return 1
num_volumes=$(( (total_size + size - 1) / size ))
size=$(( (total_size + num_volumes - 1) / num_volumes ))
echo "Calculated smart volume size '$size'" >&2
}
set_volumes() {
[[ -n "$size" ]] && calc_smart_volumes && volumes="-v${size}m"
echo "Volumes set to '$volumes'" >&2
}
# Generates a random archive name of 20 alphanumeric characters
generate_name() {
archive="$archive_dir/$(tr -dc [:alnum:] < /dev/urandom | head -c 20).7z"
echo "Generated archive name '$archive'" >&2
}
create_archive() {
echo "Packing '${input_file}' into archive '$archive' with password '${archive_pwd}'"
[[ -n "$volumes" ]] && echo "and volumes of size $size MB"
7z a -mhe=on "-p${archive_pwd}" "$volumes" "$archive" "${input_file}" >&2
}
main() {
archive_dir="$(dirname "$0")/../archives"
input_file="${1}"
archive_pwd="${2}"
size="$3"
check_dependencies "7z"
if ! mkdir -p "$archive_dir"; then
log "ERROR" "Unable to create archive directory"
exit 1
fi
check_input
set_volumes
generate_name
create_archive
}
# Missing arguments must be caught here when using `set -e`, otherwise
# the script will exit prematurely without logging the error.
if (( $# == 3 )); then
main "$@"
else
log "ERROR" "Missing arguments"
exit 2
fi