#!/bin/bash ## Modified SPACE LAUNCH, with small fix and added verbose sl -t output. ## File is here temporary, until changes are picked up by cmccabe :) ## ## SPACE LAUNCH - A multi-user take on the classic Unix ## steam locomotive (sl) prank. ## Written by cmccabe on the Zaibatsu in 2019. ## ## Questions? Comments? Smart remarks? --> cmccabe@sdf.org ## ## System users should create ~/.vroom files that contain lines within ## the configured limits of length and line numbers. These .vroom files ## will be fused together using space-age technology and launched into ## orbit whenever this script is run. ## -t, -m and -h switches are explained in the help: ## > sl.sh -h ######################################################################### ## CONFIGURATION VARIABLES source /home/nop/spacelaunch_nop/config #source /home/cmccabe/code/space_launch/config ######################################################################### ## VARIABLE INITIALIZATION AND SET-UP STEPS # stty -echo ## TO DO: HOW TO RE-ENABLE THIS FROM ^C TRAP FUNCTION? # OTHERWISE USER CAN'T SEE THEIR CHARS ECHOED # AFTER THEY KILL THIS SCRIPT. USER=$(id -run) # HEIGHT OF TERMINAL WINDOW; USED TO PUSH ROCKET OFF THE SCREEN TRAILING_SPACE=$(tput lines) ALTITIDE=0 OLDIFS=$IFS #~Nop, Backing up IFS for later use... or something... ROCKET_PARTS=$(ls $HOME_DIR/*/.vroom | shuf -n $ROCKET_SIZE) ROCKET_PARTS=(${ROCKET_PARTS[@]}) [ ${#ROCKET_PARTS[@]} -gt $ROCKET_SIZE ] && ROCKET_PARTS=(${ROCKET_PARTS[@]:1:${ROCKET_SIZE}}) # ^^ CHOOSE $ROCKET_SIZE RANDOM FILES FROM AL ~.vroom FILES read -r -d '' HELP_TEXT << EOM ================= SPACE LAUNCH (sl) HELP ================= Space Launch reads everyone's .vroom file and concatenates a random selection of them into an animated rocket. You can create your own .vroom file. Just make sure all of the lines are exactly $VROOM_WIDTH characters long and the file contains no more than $VROOM_HEIGHT_MAX lines. Make sure the file is readable by everyone (e.g. chmod ugo+r ~/.vroom) and that it is located at the top level of your home directory. Space Launch ignores any .vroom files that don't meet the file size requirements. It's not rocket science; so don't get left on the launch pad! Command line options: -t : Reports if your .vroom file passes or fails spec. -m : Prints template .vroom file of size $VROOM_WIDTH x $VROOM_HEIGHT_MAX. You can pipe this template into a .vroom file and modify it. -h : Prints this help message. Duh! ========================================================== EOM ## CTRL-C TRAP - BLOW UP THE ROCKET WHEN ^c CAUGHT: ALTITUDE=1 ## INCREMENTS AS ROCKET GOES UP trap ctrl_c INT function ctrl_c() { # PUSH ROCKET OFF THE SCREEN: i=0 while [ $i -lt $TRAILING_SPACE ]; do echo; i=$(($i+1)) done cat $KABOOM KABOOM_HEIGHT=$(wc -l "$KABOOM" | cut -d" " -f1); if [ "$ALTITUDE" -ge $((TRAILING_SPACE-$KABOOM_HEIGHT)) ] && [ $KABOOM_HEIGHT -lt $TRAILING_SPACE ]; then ALTITUDE=$(($TRAILING_SPACE-$KABOOM_HEIGHT)) elif [ "$ALTITUDE" -le "$KABOOM_HEIGHT" ]; then ALTITUDE=0 fi # PRINT EXTRA LINES TO PLACE KABOOM AT CORRECT HEIGHT i=0 while [ $i -lt $ALTITUDE ]; do echo i=$(($i+1)) done # stty echo ## RE-ENABLE ECHO exit } ############################################################################# #~Nop VALIDATE_VROOM is called by program itself (also via TEST_VROOM) ############################################################################# VALIDATE_VROOM () { local VERBOSE="${2:-0}" if [ -r $1 ]; then declare -i i=0 IFS='' #without setting IFS to '', everything below breaks now :D. while read -r line; do ## lines in file let "i+=1" if [ "${#line}" = "$VROOM_WIDTH" ]; then [ "$VERBOSE" = 1 ] && printf "%02d:%s\tWidth:%d chars. PASS\n" $i $line ${#line}; else [ "$VERBOSE" = 1 ] && printf "%02d:%s\tWidth:%d chars. FAIL\n" $i $line ${#line}; PASS='fail' fi done <$1 IFS=$OLDIFS #Reset IFS to default. if [ "$VERBOSE" = 1 ]; then echo "" echo "==========================================================" fi # CHECK THAT VROOM FILE IS UNDER HEIGHT LIMIT VROOM_HEIGHT=$(($i)) if [ "$VROOM_HEIGHT" -gt "$VROOM_HEIGHT_MAX" ]; then [ "$VERBOSE" = 1 ] && echo "Rocket section height: $VROOM_HEIGHT lines. FAIL"; PASS='fail' else [ "$VERBOSE" = 1 ] && echo "Rocket section height: $VROOM_HEIGHT lines. PASS"; fi else PASS='fail' # KICK IT OUT IF FILE IS UNREADABLE fi } ############################################################################# #TEST_VROOM is called via the sl -t option. ############################################################################# TEST_VROOM () { echo echo "==========================================================" echo "Performing rocket section diagnostics..." echo "Analyzing your .vroom file..." echo TEST_PASS_MSG="PASS! Your .vroom file meets requirements and will be included in future launches." read -r -d '' TEST_FAIL_MSG << EOM FAIL! Your .vroom file does not meet one or more of the following requirements: * Each line in the .vroom file must be exactly $VROOM_WIDTH characters in length. * The .vroom file may contain no more than $VROOM_HEIGHT_MAX lines. ========================================================== EOM PASS='pass' VALIDATE_VROOM "$HOME_DIR/$USER/.vroom" 1 #~Nop, We call VALIDATE_VROOM in verbose mode. echo "" if [[ $PASS = 'pass' ]]; then echo "PASS! Your .vroom file meets requirements and will be" echo "included in future launches."; echo "==========================================================" elif [[ $PASS = 'fail' ]]; then echo "$TEST_FAIL_MSG"; else echo "This message indicates that a bug has occured. Please submit a copy of your .vroom accompanied by pitiless mockery to the developer." fi exit } CREATE_VROOM() { IFS=$OLDIFS #~Nop, just to make sure... not strictly necessary... for i in $(seq 1 $VROOM_HEIGHT_MAX); do for j in $(seq 1 $VROOM_WIDTH); do printf "="; done echo done } ######################################################################### ## 3, 2, 1 LAUCH! MAIN PROGRAM FLOW: [ "$1" = "-h" ] && echo "$HELP_TEXT" && exit [ "$1" = "-t" ] && TEST_VROOM && exit [ "$1" = "-m" ] && CREATE_VROOM && exit # CALCUATE ADDITIONAL PADDING NEEDED RELATIVE TO FLAMES: PADDING_SIZE=0 IFS='' while read -r line; do [ ${#line} -ge $PADDING_SIZE ] && PADDING_SIZE=${#line} done <$FLAMES PADDING_SIZE=$(($PADDING_SIZE-$VROOM_WIDTH)) PADDING_SIZE=$(($PADDING_SIZE/2)) ## TO DO: WHAT IF PAD IS ODD? PADDING=$(printf '%*s' "$PADDING_SIZE" | tr ' ' " ") unset PASS # PRINT THE NOSE CONE while read -r line; do echo "$PADDING$line" sleep $SLEEP_TIME done <$NOSE_CONE # VALIDATE WIDTH AND HEIGHT OF ROCKET PARTS (FROM USERS) for i in ${ROCKET_PARTS[@]}; do PASS='pass' VALIDATE_VROOM $i IFS='' #~Nop, Setting IFS to '' again (reset to default by VALIDATE_VROOM ## PRINT THE ROCKET PARTS (FROM USERS) IF CORRECT SIZE: if [ "$PASS" = 'pass' ]; then while read -r line; do ## lines in file echo "$PADDING$line"; sleep $SLEEP_TIME done <$i fi unset PASS done # PRINT THE FLAMES: while read -r line; do ## lines in file echo "$line"; ALTITUDE=$((ALTITUDE+1)) sleep $SLEEP_TIME done <$FLAMES # PRINT EXTRA LINES TO KEEP ROCKET MOVING UP i=0 while [ $i -lt $TRAILING_SPACE ]; do echo ALTITUDE=$((ALTITUDE+1)) sleep $SLEEP_TIME i=$(($i+1)) done ## stty echo ## RE-ENABLE ECHO SO USERS CAN SEE WHAT THEY TYPE AGAIN exit