+# ya, hacky hardcoded hostnames in 2023. we could do better
+hssh-update() {
+ local -a failed_hosts hosts
+ case $HOSTNAME in
+ sy|kd)
+ hosts=(
+ kd x3.office.fsf.org syw
+ )
+ ;;
+ x3)
+ hosts=(
+ b8.nz sywg.b8.nz
+ )
+ ;;
+ esac
+ for host in ${hosts[@]}; do
+ e $host
+ if ! scp /b/fai/fai/config/files/usr/local/bin/hssh/IANK root@$host:/usr/local/bin/hssh; then
+ failed_hosts+=($host)
+ fi
+ done
+ if (( ${#failed_hosts[@]} >= 1 )); then
+ echo failed_hosts=${failed_hosts[*]}
+ return 1
+ fi
+}
+
+noi3bar() {
+ touch /tmp/noi3bar
+}
+i3bar() {
+ rm -fv /tmp/noi3bar
+}
+
+# example:
+# <#part type="image/jpeg" filename="/home/iank/2023-12-24-ski-trip.jpg" disposition=attachment> <#/part>
+#
+attach-txt() {
+ local f
+ for f; do
+ if [[ ! -s $f ]]; then
+ e "error: empty or non-existent file $f"
+ return 1
+ fi
+ done
+ for f; do
+ echo '<#part type="image/jpeg" filename="'"$(rl "$f")"'" disposition=attachment> <#/part>'
+ done | ec
+}
+
+ctof() {
+ units "tempC($1)" tempF
+}
+
+ftoc() {
+ units "tempF($1)" tempC
+}
+
+# requires dns/firewall setup first
+local-icecast() {
+ web-conf -e ian@iankelling.org -f 8000 - apache2 live.iankelling.org <<'EOF'
+<Location "/fsf.webm">
+AuthType Basic
+AuthName "basic_auth"
+# created with
+# htpasswd -c icecast-fsf-htpasswd USERNAME
+AuthUserFile "/etc/icecast-fsf-htpasswd"
+Require valid-user
+</Location>
+<Location "/fsf-tech.webm">
+AuthType Basic
+AuthName "basic_auth"
+AuthUserFile "/etc/icecast-fsf-tech-htpasswd"
+Require valid-user
+</Location>
+EOF
+}
+
+# obs screen switching of
+obof() {
+ ls -l /tmp/no-obs-auto-scene-switch
+ touch /tmp/no-obs-auto-scene-switch
+}
+# obs screen switching on
+obon() {
+ ls -l /tmp/no-obs-auto-scene-switch
+ if [[ -e /tmp/no-obs-auto-scene-switch ]]; then
+ rm -f /tmp/no-obs-auto-scene-switch
+ fi
+}
+
+obs-gen-profiles() {
+ local p=/p/c/basic/profiles
+ sed 's/fsf-sysops/fsf-tech/g' $p/fsfsysops/basic.ini >$p/fsftech/basic.ini
+ sed 's/fsf-sysops/fsf/g' $p/fsfsysops/basic.ini >$p/fsf/basic.ini
+}
+
+# terminal clear. like clear, but put the prompt at the bottom,
+# useful for obs streaming the bottom half of a terminal window.
+tclear() {
+ for ((i=i; i<COLUMNS; i++)); do
+ echo
+ done
+}
+
+