#!/bin/bash
# Desc: Utility for backing up and retrieving ots files
-# Version: 0.0.1
+# Version: 0.0.2
OTS_FCACHE_DIR="$HOME/.cache/bkotslu/";
MAX_FIND_DEPTH=12;
vbm "DEBUG:showVersion function ended."
return 0; # Function finished.
}; # Display script version.
+checkDepends() {
+ vbm "STATUS:Starting checkDepends()";
+ if ! command -v sha256sum 1>/dev/random 2>&1; then
+ die "FATAL:sha256sum not available."; fi;
+ if ! command -v grep 1>/dev/random 2>&1; then
+ die "FATAL:grep not available."; fi;
+ if ! command -v find 1>/dev/random 2>&1; then
+ die "FATAL:grep not available."; fi;
+};
processArgs() {
# Desc: Processes arguments provided to script.
# Usage: processArgs "$@"
# Input: arg1 OTS file path
# Output: stdout sha256 file hash (lowercase)
local output;
-
vbm "DEBUG:Starting get_ots_filehash() on:$1";
+
if output="$( "$(which ots)" info "$1" | \
grep -E "^File sha256 hash: " | \
head -n1 | \
sed -E -e 's/(^File sha256 hash: )([0-9a-f]+$)/\2/g'; )" && \
[[ -n "$output" ]]; then
- vbm "STATUS:Read file hash via ots from:$1";
+ vbm "STATUS:Read file digest (${output}) via ots from:$1";
printf "%s" "$output";
return 0;
else
# vbm()
# BK-2020-03: yell()
local output;
-
- vbm "DEBUG:Starting get_ots_oldestblock() on:$1";
+ vbm "DEBUG:Starting get_ots_oldestblock() on:$1";
+
if output="$( "$(which ots)" info "$1" | \
grep -E "verify BitcoinBlockHeaderAttestation\([0-9]+\)" | \
sort | head -n1 | \
sed -E -e 's/(^ verify BitcoinBlockHeaderAttestation)\(([0-9]+)(\))/\2/g'; )" && \
[[ -n "$output" ]]; then
- vbm "STATUS:Retrieved Bitcoin block via ots from:$1";
+ vbm "STATUS:Retrieved Bitcoin block (${output}) via ots from:$1";
printf "%s" "$output";
return 0;
else
}; # Gets oldest Bitcoin block from ots file
cache_ots_file() {
# Desc: Scans and caches an OTS file for storing
- if fhash="$(must get_ots_filehash "$line")" && \
- block="$(must get_ots_oldestblock "$line")"; then
+ # Input: arg1 input file
+ # Output: exit code
+ local fin="$1";
+ vbm "STATUS:Starting cache_ots_file()";
+
+ if [[ ! -f "$fin" ]]; then die "FATAL:OTS file not found:$fin"; fi;
+ if fhash="$(must get_ots_filehash "$fin")" && \
+ block="$(must get_ots_oldestblock "$fin")"; then
fout="${fhash}_${block}.otsu"; # file name out
pout="${pathDirOut1}/${fout}"; # file path out
- vbm "STATUS:Found OTS file at ${line} with hash ${fhash} and block ${block} and saving to ${pout}";
- must cp -n "$line" "$pout";
+ vbm "STATUS:Found OTS file at ${fin} with hash ${fhash} and block ${block}.";
+ vbm "STATUS:Saving found OTS file to ${pout}";
+ must cp -n "$fin" "$pout";
+ return 0;
else
- yell "ERROR:Problem analyzing file with OpenTimestamps:${line}";
+ yell "ERROR:Problem analyzing file with OpenTimestamps:${fin}";
+ return 1;
fi;
}; # Scans a single OTS file
-
+get_sha256_digest() {
+ # Depends: GNU Coreutils 8.32 (sha256sum)
+ # Input: arg1 path file path
+ # Output: stdout str sha256 digest (lowercase hexadecimal)
+ vbm "DEBUG:Starting get_sha256_digest()";
+ sha256sum "$1" | head -n1 | sed -E -e 's/(^[0-9a-f]{64})(.+)/\1/';
+};
+get_oldest_stored_ots_path() {
+ # Desc: Lookup most recent OTS file from storage
+ # Input: pathDirOut1 var path to OTS storage dir
+ # arg1 str sha256 digest (lowercase hexadecimal)
+ # Output: stdout path OTS file with matching sha256 digest
+ vbm "DEBUG:Starting get_oldest_stored_ots_path()";
+
+ digest="$1";
+ if output="$( find "$pathDirOut1" -type f -name "${digest}*" | \
+ sort | \
+ head -n1 )" && \
+ [[ -n "$output" ]]; then
+ output="$(readlink -f "$output")";
+ vbm "STATUS:Found matching OTS file with digest ${digest} at:$output";
+ printf "%s" "$output";
+ return 0;
+ else
+ yell "ERROR:Could not find matching OTS file with digest ${digest} in ${pathDirOut1}";
+ return 1;
+ fi;
+};
main() {
+ checkDepends;
processArgs "$@";
-
+ vbm "DEBUG:Starting rest of main()";
# Scan provided dir for OTS files to cache.
if [[ -n "$pathDirIn1" ]]; then
while read -r line; do
line="$(readlink -f "$line")";
- cache_ots_file;
+ cache_ots_file "$line";
done < <(find "$pathDirIn1" -maxdepth "$MAX_FIND_DEPTH" -type f -name "*.ots");
fi;
# Lookup OTS file from archive for provided file.
if [[ -n "$pathFileIn1" ]]; then
- :
+ # Check for and store any OTS file attached to provided file
+ if [[ -f "${pathFileIn1}.ots" ]]; then
+ vbm "STATUS:OTS file accompanying provided file found:${pathFileIn1}.ots";
+ cache_ots_file "${pathFileIn1}.ots" && vbm "STATUS:Stored provided file's OTS file.";
+ fi;
+
+ # Get file hash
+ fhash="$(get_sha256_digest "$pathFileIn1"; )";
+ if path_stored_ots="$(get_oldest_stored_ots_path "$fhash"; )"; then
+ vbm "STATUS:Stored OTS found with matching hash.";
+ blk_stored="$(get_ots_oldestblock "$path_stored_ots"; )";
+ vbm "STATUS:Stored OTS file has block number ${blk_stored}.";
+ if [[ -f "${pathFileIn1}.ots" ]]; then
+ vbm "STATUS:An OTS file is next to provided file.";
+ blk_provid="$(get_ots_oldestblock "${pathFileIn1}.ots"; )";
+ vbm "STATUS:Provided file's OTS file has block number ${blk_provid}";
+ if [[ "$blk_stored" -lt "$blk_provid" ]]; then
+ vbm "STATUS:Older timestamp in OTS store found. Replacing ${pathFileIn1} (block ${blk_provid}) with ${path_stored_ots} (block ${blk_stored}).";
+ #must mv "$pathFileIn1" "${pathFileIn1}.baku";
+ #must cp "$path_stored_ots" "$pathFileIn1";
+ else
+ yell "STATUS:Stored OTS file (block ${blk_stored}) is not older than provided file's OTS file (block ${blk_provid}). No action taken for:${pathFileIn1}";
+ fi;
+ else
+ vbm "STATUS:Stored OTS file found with digest matching provided file. Copying ${path_stored_ots} to ${pathFileIn1}.ots";
+ must cp "$path_stored_ots" "${pathFileIn1}.ots";
+ fi;
+ else
+ vbm "STATUS:No stored OTS found. No action taken for:${pathFileIn1}";
+ fi;
fi;
-
-
-
}; # main program