doc(user/bkphotorights): Add exiftool.org XMP tag reference
[BK-2020-03.git] / user / bksum
index 08b6c81bebe5b340fbd46821fb3e77307c5db90b..9597c820bc0a1f82957e0c2dc87f5b205a232a13 100755 (executable)
@@ -5,7 +5,7 @@
 #        arg(s): file paths (IFS delimited)
 # Output: file containing sha256 hashes and file paths
 # Depends: bash v5.1.16, date (GNU Coreutils 8.32), gpg v2.2.27, ots v0.7.0
 #        arg(s): file paths (IFS delimited)
 # Output: file containing sha256 hashes and file paths
 # Depends: bash v5.1.16, date (GNU Coreutils 8.32), gpg v2.2.27, ots v0.7.0
-# Version: 0.0.1
+# Version: 0.1.1
 
 declare -Ag appRollCall # Associative array for storing app status
 declare -Ag fileRollCall # Associative array for storing file status
 
 declare -Ag appRollCall # Associative array for storing app status
 declare -Ag fileRollCall # Associative array for storing file status
@@ -65,6 +65,11 @@ showUsage() {
         -t, --timestamp
                 Timestamp with OpenTimestamps the checksum file
                 (and GnuPG signature if -s/--sign specified).
         -t, --timestamp
                 Timestamp with OpenTimestamps the checksum file
                 (and GnuPG signature if -s/--sign specified).
+        -T, --timestamp-wait
+                Same as '-t/--timestamp' except that
+                OpenTimestamps will run as a background process
+                until a calendar server returns a completed
+                timestamp.
         --
                 Indicate end of options.
 
         --
                 Indicate end of options.
 
@@ -272,6 +277,8 @@ processArgs() {
     #   pathDirOut1          Path to output directory.
     #   pathFileOut1         Path to output file.
     #   opFileOut1_overwrite Indicates whether file pathFileOut1 should be overwritten (ex: "true", "false").
     #   pathDirOut1          Path to output directory.
     #   pathFileOut1         Path to output file.
     #   opFileOut1_overwrite Indicates whether file pathFileOut1 should be overwritten (ex: "true", "false").
+    #   opTs                 Indicates timestamp mode
+    #   opTsWait             Indicates timestamp mode with wait option
     #   arrPosArgs         Array of remaining positional argments
     # Depends:
     #   yell()           Displays messages to stderr.
     #   arrPosArgs         Array of remaining positional argments
     # Depends:
     #   yell()           Displays messages to stderr.
@@ -319,7 +326,10 @@ processArgs() {
             -s | --sign) # sign with gpg
                 opSign="true"; vbm "DEBUG:Signing mode enabled.";;
             -t | --timestamp) # timestamp with ots
             -s | --sign) # sign with gpg
                 opSign="true"; vbm "DEBUG:Signing mode enabled.";;
             -t | --timestamp) # timestamp with ots
-                opTimestamp="true"; vbm "DEBUG:Timestamp mode enabled.";;
+                opTs="true"; vbm "DEBUG:Timestamp mode enabled.";;
+            -T | --timestamp-wait) # timestamp with ots with wait option
+                opTs="true"; vbm "DEBUG:Timestamp mode enabled.";
+                opTsWait="true"; vbm "DEBUG:Timestamp wait mode enabled.";;
             --) # End of all options. See [2].
                 shift;
                 for arg in "$@"; do
             --) # End of all options. See [2].
                 shift;
                 for arg in "$@"; do
@@ -410,11 +420,26 @@ checkDepends() {
 
     checkapp date sha256sum;
     if [[ $opSign == "true" ]]; then checkapp gpg; fi;
 
     checkapp date sha256sum;
     if [[ $opSign == "true" ]]; then checkapp gpg; fi;
-    if [[ $opTimestamp == "true" ]]; then checkapp ots; fi;
+    if [[ $opTs == "true" ]]; then checkapp ots; fi;
     
     # Return failure is displayMissing() reports apps missing.
     if ! displayMissing; then return 1; else return 0; fi;
 }; # Check dependencies
     
     # Return failure is displayMissing() reports apps missing.
     if ! displayMissing; then return 1; else return 0; fi;
 }; # Check dependencies
+count_jobs() {
+    # Desc: Count and return total number of jobs
+    # Usage: count_jobs
+    # Input: None.
+    # Output: stdout   integer number of jobs
+    # Depends: Bash 5.1.16
+    # Example: while [[$(count_jobs) -gt 0]]; do echo "Working..."; sleep 1; done;
+    # Version: 0.0.1
+    
+    local job_count;
+    job_count="$(jobs -r | wc -l | tr -d ' ' )";
+    #yell "DEBUG:job_count:$job_count";
+    if [[ -z $job_count ]]; then job_count="0"; fi;
+    echo "$job_count";
+}; # Return number of background jobs
 main() {
     # Input: pathFileOut1   option-specified output file path
     #        appRollCall    assoc-array for checkapp(), displayMissing()
 main() {
     # Input: pathFileOut1   option-specified output file path
     #        appRollCall    assoc-array for checkapp(), displayMissing()
@@ -458,17 +483,43 @@ main() {
     # Do optional work
     ## Sign checksum file.
     if [[ $opSign == "true" ]]; then
     # Do optional work
     ## Sign checksum file.
     if [[ $opSign == "true" ]]; then
-        try gpg --detach-sign --armor --output "$pathSigOut" "$pathSumOut";
+        yell "STATUS:Signing checksum file...";
+        try gpg --detach-sign --armor --output "$pathSigOut" "$pathSumOut" && yell "STATUS:Checksum created.";
     fi;
     ## Timestamp checksum file.
     fi;
     ## Timestamp checksum file.
-    if [[ $opTimestamp == "true" ]]; then
-        try ots s "$pathSumOut"; fi;
-
+    if [[ $opTs == "true" ]]; then
+        yell "STATUS:Timestamping checksum file...";
+        if [[ $opTsWait != "true" ]]; then
+            try ots s "$pathSumOut" &
+        elif [[ $opTsWait == "true" ]]; then
+            yell "NOTICE:Waiting for calendar server response in background. (This may take 8 to 24 hours)...";
+            yell "ADVICE:Do not close or suspend this terminal.";
+            try ots --wait s "$pathSumOut" 1>/dev/random 2>&1 &
+        fi;    
+    fi;
     ## Timestamp checksum signature file.
     ## Timestamp checksum signature file.
-    if [[ $opTimestamp == "true" && $opSign == "true" ]]; then
-        try ots s "$pathSigOut";
+    if [[ $opTs == "true" && $opSign == "true" ]]; then
+        yell "STATUS:Timestamping signature file...";
+        if [[ $opTsWait != "true" ]]; then
+            try ots s "$pathSigOut" && yell "STATUS:Timestamp of checksum signature file created.";
+        elif [[ $opTsWait == "true" ]]; then
+            yell "NOTICE:Waiting for calendar server response in background. (This may take 8 to 24 hours)...";
+            yell "ADVICE:Do not close or suspend this terminal.";
+            try ots --wait s "$pathSigOut" 1>/dev/random 2>&1 &
+        fi;
     fi;
 
     fi;
 
+    ## Wait until background jobs (if any) completed
+    for (( n = 1; "$(count_jobs)" > 0; n++ )); do
+        if ! [[ $((n % 60)) -eq 0 ]]; then
+            printf ".";
+        else
+            printf ".%05ds passed.\n" "$SECONDS";
+        fi;
+        sleep 60;
+    done;
+    
+    yell "Done.";
     return 0;
 }; # main program
 
     return 0;
 }; # main program