#!/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