X-Git-Url: https://iankelling.org/git/?a=blobdiff_plain;ds=sidebyside;f=brc2;h=5fde3685ef65a65997aa6542cce52a87ae69f3cb;hb=b714b0dde29aaf5e44d628c1d723077465e9c488;hp=5c86f00f8845b7c5f18885922fdb06c77f300cb7;hpb=ef708570f1f42d9bb54ddc5b7b0432de4f761eb0;p=distro-setup
diff --git a/brc2 b/brc2
index 5c86f00..5fde368 100644
--- a/brc2
+++ b/brc2
@@ -1,6 +1,25 @@
#!/bin/bash
-# Copyright (C) 2019 Ian Kelling
-# SPDX-License-Identifier: AGPL-3.0-or-later
+# I, Ian Kelling, follow the GNU license recommendations at
+# https://www.gnu.org/licenses/license-recommendations.en.html. They
+# recommend that small programs, < 300 lines, be licensed under the
+# Apache License 2.0. This file contains or is part of one or more small
+# programs. If a small program grows beyond 300 lines, I plan to switch
+# its license to GPL.
+
+# Copyright 2024 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
# this gets sourced. shebang is just for file mode detection
@@ -64,15 +83,6 @@ else
export NOT_MAIL_HOST_P=t
fi
-
-source /a/bin/log-quiet/logq-function
-
-# not used
-# if [[ -s /a/opt/alacritty/extra/completions/alacritty.bash ]]; then
-# source /a/opt/alacritty/extra/completions/alacritty.bash
-# fi
-
-
source /a/bin/ds/beet-data
@@ -162,7 +172,7 @@ slemacs() {
sle() { # sl emacs
local f=/home/iank/.emacs.d/init.el
- sl --sl-test-cmd ". /etc/os-release ; printf %s \${VERSION//[^a-zA-Z0-9]/}; test -e $f && stat -c%Y $f" --sl-test-hook slemacs "$@"
+ sl --sl-test-cmd "sed -rn '/^VERSION=/{s/^.*=//;s/[^[:alnum:]]//gp}' /etc/os-release; test -e $f && stat -c%Y $f" --sl-test-hook slemacs "$@"
}
ccomp ssh sle
@@ -197,6 +207,20 @@ rm-docker-iptables() {
# usage mkschroot [-] distro codename packages
# - means no piping in of sources.list
+#
+# note some useful post mkschroot i've used in the past
+# tu /nocow/schroot/flidas/etc/sudoers </dev/null || [[ $? == 141 ]]; then
"$@"
fi
@@ -771,7 +801,7 @@ mpvrpc-loadfile() {
finalpath="$cachedir${path#/i/m}"
rowir rsync --partial -a --inplace --mkpath "b8.nz:$path" "$finalpath"
finalnextpath="$cachedir${nextpath#/i/m}"
- count=$(pgrep -a -f "^rsync --partial -a --inplace --mkpath $cachdir" || [[ $? == 1 ]] )
+ count=$(pgrep -a -f "^rsync --partial -a --inplace --mkpath $cachedir" || [[ $? == 1 ]] )
# allow us to start 2 rsyncs in the background
if [[ $count == [01] ]]; then
rinr rsync --partial -a --inplace --mkpath "b8.nz:$nextpath" "$finalnextpath" &
@@ -801,9 +831,10 @@ mpvrpc-loadfile() {
# q quit
# ret next
#
+# todo: enter should also unpause
beetag() {
local last_genre_i fstring tag id char new_item char_i genre tag remove doplay i j random path
- local do_rare_genres read_wait help line lsout tmp ls_line skip_lookback
+ local do_rare_genres read_wait line lsout tmp ls_line skip_lookback
local escape_char escaped_input expected_input skip_input_regex right_pad erasable_line seek_sec
local pl_state_path pl_state_dir pl_state_file tmpstr
local new_random pl_seed_path seed_num seed_file fmt first_play repeat1
@@ -1473,7 +1504,6 @@ btrbk-host-debug() {
# $ dig ns1.gnu.org @b0.org.afilias-nst.org.
-# todo: make sm pull/push use systemd instead of the journal cat command
bbk() { # btrbk wrapper
local ret=0
c /
@@ -1752,19 +1782,13 @@ bindpush() {
dsign iankelling.org expertpathologyreview.com zroe.org amnimal.ninja
lipush
for h in li bk; do
- m sl $h.b8.nz <<'EOF'
-source ~/.bashrc
-m dnsup
-EOF
+ m ssh $h.b8.nz dnsup
done
}
bindpushb8() {
lipush
for h in li bk; do
- m sl $h <<'EOF'
-source ~/.bashrc
-m dnsb8
-EOF
+ m ssh $h.b8.nz dnsb8
done
}
@@ -1775,8 +1799,18 @@ dnsup() {
dnsb8() {
local f=/var/lib/bind/db.b8.nz
m ser stop named
- m sleep 1
- m sudo rm -fv $f.jnl $f.signed.jnl
+ # jbk is like a temp file. dunno if removing it helps
+
+ i=0
+ while pgrep '^named$' &>/dev/null; do
+ sleep .5
+ i=$(( i + 1 ))
+ if (( i > 100 )); then
+ echo "dnsb8: error: timeout waiting for named to exit"
+ return 1
+ fi
+ done
+ m sudo rm -fv $f.jnl $f.signed.jnl $f.jbk
m sudo install -m 644 -o bind -g bind /p/c/machine_specific/vps/bind-initial/db.b8.nz $f
m ser restart named
}
@@ -1820,7 +1854,13 @@ dsign() {
# set day start for use in other programs.
# expected to do be in a format like 830, or 800 or 1300.
ds() {
+ local regex
+ regex='[0-9]?[0-9]?[0-9][0-9]'
if [[ $1 ]]; then
+ if [[ ! $1 =~ $regex ]]; then
+ echo "ds: error. expected \$1 to match $regex, got \$1: $1"
+ return 1
+ fi
echo $1 >/b/data/daystart
else
cat /b/data/daystart
@@ -1953,6 +1993,71 @@ capache()
fi
}
+
+
+apache-header() {
+ # First paragraph is to avoid people being confused about why a
+ # file is apache licensed.
+ cat <<'EOF'
+# I, Ian Kelling, follow the GNU license recommendations at
+# https://www.gnu.org/licenses/license-recommendations.en.html. They
+# recommend that small programs, < 300 lines, be licensed under the
+# Apache License 2.0. This file contains or is part of one or more small
+# programs. If a small program grows beyond 300 lines, I plan to change
+# to a recommended GPL license.
+
+# Copyright 2024 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
+
+}
+
+# apply apache to git tracked bash files + README, except files with A?GPL3 header.
+apache-apply-repo() {
+ for f in $(git ls-files); do
+ [[ -L $f || ! -f $f ]] && continue
+ if [[ $f != README ]]; then
+ if ! grep -n '^#!/bin/bash' $f | grep ^1: &>/dev/null; then continue; fi
+ if head -n 10 $f | grep 'it under the terms of the GNU General Public License as published by' &>/dev/null; then continue; fi
+ fi
+ apache-apply $f
+ done
+}
+
+apache-apply() {
+ for file; do
+ if head -n1 "$file"| grep -E '^#!/bin/bash\b' &>/dev/null; then
+ {
+ head -n1 "$file"
+ apache-header
+ tail -n+2 "$file"
+ } | sponge "$file"
+ else
+ {
+ apache-header
+ cat "$file"
+ } | sponge "$file"
+ fi
+ done
+}
+# strip out the apache license from a file.
+apache-strip() {
+ # shellcheck disable=SC2044 # meh
+ for f in $(find . -type f -maxdepth 1); do if head -n1 "$f"| grep -E '^#!/bin/bash\b' &>/dev/null; then { head -n 20 $f | tac | sed '/^# limitations under the License.$/,/^# Copyright.*Ian Kelling$/d' | tac; tail -n+21 $f; } |sponge $f; fi ; done
+}
+
chrome() {
if type -p chromium &>/dev/null; then
cmd=chromium
@@ -2240,8 +2345,8 @@ rename-test() {
# test whether missing files were renamed, generally for use with fsdiff
# $1 = fsdiff output file, $2 = directory to compare to. pwd = fsdiff dir
# echos non-renamed files
- local x y found
- unset sums
+ local x line found renamed
+ local -a sums
for x in "$2"/*; do
{ sums+=( "$(md5sum < "$x")" ) ; } 2>/dev/null
done
@@ -2293,8 +2398,8 @@ gup() { /a/f/gnulib/build-aux/gnupload "$@"; }
dejagnu() { /a/opt/dejagnu/dejagnu "$@"; }
+# do git status on published repos.
hstatus() {
- # do git status on published repos.
c /a/bin/githtml
for x in *; do
cd "$(readlink -f $x)"/..
@@ -2308,6 +2413,16 @@ hstatus() {
done
}
+hsk() {
+ local x
+ c /a/bin/githtml
+ for x in *; do
+ cd "$(readlink -f $x)"/..
+ skgit
+ cd /a/bin/githtml
+ done
+}
+
## work log
#
# note: database location is specified in ~/.timetrap.yml, currently /p/.timetrap.db
@@ -2457,15 +2572,21 @@ ilog-local() {
cd $d$n/"$chan"
hr
for x in *; do
- echo $x; sed "s/^./${x%log}/" $x; hr;
+ # *** are parts and joins and such, and they make reading hard.
+ # I probably will want to see them sometimes, just have to
+ # remove that part.
+ echo $x; sed "s/^./${x%log}/;/\*\*\*/d" $x; hr;
done
done
}
ilog() {
- local chan
+ local chan tmpf
+ tmpf=$(mktemp)
chan="${1:-#fsfsys}"
# use * instead of -r since that does sorted order
- sl root@iankelling.org ilog-local "$chan" | less +G
+ sl root@li.b8.nz ilog-local "$chan" > $tmpf
+ less +G $tmpf
+ rm -f $tmpf
}
o() {
@@ -2520,22 +2641,147 @@ wgkey() {
umask $umask_orig
}
-declare -A vpn_ips
-vpn_ips[kd]=2
-# note: 1, 4, 5 are occupied by mail wireguard
-vpn_ips[x3]=8
-vpn_ips[sy]=12
-vpn_ips[x2]=13
-vpn_ips[kw]=27
-vpn_ips[bo]=28
-vpn_ips[frodo]=34
-vpn_ips[s23b]=49
+host-info-all() {
+ host-info-update
+
+ bindpushb8
+ # for wireguard configs
+ ssh iank@li.b8.nz conflink
+ wrt-setup
+}
+
+
+
+
+
+## for updating host info like ip, location, update /p/c/host-info and
+## host_info below. the host_info array should probably be in its own
+## file that gets sourced so that it can be more easily updated.
+
+# todo: this is so long that it becomes confusing,
+# try to split it up.
+#
+# To make some changes take effect, run host-info-all.
+host-info-update() {
+
+ local -A vpn_ips host_ips host_macs portfw_ips nonvpn_ips all_ips
+ local -a root_hosts nonroot_hosts
+
+ # the hosts with no mac
+ root_hosts=( bk je li b8.nz )
+ for h in ${root_hosts[@]}; do
+ root_hosts+=(${h}ex)
+ done
+ root_hosts+=(cmc)
+
+ while read -r ip host mac opts; do
+ if [[ $ip == *#* || ! $host ]]; then continue; fi
+
+ # opt parsing
+ vpn=false
+ root=false
+ for opt in $opts; do
+ case $opt in
+ user=root)
+ root=true
+ ;;
+ vpn)
+ vpn=true
+ ;;
+ esac
+ done
+
+ all_ips[$host]=$ip
+ if $vpn; then
+ portfw_ips[$host]=$ip
+ vpn_ips[$host]=$ip
+ else
+ nonvpn_ips[$host]=$ip
+ fi
+ if $root; then
+ # note: the reason we have b8.nz suffix here but not for non_root
+ # hosts is that it is for the User part, the IdentityFile part is
+ # redundant to *.b8.nz. Also note ${host}i, we only setup those for vpn hosts, but there is no harm in overspecifying here.
+ root_hosts+=($host ${host}i $host.b8.nz ${host}i.b8.nz)
+ root_hosts_a[$host]=t # a for associative array
+ else
+ nonroot_hosts+=($host ${host}i)
+ fi
+ host_ips[$host]=$ip
+ if [[ $mac ]]; then
+ host_macs[$host]=$mac
+ fi
+
+ done
/p/c/cmc-firewall-data
+
-vpn-ips-update() {
local host ipsuf f files
+
+ # shellcheck disable=SC2016 # shellcheck doesnt know this is sed
+ sedi '/edits below here are made automatically/,$d' /p/c/machine_specific/li/filesystem/etc/wireguard/wgmail.conf
for host in ${!vpn_ips[@]}; do
+ if [[ ${root_hosts_a[$host]} ]]; then
+ # root machines dont actually need vpn, but
+ # the classification still helps with other
+ # configurations.
+ continue
+ fi
ipsuf=${vpn_ips[$host]}
wghole $host $ipsuf
+ u /b/ds/machine_specific/li/filesystem/etc/openvpn/client-config-hole/$host <$tmpf
+ cedit -e work-identity /p/c/subdir_files/.ssh/config-static <$tmpf
+ rm -f $tmpf
+
+ ### begin focus on hosts file update ###
+ #
+ # This started as its own function, but it actually
+ # needed to alter the ssh config, so combined it.
+ #
+ # background: This is finally doing dynamic ip resolution via the hosts
+ # file. I considered detecting where each host was dynamically or
+ # something, but ultimately decided to mostly avoid that, other than
+ # detecting the status of the current machine I'm on. I want to be able
+ # to move it around without having to manually type much of anything.
+ local -a host_domain_suffix hosts
+ local -A ip_to_hosts
+ local suf ip i host at_home suf_from_here
+
+ source /p/c/domain-info
+
+ at_home=false
+ if ip n | grep -q "10.2.0.1 .* b4:75:0e:fd:06:4a"; then
+ at_home=true
+ fi
+
+ for i in ${host_domain_suffix[@]}; do
+ if [[ $i == *.* ]]; then
+ suf=$i
+ continue
fi
+ hosts+=($i)
+ if [[ $i == "$HOSTNAME" ]]; then
+ unset "portfw_ips[$i]"
+ continue
+ fi
+
+ suf_from_here=$suf
+ if ! $at_home && [[ $suf == .b8.nz || $suf == [wc].b8.nz ]]; then
+ suf_from_here=i.b8.nz
+ else
+ unset "portfw_ips[$i]"
+ fi
+
+ ip=$(getent ahostsv4 "$i$suf_from_here" | awk '{ print $1 }' | head -n1) ||:
+ if [[ ! $ip ]]; then
+ if [[ $suf == .office.fsf.org ]]; then
+ suf_from_here=wg.b8.nz
+ ip=$(getent ahostsv4 "$i$suf_from_here" | awk '{ print $1 }' | head -n1) ||:
+ fi
+ if [[ ! $ip ]]; then
+ echo error: failed to get ip of "$i$suf_from_here"
+ return 1
+ fi
+ fi
+ ip_to_hosts[$ip]+=" $i"
done
+
+ for ip in "${!ip_to_hosts[@]}"; do
+ echo "$ip${ip_to_hosts[$ip]}"
+ done | s cedit -e hosts-file-up /etc/hosts
+ for host in ${hosts[@]}; do
+ echo $host
+ done | cedit -e /a/bin/ds/subdir_files/.dsh/group/btrbk
+ ### end focus on hosts file update ###
+
+
+ # note: note sure if this is a great way to check.
+ # todo: think about it
+
+ if $at_home; then
+ # possible that in the future we want to create
+ # a dynamic file here, and then we can move the cat
+ # command above out of the conditional
+ rsync -a /p/c/subdir_files/.ssh/config-static ~/.ssh/config
+ else
+ for host in ${!portfw_ips[@]}; do
+ ipsuf=${portfw_ips[$host]}
+ cat < ~/.ssh/config-dynamic
+ cat /p/c/subdir_files/.ssh/config-static ~/.ssh/config-dynamic >~/.ssh/config
+ fi
}
# usage host ipsuf [extrahost]
@@ -2842,7 +3202,7 @@ mdenable() {
two=false
case $1 in
- -2) two=true shift ;;
+ -2) two=true; shift ;;
esac
for md; do
@@ -2923,6 +3283,9 @@ mpvgpu() {
mpvd() {
mpv --profile=d "$@";
}
+mpva() {
+ mpv --profile=a "$@";
+}
# mpv all media files in . or $1
mpvm() {
local -a extensions arg
@@ -3402,8 +3765,6 @@ spd() {
}
spamf() { # spamtest on FILE
- local spamcpre spamdpid
-
if (( $# != 1 )); then
e spamtest error: expected 1 arg, filename >&2
return 1
@@ -4007,12 +4368,6 @@ vrun() {
"$@"
}
-f=/a/f/ansible-configs/files/common/etc/fsf-workstation-bashrc.sh
-if [[ -e $f ]]; then
- # shellcheck disable=SC1090
- source $f
-fi
-
electrum() {
# https://electrum.readthedocs.io/en/latest/tor.html
# https://github.com/spesmilo/electrum-docs/issues/129
@@ -4024,6 +4379,12 @@ monero() {
}
+# grep + find
+gef() {
+ faf | grep -E "$@" ||:
+ rgv "$@"
+}
+
# rg my main files
rgm() {
rg "$@" /p/w.org /a/t.org /a/work.org /b
@@ -4036,17 +4397,27 @@ rem() {
find $paths -not \( -name .svn -prune -o -name .git -prune \
-o -name .hg -prune -o -name .editor-backups -prune \
-o -name .undo-tree-history -prune \) 2>/dev/null | grep -iP --color=auto -- "$*" ||:
- rgv -- "$*" $paths /a/t.org /p/w.org /a/work.org ||:
+ rgv $local_rgv_args -g "!bash_unpublished" -- "$*" $paths /a/work.org ||:
}
-reml() { # with limit to 5 matches per file
+reml() { # rem with limit to 5 matches per file
+ local_rgv_args="-m 5"
+ rem "$@"
+}
+
+rep() {
local paths
- paths="/p/c /b"
+ paths="/p/c"
find $paths -not \( -name .svn -prune -o -name .git -prune \
-o -name .hg -prune -o -name .editor-backups -prune \
-o -name .undo-tree-history -prune \) 2>/dev/null | grep -iP --color=auto -- "$*" ||:
- rgv -m 5 -- "$*" $paths /a/t.org /p/w.org /a/work.org ||:
+ rgv $local_rgv_args -- "$*" $paths /a/t.org /p/w.org ||:
+}
+repl() { # rem with limit to 5 matches per file
+ local local_rgv_args="-m 5"
+ rem "$@"
}
+
# re on common fsf files
ref() {
local paths
@@ -4193,9 +4564,6 @@ mypyenvinit () {
}
-export GOPATH=$HOME/go
-path-add $GOPATH/bin
-path-add /usr/local/go/bin
# I have the git repo and a release. either one should work.
# I have both because I was trying to solve an issue that
@@ -4305,7 +4673,7 @@ hssh-update() {
case $HOSTNAME in
sy|kd)
hosts=(
- kd x3.office.fsf.org syw
+ kd.b8.nz x3.office.fsf.org syw x2.b8.nz
)
;;
x3)
@@ -4357,6 +4725,57 @@ 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'
+
+AuthType Basic
+AuthName "basic_auth"
+# created with
+# htpasswd -c icecast-fsf-htpasswd USERNAME
+AuthUserFile "/etc/icecast-fsf-htpasswd"
+Require valid-user
+
+
+AuthType Basic
+AuthName "basic_auth"
+AuthUserFile "/etc/icecast-fsf-tech-htpasswd"
+Require valid-user
+
+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=0; i