83 lines
2.2 KiB
Bash
Executable file
83 lines
2.2 KiB
Bash
Executable file
#!/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.
|
|
|
|
archive_dir="$(dirname "$0")/../archives"
|
|
|
|
input_file="${1}"
|
|
archive_pwd="${2}"
|
|
size="$3"
|
|
|
|
cleanup() {
|
|
[[ -n "$archive" ]] && rm -f "$archive*"
|
|
|
|
echo "Cleaned up all $archive files" >&2
|
|
}
|
|
|
|
check_dependencies() {
|
|
if ! mkdir -p "$archive_dir"; then
|
|
echo "ERROR: Unable to create archive directory"
|
|
exit 1
|
|
elif ! command -v 7z 2>&1 >/dev/null; then
|
|
echo "ERROR: 7z must be installed"
|
|
exit 1
|
|
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 -lt $size ]] && return 1
|
|
|
|
num_volumes=$(echo "($total_size + $size - 1) / $size" | bc)
|
|
size=$(echo "($total_size + $num_volumes - 1) / $num_volumes" | bc)
|
|
|
|
echo "Calculated smart volume size '$size'" >&2
|
|
}
|
|
|
|
set_volumes() {
|
|
if [[ -n "$size" ]]; then
|
|
calc_smart_volumes && volumes="-v${size}m"
|
|
fi
|
|
|
|
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
|
|
}
|
|
|
|
trap cleanup 1 2 3 6
|
|
|
|
check_dependencies
|
|
check_input
|
|
set_volumes
|
|
generate_name
|
|
create_archive
|