# See the License for the specific language governing permissions and
# limitations under the License.
+# shellcheck disable=SC2317
# to debug
#set -x
done
}
caf() {
-
local file
find -L "$@" -type f -not \( -name .svn -prune -o -name .git -prune \
-o -name .hg -prune -o -name .editor-backups -prune \
-o -name .undo-tree-history -prune \) -printf '%h\0%d\0%p\n' | sort -t '\0' -n \
| awk -F '\0' '{print $3}' 2>/dev/null | while read -r file; do
- hr
- printf "%s\n" "$file"
- hr
- cat "$file"
+ hr "$file"
+ v "$file"
done
}
ccomp cat cf caf
# horizontal row. used to break up output
hr() {
- local blocks
- # 180 is long enough.
- blocks=██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
- printf "%s\n" "$(tput setaf 5 2>/dev/null ||:)${blocks:0:${COLUMNS:-180}}$(tput sgr0 2>/dev/null||:)"
+ local start end end_count arg
+ # 180 is long enough. 5 for start.
+ start=█████ end=█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
+ end_count=$(( ${COLUMNS:-180} - 5 ))
+ arg="$*"
+ if [[ $arg ]]; then
+ end_count=$(( end_count - 2 - ${#arg} ))
+ start="$start $arg "
+ fi
+ if (( end_count >= 1 )); then
+ end=${end:0:$end_count}
+ else
+ end=
+ fi
+ printf "%s\n" "$(tput setaf 5 2>/dev/null ||:)$start$end$(tput sgr0 2>/dev/null||:)"
}
# highlight
hl() {
grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | uniq || [[ $? == 1 ]];
}
+# remove lines from history matching $1
+#
# todo: id like to do maybe a daily or hourly cronjob to
# check that my history file size is increasing. Ive had it
# inexplicably truncated in the past.
fi
x=$(ps -eF)
# final grep is because some commands tend to have a lot of trailing spaces
- y=$(echo "$x" | grep -iP "$@" | grep -o '.*[^ ]') ||:
+ y=$(echo "$x" | sed -r 's,//[^[:space:]:@/]+:[^[:space:]:@/]+@,//REDACTED_URL_USER@PASS/,g' | grep -iP "$@" | grep -o '.*[^ ]') ||:
if [[ $y ]]; then
echo "$x" | head -n 1 || [[ $? == 141 ]]
echo "$y"
shellcheck -W 999 -x -e $others "$@" || return $?
}
-# sk on all modified files in current git repo
+# sk on all modified & new files in current git repo. must git add for new files.
skmodified() {
local f
- for f in $(i s | awk '$1 == "modified:" {print $2}'); do
+ for f in $(i s | awk '$1 == "modified:" {print $2}; $1 == "new" {print $3}'); do
if sk-p "$f"; then
sk $f ||:
fi
for n in $numbers
do
- _spark_echo -n ${ticks[$(( (((n-min)<<8)/f) ))]}
+ _spark_echo -n ${ticks[$(( ((n-min)<<8)/f ))]}
done
_spark_echo
}
if [[ $HISTFILE ]]; then
history -a # save history
+ if [[ -e $HOME/.iank-stream-on ]]; then
+ if [[ $HISTFILE == $HOME/.bh ]]; then
+ ps_char="HISTP "
+ fi
+ elif [[ $HISTFILE == /a/bin/data/stream_hist ]]; then
+ ps_char="HISTS "
+ fi
fi
ps_color="$term_purple"
- ps_char='\$'
+ ps_char="$ps_char"'\$'
if [[ ! -O . ]]; then # not owner
if [[ -w . ]]; then # writable
ps_color="$term_bold$term_red"
fi
jobs_char=
if [[ $(jobs -p) ]]; then
- jobs_char='j\j '
+ jobs_char="$(jobs -p)"'j\j '
fi
room=${rooms[i]}
while read -r n; do
v=$((v+n))
+ # shellcheck disable=SC2004 # false positive
roomv[$i]=$(( ${roomv[$i]} + n ))
done < <(printf "%s\n" "$out" | grep -Po "$room.*?current[^0-9]*[0-9]*" | grep -o '[0-9]*$' )
done
command dsh -c "$@"
}
+# cat or bat with color if we have it
+v() {
+ if type -t batcat >/dev/null; then
+ # note: another useful useful style is "header"
+ batcat --color always --style plain --theme Coldark-Cold -P "$@"
+ else
+ cat "$@"
+ fi
+}
+
# * stuff that makes sense to be at the end
HISTFILE=
c() { cd "$@"; }
elif [[ $HISTFILE ]]; then
- HISTFILE=$HOME/.bh
+ # use an alternate history file when we are streaming.
+ if [[ -e $HOME/.iank-stream-on ]]; then
+ HISTFILE=/a/bin/data/stream_hist
+ else
+ HISTFILE=$HOME/.bh
+ fi
fi
+# history personal
+hip() {
+ history -c
+ HISTFILE=$HOME/.bh
+ history -r
+}
+
+# history for streaming
+his() {
+ history -c
+ HISTFILE=/a/bin/data/stream_hist
+ history -r
+}
+
+
source /a/bin/distro-setup/path-add-function
path-add /a/exe
# add this with absolute paths as needed for better security
# s sshfs bu@$host:/bu/home/md /bu/mnt -o reconnect,ServerAliveInterval=20,ServerAliveCountMax=30 -o allow_other
edelayoff() {
- echo all >/etc/exim4/no-delay-eximids
+ echo all >/var/spool/exim4/gw/.no-delay-eximids
+ if [[ $EUID == 0 ]]; then
+ chown iank:iank /var/spool/exim4/gw/.no-delay-eximids
+ fi
}
edelayon() {
- echo >/etc/exim4/no-delay-eximids
+ echo >/var/spool/exim4/gw/.no-delay-eximids
+ if [[ $EUID == 0 ]]; then
+ chown iank:iank /var/spool/exim4/gw/.no-delay-eximids
+ fi
}
eqgo() {
local p a
# excluding emacs for now
#p=(/a/opt/{emacs-debian11{,-nox},mu,emacs} /a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts})
- p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts} /c/roles/prom_export/files/simple/usr/local/bin/fsf-install-node-exporter /a/opt/fpaste)
+ p=(
+ /a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts}
+ /c/roles/prom_export/files/simple/usr/local/bin/fsf-install-node-exporter
+ /a/opt/fpaste
+ /p/c/user-specific/www-data/icecast-fsf{,-tech}-htpasswd
+ /p/c/icecast.xml
+ )
a="-ahviSAXPH --specials --devices --delete --relative --exclude-from=/p/c/li-rsync-excludes"
ret=0
for h in li je bk; do
dsign iankelling.org expertpathologyreview.com zroe.org amnimal.ninja
lipush
for h in li bk; do
- m ssh $h.b8.nz dnsup
+ m ssh iank@$h.b8.nz dnsup
done
}
bindpushb8() {
# 2023). However, in 2024-02, I ran a backup where a receiving machine
# had the wallet enabled and there was no error, so I don't know if this
# is still an issue or likely it is an inconsistent behavior.
+# Note: a pruned node won't allow for a wallet to be added, super lame
+# so i'm just not running a bitcoin node for now.
+# Error: Prune: last wallet synchronisation goes beyond pruned data. You
+# need to -reindex (download the whole blockchain again in case of
+# pruned node)
#
-# As a workaround, this function is for enabling the wallet when I want
-# to use it and leave it disabled otherwise.
-walleton() {
- local active
- active=false
- no_on=true
- if [[ ! $(readlink -f /var/lib/bitcoind/wallets) == /q/wallets ]]; then
- if systemctl --quiet is-active bitcoind; then
- if [[ -e /tmp/no-bitcoinon ]]; then
- no_on=true
- else
- if [[ $EUID == 0 ]]; then
- m install -T -o iank -g iank /dev/null /tmp/no-bitcoinon
- else
- m touch /tmp/no-bitcoinon
- fi
- fi
- active=true
- m ser stop bitcoind
- fi
- m s ln -s /q/wallets /var/lib/bitcoind
- sudo chown -h bitcoin:bitcoin /var/lib/bitcoind/wallets
- if $active; then
- m ser start bitcoind
- if ! $no_on; then
- m rm /tmp/no-bitcoinon
- fi
- fi
- fi
-}
-walletoff() {
- local active
- active=false
- no_on=true
- if [[ $(readlink -f /var/lib/bitcoind/wallets) == /q/wallets ]]; then
- if systemctl --quiet is-active bitcoind; then
- if [[ -e /tmp/no-bitcoinon ]]; then
- no_on=true
- else
- if [[ $EUID == 0 ]]; then
- m install -T -o iank -g iank /dev/null /tmp/no-bitcoinon
- else
- m touch /tmp/no-bitcoinon
- fi
- fi
- active=true
- m ser stop bitcoind
- else
- echo note: bitcoind not active
- fi
- m rm /var/lib/bitcoind/wallets
- if $active; then
- # note, starting bitcoin always fails, but it actually
- # succeeds. But this is strangely not consistent.
- m ser start bitcoind
- if ! $no_on; then
- m rm /tmp/no-bitcoinon
- fi
- fi
- fi
-}
#### end bitcoin related things
kdecd() { /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd; }
-bat() {
+batp() {
cat /sys/class/power_supply/BAT0/capacity
}
# 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)
+ # shellcheck disable=SC2004 # false positive
root_hosts_a[$host]=t # a for associative array
else
nonroot_hosts+=($host ${host}i)
b8_ip=$(dig +short b8.nz @iankelling.org | tail -1)
+ # if our dynamic ip updates broke, set manually, eg:
+ #b8_ip=72.74.193.xxx
if [[ ! $b8_ip ]]; then
echo "$0: error: got empty b8.nz ip. returning 1"
return 1
fi
{
- echo "@ A $b8_ip"
+ cat <<EOF
+@ A $b8_ip
+i A $b8_ip
+EOF
for host in ${!nonvpn_ips[@]}; do
ipsuf=${nonvpn_ips[$host]}
echo "$host A 10.2.0.$ipsuf"
${host}wg A 10.8.0.$ipsuf
${host}vp A 10.5.5.$ipsuf
${host}tr A 10.174.$ipsuf.2
-${host}i A $b8_ip
+${host}i CNAME i.b8.nz.
EOF
done
} | cedit -e vpn-ips-update /p/c/machine_specific/vps/bind-initial/db.b8.nz
unset "portfw_ips[$i]"
fi
- ip=$(getent ahostsv4 "$i$suf_from_here" | awk '{ print $1 }' | head -n1) ||:
+ # note this might be outdated until we do a dns push
+ ip=$(dig +short "$i$suf_from_here" @iankelling.org | tail -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"
+ if [[ $ip ]]; then
+ ip_to_hosts[$ip]+=" $i"
+ else
+ echo error: failed to get ip of "$i$suf_from_here"
+ fi
done
for ip in "${!ip_to_hosts[@]}"; do
chmod +x $out
}
-smeld() { # ssh meld usage host1 host2 file
+# ssh meld. usage: host1 host2 file
+smeld() {
meld <(ssh $1 cat $3) <(ssh $2 cat $3)
}
+# remote file meld
+# usage: host file1 file2
+rmeld() {
+ local tmpdir
+ tmpdir=$(mktemp -d)
+ scp "$1:$2" "$1:$3" $tmpdir
+ meld "$tmpdir/${2##*/}" "$tmpdir/${3##*/}"
+}
+
+
spd() {
PATH=/usr/local/spdhackfix:$PATH command spd "$@"
}
s nmtui-connect "$@"
}
+# check exim and others network namespace
mailnncheck() {
- local unit pid ns mailnn
+ local unit pid ns mailnn spamd_ser
+
+ spamd_ser=spamd
+ if systemctl cat spamassassin &>/dev/null; then
+ spamd_ser=spamassassin
+ fi
+
# mailvpn would belong on the list if using openvpn
- for unit in mailnn unbound dovecot spamassassin exim4 radicale; do
+ for unit in mailnn unbound dovecot $spamd_ser exim4 radicale; do
pid=$(servicepid $unit)
echo debug: unit=$unit pid=$pid
if [[ ! $pid ]]; then
}
electrum() {
+ # Running the appimage said fuse was not available, but try
+ # running the appimage with --appimage-extract, which worked.
+ # It seems there is no need to backup the wallet, it can be restored
+ # via the seed onto any computer that needs it.
+ /a/opt/electrum/squashfs-root/AppRun "$@"
+
+
+ # This was an old way I ran electrum over tor, and seems like I
+ # imported a bitcoin core wallet.
+ #
# https://electrum.readthedocs.io/en/latest/tor.html
# https://github.com/spesmilo/electrum-docs/issues/129
- s rsync -ptog --chown bitcoin:bitcoin ~/.Xauthority /var/lib/bitcoind/.Xauthority
- sudo -u bitcoin DISPLAY=$DISPLAY XAUTHORITY=/var/lib/bitcoind/.Xauthority /a/opt/electrum-4.2.1-x86_64.AppImage -p socks5:localhost:9050
+ # s rsync -ptog --chown bitcoin:bitcoin ~/.Xauthority /var/lib/bitcoind/.Xauthority
+ # sudo -u bitcoin DISPLAY=$DISPLAY XAUTHORITY=/var/lib/bitcoind/.Xauthority /a/opt/electrum-4.2.1-x86_64.AppImage -p socks5:localhost:9050
+
}
+
+
monero() {
sudo -u bitcoin DISPLAY=$DISPLAY XAUTHORITY=/var/lib/bitcoind/.Xauthority /a/opt/monero-gui-v0.17.3.2/monero-wallet-gui
}
rg "$@" /p/w.org /a/t.org /a/work.org /b
}
-# re all my files more expansively
+# re all my files more expansively.
+# usage [-OPT...] regex space combined
rem() {
local paths
+ local -a opts
+ for arg; do
+ if [[ $arg == -* ]]; then
+ opts+=("$1")
+ shift
+ else
+ break
+ fi
+ done
paths="/p/c /b/"
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 $local_rgv_args -g "!bash_unpublished" -- "$*" $paths /a/work.org ||:
+ rgv $local_rgv_args -g "!bash_unpublished" "${opts[@]}" -- "$*" $paths /a/work.org ||:
}
reml() { # rem with limit to 5 matches per file
local_rgv_args="-m 5"
ffg() { /nocow/t/ffmpeg-release/ffmpeg-7.0.1/tools/graph2dot -o /tmp/g.tmp && dot -Tpng /tmp/g.tmp -o /tmp/g.png && feh /tmp/g.png; }
+firefox-hide-tabs() {
+
+ # without this, make tabs smaller by setting browser.uidensity 1 in about:config
+
+ profiledir=$1
+ [[ $1 ]] || return 1
+ # Related: the sidebery extension is useful.
+
+ # This is from
+ # https://raw.githubusercontent.com/MrOtherGuy/firefox-csshacks/master/chrome/hide_tabs_toolbar.css
+
+ ainsl $profiledir/chrome/userChrome.css '#TabsToolbar{ visibility: collapse !important }'
+
+}
+
+# kill lease on cmc
+klease() {
+ local tmpdir ret out
+ ret=0
+ out=$(ssh cmc dnsmasq-end-lease "$1" 2>&1) || ret=1
+ printf "%s\n" "$out"
+ if [[ $out == *"try diffing"* ]]; then
+ tmpdir=$(mktemp -d)
+ m scp cmc:/tmp/dhcp.leases cmc:/tmp/dhcp.leases.iank $tmpdir
+ m diff $tmpdir/dhcp.leases $tmpdir/dhcp.leases.iank ||:
+ rm -rf $tmpdir
+ fi
+ return $ret
+}
+
+# ffs and switch the bash history on this terminal.
+ffs() {
+ local last
+ last="${*: -1}"
+ if [[ $last && $last != -* && $last != sysops ]]; then
+ his
+ fi
+ command ffs "$@"
+}
+
+i3gen() {
+ /b/ds/i3-sway/gen
+}
+
export BASEFILE_DIR=/a/bin/fai-basefiles
#export ANDROID_HOME=/a/opt/android-home
if [[ -e /var/lib/znc ]] && getent group znc; then
s chown -R znc:znc /var/lib/znc
fi
- if [[ -e /p/c/user-specific ]]; then
+ if [[ -e /p/c/user-specific/prometheus ]]; then
if getent passwd prometheus &>/dev/null; then
v s rsync -clpgoDiSAX --chmod=Dg-s --chown=root:prometheus /p/c/user-specific/prometheus/prometheus-pass /etc
v s rsync -clpgoDiSAX --chmod=Dg-s --chown=root:prometheus /p/c/user-specific/prometheus/prometheus/ssl/* /etc/prometheus/ssl
fi
+ fi
+ if [[ -e /p/c/user-specific/www-data ]]; then
if getent passwd www-data &>/dev/null; then
v s rsync -clpgoDiSAX --chmod=Dg-s --chown=root:www-data /p/c/user-specific/www-data/* /etc
fi
fi
- if [[ -d /var/lib/bitcoind && -d /p/c/user-specific/bitcoin ]]; then
- s rsync -clpgoDiSAX --chmod=Dg-s --chown=bitcoin:bitcoin /p/c/user-specific/bitcoin/settings.json /var/lib/bitcoind
- s rsync -rclpgoDiSAX --chmod=Dg-s --chown=root:bitcoin /p/c/user-specific/bitcoin/bitcoin /etc
- fi
+ # disabled
+ # if [[ -d /var/lib/bitcoind && -d /p/c/user-specific/bitcoin ]]; then
+ # s rsync -clpgoDiSAX --chmod=Dg-s --chown=bitcoin:bitcoin /p/c/user-specific/bitcoin/settings.json /var/lib/bitcoind
+ # s rsync -rclpgoDiSAX --chmod=Dg-s --chown=root:bitcoin /p/c/user-specific/bitcoin/bitcoin /etc
+ # fi
+
# this folder strangely requires ownership as icecast2
if [[ -d /etc/icecast2 && -f /p/c/icecast.xml ]]; then
m s rsync -rclgoDiSAX --chmod=0644 --chown=root:root /p/c/icecast.xml /etc/icecast2
--- /dev/null
+#!/bin/bash
+# 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.
+
+
+copyqcount=$(copyq count)
+regex='^[1-9][0-9]*$'
+if [[ ! $copyqcount =~ $regex ]]; then
+ exit 0
+fi
+
+echo "######## begin clipboard history ########"
+for ((i=0; i<copyqcount; i++)); do
+copyq read $i
+ echo -n "$i "; done)
+echo "######## press x or enter to clear clipboard history. global key is super-y ########"
+read -rsN1 -t 10 input
+if [[ ! $input || $input == x ]]; then
+ echo "running copyq-restart"
+ copyq-restart
+ sleep 1
+fi
--- /dev/null
+#!/bin/bash
+# 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.
+
+if pkill -f '^copyq$'; then
+ gone=false
+ for (( i=0; i<10; i++ )); do
+ sleep .2
+ if ! pgrep '^copyq$'; then
+ gone=true
+ break
+ fi
+ done
+ fi
+if ! $gone; then
+ i3-nagbar -m "FAILED TO KILL COPYQ" -t error -f "pango:monospace 30"
+ exit 1
+fi
+
+copyq &
####### begin setup environment #######
+# shellcheck disable=SC2317 # false positive
### make ssh interactive shell run better. for when running line interactively line by line
sudo bash -c '/a/exe/ssh-emacs-setup' || exit $?
err-catch
$interactive || set -x
-##### use systemd-resolved for glibc resolutions
-
-pi libnss-resolve
-
-if [[ ! -L /etc/nsswitch.conf ]]; then
- sudo mkdir -p /etc/resolved-nsswitch
- sudo mv /etc/nsswitch.conf /etc/resolved-nsswitch
- sudo ln -sf /etc/resolved-nsswitch/nsswitch.conf /etc
-fi
-
-f=/etc/basic-nsswitch/nsswitch.conf
-if [[ ! -e $f ]]; then
- sudo mkdir -p ${f%/*}
- sudo cp /etc/nsswitch.conf $f
- sudo sed -i --follow-symlinks 's/^ *hosts:.*/hosts: files dns myhostname/' $f
-fi
-case $HOSTNAME in
- bk|je)
- # je should be able to get along systemd-resolved, but ive had some odd
- # very intermittent dns failures with spamassassin, it seems it might only
- # be happening with systemd-resolved, so just use unbound
- # to make it consistent with the other hosts.
- sudo sed -i --follow-symlinks 's/^ *hosts:.*/hosts: files dns myhostname/' /etc/nsswitch.conf
- soff systemd-resolved
- sudo ln -sf 127.0.0.1-resolv/stub-resolv.conf /etc/resolv.conf
- sgo unbound
- # cautious measure to make sure resolution is working
- sleep 1
- ;;
- *)
- # default is
- # files mdns4_minimal [NOTFOUND=return] dns myhostname
- # mdns4 is needed for my printer and for bbb webrtc, not sure exactly why.
- # https://www.freedesktop.org/software/systemd/man/nss-resolve.html#
- # seems more important than some potential use case.
- # Interestingly, t9/t10 man page says use files before resolve, debian 10 says the opposite.
- # removing files makes hostname -f not actually give the fully qualified domain name.
- sudo sed -i --follow-symlinks 's/^ *hosts:.*/hosts: files resolve [!UNAVAIL=return] mdns4_minimal [NOTFOUND=return] myhostname/' /etc/resolved-nsswitch/nsswitch.conf
- ;;
-esac
-
-case $HOSTNAME in
- bk)
- sgo named
- ;;
-esac
-
-
-lines=(
- "/etc/resolved-nsswitch/nsswitch.conf r,"
- "/etc/basic-nsswitch/nsswitch.conf r,"
- # Aug 06 23:09:11 kd audit[3995]: AVC apparmor="DENIED" operation="connect" profile="/usr/bin/freshclam" name="/run/systemd/resolve/io.systemd.Resolve" pid=3995 comm="freshclam" requested_mask="wr" denied_mask="wr" fsuid=109 ouid=101
- # I dont know if this is quite the right fix, but I saw other sockets
- # in the nameservice files that were rw, so figured it was ok to add this and it worked.
- "/run/systemd/resolve/io.systemd.Resolve rw,"
-)
-f=/etc/apparmor.d/abstractions/nameservice
-apparmor_reload=false
-if [[ -e $f ]]; then
- for l in "${lines[@]}"; do
- if ! grep -qF "$l" $f; then
- sudo sed -i "/\/nsswitch.conf/a $l" $f
- apparmor_reload=true
- if ! grep -qF "$l" $f; then
- echo "$0: failed editing $f. investigate"
- exit 1
- fi
- fi
- done
- if $apparmor_reload && systemctl is-active apparmor; then
- m ser reload apparmor
- fi
-fi
-
if dpkg -s -- nscd &>/dev/null; then
######## fix evbug bug ######
case $(debian-codename-compat) in
- xenial|bionic|focal|jammy)
+ xenial|bionic|focal|jammy|noble)
# noticed in flidas. dunno if it affects any others
#https://bugs.launchpad.net/ubuntu/+source/module-init-tools/+bug/240553
#https://wiki.debian.org/KernelModuleBlacklisting
# SPDX-License-Identifier: GPL-3.0-or-later
+# shellcheck disable=SC2317 # false positive
export LC_USEBASHRC=t
source /a/bin/ds/.bashrc
rm -rf $tmpdir
fi
- if [[ ! -e /usr/share/debootstrap/scripts/bookworm ]]; then
+ if [[ ! -e /usr/share/debootstrap/scripts/noble ]]; then
t=$(mktemp -d)
cd $t
- m aptitude download debootstrap/bookworm
+ m aptitude download debootstrap/noble
m ex ./*
sudo cp ./usr/share/debootstrap/scripts/* /usr/share/debootstrap/scripts
fi
# Pin-Priority: 1001
# EOF
#
- # TODO: I had to uninstall linux-image-generic-hwe-20.04 because of a conflict
- # about linux-firmware. Should probably install it to begin with in fai if
- # i'm going to use.
- pi system76-driver system76-firmware
+ # s fwupdmgr get-updates
+ # says I have 3 "devices with no available firmware updates"
+ # if there were updates, install with: s fwupdmgr update
+ pi system76-firmware system76-driver fwupd
+ # system76-driver: on a modern kernel, it seems to mainly just do
+ # some power settings, I haven't looked entirely through it. it
+ # might also change fan speed. Of its recommended packages,
+ # system76-power is the only one I haven't looked at, the others
+ # do nothing for laptops i have. they have models hardcoded in
+ # source, so you can just grep for it. pkx package; caf | less.
+ #
# if you get a notice about a firmware update, the notifier on i3
- # is too dumb to do anything when you click it. so to see
- # a changelog, cd to
+ # is too dumb to do anything when you click it.
+ # to manually get new firmware,
+ # system76-firmware-cli schedule --open
+ # to see a changelog, cd to
# /var/cache/system76-firmware-daemon
# extract the xz files there, one will contain a changelog.
# then to install an update:
# box type: scale to width of bounds. alignment in bounding box:
# bottom left. bounding box size 1920 x 1080.
- # ppa:obsproject/obs-studio
- if [[ ! -s /etc/apt/sources.list.d/obs.list ]]; then
- # https://blog.zackad.dev/en/2017/08/17/add-ppa-simple-way.html
- sd /etc/apt/sources.list.d/obs.list <<EOF
+ # as of 2024-06, noble repo doesn't exist yet
+ if [[ $codename_compat != noble ]]; then
+ # ppa:obsproject/obs-studio
+ if [[ ! -s /etc/apt/sources.list.d/obs.list ]]; then
+ # https://blog.zackad.dev/en/2017/08/17/add-ppa-simple-way.html
+ sd /etc/apt/sources.list.d/obs.list <<EOF
deb http://ppa.launchpad.net/obsproject/obs-studio/ubuntu $codename_compat main
deb-src http://ppa.launchpad.net/obsproject/obs-studio/ubuntu $codename_compat main
EOF
- trysleep 4 15 s apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BC7345F522079769F5BBE987EFC71127F425E228
- p update
+ trysleep 4 15 s apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BC7345F522079769F5BBE987EFC71127F425E228
+ p update
+ fi
fi
;;
jammy)
# not yet bothering with mate
pi lightdm-gtk-greeter lightdm
+ case $HOSTNAME in
+ sy|bo)
+ # todo: try removing this. also, see if system76-driver fixes this.
+
+ # on newer laptop, this config makes xorg load an intel module
+ # in Xorg.0.log and display nothing. background:
+ #
+ # I dropped lightdm as I was trying to figure this out, why xorg was
+ # displaying nothing. I did a diff of a working Xorg.0.log from a
+ # popos is, which is in ~/.local/share/xorg/Xorg.0.log if it runs as
+ # a regular user. I noticed 2 differences, on the failing one it was
+ # loading the intel xorg module. On the successful one, it had a
+ # line systemd-logind: got fd for /dev/dri/card1 226:1, on the
+ # failing one it had a line about systemd-logind not knowing the
+ # seat or session or something. There was no search results about
+ # that, switching to xinit made that go away. Note: gpg-agent seems
+ # to be working ok as an ssh agent. xsession has an option
+ # use-ssh-agent but perhaps it decides to leave gpg agent in charge.
+ cat >/etc/X11/xorg.conf.d/20-intel.conf <<'EOF'
+# iank:
+# https://forums.linuxmint.com/viewtopic.php?f=208&t=224942#p1197049
+# prevents konsole from being borderline unusable on system76 intel graphics + i3
+Section "Device"
+ Identifier "Intel Graphics"
+ Driver "intel"
+ Option "TearFree" "true"
+EndSection
+EOF
+ ;;
+ esac
+ ;;
+ noble)
+ pi xinit
;;
esac
esac
;;
ubuntu)
+ case $codename in
+ noble)
+ # mint firefox has a dependency which is totally not really
+ # needed, just some mint branding and maybe a random firefox
+ # setting.
+ tmpdir="$(mktemp -d)"
+ cd "$tmpdir"
+ # edited from output of equivs-control ubuntu-system-adjustments
+ cat >ubuntu-system-adjustments <<'EOF'
+Section: misc
+Priority: optional
+Version: 2030
+Standards-Version: 3.9.2
+Package: ubuntu-system-adjustments
+Description: ubuntu-system-adjustments-dummy
+EOF
+ equivs-build ubuntu-system-adjustments
+ sudo dpkg -i ubuntu-system-adjustments_2030_all.deb
+ rm -rf ./ubuntu-system-adjustments*
+ cd
+ rm -r "$tmpdir"
+ ;;
+ esac
pi firefox
;;
debian)
esac
+case $codename_compat in
+ aramo|buster)
+ # https://wiki.archlinux.org/title/bluetooth
+ pi pavucontrol paprefs pulseaudio-module-bluetooth pulsemixer
+ ;;
+ noble|bookworm)
+ pi pipewire-audio
+ # having pipewire installed prevents the recommends in these from installing pulse
+ pi pulsemixer pavucontrol
+ ;;
+esac
+
+
# TODO: some of the X programs can be removed from pall when using wayland
# depends gcc is a way to install suggests. this is apparently the only
# I dont want that.
pi-nostart schroot
+## note: this bug doesn't exist in t12+
# fix systemd unit failure. i dont know of any actual impact
# other than systemd showing in degraded state. So, we dont bother
# fixing the current state, let it fix on the next reboot.
# https://gitlab.com/cjwatson/binfmt-support/-/commit/54f0e1af8a
-tmp=$(systemctl cat binfmt-support.service | grep ^After=)
-if [[ $tmp != *systemd-binfmt.service* ]]; then
- s u /etc/systemd/system/binfmt-support.service.d/override.conf <<EOF
+if pcheck binfmt-support; then
+ tmp=$(systemctl cat binfmt-support.service | grep ^After=)
+ if [[ $tmp != *systemd-binfmt.service* ]]; then
+ s u /etc/systemd/system/binfmt-support.service.d/override.conf <<EOF
[Unit]
$tmp systemd-binfmt.service
EOF
+ fi
fi
-
# commented, not worth the hassle i think.
#seru enable psd
#seru start psd
# it asks if it should make users in it's group capture packets without root,
# which is arguably more secure than running wireshark as root. default is no,
# which is what i prefer, since I plan to use tcpdump to input to wireshark.
-s DEBIAN_FRONTEND=noninteractive pi wireshark-gtk
+# note: t10 called this wireshark-gtk, i don't care about t10 anymore.
+s DEBIAN_FRONTEND=noninteractive pi wireshark
# /run and /dev/shm are listed as required for pulseaudio. All 4 in the group
# listed in the default config as suggested.
########### misc stuff
-xdg-settings set default-web-browser abrowser.desktop
# see current with:
# xdg-settings get default-web-browser
+# not sure this is needed. will add other distros if necessary
+case $distro in
+ trisquel)
+ xdg-settings set default-web-browser abrowser.desktop
+ ;;
+esac
+
# pressing tab after sdf here:
# scp sdfbash: set +o noglob: command not found
rm -fv /home/iank/.mpv/watch_later
rm -rf /home/iank/.mpv
-if [[ ! -e ~/.local/bin/pip ]]; then
- tmp=$(mktemp)
- wget -O$tmp https://bootstrap.pypa.io/get-pip.py
- python3 $tmp --user
- hash -r
-fi
+# apparently pip is deprecated in debian. try venv or pipx.
+## begin u24 message upon pip install
+# If you wish to install a non-Debian-packaged Python package,
+# create a virtual environment using python3 -m venv path/to/venv.
+# Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
+# sure you have python3-full installed.
+
+# If you wish to install a non-Debian packaged Python application,
+# it may be easiest to use pipx install xyz, which will manage a
+# virtual environment for you. Make sure you have pipx installed.
+
+# See /usr/share/doc/python3.12/README.venv for more information.
+## end
+
+# if [[ ! -e ~/.local/bin/pip ]]; then
+# tmp=$(mktemp)
+# wget -O$tmp https://bootstrap.pypa.io/get-pip.py
+# python3 $tmp --user
+# hash -r
+# fi
+
## begin beets
# soo, apt install beets fails due to wanting a pip package,
# as of 2023-02, the tox dependency was removed in debian unstable, so
# this hack will probably go away in t12.
-if pcheck beets; then
- tmpdir="$(mktemp -d)"
- cd "$tmpdir"
- # edited from output of equivs-control tox
- cat >tox <<'EOF'
+case $(debian-codename) in
+ aramo)
+ tmpdir="$(mktemp -d)"
+ cd "$tmpdir"
+ # edited from output of equivs-control tox
+ cat >tox <<'EOF'
Section: python
Priority: optional
Standards-Version: 3.9.2
Package: tox
Description: tox-dummy
EOF
- equivs-build tox
- sudo dpkg -i tox_1.0_all.deb
- rm -rf ./tox*
- pi beets python3-discogs-client
- cd
- rm -r "$tmpdir"
-fi
+ equivs-build tox
+ sudo dpkg -i tox_1.0_all.deb
+ rm -rf ./tox*
+ pi beets python3-discogs-client
+ cd
+ rm -r "$tmpdir"
+ ;;
+esac
# get rid of annoying message
s sed -ri "s/^([[:space:]]*ui.print_\('Playing)/#\1/" /usr/share/beets/beetsplug/play.py
# Font awesome is needed for the alertmanager ui.
pi prometheus-alertmanager prometheus fonts-font-awesome
/c/roles/prom/files/simple/usr/local/bin/fsf-install-prometheus
+
# make it available for other machines
rsync -a /usr/local/bin/amtool /a/opt/bin
web-conf -p 9091 -f 9090 - apache2 b8.nz <<'EOF'
;;
esac
-# cleanup old files. 2023-02
-x=(/var/lib/prometheus/node-exporter/*.premerge)
-if [[ -e ${x[0]} ]]; then
- s rm /var/lib/prometheus/node-exporter/*
+# user specific file isn't installed until the user exists
+if [[ ! -e /etc/prometheus/ssl/prom_node_key.pem ]]; then
+ conflink
fi
### end prometheus ###
-### begin bitcoin ###
-
-case $HOSTNAME in
- sy|kd|so)
- sudo install -m 0755 -o root -g root -t /usr/bin /a/opt/bitcoin-27.0/bin/*
- # Note: i leave it to system-status to start and stop bitcoin.
- # note: the bitcoin user & group are setup in fai
- sudo usermod -a -G bitcoin iank
- # todo: make bitcoin have a stable uid/gid
- sudo mkdir -p /var/lib/bitcoind
- sudo chown bitcoin:bitcoin /var/lib/bitcoind
- # 710 comes from the upstream bitcoin unit file
- sudo chmod 710 /var/lib/bitcoind
- # note, there exists
- # /a/bin/ds/disabled/bitcoin
- ;;
-esac
+# disabled
+# ### begin bitcoin ###
+
+# case $HOSTNAME in
+# sy|kd|so)
+# sudo install -m 0755 -o root -g root -t /usr/bin /a/opt/bitcoin-27.0/bin/*
+# # Note: i leave it to system-status to start and stop bitcoin.
+# # note: the bitcoin user & group are setup in fai
+# sudo usermod -a -G bitcoin iank
+# # todo: make bitcoin have a stable uid/gid
+# sudo mkdir -p /var/lib/bitcoind
+# sudo chown bitcoin:bitcoin /var/lib/bitcoind
+# # 710 comes from the upstream bitcoin unit file
+# sudo chmod 710 /var/lib/bitcoind
+# # note, there exists
+# # /a/bin/ds/disabled/bitcoin
+# ;;
+# esac
-### end bitcoin
+# ### end bitcoin
### begin live streaming ###
sudo exportfs -rav
fi
+# very temporary fix.
+# should be gone in a few days
+# https://bugs.launchpad.net/ubuntu/+source/fail2ban/+bug/2055114
+case $codename_compat in
+ noble)
+ if [[ ! -e ~/fail2ban_1.1.0-1_all.deb ]]; then
+ cd
+ wget https://launchpad.net/ubuntu/+source/fail2ban/1.1.0-1/+build/28291332/+files/fail2ban_1.1.0-1_all.deb
+ sudo dpkg -i fail2ban_1.1.0-1_all.deb
+ fi
+ ;;
+esac
+
+case $codename_compat in
+ noble)
+ # this fails on startup. i don't use resolvconf, so it is totally pointless.
+ soff unbound-resolvconf.service
+ ;;
+esac
+
+host-info-update
# if I was going to create a persistent vm, i might do it like this:
# variant=something # from: virt-install --os-variant list
fi
}
+spamd_ser=spamd
+if systemctl cat spamassassin &>/dev/null; then
+ spamd_ser=spamassassin
+fi
+
pl=/var/log/exim4/paniclog
main() {
jmax="$(date -d @$sec_max "+%F %H:%M:%S")"
description=$(systemctl cat $service | sed -rn 's/^ *Description=(.*)/\1/p')
jrregex="^Starting $description"
- if [[ $service == spamassassin ]]; then
+ if [[ $service == "$spamd_ser" ]]; then
jrregex+="\|^spamd: restarting"
fi
d "jrregex=$jrregex jmin=$jmin jmax=$jmax"
sed -ri "/$regex/d" $pl
fi
fi
- done <<'EOF'
+ done <<EOF
clamav-daemon malware acl condition
-spamassassin spam acl condition
+$spamd_ser spam acl condition
EOF
### end removing panic lines due to service restarts ###
# limitations under the License.
-volume=0
-# 3 mountpoints: fsf-sysops (default, public), fsf (all staff), fsf-tech (tech team)
-# # note: duplicated in ffp
-mount_suffix=-sysops
-while [[ $1 ]]; do
+usage() {
+ cat <<EOF
+Usage: ${0##*/} [-d] [sysops|tech|staff]
+3 mountpoints: fsf-sysops (default, public), fsf (all staff), fsf-tech (tech team)
+
+-d debug. start unmuted.
+
+note: args duplicated in ffp
+
+
+
+-h|--help Print help and exit.
+
+Note: Uses util-linux getopt option parsing: spaces between args and
+options, short options can be combined, options before args.
+EOF
+ exit $1
+}
+
+##### begin command line parsing ########
+
+# ensure we can handle args with spaces or empty.
+ret=0; getopt -T || ret=$?
+[[ $ret == 4 ]] || { echo "Install util-linux for enhanced getopt" >&2; exit 1; }
+
+volume=0
+temp=$(getopt -l help hdw "$@") || usage 1
+eval set -- "$temp"
+while true; do
case $1 in
- sysops|tech)
- mount_suffix=-$1
- ;;
- staff)
- mount_suffix=
- ;;
- -d)
- volume=100
- ;;
+ -d) volume=100 ;;
+ -h|--help) usage ;;
+ --) shift; break ;;
+ *) echo "$0: unexpected args: $*" >&2 ; usage 1 ;;
esac
shift
done
+mount_suffix=-sysops
+case $1 in
+ sysops|tech)
+ mount_suffix=-$1
+ ;;
+ staff)
+ mount_suffix=
+ ;;
+esac
+
+##### end command line parsing ########
+
+
+
+host=live.iankelling.org:8000
+if ip n show 10.2.0.1 | grep . &>/dev/null && \
+ [[ $(dig +timeout=1 +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]]; then
+ host=127.0.0.1:8000
+fi
+
opts=(
-v error
-hide_banner
-fast
-fflags nobuffer
-flags low_delay
- -i http://localhost:8000/fsf$mount_suffix.webm
+ -i http://$host/fsf$mount_suffix.webm
-autoexit
)
ffplay "${opts[@]}"
# todo: learn to start working in one corner of the screen.
-# todo: get an icecast on li.b8.nz for when i'm away from home.
-
# potential improvement: it might be nice that we could have a tall terminal bug only use
# the top half for a 1080p stream, this is how:
# https://superuser.com/questions/1106674/how-to-add-blank-lines-above-the-bottom-in-terminal
set -eE -o pipefail
trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
+usage() {
+ cat <<EOF
+Usage: ${0##*/} [OPTIONS] [sysops|tech|staff]
+3 mountpoints: fsf-sysops (default, public), fsf (all staff), fsf-tech (tech team)
+
+-d debug.
+-f Stream full screen even high resolution.
+-t Stream tall half screen
+-u Undelayed. Removes 5 second video delay, and about 4 second audio delay.
+-w do not launch watch of stream
+
+note: args duplicated in ffp
+
+
+-h|--help Print help and exit.
+Note: Uses util-linux getopt option parsing: spaces between args and
+options, short options can be combined, options before args.
+EOF
+ exit $1
+}
+
+##### begin command line parsing ########
+
+# ensure we can handle args with spaces or empty.
+ret=0; getopt -T || ret=$?
+[[ $ret == 4 ]] || { echo "Install util-linux for enhanced getopt" >&2; exit 1; }
+
+ffp_args=()
debug=false
+delay=true
loglevel=fatal
-
-# 3 mountpoints: fsf-sysops (default, public), fsf (all staff), fsf-tech (tech team)
-# # note: duplicated in ffp
-mount_suffix=-sysops
-while [[ $1 ]]; do
+watch=true
+fullscreen=false
+tall=false
+temp=$(getopt -l help hdftuw "$@") || usage 1
+eval set -- "$temp"
+while true; do
case $1 in
- sysops|tech)
- mount_suffix=-$1
- ;;
- staff)
- mount_suffix=
- ;;
-d)
debug=true
loglevel=debug
+ loglevel=info
+ ffp_args+=(-d)
+ ;;
+ -f)
+ fullscreen=true
+ tall=false
+ ;;
+ -t)
+ fullscreen=false
+ tall=true
;;
+ -w)
+ watch=false
+ ;;
+ -u)
+ delay=false
+ ;;
+ -h|--help) usage ;;
+ --) shift; break ;;
+ *) echo "$0: unexpected args: $*" >&2 ; usage 1 ;;
esac
shift
done
+mount_suffix=-sysops
+case $1 in
+ sysops|tech)
+ mount_suffix=-$1
+ ;;&
+ tech)
+ delay=false
+ ;;
+ staff)
+ mount_suffix=
+ ;;
+esac
+
+if $delay; then
+ # 2500 gets us around a 4 second delay, up from 1.5s.
+ delay_arg=,tpad=start_duration=2500ms
+fi
+
+
+##### end command line parsing ########
+
host=live.iankelling.org:8000
-if [[ $(dig +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]] \
- && ip n show 10.2.0.1 | grep . &>/dev/null; then
+if ip n show 10.2.0.1 | grep . &>/dev/null && \
+ [[ $(dig +timeout=1 +short @10.2.0.1 -x 10.2.0.2 2>&1 ||:) == kd.b8.nz. ]]; then
host=127.0.0.1:8000
fi
# example xrandr output: 1280x800+0+0
primary_res=$(awk '$2 == "connected" && $3 == "primary" { print $4 }' $tmpf | sed 's/+.*//')
-secondary_res=$(awk '$2 == "connected" && $3 != "primary" { print $3 }' $tmpf | sed 's/+.*//')
+tmp=$(awk '$2 == "connected" && $3 != "primary" { print $3 }' $tmpf | sed 's/+/ /g')
+read -r secondary_res x_offset _ <<<"$tmp"
+
if [[ $secondary_res ]]; then
- # assumes secondary is on the right
- x_offset=${primary_res%%x*}
secondary_x=${secondary_res%%x*}
secondary_y=${secondary_res##*x}
- stream_res=$(( secondary_x / 2 ))x$(( secondary_y / 2))
+ if $fullscreen; then
+ stream_res=$secondary_res
+ elif $tall; then
+ stream_res=$(( secondary_x / 2 ))x$secondary_y
+ else
+ stream_res=$(( secondary_x / 2 ))x$(( secondary_y / 2))
+ fi
else
x_offset=0
stream_res=$primary_res
# Monitor of default sink.
# eg: alsa_output.usb-Audio-gd_Audio-gd-00.analog-stereo
-pa_sink=$(pacmd list-sinks | awk '/\*/ {getline; print $2}' | sed 's/^<//;s/>$//').monitor
+pa_sink=$(pactl get-default-sink).monitor
+
+# this is for ffmpeg warnings. doesnt seem to affect latency.
+# 160 was too small. at 300, it occasionally complains,
+# probably only when we are using delayed output
+thread_queue_size_arg="-thread_queue_size 500"
opts=(
# global options
-hide_banner
-nostats
+ # tested for decreasing latency: did not help.
+ # -probesize 32
+ # tested for warning "Queue input is backward in time". did not help.
+ #-rtbufsize 500M
+
# note: ordering of inputs also affects zmqsend commands.
## audio input options
-f pulse
-name ffs
- # note: duplicated above
- -thread_queue_size 160
+ # note: duplicated
+ $thread_queue_size_arg
-fragment_size 512
-i default
-f pulse
- # this is for ffmpeg warnings. doesnt seem to affect latency.
- -thread_queue_size 160
+ $thread_queue_size_arg
# pulse knows this name somewhere
-name ffsdesktop
# This fixes latency. i haven't tried tuning it, but going too low creates
## video input options
-video_size $stream_res
+ $thread_queue_size_arg
-f x11grab
-framerate $framerate
-i :0.0+$x_offset.0
# localhost url caused an error for me.
-filter_complex "[0]azmq,volume=precision=fixed: volume=0 [vol0];
[1]azmq='b=tcp\://127.0.0.1\:5556',volume=precision=fixed: volume=0 [vol1];
-[vol0][vol1] amerge=inputs=2 [out];
-[2]zmq='b=tcp\://127.0.0.1\:5557',drawbox=color=0x262626,drawtext=fontsize=90: fontcolor=beige: x=40: y=40: text=''"
+[vol0][vol1] amerge=inputs=2;
+[2]zmq='b=tcp\://127.0.0.1\:5557',drawbox=color=0x262626,drawtext=fontsize=90: fontcolor=beige: x=40: y=40: text=''${delay_arg}[out]"
+
+# [vol0][vol1] amerge=inputs=2,adelay=6000:all=1;
+
+
+ # An online source says to match a 5 second vid delay, we can do an
+ # audio delay filter: "adelay=5000|5000". However, we already get
+ # a stream delay of about 2 seconds, and having the audio be about
+ # 2 seconds ahead is fine, they do that intentionally in soccer
+ # matches.
# Based on error message and poking around, it seems ffmpeg is not
# smart enough to see that [vol0] and [vol1] are inputs to the amerge
# for 1080p, default 256k is poor quality. 500 is ok. 1500 is a bit better.
-b:v 1500k
-threads 2
- -buffer_duration 10
-error-resilient 1
## audio output options
# start muted
pactl set-source-mute @DEFAULT_SOURCE@ true
+if pkill -f ^ffmpeg.\*icecast://source.\*/fsf; then
+ sleep 1
+fi
+
#echo executing: ffmpeg ${opts[@]}
#{ sleep 1; ffp &>/dev/null & }
exit 0
fi
-# For now, we want to watch the stream and end the stream when we stop watching.
+##### begin clipboard history checkup ####
+
+# Avoid streaming with secrets in our clipboard history. We could just
+# clear the history, but here I truncate it to a max and then show it,
+# and then I can press super+y if I want to clear it, or close the
+# window if I want to keep it.
+copyqcount=$(copyq count)
+regex='^[1-9][0-9]*$'
+if [[ $copyqcount =~ $regex ]]; then
+ # i dont want to think about more than this
+ max_rows=40
+ if (( copyqcount >= max_rows )); then
+ rows_arg=()
+ for ((i=max_rows; i<copyqcount; i++)); do
+ rows_arg+=($i)
+ done
+ copyq remove "${rows_arg[@]}"
+ fi
+ copyq show
+ gone=false
+ for (( i=0; i<40; i++ )); do
+ if i3-msg -t get_tree | jq -e '.. | select(.class? == "copyq" and .instance? == "copyq")' &>/dev/null; then
+ sleep .5
+ else
+ gone=true
+ break
+ fi
+ done
+ if ! $gone; then
+ msg="ffs: copyq not gone. aborting. super+y = copyq-restart / clear"
+ if [[ -t 0 ]]; then
+ echo $msg
+ else
+ dunstify -u critical -h string:x-dunst-stack-tag:alert "$msg"
+ fi
+ exit 1
+ fi
+fi
+##### end clipboard history checkup ####
+
+if [[ $mount_suffix == -sysops ]]; then
+ touch $HOME/.iank-stream-on
+fi
+
+echo true >$HOME/.iank-stream-muted
+
ffmpeg "${opts[@]}" &
-sleep 2
-ffp ||:
-kill %%
+if $watch; then
+ # watch the stream and end the stream when we stop watching.
+ sleep 2
+ ffp -d "${ffp_args[@]}" ||:
+ kill %%
+ rm -f $HOME/.iank-stream-on
+fi
## - https://github.com/systemd/systemd/issues/4288
## - https://www.freedesktop.org/software/systemd/man/sd-login.html
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2300", SYMLINK+="model01", ENV{ID_MM_DEVICE_IGNORE}:="1", ENV{ID_MM_CANDIDATE}:="0", TAG+="uaccess", TAG+="seat"
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2301", SYMLINK+="model01", ENV{ID_MM_DEVICE_IGNORE}:="1", ENV{ID_MM_CANDIDATE}:="0", TAG+="uaccess", TAG+="seat"
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2302", SYMLINK+="Atreus2", ENV{ID_MM_DEVICE_IGNORE}:="1", ENV{ID_MM_CANDIDATE}:="0", TAG+="uaccess", TAG+="seat"
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2303", SYMLINK+="Atreus2", ENV{ID_MM_DEVICE_IGNORE}:="1", ENV{ID_MM_CANDIDATE}:="0", TAG+="uaccess", TAG+="seat"
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="3496", ATTRS{idProduct}=="0005", SYMLINK+="model100", ENV{ID_MM_DEVICE_IGNORE}:="1", ENV{ID_MM_CANDIDATE}:="0", TAG+="uaccess", TAG+="seat"
-SUBSYSTEMS=="usb", ATTRS{idVendor}=="3496", ATTRS{idProduct}=="0006", SYMLINK+="model100", ENV{ID_MM_DEVICE_IGNORE}:="1", ENV{ID_MM_CANDIDATE}:="0", TAG+="uaccess", TAG+="seat"
+# iank: substituted := for =, based on
+# Jun 09 12:27:48 so systemd-udevd[1385]: /etc/udev/rules.d/99-kaleidoscope.rules:18 ENV key ta
+kes '==', '!=', '=', or '+=' operator, assuming '='.
+
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2300", SYMLINK+="model01", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat"
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2301", SYMLINK+="model01", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat"
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2302", SYMLINK+="Atreus2", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat"
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="2303", SYMLINK+="Atreus2", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat"
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="3496", ATTRS{idProduct}=="0005", SYMLINK+="model100", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat"
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="3496", ATTRS{idProduct}=="0006", SYMLINK+="model100", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_CANDIDATE}="0", TAG+="uaccess", TAG+="seat"
from pprint import pprint
-def find_parent(i3, window_id):
+def find_workspace(i3, window_id):
"""
- Find the parent of a given window id
+ Find the workspace of a given window id
"""
- def finder(con, parent, workspace):
+ def finder(con, workspace):
if con.id == window_id:
- return (parent, workspace)
+ return (workspace)
for node in con.nodes:
- res = finder(node, con, con if con and con.type == 'workspace' else workspace)
+ res = finder(node, con if con and con.type == 'workspace' else workspace)
if res:
return res
return None
- return finder(i3.get_tree(), None, None)
+ return finder(i3.get_tree(), None)
def kill_single_win_containers(i3, e, node, parent):
# 'window': None,
# 'window_type': None,
- parent, workspace = find_parent(i3, e.container.id)
+ workspace = find_workspace(i3, e.container.id)
# debugging
#exit(0)
+#!/usr/bin/python3
+
# 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
# See the License for the specific language governing permissions and
# limitations under the License.
-#!/usr/bin/python3
# There are only 2 cases where I want single window split containers.
#
#bindsym $mod+3 exec "abrowser 2>&1 >/tmp/l"
#bindsym $mod+3 exec "abrowser -no-remote -P sfw"
bindsym $mod+4 $ex "i3-split-maybe"; exec "abrowser -no-remote -P firefox-main-profile"
-# todo: figure out a stream delay & way to cut the stream.
-# settings, advanced, stream delay
bindsym $mod+5 $ex "/a/bin/ds/stream-interlude"
bindsym $mod+6 $ex "i3-split-maybe"; exec "/usr/local/bin/start-tor-browser"
bindsym $mod+7 $ex "/a/bin/ds/laptop-xrandr"
bindsym $mod+Shift+x move container to workspace 6
bindsym $mod+x workspace 6
-
-# todo, in newer i3, consider split toggle
bindsym $mod+v split vertical
bindsym $mod+Shift+v split horizontal
-#
-## temp for testing, add antying here
-#bindsym $mod+shift+5
+# 122 = XF86AudioLowerVolume, keyboardio function + t
+bindcode 122 $ex "toggle-mute unmute"; mode "ptt"
+mode "ptt" {
+# normally, if we hold down a button, it will start automatically
+# repeating itself, up and down events. But this stops that from
+# happening. Based on testing, making mode be 1st or 2nd doesn't matter.
+bindcode --release 122 $ex "toggle-mute mute"; mode "default"
+}
+# 171 = XF86AudioNext, keyboardio function + g
+bindcode 171 $ex "toggle-mute unmute"
+## temp for testing, add antying here
+#bindsym $mod+shift+5 $ex "/a/a.sh"
bindsym $mod+b $ex i3-pull term
# keybinds will screw up other laptop brightness keys.
bindsym XF86MonBrightnessUp $ex brightnessctl s +5%
bindsym XF86MonBrightnessDown $ex brightnessctl s 5%-
+for_window [class="copyq" instance="copyq" window_type="normal"] floating enable
+bindsym $mod+y $ex copyq-restart
# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below.
if [[ $1 == bar ]] || (( monitor_count >= 2 )); then
cat bar.conf >> $dir/config
fi
+
+i3-msg reload
# exit i3 (logs you out of your X session)
bindsym $mod+Shift+o exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
-bindsym $mod+Shift+i reload
+bindsym $mod+Shift+i $ex /b/ds/i3-sway/gen
bindsym $mod+Shift+p restart
set -e; . /usr/local/lib/bash-bear; set +e
-
-output=$(xrandr | grep -E "^(HDMI.?|DP1) connected" | awk '{print $1}' ||:)
+# eg eDP-1 connected primary
+laptop_out=$(xrandr | awk '$3 == "primary" {print $1}')
+output=$(xrandr | grep -E "^(HDMI|DP)[^ ]* connected [0-9]" | awk '{print $1}' ||:)
left_right_arg=--right-of
if [[ $output ]]; then
- if [[ $output == HDMI2 ]]; then
- sum=$(sha256sum </sys/class/drm/card0-HDMI-A-2/edid | grep -oE '^.{10}')
- # identify monitor that is always on the left.
- if [[ $sum == 192efbdcef ]]; then
- left_right_arg=--left-of
- fi
+ # identify monitors that are always on the left.
+ if [[ $output == HDMI2 && $(sha256sum </sys/class/drm/card0-HDMI-A-2/edid | grep -oE '^.{10}') == 192efbdcef ]]; then
+ left_right_arg=--left-of
+ fi
+ if [[ $output == HDMI-1 && $(sha256sum </sys/class/drm/card1-HDMI-A-1/edid | grep -oE '^.{10}') == 7c58f9ac1e ]]; then
+ left_right_arg=--left-of
fi
+
xrandr --output $output --off
sleep 2
- xrandr --output $output $left_right_arg eDP1 --mode 3840x2160
+ mode=$(xrandr | grep -A1 -E "^$output" | tail -n1 | awk '{print $1}')
+ # eg: 3840x2160
+ echo mode=$mode
+ xrandr --output $output $left_right_arg $laptop_out --mode $mode
for i in 1 2 4 5 6 7 8 9 10; do
- # if the workspace is already there, this will fail
+ # if the workspace is already there, this will fail.
+ # if the workspace doesn't exist yet, it fails with:
+ # ERROR: No output matched
i3-msg '[workspace="'$i'"]' move workspace to output $output ||:
done
else
+++ /dev/null
-bo
-sy
-so
+++ /dev/null
-# https://forums.linuxmint.com/viewtopic.php?f=208&t=224942#p1197049
-# prevents konsole from being borderline unusable on system76 intel graphics + i3
-Section "Device"
- Identifier "Intel Graphics"
- Driver "intel"
- Option "TearFree" "true"
-EndSection
# todo: run mailping test after running, or otherwise
# clear out terminal alert
-# todo: disable postgrey
+# todo: disable postgrey. (why did we have it?)
# todo: in testforward-check, we should also look
mailhost() {
[[ $HOSTNAME == "$MAIL_HOST" ]]
}
-e() { printf "%s\n" "$*"; }
reifactive() {
for service; do
if systemctl is-active $service >/dev/null; then
EOF
fi
+# name change in t12, and now timer instead of cron option in /etc/default
+first_spamd_run=false
+if ! systemctl cat spamassassin-maintenance.timer &>/dev/null; then
+ first_spamd_run=true
+fi
+
+
# light version of exim does not have sasl auth support.
# note: for bitfolk hosts, unbound has important config with conflink.
pi-nostart exim4 exim4-daemon-heavy spamassassin unbound clamav-daemon wireguard
+spamd_ser=spamd
+if systemctl cat spamassassin &>/dev/null; then
+ spamd_ser=spamassassin
+elif $first_spamd_run; then
+ systemctl start spamassassin-maintenance
+fi
+
+systemctl enable --now spamassassin-maintenance.timer
+
# note: pyzor debian readme says you need to run some initialization command
# but its outdated.
-pi spf-tools-perl p0f postgrey pyzor razor jq moreutils certbot fail2ban
+pi spf-tools-perl p0f pyzor razor jq moreutils certbot fail2ban
+pu postgrey
case $HOSTNAME in
je) : ;;
# not included due to using wireguard: openvpn
# our nostart pi fails to avoid enabling
+
+# * initial dns config & daemon setup
+#
+# use systemd-resolved for glibc resolutions, setup symlinks
+
+pi libnss-resolve
+
+# if this link gets replaced with a normal file we will get exim log
+# errors on MAIL_HOST like so:
+#
+# R=fsfsmarthost defer (-36) DT=0s: host lookup for mail.fsf.org did not complete (DNS timeout?)
+
+if [[ ! -L /etc/nsswitch.conf ]]; then
+ sudo mkdir -p /etc/resolved-nsswitch
+ sudo mv /etc/nsswitch.conf /etc/resolved-nsswitch
+ sudo ln -sf /etc/resolved-nsswitch/nsswitch.conf /etc
+fi
+
+f=/etc/basic-nsswitch/nsswitch.conf
+if [[ ! -e $f ]]; then
+ sudo mkdir -p ${f%/*}
+ sudo cp /etc/nsswitch.conf $f
+ sudo sed -i --follow-symlinks 's/^ *hosts:.*/hosts: files dns myhostname/' $f
+fi
+case $HOSTNAME in
+ bk|je)
+ # je should be able to get along systemd-resolved, but ive had some odd
+ # very intermittent dns failures with spamassassin, it seems it might only
+ # be happening with systemd-resolved, so just use unbound
+ # to make it consistent with the other hosts.
+ sudo sed -i --follow-symlinks 's/^ *hosts:.*/hosts: files dns myhostname/' /etc/nsswitch.conf
+ soff systemd-resolved
+ sudo ln -sf 127.0.0.1-resolv/stub-resolv.conf /etc/resolv.conf
+ sgo unbound
+ # cautious measure to make sure resolution is working
+ sleep 1
+ ;;
+ *)
+ # default is
+ # files mdns4_minimal [NOTFOUND=return] dns myhostname
+ # mdns4 is needed for my printer and for bbb webrtc, not sure exactly why.
+ # https://www.freedesktop.org/software/systemd/man/nss-resolve.html#
+ # seems more important than some potential use case.
+ # Interestingly, t9/t10 man page says use files before resolve, debian 10 says the opposite.
+ # removing files makes hostname -f not actually give the fully qualified domain name.
+ sudo sed -i --follow-symlinks 's/^ *hosts:.*/hosts: files resolve [!UNAVAIL=return] mdns4_minimal [NOTFOUND=return] myhostname/' /etc/resolved-nsswitch/nsswitch.conf
+ ;;
+esac
+
+case $HOSTNAME in
+ bk)
+ sgo named
+ ;;
+esac
+
+
+lines=(
+ "/etc/resolved-nsswitch/nsswitch.conf r,"
+ "/etc/basic-nsswitch/nsswitch.conf r,"
+ # Aug 06 23:09:11 kd audit[3995]: AVC apparmor="DENIED" operation="connect" profile="/usr/bin/freshclam" name="/run/systemd/resolve/io.systemd.Resolve" pid=3995 comm="freshclam" requested_mask="wr" denied_mask="wr" fsuid=109 ouid=101
+ # I dont know if this is quite the right fix, but I saw other sockets
+ # in the nameservice files that were rw, so figured it was ok to add this and it worked.
+ "/run/systemd/resolve/io.systemd.Resolve rw,"
+)
+f=/etc/apparmor.d/abstractions/nameservice
+apparmor_reload=false
+if [[ -e $f ]]; then
+ for l in "${lines[@]}"; do
+ if ! grep -qF "$l" $f; then
+ sudo sed -i "/\/nsswitch.conf/a $l" $f
+ apparmor_reload=true
+ if ! grep -qF "$l" $f; then
+ echo "$0: failed editing $f. investigate"
+ exit 1
+ fi
+ fi
+ done
+ if $apparmor_reload && systemctl is-active apparmor; then
+ m ser reload apparmor
+ fi
+fi
+
+
+
# * Mail clean cronjob
u /etc/systemd/system/mailclean.timer <<'EOF'
# this is just a bug fix for trisquel.
f=/etc/apparmor.d/usr.sbin.unbound
-line="/usr/sbin/unbound flags=(attach_disconnected) {"
-if ! grep -qFx "$line" $f; then
- badline="/usr/sbin/unbound {"
- if ! grep -qFx "$badline" $f; then
+good_string="/usr/sbin/unbound flags=(attach_disconnected) {"
+if ! grep -qF "$good_string" $f; then
+ bad_string="/usr/sbin/unbound {"
+ if ! grep -qF "$bad_string" $f; then
err expected line in $f not found
fi
- sed -i "s,^$badline$,$line," $f
+ sed -i "s,$bad_string$,$good_string," $f
if systemctl is-active apparmor &>/dev/null; then
m systemctl reload apparmor
fi
fi
+
# note: anything added to nn_progs needs corresponding rm
# down below in the host switch
nn_progs=(exim4)
if mailhost; then
# Note dovecots lmtp doesnt need to be in the same nn to accept delivery.
# Its in the nn so remote clients can connect to it.
- nn_progs+=(spamassassin dovecot)
+ nn_progs+=($spamd_ser dovecot)
fi
case $HOSTNAME in
done
;;
*)
- for unit in exim4 spamassassin dovecot unbound; do
+ for unit in exim4 $spamd_ser dovecot unbound; do
f=/etc/systemd/system/$unit.service.d/nn.conf
if [[ -s $f ]]; then
rm -fv $f
# 2020-10-19 remove old file. remove this when all hosts updated
rm -fv /etc/systemd/system/spamddnsfix.{timer,service}
-u /etc/default/spamassassin <<'EOF'
+u /etc/default/$spamd_ser <<'EOF'
# defaults plus debugging flags for an issue im having
OPTIONS="--create-prefs --max-children 5 --helper-home-dir"
-PIDFILE="/var/run/spamd.pid"
+PIDFILE="/run/spamd.pid"
# my additions
NICE="--nicelevel 15"
+# not used in t12+, that uses
+# /usr/lib/systemd/system/spamassassin-maintenance.timer
CRON=1
EOF
domains = DEBBUGS_DOMAIN
EOF
+ install -m=0775 -d -g Debian-exim -o iank /var/spool/exim4/gw
u /etc/exim4/conf.d/router/155_delay <<'EOF'
# By default, delay sending email by 30-40 minutes in case I
# change my mind.
condition = ${if and { \
{< {$tod_epoch} {${eval10:$received_time + 60*30}}} \
{!def:h_i:} \
-{!bool{${lookup{$message_exim_id}lsearch{/etc/exim4/no-delay-eximids}{true}}}} \
-{!bool{${lookup{all}lsearch{/etc/exim4/no-delay-eximids}{true}}}} \
+{!bool{${lookup{$message_exim_id}lsearch{/var/spool/exim4/gw/.no-delay-eximids}{true}}}} \
+{!bool{${lookup{all}lsearch{/var/spool/exim4/gw/.no-delay-eximids}{true}}}} \
} {true}{false}}
headers_remove = <; i:
domains = ! +local_domains
# uncomment for testing delays to jtuttle
# local_parts = ! root : ! testignore : ! alerts : ! ian-pager : ! daylert
- local_parts = ! root : ! testignore : ! alerts : ! jtuttle : ! ian-pager : ! daylert
+ local_parts = ! root : ! testignore : ! alerts : ! jtuttle : ! ian-pager : ! daylert : ! r2e
ignore_target_hosts = ROUTER_DNSLOOKUP_IGNORE_TARGET_HOSTS
EOF
;;&
$MAIL_HOST|bk|je)
# start spamassassin/dovecot before exim.
- sre dovecot spamassassin
+ sre dovecot $spamd_ser
# Wait a bit before restarting exim, else I get a paniclog entry
# like: spam acl condition: all spamd servers failed. But I'm tired
# of waiting. I'll deal with this some other way.
:
;;
*)
- soff radicale mailclean.timer dovecot spamassassin $vpnser mailnn clamav-daemon
+ soff radicale mailclean.timer dovecot $spamd_ser $vpnser mailnn clamav-daemon
;;
esac
# TODO, get je to deliver the local mailbox: /m/md/INBOX
# dovecot appears to setup, i can t be sure.
+spamd_ser=spamd
+if systemctl cat spamassassin &>/dev/null; then
+ spamd_ser=spamassassin
+fi
+
source /a/bin/bash_unpublished/source-state
doprom=false
fi
e spamdpid: $spamdpid
if [[ ! $spamdpid ]]; then
- echo mailtest spamd pid not found. systemctl status spamassassin:
- systemctl status spamassassin
+ echo mailtest spamd pid not found. systemctl status $spamd_ser:
+ systemctl status $spamd_ser
fi
tmpfile=$(mktemp)
declare -i unexpected=0
--- /dev/null
+#!/bin/sh
+# 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.
+
+konsole --profile profanity -e pulsemixer "$@"
if [[ -e /tmp/iank-i3-no-auto ]]; then
ps_char="$ps_char I"
fi
- if [[ -e /tmp/no-obs-auto-scene-switch ]]; then
- ps_char="$ps_char O"
- fi
+
+ # not using currently
+ # if [[ -e /tmp/no-obs-auto-scene-switch ]]; then
+ # ps_char="$ps_char O"
+ # fi
if pgrep -fc '^ffmpeg.*icecast://source.*/fsf' &>/dev/null; then
if [[ -e /tmp/iank-ffmpeg-interlude-toggle ]]; then
ps_char="= BRB = $ps_char"
else
ps_char="=|=|= STREAMING =|=|= $ps_char"
- if pactl get-source-mute @DEFAULT_SOURCE@ 2>/dev/null | awk '{print $2}' | grep no &>/dev/null; then
- ps_char="! UNMUTED ! $ps_char"
- fi
fi
+
+ muted=$(cat $HOME/.iank-stream-muted) ||:
+ case $muted in
+ 0) : ;;
+ 1)
+ if find $HOME/.iank-stream-muted -mmin +2 | grep . &>/dev/null; then
+ toggle-mute mute notify
+ else
+ ps_char="# UNMUTED # $ps_char"
+ fi
+ ;;
+ *)
+ ps_char="!!!!! FAILED GETTING MUTE STATUS !!!!! $ps_char"
+ ;;
+ esac
fi
+ # fyi: to check system mute:
+ # if pactl get-source-mute @DEFAULT_SOURCE@ 2>/dev/null | awk '{print $2}' | grep no &>/dev/null; then
+
+
printf '{ "name":"status", "color":"#ED297D", "full_text": "%s' "$ps_char"
printf '"},'
p1=(
bind9-host
cryptsetup
+ libpam-tmpdir
lvm2
mbuffer
moreutils
apt-show-versions
aptitude-doc-en
arandr
- arbtt
# dictionary / thesaurus
artha
asciidoc
backupninja
barrier
bash-doc
+ bat
# not using it currently and it has a dependency problem
# beets
# beets-doc
html-xml-utils
html2text
hunspell
+ # not sure i need it, but i have i2c hacking stuff and it is suggested
+ # in s76-driver
+ i2c-tools
i3lock
i3status
iftop
kid3-cli
konsole
knot-dnsutils
+ # save power when on battery
+ laptop-mode-tools
libterm-readkey-perl
libreoffice
- linphone
+ linphone-desktop
linux-doc
lshw
make-doc
mhonarc
mmdebstrap
mp3gain
- mps-youtube
mpv
mumble
mupdf
oathtool
opendkim-tools
p7zip-full
- paprefs
parted
parted-doc
pass
- pavucontrol
pdfgrep
perl-doc
pianobar
powermgmt-base
profanity
pry
- # https://wiki.archlinux.org/title/bluetooth
- pulseaudio-module-bluetooth
pv
python3-doc
qemu-user-static
qimgv
qrencode
+ read-edid
readline-doc
rename
reportbug
# first exist in t11 afaik
ripgrep
rfkill
- rng-tools
+ rng-tools-debian
rygel
sakura
schroot
# eg, in an ssh shell. confirm for regular user provides some protection
# that a rouge user program cant use my ssh key.
sed 's,^AddKeysToAgent confirm,AddKeysToAgent yes,;/^UserKnownHostsFile /d' $user_ssh_dir/config >/root/.ssh/confighome
- sed 's,^IdentityFile ~/\.ssh/home$,IdentityFile ~/\.ssh/h,' /root/.ssh/confighome >/root/.ssh/config
+ # having a different control path avoids the problem of
+ # forgetting to use confighome, and then after specifying it,
+ # it uses the multiplex socket, which means that the different
+ # key in confighome is not actually used unless we do ssh -O exit HOST.
+ sed 's,^IdentityFile ~/\.ssh/home$,IdentityFile ~/\.ssh/h\nControlPath /tmp/ssh_hmux_%u_%h_%p_%r,' /root/.ssh/confighome >/root/.ssh/config
fi
chown -R root:root /root/.ssh
i3-set-layout
i3-split-maybe
i3-split-push
+ copyq-restart
+ toggle-mute
)
for f in /b/log-quiet/*; do
if [[ $EUID != 0 ]]; then
- sudo "$0"
- exit
+ sudo "$0"
+ exit
fi
# shellcheck source=/a/bin/ds/.bashrc
if [[ -s ~/.bashrc ]];then . ~/.bashrc;fi
sed -i --follow-symlinks 's/^\s*PrintLastLog .*/PrintLastLog no/' /etc/ssh/sshd_config
rm -f /etc/update-motd.d/10-help-text /etc/update-motd.d/00-header
+ssh_ser=ssh
+if command -v apt-get &>/dev/null; then
+ # fyi: debconf-set-selections doesn't like mixing tabs and spaces
+ echo "debconf debconf/frontend select Readline" | debconf-set-selections
+else
+ ssh_ser=sshd
+fi
-if isdeb; then
- # fyi: debconf-set-selections doesn't like mixing tabs and spaces
- echo "debconf debconf/frontend select Readline" | debconf-set-selections
- service ssh reload
+if systemctl is-active $ssh_ser; then
+ systemctl reload $ssh_ser
else
- systemctl reload sshd
+ systemctl enable --now $ssh_ser
fi
}
-if pgrep '^obs$' &>/dev/null; then
- obs-interlude
-else
- ffmpeg-interlude
-fi
+ffmpeg-interlude
+
+# obs disabled
+# if pgrep '^obs$' &>/dev/null; then
+# obs-interlude
+# else
+# ffmpeg-interlude
+# fi
<?xml version='1.0'?>
<!DOCTYPE gui SYSTEM 'kpartgui.dtd'>
-<gui name="session" version="29">
+<gui version="35" name="session">
<MenuBar>
<Menu name="file">
<Action group="session-operations" name="file_save_as"/>
<Action group="session-edit-operations" name="edit_paste"/>
<Separator group="session-edit-operations"/>
<Action group="session-edit-operations" name="select-all"/>
+ <Action group="session-edit-operations" name="select-mode"/>
<Separator group="session-edit-operations"/>
<Action group="session-edit-operations" name="copy-input-to"/>
<Action group="session-edit-operations" name="send-signal"/>
<Action group="session-edit-operations" name="edit_find_prev"/>
</Menu>
<Menu name="view">
+ <Action group="session-view-operations" name="monitor-once"/>
+ <Action group="session-view-operations" name="monitor-prompt"/>
<Action group="session-view-operations" name="monitor-silence"/>
<Action group="session-view-operations" name="monitor-activity"/>
<Action group="session-view-operations" name="monitor-process-finish"/>
<Separator group="session-view-operations"/>
<Action group="session-view-operations" name="view-readonly"/>
+ <Action group="session-view-operations" name="allow-mouse-tracking"/>
<Separator group="session-view-operations"/>
<Action group="session-view-operations" name="enlarge-font"/>
<Action group="session-view-operations" name="reset-font-size"/>
<Action group="session-settings" name="switch-profile"/>
</Menu>
</MenuBar>
+ <ToolBar name="sessionToolbar">
+ <text>Session Toolbar</text>
+ <index>1</index>
+ <Spacer/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Action name="edit_find"/>
+ </ToolBar>
<Menu name="session-popup-menu">
<Action name="edit_copy_contextmenu"/>
+ <Action name="edit_copy_contextmenu_in"/>
+ <Action name="edit_copy_contextmenu_out"/>
+ <Action name="edit_copy_contextmenu_in_out"/>
<Action name="edit_paste"/>
<Action name="web-search"/>
<Action name="open-browser"/>
<Separator/>
+ <Menu name="view-split">
+ <text>Split View</text>
+ <Action name="split-view-left-right"/>
+ <Action name="split-view-top-bottom"/>
+ </Menu>
+ <Separator/>
<Action name="set-encoding"/>
<Action name="clear-history"/>
<Action name="adjust-history"/>
<Separator/>
<Action name="view-readonly"/>
+ <Action name="allow-mouse-tracking"/>
+ <Separator/>
<Action name="switch-profile"/>
<Action name="edit-current-profile"/>
</Menu>
- <ToolBar name="sessionToolbar">
- <text>Session Toolbar</text>
- <index>1</index>
- <Spacer/>
- <Action name="edit_copy"/>
- <Action name="edit_paste"/>
- <Action name="edit_find"/>
- </ToolBar>
<ActionProperties>
<Action name="edit_find_next" shortcut="Ctrl+Shift+R"/>
<Action name="edit_find_prev" shortcut="Ctrl+Shift+E"/>
# check email.
$MAIL_HOST)
p $qmsg | loday -120 qlen
+
+
+ f=/var/spool/exim4/gw/no-delay-eximids
+ if (( loop_count % 10 == 0 )) && \
+ [[ -s $f ]] && [[ $(cat $f) == all ]]; then
+ # I've left this on longer than I intended, so just auto-delete
+ # it after some time.
+ find $f -mmin +180 -delete
+ if [[ -s $f ]]; then
+ chars+=("NO_DELAY")
+ fi
+ fi
+
+
;;
*)
rmg /home/iank/cron-errors/qlen*
echo "ps_char=\"${chars[*]} \$ps_char\"" >>$status_file
fi
fi
-}
+
+ if [[ -e $HOME/.iank-stream-on ]] && ! pgrep -fc '^ffmpeg.*icecast://source.*/fsf-sysops' >/dev/null; then
+ rm -f $HOME/.iank-stream-on
+ fi
+
+} # end write-status
# This prevents me having to mute notifications when I'm going to bed.
mute() {
if [[ -e /sys/class/power_supply/AC/online && $(</sys/class/power_supply/AC/online) == 0 ]]; then
power=false
fi
- wait=15
if $power; then
- if (( loop_count % 10 == 0 )); then
- if [[ -r /sys/class/power_supply/BAT0/capacity ]]; then
- bat=$(cat /sys/class/power_supply/BAT0/capacity)
- else
- bat=100
- fi
- case $bat in
- 100|9?)
- :
- bitcoinon &
- ;;
- esac
- fi
+ wait=15
else
- bitcoinoff
wait=60
fi
# See the License for the specific language governing permissions and
# limitations under the License.
+# mutes or unmutes ffmpeg stream
+# usage: toggle-mute [mute|unmute|mute notify]
+#
+#
+# gets state from $HOME/.iank-stream-muted
if ! test "$BASH_VERSION"; then echo "error: shell is not bash" >&2; exit 1; fi
shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4
trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
-mute=true
-volume_level=0
-
-# mute / unmute instead of toggle.
-if [[ $1 ]]; then
- case $1 in
- mute)
- mute=true
- ;;
- unmute)
- mute=false
- ;;
- esac
-else
-
- muted=$(pactl get-source-mute @DEFAULT_SOURCE@ | awk '{print $2}' ||:)
- case $muted in
- no) : ;;
- yes) mute=false; volume_level=1 ;;
- *)
- i3-nagbar -m "FAILED TO GET PULSE MUTE STATE" -t error -f "pango:monospace 30"
- ;;
- esac
-fi
-
-# we double mute here because it could be useful, and I figured out how
-# and feel like using what I know.
-
-pactl set-source-mute @DEFAULT_SOURCE@ $mute
-
+v=0
+notify=false
# note: condition duplicated in stream-clip, myi3statsus
if pgrep -fc '^ffmpeg.*icecast://source.*/fsf' >/dev/null; then
- out=$(echo Parsed_volume_1 volume $volume_level | zmqsend ||:)
- if [[ $out != "0 Success" ]]; then
- i3-nagbar -m "FAILED to set ffmpeg volume to $volume_level" -t error -f "pango:monospace 30"
+ if [[ $1 ]]; then
+ case $1 in
+ mute)
+ v=0
+ if [[ $2 == notify ]]; then
+ notify=true
+ fi
+ ;;
+ unmute)
+ v=1
+ ;;
+ *)
+ i3-nagbar -m "INVALID mute argument:$1" -t error -f "pango:monospace 30"
+ ;;
+ esac
+
+ else
+ v_state=$(cat $HOME/.iank-stream-muted) ||:
+ case $v_state in
+ 1) : ;; # default action
+ 0) v=1 ;;
+ *)
+ i3-nagbar -m "FAILED GETTING MUTE STATE:$v" -t error -f "pango:monospace 30"
+ ;;
+ esac
+ fi
+
+ out=$(echo Parsed_volume_1 volume $v | zmqsend ||:)
+ if [[ $out == "0 Success" ]]; then
+ echo $v >$HOME/.iank-stream-muted
+ if $notify; then
+ dunstify -h string:x-dunst-stack-tag:alert "automuted"
+ fi
+ else
+ i3-nagbar -m "FAILED ffmpeg volume:$v out:$out" -t error -f "pango:monospace 30"
fi
fi
+
+
+# note: i figured out how to do system input level muting, but I don't
+# really have a use case for it other than being doubly sure that i'm
+# muted. leaving it commented in case I figure out a use case, or I
+# find the application level muting to be unreliable.
+
+# uncomment and refactor for system muting
+# muted=$(pactl get-source-mute @DEFAULT_SOURCE@ | awk '{print $2}' ||:)
+# case $muted in
+# no) v=0 ;;
+# yes) v=1 ;;
+# esac
+
+
+
+# uncomment for system muting, and set $mute_p
+# pactl set-source-mute @DEFAULT_SOURCE@ $mute_p
# See the License for the specific language governing permissions and
# limitations under the License.
+if pkill -f ^ffmpeg.\*icecast://source.\*/fsf; then
+ dunstify -h string:x-dunst-stack-tag:alert "stream killed"
+ exit 0
+fi
if pgrep gnome-screensav &>/dev/null; then
# this command actually starts gnome-screensaver if it isn\'t running.
# limitations under the License.
-# Get screenshots from bow, discard them if they dont change much.
+# Get screenshots from bo, discard them if they dont change much.
[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@"
f=/run/user/1000/ziva-tmp.jpg
-install -g 1000 -o 1000 -m 700 $dest_dir
+install -d -g 1000 -o 1000 -m 700 $dest_dir
cd $dest_dir
shopt -s nullglob
jpgs=( 20*jpg )
lastf=$(ls -1 20*jpg | tail -n1)
fi
-ssh bow DISPLAY=:0 scrot -z $f 2>/dev/null || exit 0
-rsync --inplace bow:$f $dest_dir 2>/dev/null || exit 0
-ssh bow rm -f $f
+ssh bo DISPLAY=:0 scrot -z $f 2>/dev/null || exit 0
+rsync --inplace bo:$f $dest_dir 2>/dev/null || exit 0
+ssh bo rm -f $f
same=false
if [[ $lastf ]]; then