cosmic/bin/log

263 lines
6.1 KiB
Bash
Executable File

#!/bin/sh
# TODO: better isolate listings.gophermap from accidental clobbering
die () {
msg="$1"
code="$2"
# exit code defaults to 1
if printf "%s" "$code" | grep -q '^[0-9]+$'; then
code=1
fi
# output message to stdout or stderr based on code
if [ -n "$msg" ]; then
if [ "$code" -eq 0 ]; then
printf "%s\\n" "$msg"
else
printf "%s\\n" "$msg" >&2
fi
fi
exit "$code"
}
finish () {
rm -f "$tmp"
}
trap finish EXIT
parse_input () {
if ! parsed=$(getopt "$arg_options" "$@"); then
die "Invalid input" 2
fi
eval set -- "$parsed"
while true; do
case "$1" in
-h)
flag_help=1
arg_log=0
shift
;;
-v)
flag_version=1
arg_log=0
shift
;;
-d)
flag_debug=1
arg_log=0
shift
;;
-s)
shift
arg_ship="$1"
shift
;;
-z)
flag_shortlist=1
shift
;;
-n)
arg_log=0
shift
arg_new="$1"
shift
;;
--)
shift
break
;;
*)
die "Internal error: $1" 3
;;
esac
done
}
show_help () {
printf "%s [-hvd] [-s shipname]\\n\\n" "$(basename "$0")"
printf " -h Show this help\\n"
printf " -v Show current version info\\n"
printf " -d Debug mode\\n"
printf " -s [shipname] Only log messages for ship named\\n"
printf " -n [filename] Create new message with filename\\n"
printf " (Users with multiple ships must use -s)\\n"
printf "\\n"
printf "Passing no options will enter interactive mode.\\n\\n"
printf "\\n"
}
read_key () {
_key=
if [ -t 0 ]; then
if [ -z "$_stty" ]; then
_stty=$(stty -g)
fi
stty -echo -icanon min 1
_key=$(dd bs=1 count=1 2>/dev/null)
stty "$_stty"
fi
}
yesno () {
read_key
case $_key in
y ) result=0 ;;
* ) result=1 ;;
esac
return $result
}
check_log () {
ship="$*"
printf ">> %s" "${ship}"
# look at log entries in gophermap
# compare against files in ship directory
# store list of unpublished logs
logs=$(grep "^0${ship}" "/var/gopher/listing.gophermap" | awk -F'\t' '{print $2}')
files=$(find "/var/gopher/$ship" -regex ".*\\.txt$" -not -path '*/\.*' -type f | sed 's|/var/gopher||')
uniq=$(printf "%s\\n%s" "$logs" "$files" | sort | uniq -u)
if [ -z "$uniq" ]; then
printf " .... No messages.\\n"
else
# check each unpublished message for sending
IFS='
'
for u in $uniq
do
printf "\\n Send message %s? " "$(basename "$u" | sed 's/\.[^.]*$//')"
if yesno; then
# prompt for title and prepare output
printf "\\n Title for message %s? " "$(basename "$u" | sed 's/\.[^.]*$//')"
read -r title
if [ ! -z "$title" ]; then
printf "0%s - %s\\t%s\\n" "$ship" "$title" "$u" | cat - /var/gopher/listing.gophermap > "$tmp" && cat "$tmp" > /var/gopher/listing.gophermap && rm "$tmp"
printf "\\n %s - %s .... Sent.\\n" "$(basename "$u" | sed 's/\.[^.]*$//')" "$title"
else
printf " %s .... No title, abort.\\n" "$(basename "$u" | sed 's/\.[^.]*$//')"
fi
else
printf "\\n %s .... Skipped.\\n" "$(basename "$u" | sed 's/\.[^.]*$//')"
fi
done
unset IFS
fi
}
new_message () {
ship="$1"
post_file="/var/gopher/${ship}/${2}"
template_file="/var/gopher/${ship}/.template"
temp_post=$(mktemp -t "$(basename "$0").post.XXXXXXX") || die "Failed to create temporary file" 1
if [ -f "$post_file" ]; then
cp "$post_file" "$temp_post"
elif [ -f "$template_file" ]; then
cp "$template_file" "$temp_post"
fi
temp_post_time=$(stat -c %Y "$temp_post")
${EDITOR:-nano} "$temp_post"
temp_post_time_check=$(stat -c %Y "$temp_post")
if [ "$temp_post_time" -ne "$temp_post_time_check" ] ; then
printf "Drafted message %s (%s)\\n" "$2" "$1"
touch "${post_file}"
cat "${temp_post}" > "${post_file}"
rm "${temp_post}"
else
printf "Aborted message.\\n"
rm "${temp_post}"
fi
}
main() {
parse_input "$@"
# debug
if [ $flag_debug -gt 0 ]; then
set -x
fi
# shortlist for bash completion
if [ $flag_shortlist -gt 0 ]; then
out="$ships"
die "${out}" 0
fi
# version
if [ $flag_version -gt 0 ]; then
printf "%s\\n" "$version"
fi
# print help
if [ $flag_help -gt 0 ]; then
show_help
fi
# standard log if no params
if [ $arg_log -gt 0 ]; then
printf "INITIALIZING QEC...\\n"
printf "Ready to transmit for [%s]\\n" "${user}"
if [ "$numships" -eq 0 ]; then
printf "No registered ships found in system.\\n"
elif [ "$numships" -eq 1 ]; then
if [ -z "$arg_ship" ] || [ "$ships" = "$arg_ship" ]; then
check_log "$ships"
fi
else
IFS='
'
for f in $ships
do
if [ -z "$arg_ship" ] || [ "$f" = "$arg_ship" ]; then
check_log "$(basename "$f")"
fi
done
unset IFS
fi
fi
# new message
if [ ! -z "$arg_new" ]; then
if [ "$numships" -eq 0 ]; then
printf "No registered ships found in system.\\n"
elif [ "$numships" -eq 1 ]; then
if [ -z "$arg_ship" ] || [ "$ships" = "$arg_ship" ]; then
new_message "$ships" "$arg_new"
fi
else
IFS='
'
for f in $ships
do
if [ "$f" = "$arg_ship" ]; then
new_message "$arg_ship" "$arg_new"
fi
done
unset IFS
fi
fi
}
##############################################################################
##############################################################################
##############################################################################
version="0.1.0"
user=$(whoami)
ships=$(find /var/gopher -user "$user" -type d -exec basename {} \;)
numships=$(echo "${ships}" | wc -l)
tmp=$(mktemp -t "$(basename "$0").tmp.XXXXXXX") || die "Failed to create temporary file" 1
flag_help=0
flag_version=0
flag_debug=0
flag_shortlist=0
arg_options="hvds:zn:"
arg_log=1
arg_ship=""
arg_new=""
main "$@"