2 # Desc: Runs gpg --verify on all .asc, .gpg, and .sig files in specified directory. 
   4 # Depends: GNU parallel 20210822 
   5 # Assumes: File names do not contain newlines. 
   7 declare -Ag appRollCall 
# Associative array for storing app status 
   8 declare -Ag fileRollCall 
# Associative array for storing file status 
   9 declare -Ag dirRollCall 
# Associative array for storing dir status 
  10 find_pat_regex
=".+\(sig\|asc\|gpg\)$"; 
  13 yell
() { echo "$0: $*" >&2; } # print script path and all args to stderr 
  14 die
() { yell 
"$*"; exit 111; } # same as yell() but non-zero exit status 
  15 must
() { "$@" || die 
"cannot $*"; } # runs args as command, reports args if command fails 
  17     # Desc: If arg is a command, save result in assoc array 'appRollCall' 
  18     # Usage: checkapp arg1 arg2 arg3 ... 
  20     # Input: global assoc. array 'appRollCall' 
  21     # Output: adds/updates key(value) to global assoc array 'appRollCall' 
  27         if command -v "$arg" 1>/dev
/null 
2>&1; then # Check if arg is a valid command 
  28             appRollCall
[$arg]="true"; 
  29             if ! [ "$returnState" = "false" ]; then returnState
="true"; fi; 
  31             appRollCall
[$arg]="false"; returnState
="false"; 
  35     #===Determine function return code=== 
  36     if [ "$returnState" = "true" ]; then 
  41 } # Check that app exists 
  43     # Desc: If arg is a file path, save result in assoc array 'fileRollCall' 
  44     # Usage: checkfile arg1 arg2 arg3 ... 
  46     # Input: global assoc. array 'fileRollCall' 
  47     # Output: adds/updates key(value) to global assoc array 'fileRollCall'; 
  48     # Output: returns 0 if app found, 1 otherwise 
  54         if [ -f "$arg" ]; then 
  55             fileRollCall
["$arg"]="true"; 
  56             if ! [ "$returnState" = "false" ]; then returnState
="true"; fi; 
  57         elif [ -z "$arg" ]; then 
  58             fileRollCall
["(no name)"]="false"; returnState
="false"; 
  60             fileRollCall
["$arg"]="false"; returnState
="false"; 
  64     #===Determine function return code=== 
  65     if [ "$returnState" = "true" ]; then 
  70 } # Check that file exists 
  72     # Desc: If arg is a dir path, save result in assoc array 'dirRollCall' 
  73     # Usage: checkdir arg1 arg2 arg3 ... 
  75     # Input: global assoc. array 'dirRollCall' 
  76     # Output: adds/updates key(value) to global assoc array 'dirRollCall'; 
  77     # Output: returns 0 if all args are dirs; 1 otherwise 
  83         if [ -z "$arg" ]; then 
  84             dirRollCall
["(Unspecified Dirname(s))"]="false"; returnState
="false"; 
  85         elif [ -d "$arg" ]; then 
  86             dirRollCall
["$arg"]="true"; 
  87             if ! [ "$returnState" = "false" ]; then returnState
="true"; fi 
  89             dirRollCall
["$arg"]="false"; returnState
="false"; 
  93     #===Determine function return code=== 
  94     if [ "$returnState" = "true" ]; then 
  99 } # Check that dir exists 
 101     # Desc: Displays missing apps, files, and dirs 
 102     # Usage: displayMissing 
 104     # Input: associative arrays: appRollCall, fileRollCall, dirRollCall 
 105     # Output: stderr: messages indicating missing apps, file, or dirs 
 106     # Output: returns exit code 0 if nothing missing; 1 otherwise 
 107     # Depends: bash 5, checkAppFileDir() 
 108     local missingApps value appMissing missingFiles fileMissing
 
 109     local missingDirs dirMissing
 
 111     #==BEGIN Display errors== 
 112     #===BEGIN Display Missing Apps=== 
 113     missingApps
="Missing apps  :"; 
 114     #for key in "${!appRollCall[@]}"; do echo "DEBUG:$key => ${appRollCall[$key]}"; done 
 115     for key 
in "${!appRollCall[@]}"; do 
 116         value
="${appRollCall[$key]}"; 
 117         if [ "$value" = "false" ]; then 
 118             #echo "DEBUG:Missing apps: $key => $value"; 
 119             missingApps
="$missingApps""$key "; 
 123     if [ "$appMissing" = "true" ]; then  # Only indicate if an app is missing. 
 124         echo "$missingApps" 1>&2; 
 127     #===END Display Missing Apps=== 
 129     #===BEGIN Display Missing Files=== 
 130     missingFiles
="Missing files:"; 
 131     #for key in "${!fileRollCall[@]}"; do echo "DEBUG:$key => ${fileRollCall[$key]}"; done 
 132     for key 
in "${!fileRollCall[@]}"; do 
 133         value
="${fileRollCall[$key]}"; 
 134         if [ "$value" = "false" ]; then 
 135             #echo "DEBUG:Missing files: $key => $value"; 
 136             missingFiles
="$missingFiles""$key "; 
 140     if [ "$fileMissing" = "true" ]; then  # Only indicate if an app is missing. 
 141         echo "$missingFiles" 1>&2; 
 144     #===END Display Missing Files=== 
 146     #===BEGIN Display Missing Directories=== 
 147     missingDirs
="Missing dirs:"; 
 148     #for key in "${!dirRollCall[@]}"; do echo "DEBUG:$key => ${dirRollCall[$key]}"; done 
 149     for key 
in "${!dirRollCall[@]}"; do 
 150         value
="${dirRollCall[$key]}"; 
 151         if [ "$value" = "false" ]; then 
 152             #echo "DEBUG:Missing dirs: $key => $value"; 
 153             missingDirs
="$missingDirs""$key "; 
 157     if [ "$dirMissing" = "true" ]; then  # Only indicate if an dir is missing. 
 158         echo "$missingDirs" 1>&2; 
 161     #===END Display Missing Directories=== 
 163     #==END Display errors== 
 164     #==BEGIN Determine function return code=== 
 165     if [ "$appMissing" == "true" ] || 
[ "$fileMissing" == "true" ] || 
[ "$dirMissing" == "true" ]; then 
 170     #==END Determine function return code=== 
 171 } # Display missing apps, files, dirs 
 173     # input: arg1: file path 
 177     if gpg 
--verify "$path_in" 1>&2 2>/dev
/random
; then 
 178         printf "STATUS:Good sig for:%s\n" "$path_in"; 
 180         printf "STATUS:Bad sig for :%s\n" "$path_in"; 
 182 }; # verfiies one gpg file 
 185     ## Note: Assume a single arg that is a dir 
 186     if [[ ! $# -eq 1 ]]; then die 
"FATAL:Incorrect number of args (must be 1):$#"; fi; 
 187     if [[ ! -d "$1" ]]; then die 
"FATAL:Not a dir:$1"; fi; 
 190     if ! checkapp 
find gpg parallel
; then displayMissing
; printf "FATAL:Missing apps."; exit 1; fi; 
 192     # Export bash functions (for GNU parallel) 
 193     export -f yell die must verify_file
; 
 196     list_paths
="$( find "$1" -maxdepth "$find_depth" -type f -iregex "$find_pat_regex" )"; 
 199     echo "$list_paths" | parallel 
--group verify_file 
'{}'; 
 206 #    find "$1" -maxdepth "$find_depth" -type f -iregex "find_pat_regex" | parallel if gpg --verify '{}' 2>/dev/random \; then echo "STATUS:Good sig:" '{}' \; else echo "STATUS:Bad sig :" '{}' \; fi\;