#!/bin/bash # Copyright (C) 2019 Ian Kelling # SPDX-License-Identifier: AGPL-3.0-or-later # this gets sourced. shebang is just for file mode detection # * settings if [[ $LESSHISTFILE == - ]]; then HISTFILE= c() { cd "$@"; } elif [[ $HISTFILE ]]; then HISTFILE=$HOME/.bh fi source /a/bin/distro-setup/path-add-function path-add /a/exe # add this with absolute paths as needed for better security #path-add --end /path/to/node_modules/.bin ## for yarn, etc #path-add --end /usr/lib/node_modules/corepack/shims/ # pip3 --user things go here: path-add --end ~/.local/bin path-add --ifexists --end /a/work/libremanage path-add --ifexists --end /a/opt/adt-bundle*/tools /a/opt/adt-bundle*/platform-tools path-add --ifexists --end /a/opt/scancode-toolkit-3.10. path-add --ifexists --end /p/bin case $HOSTNAME in sy|bo) # https://askubuntu.com/questions/1254544/vlc-crashes-when-opening-any-file-ubuntu-20-04 if grep -qE '^VERSION_CODENAME="(nabia|focal)"' /etc/os-release &>/dev/null; then export MESA_LOADER_DRIVER_OVERRIDE=i965 fi ;; esac export WCDHOME=/a case $EUID in 0) SL_SSH_ARGS="-F $HOME/.ssh/confighome" ;; esac # * include files # generated instead of dynamic for the benefit of shellcheck #for x in /a/bin/distro-functions/src/* /a/bin/!(githtml)/*-function?(s); do echo source $x ; done source /a/bin/distro-functions/src/identify-distros source /a/bin/log-quiet/logq-function # for x in /a/bin/bash_unpublished/source-!(.#*); do echo source $x; done source /a/bin/bash_unpublished/source-semi-priv source /a/bin/bash_unpublished/source-state source /a/bin/log-quiet/logq-function if [[ -s /a/opt/alacritty/extra/completions/alacritty.bash ]]; then source /a/opt/alacritty/extra/completions/alacritty.bash fi # * functions multimic() { local i local -a sources m pactl unload-module module-loopback m pactl unload-module module-null-sink m pactl unload-module module-remap-source sources=($(pacmd list-sources | sed -rn 's/.*name: <([^>]+).*/\1/p')) if (( ! $# )); then i=0 for s in ${sources[@]}; do e $i $s i=$(( i+1 )) done read -r l set -- $l fi m pactl load-module module-null-sink sink_name=ianinput sink_properties=device.description=ianinputs for i; do m pactl load-module module-loopback source=${sources[i]} sink_dont_move=true sink=ianinput done pactl load-module module-remap-source source_name=iancombine master=ianinput.monitor source_properties=device.description=iancombine } # h ssh test # For testing restrictive ssh. hstest() { install-my-scripts d=$(mktemp -d) sed '/^ *IdentityFile/d' ~/.ssh/config >$d/config s command ssh -F $d/config -i /q/root/h "$@" } # h rsync test # For testing restrictive rsync hrtest() { # install-my-scripts d=$(mktemp -d) sed '/^ *IdentityFile/d' ~/.ssh/config >$d/config s rsync -e "ssh -F $d/config -i /q/root/h" "$@" } # rsync as root and avoid the default restrictive h key & config. rootrsync() { s rsync -e "ssh -F /root/.ssh/confighome" "$@" } zcheck() { ssh bow DISPLAY=:0 scrot /tmp/oegu.jpg scp bow:/tmp/oegu.jpg /t ssh bow rm /tmp/oegu.jpg feh /t/oegu.jpg } slemacs() { local arg rtime v arg="$1" remote="$2" if [[ $arg == [89]0Etiona* ]]; then v=${arg::1} rtime=${arg#*Etiona} # remote time if [[ ! $rtime ]]; then rtime=0 fi dir=/a/opt/emacs-trisquel${v}-nox/.iank ltime=$(stat -c%Y $dir/e/e/.emacs.d/init.el) if (( ltime > rtime )); then m rsync -rptL --delete --filter=". /b/ds/sl/rsync-filter" $dir "$remote":/home/iank fi fi } sle() { # sl emacs local f=/home/iank/.emacs.d/init.el sl --sl-test-cmd ". /etc/os-release ; printf %s \${VERSION//[^a-zA-Z0-9]/}; test -e $f && stat -c%Y $f" --sl-test-hook slemacs "$@" } ccomp ssh sle # Run this manually after .emacs.d changes. Otherwise, to check if # files changed with find takes 90ms. sl normally only adds 25ms. We # could cut it down to 10ms if we put things on a btrfs filesystem and # looked for changes there, or used some inotify thing, but that seems # like too much work. egh() { # emacs gnuhope RSYNC_RSH=ssh m rsync -rptL --delete --filter=". /b/ds/sl/rsync-filter" /a/opt/emacs-trisquel9-nox/.iank lists2d.fsf.org:.ianktrisquel_9 RSYNC_RSH=ssh m rsync -rptL --delete --filter=". /b/ds/sl/rsync-filter" /a/opt/emacs-trisquel8-nox/.iank lists2d.fsf.org:/home/iank } ekw() { local shell="bash -s" if [[ $HOSTNAME != kw ]]; then shell="ssh kw.office.fsf.org" bbk -m /a -t kw fi $shell <<'EOF' sudo mkdir /root/.ianktrisquel_9 sudo rsync -rptL --delete --filter=". /b/ds/sl/rsync-filter" /a/opt/emacs-trisquel9-nox/.iank /root/.ianktrisquel_9 rsync -rptL --delete --filter=". /b/ds/sl/rsync-filter" /a/opt/emacs-trisquel8-nox/.iank /home/iank EOF } rm-docker-iptables() { s iptables -S | gr docker | gr -- -A | sed 's/-A/-D/'| while read -r l; do sudo iptables $l; done s iptables -S -t nat | gr docker | gr -- -A | sed 's/-A/-D/'| while read -r l; do sudo iptables -t nat $l; done s iptables -S | gr docker | gr -- -N | sed 's/-N/-X/'| while read -r l; do sudo iptables $l; done s iptables -S -t nat | gr docker | gr -- -N | sed 's/-N/-X/'| while read -r l; do sudo iptables -t nat $l; done } # usage mkschroot [-] distro codename packages # - means no piping in of sources.list mkschroot() { local force=false while [[ $1 == -* ]]; do case $1 in -f) force=true; shift ;; -s) sources="$2" if [[ ! -s $sources ]]; then echo mkschroot: error: sources file $sources does not exist or is empty return 1 fi shift 2 ;; esac done distro=$1 shift case $distro in trisquel) repo=http://mirror.fsf.org/trisquel/ ;; ubuntu) repo=http://archive.ubuntu.com/ubuntu/ ;; debian) repo=http://deb.debian.org/debian/ ;; esac n=$1 shift if ! $force && schroot -l | grep -xFq chroot:$n; then echo "$0: $n schroot already installed, skipping" return 0 fi apps=($@) d=/nocow/schroot/$n sd /etc/schroot/chroot.d/$n.conf <> $f # fi # su iank # wget https://aur.archlinux.org/cgit/aur.git/snapshot/anbox-image-gapps.tar.gz # tar xzf anbox-image-gapps.tar.gz # cd anbox-image-gapps # makepkg -s } # clock back in to timetrack from last entry tback() { sqlite3 /p/.timetrap.db "update entries set end = NULL where id = (select max(id) from entries);" } # sshfs example: # s sshfs bu@$host:/bu/home/md /bu/mnt -o reconnect,ServerAliveInterval=20,ServerAliveCountMax=30 -o allow_other eqgo() { enn -M $(exiqgrep -i -r.\*) } eqgo1() { enn -M $(exipick -i -r.\*|h1) } gnupload(){ /a/f/gnulib/build-aux/gnupload "$@" } abrowserrmcompat() { local f ngset f=(/p/c/firefox*/compatibility.ini) if (( ${#f[@]} )); then rm ${f[@]} fi ngreset } checkre() { s checkrestart -b /a/bin/ds/checkrestart-blacklist -pv } cp-blocked-domains-to-brains() { cp /a/f/ans/roles/exim/files/mx/simple/etc/exim4/bad-sender_domains /a/f/brains/sysadmin/kb/blocked_email_domains.mdwn } cp-blocked-domains-to-ansible() { cp /a/f/brains/sysadmin/kb/blocked_email_domains.mdwn /a/f/ans/roles/exim/files/mx/simple/etc/exim4/bad-sender_domains } anki() { # crashes on adding new cards in t9 schroot -c buster -- anki } acat() { ngset hrcat /m/md/alerts/{cur,new}/* ngreset hr; echo bk; hr ssh bk.b8.nz "shopt -s nullglob; hrcat /m/md/INBOX/new/* /m/md/INBOX/cur/*" } aclear() { ngset rm -f /m/md/alerts/{cur,new}/* ngreset ssh bk.b8.nz "shopt -s nullglob; rm -f /m/md/INBOX/new/* /m/md/INBOX/cur/*" system-status _ } alerts() { find /var/local/cron-errors /home/iank/cron-errors /sysd-mail-once-state -type f } ralerts() { # remote alerts local ret shell # this list is duplicated in check-remote-mailqs for h in bk je li frodo kwwg x3wg x2wg kdwg sywg; do echo $h: shell="ssh $h" if [[ $HOSTNAME == "${h%wg}" ]]; then shell= fi ret=0 $shell find /var/local/cron-errors /home/iank/cron-errors /sysd-mail-once-state -type f || ret=$? if (( ret )); then echo ret:$ret fi done } ap() { # pushd in case current directory has an ansible.cfg file pushd /a/xans >/dev/null ansible-playbook -v -l ${1:- $(hostname -f)} site.yml popd >/dev/null } aw() { pushd /a/work/ans >/dev/null time ansible-playbook -i inventory adhoc.yml "$@" popd >/dev/null } ad() { pushd /a/bin/distro-setup/a >/dev/null ansible-playbook site.yml "$@" popd >/dev/null } astudio() { # googling android emulator libGL error: failed to load driver: r600 # lead to http://stackoverflow.com/a/36625175/14456 export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1 /a/opt/android-studio/bin/studio.sh "$@" &r; } # note, to check for glue records # First, find some the .org nameservers: # dig +trace iankelling.org # then, query one: # dig ns1.iankelling.org @b0.org.afilias-nst.org. # Now, compare for a domain that does have glue records setup (note the A # and AAAA records in ADDITIONAL SECTION, those are glue records like the # one I'm asking for): # $ dig ns1.gnu.org @b0.org.afilias-nst.org. # todo: make sm pull/push use systemd instead of the journal cat command bbk() { # btrbk wrapper local ret=0 c / local active=true systemctl is-active btrbk.timer || active=false if $active; then ser stop btrbk.timer fi btrbk_is_active=$(systemctl is-active btrbk.service ||:) case $btrbk_is_active in inactive|failed) : ;; *) echo "bbk: error: systemctl is-active btrbk.service output: $btrbk_is_active" if $active; then ser start btrbk.timer; fi return 1 ;; esac # run latest install-my-scripts # todo: consider changing this to srun and having the args come # from a file like /etc/default/btrbk, like is done in exim s jdo btrbk-run "$@" if $active; then if (( ret )); then echo bbk: WARNING: btrbk.timer not restarted due to failure else ser start btrbk.timer fi fi return $ret } faimon() { fai-monitor | pee cat "fai-monitor-gui -" } bfg() { java -jar /a/opt/bfg-1.12.14.jar "$@"; } bigclock() { xclock -digital -update 1 -face 'arial black-80:bold' } nnn() { /a/opt/nnn -H "$@"; } locat() { # log-once cat local files ngset files=(/var/local/cron-errors/* /home/iank/cron-errors/* /sysd-mail-once-state/*) case ${#files[@]} in 0) : ;; 1) echo ${files[0]} head ${files[0]} ;; *) head ${files[@]} ;; esac ngreset } scr() { screen -RD "$@" } # version of jdo for my non-root user jdo() { # comparison of alternative logging methods: # # systemd-run command (what this function does) # # If there is a user prompt, the program will detect that it is not # connected to a terminal and act in a non-interactive way, skipping # the prompt. This has the benefit that you know exactly how the # program will act if you want to move it into a service that runs # automatically. # # If run with sudo and command is a shell script which does a sleep, # it can (sometimes?) output some extra whitespace in front of # messages, more for each subsequent message. This can be avoided by # becoming root first. # # It logs the command's pid and exit code, which is nice. # # ### command |& ts | tee file.log # # If there is a user prompt, like "read -p prompt var", it will hang # without outputting the prompt. # # I've had a few times where ts had an error and I wasn't totally sure # if it was really the command or ts having the problem. # # Sometimes some output will get hidden until you hit enter. # # ### command |& pee cat logger # # This seems to work. I need to test more. # # ### command |& logger -s # # User prompts get confusingly prefixed to earlier output, and all log # entries get prefixed with annoying priority level. # # ### systemd-cat # # Had a few problems. One major one is that it exited in the middle of # a command on systemctl daemon-reload # # Related commands which can log a whole session: script, sudo, screen local cmd cmd_name jr_pid ret ret=0 cmd="$1" shift cmd_name=${cmd##*/} if [[ $cmd != /* ]]; then cmd=$(type -P "$cmd") fi # -q = quiet journalctl -qn2 -f -u "$cmd_name" & # Trial and error of time needed to avoid missing initial lines. # .5 was not reliable. 1 was not reliable. 2 was not reliable sleep 4 jr_pid=$! # note, we could have a version that does system --user, but if for example # it does sudo ssh, that will leave a process around that we can't kill # and it will leave the unit hanging around in a failed state needing manual # killing of the process. s systemd-run --uid $(id -u) --gid $(id -g) \ -E SSH_AUTH_SOCK=/run/openssh_agent \ --unit "$cmd_name" --wait --collect "$cmd" "$@" || ret=$? # The sleep lets the journal output its last line # before the prompt comes up. sleep .5 kill $jr_pid &>/dev/null ||: unset jr_pid fg &>/dev/null ||: # this avoids any err-catch (( $ret == 0 )) || return $ret } # service run, and watch the output srun() { local unit ret=0 unit=$1 journalctl -qn2 -f -u $unit & systemctl start $unit sleep 2 kill $jr_pid &>/dev/null ||: unset jr_pid fg &>/dev/null ||: } sm() { # switch mail host local tmp keyhash c / # run latest keyhash=$(s ssh-keygen -lf /root/.ssh/home | awk '{print $2}') tmp=$(s ssh-add -l | awk '$2 == "'$keyhash'"') if [[ ! $tmp ]]; then s ssh-add /root/.ssh/home fi install-my-scripts s jdo switch-mail-host "$@" return $ret } sh2() { # switch host2 local tmp keyhash c / # run latest keyhash=$(s ssh-keygen -lf /root/.ssh/home | awk '{print $2}') tmp=$(s ssh-add -l | awk '$2 == "'$keyhash'"') if [[ ! $tmp ]]; then s ssh-add /root/.ssh/home fi install-my-scripts s jdo switch-host2 "$@" return $ret } # shellcheck disable=SC2120 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 # 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}) a="-ahviSAXPH --specials --devices --delete --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:/ ## only li is debian11 #p[0]=/a/opt/emacs-trisuqel10 #p[1]=/a/opt/emacs-trisquel10-nox done m s rsync "$@" -ahviSAXPH root@li.b8.nz:/a/h/proposed-comments/ /a/h/proposed-comments || ret=$? return $ret } bkpush() { # no emacs. for running faster. p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts}) 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=$? return $ret } jepush() { # no emacs. for running faster. p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts}) 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=$? return $ret } bindpush() { dsign iankelling.org expertpathologyreview.com zroe.org amnimal.ninja lipush for h in li bk; do m sl $h <<'EOF' source ~/.bashrc m dnsup EOF done } bindpushb8() { lipush for h in li bk; do m sl $h <<'EOF' source ~/.bashrc m dnsb8 EOF done } dnsup() { conflink -f m ser reload named } dnsb8() { local f=/var/lib/bind/db.b8.nz m ser stop named m sleep 1 m sudo rm -fv $f.jnl $f.signed.jnl m sudo install -m 644 -o bind -g bind /p/c/machine_specific/vps/bind-initial/db.b8.nz $f m ser restart named } dnsecgen() { # keys generated like this # because of https://ftp.isc.org/isc/dnssec-guide/dnssec-guide.pdf # https://blog.apnic.net/2019/05/23/how-to-deploying-dnssec-with-bind-and-ubuntu-server/ # key length is longer than that guide because # we are using those at fsf and when old key lengths # become insecure, I want some extra time to update. # dnsecgen (in brc2) local 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 # eg Kb8.nz.+008+47995.key tag=47995 # in dnsimple, you add the long string from this. # in gandi, you add the long string from the .key file, # then see that the digest matches the ds. echo "tag is the number after DS" dnssec-dsfromkey -a SHA-256 $f done # For b8.nz, we let bind read the keys and sign, and # right now they have root ownership, so let them # get group read. chmod g+r *.private } dsign() { # create .signed file # note: full paths probably not needed. local arg for arg; do local zone=${arg#db.} local dir=/p/c/machine_specific/vps/filesystem/var/lib/bind dnssec-signzone -S -e +31536000 -o $zone -K $dir -d $dir $dir/db.$zone done } #### begin bitcoin related things btc() { local f=/etc/bitcoin/bitcoin.conf # importprivkey will timeout if using the default of 15 mins. # upped it to 1 hour. bitcoin-cli -rpcclienttimeout=60000 -$(s grep rpcuser= $f) -$(s grep rpcpassword= $f) "$@" } btcusd() { # $1 btc in usd local price price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)" printf "$%s\n" "$price" if [[ $1 ]]; then printf "$%.2f\n" "$(echo "scale=4; $price * $1"| bc -l)" fi } usdbtc() { # $1 usd in btc local price price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)" printf "$%s\n" "$price" if [[ $1 ]]; then # 100 mil satoshi / btc. 8 digits after the 1. printf "%.8f btc\n" "$(echo "scale=10; $1 / $price "| bc -l)" fi } satoshi() { # $1 satoshi in usd local price price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)" price=$(echo "scale=10; $price * 0.00000001"| bc -l) printf "$%f\n" "$price" if [[ $1 ]]; then printf "$%.2f\n" "$(echo "scale=10; $price * $1"| bc -l)" fi } #### end bitcoin related things cbfstool () { /a/opt/coreboot/build/cbfstool "$@"; } cgpl() { if (($#)); then cp /a/bin/data/COPYING "$@" else cp /a/bin/data/COPYING . fi } capache() { if (($#)); then cp /a/bin/data/LICENSE "$@" else cp /a/bin/data/LICENSE . fi } chrome() { if type -p chromium &>/dev/null; then cmd=chromium else cd / cmd="schroot -c bullseye chromium" CHROMIUM_FLAGS='--enable-remote-extensions' $cmd &r fi } # do all tee. # pipe to this, or just type like a shell # todo: test this dat() { tee >(ssh frodo.b8.nz) >(ssh x2) >(ssh tp.b8.nz) >(ssh kw) >(ssh tp.b8.nz) } da() { # do all local host for host in x2 kw tp.b8.nz x3.b8.nz frodo.b8.nz; do ssh $host "$@" done } debian_pick_mirror () { # netselect-apt finds a fast mirror. # but we need to replace the mirrors ourselves, # because it doesnt do that. best it can do is # output a basic sources file # here we get the server it found, get the main server we use # then substitute all instances of one for the other in the sources file # and backup original to /etc/apt/sources.list-original. # this is idempotent. the only way to identify debian sources is to # note the original server, so we put it in a comment so we can # identify it later. local file file=$(mktemp -d)/f # safe way to get file name without creating one sudo netselect-apt -o "$file" || return 1 url=$(grep ^\\w $file | head -n1 | awk '{print $2}') sudo cp -f /etc/apt/sources.list /etc/apt/sources.list-original sudo sed -ri "/http.us.debian.org/ s@( *[^ #]+ +)[^ ]+([^#]+).*@\1$url\2# http.us.debian.org@" /etc/apt/sources.list sudo apt-get update } digme() { digdiff @ns{1,2}.iankelling.org "$@" } tsr() { # ts run "$@" |& ts || return $? } dup() { local ran_d ran_d=false system-status _ case $PS1 in *[\ \]]D\ *) pushd / /b/ds/distro-begin |& ts || return $? /b/ds/distro-end |& ts || return $? popd ran_d=true ;;& *[\ \]]DB\ *) pushd / /b/ds/distro-begin |& ts || return $? popd ran_d=true ;; *[\ \]]DE\ *) pushd / /b/ds/distro-end |& ts || return $? popd ran_d=true ;;& *CONFLINK*) if ! $ran_d; then conflink fi ;; esac system-status _ } envload() { # load environment from a previous: export > file local file=${1:-$HOME/.${USER}_env} eval "$(export | sed 's/^declare -x/export -n/')" while IFS= read -r line; do # declare -x makes variables local to a function eval ${line/#declare -x/export} done < "$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 "$@"; } kdecd() { /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd; } bat() { cat /sys/class/power_supply/BAT0/capacity } # List of apps to install/update # Create from existing manually installed apps by doing # fdroidcl update # fdroidcl search -i, then manually removing # automatically installed/preinstalled apps # # # my attempt at recovering from boot loop: # # in that case, boot to recovery (volume up, home button, power, let go of power after samsun logo) # # then # mount /dev/block/mmcblk0p12 /data # cd /data # find -iname '*appname*' # rm -rf FOUND_DIRS # usually good enough to just rm -rf /data/app/APPNAME # # currently broken: # # causes replicant to crash # org.quantumbadger.redreader # org.kde.kdeconnect_tp # not broke, but wont work without gps #com.zoffcc.applications.zanavi # not broke, but not using atm #com.nutomic.syncthingandroid # # doesn\'t work on replicant #net.sourceforge.opencamera # fdroid_pkgs=( net.mullvad.mullvadvpn org.schabi.newpipe io.github.subhamtyagi.lastlauncher io.anuke.mindustry com.biglybt.android.client de.marmaro.krt.ffupdater me.ccrama.redditslide org.fedorahosted.freeotp at.bitfire.davdroid com.alaskalinuxuser.justnotes com.artifex.mupdf.viewer.app com.danielkim.soundrecorder com.fsck.k9 com.ichi2.anki com.jmstudios.redmoon com.jmstudios.chibe org.kde.kdeconnect_tp com.notecryptpro com.termux cz.martykan.forecastie de.danoeh.antennapod de.blinkt.openvpn de.marmaro.krt.ffupdater eu.siacs.conversations free.rm.skytube.oss im.vector.alpha # riot info.papdt.blackblub me.tripsit.tripmobile net.gaast.giggity net.minetest.minetest net.osmand.plus org.isoron.uhabits org.linphone org.gnu.icecat org.smssecure.smssecure org.yaaic sh.ftp.rocketninelabs.meditationassistant.opensource ) # https://forum.xda-developers.com/android/software-hacking/wip-selinux-capable-superuser-t3216394 # for maru, #me.phh.superuser fdup() { local -A installed updated local p # tried putting this in go buildscript cronjob, # but it failed with undefined: os.UserCacheDir. I expect its due to # an environment variable missing, but its easier just to stick it here. m go get -u mvdan.cc/fdroidcl || return 1 m fdroidcl update if fdroidcl search -u | grep ^org.fdroid.fdroid; then fdroidcl install org.fdroid.fdroid sleep 5 m fdroidcl update fi for p in $(fdroidcl search -i| grep -o "^\S\+"); do installed[$p]=true done for p in $(fdroidcl search -u| grep -o "^\S\+"); do updated[$p]=false done for p in ${fdroid_pkgs[@]}; do if ! ${installed[$p]:-false}; then m fdroidcl install $p # sleeps are just me being paranoid since replicant has a history of crashing when certain apps are installed sleep 5 fi done for p in ${!installed[@]}; do if ! ${updated[$p]:-true}; then m fdroidcl install $p sleep 5 fi done } firefox-default-profile() { key=Default value=1 section=$1 file=/p/c/subdir_files/.mozilla/firefox/profiles.ini sed -ri "/^ *$key/d" "$file" sed -ri "/ *\[$section\]/,/^ *\[[^]]+\]/{/^\s*$key[[:space:]=]/d};/ *\[$section\]/a $key=$value" "$file" } fdhome() { #firefox default home profile firefox-default-profile Profile0 } fdwork() { firefox-default-profile Profile4 } ff() { if type -P firefox &>/dev/null; then firefox "$@" else iceweasel "$@" fi } fn() { firefox -P alt "$@" >/dev/null 2>&1 } fsdiff () { local missing=false local dname="${PWD##*/}" local m="/a/tmp/$dname-missing" local d="/a/tmp/$dname-diff" [[ -e $d ]] && rm "$d" [[ -e $m ]] && rm "$m" local msize=0 local fsfile while read -r line; do fsfile="$1${line#.}" if [[ -e "$fsfile" ]]; then md5diff "$line" "$fsfile" && tee -a "/a/tmp/$dname-diff" <<< "$fsfile $line" else missing=true echo "$line" >> "$m" msize=$((msize + 1)) fi done < <(find . -type f ) if $missing; then echo "$m" (( msize <= 100 )) && cat $m fi } fsdiff-test() { # expected output, with different tmp dirs # /tmp/tmp.HDPbwMqdC9/c/d ./c/d # /a/tmp/tmp.qLDkYxBYPM-missing # ./b cd $(mktemp -d) echo ok > a echo nok > b mkdir c echo ok > c/d local x x=$(mktemp -d) mkdir $x/c echo different > $x/c/d echo ok > $x/a fsdiff $x } rename-test() { # test whether missing files were renamed, generally for use with fsdiff # $1 = fsdiff output file, $2 = directory to compare to. pwd = fsdiff dir # echos non-renamed files local x y found unset sums for x in "$2"/*; do { sums+=( "$(md5sum < "$x")" ) ; } 2>/dev/null done while read -r line; do { missing_sum=$(md5sum < "$line") ; } 2>/dev/null renamed=false for x in "${sums[@]}"; do if [[ $missing_sum == "$x" ]]; then renamed=true break fi done $renamed || echo "$line" done < "$1" return 0 } feh() { # F = fullscren, z = random, Z = auto zoom command feh -FzZ "$@" } fw() { firefox -P default "$@" >/dev/null 2>&1 } gitian() { git config user.email ian@iankelling.org } # at least in flidas, things rely on gpg being gpg1 gpg() { if type -P gpg2 &>/dev/null; then command gpg2 "$@" else command gpg "$@" fi } gse() { local email=ian@iankelling.org git send-email --notes "--envelope-sender=<$email>" \ --suppress-cc=self "$@" } gup() { /a/f/gnulib/build-aux/gnupload "$@"; } dejagnu() { /a/opt/dejagnu/dejagnu "$@"; } hstatus() { # do git status on published repos. c /a/bin/githtml for x in *; do cd $(readlink -f $x)/.. status=$(i status -s) || pwd if [[ $status ]]; then hr echo $x printf "%s\n" "$status" fi cd /a/bin/githtml done } # work log wlog() { local day now i days_back days_back=${1:-16} for (( i=0; i /dev/null ; then gio open "$@" elif type gvfs-open &> /dev/null ; then gvfs-open "$@" else xdg-open "$@" fi # another alternative is run-mailcap } ccomp xdg-open o # jfilter() { # grep -Evi -e "^(\S+\s+){4}(sudo|sshd|cron)\[\S*:" \ # -e "^(\S+\s+){4}systemd\[\S*: (starting|started) (btrfsmaintstop|dynamicipupdate|spamd dns bug fix cronjob|rss2email)\.*$" # } # jtail() { # journalctl -n 10000 -f "$@" | jfilter # } # jr() { journalctl "$@" | jfilter | less ; } # jrf() { journalctl -n 200 -f "$@" | jfilter; } jr() { journalctl "$@" ; } jrf() { journalctl -n 200 -f "$@" ; } ccomp journalctl jtail jr jrf kff() { # keyboardio firmware flash. you must hold down the tilde key pushd /a/opt/Model01-Firmware # if we didn't want this yes hack, then remove "shell read" from # /a/opt/Kaleidoscope/etc/makefiles/sketch.mk yes $'\n' | VERBOSE=1 make flash popd } wgkey() { local umask_orig name if (( $# != 1 )); then e expected 1 arg >&2 return 1 fi name=$1 umask_orig=$(umask) umask 0077 wg genkey | tee $name-priv.key | wg pubkey > $name-pub.key umask $umask_orig } wghole() { if (( $# != 2 )); then e expected 2 arg of hostname, ip suffix >&2 return 1 fi local host ipsuf umask_orig host=$1 ipsuf=$2 mkdir -p /p/c/machine_specific/$host/filesystem/etc/wireguard cd /p/c/machine_specific/$host/filesystem/etc/wireguard umask_orig=$(umask) umask 0077 wg genkey | tee hole-priv.key | wg pubkey > hole-pub.key cat >wghole.conf </dev/null } mns() { # mount namespace ns=$1 shift s mkdir -p /root/mount_namespaces if ! sudo mountpoint /root/mount_namespaces >/dev/null; then m sudo mount --bind /root/mount_namespaces /root/mount_namespaces fi m sudo mount --make-private /root/mount_namespaces if [[ ! -e /root/mount_namespaces/$ns ]]; then m sudo touch /root/mount_namespaces/$ns fi if ! sudo mountpoint /root/mount_namespaces/$ns >/dev/null; then m sudo unshare --propagation slave --mount=/root/mount_namespaces/$ns /bin/true fi m sudo -E /usr/bin/nsenter --mount=/root/mount_namespaces/$ns "$@" } mnsr() { # mns run local ns=$1 shift mns $ns sudo -u iank -E env "PATH=$PATH" "$@" } mnsnonet() { ns=$1 lomh if ! s ip netns list | grep -Fx nonet &>/dev/null; then s ip netns add nonet fi mns $ns --net=/var/run/netns/nonet sudo -E -u iank /bin/bash lomh } lom() { # l = the loopback device local l base if [[ $1 == /* ]]; then base=${1##*/} fs_file=$1 if mns $base mountpoint -q /mnt/$base; then return 0 fi l=$(losetup -j $fs_file | sed -rn 's/^([^ ]+): .*/\1/p' | head -n1 ||:) if [[ ! $l ]]; then l=$(sudo losetup -f) m sudo losetup $l $fs_file fi if ! sudo cryptsetup status /dev/mapper/$base &>/dev/null; then if ! sudo cryptsetup luksOpen $l $base; then m sudo losetup -d $l return 1 fi fi m sudo mkdir -p /mnt/$base m mns $base mount /dev/mapper/$base /mnt/$base m mns $base chown $USER:$USER /mnt/$base lomh else base=$1 if mns $base mountpoint /mnt/$base &>/dev/null; then m mns $base umount /mnt/$base fi if sudo cryptsetup status /dev/mapper/$base &>/dev/null; then if ! m sudo cryptsetup luksClose /dev/mapper/$base; then echo lom: failed cryptsetup luksClose /dev/mapper/$base return 1 fi fi l=$(losetup -l --noheadings | awk '$6 ~ /\/'$base'$/ {print $1}') if [[ $l ]]; then m sudo losetup -d $l else echo lom: warning: no loopback device found fi fi } # mu personality. for original, just run mp. for 2, run mp 2. # this is partly duplicated in mail-setup mp() { local dead=false for s in {1..5}; do if ! killall mu; then dead=true break fi sleep 1 done if ! $dead; then echo error: mu not dead m psg mu return 1 fi suf=$1 set -- /m/mucache ~/.cache/mu /m/.mu ~/.config/mu while (($#)); do target=$1$suf f=$2 shift 2 if [[ -e $f && ! -L $f ]]; then m rm -rf $f fi m ln -sf -T $target $f done } # maildir enable mdenable() { local md dst ln_path src two two=false case $1 in -2) two=true shift ;; esac for md; do src= if $two; then dst=/m/4e2/$md else dst=/m/4e/$md fi ln_path=/m/md/$md for d in /m/md/$md /m/4e2/$md; do if [[ -d $d && ! -L $d ]]; then src=$d break fi done if [[ ! $src ]]; then echo "error: could not find $md" >&2 return 1 fi m mv -T $src $dst m ln -sf -T $dst $ln_path done } md2enable() { mdenable -2 "$@" } mddisable() { local md=$1 dst=/m/md/$md ### begin copied from mdenable, but different d ### for d in /m/4e/$md /m/4e2/$md; do if [[ -d $d && ! -L $d ]]; then src=$d break fi done if [[ ! $src ]]; then echo "error: could not find $md" >&2 return 1 fi ### end copy from mdenable ### if [[ -L $dst ]]; then m rm $dst; fi m mv -T $src $dst } mdt() { markdown "$1" >/tmp/mdtest.html firefox /tmp/mdtest.html } mo() { xset dpms force off; } # monitor off mpvgpu() { # seems to be the best gpu decoding on my nvidia 670. # vlc gets similar or better framerate, but is much darker output on my test movie at least. case $HOSTNAME in kd) echo 0f | sudo tee -a /sys/kernel/debug/dri/0/pstate ;; esac # going back to the default slow clock, and slower fan: # echo 07 | sudo tee -a /sys/kernel/debug/dri/0/pstate if [[ $DISPLAY ]]; then mpv --vo=vdpau --hwdec=auto "$@" else # waylandvk seems to work the same mpv --gpu-context=wayland --hwdec=auto fi } mpvd() { mpv --profile=d "$@"; } # mpv all media files in . or $1 mpvm() { local -a extensions arg # 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' extensions=( .webm .mkv .flv .flv .vob .ogv .ogg .drc .gif .gifv .mng .avi .MTS .M2TS .TS .mov .qt .wmv .yuv .rm .rmvb .viv .asf .amv .mp4 .m4p .m4v .mpg .mp2 .mpeg .mpe .mpv .mpg .mpeg .m2v .m4v .svi .3gp .3g2 .mxf .roq .nsv ) arg=("(" -iname "*${extensions[0]}") for (( i=1 ; i < ${#extensions[@]}; i++ )); do arg+=(-o -iname "*${extensions[i]}") done arg+=(")") dir=${1:-.} # debug: #find $dir "${arg[@]}" -size +200k find $dir "${arg[@]}" -size +200k -exec mpv --profile=d '{}' + } mpvs() { mpv --profile=s "$@"; } myirc() { if [[ ! $1 ]]; then set -- fsf-office fi local d1 d2 d=( /var/lib/znc/moddata/log/iank/{freenode,libera} ) # use * instead of -r since that does sorted order ssh root@iankelling.org "for f in ${d[@]}; do cd \$f/#$1; grep '\= nth )); do name="$(echo "$name" | head -n $nth | tail -n 1 )" read -r -p "$name [Y/n] " ask if [[ ! $ask || $ask == [Yy] ]]; then x=$( echo "$name" | gr -o "^\s*[0-9]*" ) echo $x | restore-trash > /dev/null elif [[ $ask == [Nn] ]]; then nth=$((nth+1)) else return fi done } pub() { rld /a/h/_site/ li:/var/www/iankelling.org/html } pumpa() { # fixes the menu bar in xmonad. this won\'t be needed when xmonad # packages catches up on some changes in future (this is written in # 4/2017) # # geekosaur: so youll want to upgrade to xmonad 0.13 or else use a # locally modified XMonad.Hooks.ManageDocks that doesnt set the # work area; turns out it\'s impossible to set correctly if you are # not a fully EWMH compliant desktop environment # # geekosaur: chrome shows one failure mode, qt/kde another, other # gtk apps a third, ... I came up with a setting that works for me # locally but apparently doesnt work for others, so we joined the # other tiling window managers in giving up on setting it at all # xprop -root -remove _NET_WORKAREA command pumpa & r } # reviewboard, used at my old job #rbpipe() { rbt post -o --diff-filename=- "$@"; } #rbp() { rbt post -o "$@"; } rebr() { sudo ifdown br0 sudo ifup br0 } r2e() { command r2e -d /p/c/rss2email.json -c /p/c/rss2email.cfg "$@"; } # only run on MAIL_HOST. simpler to keep this on one system. r2eadd() { # usage: name url # initial setup of rss2email: # r2e new r2e@iankelling.org # that initializes files, and sets default email. # symlink to the config doesnt work, so I copied it to /p/c # and then use cli option to specify explicit path. # Only option changed from default config is to set # force-from = True # # or else for a few feeds, the from address is set by the feed, and # if I fail delivery, then I send a bounce message to that from # address, which makes me be a spammer. r2e add $1 "$2" $1@r2e.iankelling.org # get up to date and dont send old entries now: r2e run --no-send $1 } rspicy() { # usage: HOST DOMAIN # connect to spice vm remote host. use vspicy for local host local port # shellcheck disable=SC2087 port=$(ssh $1<$tmp/timing # todo, the current sleep seems pretty good, but it # would be nice to have an empirical measurement, or # some better wait to sync up. # # note: --loop-file=no prevents it from hanging if you have that # set to inf the mpv config. # --loop=no prevents it from exit code 3 due to stdin if you # had it set to inf in mpv config. # # args go to mpv, for example --volume=80, 50% cat >$out <&2 return 1 fi spamdpid=$(systemctl status spamassassin| sed -n '/^ *Main PID:/s/[^0-9]//gp') spamcpre="nsenter -t $spamdpid -n -m" s $spamcpre sudo -u Debian-exim spamassassin -t --cf='score PYZOR_CHECK 0' <"$1" } # mail related testmail() { declare -gi _seq; _seq+=1 echo "test body" | m mail -s "test mail from $HOSTNAME, $_seq" "${@:-root@localhost}" # for testing to send from an external address, you can do for example # -fian@iank.bid -aFrom:ian@iank.bid web-6fnbs@mail-tester.com # note in exim, you can retry a deferred message # s exim -M MSG_ID # MSG_ID is in /var/log/exim4/mainlog, looks like 1ccdnD-0001nh-EN } # to test sieve, use below command. for fsf mail, see offlineimap-sync script # make modifications, then copy to live file, use -eW to actually modify mailbox # # Another option is to use sieve-test SCRIPT MAIL_FILE. note, # sieve-test doesnt know about envelopes, Im not sure if sieve-filter does. # sieve with output filter. arg is mailbox, like INBOX. # This depends on dovecot conf, notably mail_location in /etc/dovecot/conf.d/10-mail.conf # always run this first, edit the test files, then run the following testsieve() { sieve-filter ~/sieve/maintest.sieve ${1:-INBOX} delete 2> >(head; tail) >/tmp/testsieve.log && sed -rn '/^Performed actions:/,/^[^ ]/{/^ /p}' /tmp/testsieve.log | sort | uniq -c } runsieve() { c ~/sieve; cp personal{test,}.sieve; cp lists{test,}.sieve; cp personalend{test,}.sieve sieve-filter -eWv ~/sieve/maintest.sieve ${1:-INBOX} delete &> /tmp/testsieve.log sed -r '/^info: filtering:/{h;d};/^info: msgid=$/N;/^info: msgid=.*left message in mailbox [^ ]+$/d;/^info: msgid=/{H;g};/^info: message kept in source mailbox.$/d' /tmp/testsieve.log } # usage: # alertme SUBJECT # printf "subject\nbody\n" | alertme alertme() { if [[ -t 0 ]]; then exim -t <' $to < To: $to Subject: Mail delivery failed: returning message to sender This message was created automatically by mail delivery software. EOF } # toggle keyboard tk() { # based on # https://askubuntu.com/questions/160945/is-there-a-way-to-disable-a-laptops-internal-keyboard id=$(xinput --list --id-only 'AT Translated Set 2 keyboard') if xinput list | grep -F '∼ AT Translated Set 2 keyboard' &>/dev/null; then echo enabling keyboard # find the first slave keyboard number, they are all the same in my output. # if they werent, worst case we would need to save the slave number somewhere # when it got disabled. slave=$(xinput list | sed -n 's/.*slave \+keyboard (\([0-9]*\)).*/\1/p' | head -n1) xinput reattach $id $slave else xinput float $id fi } tm() { # timer in minutes # --no-config (sleep $(calc "$* * 60") && mpv --no-config --volume 50 /a/bin/data/alarm.mp3) > /dev/null 2>&1 & } trg() { transmission-remote-gtk & r; } trc() { # example, set global upload limit to 100 kilobytes: # trc -u 100 TR_AUTH=":$(jq -r .profiles[0].password ~/.config/transmission-remote-gtk/config.json)" transmission-remote transmission.lan -ne "$@" } trysleep() { retries="$1" sleepsecs="$2" shift 2 for (( i=0; i < retries - 1; i++ )); do if "$@"; then return 0 fi sleep $sleepsecs done "$@" } tu() { local s if [[ -e $1 && ! -w $1 || ! -w $(dirname "$1") ]]; then s=s; fi # full path for using in some initial setup steps $s /a/exe/teeu "$@" } enn() { local ecmd pid ecmd="/usr/sbin/exim4 -C /etc/exim4/my.conf" if ip a show veth1-mail &>/dev/null; then s $ecmd "$@" return fi pid=$(pgrep -f "/usr/sbin/exim4 -bd -q30m -C /etc/exim4/my.conf"|h1) m s nsenter -t $pid -n -m $ecmd "$@" } # get pid of systemd service servicepid() { local pid unit dir unit="$1" pid=$(systemctl show --property MainPID --value "$unit") case $pid in [1-9]*) : ;; *) dir=/sys/fs/cgroup/system.slice if [[ ! -d $dir ]]; then # t10 and older directory. dir=/sys/fs/cgroup/systemd/system.slice fi # 0 or empty. This file includes the MainPid, so I expect we # could just get this in the first place, but i don't know if that # is always the case. pid=$(head -n1 $dir/${unit%.service}.service/cgroup.procs) ;; esac if [[ $pid ]]; then printf "%s\n" "$pid" else return 1 fi } sdnbash() { # systemd namespace bash local unit pid if (( $# != 1 )); then echo $0: error wrong number of args >&2 return 1 fi unit=$1 pid=$(servicepid $unit) m sudo nsenter -t $pid -n -m sudo -u $USER -i bash } sdnbashroot() { # systemd namespace bash local unit pid if (( $# != 1 )); then echo $0: error wrong number of args >&2 return 1 fi unit=$1 pid=$(servicepid $unit) m sudo nsenter -t $pid -n -m bash } sdncmd() { # systemd namespace cmd local unit pid if (( $# <= 2 )); then echo $0: error wrong number of args >&2 return 1 fi unit=$1 shift pid=$(servicepid $unit) m sudo nsenter -t $pid -n -m sudo -u $USER -i "$@" } mailnnbash() { sdnbash mailnn } # we use wireguard now, use mailnnbash. # mailvpnbash() { # m sudo nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*mail.conf") -n -m sudo -u $USER -i bash # } eximbash() { local pid pid=$(pgrep -f "/usr/sbin/exim4 -bd -q30m -C /etc/exim4/my.conf"|h1) if [[ ! $pid ]]; then echo "eximbash: failed to find exim pid. systemctl -n 30 status exim4:" systemctl status exim4 fi m sudo nsenter -t $pid -n -m } spamnn() { local spamdpid spamdpid=$(systemctl show --property MainPID --value spamassassin) m sudo nsenter -t $spamdpid -n -m sudo -u Debian-exim spamassassin "$@" } unboundbash() { m sudo nsenter -t $(systemctl status unbound| sed -n '/^ *Main PID:/s/[^0-9]//gp') -n -m sudo -u $USER -i bash } nmtc() { s nmtui-connect "$@" } mailnncheck() { local unit pid ns mailnn # mailvpn would belong on the list if using openvpn for unit in mailnn unbound dovecot spamassassin exim4 radicale; do pid=$(servicepid $unit) echo debug: unit=$unit pid=$pid if [[ ! $pid ]]; then echo failed to find pid for unit=$unit continue fi if ! ns=$(s readlink /proc/$pid/ns/net); then echo failed to find ns for unit=$unit pid=$pid continue fi if [[ $mailnn ]]; then if [[ $ns != "$mailnn" ]]; then echo "$unit ns $ns != $mailnn" fi else mailnn=$ns fi done } vpncmd() { m sudo -E env "PATH=$PATH" nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*client.conf") -n "$@" } vpni() { vpncmd sudo -u iank env "PATH=$PATH" "$@" } vpnbash() { vpncmd bash } vpn() { if [[ -e /lib/systemd/system/openvpn-client@.service ]]; then local vpn_service=openvpn-client else local vpn_service=openvpn fi [[ $1 ]] || { echo need arg; return 1; } journalctl --unit=$vpn_service@$1 -f -n0 & # sometimes the journal doesnt open until after the vpn output # has happened. hoping this fixes that. sleep 1 sudo systemctl start $vpn_service@$1 # sometimes the ask-password agent does not work and needs a delay. sleep .5 # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=779240 # noticed around 8-2017 after update from around stretch release # on debian testing, even though the bug is much older. sudo systemd-tty-ask-password-agent } fixu() { local stats ls -lad /run/user/1000 stats=$(stat -c%a-%g-%u /run/user/1000) if [[ $stats != 700-1000-1000 ]]; then m s chmod 700 /run/user/1000; m s chown iank.iank /run/user/1000 fi } # systemctl is-enabled / status / cat says nothing, instead theres # some obscure symlink. paths copied from man systemd.unit. # possibly also usefull, but incomplete, doesnt show units not loaded in memory: # seru list-dependencies --reverse --all UNIT sysd-deps() { local f local -a dirs search ngset case $1 in u) search=( ~/.config/systemd/user.control/* $XDG_RUNTIME_DIR/systemd/user.control/* $XDG_RUNTIME_DIR/systemd/transient/* $XDG_RUNTIME_DIR/systemd/generator.early/* ~/.config/systemd/user/* /etc/systemd/user/* $XDG_RUNTIME_DIR/systemd/user/* /run/systemd/user/* $XDG_RUNTIME_DIR/systemd/generator/* ~/.local/share/systemd/user/* /usr/lib/systemd/user/* $XDG_RUNTIME_DIR/systemd/generator.late/* ) ;; *) search=( /etc/systemd/system.control/* /run/systemd/system.control/* /run/systemd/transient/* /run/systemd/generator.early/* /etc/systemd/system/* /etc/systemd/systemd.attached/* /run/systemd/system/* /run/systemd/systemd.attached/* /run/systemd/generator/* /lib/systemd/system/* /run/systemd/generator.late/* ) ;; esac for f in "${search[@]}"; do [[ -d $f ]] || continue case $f in *.requires|*.wants) dirs+=("$f") ;; esac done # dirs is just so we write out the directory names, ls does it when there is 2 or more dirs. case ${#dirs[@]} in 1) echo "${dirs[0]}:" ll "${dirs[@]}" ;; 0) : ;; *) ll "${dirs[@]}" ;; esac ngreset } fixvpndns() { local link istls read _ link _ istls < <(resolvectl dnsovertls tunfsf) case $istls in yes|no) : ;; *) echo fixvpndns error: unexpected istls value: $istls >&2; return 1 ;; esac s busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1 org.freedesktop.resolve1.Manager SetLinkDNSOverTLS is $link no } vpnoff() { [[ $1 ]] || { echo need arg; return 1; } if [[ -e /lib/systemd/system/openvpn-client@.service ]]; then local vpn_service=openvpn-client else local vpn_service=openvpn fi sudo systemctl stop $vpn_service@$1 } vpnoffc() { # vpn off client ser stop openvpn-client-tr@client } vpnc() { ser start openvpn-client-tr@client } vspicy() { # usage: VIRSH_DOMAIN # connect to vms made with virt-install spicy -p $(sudo virsh dumpxml "$1"|grep "\0,' } reset-xscreensaver() { # except for spash, i set these by setting gui options in # xscreensaver-command -demo # then finding the corresponding option in .xscreensaver # spash, i happened to notice in .xscreensaver # # dpmsOff, monitor doesnt come back on using old free software supported nvidia card cat > /home/iank/.xscreensaver <<'EOF' mode: blank dpmsEnabled: True dpmsStandby: 0:07:00 dpmsSuspend: 0:08:00 dpmsOff: 0:00:00 timeout: 0:05:00 lock: True lockTimeout: 0:06:00 splash: False EOF } # very useful, copy directory structure 3 deep. add remove /*/ to change level # rsync -aivh --exclude '/*/*/*/' -f"+ */" -f"- *" SRC DEST # * stuff that makes sense to be at the end if [[ "$SUDOD" ]]; then # allow failure, for example if we are sudoing into a user with diffferent/lesser permissions. cd "$SUDOD" ||: unset SUDOD elif [[ -d /a ]] && [[ $PWD == "$HOME" ]] && [[ $- == *i* ]]; then cd /a OLDPWD= fi # for mitmproxy to get a newer python. # commented until i want to use it because it # noticably slows bash startup # mypyenvinit () { if [[ $EUID == 0 || ! -e ~/.pyenv/bin ]]; then echo "error: dont be root. make sure pyenv is installed" return 1 fi export PATH="$HOME/.pyenv/bin:$PATH" eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" } export GOPATH=$HOME/go path-add $GOPATH/bin path-add /usr/local/go/bin # I have the git repo and a release. either one should work. # I have both because I was trying to solve an issue that # turned out to be unrelated. # ARDUINO_PATH=/a/opt/Arduino/build/linux/work ## i should have documented this... # based on https://github.com/keyboardio/Kaleidoscope export KALEIDOSCOPE_DIR=/a/opt/Kaleidoscope # They want to be added to the start, but i think # that should be avoided unless we really need it. path-add --end ~/.npm-global path-add --end $HOME/.cargo/bin if type -P rg &>/dev/null; then # --no-messages because of annoying errors on broken symlinks # -z = search .gz etc files # -. = search dotfilesq rg() { command rg -. -z --no-messages -L -i -M 900 --no-ignore-parent --no-ignore-vcs -g '!.git' -g '!auto-save-list' -g '!.savehist' "$@" || return $?; } #fails if not exist. ignore complete -r rg 2>/dev/null ||: else alias rg=grr fi # taken from default changes to bashrc and bash_profile path-add --end --ifexists $HOME/.rvm/bin # also had ruby bin dir, but moved that to environment.sh # so its included in overall env export BASEFILE_DIR=/a/bin/fai-basefiles #export ANDROID_HOME=/a/opt/android-home # https://f-droid.org/en/docs/Installing_the_Server_and_Repo_Tools/ #export USE_SDK_WRAPPER=yes #PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools # didnt get drush working, if I did, this seems like the # only good thing to include for it. # Include Drush completion. # if [ -f "/home/ian/.drush/drush.complete.sh" ] ; then # source /home/ian/.drush/drush.complete.sh # fi # best practice unset IFS # https://wiki.archlinux.org/index.php/Xinitrc#Autostart_X_at_login # i added an extra condition as gentoo xorg guide says depending on # $DISPLAY is fragile. if [[ ! $DISPLAY && $XDG_VTNR == 1 ]] && shopt -q login_shell && isarch; then exec startx fi # ensure no bad programs appending to this file will have an affect return 0