From bc1d5fb28841f6050605e93886685b3a02e7787a Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Fri, 2 Jun 2017 22:07:52 +1200 Subject: Use mi5 to make templated shell scripts --- .gitignore | 21 +++++++- Makefile | 77 ++++++++++++++++++++---------- bin/chn.mi5 | 57 ++++++++++++++++++++++ bin/chn.sh | 69 --------------------------- bin/edda.mi5 | 21 ++++++++ bin/edda.sh | 33 ------------- bin/pst.mi5 | 19 ++++++++ bin/pst.sh | 32 ------------- bin/rndl.mi5 | 38 +++++++++++++++ bin/rndl.sh | 50 ------------------- bin/swr.mi5 | 52 ++++++++++++++++++++ bin/swr.sh | 64 ------------------------- bin/tlcs.mi5 | 81 +++++++++++++++++++++++++++++++ bin/tlcs.sh | 93 ------------------------------------ bin/try.mi5 | 65 +++++++++++++++++++++++++ bin/try.sh | 77 ------------------------------ bin/urlc.mi5 | 64 +++++++++++++++++++++++++ bin/urlc.sh | 76 ----------------------------- git/gitconfig.m4.mi5 | 64 ------------------------- git/gitconfig.mi5 | 64 +++++++++++++++++++++++++ gnupg/gpg.conf.m4.mi5 | 52 -------------------- gnupg/gpg.conf.mi5 | 52 ++++++++++++++++++++ include/mktd.mi5 | 15 ++++++ tmux/tmux.conf.m4.mi5 | 130 -------------------------------------------------- tmux/tmux.conf.mi5 | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ 25 files changed, 730 insertions(+), 766 deletions(-) create mode 100644 bin/chn.mi5 delete mode 100644 bin/chn.sh create mode 100644 bin/edda.mi5 delete mode 100644 bin/edda.sh create mode 100644 bin/pst.mi5 delete mode 100644 bin/pst.sh create mode 100644 bin/rndl.mi5 delete mode 100644 bin/rndl.sh create mode 100644 bin/swr.mi5 delete mode 100644 bin/swr.sh create mode 100644 bin/tlcs.mi5 delete mode 100644 bin/tlcs.sh create mode 100644 bin/try.mi5 delete mode 100644 bin/try.sh create mode 100644 bin/urlc.mi5 delete mode 100644 bin/urlc.sh delete mode 100644 git/gitconfig.m4.mi5 create mode 100644 git/gitconfig.mi5 delete mode 100644 gnupg/gpg.conf.m4.mi5 create mode 100644 gnupg/gpg.conf.mi5 create mode 100644 include/mktd.mi5 delete mode 100644 tmux/tmux.conf.m4.mi5 create mode 100644 tmux/tmux.conf.mi5 diff --git a/.gitignore b/.gitignore index 873b60a1..153d2227 100644 --- a/.gitignore +++ b/.gitignore @@ -12,16 +12,20 @@ bin/cf bin/cfr bin/chc bin/chn +bin/chn.sh +bin/chn.m4 bin/clog bin/clrd bin/clwr bin/csmw -bin/dam bin/d2u +bin/dam bin/ddup bin/dmp bin/dub bin/edda +bin/edda.sh +bin/edda.m4 bin/eds bin/exm bin/fgscr @@ -46,13 +50,13 @@ bin/jfc bin/jfcd bin/jfp bin/loc -bin/mi5 bin/max bin/maybe bin/mean bin/med bin/mex bin/mftl +bin/mi5 bin/min bin/mkcp bin/mkmv @@ -73,6 +77,8 @@ bin/plmu bin/pp bin/pph bin/pst +bin/pst.sh +bin/pst.m4 bin/pvi bin/pwg bin/quo @@ -84,6 +90,8 @@ bin/rnda bin/rndf bin/rndi bin/rndl +bin/rndl.sh +bin/rndl.m4 bin/rnds bin/sd2u bin/sec @@ -102,17 +110,25 @@ bin/su2d bin/sue bin/supp bin/swr +bin/swr.sh +bin/swr.m4 bin/td bin/tl bin/tlcs +bin/tlcs.sh +bin/tlcs.m4 bin/tm bin/tot bin/trs bin/try +bin/try.sh +bin/try.m4 bin/u2d bin/umake bin/unf bin/urlc +bin/urlc.sh +bin/urlc.m4 bin/urlh bin/urlmt bin/uts @@ -140,6 +156,7 @@ git/gitconfig git/gitconfig.m4 gnupg/gpg.conf gnupg/gpg.conf.m4 +include/mktd.m4 man/man7/dotfiles.7df tmux/tmux.conf tmux/tmux.conf.m4 diff --git a/Makefile b/Makefile index 11bcf6f0..8f278325 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ lint-xinit .SUFFIXES: -.SUFFIXES: .awk .bash .mi5 .pl .sed .sh +.SUFFIXES: .awk .bash .m4 .mi5 .pl .sed .sh NAME = 'Tom Ryder' EMAIL = tom@sanctum.geek.nz @@ -217,15 +217,67 @@ clean distclean: rm -f -- \ $(BINS) \ $(GAMES) \ + bin/chn.sh \ + bin/chn.m4 \ + bin/edda.sh \ + bin/edda.m4 \ + bin/pst.sh \ + bin/pst.m4 \ + bin/rndl.sh \ + bin/rndl.m4 \ + bin/swr.sh \ + bin/swr.m4 \ + bin/tlcs.sh \ + bin/tlcs.m4 \ + bin/try.sh \ + bin/try.m4 \ + bin/urlc.sh \ + bin/urlc.m4 \ git/gitconfig \ git/gitconfig.m4 \ gnupg/gpg.conf \ gnupg/gpg.conf.m4 \ + include/mktd.m4 \ man/man8/dotfiles.7df \ tmux/tmux.conf \ tmux/tmux.conf.m4 \ urxvt/ext/select +.awk: + sh bin/shb.sh awk -f < $< > $@ + chmod +x ./$@ + +.bash: + sh bin/shb.sh bash < $< > $@ + chmod +x ./$@ + +.pl: + sh bin/shb.sh perl < $< > $@ + chmod +x ./$@ + +.sed: + sh bin/shb.sh sed -f < $< > $@ + chmod +x ./$@ + +.sh: + sh bin/shb.sh sh < $< > $@ + chmod +x ./$@ + +.mi5.m4: + awk -f bin/mi5.awk < $< > $@ + +.m4.sh: + m4 < $< > $@ + +bin/chn.sh: include/mktd.m4 +bin/edda.sh: include/mktd.m4 +bin/pst.sh: include/mktd.m4 +bin/rndl.sh: include/mktd.m4 +bin/swr.sh: include/mktd.m4 +bin/tlcs.sh: include/mktd.m4 +bin/try.sh: include/mktd.m4 +bin/urlc.sh: include/mktd.m4 + git/gitconfig: git/gitconfig.m4 m4 \ -D DF_NAME=$(NAME) \ @@ -253,29 +305,6 @@ tmux/tmux.conf: tmux/tmux.conf.m4 m4 -D DF_TMUX_BG=$(TMUX_BG) -D DF_TMUX_FG=$(TMUX_FG) \ tmux/tmux.conf.m4 > $@ -.awk: - sh bin/shb.sh awk -f < $< > $@ - chmod +x ./$@ - -.bash: - sh bin/shb.sh bash < $< > $@ - chmod +x ./$@ - -.pl: - sh bin/shb.sh perl < $< > $@ - chmod +x ./$@ - -.sed: - sh bin/shb.sh sed -f < $< > $@ - chmod +x ./$@ - -.sh: - sh bin/shb.sh sh < $< > $@ - chmod +x ./$@ - -.mi5: - awk -f bin/mi5.awk < $< > $@ - install: install-bin \ install-curl \ install-ex \ diff --git a/bin/chn.mi5 b/bin/chn.mi5 new file mode 100644 index 00000000..dfc1000c --- /dev/null +++ b/bin/chn.mi5 @@ -0,0 +1,57 @@ +# Repeat a command to filter input several times +self=chn + +# Check arguments. +if [ "$#" -lt 2 ] ; then + printf >&2 '%s: Need a count and a program name\n' "$self" + exit 2 +fi + +# Shift off the repetition count. +c=$1 +shift + +# Check the repetition count looks sane. Zero is fine! +if [ "$c" -lt 0 ] ; then + printf >&2 '%s: Nonsensical negative count\n' "$self" + exit 2 +fi + +# If the count is zero, just run the input straight through! +if [ "$c" -eq 0 ] ; then + cat + exit +fi + +<% +include(`include/mktd.m4') +%> + +# Define and create input and output files +if=$td/if of=$td/of +touch -- "$if" "$of" + +# Iterate through the count +while [ "${n=1}" -le "$c" ] ; do + + # Start a subshell so we can deal with FDs cleanly + ( + # If this isn't the first iteration, our input comes from $if + [ "$n" -eq 1 ] || + exec <"$if" + + # If this isn't the last iteration, our output goes to $of + [ "$n" -eq "$c" ] || + exec >"$of" + + # Run the command with the descriptors above; if the command fails, the + # subshell will exit, which will in turn exit the program + "$@" + ) || exit + + # Copy the output file over the input one + cp -- "$of" "$if" + + # Increment the counter for the next while loop run + n=$((n+1)) +done diff --git a/bin/chn.sh b/bin/chn.sh deleted file mode 100644 index 9103dd07..00000000 --- a/bin/chn.sh +++ /dev/null @@ -1,69 +0,0 @@ -# Repeat a command to filter input several times -self=chn - -# Check arguments. -if [ "$#" -lt 2 ] ; then - printf >&2 '%s: Need a count and a program name\n' "$self" - exit 2 -fi - -# Shift off the repetition count. -c=$1 -shift - -# Check the repetition count looks sane. Zero is fine! -if [ "$c" -lt 0 ] ; then - printf >&2 '%s: Nonsensical negative count\n' "$self" - exit 2 -fi - -# If the count is zero, just run the input straight through! -if [ "$c" -eq 0 ] ; then - cat - exit -fi - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Define and create input and output files -if=$td/if of=$td/of -touch -- "$if" "$of" - -# Iterate through the count -while [ "${n=1}" -le "$c" ] ; do - - # Start a subshell so we can deal with FDs cleanly - ( - # If this isn't the first iteration, our input comes from $if - [ "$n" -eq 1 ] || - exec <"$if" - - # If this isn't the last iteration, our output goes to $of - [ "$n" -eq "$c" ] || - exec >"$of" - - # Run the command with the descriptors above; if the command fails, the - # subshell will exit, which will in turn exit the program - "$@" - ) || exit - - # Copy the output file over the input one - cp -- "$of" "$if" - - # Increment the counter for the next while loop run - n=$((n+1)) -done diff --git a/bin/edda.mi5 b/bin/edda.mi5 new file mode 100644 index 00000000..aaf974cf --- /dev/null +++ b/bin/edda.mi5 @@ -0,0 +1,21 @@ +# Run ed(1) over multiple files, duplicating stdin. +self=edda + +# Need at least one file +if [ "$#" -eq 0 ] ; then + printf >&2 'edda: Need at least one file\n' + exit 2 +fi + +<% +include(`include/mktd.m4') +%> + +# Duplicate stdin into a file +script=$td/script +cat >"$script" || exit + +# Run ed(1) over each file with the stdin given +for file ; do + ed -- "$file" <"$script" +done diff --git a/bin/edda.sh b/bin/edda.sh deleted file mode 100644 index b1d7b27a..00000000 --- a/bin/edda.sh +++ /dev/null @@ -1,33 +0,0 @@ -# Run ed(1) over multiple files, duplicating stdin. -self=edda - -# Need at least one file -if [ "$#" -eq 0 ] ; then - printf >&2 'edda: Need at least one file\n' - exit 2 -fi - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Duplicate stdin into a file -script=$td/script -cat >"$script" || exit - -# Run ed(1) over each file with the stdin given -for file ; do - ed -- "$file" <"$script" -done diff --git a/bin/pst.mi5 b/bin/pst.mi5 new file mode 100644 index 00000000..34ffbd8c --- /dev/null +++ b/bin/pst.mi5 @@ -0,0 +1,19 @@ +# Interrupt a pipe with manual /dev/tty input to a program +self=pst + +# Don't accept terminal as stdin +if [ -t 0 ] ; then + printf >&2 '%s: stdin is a term\n' "$self" + exit 2 +fi + +<% +include(`include/mktd.m4') +%> + +# Run the interactive command on the temporary file forcing /dev/tty as +# input/output +tf=$td/data +cat - > "$tf" || exit +"${@:-"${PAGER:-more}"}" "$tf" /dev/tty +cat -- "$tf" || exit diff --git a/bin/pst.sh b/bin/pst.sh deleted file mode 100644 index fdea9884..00000000 --- a/bin/pst.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# Interrupt a pipe with manual /dev/tty input to a program -self=pst - -# Don't accept terminal as stdin -if [ -t 0 ] ; then - printf >&2 '%s: stdin is a term\n' "$self" - exit 2 -fi - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Run the interactive command on the temporary file forcing /dev/tty as -# input/output -tf=$td/data -cat - > "$tf" || exit -"${@:-"${PAGER:-more}"}" "$tf" /dev/tty -cat -- "$tf" || exit diff --git a/bin/rndl.mi5 b/bin/rndl.mi5 new file mode 100644 index 00000000..f99ccbea --- /dev/null +++ b/bin/rndl.mi5 @@ -0,0 +1,38 @@ +# Print a random line from input +self=rndl + +# If there are no arguments, we're checking stdin; this is more complicated +# than checking file arguments because we have to count the lines in order to +# correctly choose a random one, and two passes means we require a temporary +# file if we don't want to read all of the input into memory (!) +if [ "$#" -eq 0 ] ; then + +<% +include(`include/mktd.m4') +%> + + # We'll operate on stdin in the temp directory; write the script's stdin to + # it with cat(1) + set -- "$td"/stdin + cat >"$td"/stdin +fi + +# Count the number of lines in the input +lc=$(sed -- '$=;d' "$@") || exit + +# If there were none, bail +case $lc in + ''|0) + printf >&2 'rndl: No lines found on input\n' + exit 2 + ;; +esac + +# Try to get a random seed from rnds(1df) for rndi(1df) +seed=$(rnds) + +# Get a random line number from rndi(1df) +ri=$(rndi 1 "$lc" "$seed") || exit + +# Print the line using sed(1) +sed -- "$ri"'!d' "$@" diff --git a/bin/rndl.sh b/bin/rndl.sh deleted file mode 100644 index 18bcec07..00000000 --- a/bin/rndl.sh +++ /dev/null @@ -1,50 +0,0 @@ -# Print a random line from input -self=rndl - -# If there are no arguments, we're checking stdin; this is more complicated -# than checking file arguments because we have to count the lines in order to -# correctly choose a random one, and two passes means we require a temporary -# file if we don't want to read all of the input into memory (!) -if [ "$#" -eq 0 ] ; then - - # Create a temporary directory with name in $td, and handle POSIX-ish traps to - # remove it when the script exits. - td= - cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi - } - for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" - done - td=$(mktd "$self") || exit - - # We'll operate on stdin in the temp directory; write the script's stdin to - # it with cat(1) - set -- "$td"/stdin - cat >"$td"/stdin -fi - -# Count the number of lines in the input -lc=$(sed -- '$=;d' "$@") || exit - -# If there were none, bail -case $lc in - ''|0) - printf >&2 'rndl: No lines found on input\n' - exit 2 - ;; -esac - -# Try to get a random seed from rnds(1df) for rndi(1df) -seed=$(rnds) - -# Get a random line number from rndi(1df) -ri=$(rndi 1 "$lc" "$seed") || exit - -# Print the line using sed(1) -sed -- "$ri"'!d' "$@" diff --git a/bin/swr.mi5 b/bin/swr.mi5 new file mode 100644 index 00000000..9b73b6d6 --- /dev/null +++ b/bin/swr.mi5 @@ -0,0 +1,52 @@ +# Transparently wrap scp(1) targets to read (not write) on the command line +self=swr + +<% +include(`include/mktd.m4') +%> + +# Set a flag to manage resetting the positional parameters at the start of the +# loop +n=1 +for arg ; do + + # If this is our first iteration, reset the shell parameters + case $n in + 1) set -- ;; + esac + + # Test whether this argument looks like a remote file + if ( + + # Test it contains a colon + case $arg in + *:*) ;; + *) exit 1 ;; + esac + + # Test the part before the first colon has at least one character and + # only hostname characters + case ${arg%%:*} in + '') exit 1 ;; + *[!a-zA-Z0-9-.]*) exit 1 ;; + esac + + ) ; then + + # Looks like a remote file request; try to copy it into the temporary + # directory, bail out completely if we can't + dst=$td/$n + scp -q -- "$arg" "$dst" || exit + set -- "$@" "$dst" + + else + # Just a plain old argument; stack it up + set -- "$@" "$arg" + fi + + # Bump n + n=$((n+1)) +done + +# Run the command with the processed arguments +exec "$@" diff --git a/bin/swr.sh b/bin/swr.sh deleted file mode 100644 index 5bad63ae..00000000 --- a/bin/swr.sh +++ /dev/null @@ -1,64 +0,0 @@ -# Transparently wrap scp(1) targets to read (not write) on the command line -self=swr - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Set a flag to manage resetting the positional parameters at the start of the -# loop -n=1 -for arg ; do - - # If this is our first iteration, reset the shell parameters - case $n in - 1) set -- ;; - esac - - # Test whether this argument looks like a remote file - if ( - - # Test it contains a colon - case $arg in - *:*) ;; - *) exit 1 ;; - esac - - # Test the part before the first colon has at least one character and - # only hostname characters - case ${arg%%:*} in - '') exit 1 ;; - *[!a-zA-Z0-9-.]*) exit 1 ;; - esac - - ) ; then - - # Looks like a remote file request; try to copy it into the temporary - # directory, bail out completely if we can't - dst=$td/$n - scp -q -- "$arg" "$dst" || exit - set -- "$@" "$dst" - - else - # Just a plain old argument; stack it up - set -- "$@" "$arg" - fi - - # Bump n - n=$((n+1)) -done - -# Run the command with the processed arguments -exec "$@" diff --git a/bin/tlcs.mi5 b/bin/tlcs.mi5 new file mode 100644 index 00000000..a3e17c82 --- /dev/null +++ b/bin/tlcs.mi5 @@ -0,0 +1,81 @@ +# Execute a command and tag the output of the stdout and stderr streams. +self=tlcs + +# Set the default prefixes and suffixes for stdout/err +out_pref='stdout: ' +err_pref='stderr: ' +out_suff= +err_suff= + +# Parse options out, give help if necessary +while getopts 'co:e:' opt ; do + case $opt in + c) + color=1 + ;; + o) + out_pref=$OPTARG + ;; + e) + err_pref=$OPTARG + ;; + \?) + printf >&2 'Unknown option %s\n' "$opt" + exit 2 + ;; + esac +done +shift "$((OPTIND-1))" + +# We need at least one more argument +if [ "$#" -eq 0 ] ; then + printf >&2 '%s: Need a command to run\n' "$self" + exit 2 +fi + +# If color was requested for the output, try and get a count of available +# colors; otherwise default to zero +[ -n "$color" ] && color_count=$( { + tput colors || tput Co +} 2>/dev/null ) +: "${color_count:=0}" + +# If the color count is 8 or greater, we'll color the output +if [ "$((color_count >= 8))" -eq 1 ] ; then + + # Color code for resetting + color_reset=$( { + tput me || tput sgr0 + } 2>/dev/null ) + + # If stdout is a terminal, color it + if [ -t 1 ] ; then + color_stdout=$( { + tput AF 2 || tput setaf 2 + } 2>/dev/null ) + out_pref=${color_stdout}${out_pref} + out_suff=${out_suff}${color_reset} + fi + + # If stderr is a terminal, color it + if [ -t 2 ] ; then + color_stderr=$( { + tput AF 1 || tput setaf 1 + } 2>/dev/null ) + err_pref=${color_stderr}${err_pref} + out_suff=${err_suff}${color_reset} + fi +fi + +<% +include(`include/mktd.m4') +%> + +# Execute the command, passing stdout and stderr to tl(1df) calls as appropriate +# via named pipes +out=$td/out err=$td/err +mkfifo -- "$out" "$err" || exit +tl -p "$out_pref" -s "$out_suff" < "$out" & +tl -p "$err_pref" -s "$err_suff" < "$err" & +"$@" >"$out" 2>"$err" +ex=$? ; wait ; exit "$ex" diff --git a/bin/tlcs.sh b/bin/tlcs.sh deleted file mode 100644 index f20b160e..00000000 --- a/bin/tlcs.sh +++ /dev/null @@ -1,93 +0,0 @@ -# Execute a command and tag the output of the stdout and stderr streams. -self=tlcs - -# Set the default prefixes and suffixes for stdout/err -out_pref='stdout: ' -err_pref='stderr: ' -out_suff= -err_suff= - -# Parse options out, give help if necessary -while getopts 'co:e:' opt ; do - case $opt in - c) - color=1 - ;; - o) - out_pref=$OPTARG - ;; - e) - err_pref=$OPTARG - ;; - \?) - printf >&2 'Unknown option %s\n' "$opt" - exit 2 - ;; - esac -done -shift "$((OPTIND-1))" - -# We need at least one more argument -if [ "$#" -eq 0 ] ; then - printf >&2 '%s: Need a command to run\n' "$self" - exit 2 -fi - -# If color was requested for the output, try and get a count of available -# colors; otherwise default to zero -[ -n "$color" ] && color_count=$( { - tput colors || tput Co -} 2>/dev/null ) -: "${color_count:=0}" - -# If the color count is 8 or greater, we'll color the output -if [ "$((color_count >= 8))" -eq 1 ] ; then - - # Color code for resetting - color_reset=$( { - tput me || tput sgr0 - } 2>/dev/null ) - - # If stdout is a terminal, color it - if [ -t 1 ] ; then - color_stdout=$( { - tput AF 2 || tput setaf 2 - } 2>/dev/null ) - out_pref=${color_stdout}${out_pref} - out_suff=${out_suff}${color_reset} - fi - - # If stderr is a terminal, color it - if [ -t 2 ] ; then - color_stderr=$( { - tput AF 1 || tput setaf 1 - } 2>/dev/null ) - err_pref=${color_stderr}${err_pref} - out_suff=${err_suff}${color_reset} - fi -fi - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Execute the command, passing stdout and stderr to tl(1df) calls as appropriate -# via named pipes -out=$td/out err=$td/err -mkfifo -- "$out" "$err" || exit -tl -p "$out_pref" -s "$out_suff" < "$out" & -tl -p "$err_pref" -s "$err_suff" < "$err" & -"$@" >"$out" 2>"$err" -ex=$? ; wait ; exit "$ex" diff --git a/bin/try.mi5 b/bin/try.mi5 new file mode 100644 index 00000000..ea39d717 --- /dev/null +++ b/bin/try.mi5 @@ -0,0 +1,65 @@ +# Attempt a certain number of times to perform a task, buffer stderr unless and +# until all command attempts fail +self=try + +# Parse options +while getopts 's:n:' opt ; do + case $opt in + n) + attn=$OPTARG + ;; + s) + sleep=$OPTARG + ;; + \?) + printf >&2 '%s: Unknown option\n' "$self" + exit 2 + ;; + esac +done +shift "$((OPTIND-1))" + +# Check we have at least one argument left (the command to run) +if [ "$#" -eq 0 ] ; then + printf >&2 '%s: Need a command to run\n' "$self" + exit 2 +fi + +<% +include(`include/mktd.m4') +%> + +# Open a filehandle to the error buffer, just to save on file operations +errbuff=$td/errbuff +exec 3>"$errbuff" + +# Keep trying the command, writing error output to the buffer file, and exit +# if we succeed on any of them +attc=1 +: "${attn:=3}" "${sleep:=0}" +while [ "$attc" -le "$attn" ] ; do + + # Try running the command; if it succeeds, we're done, and any previous + # failures get their errors discarded + if "$@" 2>&3 ; then + exit + + # If the command failed, record the exit value + else + ex=$? + fi + + # If this isn't the last run, have a sleep + if [ "$attc" -lt "$attn" ] ; then + sleep "${sleep:=0}" + fi + + # Increment the attempt count + attc=$((attc + 1)) +done + +# Attempts were exhausted, and all failed; print the error output from all of +# the failures and exit with the non-zero exit value of the most recent one +exec 3>&- +cat -- "$td"/errbuff >&2 +exit "$ex" diff --git a/bin/try.sh b/bin/try.sh deleted file mode 100644 index 20ccbe5f..00000000 --- a/bin/try.sh +++ /dev/null @@ -1,77 +0,0 @@ -# Attempt a certain number of times to perform a task, buffer stderr unless and -# until all command attempts fail -self=try - -# Parse options -while getopts 's:n:' opt ; do - case $opt in - n) - attn=$OPTARG - ;; - s) - sleep=$OPTARG - ;; - \?) - printf >&2 '%s: Unknown option\n' "$self" - exit 2 - ;; - esac -done -shift "$((OPTIND-1))" - -# Check we have at least one argument left (the command to run) -if [ "$#" -eq 0 ] ; then - printf >&2 '%s: Need a command to run\n' "$self" - exit 2 -fi - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Open a filehandle to the error buffer, just to save on file operations -errbuff=$td/errbuff -exec 3>"$errbuff" - -# Keep trying the command, writing error output to the buffer file, and exit -# if we succeed on any of them -attc=1 -: "${attn:=3}" "${sleep:=0}" -while [ "$attc" -le "$attn" ] ; do - - # Try running the command; if it succeeds, we're done, and any previous - # failures get their errors discarded - if "$@" 2>&3 ; then - exit - - # If the command failed, record the exit value - else - ex=$? - fi - - # If this isn't the last run, have a sleep - if [ "$attc" -lt "$attn" ] ; then - sleep "${sleep:=0}" - fi - - # Increment the attempt count - attc=$((attc + 1)) -done - -# Attempts were exhausted, and all failed; print the error output from all of -# the failures and exit with the non-zero exit value of the most recent one -exec 3>&- -cat -- "$td"/errbuff >&2 -exit "$ex" diff --git a/bin/urlc.mi5 b/bin/urlc.mi5 new file mode 100644 index 00000000..55dac171 --- /dev/null +++ b/bin/urlc.mi5 @@ -0,0 +1,64 @@ +# Try to find erroneous or insecure URLs +self=urlc + +# cURL request timeout +tm=${URLCHECK_TIMEOUT:-8} + +<% +include(`include/mktd.m4') +%> + +# Create buffer files for the headers and body content, to be cleaned up on +# exit +list=$td/list head=$td/head body=$td/body + +# Iterate through input; ignore leading/trailing whitespace +cat -- "${@:--}" >"$list" +while read -r url ; do + + # Skip anything that doesn't start with HTTP + case $url in + http*) ;; + *) continue ;; + esac + + # Make initial request, log head and body to files, cry and skip on error + if ! curl -A Mozilla -fHLsS -D "$head" -m "$tm" -o "$body" -- \ + "$url" ; then + printf >&2 '%s: %s raises error\n' \ + "$self" "$url" + ex=1 + continue + fi + + # Iterate through header file, cry about the first redirect we find + while IFS=': ' read -r header value ; do + [ "$header" = 'Location' ] || continue + printf >&2 '%s: %s redirects to %s\n' \ + "$self" "$url" "$value" >&2 + ex=1 + break + done < "$head" + + # Skip anything that's already secure + case $url in + https*) continue ;; + *) ;; + esac + + # Form a naïve attempt at a possible secure URL and try to request it, + # point it out if it actually works + surl=https://${url#http://} + if curl -A Mozilla -fLsS -D "$head" -m "$tm" -o "$body" -- \ + "$surl" 2>/dev/null ; then + printf >&2 '%s: %s has a working secure version at %s\n' \ + "$self" "$url" "$surl" + ex=1 + fi +done <"$list" + +# Wait for the input process to finish +wait + +# Exit if any errors +exit "${ex:-0}" diff --git a/bin/urlc.sh b/bin/urlc.sh deleted file mode 100644 index 0e6530fa..00000000 --- a/bin/urlc.sh +++ /dev/null @@ -1,76 +0,0 @@ -# Try to find erroneous or insecure URLs -self=urlc - -# cURL request timeout -tm=${URLCHECK_TIMEOUT:-8} - -# Create a temporary directory with name in $td, and handle POSIX-ish traps to -# remove it when the script exits. -td= -cleanup() { - [ -n "$td" ] && rm -fr -- "$td" - if [ "$1" != EXIT ] ; then - trap - "$1" - kill "-$1" "$$" - fi -} -for sig in EXIT HUP INT TERM ; do - # shellcheck disable=SC2064 - trap "cleanup $sig" "$sig" -done -td=$(mktd "$self") || exit - -# Create buffer files for the headers and body content, to be cleaned up on -# exit -list=$td/list head=$td/head body=$td/body - -# Iterate through input; ignore leading/trailing whitespace -cat -- "${@:--}" >"$list" -while read -r url ; do - - # Skip anything that doesn't start with HTTP - case $url in - http*) ;; - *) continue ;; - esac - - # Make initial request, log head and body to files, cry and skip on error - if ! curl -A Mozilla -fHLsS -D "$head" -m "$tm" -o "$body" -- \ - "$url" ; then - printf >&2 '%s: %s raises error\n' \ - "$self" "$url" - ex=1 - continue - fi - - # Iterate through header file, cry about the first redirect we find - while IFS=': ' read -r header value ; do - [ "$header" = 'Location' ] || continue - printf >&2 '%s: %s redirects to %s\n' \ - "$self" "$url" "$value" >&2 - ex=1 - break - done < "$head" - - # Skip anything that's already secure - case $url in - https*) continue ;; - *) ;; - esac - - # Form a naïve attempt at a possible secure URL and try to request it, - # point it out if it actually works - surl=https://${url#http://} - if curl -A Mozilla -fLsS -D "$head" -m "$tm" -o "$body" -- \ - "$surl" 2>/dev/null ; then - printf >&2 '%s: %s has a working secure version at %s\n' \ - "$self" "$url" "$surl" - ex=1 - fi -done <"$list" - -# Wait for the input process to finish -wait - -# Exit if any errors -exit "${ex:-0}" diff --git a/git/gitconfig.m4.mi5 b/git/gitconfig.m4.mi5 deleted file mode 100644 index bce64d6c..00000000 --- a/git/gitconfig.m4.mi5 +++ /dev/null @@ -1,64 +0,0 @@ -[advice] - statusHints = false - detachedHead = false - implicitIdentity = false - pushUpdateRejected = false - -[alias] - amend = commit --amend - ls = log --oneline - others = ls-files --others --exclude-standard - fuckit = "!git clean -dfx ; git reset --hard" - -[color] - ui = true - -[commit] - status = false - -[core] - compression = 9 - -[diff] - algorithm = patience - tool = vimdiff - -[difftool] - prompt = false - -[fetch] - output = compact - prune = true - -[grep] - extendRegexp = true - lineNumber = true - -[log] - date = local - decorate = short - -[merge] - ff = false - -[pager] - diff = cat - -[pull] - ff = only - -[push] - default = current - -[sendemail] - confirm = compose - smtpServer = <% DF_SENDMAIL %> - -[status] - short = true - showUntrackedFiles = all - -[user] - name = <% DF_NAME %> - email = <% DF_EMAIL %> - signingKey = <% DF_KEY %> diff --git a/git/gitconfig.mi5 b/git/gitconfig.mi5 new file mode 100644 index 00000000..bce64d6c --- /dev/null +++ b/git/gitconfig.mi5 @@ -0,0 +1,64 @@ +[advice] + statusHints = false + detachedHead = false + implicitIdentity = false + pushUpdateRejected = false + +[alias] + amend = commit --amend + ls = log --oneline + others = ls-files --others --exclude-standard + fuckit = "!git clean -dfx ; git reset --hard" + +[color] + ui = true + +[commit] + status = false + +[core] + compression = 9 + +[diff] + algorithm = patience + tool = vimdiff + +[difftool] + prompt = false + +[fetch] + output = compact + prune = true + +[grep] + extendRegexp = true + lineNumber = true + +[log] + date = local + decorate = short + +[merge] + ff = false + +[pager] + diff = cat + +[pull] + ff = only + +[push] + default = current + +[sendemail] + confirm = compose + smtpServer = <% DF_SENDMAIL %> + +[status] + short = true + showUntrackedFiles = all + +[user] + name = <% DF_NAME %> + email = <% DF_EMAIL %> + signingKey = <% DF_KEY %> diff --git a/gnupg/gpg.conf.m4.mi5 b/gnupg/gpg.conf.m4.mi5 deleted file mode 100644 index d8f14c09..00000000 --- a/gnupg/gpg.conf.m4.mi5 +++ /dev/null @@ -1,52 +0,0 @@ -# Retrieve certs automatically if possible -auto-key-locate cert pka - -# Prevent boilerplate about needing key decryption, which is handled by the -# agent; the gpg function in my Bash scripts overrides this for certain -# commands where it interferes -batch - -# Use SHA512 as the hash when making key signatures -cert-digest-algo SHA512 - -# Specify the hash algorithms to be used for new keys as available -default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed - -# In the absence of any other recipient, encrypt messages for myself -default-recipient-self - -# Show complete dates and use proper column separation for --with-colon listing mode -fixed-list-mode - -# Use 16-character key IDs as the default 8-character key IDs can be forged -keyid-format 0xlong - -# Use a pool of servers which support HKPS (encrypted key retrieval) -keyserver DF_KEYSERVER - -# Retrieve keys automatically; check the keyserver port cert; use whichever -# server is proffered from the pool -keyserver-options auto-key-retrieve check-cert no-honor-keyserver-url ca-certfile=<% DF_HOME %>/.gnupg/sks-keyservers.net/sks-keyservers.netCA.pem - -# Include trust/validity for UIDs in listings -list-options show-uid-validity - -# Suppress the copyright message -no-greeting - -# Use SHA512 as my message digest, overriding GnuPG's efforts to use the lowest -# common denominator in hashing algorithms -personal-digest-preferences SHA512 - -# Suppress a lot of output; sometimes I add --verbose to undo this -quiet - -# Use the GPG agent for key management and decryption -use-agent - -# Include trust/validity for UIDs when verifying signatures -verify-options pka-lookups show-uid-validity - -# Assume "yes" is the answer to most questions, that is, don't keep asking me -# to confirm something I've asked to be done -yes diff --git a/gnupg/gpg.conf.mi5 b/gnupg/gpg.conf.mi5 new file mode 100644 index 00000000..d8f14c09 --- /dev/null +++ b/gnupg/gpg.conf.mi5 @@ -0,0 +1,52 @@ +# Retrieve certs automatically if possible +auto-key-locate cert pka + +# Prevent boilerplate about needing key decryption, which is handled by the +# agent; the gpg function in my Bash scripts overrides this for certain +# commands where it interferes +batch + +# Use SHA512 as the hash when making key signatures +cert-digest-algo SHA512 + +# Specify the hash algorithms to be used for new keys as available +default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed + +# In the absence of any other recipient, encrypt messages for myself +default-recipient-self + +# Show complete dates and use proper column separation for --with-colon listing mode +fixed-list-mode + +# Use 16-character key IDs as the default 8-character key IDs can be forged +keyid-format 0xlong + +# Use a pool of servers which support HKPS (encrypted key retrieval) +keyserver DF_KEYSERVER + +# Retrieve keys automatically; check the keyserver port cert; use whichever +# server is proffered from the pool +keyserver-options auto-key-retrieve check-cert no-honor-keyserver-url ca-certfile=<% DF_HOME %>/.gnupg/sks-keyservers.net/sks-keyservers.netCA.pem + +# Include trust/validity for UIDs in listings +list-options show-uid-validity + +# Suppress the copyright message +no-greeting + +# Use SHA512 as my message digest, overriding GnuPG's efforts to use the lowest +# common denominator in hashing algorithms +personal-digest-preferences SHA512 + +# Suppress a lot of output; sometimes I add --verbose to undo this +quiet + +# Use the GPG agent for key management and decryption +use-agent + +# Include trust/validity for UIDs when verifying signatures +verify-options pka-lookups show-uid-validity + +# Assume "yes" is the answer to most questions, that is, don't keep asking me +# to confirm something I've asked to be done +yes diff --git a/include/mktd.mi5 b/include/mktd.mi5 new file mode 100644 index 00000000..388eb9be --- /dev/null +++ b/include/mktd.mi5 @@ -0,0 +1,15 @@ +# Create a temporary directory with name in $td, and handle POSIX-ish traps to +# remove it when the script exits. +td= +cleanup() { + [ -n "$td" ] && rm -fr -- "$td" + if [ "$1" != EXIT ] ; then + trap - "$1" + kill "-$1" "$$" + fi +} +for sig in EXIT HUP INT TERM ; do + # shellcheck disable=SC2064 + trap "cleanup $sig" "$sig" +done +td=$(mktd "$self") || exit diff --git a/tmux/tmux.conf.m4.mi5 b/tmux/tmux.conf.m4.mi5 deleted file mode 100644 index 76d493c1..00000000 --- a/tmux/tmux.conf.m4.mi5 +++ /dev/null @@ -1,130 +0,0 @@ -# Strip out a lot of machine and X11 dependent crap from the initial -# environment -set-environment -gru COLORFGBG -set-environment -gru COLORTERM -set-environment -gru DISPLAY -set-environment -gru SSH_CLIENT -set-environment -gru SSH_CONNECTION -set-environment -gru SSH_TTY -set-environment -gru WINDOWID - -# Otherwise, use the environment we had when we started; don't touch it during -# a session unless I specifically ask -set-option -g update-environment '' - -# Setting this makes each new pane a non-login shell, which suits me better -set-option -g default-command "$SHELL" - -# Expect a 256-color terminal -set-option -g default-terminal 'screen-256color' - -# Change the prefix to ^A rather than the default of ^B, because I'm a godless -# GNU Screen refugee, and also I like using ^B in my shell and in Vim more -unbind-key C-b -set-option -g prefix C-a -bind-key a send-prefix - -# Repeating the prefix switches to the last window and back, a GNU Screen -# feature that's hardwired into my brain now -bind-key C-a last-window - -# Quick ways to kill single windows and the whole server -bind-key '/' confirm-before 'kill-window' -bind-key '\' confirm-before 'kill-server' - -# Slightly more intuitive way to split windows -bind-key '_' split-window -v -bind-key '|' split-window -h - -# Switch to the last active pane -bind-key Tab last-pane - -# Use the vi mode for tmux interaction behaviour in copy and choice modes -set-window-option -g mode-keys vi -bind-key -T copy-mode-vi v send -X begin-selection -bind-key -T copy-mode-vi y send -X copy-selection-and-cancel - -# Detach with Alt-M, no prefix required -bind-key -n M-m detach - -# Vim-like pane resizing -bind-key -r '+' resize-pane -U 5 -bind-key -r '-' resize-pane -D 5 -bind-key -r '<' resize-pane -L 5 -bind-key -r '>' resize-pane -R 5 - -# Vim-like pane switching -bind-key h select-pane -L -bind-key j select-pane -D -bind-key k select-pane -U -bind-key l select-pane -R - -# Join and break panes -bind-key J choose-window "join-pane -h -s '%%'" -bind-key B break-pane -d - -# Select only sessions in the choose-tree menu, not the whole tree of sessions -# and windows, I prefer to drill down -bind-key s choose-session - -# Session title on the left side of the status bar -set-option -g status-left '[#S] ' - -# Username, hostname, and the current date on the right side of the status bar -set-option -g status-right ' [#(whoami)@#H] #(date +"%F %T")' - -# Update the status bar every second -set-option -g status-interval 1 - -# The first window in a session has index 1, rather than 0 -set-option -g base-index 1 - -# Don't worry about timeouts for key combinations, as I don't use Escape as -# meta and prefer things to be snappier -set-option -g escape-time 0 - -# Keep plenty of history -set-option -g history-limit 100000 - -# Don't interfere with my system clipboard -set-option -g set-clipboard off - -# Only force individual windows to the smallest attached terminal size, not -# whole sessions -set-window-option -g aggressive-resize on - -# If I don't set a title on a window, use the program name for the window title -set-window-option -g automatic-rename on - -# However, don't let terminal escape sequences rename my windows -set-window-option -g allow-rename off - -# Window titles are the window index, a colon, the window or command name, and -# any activity or alert indicators -set-window-option -g window-status-format "#I:#W#F" - -# Message dialogs are white on blue -set-option -g message-style "bg=colour18,fg=colour231" - -# Window choosers are white on blue -set-window-option -g mode-style "bg=colour18,fg=colour231" - -# Pane borders are always in the background color -set-option -g pane-border-style "fg=<% DF_TMUX_BG %>" -set-option -g pane-active-border-style "fg=<% DF_TMUX_BG %>" - -# Inactive windows have slightly washed-out system colours -set-option -g window-style "bg=colour232,fg=colour248" -set-option -g window-active-style "bg=colour0,fg=colour15" - -# The status bar has the defined background and foreground colours -set-option -g status-style "bg=<% DF_TMUX_BG %>,fg=<% DF_TMUX_FG %>" - -# Titles of windows default to black text with no embellishment -set-window-option -g window-status-style "fg=colour16" - -# The title of the active window is in white rather than black -set-window-option -g window-status-current-style "fg=colour231" - -# A window with a bell has a title with a red background until cleared -set-window-option -g window-status-bell-style "bg=colour9" diff --git a/tmux/tmux.conf.mi5 b/tmux/tmux.conf.mi5 new file mode 100644 index 00000000..76d493c1 --- /dev/null +++ b/tmux/tmux.conf.mi5 @@ -0,0 +1,130 @@ +# Strip out a lot of machine and X11 dependent crap from the initial +# environment +set-environment -gru COLORFGBG +set-environment -gru COLORTERM +set-environment -gru DISPLAY +set-environment -gru SSH_CLIENT +set-environment -gru SSH_CONNECTION +set-environment -gru SSH_TTY +set-environment -gru WINDOWID + +# Otherwise, use the environment we had when we started; don't touch it during +# a session unless I specifically ask +set-option -g update-environment '' + +# Setting this makes each new pane a non-login shell, which suits me better +set-option -g default-command "$SHELL" + +# Expect a 256-color terminal +set-option -g default-terminal 'screen-256color' + +# Change the prefix to ^A rather than the default of ^B, because I'm a godless +# GNU Screen refugee, and also I like using ^B in my shell and in Vim more +unbind-key C-b +set-option -g prefix C-a +bind-key a send-prefix + +# Repeating the prefix switches to the last window and back, a GNU Screen +# feature that's hardwired into my brain now +bind-key C-a last-window + +# Quick ways to kill single windows and the whole server +bind-key '/' confirm-before 'kill-window' +bind-key '\' confirm-before 'kill-server' + +# Slightly more intuitive way to split windows +bind-key '_' split-window -v +bind-key '|' split-window -h + +# Switch to the last active pane +bind-key Tab last-pane + +# Use the vi mode for tmux interaction behaviour in copy and choice modes +set-window-option -g mode-keys vi +bind-key -T copy-mode-vi v send -X begin-selection +bind-key -T copy-mode-vi y send -X copy-selection-and-cancel + +# Detach with Alt-M, no prefix required +bind-key -n M-m detach + +# Vim-like pane resizing +bind-key -r '+' resize-pane -U 5 +bind-key -r '-' resize-pane -D 5 +bind-key -r '<' resize-pane -L 5 +bind-key -r '>' resize-pane -R 5 + +# Vim-like pane switching +bind-key h select-pane -L +bind-key j select-pane -D +bind-key k select-pane -U +bind-key l select-pane -R + +# Join and break panes +bind-key J choose-window "join-pane -h -s '%%'" +bind-key B break-pane -d + +# Select only sessions in the choose-tree menu, not the whole tree of sessions +# and windows, I prefer to drill down +bind-key s choose-session + +# Session title on the left side of the status bar +set-option -g status-left '[#S] ' + +# Username, hostname, and the current date on the right side of the status bar +set-option -g status-right ' [#(whoami)@#H] #(date +"%F %T")' + +# Update the status bar every second +set-option -g status-interval 1 + +# The first window in a session has index 1, rather than 0 +set-option -g base-index 1 + +# Don't worry about timeouts for key combinations, as I don't use Escape as +# meta and prefer things to be snappier +set-option -g escape-time 0 + +# Keep plenty of history +set-option -g history-limit 100000 + +# Don't interfere with my system clipboard +set-option -g set-clipboard off + +# Only force individual windows to the smallest attached terminal size, not +# whole sessions +set-window-option -g aggressive-resize on + +# If I don't set a title on a window, use the program name for the window title +set-window-option -g automatic-rename on + +# However, don't let terminal escape sequences rename my windows +set-window-option -g allow-rename off + +# Window titles are the window index, a colon, the window or command name, and +# any activity or alert indicators +set-window-option -g window-status-format "#I:#W#F" + +# Message dialogs are white on blue +set-option -g message-style "bg=colour18,fg=colour231" + +# Window choosers are white on blue +set-window-option -g mode-style "bg=colour18,fg=colour231" + +# Pane borders are always in the background color +set-option -g pane-border-style "fg=<% DF_TMUX_BG %>" +set-option -g pane-active-border-style "fg=<% DF_TMUX_BG %>" + +# Inactive windows have slightly washed-out system colours +set-option -g window-style "bg=colour232,fg=colour248" +set-option -g window-active-style "bg=colour0,fg=colour15" + +# The status bar has the defined background and foreground colours +set-option -g status-style "bg=<% DF_TMUX_BG %>,fg=<% DF_TMUX_FG %>" + +# Titles of windows default to black text with no embellishment +set-window-option -g window-status-style "fg=colour16" + +# The title of the active window is in white rather than black +set-window-option -g window-status-current-style "fg=colour231" + +# A window with a bell has a title with a red background until cleared +set-window-option -g window-status-bell-style "bg=colour9" -- cgit v1.2.3