]> CyberLeo.Net >> Repos - CDN/flag.git/blob - flag
Help blurb clarification
[CDN/flag.git] / flag
1 #!/bin/sh
2
3 #set -x
4
5 # Places for flags:
6 # $HOME/.flag-cache <- Autogenerated flag (refreshed when hostname changes)
7 # /etc/flag <- Site admin's flag
8 # $HOME/.flag <- Local user's flag
9 # Check them in that order.
10
11 hash_string() {
12   # Hash the passed string into 8 hex characters
13   [ -z "${crc32_bin}" ] && find_crc32_bin
14   if [ -z "${crc32_bin}" ]
15   then
16     echo "No crc32 algo found!" >&2
17     echo "deadbeef"
18   else
19     echo -n "${*}" | eval "${crc32_bin}" | awk '{print $1}'
20   fi
21 }
22
23 find_crc32_bin() {
24   crc32=""
25   for bin in crc32sum crc32sum-linux crc32sum-freebsd
26   do
27     bin="$(which "${bin}" 2>/dev/null)"
28     if [ -x "${bin}" ]
29     then
30       export crc32_bin="${bin}"
31       if [ "$(hash_string "meow" 2>/dev/null)" = "8a106afe" ]
32       then
33         crc32="${bin}"
34         break
35       fi
36     fi
37   done
38   
39   if [ -z "${crc32}" ]
40   then
41     for bin in ruby php perl
42     do
43       bin="$(which "${bin}" 2>/dev/null)"
44       if [ -x "${bin}" ]
45       then
46         case "${bin}" in
47         */ruby) bin="${bin} -e 'require \"zlib\"; printf(\"%08x\n\", Zlib.crc32(STDIN.readlines.join))'" ;;
48         */php)  bin="${bin} -r 'printf(\"%08x\n\", crc32(file_get_contents(\"/dev/stdin\")));'" ;;
49         */perl)        bin="${bin} -e 'use String::CRC32; printf(\"%08x\n\", crc32(*STDIN));'" ;;
50         esac
51         export crc32_bin="${bin}"
52         if [ "$(hash_string "meow" 2>/dev/null)" = "8a106afe" ]
53         then
54           crc32="${bin}"
55           break
56         fi
57       fi
58     done
59   fi
60   if [ -n "${crc32}" ]
61   then
62     export crc32_bin="${crc32}"
63   else
64     echo "Failed to locate usable crc32 algo"
65     unset crc32_bin
66     return 1
67   fi
68 }
69
70 find_crc32_bin
71
72 flagcache(){
73   myhost="$(/bin/hostname -f)"
74   cache="${HOME}/.flag-cache"
75   if [ -f "${cache}" ]
76   then
77     flag_hex="$(awk '/^'${myhost}'/{print $2}' "${cache}")"
78   fi
79   if [ -z "${flag_hex}" ]
80   then
81     flag_hex="$(hash_string "${myhost}")"
82     echo -e "${myhost}\t${flag_hex}" >> "${cache}"
83   fi
84 }
85
86 if [ -f "${HOME}/.flag" ]
87 then
88   flag_hex="$(cat "${HOME}/.flag")"
89 fi
90
91 if [ -z "${flag_hex}" -a -f "/etc/flag" ]
92 then
93   flag_hex="$(cat "/etc/flag")"
94 fi
95
96 if [ -z "${flag_hex}" ]
97 then
98   flagcache
99 fi
100
101 # Now we definitely have flag_hex
102 firstchar() {
103   eval $(echo -en "${data}" | sed -e 's/^\(.\)\(.*\)$/char="\1" data="\2"/g')
104 }
105
106 hexdec() {
107   if [ -z "${1}" ]
108   then
109     echo "0"
110     return
111   fi
112   echo $(( 0x${1} + 0 ))
113 }
114
115 flag() {
116   if [ -z "${1}" ]
117   then
118     echo "Usage: flag 'hexcode' [symbol] [shellmode]"
119     echo "Generates an ANSI color flag using the specified hex codes"
120     echo "Uses the optional symbol (or ' ') to draw the flag"
121     echo "shellmode encapsulates all nonprintable codes in \[\] to"
122     echo " give the shell hints on how long the string is, for proper"
123     echo " wrapping of command prompts."
124     return
125   fi
126   data="${1}"
127   sym="${2}"
128   shm="${3}"
129   [ -z "${sym}" ] && sym=" "
130   [ -n "${shm}" ] && open="\[" shut="\]"
131   while [ -n "${data}" ]
132   do
133     firstchar
134     ord=$(hexdec "${char}")
135     bright="0"
136     [ "$(( ${ord} & 8 ))" -gt 0 ] && bright="1"
137     fore="3$(( ${ord} & 7 ))"
138     back="4$(( ${ord} & 7 ))"
139     printf "${open}\033[%s;%s;%s;7m${shut}%s" "${bright}" "${fore}" "${back}" "${sym}"
140   done
141   printf "${open}\033[0m${shut}"
142 }
143
144 pebkac() {
145    echo "Usage: $(basename "${0}") [-s #] [-e]"
146    echo "Produces a neat little ansi colour 'flag' based off"
147    echo " a hash of the machine's hostname (or settable via"
148    echo " ~/.flag or /etc/flag) which can uniquely visually"
149    echo " identify a machine, at a glance. Useful for placing"
150    echo " into /etc/issue or your bash prompt, so that you"
151    echo " don't send stupid commands to the wrong machine."
152    echo " "
153    echo " -s #   Specify which character should be used to"
154    echo "         render the flag"
155    echo " -e     Turn on bash encapsulation mode, to provide"
156    echo "         hints to Bash on what is or is not printable"
157    echo "         so it can wrap your commands appropriately"
158    echo "         when used in your prompt"
159    echo " "
160    echo "This machine's flag is as such: ($(flag "${flag_hex}"))"
161    exit 1
162 }
163
164 symbol=" "
165 shellmode=""
166
167 while [ -n "${1}" ]
168 do
169   case "${1}" in
170   -s)   shift; symbol="${1}" ;;
171   -e)   shellmode="yes" ;;
172   *)    pebkac ;;
173   esac
174   shift
175 done
176 flag "${flag_hex}" "${symbol}" "${shellmode}"
177