From f27b67a1dfa58b5f101bba607b2f91a73e65299e Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Wed, 12 Jun 2024 16:20:48 -0400 Subject: [PATCH] lots of fixes, improvements, t12 stuff --- .bashrc | 1 + .xsession | 1 + brc | 58 ++-- brc2 | 232 ++++++++++------ conflink | 14 +- copyq-clear | 40 +++ copyq-restart | 38 +++ .../etc/systemd/system/bitcoind.service | 0 .../filesystem}/usr/local/bin/bitcoinoff | 0 .../filesystem}/usr/local/bin/bitcoinon | 0 distro-begin | 77 +----- distro-end | 250 +++++++++++++----- epanic-clean | 11 +- ffp | 69 +++-- ffs | 201 +++++++++++--- .../etc/udev/rules.d/99-kaleidoscope.rules | 16 +- i3-event-hook | 14 +- i3-split-push | 3 +- i3-sway/common.conf | 21 +- i3-sway/gen | 2 + i3-sway/i3.conf | 2 +- laptop-xrandr | 27 +- machine_specific/s76.hosts | 3 - .../etc/X11/xorg.conf.d/20-intel.conf | 7 - mail-setup | 138 ++++++++-- mailtest-check | 9 +- mix | 23 ++ myi3status | 30 ++- pkgs | 18 +- rootsshsync | 6 +- script-files | 2 + ssh-emacs-setup | 19 +- stream-interlude | 13 +- .../share/kxmlgui5/konsole/sessionui.rc | 33 ++- system-status | 37 +-- toggle-mute | 93 ++++--- xl | 4 + ziva-screen | 10 +- 38 files changed, 1085 insertions(+), 437 deletions(-) create mode 100755 .xsession create mode 100755 copyq-clear create mode 100755 copyq-restart rename {filesystem => disabled/bitcoin/filesystem}/etc/systemd/system/bitcoind.service (100%) rename {filesystem => disabled/bitcoin/filesystem}/usr/local/bin/bitcoinoff (100%) rename {filesystem => disabled/bitcoin/filesystem}/usr/local/bin/bitcoinon (100%) delete mode 100644 machine_specific/s76.hosts delete mode 100644 machine_specific/s76/filesystem/etc/X11/xorg.conf.d/20-intel.conf create mode 100755 mix diff --git a/.bashrc b/.bashrc index 81853d0..0376fd6 100644 --- a/.bashrc +++ b/.bashrc @@ -20,6 +20,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +# shellcheck disable=SC2317 # to debug #set -x diff --git a/.xsession b/.xsession new file mode 100755 index 0000000..ba0c6ef --- /dev/null +++ b/.xsession @@ -0,0 +1 @@ +exec i3 diff --git a/brc b/brc index 8e1b327..4aacc47 100644 --- a/brc +++ b/brc @@ -1041,16 +1041,13 @@ cf() { 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 @@ -1733,10 +1730,21 @@ re() { # 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() { @@ -2049,6 +2057,8 @@ ksu() { # history search unique 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. @@ -2220,7 +2230,7 @@ grep ps and output in a nice format" 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" @@ -2541,10 +2551,10 @@ skq() { 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 @@ -3139,7 +3149,7 @@ spark() for n in $numbers do - _spark_echo -n ${ticks[$(( (((n-min)<<8)/f) ))]} + _spark_echo -n ${ticks[$(( ((n-min)<<8)/f ))]} done _spark_echo } @@ -3345,10 +3355,17 @@ if [[ $- == *i* ]]; then 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" @@ -3371,7 +3388,7 @@ if [[ $- == *i* ]]; then fi jobs_char= if [[ $(jobs -p) ]]; then - jobs_char='j\j ' + jobs_char="$(jobs -p)"'j\j ' fi @@ -3471,6 +3488,7 @@ lp22viewers() { 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 @@ -3493,6 +3511,16 @@ dsh() { 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 diff --git a/brc2 b/brc2 index 8406dab..c857670 100644 --- a/brc2 +++ b/brc2 @@ -29,9 +29,29 @@ if [[ $LESSHISTFILE == - ]]; then 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 @@ -329,10 +349,16 @@ tback() { # 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() { @@ -1749,7 +1775,13 @@ lipush() { 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 @@ -1780,7 +1812,7 @@ bindpush() { 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() { @@ -1904,68 +1936,12 @@ satoshi() { # $1 satoshi in usd # 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 @@ -2156,7 +2132,7 @@ fastboot() { kdecd() { /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd; } -bat() { +batp() { cat /sys/class/power_supply/BAT0/capacity } @@ -2701,6 +2677,7 @@ host-info-update() { # 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) @@ -2841,12 +2818,17 @@ EOF 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 </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 @@ -4366,11 +4367,24 @@ vrun() { } 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 } @@ -4387,14 +4401,24 @@ rgm() { 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" @@ -4795,6 +4819,50 @@ zmqsend() { 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 diff --git a/conflink b/conflink index da04cb9..0ca21f0 100755 --- a/conflink +++ b/conflink @@ -252,20 +252,24 @@ case $user in 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 diff --git a/copyq-clear b/copyq-clear new file mode 100755 index 0000000..85facdf --- /dev/null +++ b/copyq-clear @@ -0,0 +1,40 @@ +#!/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/dev/null; then @@ -497,7 +424,7 @@ pi ${p1[@]} ######## 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 diff --git a/distro-end b/distro-end index d99e6a1..dcf9198 100755 --- a/distro-end +++ b/distro-end @@ -18,6 +18,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later +# shellcheck disable=SC2317 # false positive export LC_USEBASHRC=t source /a/bin/ds/.bashrc @@ -205,10 +206,10 @@ EOF 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 @@ -748,13 +749,22 @@ EOF # 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: @@ -796,15 +806,18 @@ case $distro in # 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 </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 @@ -886,6 +932,29 @@ case $distro in 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) @@ -925,6 +994,19 @@ case $codename_compat in 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 @@ -938,19 +1020,21 @@ pi ${pall[@]} $(apt-cache search ruby[.0-9]+-doc| awk '{print $1}') $($src/distr # 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 <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 @@ -1833,6 +1941,7 @@ case $HOSTNAME in # 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' @@ -1882,10 +1991,9 @@ 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 @@ -1933,25 +2041,26 @@ esac ### 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 ### @@ -2106,6 +2215,27 @@ EOF 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 diff --git a/epanic-clean b/epanic-clean index c171746..c9739ba 100755 --- a/epanic-clean +++ b/epanic-clean @@ -50,6 +50,11 @@ v() { fi } +spamd_ser=spamd +if systemctl cat spamassassin &>/dev/null; then + spamd_ser=spamassassin +fi + pl=/var/log/exim4/paniclog main() { @@ -108,7 +113,7 @@ 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" @@ -129,9 +134,9 @@ main() { sed -ri "/$regex/d" $pl fi fi - done <<'EOF' + done <&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 @@ -50,7 +89,7 @@ opts=( -fast -fflags nobuffer -flags low_delay - -i http://localhost:8000/fsf$mount_suffix.webm + -i http://$host/fsf$mount_suffix.webm -autoexit ) ffplay "${opts[@]}" diff --git a/ffs b/ffs index 6975d38..0bb4ae7 100755 --- a/ffs +++ b/ffs @@ -24,8 +24,6 @@ # 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 @@ -130,32 +128,96 @@ shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4 set -eE -o pipefail trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" exit status: $?, PIPESTATUS: ${PIPESTATUS[*]}" >&2' ERR +usage() { + cat <&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 @@ -167,14 +229,20 @@ xrandr >$tmpf # 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 @@ -185,7 +253,12 @@ keyframe_interval=$((framerate * 2)) # 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/^$//').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 @@ -194,20 +267,24 @@ opts=( -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 @@ -218,6 +295,7 @@ opts=( ## video input options -video_size $stream_res + $thread_queue_size_arg -f x11grab -framerate $framerate -i :0.0+$x_offset.0 @@ -236,8 +314,17 @@ opts=( # 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 @@ -254,7 +341,6 @@ opts=( # 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 @@ -274,6 +360,10 @@ rm -f /tmp/iank-ffmpeg-interlude-toggle # 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 & } @@ -283,8 +373,57 @@ if $debug; then 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/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 diff --git a/filesystem/etc/udev/rules.d/99-kaleidoscope.rules b/filesystem/etc/udev/rules.d/99-kaleidoscope.rules index 9f14aaf..b238912 100644 --- a/filesystem/etc/udev/rules.d/99-kaleidoscope.rules +++ b/filesystem/etc/udev/rules.d/99-kaleidoscope.rules @@ -10,9 +10,13 @@ ## - 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" diff --git a/i3-event-hook b/i3-event-hook index 196e608..bcee20e 100755 --- a/i3-event-hook +++ b/i3-event-hook @@ -39,21 +39,21 @@ from i3ipc import Connection, Event 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): @@ -98,7 +98,7 @@ def focus_hook(i3, e): # 'window': None, # 'window_type': None, - parent, workspace = find_parent(i3, e.container.id) + workspace = find_workspace(i3, e.container.id) # debugging #exit(0) diff --git a/i3-split-push b/i3-split-push index f78ca9a..c760738 100755 --- a/i3-split-push +++ b/i3-split-push @@ -1,3 +1,5 @@ +#!/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 @@ -19,7 +21,6 @@ # 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. # diff --git a/i3-sway/common.conf b/i3-sway/common.conf index 738cd0d..40b1bb5 100644 --- a/i3-sway/common.conf +++ b/i3-sway/common.conf @@ -30,8 +30,6 @@ bindsym $mod+3 $ex "i3-split-maybe"; exec "abrowser" #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" @@ -110,15 +108,22 @@ bindsym $mod+z workspace 5 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 @@ -176,6 +181,8 @@ bindsym $mod+shift+semicolon $ex /b/ds/stream-clip sad # 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. diff --git a/i3-sway/gen b/i3-sway/gen index cf262ad..d4a4e7e 100755 --- a/i3-sway/gen +++ b/i3-sway/gen @@ -37,3 +37,5 @@ monitor_count=$(xrandr|grep -c ' connected') if [[ $1 == bar ]] || (( monitor_count >= 2 )); then cat bar.conf >> $dir/config fi + +i3-msg reload diff --git a/i3-sway/i3.conf b/i3-sway/i3.conf index bf1aba8..92f40dd 100644 --- a/i3-sway/i3.conf +++ b/i3-sway/i3.conf @@ -1,7 +1,7 @@ # 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 diff --git a/laptop-xrandr b/laptop-xrandr index 28c840e..6701e74 100755 --- a/laptop-xrandr +++ b/laptop-xrandr @@ -22,25 +22,32 @@ 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 /dev/null; then @@ -474,13 +473,30 @@ Pin-Priority: 500 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 @@ -509,6 +525,90 @@ fi # 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' @@ -775,25 +875,26 @@ 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 @@ -873,7 +974,7 @@ EOF 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 @@ -925,12 +1026,14 @@ EOF # 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 @@ -3181,6 +3284,7 @@ bounce_debbugs: 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. @@ -3200,14 +3304,14 @@ delay_iank: 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 @@ -3860,7 +3964,7 @@ case $HOSTNAME in ;;& $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. @@ -3894,7 +3998,7 @@ case $HOSTNAME in : ;; *) - soff radicale mailclean.timer dovecot spamassassin $vpnser mailnn clamav-daemon + soff radicale mailclean.timer dovecot $spamd_ser $vpnser mailnn clamav-daemon ;; esac diff --git a/mailtest-check b/mailtest-check index 856d774..fd27ae5 100755 --- a/mailtest-check +++ b/mailtest-check @@ -83,6 +83,11 @@ fi # 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 @@ -158,8 +163,8 @@ EOF 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 diff --git a/mix b/mix new file mode 100755 index 0000000..64d3703 --- /dev/null +++ b/mix @@ -0,0 +1,23 @@ +#!/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 "$@" diff --git a/myi3status b/myi3status index 2df9746..53b6458 100755 --- a/myi3status +++ b/myi3status @@ -177,21 +177,39 @@ main() { 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 '"},' diff --git a/pkgs b/pkgs index 8d58447..b051773 100644 --- a/pkgs +++ b/pkgs @@ -27,6 +27,7 @@ p1=( bind9-host cryptsetup + libpam-tmpdir lvm2 mbuffer moreutils @@ -91,13 +92,13 @@ p3=( 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 @@ -186,6 +187,9 @@ p3=( 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 @@ -202,9 +206,11 @@ p3=( 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 @@ -222,7 +228,6 @@ p3=( mhonarc mmdebstrap mp3gain - mps-youtube mpv mumble mupdf @@ -242,11 +247,9 @@ p3=( oathtool opendkim-tools p7zip-full - paprefs parted parted-doc pass - pavucontrol pdfgrep perl-doc pianobar @@ -259,20 +262,19 @@ p3=( 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 diff --git a/rootsshsync b/rootsshsync index 5395c44..9db6b73 100755 --- a/rootsshsync +++ b/rootsshsync @@ -63,7 +63,11 @@ if [[ -e $user_ssh_dir/config ]]; then # 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 diff --git a/script-files b/script-files index f4f4b93..1cbb6aa 100644 --- a/script-files +++ b/script-files @@ -53,6 +53,8 @@ my_bin_files=( i3-set-layout i3-split-maybe i3-split-push + copyq-restart + toggle-mute ) for f in /b/log-quiet/*; do diff --git a/ssh-emacs-setup b/ssh-emacs-setup index 309ab0a..9faf683 100755 --- a/ssh-emacs-setup +++ b/ssh-emacs-setup @@ -22,8 +22,8 @@ if [[ $EUID != 0 ]]; then - sudo "$0" - exit + sudo "$0" + exit fi # shellcheck source=/a/bin/ds/.bashrc if [[ -s ~/.bashrc ]];then . ~/.bashrc;fi @@ -39,11 +39,16 @@ cd "$this_dir" 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 diff --git a/stream-interlude b/stream-interlude index ea5812e..2fedf47 100755 --- a/stream-interlude +++ b/stream-interlude @@ -76,8 +76,11 @@ zsend() { } -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 diff --git a/subdir_files/.local/share/kxmlgui5/konsole/sessionui.rc b/subdir_files/.local/share/kxmlgui5/konsole/sessionui.rc index 66cabd0..9faefbf 100644 --- a/subdir_files/.local/share/kxmlgui5/konsole/sessionui.rc +++ b/subdir_files/.local/share/kxmlgui5/konsole/sessionui.rc @@ -1,6 +1,6 @@ - + @@ -15,6 +15,7 @@ + @@ -26,11 +27,14 @@ + + + @@ -45,28 +49,39 @@ + + Session Toolbar + 1 + + + + + + + + + + Split View + + + + + + - - Session Toolbar - 1 - - - - - diff --git a/system-status b/system-status index ae37d3b..745e335 100755 --- a/system-status +++ b/system-status @@ -309,6 +309,20 @@ write-status() { # 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* @@ -433,7 +447,12 @@ write-status() { 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() { @@ -483,24 +502,10 @@ main-loop() { if [[ -e /sys/class/power_supply/AC/online && $(&2; exit 1; fi shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4 @@ -27,40 +32,62 @@ set -eE -o pipefail 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 diff --git a/xl b/xl index cff3992..0751729 100755 --- a/xl +++ b/xl @@ -20,6 +20,10 @@ # 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. diff --git a/ziva-screen b/ziva-screen index 4f62c03..9a9aa6a 100755 --- a/ziva-screen +++ b/ziva-screen @@ -21,7 +21,7 @@ # 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]}" "$@" @@ -36,7 +36,7 @@ esac 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 ) @@ -45,9 +45,9 @@ if (( ${#jpgs[@]} >= 1 )); then 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 -- 2.30.2