bunch of small fixes master
authorIan Kelling <ian@iankelling.org>
Sun, 18 Jan 2026 23:50:13 +0000 (18:50 -0500)
committerIan Kelling <ian@iankelling.org>
Sun, 18 Jan 2026 23:50:13 +0000 (18:50 -0500)
.gemrc-README [new file with mode: 0644]
.perlcriticrc [new file with mode: 0644]
brc
brc2
filesystem/usr/local/bin/i3-chat
filesystem/usr/local/bin/rs [new file with mode: 0755]
filesystem/usr/local/bin/ssh-askpass-hack [new file with mode: 0755]
fsf-script-lib
mail-route
mailtest-check

diff --git a/.gemrc-README b/.gemrc-README
new file mode 100644 (file)
index 0000000..abccb70
--- /dev/null
@@ -0,0 +1,8 @@
+# if a gem fails on documentation, uncomment this.
+# gem: --no-document
+
+
+# for downloading Gemfile.lock dependencies for license checking:
+# p install ruby-bundler
+# bundle config set --local deployment true
+# bundle install
diff --git a/.perlcriticrc b/.perlcriticrc
new file mode 100644 (file)
index 0000000..178402f
--- /dev/null
@@ -0,0 +1,2 @@
+[-Subroutines::RequireArgUnpacking]
+[-Subroutines::RequireFinalReturn]
diff --git a/brc b/brc
index 545aa85c0dc939bbdbc9903d8d77c3239bf93bb4..9a8de9167dbb0f51ffe2233d9f871341c53d3013 100644 (file)
--- a/brc
+++ b/brc
@@ -148,7 +148,7 @@ if [[ $LC_INSIDE_EMACS ]]; then
 fi
 
 export SSH_CONFIG_FILE_OVERRIDE=/root/.ssh/confighome
-
+export SL_RSYNC_CMD=/usr/local/bin/rs
 
 
 # emacs has a different default search path than the info command. This
@@ -1411,6 +1411,11 @@ dus() {
 }
 ccomp du dus
 
+du-lines() {
+  # note: -s if -f; is implicitly -s $_ if -f $_;
+  perl -lne '$s += -s if -f; END { printf "%.2f GB\n", $s / 1024**3 }'
+}
+
 # echo args, one per line
 ea() {
   local arg
@@ -3119,11 +3124,13 @@ slowdo() {
 # above. It is run unquoted (with expansion). This can set $SL_FILES_DIR
 # to vary the files synced. cli option overrides env var.
 
-# SL_RSYNC_ARGS / --sl-rsync-args ARGS: Env var or cli option. String of
-# arguments passed to rsync. For example to exclude files within a
-# directory. Note, excluded files wont be deleted on rsync, you can add
-# --delete-excluded to the rsync command if that is desired. cli
-# overrides env var.
+# SL_RSYNC_CMD / --sl-rsync-cmd CMD_WITH_ARGS: Env var or cli
+# option. String of command and optionally arguments passed to
+# rsync. For example to exclude files within a directory or use an
+# alternate rsync command. Ian: I use this to run an rsync wrapper in
+# order to support ssh option "ControlMaster autoask". Note, excluded
+# files wont be deleted on rsync, you can add --delete-excluded to the
+# rsync command if that is desired. cli overrides env var.
 
 # SL_SSH_ARGS: Env var. Default arguments passed to ssh.
 
@@ -3149,8 +3156,9 @@ sl() {
   # .bashrc. This means the outer shell still ran the default .bashrc,
   # but that is the best we can do.
 
-  local verbose_arg now args remote do_rsync haveinfo tmpa sshinfo tmp tmp2 host_type info_sec force_rsync \
-        sync_dirname testcmd extra_info testbool files_sec sl_test_cmd sl_test_hook
+  local verbose now args remote do_rsync haveinfo tmpa sshinfo tmp tmp2 host_type info_sec force_rsync
+  local sync_dirname testcmd extra_info testbool files_sec sl_test_cmd sl_test_hook
+  local sl_rsync_cmd sl_test_cmd sl_test_hook
   declare -a args tmpa
 
   args=($SL_SSH_ARGS)
@@ -3171,7 +3179,7 @@ sl() {
   # [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]
 
   # shellcheck disable=SC3127 # todo: remove this once we use this var
-  verbose_arg=false
+  verbose=false
   force_rsync=false
   if [[ $1 == --rsync ]]; then
     force_rsync=true
@@ -3182,7 +3190,7 @@ sl() {
   # shellcheck disable=SC2153 # intentional
   sl_test_hook=$SL_TEST_HOOK
   # shellcheck disable=SC2153 # intentional
-  sl_rsync_args=$SL_RSYNC_ARGS
+  sl_rsync_cmd=${SL_RSYNC_CMD:-rsync}
   while [[ $1 ]]; do
     case "$1" in
       --rsync)
@@ -3196,8 +3204,8 @@ sl() {
         sl_test_hook="$2"
         shift
         ;;
-      --sl-rsync-args)
-        sl_rsync_args="$2"
+      --sl-rsync-cmd)
+        sl_rsync_cmd="$2"
         shift
         ;;
       *)
@@ -3214,7 +3222,7 @@ sl() {
         if [[ $1 == *v* ]]; then
           # todo: try running slowdo if this is false
           # shellcheck disable=SC2034 # todo: remove this once we use this var
-          verbose_arg=true
+          verbose=true
         fi
         args+=("$1"); shift
         ;;
@@ -3265,7 +3273,7 @@ sl() {
     # we test for string to know ssh succeeded
     testbool="test -e $SL_FILES_DIR/.bashrc -a -L .bashrc -a -v LC_USEBASHRC"
     testcmd="if $testbool; then printf y; else printf n; fi"
-    if ! tmp=$(LC_USEBASHRC=y command ssh "${args[@]}" "$remote" "$testcmd; $sl_test_cmd"); then
+    if ! tmp=$(mq LC_USEBASHRC=y command ssh "${args[@]}" "$remote" "$testcmd; $sl_test_cmd"); then
       echo failed sl test. doing plain ssh -v
       command ssh -v "${args[@]}" "$remote"
     fi
@@ -3279,7 +3287,7 @@ sl() {
     extra_info="${tmp:1}"
   fi
   if [[ $sl_test_hook ]]; then
-    RSYNC_RSH="ssh ${args[*]}" $sl_test_hook "$extra_info" "$remote"
+    mq RSYNC_RSH="ssh ${args[*]}" $sl_test_hook "$extra_info" "$remote"
   fi
 
   if $haveinfo && [[ $host_type == sync ]]; then
@@ -3292,7 +3300,6 @@ sl() {
     if (( files_sec > info_sec )); then
       #echo "d4 $files_sec > $info_sec"
       do_rsync=true
-      rm -f $sshinfo
     fi
   fi
 
@@ -3306,9 +3313,10 @@ sl() {
     # todo: it would be nice if we did this with -v, but
     # only showed the output if the command lasted more than
     # about 4 seconds.
-    RSYNC_RSH="ssh ${args[*]}" m rsync -rptL --delete $sl_rsync_args $SL_FILES_DIR "$remote":
+    m RSYNC_RSH="ssh ${args[*]}" $sl_rsync_cmd -rptL --delete $SL_FILES_DIR "$remote":
   fi
   if $do_rsync || ! $haveinfo; then
+    if [[ $sshinfo && -e $sshinfo ]]; then rm -f $sshinfo; fi
     sshinfo=$SL_INFO_DIR/$EPOCHSECONDS-$host_type-"$remote"
     [[ -e $SL_INFO_DIR ]] || mkdir -p $SL_INFO_DIR
     # debug
@@ -3322,7 +3330,7 @@ sl() {
       # later, I noticed it didn't handle spaces as normal ssh does, and
       # didn't see any benefit to doing it that way (perhaps forgot what
       # I originally saw in it).
-      command ssh "${args[@]}" "$remote" \
+      mq command ssh "${args[@]}" "$remote" \
               LC_USEBASHRC=t . $sync_dirname/.bashrc\; "$@"
     elif [[ ! -t 0 ]]; then
       # This case is when commands are being piped to ssh.
@@ -3330,13 +3338,13 @@ sl() {
       # 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
-      command ssh -t "${args[@]}" "$remote" LC_USEBASHRC=t INPUTRC=$sync_dirname/.inputrc bash --rcfile $sync_dirname/.bashrc
+      mq command ssh -t "${args[@]}" "$remote" LC_USEBASHRC=t INPUTRC=$sync_dirname/.inputrc bash --rcfile $sync_dirname/.bashrc
     fi
   else
     if [[ -t 0 ]]; then
-      LC_USEBASHRC=t command ssh "${args[@]}" "$remote" "$@"
+      mq LC_USEBASHRC=t command ssh "${args[@]}" "$remote" "$@"
     else
-      command ssh "${args[@]}" "$remote" LC_USEBASHRC=t bash
+      mq command ssh "${args[@]}" "$remote" LC_USEBASHRC=t bash
     fi
   fi
   # this function inspired from https://github.com/Russell91/sshrc
@@ -3522,12 +3530,6 @@ nonet() {
   fi
   sudo -E env /sbin/ip netns exec nonet sudo -E -u iank /bin/bash
 }
-# echo args then run
-m() { printf "%s\n" "$*";  "$@"; }
-# echo args to stderr, then run. Useful when discarding stdout
-m2() { printf "%s\n" "$*" >&2;  "$@"; }
-# echo args, then run args in background, discarding output.
-mq() { printf "%s\n" "$*";  "$@" &>/dev/null & }
 
 # m ask. print args, then prompt to confirm running them.
 ma() {
@@ -4632,7 +4634,7 @@ dtsort() {
   daystart=$(date -d 00:00 +%s)
   day_mins=$(( ( EPOCHSECONDS - daystart ) / 60 ))
   echo $(date +%j)---$day_mins
-  }
+}
 
 wgkey() {
   local umask_orig name
@@ -4659,7 +4661,12 @@ dedup-node-modules() {
   # is bigger, then flag it by doing an ls.
   for d in $(find -type f -name '*.min.js'|sed -r 's,^./,,;s,/.*$,,' | sort -u); do a=$(cat $(find $d -name '*.min.js')|wc -c); b=$(cat $(find $d -type f \! -name '*.min.js' \( -name '*.js' -o -name '*.ts' -o -name '*.mjs' -o -name '*.tsx' -o -name '*.cts' -o -name '*.mts \)') | wc -c); if ! uintp "$a" "$b"; then e "uint $a, $b"; continue; fi; if (( a < b )); then find $d -name '*.min.js' -delete; else m ll $d; fi; done
   #time /t/sc/scancode --info --classify --only-findings --max-in-memory 300000 -clpue --unknown-licenses --tallies --tallies-with-details --summary --generated --json-pp scan.json .
-  }
+}
+
+# iptables -I without duplication.
+iptI() { ${*/ -I/ -C/} 2>/dev/null || "$@"; }
+# iptables -A without duplication.
+iptA() { ${*/ -A/ -C/} 2>/dev/null || "$@"; }
 
 
 # * stuff that makes sense to be at the end
diff --git a/brc2 b/brc2
index e36cef2ee60c45dd425f08f18ebc16513f2b9b5e..0bf38c9ded2fc5f55eb6d8066e50fedf748a51cc 100644 (file)
--- a/brc2
+++ b/brc2
@@ -1573,10 +1573,12 @@ envload() { # load environment from a previous: export > file
 failfunc() { asdf a b c; }
 failfunc2() { failfunc d e f; }
 
-# one that comes with distros is too old for newer devices
-fastboot() {
-  /a/opt/android-platform-tools/fastboot "$@";
-}
+# one that comes with distros is too old for newer devices. commented in
+# case this happens again.
+#
+# fastboot() {
+#   /a/opt/android-platform-tools/fastboot "$@";
+# }
 
 kdecd() { /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd; }
 
@@ -2942,7 +2944,7 @@ allmyirc() {
 # out a new client: profanity.
 mypidgin() {
   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;
+  for x in *.html; do html2text -o ${x%.html}.txt $x; done
   # shellcheck disable=SC2016 # false positive on ${
   grep -A1 ') iank:' ./*.txt \
     | sed -r 's/^(.{10})[^ ]*\.txt:\(?([^ ]*)[[:space:]](..). iank:/\1_\2_\3/
@@ -4986,7 +4988,8 @@ i2x100() {
   for (( ; i<${#ds[@]}; i+=batch)); do
     e i=$i
      m i2x ${ds[@]:$i:$batch};
-  done; };
+  done
+}
 
 
 ########################## ####################################################
index b6d854bcadc9c6a84f4836ff9de217f7366c64f6..a9a7c596ca2b1e0c80eb755cc9ec33907c797306 100755 (executable)
@@ -36,24 +36,27 @@ fi
 
 # tree of profanity related processes:
 
+#
 # i3-chat (ctrl+y)
 #  prof
-#   export IANK_BASHRC_RUN="prof-remote $remote"
-#   konsole --profile profanity
-#     prof-remote $remote
-#       ssh -n $remote tail -n0 -qF \
-#         /home/iank/.local/share/profanity/prof-tail.log | prof-notify &
-#       ssh -t $remote tmux -L profanity a ||:
-
+#   If this is my desktop:
+#     prof-tail &
+#     konsole --profile profanity -e tmux -L profanity a
+#       tmux (attaches to existing profanity session)
+#   If we are on a computer other than my desktop:
+#     export IANK_BASHRC_RUN="prof-remote $remote"
+#     konsole --profile profanity
+#       prof-remote $remote
+#         ssh -n $remote -- prof-tail -r | prof-notify &
+#         ssh -t $remote tmux -L profanity a ||:
+#
+# systemd (on my desktop)
+#  profanity.service -> /usr/bin/tmux -L profanity new-session -d profanity
 
 # distro_end, on $d_host
 #  systemctl --user enable --now profanity.service
 #   /b/ds/subdir_files/.config/systemd/user/profanity.service
 #    /usr/bin/tmux -L profanity new-session -d profanity
-#  systemctl --user enable --now prof-tail.service
-#    note: StandardOutput=truncate:/home/iank/.local/share/profanity/prof-tail.log
-#   /usr/local/bin/prof-tail
-#
 
 # /p/profanity-config/profrc & /d/p/profanity-config:
 # compose.editor=/usr/local/bin/prof-irc (alt-c)
diff --git a/filesystem/usr/local/bin/rs b/filesystem/usr/local/bin/rs
new file mode 100755 (executable)
index 0000000..0f1e551
--- /dev/null
@@ -0,0 +1,31 @@
+#!/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 switch
+# its license to GPL.
+
+# Copyright 2024 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+#     http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# rsync strips DISPLAY when launching ssh, which makes it so we can't
+# use ssh-askpass for multiplexing in the normal way, this works around
+# that, along with an askpass wrapper.
+if [[ $DISPLAY ]]; then
+  RSYNC_SSH_DISPLAY_HACK="$DISPLAY" SSH_ASKPASS_REQUIRE=force SSH_ASKPASS=/usr/local/bin/ssh-askpass-hack rsync "$@"
+else
+  rsync "$@"
+fi
diff --git a/filesystem/usr/local/bin/ssh-askpass-hack b/filesystem/usr/local/bin/ssh-askpass-hack
new file mode 100755 (executable)
index 0000000..d6554bc
--- /dev/null
@@ -0,0 +1,28 @@
+#!/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 switch
+# its license to GPL.
+
+# Copyright 2024 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+#     http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [[ ! $DISPLAY ]]; then
+  if [[ $RSYNC_SSH_DISPLAY_HACK ]]; then
+    export "DISPLAY=$RSYNC_SSH_DISPLAY_HACK"
+  fi
+fi
+/usr/bin/ssh-askpass "$@"
index 1abab5feba1f27f488219ab6c79edab7f46d7599..14096f29572d61338358b279ae48c51b69f52716 100644 (file)
@@ -129,8 +129,15 @@ slog() {
 
 # usage: m COMMAND...
 #
-# echo COMMAND then run it.
-m() { printf "+ %s\n" "$*" >&2;  "$@"; }
+# echo COMMAND then run it. Supports prefixed vars eg. x=3 cmd.
+m() {
+  printf "+ %s\n" "$*" >&2
+  while [[ $1 == *=* ]]; do
+    declare -x "$1"
+    shift
+  done
+  "$@"
+}
 
 # usage: mq COMMAND...
 #
@@ -141,15 +148,24 @@ mq() {
   if [[ $verbose == true ]]; then
     printf "+ %s\n" "$*" >&2
   fi
+  while [[ $1 == *=* ]]; do
+    declare -x "$1"
+    shift
+  done
   "$@"
 }
 
 # mb, maybe. echo args if they fail.
 mb() {
-  local ret=0
+  local evars ret=0
+  while [[ $1 == *=* ]]; do
+    declare -x "$1"
+    evars+="$1 "
+    shift
+  done
   "$@" || ret=$?
   if (( ret )); then
-    printf "error: exit code $ret from: %s\n" "$*" >&2
+    printf "error: exit code $ret from: %s\n" "$evars$*" >&2
   fi
   return $ret
 }
index 1ce27acd64afb8eae9d0fb8a5cd666c882ec511b..773b95bfa4422e532f15bf8a5ebfd574c687a258 100755 (executable)
@@ -134,7 +134,7 @@ runtest() {
 iptmod() { #iptables modify
   local cmd="$*"
   local exists=true
-  ${cmd/-[AD]/-C} &>/dev/null || exists=false
+  ${cmd/-[IAD]/-C} &>/dev/null || exists=false
   if runtest; then e $cmd; fi
 }
 
index 8e7050607a72a8e88d55c6d984ae59eb6fbd742a..14f7e8b3e683f774443c9fc85964e305a0a3fd1d 100755 (executable)
@@ -63,12 +63,21 @@ parse-rspamd() {
 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
+}
+ssh-lan() {
+  printf "Port 22\n" > /etc/ssh/sshd_config.d/iank.conf
+  systemctl reload ssh.service
+}
+
+
 maybe-toggle-ssh() {
 
   # something went wrong in this case.
-  if (( lock_check_fails >= 20 )); then
-    systemctl enable --now ssh.socket
-    systemctl start ssh.service
+  if (( lock_check_fails >= 2 )); then
+    ssh-wan
   fi
   export DISPLAY=:0
   export XAUTHORITY=/home/iank/.Xauthority
@@ -90,18 +99,12 @@ maybe-toggle-ssh() {
   if [[ $lock_info == *non-blanked* ]]; then
     if ! $deactivated_sshd; then
       deactivated_sshd=true
-      if systemctl is-active ssh; then
-        systemctl disable --now ssh.socket
-        systemctl stop ssh.service
-      fi
+      ssh-lan
     fi
     # if its been blanked more than a few minutes while I'm afk turn ssh back on.
   elif $deactivated_sshd && (( EPOCHSECONDS - lock_or_unlock_time > 60 * 2 )); then
     deactivated_sshd=false
-    if ! systemctl is-active ssh; then
-      systemctl enable --now ssh.socket
-      systemctl start ssh.service
-    fi
+    ssh-wan
   fi
 }
 
@@ -289,7 +292,7 @@ main() {
   local -a p_unexpected_spamd_results p_missing_dnswl p_last_usec
   case $HOSTNAME in
     bk)
-      folders=(/m/md/{amnimal.ninja}/testignore)
+      folders=(/m/md/amnimal.ninja/testignore)
       froms=(ian@iankelling.org z@zroe.org testignore@je.b8.nz iank@gnu.org)
       ;;
     je)