|
|
@ -25,18 +25,115 @@ DARKPINK="${ANSI_ESC}0;35m" |
|
|
|
DARKCYAN="${ANSI_ESC}0;36m" |
|
|
|
DARKWHITE="${ANSI_ESC}0;37m" |
|
|
|
|
|
|
|
read-0() { |
|
|
|
local eof= IFS='' |
|
|
|
while [ "$1" ]; do |
|
|
|
read -r -d '' -- "$1" || eof=1 |
|
|
|
shift |
|
|
|
done |
|
|
|
[ -z "$eof" ] |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
col:normalize:size() { |
|
|
|
local alignment="$1" colors="$2" |
|
|
|
|
|
|
|
|
|
|
|
# Encode the associative array into a string for awk |
|
|
|
local col_colors_string="" |
|
|
|
for key in "${!col_colors[@]}"; do |
|
|
|
col_colors_string+="${key}=${col_colors[$key]} " |
|
|
|
done |
|
|
|
|
|
|
|
# Pass the string to awk |
|
|
|
awk -v alignment="$alignment" -v colors="$colors" -v colorStr="$col_colors_string" -v normal="$NORMAL" ' |
|
|
|
BEGIN { |
|
|
|
# Split the color string into key-value pairs |
|
|
|
n = split(colorStr, pairs); |
|
|
|
for (i = 1; i <= n; i++) { |
|
|
|
split(pairs[i], kv, "="); |
|
|
|
col_colors[kv[1]] = kv[2]; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
{ |
|
|
|
# Store the entire line in the lines array |
|
|
|
lines[NR] = $0; |
|
|
|
|
|
|
|
# Split the line into fields and update max lengths |
|
|
|
split($0, fields); |
|
|
|
for (i = 1; i <= length(fields); i++) { |
|
|
|
if (length(fields[i]) > max[i]) { |
|
|
|
max[i] = length(fields[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
END { |
|
|
|
# Print lines with fields padded to max, apply color |
|
|
|
for (i = 1; i <= NR; i++) { |
|
|
|
split(lines[i], fields); |
|
|
|
line = ""; |
|
|
|
for (j = 1; j <= length(fields); j++) { |
|
|
|
# Determine alignment |
|
|
|
align = substr(alignment, j, 1) == "+" ? "+" : "-"; |
|
|
|
color_code = substr(colors, j, 1); |
|
|
|
|
|
|
|
color_prefix = (color_code != "-" && color_code in col_colors) ? col_colors[color_code] : ""; |
|
|
|
color_suffix = (color_prefix != "") ? normal : ""; |
|
|
|
|
|
|
|
# Construct line with alignment and color |
|
|
|
line = line color_prefix sprintf("%" align max[j] "s ", fields[j]) color_suffix; |
|
|
|
} |
|
|
|
print line; |
|
|
|
} |
|
|
|
}' |
|
|
|
} |
|
|
|
|
|
|
|
declare -A col_colors=( |
|
|
|
[s]=${DARKGRAY} ## s for 'slate' (actually gray) |
|
|
|
[r]=${DARKRED} |
|
|
|
[g]=${DARKGREEN} |
|
|
|
[y]=${DARKYELLOW} |
|
|
|
[b]=${DARKBLUE} |
|
|
|
[p]=${DARKPINK} |
|
|
|
[c]=${DARKCYAN} |
|
|
|
[w]=${DARKWHITE} |
|
|
|
|
|
|
|
[S]=${GRAY} |
|
|
|
[R]=${RED} |
|
|
|
[G]=${GREEN} |
|
|
|
[Y]=${YELLOW} |
|
|
|
[B]=${BLUE} |
|
|
|
[P]=${PINK} |
|
|
|
[C]=${CYAN} |
|
|
|
[W]=${WHITE} |
|
|
|
) |
|
|
|
|
|
|
|
ssh-key-ls() { |
|
|
|
local label="$1" f content |
|
|
|
for f in "${RSYNC_KEY_PATH}"/backup/"$label"/*.pub; do |
|
|
|
shift |
|
|
|
while read-0 f; do |
|
|
|
[ -e "$f" ] || continue |
|
|
|
ident=${f##*/} |
|
|
|
if [ "$f" != "${f%.disabled}" ]; then |
|
|
|
enabled="${RED}x" |
|
|
|
ident=${ident%.disabled} |
|
|
|
else |
|
|
|
enabled="${GREEN}✓" |
|
|
|
fi |
|
|
|
ident=${ident%.pub} |
|
|
|
content=$(cat "$f") |
|
|
|
content=$(cat "$f") || return 1 |
|
|
|
key=${content#* } |
|
|
|
key=${key% *} |
|
|
|
printf "${DARKGRAY}..${NORMAL}%24s ${DARKCYAN}%s${NORMAL}\n" "${key: -24}" "$ident" |
|
|
|
done |
|
|
|
commentary=${content##* } |
|
|
|
type=${commentary%%@*} |
|
|
|
# printf "${DARKGRAY}..${NORMAL}%12s ${DARKPINK}%-7s${NORMAL} ${DARKCYAN}%s${NORMAL}\n" \ |
|
|
|
# "${key: -12}" "${type}" "$ident" |
|
|
|
printf "%s %s %s %s\n" "…${key: -12}" "$type" "$enabled" "$ident" |
|
|
|
done < <(find "${RSYNC_KEY_PATH}"/backup/"$label" \ |
|
|
|
-maxdepth 1 -mindepth 1 \ |
|
|
|
\( -name \*.pub -or -name \*.pub.disabled \) -print0 | sort -z |
|
|
|
) | col:normalize:size "----" "ysGc" |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -45,10 +142,47 @@ ssh-key-rm() { |
|
|
|
|
|
|
|
delete="${RSYNC_KEY_PATH}/backup/$label/$ident.pub" |
|
|
|
if ! [ -e "$delete" ]; then |
|
|
|
echo "Error: key '$ident' not found." >&2 |
|
|
|
return 1 |
|
|
|
if ! [ -e "${delete}.disabled" ]; then |
|
|
|
echo "Error: key '$ident' not found." >&2 |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
rm "${delete}.disabled" |
|
|
|
return 0 |
|
|
|
fi |
|
|
|
rm "$delete" |
|
|
|
/usr/local/sbin/ssh-update-keys |
|
|
|
} |
|
|
|
|
|
|
|
ssh-key-disable() { |
|
|
|
local label="$1" ident="$2" disable |
|
|
|
|
|
|
|
disable="${RSYNC_KEY_PATH}/backup/$label/$ident.pub" |
|
|
|
if ! [ -e "$disable" ]; then |
|
|
|
if ! [ -e "${disable}.disabled" ]; then |
|
|
|
echo "Error: key '$ident' not found." >&2 |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
echo "Already disabled." >&2 |
|
|
|
return 0 |
|
|
|
fi |
|
|
|
mv "${disable}" "${disable}.disabled" |
|
|
|
|
|
|
|
/usr/local/sbin/ssh-update-keys |
|
|
|
} |
|
|
|
|
|
|
|
ssh-key-enable() { |
|
|
|
local label="$1" ident="$2" enable |
|
|
|
|
|
|
|
enable="${RSYNC_KEY_PATH}/backup/$label/$ident.pub.disabled" |
|
|
|
if ! [ -e "$enable" ]; then |
|
|
|
if ! [ -e "${enable%.disabled}" ]; then |
|
|
|
echo "Error: key '$ident' not found." >&2 |
|
|
|
return 1 |
|
|
|
fi |
|
|
|
echo "Already enabled." >&2 |
|
|
|
return 0 |
|
|
|
fi |
|
|
|
mv "${enable}" "${enable%.disabled}" |
|
|
|
|
|
|
|
/usr/local/sbin/ssh-update-keys |
|
|
|
} |
|
|
@ -141,6 +275,11 @@ case "$1" in |
|
|
|
shift |
|
|
|
ssh-key-ls "$@" |
|
|
|
;; |
|
|
|
"disable"|"enable") |
|
|
|
arg="$1" |
|
|
|
shift |
|
|
|
ssh-key-"$arg" "$@" |
|
|
|
;; |
|
|
|
"get-type") |
|
|
|
shift |
|
|
|
ssh-key-get-type "$@" |
|
|
|