294 lines
7.7 KiB
Bash
Executable File
294 lines
7.7 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
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 () {
|
|
while getopts "$arg_options" opt; do
|
|
case "$opt" in
|
|
h)
|
|
flag_help=1
|
|
arg_log=0
|
|
;;
|
|
v)
|
|
flag_version=1
|
|
arg_log=0
|
|
;;
|
|
d)
|
|
flag_debug=1
|
|
arg_log=0
|
|
;;
|
|
c)
|
|
flag_nocolor=1
|
|
;;
|
|
s)
|
|
arg_ship="$OPTARG"
|
|
;;
|
|
z)
|
|
flag_shortlist=1
|
|
;;
|
|
f)
|
|
arg_log=0
|
|
flag_file=1
|
|
flag_nocolor=1
|
|
arg_file="$OPTARG"
|
|
;;
|
|
t)
|
|
flag_title=1
|
|
arg_title="$OPTARG"
|
|
;;
|
|
*)
|
|
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 " -c No-Color 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"
|
|
}
|
|
|
|
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
|
|
if [ -z "${u##*\#*}" ] ;then
|
|
printf " ${RED}Warning!${RESET} Message title [%s] contains illegal character \"#\". Skipping.\\n" "$(basename "$u" | sed 's/\.[^.]*$//')"
|
|
else
|
|
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
|
|
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
|
|
}
|
|
|
|
contains() {
|
|
string="$1"
|
|
substring="$2"
|
|
if test "${string#*$substring}" != "$string"
|
|
then
|
|
return 0 # $substring is in $string
|
|
else
|
|
return 1 # $substring is not in $string
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
|
|
run_user=$(id -un)
|
|
if [ "$run_user" = "root" ] || [ "$run_user" = "publish" ]; then
|
|
# if running as publish, check who sudoed and create ship for that user
|
|
user="$SUDO_USER"
|
|
else
|
|
user="$run_user"
|
|
fi
|
|
|
|
version="0.1.1"
|
|
user="$SUDO_USER"
|
|
ships=$(find /var/gopher -maxdepth 1 -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
|
|
flag_file=0
|
|
flag_title=0
|
|
flag_nocolor=0
|
|
|
|
arg_options="hvdct:f:s:z"
|
|
arg_log=1
|
|
arg_ship=""
|
|
arg_file=""
|
|
arg_title=""
|
|
|
|
parse_input "$@"
|
|
|
|
if [ $flag_nocolor -gt 0 ]; then
|
|
YELLOW=""
|
|
GREEN=""
|
|
RED=""
|
|
RESET=""
|
|
else
|
|
YELLOW="$(tput setaf 12)"
|
|
GREEN="$(tput setaf 10)"
|
|
RED="$(tput setaf 9)"
|
|
RESET="$(tput sgr0)"
|
|
fi
|
|
|
|
# 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
|
|
|
|
# handle -f switch
|
|
if [ $flag_file -gt 0 ]; then
|
|
if [ -r "$arg_file" ]; then
|
|
owner=$(stat -c %U "$arg_file")
|
|
if [ "$user" = "$owner" ]; then
|
|
# if file exists and user owns it
|
|
realfile=$(readlink -f "$arg_file")
|
|
for ship in $ships
|
|
do
|
|
if contains "$realfile" "/var/gopher/${ship}"; then
|
|
if [ "$(wc -L < "$realfile")" -lt 81 ]; then
|
|
# looking for -t titles only for now
|
|
if [ $flag_title -gt 0 ]; then
|
|
if printf "%s" "$arg_title" | grep -Pq "^[\\x20-\\x7E]*$"; then
|
|
gopherfile="$(printf "%s" "$realfile" | sed 's|/var/gopher||')"
|
|
printf "0%s - %s\\t%s\\n" "$ship" "$arg_title" "$gopherfile" | cat - /var/gopher/listing.gophermap > "$tmp" && cat "$tmp" > /var/gopher/listing.gophermap && rm "$tmp"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
##############################################################################
|
|
##############################################################################
|
|
##############################################################################
|
|
|
|
run_user=$(id -un)
|
|
if [ "$run_user" = "root" ] || [ "$run_user" = "publish" ]; then
|
|
main "$@"
|
|
else
|
|
exec sudo -u publish "$0" "$@"
|
|
fi
|