From 91266ca8eb4dfb59df40baac1d61c1e93ea5e9d3 Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Fri, 27 Dec 2019 17:13:25 +0100 Subject: [PATCH 01/11] Check encrypted files with SHA-512/256 checksums --- contrib/hooks/post_encrypt | 57 +++++++++++++++++++++++++++++++ contrib/hooks/post_status | 69 ++++++++++++++++++++++++++++++++++++++ yadm | 2 ++ 3 files changed, 128 insertions(+) create mode 100755 contrib/hooks/post_encrypt create mode 100755 contrib/hooks/post_status diff --git a/contrib/hooks/post_encrypt b/contrib/hooks/post_encrypt new file mode 100755 index 0000000..eb35299 --- /dev/null +++ b/contrib/hooks/post_encrypt @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# yadm - Yet Another Dotfiles Manager +# Copyright (C) 2015-2019 Tim Byrne and Martin Zuther + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +YADM_DIRECTORY=$(dirname $YADM_HOOK_REPO) +YADM_CHECKSUMS=$YADM_DIRECTORY/files.checksums + + +# check if "shasum" exists +if command -v shasum > /dev/null; then + # check if "shasum" supports SHA-512/256 algorithm + echo -n | shasum --algorithm 512256 2>&1 1> /dev/null + + if [ $? -ne 0 ]; then + echo + echo "WARNING: \"shasum\" does not support SHA-512/256. No checksums were created." + exit $YADM_HOOK_EXIT + fi + + # empty checksum file + echo -n > $YADM_CHECKSUMS + + # calculate checksums for encrypted files + for included in ${YADM_ENCRYPT_INCLUDE_FILES[@]}; do + shasum --algorithm 512256 $included >> $YADM_CHECKSUMS + ERROR_CODE=$? + + # signal errors + if [ $ERROR_CODE -ne 0 ]; then + exit $ERROR_CODE + fi + done + + echo "Wrote checksums: $YADM_CHECKSUMS (SHA-512/256)" +else + echo + echo "WARNING: command \"shasum\" not found. No checksums were created." + exit $YADM_HOOK_EXIT +fi + +# return exit status of the yadm command +exit $YADM_HOOK_EXIT diff --git a/contrib/hooks/post_status b/contrib/hooks/post_status new file mode 100755 index 0000000..f4a3b5d --- /dev/null +++ b/contrib/hooks/post_status @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +# yadm - Yet Another Dotfiles Manager +# Copyright (C) 2015-2019 Tim Byrne and Martin Zuther + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +YADM_DIRECTORY=$(dirname $YADM_HOOK_REPO) +YADM_CHECKSUMS=$YADM_DIRECTORY/files.checksums + + +# check whether file with checksums exists +if [ -f $YADM_CHECKSUMS ]; then + # check if "shasum" exists + if command -v shasum > /dev/null; then + # check if "shasum" supports SHA-512/256 algorithm + echo -n | shasum --algorithm 512256 2>&1 1> /dev/null + + if [ $? -ne 0 ]; then + echo + echo "WARNING: \"shasum\" does not support SHA-512/256. Checksums were not verified." + exit $YADM_HOOK_EXIT + fi + + # check encrypted files for differences and capture output + YADM_CHECKSUM_OUTPUT=$(shasum --algorithm 512256 --check $YADM_CHECKSUMS 2> /dev/null) + ERROR_CODE=$? + + # some checksums do not match + if [ $ERROR_CODE -ne 0 ]; then + echo + echo "Some SHA-512/256 sums do not match:" + + # set output color to red + echo -e "\033[0;31m" + + # display mismatching files + while IFS= read -r line; do + echo $line | grep -iv "\sok$" | sed 's/^/ / ; s/: FAILED$//' + done <<< "$YADM_CHECKSUM_OUTPUT" + + # reset output color + echo -e "\033[0m" + echo "Consider running either \"yadm encrypt\" or \"yadm decrypt\"." + + # signal error + exit $ERROR_CODE + fi + else + echo + echo "WARNING: command \"shasum\" not found. Checksums were not verified." + exit $YADM_HOOK_EXIT + fi +fi + +# return exit status of the yadm command +exit $YADM_HOOK_EXIT diff --git a/yadm b/yadm index b8f42fd..0410482 100755 --- a/yadm +++ b/yadm @@ -1577,11 +1577,13 @@ function invoke_hook() { YADM_HOOK_FULL_COMMAND=$FULL_COMMAND YADM_HOOK_REPO=$YADM_REPO YADM_HOOK_WORK=$YADM_WORK + YADM_ENCRYPT_INCLUDE_FILES=${ENCRYPT_INCLUDE_FILES[@]} export YADM_HOOK_COMMAND export YADM_HOOK_EXIT export YADM_HOOK_FULL_COMMAND export YADM_HOOK_REPO export YADM_HOOK_WORK + export YADM_ENCRYPT_INCLUDE_FILES "$hook_command" hook_status=$? From e96345eb87fd2324bfbaf79bd6778dedefba81d6 Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Fri, 27 Dec 2019 23:25:45 +0100 Subject: [PATCH 02/11] re-factor hooks * gracefully pass missing dependencies (grep and sed) --- contrib/hooks/post_encrypt | 73 +++++++++++++++-------- contrib/hooks/post_status | 117 +++++++++++++++++++++++-------------- 2 files changed, 123 insertions(+), 67 deletions(-) diff --git a/contrib/hooks/post_encrypt b/contrib/hooks/post_encrypt index eb35299..ffec5d5 100755 --- a/contrib/hooks/post_encrypt +++ b/contrib/hooks/post_encrypt @@ -20,38 +20,63 @@ YADM_DIRECTORY=$(dirname $YADM_HOOK_REPO) YADM_CHECKSUMS=$YADM_DIRECTORY/files.checksums +CHECKSUM_ALGORITHM="512256" +CHECKSUM_ALGORITHM_NAME="SHA-512/256" +WARNING_MESSAGE="No checksums were created." -# check if "shasum" exists -if command -v shasum > /dev/null; then - # check if "shasum" supports SHA-512/256 algorithm - echo -n | shasum --algorithm 512256 2>&1 1> /dev/null + +function print_warning_and_exit { + MESSAGE=$1 + + # set output color to yellow + echo -e "\033[1;33m" + echo "WARNING: $MESSAGE $WARNING_MESSAGE" + + # reset output color + echo -e "\033[0m" + + exit $YADM_HOOK_EXIT +} + + +function ensure_command { + COMMAND_NAME=$1 + + # check if command exists + if ! command -v "$COMMAND_NAME" > /dev/null; then + print_warning_and_exit "command \"$COMMAND_NAME\" not found." + fi +} + + +function ensure_algorithm { + # check if "shasum" supports algorithm + echo -n | shasum --algorithm "$CHECKSUM_ALGORITHM" &> /dev/null if [ $? -ne 0 ]; then - echo - echo "WARNING: \"shasum\" does not support SHA-512/256. No checksums were created." - exit $YADM_HOOK_EXIT + print_warning_and_exit "\"shasum\" does not support $CHECKSUM_ALGORITHM_NAME." fi +} - # empty checksum file - echo -n > $YADM_CHECKSUMS - # calculate checksums for encrypted files - for included in ${YADM_ENCRYPT_INCLUDE_FILES[@]}; do - shasum --algorithm 512256 $included >> $YADM_CHECKSUMS - ERROR_CODE=$? +# check if "shasum" exists and supports algorithm +ensure_command shasum +ensure_algorithm - # signal errors - if [ $ERROR_CODE -ne 0 ]; then - exit $ERROR_CODE - fi - done +# empty checksum file +echo -n > $YADM_CHECKSUMS - echo "Wrote checksums: $YADM_CHECKSUMS (SHA-512/256)" -else - echo - echo "WARNING: command \"shasum\" not found. No checksums were created." - exit $YADM_HOOK_EXIT -fi +# calculate checksums for encrypted files +for included in ${YADM_ENCRYPT_INCLUDE_FILES[@]}; do + shasum --algorithm $CHECKSUM_ALGORITHM $included >> $YADM_CHECKSUMS + + # signal errors + if [ $? -ne 0 ]; then + exit $? + fi +done + +echo "Wrote checksums: $YADM_CHECKSUMS ($CHECKSUM_ALGORITHM_NAME)" # return exit status of the yadm command exit $YADM_HOOK_EXIT diff --git a/contrib/hooks/post_status b/contrib/hooks/post_status index f4a3b5d..036264e 100755 --- a/contrib/hooks/post_status +++ b/contrib/hooks/post_status @@ -20,50 +20,81 @@ YADM_DIRECTORY=$(dirname $YADM_HOOK_REPO) YADM_CHECKSUMS=$YADM_DIRECTORY/files.checksums +CHECKSUM_ALGORITHM="512256" +CHECKSUM_ALGORITHM_NAME="SHA-512/256" +WARNING_MESSAGE="Checksums were not verified." + + +function print_warning_and_exit { + MESSAGE=$1 + + # set output color to yellow + echo -e "\033[1;33m" + echo "WARNING: $MESSAGE $WARNING_MESSAGE" + + # reset output color + echo -e "\033[0m" + + exit $YADM_HOOK_EXIT +} + + +function ensure_command { + COMMAND_NAME=$1 + + # check if command exists + if ! command -v "$COMMAND_NAME" > /dev/null; then + print_warning_and_exit "command \"$COMMAND_NAME\" not found." + fi +} + + +function ensure_algorithm { + # check if "shasum" supports algorithm + echo -n | shasum --algorithm "$CHECKSUM_ALGORITHM" &> /dev/null + + if [ $? -ne 0 ]; then + print_warning_and_exit "\"shasum\" does not support $CHECKSUM_ALGORITHM_NAME." + fi +} + # check whether file with checksums exists -if [ -f $YADM_CHECKSUMS ]; then - # check if "shasum" exists - if command -v shasum > /dev/null; then - # check if "shasum" supports SHA-512/256 algorithm - echo -n | shasum --algorithm 512256 2>&1 1> /dev/null - - if [ $? -ne 0 ]; then - echo - echo "WARNING: \"shasum\" does not support SHA-512/256. Checksums were not verified." - exit $YADM_HOOK_EXIT - fi - - # check encrypted files for differences and capture output - YADM_CHECKSUM_OUTPUT=$(shasum --algorithm 512256 --check $YADM_CHECKSUMS 2> /dev/null) - ERROR_CODE=$? - - # some checksums do not match - if [ $ERROR_CODE -ne 0 ]; then - echo - echo "Some SHA-512/256 sums do not match:" - - # set output color to red - echo -e "\033[0;31m" - - # display mismatching files - while IFS= read -r line; do - echo $line | grep -iv "\sok$" | sed 's/^/ / ; s/: FAILED$//' - done <<< "$YADM_CHECKSUM_OUTPUT" - - # reset output color - echo -e "\033[0m" - echo "Consider running either \"yadm encrypt\" or \"yadm decrypt\"." - - # signal error - exit $ERROR_CODE - fi - else - echo - echo "WARNING: command \"shasum\" not found. Checksums were not verified." - exit $YADM_HOOK_EXIT - fi +if [ ! -f $YADM_CHECKSUMS ]; then + # return exit status of the yadm command + exit $YADM_HOOK_EXIT fi -# return exit status of the yadm command -exit $YADM_HOOK_EXIT +# check if "shasum" exists and supports algorithm +ensure_command shasum +ensure_algorithm + +# check encrypted files for differences and capture output +YADM_CHECKSUM_OUTPUT=$(shasum --algorithm "$CHECKSUM_ALGORITHM" --check $YADM_CHECKSUMS 2> /dev/null) +ERROR_CODE=$? + +# some checksums do not match +if [ $ERROR_CODE -ne 0 ]; then + echo + echo "Some $CHECKSUM_ALGORITHM_NAME sums do not match:" + + # set output color to red + echo -e "\033[0;31m" + + # display mismatching files + while IFS= read -r line; do + # try to beautify output + if command -v grep > /dev/null && command -v sed > /dev/null; then + echo $line | grep -iv "\sok$" | sed 's/^/ / ; s/: FAILED$//' + else + echo $line + fi + done <<< "$YADM_CHECKSUM_OUTPUT" + + # reset output color + echo -e "\033[0m" + echo "Consider running either \"yadm encrypt\" or \"yadm decrypt\"." + + # signal error + exit $ERROR_CODE +fi From e9720fb1c36c90be73d4f6c0c0b47f62322a2646 Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Fri, 27 Dec 2019 23:39:06 +0100 Subject: [PATCH 03/11] add quotes to support spaces in filenames --- contrib/hooks/post_encrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/hooks/post_encrypt b/contrib/hooks/post_encrypt index ffec5d5..a37a8ee 100755 --- a/contrib/hooks/post_encrypt +++ b/contrib/hooks/post_encrypt @@ -67,7 +67,7 @@ ensure_algorithm echo -n > $YADM_CHECKSUMS # calculate checksums for encrypted files -for included in ${YADM_ENCRYPT_INCLUDE_FILES[@]}; do +for included in "${YADM_ENCRYPT_INCLUDE_FILES[@]}"; do shasum --algorithm $CHECKSUM_ALGORITHM $included >> $YADM_CHECKSUMS # signal errors From 0b79b461a66886b66bcb68600ca6ab0757374d7a Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Sat, 28 Dec 2019 11:17:52 +0100 Subject: [PATCH 04/11] change checksum algorithm to SHA-512 * SHA-512/256 doesn't seem to be supported on OS X (see https://ss64.com/osx/shasum.html) --- contrib/hooks/post_encrypt | 4 ++-- contrib/hooks/post_status | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/hooks/post_encrypt b/contrib/hooks/post_encrypt index a37a8ee..c4808c8 100755 --- a/contrib/hooks/post_encrypt +++ b/contrib/hooks/post_encrypt @@ -20,8 +20,8 @@ YADM_DIRECTORY=$(dirname $YADM_HOOK_REPO) YADM_CHECKSUMS=$YADM_DIRECTORY/files.checksums -CHECKSUM_ALGORITHM="512256" -CHECKSUM_ALGORITHM_NAME="SHA-512/256" +CHECKSUM_ALGORITHM="512" +CHECKSUM_ALGORITHM_NAME="SHA-512" WARNING_MESSAGE="No checksums were created." diff --git a/contrib/hooks/post_status b/contrib/hooks/post_status index 036264e..1190785 100755 --- a/contrib/hooks/post_status +++ b/contrib/hooks/post_status @@ -20,8 +20,8 @@ YADM_DIRECTORY=$(dirname $YADM_HOOK_REPO) YADM_CHECKSUMS=$YADM_DIRECTORY/files.checksums -CHECKSUM_ALGORITHM="512256" -CHECKSUM_ALGORITHM_NAME="SHA-512/256" +CHECKSUM_ALGORITHM="512" +CHECKSUM_ALGORITHM_NAME="SHA-512" WARNING_MESSAGE="Checksums were not verified." From c190333fdf6005e16dc85b3803e72d64019239ed Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Sat, 28 Dec 2019 16:09:19 +0100 Subject: [PATCH 05/11] correctly export array to subscript * fix shellcheck errors and warnings --- contrib/hooks/post_encrypt | 21 ++++++++++++++------- contrib/hooks/post_status | 23 +++++++++++++++-------- yadm | 16 ++++++++++++++-- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/contrib/hooks/post_encrypt b/contrib/hooks/post_encrypt index c4808c8..ae9874c 100755 --- a/contrib/hooks/post_encrypt +++ b/contrib/hooks/post_encrypt @@ -17,9 +17,16 @@ # along with this program. If not, see . -YADM_DIRECTORY=$(dirname $YADM_HOOK_REPO) +YADM_DIRECTORY=$(dirname "$YADM_HOOK_REPO") YADM_CHECKSUMS=$YADM_DIRECTORY/files.checksums +# unpack exported array; filenames including a newline character (\n) +# are NOT supported +OLD_IFS="$IFS" +IFS=$'\n' +YADM_ENCRYPT_INCLUDE_FILES=( $YADM_ENCRYPT_INCLUDE_FILES ) +IFS="$OLD_IFS" + CHECKSUM_ALGORITHM="512" CHECKSUM_ALGORITHM_NAME="SHA-512" WARNING_MESSAGE="No checksums were created." @@ -35,7 +42,7 @@ function print_warning_and_exit { # reset output color echo -e "\033[0m" - exit $YADM_HOOK_EXIT + exit "$YADM_HOOK_EXIT" } @@ -50,7 +57,7 @@ function ensure_command { function ensure_algorithm { - # check if "shasum" supports algorithm + # check if "shasum" supports algorithm by hashing an empty string echo -n | shasum --algorithm "$CHECKSUM_ALGORITHM" &> /dev/null if [ $? -ne 0 ]; then @@ -64,11 +71,11 @@ ensure_command shasum ensure_algorithm # empty checksum file -echo -n > $YADM_CHECKSUMS +echo -n > "$YADM_CHECKSUMS" # calculate checksums for encrypted files -for included in "${YADM_ENCRYPT_INCLUDE_FILES[@]}"; do - shasum --algorithm $CHECKSUM_ALGORITHM $included >> $YADM_CHECKSUMS +for included in ${YADM_ENCRYPT_INCLUDE_FILES[*]}; do + shasum --algorithm $CHECKSUM_ALGORITHM "$included" >> "$YADM_CHECKSUMS" # signal errors if [ $? -ne 0 ]; then @@ -79,4 +86,4 @@ done echo "Wrote checksums: $YADM_CHECKSUMS ($CHECKSUM_ALGORITHM_NAME)" # return exit status of the yadm command -exit $YADM_HOOK_EXIT +exit "$YADM_HOOK_EXIT" diff --git a/contrib/hooks/post_status b/contrib/hooks/post_status index 1190785..5e91c9e 100755 --- a/contrib/hooks/post_status +++ b/contrib/hooks/post_status @@ -17,9 +17,16 @@ # along with this program. If not, see . -YADM_DIRECTORY=$(dirname $YADM_HOOK_REPO) +YADM_DIRECTORY=$(dirname "$YADM_HOOK_REPO") YADM_CHECKSUMS=$YADM_DIRECTORY/files.checksums +# unpack exported array; filenames including a newline character (\n) +# are NOT supported +OLD_IFS="$IFS" +IFS=$'\n' +YADM_ENCRYPT_INCLUDE_FILES=( $YADM_ENCRYPT_INCLUDE_FILES ) +IFS="$OLD_IFS" + CHECKSUM_ALGORITHM="512" CHECKSUM_ALGORITHM_NAME="SHA-512" WARNING_MESSAGE="Checksums were not verified." @@ -35,7 +42,7 @@ function print_warning_and_exit { # reset output color echo -e "\033[0m" - exit $YADM_HOOK_EXIT + exit "$YADM_HOOK_EXIT" } @@ -50,7 +57,7 @@ function ensure_command { function ensure_algorithm { - # check if "shasum" supports algorithm + # check if "shasum" supports algorithm by hashing an empty string echo -n | shasum --algorithm "$CHECKSUM_ALGORITHM" &> /dev/null if [ $? -ne 0 ]; then @@ -60,9 +67,9 @@ function ensure_algorithm { # check whether file with checksums exists -if [ ! -f $YADM_CHECKSUMS ]; then +if [ ! -f "$YADM_CHECKSUMS" ]; then # return exit status of the yadm command - exit $YADM_HOOK_EXIT + exit "$YADM_HOOK_EXIT" fi # check if "shasum" exists and supports algorithm @@ -70,7 +77,7 @@ ensure_command shasum ensure_algorithm # check encrypted files for differences and capture output -YADM_CHECKSUM_OUTPUT=$(shasum --algorithm "$CHECKSUM_ALGORITHM" --check $YADM_CHECKSUMS 2> /dev/null) +YADM_CHECKSUM_OUTPUT=$(shasum --algorithm "$CHECKSUM_ALGORITHM" --check "$YADM_CHECKSUMS" 2> /dev/null) ERROR_CODE=$? # some checksums do not match @@ -85,9 +92,9 @@ if [ $ERROR_CODE -ne 0 ]; then while IFS= read -r line; do # try to beautify output if command -v grep > /dev/null && command -v sed > /dev/null; then - echo $line | grep -iv "\sok$" | sed 's/^/ / ; s/: FAILED$//' + echo "$line" | grep -iv "\sok$" | sed 's/^/ / ; s/: FAILED$//' else - echo $line + echo "$line" fi done <<< "$YADM_CHECKSUM_OUTPUT" diff --git a/yadm b/yadm index 0410482..90b2672 100755 --- a/yadm +++ b/yadm @@ -1577,7 +1577,11 @@ function invoke_hook() { YADM_HOOK_FULL_COMMAND=$FULL_COMMAND YADM_HOOK_REPO=$YADM_REPO YADM_HOOK_WORK=$YADM_WORK - YADM_ENCRYPT_INCLUDE_FILES=${ENCRYPT_INCLUDE_FILES[@]} + + # pack array to export it; filenames including a newline character (\n) + # are NOT supported + YADM_ENCRYPT_INCLUDE_FILES=$(join_string $'\n' "${ENCRYPT_INCLUDE_FILES[@]}") + export YADM_HOOK_COMMAND export YADM_HOOK_EXIT export YADM_HOOK_FULL_COMMAND @@ -1821,6 +1825,13 @@ function auto_bootstrap() { } +# ****** Helper Functions ****** + +function join_string { + local IFS="$1" + echo "${*:2}" +} + # ****** Prerequisites Functions ****** function require_archive() { @@ -1888,7 +1899,7 @@ function readlink_available() { return 1 } -# ****** Directory tranlations ****** +# ****** Directory translations ****** function unix_path() { # for paths used by bash/yadm @@ -1908,6 +1919,7 @@ function mixed_path() { } # ****** echo replacements ****** + function echo() { IFS=' ' printf '%s\n' "$*" From 3c204119fb93956a6a9a68e36a653e41f44b6cec Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Sat, 28 Dec 2019 22:35:55 +0100 Subject: [PATCH 06/11] select one of several checksum commands --- contrib/hooks/post_encrypt | 98 +++++++++++++++++++++----------------- contrib/hooks/post_status | 91 +++++++++++++++++------------------ 2 files changed, 97 insertions(+), 92 deletions(-) diff --git a/contrib/hooks/post_encrypt b/contrib/hooks/post_encrypt index ae9874c..eefb666 100755 --- a/contrib/hooks/post_encrypt +++ b/contrib/hooks/post_encrypt @@ -27,63 +27,73 @@ IFS=$'\n' YADM_ENCRYPT_INCLUDE_FILES=( $YADM_ENCRYPT_INCLUDE_FILES ) IFS="$OLD_IFS" -CHECKSUM_ALGORITHM="512" -CHECKSUM_ALGORITHM_NAME="SHA-512" -WARNING_MESSAGE="No checksums were created." +WARNING_MESSAGE="No checksums were created" -function print_warning_and_exit { - MESSAGE=$1 +function get_checksum_command { + # check if "shasum" exists and supports the algorithm (which is + # tested by sending an empty string to "shasum") + if command -v "shasum" > /dev/null && echo -n | shasum --algorithm "256" &> /dev/null; then + echo "shasum --algorithm 256" + # check if "sha256sum" exists + elif command -v "sha256sum" > /dev/null; then + echo "sha256sum" + # check if "gsha256sum" exists + elif command -v "gsha256sum" > /dev/null; then + echo "gsha256sum" + else + # display warning in bright yellow + echo -e "\033[1;33m" >&2 + echo -n "WARNING: \"shasum\", \"sha256sum\" and \"gsha256sum\" not found. $WARNING_MESSAGE." >&2 - # set output color to yellow - echo -e "\033[1;33m" - echo "WARNING: $MESSAGE $WARNING_MESSAGE" + # reset output color + echo -e "\033[0m" >&2 - # reset output color - echo -e "\033[0m" + # signal error + return 1 + fi +} + +# get checksum command +CHECKSUM_COMMAND=$(get_checksum_command) +ERROR_CODE=$? + +# no command found +if [ $ERROR_CODE -ne 0 ]; then + # return original exit status of yadm command exit "$YADM_HOOK_EXIT" -} +fi - -function ensure_command { - COMMAND_NAME=$1 - - # check if command exists - if ! command -v "$COMMAND_NAME" > /dev/null; then - print_warning_and_exit "command \"$COMMAND_NAME\" not found." - fi -} - - -function ensure_algorithm { - # check if "shasum" supports algorithm by hashing an empty string - echo -n | shasum --algorithm "$CHECKSUM_ALGORITHM" &> /dev/null - - if [ $? -ne 0 ]; then - print_warning_and_exit "\"shasum\" does not support $CHECKSUM_ALGORITHM_NAME." - fi -} - - -# check if "shasum" exists and supports algorithm -ensure_command shasum -ensure_algorithm - -# empty checksum file +# empty (or create) checksum file echo -n > "$YADM_CHECKSUMS" # calculate checksums for encrypted files for included in ${YADM_ENCRYPT_INCLUDE_FILES[*]}; do - shasum --algorithm $CHECKSUM_ALGORITHM "$included" >> "$YADM_CHECKSUMS" + # highlight any errors in red + echo -en "\033[0;31m" - # signal errors - if [ $? -ne 0 ]; then - exit $? + # calculate checksums + $CHECKSUM_COMMAND "$included" >> "$YADM_CHECKSUMS" + ERROR_CODE=$? + + # reset output color + echo -ne "\033[0m" + + # handle errors + if [ $ERROR_CODE -ne 0 ]; then + # display warning in bright yellow + echo -e "\033[1;33m" >&2 + echo -n "WARNING: an error occurred. Please inspect the checksum file." >&2 + + # reset output color + echo -e "\033[0m" >&2 + + # exit and signal error + exit $ERROR_CODE fi done -echo "Wrote checksums: $YADM_CHECKSUMS ($CHECKSUM_ALGORITHM_NAME)" - -# return exit status of the yadm command +# announce success and return original exit status of yadm command +echo "Wrote SHA-256 checksums: $YADM_CHECKSUMS" exit "$YADM_HOOK_EXIT" diff --git a/contrib/hooks/post_status b/contrib/hooks/post_status index 5e91c9e..aba3ae8 100755 --- a/contrib/hooks/post_status +++ b/contrib/hooks/post_status @@ -27,72 +27,67 @@ IFS=$'\n' YADM_ENCRYPT_INCLUDE_FILES=( $YADM_ENCRYPT_INCLUDE_FILES ) IFS="$OLD_IFS" -CHECKSUM_ALGORITHM="512" -CHECKSUM_ALGORITHM_NAME="SHA-512" -WARNING_MESSAGE="Checksums were not verified." +WARNING_MESSAGE="Checksums were not verified" -function print_warning_and_exit { - MESSAGE=$1 +function get_checksum_command { + # check if "shasum" exists and supports the algorithm (which is + # tested by sending an empty string to "shasum") + if command -v "shasum" > /dev/null && echo -n | shasum --algorithm "256" &> /dev/null; then + echo "shasum --algorithm 256" + # check if "sha256sum" exists + elif command -v "sha256sum" > /dev/null; then + echo "sha256sum" + # check if "gsha256sum" exists + elif command -v "gsha256sum" > /dev/null; then + echo "gsha256sum" + else + # display warning in bright yellow + echo -e "\033[1;33m" >&2 + echo -n "WARNING: \"shasum\", \"sha256sum\" and \"gsha256sum\" not found. $WARNING_MESSAGE." >&2 - # set output color to yellow - echo -e "\033[1;33m" - echo "WARNING: $MESSAGE $WARNING_MESSAGE" + # reset output color + echo -e "\033[0m" >&2 - # reset output color - echo -e "\033[0m" - - exit "$YADM_HOOK_EXIT" -} - - -function ensure_command { - COMMAND_NAME=$1 - - # check if command exists - if ! command -v "$COMMAND_NAME" > /dev/null; then - print_warning_and_exit "command \"$COMMAND_NAME\" not found." + # signal error + return 1 fi } -function ensure_algorithm { - # check if "shasum" supports algorithm by hashing an empty string - echo -n | shasum --algorithm "$CHECKSUM_ALGORITHM" &> /dev/null - - if [ $? -ne 0 ]; then - print_warning_and_exit "\"shasum\" does not support $CHECKSUM_ALGORITHM_NAME." - fi -} - - -# check whether file with checksums exists +# if there is no checksum file, exit with original status of yadm +# command if [ ! -f "$YADM_CHECKSUMS" ]; then - # return exit status of the yadm command exit "$YADM_HOOK_EXIT" fi -# check if "shasum" exists and supports algorithm -ensure_command shasum -ensure_algorithm - -# check encrypted files for differences and capture output -YADM_CHECKSUM_OUTPUT=$(shasum --algorithm "$CHECKSUM_ALGORITHM" --check "$YADM_CHECKSUMS" 2> /dev/null) +# get checksum command +CHECKSUM_COMMAND=$(get_checksum_command) ERROR_CODE=$? -# some checksums do not match +# no command found +if [ $ERROR_CODE -ne 0 ]; then + # return original exit status of yadm command + exit "$YADM_HOOK_EXIT" +fi + +# check encrypted files for differences and capture output and error +# messages +YADM_CHECKSUM_OUTPUT=$($CHECKSUM_COMMAND --check "$YADM_CHECKSUMS" 2>&1) +ERROR_CODE=$? + +# handle mismatched checksums and errors if [ $ERROR_CODE -ne 0 ]; then echo - echo "Some $CHECKSUM_ALGORITHM_NAME sums do not match:" + echo "Some SHA-256 sums do not match (or an error occurred):" - # set output color to red + # display differing files and errors (highlighted in red) echo -e "\033[0;31m" - # display mismatching files while IFS= read -r line; do - # try to beautify output + # try to beautify output (requires "grep" and "sed") if command -v grep > /dev/null && command -v sed > /dev/null; then - echo "$line" | grep -iv "\sok$" | sed 's/^/ / ; s/: FAILED$//' + echo "$line" | grep -iv "\sok$" | sed 's/^/ / ; s/: FAILED$// ; /^.*WARNING:.*did NOT match$/ d' else echo "$line" fi @@ -100,8 +95,8 @@ if [ $ERROR_CODE -ne 0 ]; then # reset output color echo -e "\033[0m" - echo "Consider running either \"yadm encrypt\" or \"yadm decrypt\"." - # signal error - exit $ERROR_CODE + # display advice for differing files and signal error + echo "Consider running either \"yadm encrypt\" or \"yadm decrypt\"." + exit $ERROR_CODE fi From bd19e31c6e6db08b7b8c6d652af3c2e0ee896c1a Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Sun, 29 Dec 2019 12:51:29 +0100 Subject: [PATCH 07/11] get rid of dirname --- contrib/hooks/post_encrypt | 6 ++---- contrib/hooks/post_status | 6 ++---- yadm | 2 ++ 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/contrib/hooks/post_encrypt b/contrib/hooks/post_encrypt index eefb666..d77d988 100755 --- a/contrib/hooks/post_encrypt +++ b/contrib/hooks/post_encrypt @@ -17,8 +17,8 @@ # along with this program. If not, see . -YADM_DIRECTORY=$(dirname "$YADM_HOOK_REPO") -YADM_CHECKSUMS=$YADM_DIRECTORY/files.checksums +YADM_CHECKSUMS="$YADM_HOOK_DIR/files.checksums" +WARNING_MESSAGE="No checksums were created" # unpack exported array; filenames including a newline character (\n) # are NOT supported @@ -27,8 +27,6 @@ IFS=$'\n' YADM_ENCRYPT_INCLUDE_FILES=( $YADM_ENCRYPT_INCLUDE_FILES ) IFS="$OLD_IFS" -WARNING_MESSAGE="No checksums were created" - function get_checksum_command { # check if "shasum" exists and supports the algorithm (which is diff --git a/contrib/hooks/post_status b/contrib/hooks/post_status index aba3ae8..1a308ef 100755 --- a/contrib/hooks/post_status +++ b/contrib/hooks/post_status @@ -17,8 +17,8 @@ # along with this program. If not, see . -YADM_DIRECTORY=$(dirname "$YADM_HOOK_REPO") -YADM_CHECKSUMS=$YADM_DIRECTORY/files.checksums +YADM_CHECKSUMS="$YADM_HOOK_DIR/files.checksums" +WARNING_MESSAGE="Checksums were not verified" # unpack exported array; filenames including a newline character (\n) # are NOT supported @@ -27,8 +27,6 @@ IFS=$'\n' YADM_ENCRYPT_INCLUDE_FILES=( $YADM_ENCRYPT_INCLUDE_FILES ) IFS="$OLD_IFS" -WARNING_MESSAGE="Checksums were not verified" - function get_checksum_command { # check if "shasum" exists and supports the algorithm (which is diff --git a/yadm b/yadm index 90b2672..312b70a 100755 --- a/yadm +++ b/yadm @@ -1573,6 +1573,7 @@ function invoke_hook() { # expose some internal data to all hooks YADM_HOOK_COMMAND=$HOOK_COMMAND + YADM_HOOK_DIR=$YADM_DIR YADM_HOOK_EXIT=$exit_status YADM_HOOK_FULL_COMMAND=$FULL_COMMAND YADM_HOOK_REPO=$YADM_REPO @@ -1583,6 +1584,7 @@ function invoke_hook() { YADM_ENCRYPT_INCLUDE_FILES=$(join_string $'\n' "${ENCRYPT_INCLUDE_FILES[@]}") export YADM_HOOK_COMMAND + export YADM_HOOK_DIR export YADM_HOOK_EXIT export YADM_HOOK_FULL_COMMAND export YADM_HOOK_REPO From 45b218d5c18c7ce61b1fcca8cc185b36ac34a1f6 Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Sun, 29 Dec 2019 15:21:55 +0100 Subject: [PATCH 08/11] support encrypted files in "yadm list" * export some helper functions to hooks --- contrib/hooks/post_list | 73 +++++++++++++++++++++++++++++++++++++++++ yadm | 6 ++++ 2 files changed, 79 insertions(+) create mode 100755 contrib/hooks/post_list diff --git a/contrib/hooks/post_list b/contrib/hooks/post_list new file mode 100755 index 0000000..6e0394e --- /dev/null +++ b/contrib/hooks/post_list @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# yadm - Yet Another Dotfiles Manager +# Copyright (C) 2015-2019 Tim Byrne and Martin Zuther + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +YADM_CHECKSUMS="$YADM_HOOK_DIR/files.checksums" + + +# is current directory on yadm's work path? +# (adapted from https://unix.stackexchange.com/a/6438/122163) +if [ "${PWD##$YADM_HOOK_WORK}" != "$PWD" ]; then + ON_WORK_PATH=1 +else + ON_WORK_PATH=0 +fi + + +# list all files or only those in the subdirectories below? +OPTION_LIST_ALL=0 +for argument in ${YADM_HOOK_FULL_COMMAND[*]}; do + # mimick git ls-files by displaying all files when not on work + # path + if [ "$argument" = "-a" ] || [ $ON_WORK_PATH -eq 0 ]; then + OPTION_LIST_ALL=1 + break + fi +done + + +# if there is no checksum file, exit with original status of yadm +# command +if [ ! -f "$YADM_CHECKSUMS" ]; then + exit "$YADM_HOOK_EXIT" +fi + +# list encrypted files; try to satisfy the "list -a" argument and +# beautify the output (requires "grep" and "sed") +if command -v grep > /dev/null && command -v sed > /dev/null; then + # remove checksums from file names + while IFS= read -r filename; do + if [ $OPTION_LIST_ALL -eq 0 ]; then + # list only files in the subdirectories below (i.e. files + # whose relative path doesn't begin with "../") + REL_PATH=$(relative_path "$PWD" "$YADM_HOOK_WORK/$filename") + + if ! echo "$REL_PATH" | grep '^\.\./' > /dev/null; then + echo "$REL_PATH" + fi + else + # list all files + echo "$filename" + fi + done <<< "$(sed -r 's/^\S+\s+//' "$YADM_CHECKSUMS")" +else + # just display checksum file + cat "$YADM_CHECKSUMS" +fi + +# return original exit status of yadm command +exit "$YADM_HOOK_EXIT" diff --git a/yadm b/yadm index 312b70a..0a642aa 100755 --- a/yadm +++ b/yadm @@ -1591,6 +1591,12 @@ function invoke_hook() { export YADM_HOOK_WORK export YADM_ENCRYPT_INCLUDE_FILES + # export helper functions + export -f builtin_dirname + export -f relative_path + export -f unix_path + export -f mixed_path + "$hook_command" hook_status=$? From 9c9a750009897f0acab2a5320300cdcb42d62aae Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Sun, 29 Dec 2019 15:53:01 +0100 Subject: [PATCH 09/11] get rid of dependencies (pure bash) --- contrib/hooks/post_list | 34 +++++++++++++++------------------- contrib/hooks/post_status | 10 ++++++---- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/contrib/hooks/post_list b/contrib/hooks/post_list index 6e0394e..0cc65c4 100755 --- a/contrib/hooks/post_list +++ b/contrib/hooks/post_list @@ -46,28 +46,24 @@ if [ ! -f "$YADM_CHECKSUMS" ]; then exit "$YADM_HOOK_EXIT" fi -# list encrypted files; try to satisfy the "list -a" argument and -# beautify the output (requires "grep" and "sed") -if command -v grep > /dev/null && command -v sed > /dev/null; then +# list encrypted files +while IFS= read -r filename; do # remove checksums from file names - while IFS= read -r filename; do - if [ $OPTION_LIST_ALL -eq 0 ]; then - # list only files in the subdirectories below (i.e. files - # whose relative path doesn't begin with "../") - REL_PATH=$(relative_path "$PWD" "$YADM_HOOK_WORK/$filename") + filename="${filename##[a-zA-Z0-9]* }" - if ! echo "$REL_PATH" | grep '^\.\./' > /dev/null; then - echo "$REL_PATH" - fi - else - # list all files - echo "$filename" + # list only files in the subdirectories below (i.e. files + # whose relative path doesn't begin with "../") + if [ $OPTION_LIST_ALL -eq 0 ]; then + REL_PATH=$(relative_path "$PWD" "$YADM_HOOK_WORK/$filename") + + if [ "$REL_PATH" = "${REL_PATH##../}" ]; then + echo "$REL_PATH" fi - done <<< "$(sed -r 's/^\S+\s+//' "$YADM_CHECKSUMS")" -else - # just display checksum file - cat "$YADM_CHECKSUMS" -fi + # list all files + else + echo "$filename" + fi +done <<< "$(cat "$YADM_CHECKSUMS")" # return original exit status of yadm command exit "$YADM_HOOK_EXIT" diff --git a/contrib/hooks/post_status b/contrib/hooks/post_status index 1a308ef..e13b599 100755 --- a/contrib/hooks/post_status +++ b/contrib/hooks/post_status @@ -83,10 +83,12 @@ if [ $ERROR_CODE -ne 0 ]; then echo -e "\033[0;31m" while IFS= read -r line; do - # try to beautify output (requires "grep" and "sed") - if command -v grep > /dev/null && command -v sed > /dev/null; then - echo "$line" | grep -iv "\sok$" | sed 's/^/ / ; s/: FAILED$// ; /^.*WARNING:.*did NOT match$/ d' - else + # beautify output and get rid of unnecessary lines + line="${line%%*: [Oo][Kk]}" + line="${line%%: [Ff][Aa][Ii][Ll][Ee][Dd]}" + line="${line##*WARNING:*did NOT match}" + + if [ -n "$line" ]; then echo "$line" fi done <<< "$YADM_CHECKSUM_OUTPUT" From 499837bd80dcd6a578b31e8cc6c70e132d481ece Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Mon, 30 Dec 2019 00:11:36 +0100 Subject: [PATCH 10/11] apply code review changes --- contrib/hooks/post_encrypt | 7 +++---- contrib/hooks/post_list | 4 ++-- contrib/hooks/post_status | 5 ++--- yadm | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/contrib/hooks/post_encrypt b/contrib/hooks/post_encrypt index d77d988..7ffce13 100755 --- a/contrib/hooks/post_encrypt +++ b/contrib/hooks/post_encrypt @@ -55,10 +55,9 @@ function get_checksum_command { # get checksum command CHECKSUM_COMMAND=$(get_checksum_command) -ERROR_CODE=$? # no command found -if [ $ERROR_CODE -ne 0 ]; then +if (($?)); then # return original exit status of yadm command exit "$YADM_HOOK_EXIT" fi @@ -67,7 +66,7 @@ fi echo -n > "$YADM_CHECKSUMS" # calculate checksums for encrypted files -for included in ${YADM_ENCRYPT_INCLUDE_FILES[*]}; do +for included in "${YADM_ENCRYPT_INCLUDE_FILES[@]}"; do # highlight any errors in red echo -en "\033[0;31m" @@ -79,7 +78,7 @@ for included in ${YADM_ENCRYPT_INCLUDE_FILES[*]}; do echo -ne "\033[0m" # handle errors - if [ $ERROR_CODE -ne 0 ]; then + if (($ERROR_CODE)); then # display warning in bright yellow echo -e "\033[1;33m" >&2 echo -n "WARNING: an error occurred. Please inspect the checksum file." >&2 diff --git a/contrib/hooks/post_list b/contrib/hooks/post_list index 0cc65c4..6c6acf0 100755 --- a/contrib/hooks/post_list +++ b/contrib/hooks/post_list @@ -30,7 +30,7 @@ fi # list all files or only those in the subdirectories below? OPTION_LIST_ALL=0 -for argument in ${YADM_HOOK_FULL_COMMAND[*]}; do +for argument in "${YADM_HOOK_FULL_COMMAND[@]}"; do # mimick git ls-files by displaying all files when not on work # path if [ "$argument" = "-a" ] || [ $ON_WORK_PATH -eq 0 ]; then @@ -63,7 +63,7 @@ while IFS= read -r filename; do else echo "$filename" fi -done <<< "$(cat "$YADM_CHECKSUMS")" +done < "$YADM_CHECKSUMS" # return original exit status of yadm command exit "$YADM_HOOK_EXIT" diff --git a/contrib/hooks/post_status b/contrib/hooks/post_status index e13b599..137af04 100755 --- a/contrib/hooks/post_status +++ b/contrib/hooks/post_status @@ -61,10 +61,9 @@ fi # get checksum command CHECKSUM_COMMAND=$(get_checksum_command) -ERROR_CODE=$? # no command found -if [ $ERROR_CODE -ne 0 ]; then +if (($?)); then # return original exit status of yadm command exit "$YADM_HOOK_EXIT" fi @@ -75,7 +74,7 @@ YADM_CHECKSUM_OUTPUT=$($CHECKSUM_COMMAND --check "$YADM_CHECKSUMS" 2>&1) ERROR_CODE=$? # handle mismatched checksums and errors -if [ $ERROR_CODE -ne 0 ]; then +if (($ERROR_CODE)); then echo echo "Some SHA-256 sums do not match (or an error occurred):" diff --git a/yadm b/yadm index 0a642aa..f164b16 100755 --- a/yadm +++ b/yadm @@ -1837,7 +1837,7 @@ function auto_bootstrap() { function join_string { local IFS="$1" - echo "${*:2}" + printf "%s" "${*:2}" } # ****** Prerequisites Functions ****** From 0009bb350b745cd800b1272ef3c047549ece24c2 Mon Sep 17 00:00:00 2001 From: Martin Zuther Date: Mon, 30 Dec 2019 00:43:24 +0100 Subject: [PATCH 11/11] get rid of echo --- contrib/hooks/post_encrypt | 28 ++++++++++++++-------------- contrib/hooks/post_list | 4 ++-- contrib/hooks/post_status | 25 ++++++++++++------------- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/contrib/hooks/post_encrypt b/contrib/hooks/post_encrypt index 7ffce13..bc4cbf6 100755 --- a/contrib/hooks/post_encrypt +++ b/contrib/hooks/post_encrypt @@ -31,21 +31,21 @@ IFS="$OLD_IFS" function get_checksum_command { # check if "shasum" exists and supports the algorithm (which is # tested by sending an empty string to "shasum") - if command -v "shasum" > /dev/null && echo -n | shasum --algorithm "256" &> /dev/null; then - echo "shasum --algorithm 256" + if command -v "shasum" > /dev/null && printf "" | shasum --algorithm "256" &> /dev/null; then + printf "shasum --algorithm 256" # check if "sha256sum" exists elif command -v "sha256sum" > /dev/null; then - echo "sha256sum" + printf "sha256sum" # check if "gsha256sum" exists elif command -v "gsha256sum" > /dev/null; then - echo "gsha256sum" + printf "gsha256sum" else # display warning in bright yellow - echo -e "\033[1;33m" >&2 - echo -n "WARNING: \"shasum\", \"sha256sum\" and \"gsha256sum\" not found. $WARNING_MESSAGE." >&2 + printf "\033[1;33m" >&2 + printf "\nWARNING: \"shasum\", \"sha256sum\" and \"gsha256sum\" not found. %s\n" "$WARNING_MESSAGE." >&2 # reset output color - echo -e "\033[0m" >&2 + printf "\033[0m" >&2 # signal error return 1 @@ -63,28 +63,28 @@ if (($?)); then fi # empty (or create) checksum file -echo -n > "$YADM_CHECKSUMS" +true > "$YADM_CHECKSUMS" # calculate checksums for encrypted files for included in "${YADM_ENCRYPT_INCLUDE_FILES[@]}"; do # highlight any errors in red - echo -en "\033[0;31m" + printf "\033[0;31m" # calculate checksums $CHECKSUM_COMMAND "$included" >> "$YADM_CHECKSUMS" ERROR_CODE=$? # reset output color - echo -ne "\033[0m" + printf "\033[0m" # handle errors if (($ERROR_CODE)); then # display warning in bright yellow - echo -e "\033[1;33m" >&2 - echo -n "WARNING: an error occurred. Please inspect the checksum file." >&2 + printf "\033[1;33m" >&2 + printf "\nWARNING: an error occurred. Please inspect the checksum file.\n" >&2 # reset output color - echo -e "\033[0m" >&2 + printf "\033[0m" >&2 # exit and signal error exit $ERROR_CODE @@ -92,5 +92,5 @@ for included in "${YADM_ENCRYPT_INCLUDE_FILES[@]}"; do done # announce success and return original exit status of yadm command -echo "Wrote SHA-256 checksums: $YADM_CHECKSUMS" +printf "Wrote SHA-256 checksums: %s\n" "$YADM_CHECKSUMS" exit "$YADM_HOOK_EXIT" diff --git a/contrib/hooks/post_list b/contrib/hooks/post_list index 6c6acf0..b95acc2 100755 --- a/contrib/hooks/post_list +++ b/contrib/hooks/post_list @@ -57,11 +57,11 @@ while IFS= read -r filename; do REL_PATH=$(relative_path "$PWD" "$YADM_HOOK_WORK/$filename") if [ "$REL_PATH" = "${REL_PATH##../}" ]; then - echo "$REL_PATH" + printf "%s\n" "$REL_PATH" fi # list all files else - echo "$filename" + printf "%s\n" "$filename" fi done < "$YADM_CHECKSUMS" diff --git a/contrib/hooks/post_status b/contrib/hooks/post_status index 137af04..3dd0465 100755 --- a/contrib/hooks/post_status +++ b/contrib/hooks/post_status @@ -31,21 +31,21 @@ IFS="$OLD_IFS" function get_checksum_command { # check if "shasum" exists and supports the algorithm (which is # tested by sending an empty string to "shasum") - if command -v "shasum" > /dev/null && echo -n | shasum --algorithm "256" &> /dev/null; then - echo "shasum --algorithm 256" + if command -v "shasum" > /dev/null && printf "" | shasum --algorithm "256" &> /dev/null; then + printf "shasum --algorithm 256" # check if "sha256sum" exists elif command -v "sha256sum" > /dev/null; then - echo "sha256sum" + printf "sha256sum" # check if "gsha256sum" exists elif command -v "gsha256sum" > /dev/null; then - echo "gsha256sum" + printf "gsha256sum" else # display warning in bright yellow - echo -e "\033[1;33m" >&2 - echo -n "WARNING: \"shasum\", \"sha256sum\" and \"gsha256sum\" not found. $WARNING_MESSAGE." >&2 + printf "\033[1;33m" >&2 + printf "\nWARNING: \"shasum\", \"sha256sum\" and \"gsha256sum\" not found. %s\n" "$WARNING_MESSAGE." >&2 # reset output color - echo -e "\033[0m" >&2 + printf "\033[0m" >&2 # signal error return 1 @@ -75,11 +75,10 @@ ERROR_CODE=$? # handle mismatched checksums and errors if (($ERROR_CODE)); then - echo - echo "Some SHA-256 sums do not match (or an error occurred):" + printf "\nSome SHA-256 sums do not match (or an error occurred):\n\n" # display differing files and errors (highlighted in red) - echo -e "\033[0;31m" + printf "\033[0;31m" while IFS= read -r line; do # beautify output and get rid of unnecessary lines @@ -88,14 +87,14 @@ if (($ERROR_CODE)); then line="${line##*WARNING:*did NOT match}" if [ -n "$line" ]; then - echo "$line" + printf "%s\n" "$line" fi done <<< "$YADM_CHECKSUM_OUTPUT" # reset output color - echo -e "\033[0m" + printf "\033[0m" # display advice for differing files and signal error - echo "Consider running either \"yadm encrypt\" or \"yadm decrypt\"." + printf "\nConsider running either \"yadm encrypt\" or \"yadm decrypt\".\n" exit $ERROR_CODE fi