290 lines
7.3 KiB
Bash
Executable File
290 lines
7.3 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
YELLOW="$(tput setaf 11)"
|
|
GREEN="$(tput setaf 10)"
|
|
RED="$(tput setaf 9)"
|
|
RESET="$(tput sgr0)"
|
|
|
|
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"
|
|
}
|
|
|
|
yesno () {
|
|
old_stty_cfg=$(stty -g)
|
|
stty raw -echo
|
|
yn=$(while ! head -c 1 | grep -i '[ny]'; do true; done)
|
|
stty "$old_stty_cfg"
|
|
case $yn in
|
|
y ) result=0 ;;
|
|
* ) result=1 ;;
|
|
esac
|
|
return $result
|
|
}
|
|
|
|
check_log () {
|
|
ship="$*"
|
|
printf ">> %s" "${YELLOW}${ship}${RESET}"
|
|
# 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 new messages.\\n"
|
|
else
|
|
printf "\\n" # break to new line for each message query
|
|
# check each unpublished message for sending
|
|
IFS='
|
|
'
|
|
for u in $uniq
|
|
do
|
|
printf " Send [%s%s%s]? " "${YELLOW}" "$(basename "$u" | sed 's/\.[^.]*$//')" "${RESET}"
|
|
if yesno; then
|
|
# prompt for title and prepare output
|
|
printf ".. %sYES%s.\\n" "${GREEN}" "${RESET}"
|
|
# check for UTF compatability or fail
|
|
if iconv -f UTF-8 "/var/gopher${u}" > /dev/null 2> /dev/null; then
|
|
if [ "$(wc -L < "/var/gopher${u}")" -gt 80 ]; then
|
|
printf " ${RED}Warning!${RESET} Message [%s] exceeds 80 columns.\\n" "$(basename "$u" | sed 's/\.[^.]*$//')"
|
|
fi
|
|
get_title
|
|
else
|
|
printf " Message [%s] is not encoded in UTF-8. %sABORT%s\\n" "$(basename "$u" | sed 's/\.[^.]*$//')" "${RED}" "${RESET}"
|
|
fi
|
|
else
|
|
printf ".. %sNO%s.\\n" "${RED}" "${RESET}"
|
|
fi
|
|
done
|
|
unset IFS
|
|
fi
|
|
}
|
|
|
|
get_title () {
|
|
printf " Title for [%s%s%s] (null exits): " "${YELLOW}" "$(basename "$u" | sed 's/\.[^.]*$//')" "${RESET}"
|
|
read -r title
|
|
if [ -z "$title" ]; then
|
|
printf " .. No title. %sABORT%s.\\n" "${RED}" "${RESET}"
|
|
return
|
|
else
|
|
title=$(printf "%s" "$title" | cut -c -60)
|
|
printf " .. Confirm title [%s%s%s]? " "${YELLOW}" "$title" "${RESET}"
|
|
if yesno; then
|
|
printf ".. %sYES%s.\\n" "${GREEN}" "${RESET}"
|
|
if printf "%s" "$title" | grep -Pq "^[\\x20-\\x7E]*$"; 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 " .. [%s] .. %sSENT%s.\\n" "$title" "${GREEN}" "${RESET}"
|
|
else
|
|
printf " .. Titles must be ASCII characters. %sTry Again%s.\\n" "${RED}" "${RESET}"
|
|
get_title
|
|
fi
|
|
else
|
|
printf ".. %sNO%s.\\n" "${RED}" "${RESET}"
|
|
get_title
|
|
fi
|
|
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() {
|
|
version="0.1.1"
|
|
user="$SUDO_USER"
|
|
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=""
|
|
|
|
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 "%sINITIALIZING QEC%s .. %sGOOD%s\\n" "${YELLOW}" "${RESET}" "${GREEN}" "${RESET}"
|
|
printf "Ready to transmit for [%s]\\n" "${GREEN}${user}${RESET}"
|
|
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 [ -n "$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
|
|
}
|
|
|
|
##############################################################################
|
|
##############################################################################
|
|
##############################################################################
|
|
|
|
run_user=$(id -un)
|
|
if [ "$run_user" = "root" ] || [ "$run_user" = "publish" ]; then
|
|
main "$@"
|
|
else
|
|
exec sudo -u publish "$0" "$@"
|
|
fi
|