# The machine page's console is an xterm, but the launcher hands the shell # TERM=dumb, and full-screen tools (minicom) refuse a terminal with no cursor motion. if [ "${TERM:-dumb}" = dumb ]; then export TERM=xterm-256color; fi # som-mfg-f7's MAC list, read by its own rules (mac_next), for the banner. /etc/motd # is written once, at build time, so the figures are worked out here. _som_first() { local l while IFS= read -r l || [ -n "$l" ]; do l=${l//$'\r'/}; l=${l#"${l%%[!$' \t']*}"} case $l in ''|'#'*) continue ;; esac printf '%s\n' "$l"; return 0 done <"$1" } _som_mac() { [[ $1 =~ ^([0-9A-Fa-f]{1,2}):([0-9A-Fa-f]{1,2}):([0-9A-Fa-f]{1,2}):([0-9A-Fa-f]{1,2}):([0-9A-Fa-f]{1,2}):([0-9A-Fa-f]{1,2})$ ]] || return 1 local r=("${BASH_REMATCH[@]}") printf '%d %d\n' $(( (16#${r[1]} << 16) | (16#${r[2]} << 8) | 16#${r[3]} )) \ $(( (16#${r[4]} << 16) | (16#${r[5]} << 8) | 16#${r[6]} )) } _som_join() { printf '%02X:%02X:%02X:%02X:%02X:%02X' $(( $1 >> 16 & 255 )) $(( $1 >> 8 & 255 )) $(( $1 & 255 )) \ $(( $2 >> 16 & 255 )) $(( $2 >> 8 & 255 )) $(( $2 & 255 )) } _som_maclist() { local d=${SOM_STATION_DIR:-/var/lib/brintos-som}/mac line w l f t p range local listf=$d/maclist lastf=$d/lastmac [ -e "$listf" ] || { echo "no MAC list at $listf: som-mfg-f7 needs one (FROM TO), --mac, or --keep-mac"; return; } line=$(_som_first "$listf" 2>/dev/null) || [ -r "$listf" ] || { echo "cannot read $listf"; return; } read -r -a w <<<"$line" [ "${#w[@]}" -ge 2 ] || { echo "$listf: no range in it (want one line: FROM TO); som-mfg-f7 refuses it"; return; } f=$(_som_mac "${w[0]}") && t=$(_som_mac "${w[1]}") || { echo "$listf: not two MAC addresses: '$line'; som-mfg-f7 refuses it"; return; } f=($f); t=($t) [ "${f[0]}" -eq "${t[0]}" ] || { echo "$listf: the first three octets of FROM and TO differ; som-mfg-f7 refuses it"; return; } [ "${f[1]}" -le "${t[1]}" ] || { echo "$listf: FROM is above TO; som-mfg-f7 refuses it"; return; } range="$(_som_join "${f[@]}")..$(_som_join "${t[@]}")" if [ ! -e "$lastf" ]; then echo "MAC list $range: none handed out yet; 0 used, $(( t[1] - f[1] + 1 )) left" return fi l=$(_som_first "$lastf" 2>/dev/null) [ -n "$l" ] || { echo "$lastf exists but holds no MAC; som-mfg-f7 refuses the list until it does"; return; } p=$(_som_mac "${l%%[$' \t']*}") || { echo "$lastf: not a MAC address: '$l'; som-mfg-f7 refuses it"; return; } p=($p) [ "${p[0]}" -eq "${f[0]}" ] || { echo "$lastf: $(_som_join "${p[@]}") is not in the range's first three octets; som-mfg-f7 refuses it"; return; } [ "${p[1]}" -ne "${t[1]}" ] || { echo "MAC list $range: used up, lastmac $(_som_join "${p[@]}") is the end of the range; som-mfg-f7 needs a new one"; return; } [ "${p[1]}" -ge "${f[1]}" ] && [ "${p[1]}" -le "${t[1]}" ] || { echo "$lastf: $(_som_join "${p[@]}") lies outside the range $range; som-mfg-f7 refuses it"; return; } echo "MAC list $range: last handed out $(_som_join "${p[@]}"); $(( p[1] - f[1] + 1 )) used, $(( t[1] - p[1] )) left" } # Nothing else prints /etc/motd here: the guest has no login, and /etc/profile is empty. # Read by bash itself: busybox cat copies with sendfile(2), which hangs on the served runtime. case $- in *i*) if [ -s /etc/motd ]; then _som_station= while IFS= read -r l || [ -n "$l" ]; do printf '%s\n' "$l" case $l in "brintOS SOM programming station"*) _som_station=1 ;; esac done