# History related options first and always, or else we risk screwing up
# the history file. This is duplicated in ~/.bash_profile just for good
-# measure
+# measure. Duplicated in hist-catcher also.
# History file size limit, set to unlimited.
# this needs to be different from the default because
# bashrc is too slow. 3 SECONDS because if the shell is around longer
# than that, I'm probably sourcing the file manually, not as part of
# shell startup._
-if [[ ( $SECONDS && $SECONDS -lt 3 ) && $LC_USEBASHRC != t && ( $SSH_CONNECTION || $TERM == linux ) ]]; then
+if [[ ( $SECONDS && $SECONDS -lt 3 ) && ! $LC_USEBASHRC && ( $SSH_CONNECTION || $TERM == linux ) ]]; then
# Here we did not opt-in to running our .bashrc file so we just
# return, but we still setup a function to source it without returning
# so if we want it we don't have to restart our ssh connection.
# df progress
# usage: dfp [-SECOND_INTERVAL] MOUNTPOINT...
# SECOND_INTERVAL defaults to 120
+# shellcheck disable=SC2207,SC2059 # low stakes
dfp() {
local f1 f2 f3
local -i i mp_count M_diff interval=120
# bf() { btrfs fi usage -k / | sed -rn '/^Data/,/S7KGNU0X708190H-root/p'|tail -n1|awk '{print $2}' | sed -r 's/[^0-9].*//'; }
# funcp bf
funcp() {
- local a b mp interval
+ local cmd a b interval
cmd=$1
interval=${2:-90}
if [[ ! $cmd ]]; then
}
+
#### sl: ssh wrapper, but if needed, first rsync files that we configure and
# always source our .bashrc on the remote.
# TODO: docs needs polishing.
+#
+# TODO: histcatcher feature is undocumented & won't work for anyone but ian.
# Usage: all the same args as ssh + a few below. Note, combining options
# that have arguments with ones that dont, like -4oOption is not
local verbose now args remote sshinfo tmp host_type info_sec force_rsync
local sync_dirname extra_info files_sec sl_test_cmd sl_test_hook pre_synced
- local sl_rsync_cmd sl_test_cmd sl_test_hook sl_local_test_cmd
+ local sl_rsync_cmd sl_test_cmd sl_test_hook sl_local_test_cmd sl_hist_arg
+ local sl_usebashrc=t
local -a args sshinfo_files
args=($SL_SSH_ARGS)
verbose=false
force_rsync=false
- if [[ $1 == --rsync ]]; then
- force_rsync=true
- shift
- fi
# shellcheck disable=SC2153 # intentional
sl_local_test_cmd=$SL_LOCAL_TEST_CMD
# shellcheck disable=SC2153 # intentional
case "$1" in
--rsync)
force_rsync=true
+ shift
;;
--sl-local-test-cmd)
sl_local_test_cmd="$2"
# But, since we are doing all this, lets source it because we can.
cat <(echo . $sync_dirname/.bashrc) - | command ssh "${args[@]}" "$remote" LC_USEBASHRC=t bash
else
- mq command ssh -R localhost:36660:localhost:36661 -t "${args[@]}" "$remote" LC_USEBASHRC=t INPUTRC=$sync_dirname/.inputrc bash --rcfile $sync_dirname/.bashrc
+ _sl-hist-arg
+ mq command ssh $sl_hist_arg -t "${args[@]}" "$remote" LC_USEBASHRC=$sl_usebashrc INPUTRC=$sync_dirname/.inputrc bash --rcfile $sync_dirname/.bashrc
fi
else
if [[ -t 0 ]]; then
- mq LC_USEBASHRC=t command ssh -R localhost:36660:localhost:36661 "${args[@]}" "$remote" "$@"
+ _sl-hist-arg
+ mq LC_USEBASHRC=$sl_usebashrc command ssh $sl_hist_arg "${args[@]}" "$remote" "$@"
else
mq command ssh "${args[@]}" "$remote" LC_USEBASHRC=t bash
fi
# output if it took longer than 4 seconds or so.
# todo: try running slowdo on verbose ssh
-# Stores some history from remote ssh sessions via sl.
-hist-catcher() {
- local cmd
- local cmd_regex='[[:alnum:]]'
-
- while true; do
- cmd=$(nc -l 36661) || sleep 1
- if [[ $verbose == true ]]; then
- e "cmd:'$cmd'";
- fi
- if [[ ! $cmd =~ $cmd_regex ]]; then
- continue
+_sl-hist-arg() {
+ if [[ $EUID != 1000 || $USER != iank || ! -d /home/iank/.local ]]; then return 0; fi
+ local -i hist_catchern
+ for (( hist_catchern=36660; hist_catchern <= 36690; hist_catchern++ )); do
+ if ! pgrep -f "^ssh -R tmp/S.sl_[^:]*:$hist_catchern" &>/dev/null; then
+ break
fi
- history -s "$cmd" && history -a ||:
done
+ if (( hist_catchern == 36690 )); then
+ e "sl: something is wrong, over 31 ssh calls, hist_catchern = 36690" >&2
+ return 1
+ fi
+ sl_usebashrc=sl_$(tr -dc 'a-zA-Z0-9' </dev/urandom | head -c20 || [[ $? == 141 ]])
+ sl_hist_arg="-R /tmp/S.$sl_usebashrc:/home/iank/.local/S.hist-catcher.$hist_catchern"
+ systemctl --user start hist-catcher@$hist_catchern
}
-# dev notes: useful: https://www.baeldung.com/linux/local-data-remote-ssh-session#:~:text=%23%23%23%205.2%5C.%20Netcat,provide%20data%20back%2A%2A.
-# TODO: automate starting/restarting this.
-
slr() {
sl --rsync "$@"
# red bold pwd different owner & group & writable (pri 2)
# yellow
- local ps_char ps_color col tmp
+ local ps_char ps_color col tmp h
# note, I tried reading the current column here in order to add a
# did work in 5.1 something. It did not work in emacs. And, one time
# it just randomly output to the terminal. Not worth it.
+ # duplicated in hist-catcher
+ # shellcheck disable=SC2016 # false positive
+ local cmd_regex='^ *[][a-zA-Z0-9!#$(){}~`"/._][][a-zA-Z0-9 !@#$%^&*(){}+~=`\"'\'';:/?.><,_-]*$'
+
if [[ $HISTFILE ]]; then
# save history. if our filesystem went read-only or something, continue on
if history -a; then
- if [[ $SSH_CLIENT && $NOT_MAIL_HOST_P == t ]]; then
- h="$(history 1)"
- if [[ $h ]]; then
- sed -r 's/^([^ ]+ +){4}//' <<<"$h" | nc -w 1 -N localhost 36660 ||:
+ # If are sshed to HOST2, our history will get overwritten after
+ # syncing with HOST2 so don't bother.
+ if [[ $SSH_CLIENT && $HOST2 != "$HOSTNAME" && $LC_USEBASHRC == sl_* && -w /tmp/S.$LC_USEBASHRC ]]; then
+ if [[ $_did_ssh_prompt1 ]]; then
+ h="$(history 1)"
+ # note: _sl_last_history is to avoid wastefully sending
+ # history which won't actually get saved.
+ if [[ $h != "$_sl_last_history" && $h =~ $cmd_regex ]]; then
+ _sl_last_history="$h"
+ if type -p socat &>/dev/null; then
+ sed -r 's/^ *([^ ]+ +){4}//' <<<"$h" | (socat - UNIX-CONNECT:/tmp/S.$LC_USEBASHRC &)
+ elif type -p nc &>/dev/null; then
+ sed -r 's/^ *([^ ]+ +){4}//' <<<"$h" | (nc -w 1 -U /tmp/S.$LC_USEBASHRC &)
+ fi
+ fi
+ else
+ _sl_last_history="$(history 1)"
+ _did_ssh_prompt1=t
fi
fi
fi
# s 22720934 i 858939
lswc-avg() {
- local -i size fcount sum=0
- for i in $(stat -c %s "$@"); do
+ local i
+ local -i fcount sum=0
+ stat -c %s "$@" | while read -r i; do
fcount=$(( i / 26 ))
sum+=$fcount
printf "%'12d %s\n" $fcount "$1"
s ionice -c3 -P "$@"
}
# Prefix for launching a command:
+# shellcheck disable=SC2034 # false positive
maxpri="s nice -n-40 ionice -c1 -n0"
+# shellcheck disable=SC2034 # false positive
minpri="nice -n40 ionice -c3"
sql() {
# wait for PID $1 to die
pidw() {
- local pid="$1"
- local x=$(mktemp); e $pid >$x; pidwait -e -F $x; rm $x
+ local x pid="$1"
+ x=$(mktemp); e $pid >$x; pidwait -e -F $x; rm $x
}
# printf string + newline
multimic() {
- local i
+ local i s l
local -a sources
m pactl unload-module module-loopback
}
crypttab-open() {
- for f in $(awk '{print $1}' /etc/crypttab | grep -v '#'); do
- m cryptdisks_start $f
- done
+ awk '{print $1}' /etc/crypttab | grep -v '#' |
+ while read -r f; do
+ if [[ ! $f ]]; then continue; fi
+ m cryptdisks_start $f
+ done
}
# note: this is incomplete and untested.
}
# remote alerts
ralerts() {
- local ret shell
+ local shell h
+ local -i ret
local -a active_hosts
source /p/c/domain-info
for h in ${active_hosts[@]}; do
# debug variables
dv() {
+ local arg
for arg; do
printf "%s=%s " "$arg" "${!arg}"
done
# for going in the reverse direction, run
# /b/ds/navidrome-playlist-export
beetsmartplaylists() {
+ local f
install -m 0700 -d /tmp/ianbeetstmp
beet splupdate
# kill off any playlists we deleted. they will still need manual
# Alt is just the other host that takes snapshots
# besides the local host.
btrbk-host-debug() {
-
+local host remote alt f
remote=b8.nz
alt=sywg.b8.nz
lipush() {
# note, i had --delete-excluded, but that deletes all files in --exclude-from on
# the remote site, which doesn't make sense, so not sure why i had it.
- local p a
+ local a h
+ local -a fs
+ local -i ret=0
# 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=(
+ #fs=(/a/opt/{emacs-debian11{,-nox},mu,emacs} /a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts})
+ fs=(
/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts} /p/c/user-specific/{bind,znc,icecast2}
/a/f/ans/roles/prom_export/files/simple/usr/local/bin/fsf-install-node-exporter
/a/opt/fpaste
/p/c/subdir_files
)
a="-ahviSAXPH --specials --devices --delete --delete-excluded --relative --exclude-from=/p/c/li-rsync-excludes"
- ret=0
for h in li je bk; do
- m s rsync "$@" $a ${p[@]} /p/c/machine_specific/$h root@$h.b8.nz:/
+ m s rsync "$@" $a ${fs[@]} /p/c/machine_specific/$h root@$h.b8.nz:/
## only li is debian11
#p[0]=/a/opt/emacs-trisuqel10
#p[1]=/a/opt/emacs-trisquel10-nox
}
# compared to li, no emacs and some user-specific files.
bkpush() {
- p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts}
+ local a
+ local -a fs
+ local -i ret=0
+ fs=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts}
/a/f/ans/roles/prom_export/files/simple/usr/local/bin/fsf-install-node-exporter
)
a="-ahviSAXPH --specials --devices --delete --relative --exclude-from=/p/c/li-rsync-excludes"
ret=0
- m rsync "$@" $a ${p[@]} /p/c/machine_specific/bk root@bk.b8.nz:/ || ret=$?
+ m rsync "$@" $a ${fs[@]} /p/c/machine_specific/bk root@bk.b8.nz:/ || ret=$?
return $ret
}
jepush() { # no emacs. for running faster.
- p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts}
+ local a
+ local -a fs
+ local -i ret=0
+ fs=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts}
/a/f/ans/roles/prom_export/files/simple/usr/local/bin/fsf-install-node-exporter
)
a="-ahviSAXPH --specials --devices --delete --relative --exclude-from=/p/c/li-rsync-excludes"
ret=0
- m rsync "$@" $a ${p[@]} /p/c/machine_specific/je root@je.b8.nz:/ || ret=$?
+ m rsync "$@" $a ${fs[@]} /p/c/machine_specific/je root@je.b8.nz:/ || ret=$?
return $ret
}
bindpush() {
+ local h
dsign iankelling.org zroe.org amnimal.ninja
lipush
for h in li bk; do
done
}
bindpushb8() {
+ local h
lipush
for h in li bk; do
m ssh $h.b8.nz dnsb8
# become insecure, I want some extra time to update.
# dnsecgen (in brc2)
- local zone=$1
+ local f zone=$1
dnssec-keygen -a RSASHA256 -b 2048 $zone
dnssec-keygen -f KSK -a RSASHA256 -b 4096 $zone
for f in K"$zone".*.key; do
# apply apache to git tracked bash files + README, except files with A?GPL3 header.
apache-apply-repo() {
+ local f
for f in $(git ls-files); do
[[ -L $f || ! -f $f ]] && continue
if [[ $f != README ]]; then
}
apache-apply() {
- local header_suffix
+ local header_suffix file
if [[ $1 == -* ]]; then
header_suffix="$1"
shift
# strip out the apache license from a file.
apache-strip() {
+ local f
# 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
}
# do git status on published repos.
hstatus() {
+ local x
c /a/bin/githtml
for x in *; do
cd "$(readlink -f $x)"/..
}
ilogs-local() {
+ local n f x d tmp base
+ local -a files
d=/var/lib/znc/moddata/log/iank/
for n in freenode libera; do
cd $d/$n
ilog-local() {
- local d chan
+ local d chan n x
chan="$1"
if [[ ! $chan ]]; then
err "requires 1 argument, got 0. check ssh interpolation"
hiup() {
# incomplete local vars list
- local usb ip host mac opts
+ local usb ip host mac opts h opt user root vpn i arg
local -A vpn_ips host_ips host_macs portfw_ips nonvpn_ips all_ips root_hosts_a
local -a root_hosts nonroot_hosts work_hosts
mntns1-p() {
# fyi, another way to compare:
#s bash -c '[[ /proc/self/ns/mnt -ef /proc/1/ns/mnt ]]'
- s stat -Lc %i /proc/{1,self}/ns/mnt|uniq -d|read
+ s stat -Lc %i /proc/{1,self}/ns/mnt|uniq -d|read -r
}
# Like mntns1-p except with network ns.
netns1-p() {
- s stat -Lc %i /proc/{1,self}/ns/net|uniq -d|read
+ s stat -Lc %i /proc/{1,self}/ns/net|uniq -d|read -r
}
mns-setup() {
# mu personality. for original, just run mp. for 2, run mp 2.
# this is partly duplicated in mail-setup
mp() {
- local dead=false
+ local dead=false s suf f target
for s in {1..5}; do
if ! killall mu; then
dead=true
# maildir enable
mdenable() {
- local md dst ln_path src two
+ local md dst ln_path src two d
two=false
case $1 in
mdenable -2 "$@"
}
mddisable() {
- local md=$1
+ local md=$1 d src
dst=/m/md/$md
### begin copied from mdenable, but different d ###
# mpv all media files in . or $1
mpvm() {
- local -a extensions arg
+ local -a extensions arg dir
+ local -i i
# get page source of https://en.wikipedia.org/w/index.php?title=Video_file_format&action=edit
# into /a/x.log, then
# grep '^| *\.' /a/x.log | sed 's/| *//;s/,//g'
# date and time I said when I started and stopped working, so I'm trying
# out a new client: profanity.
mypidgin() {
+ local x
c /p/c/.purple/logs/jabber/iank@fsf.org/office@conference.fsf.org.chat
for x in *.html; do html2text -o ${x%.html}.txt $x; done
# shellcheck disable=SC2016 # false positive on ${
local pid
pid="$1"
[[ $pid ]]
- ! s stat -Lc %i /proc/{1,$pid}/ns/net|uniq -d|read
+ ! s stat -Lc %i /proc/{1,$pid}/ns/net|uniq -d|read -r
}
# Get pid of systemd service
fi
unit=$1
pid=$(servicepid $unit)
+ # shellcheck disable=SC2046
m sudo nsenter -t $pid -n $(mntns1-p && e -m) sudo -u $USER -i bash
}
fi
unit=$1
pid=$(servicepid $unit)
+ # shellcheck disable=SC2046
m sudo nsenter -t $pid -n $(mntns1-p && e -m) bash
}
# We use the mount namespace to use a non-systemd dns but doing it
# twice doesn't work.
+ # shellcheck disable=SC2046
m sudo nsenter -t $pid -n $(mntns1-p && e -m) sudo -u $user -i "${final_args[@]}"
}
printf "%d:%02d\n" $(( sec / 60 / 60)) $(( (sec / 60) % 60 ))
}
-calvis() { # calendar visualize
+# calendar visualize
+calvis() {
+ local l char
install -m 600 /dev/null /tmp/calendar-bytes
while read -r l; do
for char in $l; do
# re all my files more expansively.
# usage [-OPT...] regex space combined
rem() {
- local paths
+ local paths arg
local -a opts
if [[ ! $1 ]]; then
echo rem: missing argument >&2
# pip3 install linode-cli
# linode-cli
livp9() {
- local input ip id tmp
+ local input ip id tmp string
input=$1
if [[ $2 ]]; then
id=$2
# ya, hacky hardcoded hostnames in 2023. we could do better
hssh-update() {
+ local host
local -a failed_hosts hosts
source /p/c/domain-info
# terminal clear. like clear, but put the prompt at the bottom,
# useful for obs streaming the bottom half of a terminal window.
tclear() {
+ local -i i
for ((i=0; i<COLUMNS; i++)); do
echo
done
# insensitive find plus edit
ife() {
- local tmps found_count i char file
+ local tmps found_count i char file button
local -a found_files
local -A button_file
tmps=$(ifn "$@")
}
snap-last() {
+ local sub
# shellcheck disable=SC2012 # not relevant since this is for printing
ls -lad /mnt/o/btrbk/o.* | tail -n2
for sub in a q; do
if ! pcheck $pkg; then
e "warning: this will overwrite an installed package"
fi
- local tmpdir="$(mktemp -d)"
+ local tmpdir
+ tmpdir=$(mktemp -d)
# it puts the deb in .., so use a subdir to stay contained
mkdir $tmpdir/sub
cd "$tmpdir/sub"
}
mnt-df() {
+ local f mnts
cd /mnt;
- local mnts=$(for f in *; do if mountpoint -q $f; then e $f; fi; done)
+ mnts=$(for f in *; do if mountpoint -q $f; then e $f; fi; done)
df -h $mnts | awk '{printf "%8s %12s\n", $4,$NF}' | sort -hr
}
lazywrites() {
- local t=$(mktemp)
+ local t
+ t=$(mktemp)
cat >$t <<'EOF'
fs.xfs.xfssyncd_centisecs=13000
vm.dirty_background_ratio=25
vm.dirty_writeback_centisecs=1500
EOF
s sysctl -p$t
-
}
set -eE -o pipefail
trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
-readonly this_file="$(readlink -f -- "${BASH_SOURCE[0]}")"
+readonly this_file
+this_file="$(readlink -f -- "${BASH_SOURCE[0]}")"
readonly this_dir="${this_file%/*}"
cd "$this_dir"
./distro-begin
trisquel)
case $codename in
*)
- # firefox would work here too, apt would select abrowser.
- # and the update-alternatives thing i think is becuz firefox is
- # generally available before abrowser and this helps fix things
- # up when we have both.
- pi abrowser
- s update-alternatives --set x-www-browser /usr/bin/abrowser
+ # pi abrowser
+ # s update-alternatives --set x-www-browser /usr/bin/abrowser
+ # xdg-settings set default-web-browser abrowser.desktop
+
+ if [[ ! -s /etc/apt/sources.list.d/extrepo_librewolf.sources ]]; then
+ pi extrepo
+ sudo extrepo enable librewolf
+ sudo extrepo update librewolf
+ p update
+ pi librewolf
+ # I think this handles the case when we have multiple browsers installed.
+ s update-alternatives --set x-www-browser /usr/bin/librewolf
+ # not sure this is needed
+ xdg-settings set default-web-browser librewolf.desktop
+ fi
;;
esac
;;
########### misc stuff
+
# i rely on a newer version.
pu fzf
sudo systemctl mask wacom-inputattach@ttyS4.service
-# see current with:
-# xdg-settings get default-web-browser
-# not sure this is needed.
-#
-# These are some old files that made xdg-open open firefox from a chroot.
-rm -f ~/.local/share/applications/{firefox,chromium}*
-case $distro in
- trisquel)
- xdg-settings set default-web-browser abrowser.desktop
- ;;
- ubuntu)
- xdg-settings set default-web-browser firefox.desktop
- ;;
-esac
-
# pressing tab after sdf here:
# scp sdfbash: set +o noglob: command not found
# 249.11-0ubuntu3.4 for libsystemd-dev was phased, while libsystemd0 wasn't
APT::Get::Always-Include-Phased-Updates "true";
+
+
+# 2026, just continuing to reuse this file for apt settings
+DPkg::Post-Invoke {
+ "if [ -x /usr/local/bin/iank-apt-post-hook ]; then /usr/local/bin/iank-apt-post-hook; fi";
+};
+++ /dev/null
-[Unit]
-Description=bash remote history
-StartLimitIntervalSec=0
-After=local-fs.target
-
-[Service]
-Type=simple
-ExecStart=/usr/local/bin/hist-catcher
-IOSchedulingClass=idle
-CPUSchedulingPolicy=idle
-User=iank
-Group=iank
-Restart=always
-RestartSec=600
-
-
-[Install]
-WantedBy=graphical.target
# prefer abrowser
-if [[ -x /usr/bin/abrowser ]]; then
+if [[ -x /usr/bin/librewolf ]]; then
+ b=librewolf
+elif [[ -x /usr/bin/abrowser ]]; then
b=abrowser
else
b=firefox
profile="$1"
shift
-if pgrep -f "^/usr/lib/abrowser/abrowser --new-instance -P ${profile}$" &>/dev/null; then
+if [[ -x /usr/bin/librewolf ]]; then
+ b=librewolf
+ ps_name=/usr/bin/librewolf
+elif [[ -x /usr/bin/abrowser ]]; then
+ b=librewolf
+ ps_name=/usr/lib/abrowser/abrowser
+fi
+
+if pgrep -f "^$ps_name --new-instance -P ${profile}$" &>/dev/null; then
if (( $# )); then
- abrowser -P $profile --new-tab "$@"
+ $b -P $profile --new-tab "$@"
else
- abrowser -P $profile
+ $b -P $profile
fi
else
- abrowser --new-instance -P $profile &>/dev/null &
+ $b --new-instance -P $profile &>/dev/null &
fi
trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR
-# prefer abrowser
-if [[ -x /usr/bin/abrowser ]]; then
+# prefer librewolf, trying it out due to faster at getting upstream fixes
+if [[ -x /usr/bin/librewolf ]]; then
+ b=librewolf
+elif [[ -x /usr/bin/abrowser ]]; then
b=abrowser
else
b=firefox
# See the License for the specific language governing permissions and
# limitations under the License.
+# Note, no automatic error exit since that is super annoying for package installs.
-cmd_regex='[[:alnum:]]'
-while true; do
- cmd=$(nc -l 36661) || sleep 1
- if [[ ! $cmd =~ $cmd_regex ]]; then
- continue
- fi
- history -s "$cmd" && history -a ||:
-done
+if grep -q 'VERSION_ID="11' /etc/os-release ; then exit 0; fi
+
+if [[ ! -s /usr/sbin/exim4 ]]; then exit 0; fi
+
+if ! type -p setcap &>/dev/null || ! type -p getcap &>/dev/null; then exit 0; fi
+
+modified=false
+
+owners=$(stat -c %U:%G /usr/sbin/exim4)
+if [[ $owners != Debian-exim:Debian-exim ]]; then
+ chown Debian-exim:Debian-exim /usr/sbin/exim4
+ modified=true
+fi
+perms=$(stat --format %a /usr/sbin/exim4)
+if [[ $perms != 6* ]]; then
+ chmod g+s,u+s /usr/sbin/exim4
+ modified=true
+fi
+
+caps=$(getcap /usr/sbin/exim4)
+if [[ ! $caps ]]; then
+ setcap CAP_NET_BIND_SERVICE+ei /usr/sbin/exim4
+ modified=true
+fi
+
+if $modified && systemctl is-active exim4 &>/dev/null; then
+ systemctl restart exim4
+fi
+exit 0
run_as_nonroot=true
if $run_as_nonroot; then
- # settings that go away when exim gets upgraded. obviously the best
- # way to do this would be to modify the exim package itself, but this
- # is easier.
+ # settings that go away when exim gets upgraded. We shouldn't hit this
+ # because we have an apt hook, but just in case.
caps=$(getcap /usr/sbin/exim4)
if [[ ! $caps ]]; then
echo "$0: setting capabilities, user and setuid/gid on /usr/sbin/exim4"
chown Debian-exim:Debian-exim /usr/sbin/exim4
chmod g+s,u+s /usr/sbin/exim4
setcap CAP_NET_BIND_SERVICE+ei /usr/sbin/exim4
+ systemctl restart exim4
fi
fi
done
local mount_source mpoint line_end l
while read -r mount_source mpoint line_end; do
l="$mount_source $mpoint $line_end"
- if grep -rq "^[[:space:]]*$mount_source[[:space:]]+$mpoint[[:space:]]+" /etc/fstab; then continue; fi
+ if grep -rq "^[[:space:]]*${mount_source}[[:space:]]+${mpoint}[[:space:]]+" /etc/fstab; then continue; fi
tu /etc/fstab <<<"$l"
done
}
# SPDX-License-Identifier: GPL-3.0-or-later
+# TODO: track the actual generated exim config files in git. Somehow an
+# exim update screwed up the config file, probably by generating it
+# outside of the normal processes. It was fixed when I reran this file,
+# but then I didn't actually know for sure what went wrong.
+
# todo:
# on bk (and fsf servers that run multiple exim4 daemons, eg eximfsf2 and eximfsf3),
# make it so that when exim is restarted due to package upgrades,
# make exim be a nonroot setuid program.
m chown Debian-exim:Debian-exim /usr/sbin/exim4
fi
- # needs guid set in order to become Debian-exim
- m chmod g+s,u+s /usr/sbin/exim4
+ perms=$(stat --format %a /usr/sbin/exim4)
+ if [[ $perms != 6* ]]; then
+ # needs guid set in order to become Debian-exim
+ m chmod g+s,u+s /usr/sbin/exim4
+ fi
# need this to avoid error on service reload:
# 2022-08-07 18:44:34.005 [892491] pid 892491: SIGHUP received: re-exec daemon
# 2022-08-07 18:44:34.036 [892491] cwd=/var/spool/exim4 5 args: /usr/sbin/exim4 -bd -q30m -C /etc/exim4/nn-mainlog.conf
awk '$1 == "Symbol:" && $2 !~ /\(0\.00\)/ && $3 !~ /\(0\.00\)/ {print $2}' | sed 's/(.*//'
}
-deactivated_sshd=false
-lock_check_fails=0
-
ssh-wan() {
printf "Port 22\nPort 8989\n" > /etc/ssh/sshd_config.d/iank.conf
systemctl reload ssh.service
my_service_scripts=(
epanic-clean
system-status
- hist-catcher
btrfsmaint
mailtest-check
dynamic-ip-update
2 screens: XPosition=2
2 screens: YPosition=2
3840x2160 screen: Height=2156
-3840x2160 screen: Width=1916
-3840x2160 screen: XPosition=1922
+3840x2160 screen: Width=1276
+3840x2160 screen: XPosition=2562
3840x2160 screen: YPosition=2
DP-0=DP-0
DP-1 eDP-1=DP-1
fi
done
fi
+ if [[ -s /home/iank/hist-catcher.log ]]; then
+ chars+=("HC")
+ fi
# if [[ $(grep -v "exim user lost privilege for using -C option" /var/log/exim4/paniclog 2>/dev/null ||:) ]]; then
if [[ -s /var/log/exim4/paniclog ]]; then