big tidy up and shellcheck fixes

This commit is contained in:
Ben Harris 2020-06-10 22:21:08 -04:00
parent f94ce2dfe3
commit e92ace542d
1 changed files with 181 additions and 177 deletions

242
tilde
View File

@ -20,7 +20,7 @@
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
PROGNAME=${0##*/} PROGNAME=${0##*/}
VERSION="0.0.1" VERSION="0.1.0"
# check coreutils and wrap stat for portability # check coreutils and wrap stat for portability
if stat -c"%U" /dev/null >/dev/null 2>/dev/null ; then if stat -c"%U" /dev/null >/dev/null 2>/dev/null ; then
@ -36,90 +36,81 @@ else
fi fi
clean_up() { # Perform pre-exit housekeeping
return
}
error_exit() { error_exit() {
echo -e "${1:-"unknown Error"}" >&2 printf "%s\n" "${1:-"unknown Error"}" >&2
clean_up
exit 1 exit 1
} }
graceful_exit() {
clean_up
exit
}
signal_exit() { # Handle trapped signals signal_exit() { # Handle trapped signals
case $1 in case $1 in
INT) INT)
error_exit "program interrupted by user" ;; error_exit "program interrupted by user"
;;
TERM) TERM)
echo -e "\n$PROGNAME: program terminated" >&2 printf "\n%s: program terminated" "$PROGNAME" >&2
graceful_exit ;; exit
;;
*) *)
error_exit "$PROGNAME: terminating on unknown signal" ;; error_exit "$PROGNAME: terminating on unknown signal"
;;
esac esac
} }
prompt_confirm() { prompt_confirm() {
while true; do while true; do
read -r -n 1 -p "${1:-continue?} [y/n]: " REPLY read -r -n 1 -p "${1:-continue?} [y/n]: " REPLY
case $REPLY in case $REPLY in
[yY]) echo ; return 0 ;; [yY]) printf "\n" ; return 0 ;;
[nN]) echo ; return 1 ;; [nN]) printf "\n" ; return 1 ;;
*) printf " \033[31m %s \n\033[0m" "invalid input" *) printf " \033[31m %s \n\033[0m" "invalid input" ;;
esac esac
done done
} }
help_message() {
printf "%s version %s\n" "$PROGNAME" "$VERSION"
printf "wrapper for user-submitted scripts\n"
printf "supports submission and admin approval\n"
usage
}
usage() { usage() {
echo -e "\nusage: $PROGNAME [help|list|submit|about|script_name]\n" printf "\nusage: %s [help|list|submit|about|script_name\n\n" "$PROGNAME"
echo " $PROGNAME list - show a list of approved userscripts" printf " list - show a list of approved userscripts\n"
echo " $PROGNAME submit - start the submission flow for your own script" printf " submit - start the submission flow for your own script\n"
[[ $(id -u) == 0 ]] && {
echo " $PROGNAME approve - enter the approval queue" if [[ $(id -u) == 0 ]]; then
echo " $PROGNAME revoke <script_name> - send a script back to the author and remove from /tilde/bin" printf " approve - enter the approval queue\n"
} printf " revoke <script_name> - send a script back to the author and remove from /tilde/bin\n"
echo " $PROGNAME about <script_name> - get the description for script_name" fi
echo " $PROGNAME <script_name> - run script_name with all remaining args are passed to the script"
printf " about <script_name> - get the description for script_name\n"
printf " <script_name> - run script_name with all remaining args are passed to the script\n"
if [[ :$PATH: != *:"/tilde/bin":* ]] ; then if [[ :$PATH: != *:"/tilde/bin":* ]] ; then
echo -e "\nadd /tilde/bin to your PATH to use approved scripts without this wrapper" printf "\nadd /tilde/bin to your PATH to use approved scripts without this wrapper\n"
echo "if you're using bash, run the following to add it quickly" printf "if you're using bash, run the following to add it quickly\n"
echo " echo 'export PATH=\$PATH:/tilde/bin' >> ~/.bashrc && source ~/.bashrc" printf " echo 'export PATH=\$PATH:/tilde/bin' >> ~/.bashrc && source ~/.bashrc\n"
fi fi
} }
help_message() {
cat <<- _EOF_
$PROGNAME ver. $VERSION
wrapper for user-submitted scripts
supports user submission and admin approval
$(usage)
_EOF_
return
}
verify_script_name() { verify_script_name() {
[[ $1 == "" ]] && error_exit "please start over and enter the script name" [[ $1 == "" ]] && \
if [[ $(type "$1" > /dev/null 2>&1) ]]; then error_exit "please start over and enter the script name"
[[ $(type "$1" > /dev/null 2>&1) ]] && \
error_exit "$1 already exists. rename your script and try again." error_exit "$1 already exists. rename your script and try again."
fi
[[ -x /tilde/bin/$1 ]] && error_exit "$1 is already taken. rename your script and try again." [[ -x /tilde/bin/$1 ]] && \
error_exit "$1 is already taken. rename your script and try again."
case $1 in case $1 in
about|description|list|ls|submit|about|help|apropos|submit|approve) about|description|list|ls|submit|about|help|apropos|submit|approve)
error_exit "$1 is a subcommand of tilde. rename your script and try again." ;; error_exit "$1 is a subcommand of tilde. rename your script and try again."
;;
*) *)
return ;; return
;;
esac esac
} }
@ -165,123 +156,136 @@ _EOF_
trap "signal_exit TERM" TERM HUP trap "signal_exit TERM" TERM HUP
trap "signal_exit INT" INT trap "signal_exit INT" INT
# Check for root UID
# Parse command-line # Parse command-line
case $1 in case $1 in
-h | --help | help) -h | --help | help)
help_message; graceful_exit ;; help_message; exit
;;
-v | --version) -v | --version)
echo $VERSION ;; printf "%s" "$VERSION"
;;
-* | --*) -* | --*)
usage usage
error_exit "Unknown option $1" ;; error_exit "Unknown option $1"
;;
list | ls) list | ls)
echo -e "available scripts:\n" printf "available scripts:\n\n"
for scr in /tilde/bin/*; do for scr in /tilde/bin/*; do
if [ -f "$scr" ]; then if [ -f "$scr" ]; then
script_name=$(basename $scr) script_name=$(basename "$scr")
target=$(readlink -f "$scr") target=$(readlink -f "$scr")
echo "$script_name by "$(stat_func $target) printf "%s by %s\n" "$script_name" "$(stat_func "$target")"
cat /tilde/descriptions/$script_name cat "/tilde/descriptions/$script_name"
echo "" printf "\n"
fi fi
done ;; done
;;
about | apropos | description) about | apropos | description)
if [[ -f /tilde/descriptions/$2 ]]; then if [[ -f "/tilde/descriptions/$2" ]]; then
cat /tilde/descriptions/$2 cat "/tilde/descriptions/$2"
else else
echo "$2 not found. try $PROGNAME list to see available user scripts." printf "%s not found. try %s list to see available user scripts.\n" "$2" "$PROGNAME"
fi fi
;; ;;
submit) submit)
echo "hello, $USER! so it's time to submit your script?" printf "hello, %s! so it's time to submit your script?\n" "$USER"
submission_checklist submission_checklist
prompt_confirm "are you ready to continue?" || graceful_exit prompt_confirm "are you ready to continue?" || exit
echo -n "enter the name of your script: " printf "enter the name of your script: "
read script_name read -r script_name
verify_script_name $script_name verify_script_name "$script_name"
if [[ -x $HOME/bin/$script_name ]]; then if [[ -x "$HOME/bin/$script_name" ]]; then
echo "cool, found your script" printf "cool, found your script\n"
[[ -x /tilde/pending-submissions/$USER/$script_name/$script_name ]] && error_exit "you've already submitted $script_name" [[ -x "/tilde/pending-submissions/$USER/$script_name/$script_name" ]] && \
error_exit "you've already submitted $script_name"
else else
error_exit "$script_name not found in ~/bin" error_exit "$script_name not found in ~/bin"
fi fi
echo "enter a description of your script: " printf "enter a description of your script: \n"
read description read -r description
echo -e "\nyour script, along with your description will be sent to the admins for approval" printf "\nyour script, along with your description will be sent to the admins for approval\n"
prompt_confirm "ready to submit?" || graceful_exit prompt_confirm "ready to submit?" || exit
# submit now # submit now
mkdir -p /tilde/pending-submissions/$USER/$script_name mkdir -p "/tilde/pending-submissions/$USER/$script_name"
ln -s $HOME/bin/$script_name /tilde/pending-submissions/$USER/$script_name/$script_name ln -s "$HOME/bin/$script_name" "/tilde/pending-submissions/$USER/$script_name/$script_name"
echo $description > /tilde/pending-submissions/$USER/$script_name/description.txt printf "%s" "$description" > "/tilde/pending-submissions/$USER/$script_name/description.txt"
mail_body $script_name "$description" | sendmail root mail_body "$script_name" "$description" | sendmail root
echo "script submitted. thanks! :)" ;; printf "script submitted. thanks! :)\n"
;;
approve) approve)
[[ $(id -u) != 0 ]] && error_exit "re-run this as sudo to access the approval queue" [[ $(id -u) != 0 ]] && error_exit "re-run this as root to access the approval queue"
echo -e "welcome to the approval queue\n\n" printf "welcome to the approval queue\n\n"
for user in /tilde/pending-submissions/*; do for user in /tilde/pending-submissions/*; do
for scr in $user/*; do for scr in $user/*; do
user=$(basename $user) user=$(basename "$user")
script_name=$(basename $scr) script_name=$(basename "$scr")
[[ -f $scr/approved ]] && continue [[ -f "$scr/approved" ]] && continue
script=$scr/$script_name script="$scr/$script_name"
echo "$script_name by $user"
cat $scr/description.txt if [ -f "$script" ]; then
printf "%s by %s\n" "$script_name" "$user"
cat "$scr/description.txt"
prompt_confirm "approve?" || continue prompt_confirm "approve?" || continue
sudo ln -s $(readlink -f $script) /tilde/bin/$script_name ln -s "$(readlink -f "$script")" "/tilde/bin/$script_name"
sudo cp $scr/description.txt /tilde/descriptions/$script_name cp "$scr/description.txt" "/tilde/descriptions/$script_name"
sudo touch $scr/approved touch "$scr/approved"
sudo chmod 664 /tilde/descriptions/* chmod 664 /tilde/descriptions/*
echo "your submission of $script_name has been approved and is now available at /tilde/bin/$script_name" | sendmail $user printf "your submission of %s has been approved and is now available at /tilde/bin/%s" "$script_name" "$script_name" \
| sendmail "$user"
fi
done done
done done
echo "~~done for now~~" ;; printf "~~done for now~~\n"
;;
revoke) revoke)
[[ $(id -u) != 0 ]] && error_exit "re-run this as sudo to access the revoke menu" [[ $(id -u) != 0 ]] && \
[[ -f /tilde/bin/$2 ]] || error_exit "$2 isn't an approved script" error_exit "re-run this as sudo to access the revoke menu"
[[ -f /tilde/bin/$2 ]] || \
error_exit "$2 isn't an approved script"
prompt_confirm "revoke $2?" prompt_confirm "revoke $2?"
echo -n "please provide a reason: " printf "please provide a reason: "
read reason read -r reason
original_script=$(readlink -f /tilde/bin/$2) original_script=$(readlink -f "/tilde/bin/$2")
author=$(stat_func $original_script) author=$(stat_func "$original_script")
sudo rm /tilde/{bin,descriptions}/$2 rm "/tilde/bin/$2"
sudo rm -rf /tilde/pending-submissions/$author/$2 rm "/tilde/descriptions/$2"
rm -rf "/tilde/pending-submissions/$author/$2"
echo -e "your script $2 has been returned because: $reason\nfeel free to resubmit" | sendmail $author printf "your script %s has been returned because: %s\nfeel free to resubmit\n" "$2" "$reason" \
echo "$2 revoked and returned to author" ;; | sendmail "$author"
printf "%s revoked and returned to author" "$2"
;;
*) *)
if [[ -f /tilde/bin/$1 ]]; then if [[ -x "/tilde/bin/$1" ]]; then
prog=/tilde/bin/$1 prog="/tilde/bin/$1"
shift shift
$prog "$@" exec "$prog" "$@"
graceful_exit
else else
[[ $1 == "" ]] || echo -e "$1 not found. try $PROGNAME list to see what's available\n" [[ $1 == "" ]] || \
help_message; graceful_exit; printf "%s not found. try %s list to see what's available\n" "$1" "$PROGNAME"
fi ;; help_message
exit
fi
;;
esac esac
# Main logic
graceful_exit