#!/bin/sh #set -x # Places for flags: # $HOME/.flag-cache <- Autogenerated flag (refreshed when hostname changes) # /etc/flag <- Site admin's flag # $HOME/.flag <- Local user's flag # Check them in that order. hash_string() { # Hash the passed string into 8 hex characters [ -z "${crc32_bin}" ] && find_crc32_bin if [ -z "${crc32_bin}" ] then echo "No crc32 algo found!" >&2 echo "deadbeef" else echo -n "${*}" | eval "${crc32_bin}" | awk '{print $1}' fi } find_crc32_bin() { crc32="" for bin in crc32sum crc32sum-linux crc32sum-freebsd do bin="$(which "${bin}" 2>/dev/null)" if [ -x "${bin}" ] then export crc32_bin="${bin}" if [ "$(hash_string "meow" 2>/dev/null)" = "8a106afe" ] then crc32="${bin}" break fi fi done if [ -z "${crc32}" ] then for bin in ruby php perl do bin="$(which "${bin}" 2>/dev/null)" if [ -x "${bin}" ] then case "${bin}" in */ruby) bin="${bin} -e 'require \"zlib\"; printf(\"%08x\n\", Zlib.crc32(STDIN.readlines.join))'" ;; */php) bin="${bin} -r 'printf(\"%08x\n\", crc32(file_get_contents(\"/dev/stdin\")));'" ;; */perl) bin="${bin} -e 'use String::CRC32; printf(\"%08x\n\", crc32(*STDIN));'" ;; esac export crc32_bin="${bin}" if [ "$(hash_string "meow" 2>/dev/null)" = "8a106afe" ] then crc32="${bin}" break fi fi done fi if [ -n "${crc32}" ] then export crc32_bin="${crc32}" else echo "Failed to locate usable crc32 algo" >&2 unset crc32_bin return 1 fi } flagcache(){ myhost="$(/bin/hostname -f)" cache="${HOME}/.flag-cache" if [ -f "${cache}" ] then flag_hex="$(awk '/^'${myhost}'/{print $2}' "${cache}")" fi if [ -z "${flag_hex}" ] then flag_hex="$(hash_string "${myhost}")" echo -e "${myhost}\t${flag_hex}" >> "${cache}" fi } if [ -f "${HOME}/.flag" ] then flag_hex="$(cat "${HOME}/.flag")" fi if [ -z "${flag_hex}" -a -f "/etc/flag" ] then flag_hex="$(cat "/etc/flag")" fi if [ -z "${flag_hex}" ] then flagcache fi # Now we definitely have flag_hex firstchar() { eval $(echo -n "${data}" | sed -e 's/^\(.\)\(.*\)$/char="\1" data="\2"/g') } hexdec() { if [ -z "${1}" ] then echo "0" return fi echo $(( 0x${1} + 0 )) } flag() { if [ -z "${1}" ] then echo "Usage: flag 'hexcode' [symbol] [shellmode]" >&2 echo "Generates an ANSI color flag using the specified hex codes" >&2 echo "Uses the optional symbol (or ' ') to draw the flag" >&2 echo "shellmode encapsulates all nonprintable codes in \[\] to" >&2 echo " give the shell hints on how long the string is, for proper" >&2 echo " wrapping of command prompts." >&2 return fi data="${1}" sym="${2}" shm="${3}" [ -n "${shm}" ] && open='\\[' shut='\\]' while [ -n "${data}" ] do firstchar ord=$(hexdec "${char}") bright="0" [ "$(( ${ord} & 8 ))" -gt 0 ] && bright="1;7" colour="$(( ${ord} & 7 ))" printf "${open}\033[%s;3%s;4%sm${shut}%s" "${bright}" "${colour}" "${colour}" "${sym:-${char}}" done printf "${open}\033[0m${shut}" } pebkac() { echo "Usage: $(basename "${0}") [-s #] [-e]" >&2 echo "Produces a neat little ansi colour 'flag' based off" >&2 echo " a hash of the machine's hostname (or settable via" >&2 echo " ~/.flag or /etc/flag) which can uniquely visually" >&2 echo " identify a machine, at a glance. Useful for placing" >&2 echo " into /etc/issue or your bash prompt, so that you" >&2 echo " don't send stupid commands to the wrong machine." >&2 echo " " >&2 echo " -s # Specify which character should be used to" >&2 echo " render the flag. If empty, use the hex code." >&2 echo " -e Turn on bash encapsulation mode, to provide" >&2 echo " hints to Bash on what is or is not printable" >&2 echo " so it can wrap your commands appropriately" >&2 echo " when used in your prompt" >&2 echo " " >&2 echo "This machine's flag is as such: ($(flag "${flag_hex}"))" >&2 exit 1 } symbol="" shellmode="" while [ -n "${1}" ] do case "${1}" in -s) shift; symbol="${1}" ;; -e) shellmode="yes" ;; *) pebkac ;; esac shift done flag "${flag_hex}" "${symbol}" "${shellmode}"