From 6f1f8a104c9b38936ade2d27e835479523985133 Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Sun, 13 Oct 2019 22:46:30 -0400 Subject: [PATCH] bunch of updates and fixes --- .bashrc | 55 +- .iank/.bashrc | 1 + .iank/.inputrc | 1 + .iank/brc | 1 + .iank/ll-function | 1 + brc | 1211 +---------------- brc2 | 1178 ++++++++++++++++ conflink | 17 +- distro-end | 69 +- epanic-clean | 42 + filesystem/etc/profile.d/environment.sh | 12 +- filesystem/usr/local/bin/myupgrade | 1 + .../etc/systemd/system/btrbk.service | 1 + mail-setup | 9 +- mailclean | 16 +- path-add-function | 84 ++ path_add-function | 80 -- .../.config/systemd/user/emacs.service | 17 + subdir_files/.gnupg/gpg.conf | 4 +- subdir_files/sieve/fsf-test.sieve | 29 - subdir_files/sieve/fsf.sieve | 45 - subdir_files/sieve/lists.sieve | 3 + subdir_files/sieve/liststest.sieve | 3 + system-status | 29 +- 24 files changed, 1536 insertions(+), 1373 deletions(-) create mode 120000 .iank/.bashrc create mode 120000 .iank/.inputrc create mode 120000 .iank/brc create mode 120000 .iank/ll-function create mode 100644 brc2 create mode 100755 epanic-clean create mode 100644 path-add-function delete mode 100644 path_add-function create mode 100644 subdir_files/.config/systemd/user/emacs.service delete mode 100644 subdir_files/sieve/fsf-test.sieve delete mode 100644 subdir_files/sieve/fsf.sieve diff --git a/.bashrc b/.bashrc index da70b07..6780da6 100644 --- a/.bashrc +++ b/.bashrc @@ -19,10 +19,13 @@ # And we don't keep the rest of the code in this file, because even # though we return, we already parsed the whole code, and as I develop # the code, the parsing can have errors, which can screw up cronjobs -# etc. To test for an overriding condition, we have a few options. one -# is to use an environment variable. env variables sent across ssh are +# etc. +# +# To test for an overriding condition, we have a few options. one is to +# use an environment variable. env variables sent across ssh are # strictly limited. ssh -t which sets $SSH_TTY, but within a script that -# won't work because tty allocation will fail. We could override an +# won't work because tty allocation will fail. However, I do use -t for +# strange hosts, so we consider it an indicator. We could override an # obscure unused LC_var, like telephone, but I don't want to run into # some edge case where that messes things up. we could transfer a file # which we could test for, but I can't think of a way to make that @@ -30,26 +33,40 @@ # and AcceptEnv ssh config vars to allow the environment variable # BASH_LOGIN_SHELL to propagate across ssh. This also requires that we # wrap ssh in interactive shells, because, once we export the var, it -# will go into scripts and theres no way to automatically set it. - - -# first conditions show that we are an ssh command without an interactive shell +# will go into scripts, and we want it to be nondefault there. +# +# -c is set whenever a command is passed to ssh +# -i is set whenever a command is not passed if [[ $SSH_CONNECTION ]] \ - && [[ $- == *c* ]] \ - && [[ ! $SSH_TTY ]] \ - && [[ $- != *i* ]] \ - && [[ $BASH_LOGIN_SHELL != true ]]; then - return 0 + && [[ $- == *c* ]] \ + && [[ $- != *i* ]] \ + && { [[ ! $SSH_TTY ]] || [[ $BASH_LOGIN_SHELL == false ]] ; } ; then + return 0 else + + # the distinction between login and non-login shells is lame, + # get rid of it. note ssh shells normally its login if a command is passed + if ! shopt -q login_shell; then if [[ -r /etc/profile ]]; then - source /etc/profile - fi - _x=$(readlink -f ${BASH_SOURCE[0]}) - _x=${_x%/*}/brc - if [[ -r $_x ]]; then - # shellcheck source=./brc - source $_x + source /etc/profile fi + # note, this is not exactly the same as a login shell, because that + # reads ~/.bash_profile or alternative, which usually just sources + # this file, and we don't want to do that and cause an infinite + # loop. + fi + _x=$(readlink -f ${BASH_SOURCE[0]}) + _x=${_x%/*}/brc + if [[ -r $_x ]]; then + # shellcheck source=./brc + source $_x + fi + # brc2 is for things i dont necessarily want on every system + _x=${_x%/*}/brc2 + if [[ -r $_x ]]; then + # shellcheck source=./brc2 + source $_x + fi fi # ensure no bad programs appending to this file will have an affect return 0 diff --git a/.iank/.bashrc b/.iank/.bashrc new file mode 120000 index 0000000..988a415 --- /dev/null +++ b/.iank/.bashrc @@ -0,0 +1 @@ +../.bashrc \ No newline at end of file diff --git a/.iank/.inputrc b/.iank/.inputrc new file mode 120000 index 0000000..36b66bf --- /dev/null +++ b/.iank/.inputrc @@ -0,0 +1 @@ +../.inputrc \ No newline at end of file diff --git a/.iank/brc b/.iank/brc new file mode 120000 index 0000000..4f1c8d0 --- /dev/null +++ b/.iank/brc @@ -0,0 +1 @@ +../brc \ No newline at end of file diff --git a/.iank/ll-function b/.iank/ll-function new file mode 120000 index 0000000..2633506 --- /dev/null +++ b/.iank/ll-function @@ -0,0 +1 @@ +/a/bin/small-misc-bash/ll-function \ No newline at end of file diff --git a/brc b/brc index 41d7d8a..ad1a078 100644 --- a/brc +++ b/brc @@ -1,4 +1,6 @@ #!/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 # note, to catch errors in functions but not outside, do: @@ -33,20 +35,12 @@ export GLOBIGNORE="*/.:*/.." # still buggered in latest stable from the web, version 2.1 # perhaps its fixed in newer git version, which fails to make for me # this note is from 6-2014. -# Also, enabling this before sourcing .bashrc makes PATH be empty. +# still broken in flidas. #shopt -s nullglob # make tab on an empty line do nothing shopt -s no_empty_cmd_completion -# advanced completion -# http://bash-completion.alioth.debian.org/ -# might be sourced by the system already, but ive noticed it not being sourced before -if ! type _init_completion &> /dev/null && [[ -r "/usr/share/bash-completion/bash_completion" ]]; then - . /usr/share/bash-completion/bash_completion -fi - - # fix spelling errors for cd, only in interactive shell shopt -s cdspell # append history instead of overwritting it @@ -155,10 +149,7 @@ PS4='$LINENO+ ' # default HISTFILESIZE is 500 and could clobber our history HISTFILESIZE= # max commands 1 session can append/read from history -HISTSIZE=100000 -# my own history size limit based on lines -HISTFILELINES=1000000 -HISTFILE=$HOME/.bh +HISTSIZE=1000000 # the time format display when doing the history command # also, setting this makes the history file record time # of each command as seconds from the epoch @@ -183,24 +174,11 @@ export PROFILE_TASKS_TASK_OUTPUT_LIMIT=100 export LESS=RXi export SYSTEMD_LESS=$LESS + # * 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/distro-functions/src/package-manager-abstractions -source /a/bin/distro-setup/path_add-function -source /a/bin/ds/path_add-function -source /a/bin/log-quiet/logq-function -source /a/bin/small-misc-bash/ll-function -source /a/bin/small-misc-bash/psg-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 - -# shellcheck source=./path_add-function -source $(dirname $(readlink -f $BASH_SOURCE))/path_add-function -source /a/bin/log-quiet/logq-function + + # if someone exported $SOE (stop on error), catch errors. # # Note, on debian this results in the following warning when in ssh, @@ -215,48 +193,16 @@ if [[ $SOE ]]; then fi fi -path_add /a/exe -# add this with absolute paths as needed for better security -#path_add --end /path/to/node_modules/.bin - -# 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.0.2 -export WCDHOME=/a # based on readme.debian. dunno if this will break on other distros. if [[ -s /usr/share/wcd/wcd-include.sh ]]; then source /usr/share/wcd/wcd-include.sh fi - -# * aliases - -# very few aliases, functions are always preferred. - -# ancient stuff. -if [[ $OS == Windows_NT ]]; then - alias ffs='cygstart "/c/Program Files (x86)/Mozilla Firefox/firefox.exe" -P scratch' - export DISPLAY=nt - alias j='command cygpath' - alias t='command cygstart' - alias cygstart='echo be quick, use the alias "t" instead :\)' - alias cygpath='echo be quick, use the alias "j" instead :\)' +if [[ -s ~/.iank/ll-function ]]; then + # shellcheck source=.iank/ll-function + source ~/.iank/ll-function fi - - -# keep this in mind? good for safety. -# alias cp='cp -i' -# alias mv='mv -i' - - -# remove any default aliases for these -unalias ls ll grep &>/dev/null ||: - - - # * functions @@ -266,7 +212,6 @@ unalias ls ll grep &>/dev/null ||: .....() { c ../../../..; } ......() { c ../../../../..; } - # file cut copy and paste, like the text buffers :) # I havnt tested these. _fbufferinit() { # internal use @@ -287,32 +232,6 @@ fpst() { # file paste cp "$my_f_tempdir"/* "$target" } - -# todo, update this -complete -F _longopt la lower low rlt rld rl lld ts ll dircp ex fcp fct fpst gr - - -_cdiff-prep() { - # join options which are continued to multiples lines onto one line - local first=true - while IFS= read -r line; do - # remove leading spaces/tabs. assumes extglob - if [[ $line == "[ ]*" ]]; then - line="${line##+( )}" - fi - if $first; then - pastline="$line" - first=false - elif [[ $line == *=* ]]; then - echo "$pastline" >> "$2" - pastline="$line" - else - pastline="$pastline $line" - fi - done < <(grep -vE '^([ \t]*#|^[ \t]*$)' "$1") - echo "$pastline" >> "$2" -} - _khfix_common() { local host=${1##*@} local ip port @@ -351,134 +270,26 @@ a() { ack() { ack-grep "$@"; } -anki() { - if which anki &>/dev/null; then - command anki - else - schroot -c anki -- anki - fi -} - -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/ansible-configs >/dev/null - time ansible-playbook -v -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; -} - b() { # backwards c - } -bbk() { - c / - local active=true - systemctl is-active btrbk.timer || active=false - if $active; then - ser disable btrbk.timer - fi - if systemctl is-active btrbk.service; then - $active && ser enable btrbk.timer - echo "cron btrbk is already running" - return 1 - fi - # run latest - install-my-scripts - btrbk-run "$@" - $active && ser enable btrbk.timer -} - -bfg() { java -jar /a/opt/bfg-1.12.14.jar "$@"; } - -bigclock() { - xclock -digital -update 1 -face 'arial black-80:bold' -} - -bpull() { - [[ $1 ]] || return 1 - c / - # run latest - install-my-scripts - switch-mail-host $1 $HOSTNAME -} -bpush() { - [[ $1 ]] || return 1 - c / - # run latest - install-my-scripts - switch-mail-host $HOSTNAME $1 -} -lipush() { - rsync $@ --delete-excluded -ahviSAXPH --specials --devices --delete --relative \ - --exclude-from=/p/c/li-rsync-excludes /a/bin /a/exe /a/h /a/c /p/c/machine_specific/li /a/opt/{emacs,emacs-debianstable,mu} root@li:/ -} -lipushnoe() { - rsync $@ --delete-excluded -ahviSAXPH --specials --devices --delete --relative \ - --exclude-from=/p/c/li-rsync-excludes /a/bin /a/exe /a/h /a/c /p/c/machine_specific/li root@li:/ -} - - -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 -} - # c. better cd -if [[ $RLC_INSIDE_EMACS ]]; then - c() { wcd -c -z 50 -o "$@"; } +if type -p wcd &>/dev/null; then + if [[ $RLC_INSIDE_EMACS ]]; then + c() { wcd -c -z 50 -o "$@"; } + else + # lets see what the fancy terminal does from time to time + c() { wcd -c -z 50 "$@"; } + fi else - # lets see what the fancy terminal does from time to time - c() { wcd -c -z 50 "$@"; } + c() { cd "$@"; } fi +c4() { c /var/log/exim4; } + caa() { git commit --amend --no-edit -a; } caf() { @@ -502,12 +313,33 @@ cam() { git commit -am "$*" } -cbfstool () { /a/opt/coreboot/build/cbfstool "$@"; } ccat () { # config cat. see a config without extra lines. grep '^\s*[^;[:space:]#]' "$@" } + +_cdiff-prep() { + # join options which are continued to multiples lines onto one line + local first=true + while IFS= read -r line; do + # remove leading spaces/tabs. assumes extglob + if [[ $line == "[ ]*" ]]; then + line="${line##+( )}" + fi + if $first; then + pastline="$line" + first=false + elif [[ $line == *=* ]]; then + echo "$pastline" >> "$2" + pastline="$line" + else + pastline="$pastline $line" + fi + done < <(grep -vE '^([ \t]*#|^[ \t]*$)' "$1") + echo "$pastline" >> "$2" +} + cdiff() { # diff config files, # setup for format of postfix, eg: @@ -526,23 +358,6 @@ cdiff() { done < "$unified" } -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 -} cat-new-files() { local start=$SECONDS @@ -579,54 +394,14 @@ cl() { c = } -chrome() { - if type -p chromium &>/dev/null; then - cmd=chromium - else - cd - cmd="schroot -c stretch chromium" - CHROMIUM_FLAGS='--enable-remote-extensions' $cmd &r - fi -} - d() { builtin bg; } complete -A stopped -P '"%' -S '"' d -dat() { # do all tee, for more complex scripts - tee >(ssh frodo bash -l) >(bash -l) >(ssh x2 bash -l) >(ssh tp bash -l) -} -da() { # do all - local host - "$@" - for host in x2 tp kd; do - ssh $host $(printf "") - done -} dc() { diff --strip-trailing-cr -w "$@" # diff content } -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 -} - despace() { local x y for x in "$@"; do @@ -659,16 +434,6 @@ ediff() { emacs --eval "(ediff-files \"$1\" \"$2\")" } - -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" -} - # mail related etail() { tail -F /var/log/exim4/mainlog -n 200 @@ -677,6 +442,7 @@ eless() { less /var/log/exim4/mainlog } + # shellcheck disable=SC2032 f() { # cd forward @@ -698,208 +464,6 @@ faf() { # find all files. use -L to follow symlinks -o -name .undo-tree-history -prune \) -type f 2>/dev/null } -# 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; } - -# 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=( - 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.ghostsq.commander - 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 - fdroidcl update - if fdroidcl search -u | grep ^org.fdroid.fdroid; then - fdroidcl install org.fdroid.fdroid - sleep 5 - 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 - 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 - 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 "$@" -} - # mail related frozen() { rm -rf /tmp/frozen @@ -933,11 +497,6 @@ trap ERR return' ERR } - -fw() { - firefox -P default "$@" >/dev/null 2>&1 -} - getdir () { local help="Usage: getdir [--help] PATH Output the directory of PATH, or just PATH if it is a directory." @@ -990,10 +549,6 @@ and works in older versions of git which did not have that." echo "${p%%/.git}" } -gitian() { - git config user.email ian@iankelling.org -} - gh() { # i got an error, gh not found when doing a pull request, it seems like it wants itself in it\'s path. local _oldpath="$PATH" @@ -1012,20 +567,6 @@ gdkill() { pk1 emacs --daemon } -# at least in flidas, things rely on gpg being gpg1 -gpg() { - command gpg2 "$@" -} - -gse() { - local email=ian@iankelling.org - if readlink ~/.mu | grep fsf &>/dev/null; then - email=iank@fsf.org - fi - git send-email --notes "--envelope-sender=<$email>" \ - --suppress-cc=self "$@" -} - gr() { grep -iIP --color=auto "$@" } @@ -1041,44 +582,6 @@ rg() { command rg -i -M 200 "$@" } -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 -} - -hl() { # history limit. Write extra history to archive file. - # todo: this is not working or not used currently - local max_lines linecount prune_lines x - local harchive="${HISTFILE}_archive" - for x in "$HISTFILE" "$harchive"; do - [[ -e $x ]] || { touch "$x" && echo "notice from hl(): creating $x"; } - if [[ ! $x || ! -e $x || ! -w $x || $(stat -c "%u" "$x") != "$EUID" ]]; then - echo "error in hl: history file \$x:$x no good" - return 1 - fi - done - history -a # save history - max_lines=$HISTFILELINES - [[ $max_lines =~ ^[0-9]+$ ]] || { echo "error in hl: failed to get max line count"; return 1; } - linecount=$(wc -l < $HISTFILE) # pipe so it doesnt output a filename - [[ $linecount =~ ^[0-9]+$ ]] || { echo "error in hl: wc failed"; return 1; } - if ((linecount > max_lines)); then - prune_lines=$((linecount - max_lines)) - head -n $prune_lines "$HISTFILE" >> "$harchive" \ - && sed --follow-symlinks -ie "1,${prune_lines}d" $HISTFILE - fi -} - hr() { # horizontal row. used to break up output printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(seq ${COLUMNS:-60}) echo @@ -1132,15 +635,14 @@ if ! type service &>/dev/null; then } fi + + ic() { # fast commit all git commit -am "$*" } -idea() { - /a/opt/idea-IC-163.7743.44/bin/idea.sh "$@" &r -} ifn() { # insensitive find @@ -1149,16 +651,6 @@ ifn() { -o -name .undo-tree-history -prune \) -iname "*$**" 2>/dev/null } - -o() { - if type gvfs-open &> /dev/null ; then - gvfs-open "$@" - else - xdg-open "$@" - fi - # another alternative is run-mailcap -} - ipdrop() { s iptables -A INPUT -s $1 -j DROP } @@ -1168,21 +660,11 @@ istext() { grep -Il "" "$@" &>/dev/null } -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 -f "$@" | jfilter; } - -kff() { # keyboardio firmware flash - pushd /a/bin/distro-setup/Arduino/Model01-Firmware - yes $'\n' | make flash - popd + journalctl -n 10000 -f "$@" } +jr() { journalctl "$@" ; } +jrf() { journalctl -f "$@" ; } l() { if [[ $PWD == /[iap] ]]; then @@ -1201,31 +683,6 @@ lt() { ll -tr "$@"; } lld() { ll -d "$@"; } -lom() { - local l base - if [[ $1 == /* ]]; then - base=${1##*/} - if mountpoint /mnt/$base; then - return 0 - fi - l=$(sudo losetup -f) - sudo losetup $l $1 - if ! sudo cryptsetup luksOpen $l $base; then - sudo losetup -d $l - return 1 - fi - sudo mkdir -p /mnt/$base - sudo mount /dev/mapper/$base /mnt/$base - sudo chown $USER:$USER /mnt/$base - else - base=$1 - sudo umount /mnt/$base - l=$(sudo cryptsetup status /dev/mapper/$base|sed -rn 's/^\s*device:\s*(.*)/\1/p') - sudo cryptsetup luksClose /dev/mapper/$base || return 1 - sudo losetup -d $l - fi -} - low() { # make filenames lowercase, remove bad chars local f new for f in "$@"; do @@ -1265,36 +722,6 @@ make-targets() { make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}' } -mbenable() { - local mb=$1 - dst=/m/4e/$mb - src=/m/md/$mb - set -x - [[ -e $src ]] || { set +x; return 1; } - mv -T $src $dst || { set +x; return 1; } - ln -s -T $dst $src - /a/exe/lnf /m/.mu ~ - mu index --maildir=/m/4e - set +x -} -mbdisable() { - local mb=$1 - dst=/m/md/$mb - src=/m/4e/$mb - set -x - [[ -e $src ]] || { set +x; return 1; } - if [[ -L $dst ]]; then rm $dst; fi - mv -T $src $dst - set +x -} - - -mdt() { - markdown "$1" >/tmp/mdtest.html - firefox /tmp/mdtest.html -} - - mkc() { mkdir "$1" c "$1" @@ -1313,73 +740,30 @@ mkt() { # mkdir and touch file # shellcheck disable=SC2032 mkdir() { command mkdir -p "$@"; } -mo() { xset dpms force off; } # monitor off - -net-dev-info() { - e "lspci -nnk|gr -iA2 net" - lspci -nnk|gr -iA2 net - hr - e "s lshw -C network" - hr - s lshw -C network - -} - -nk() { - ser stop NetworkManager - ser stop dnsmasq - s resolvconf -d NetworkManager - ser start dnsmasq - s ifup br0 -} -ngo() { - s ifdown br0 - ser start NetworkManager - sleep 4 - s nmtui-connect -} - nopanic() { # shellcheck disable=SC2024 sudo tee -a /var/log/exim4/paniclog-archive /dev/null) if [[ $cached ]]; then cp $cached . else - aptitude download $pkg + aptitude download $pkg || return 1 fi tmp=(*); f=${tmp[0]} # only 1 expected ex $f rm -f $f } +# pgrep and kill pk1() { local pid pid=($(pgrep -f "$*")) @@ -1398,58 +782,10 @@ pk1() { esac } -pick-trash() { - # trash-restore lists everything that has been trashed at or below CWD - # This picks out files just in CWD, not subdirectories, - # which also match grep $1, usually use $1 for a time string - # which you get from running restore-trash once first - local name x ask - local nth=1 - # last condition is to not ask again for ones we skipped - while name="$( echo | restore-trash | gr "$PWD/[^/]\+$" | gr "$1" )" \ - && [[ $name ]] && (( $(wc -l <<<"$name") >= 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 -} - pubip() { curl -4s https://icanhazip.com; } pubip6() { curl -6s https://icanhazip.com; } whatismyip() { pubip; } -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 -} - - pwgen() { # -m = min length # -x = max length @@ -1481,25 +817,6 @@ r() { # exit "$@" 2>/dev/null } -rbpipe() { rbt post -o --diff-filename=- "$@"; } -rbp() { rbt post -o "$@"; } - -rebr() { - s ifdown br0 - s ifup br0 -} - -resolvcat() { - local f - f=/etc/resolv.conf - echo $f:; ccat $f - hr; echo dnsmasq is $(systemctl is-active dnsmasq) - f=/var/run/dnsmasq/resolv.conf - hr; echo $f:; ccat $f - f=/etc/dnsmasq-servers.conf - hr; echo $f:; ccat $f -} - rl() { # rsync, root is required to keep permissions right. # rsync --archive --human-readable --verbose --itemize-changes --checksum \(-ahvic\) \ @@ -1534,42 +851,6 @@ rlu() { # [OPTS] HOST PATH s rsync -rlpchviog --relative "${opts[@]}" "$path" "root@$host:/"; } -# 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 -} -r2e() { command r2e -d /p/c/rss2email.json -c /p/c/rss2email.cfg "$@"; } - -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 </dev/null; then - # skip args that dont exist, or else trash-put will have an error - for x in "$@"; do - if [[ -e $x || -L $x ]]; then - args+=("$x") - fi - done - (( ! ${#args[@]} )) || trash-put "${args[@]}" - else - rm -rf "$@" - fi -} - - -tclock() { +tclock() { # terminal clock local x clear date +%l:%_M @@ -1861,101 +1059,6 @@ te() { return $ret } -# 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 - -_dosieve() { - sieve-filter "$@" 2> >(head; tail) >/tmp/testsieve.log && sed -rn '/^Performed actions:/,/^[^ ]/{/^ /p}' /tmp/testsieve.log | sort | uniq -c -} - -# always run this first, edit the test files, then run the following -testsieve() { - _dosieve ~/sieve/maintest.sieve ${1:-INBOX} delete -} -runsieve() { - c ~/sieve; cp personal{test,}.sieve; cp lists{test,}.sieve; cp personalend{test,}.sieve - _dosieve ~/sieve/main.sieve -eW ${1:-INBOX} delete -} - -# mail related -testexim() { - # testmail above calls sendmail, which is a link to exim/postfix. - # its docs dont say a way of adding an argument - # to sendmail to turn on debug output. We could make a wrapper, but - # that is a pain. Exim debug args are documented here: - # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html - # - # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-building_and_installing_exim.html - # note, for exim daemon, you can turn on debug options by - # adding -d, etc to COMMONOPTIONS in - # /etc/default/exim4 -# exim -d -t <<'EOF' - exim -i 'test@zroe.org, t2@zroe.org' <<'EOF' -From: ian@iankelling.org -To: test@zroe.org, t2@zroe.org -Subject: Testing Exim - -This is a test message. -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 "$@" -} - - -tu() { - local s dir - dir="$(dirname "$1")" - 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 "$@" -} tx() { # toggle set -x, and the prompt so it doesnt spam if [[ $- == *x* ]]; then @@ -1994,21 +1097,6 @@ psnetns() { m() { printf "%s\n" "$*"; "$@"; } -vpncmd() { - #m s nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*pia.conf") -n -m "$@" - m s nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*client.conf") -n -m "$@" -} -vpnf() { - vpncmd gksudo -u iank "firefox -no-remote -P vpn" &r -} -vpni() { - vpncmd gksudo -u iank "$*" -} -vpnbash() { - vpncmd bash -} - - virshrm() { for x in "$@"; do virsh destroy "$x"; virsh undefine "$x"; done @@ -2035,84 +1123,8 @@ vmunshare() { vm-set-listen $1 127.0.0.1 } - -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 & - s 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. - s systemd-tty-ask-password-agent -} - -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 - s systemctl stop $vpn_service@$1 -} - - -vrm() { - virsh destroy $1 - virsh undefine $1 -} - - - -vspicy() { # usage: VIRSH_DOMAIN - # connect to vms made with virt-install - spicy -p $(sudo virsh dumpxml "$1"|grep " /home/iank/.xscreensaver <<'EOF' -mode: blank -dpmsEnabled: True -dpmsStandby: 0:02:00 -dpmsSuspend: 0:03:00 -dpmsOff: 0:00:00 -timeout: 0:02:00 -lock: True -lockTimeout: 0:03:00 -splash: False -EOF - -} - - # * stuff that makes sense to be at the end -if [[ "$SUDOD" ]]; then - cd "$SUDOD" - unset SUDOD -elif [[ -d /a ]] && [[ $PWD == "$HOME" ]] && [[ $- == *i* ]]; then - cd /a -fi # best practice unset IFS - -# 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 -export ARDUINO_PATH=/a/opt/arduino-1.8.9 - -# 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 - -# taken from default changes to bashrc and bash_profile -path_add --end $HOME/.rvm/bin -path_add --end $HOME/.gem/ruby/2.3.0/bin - # shellcheck disable=SC1090 [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function* -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 - - -# 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 diff --git a/brc2 b/brc2 new file mode 100644 index 0000000..fd7fcaf --- /dev/null +++ b/brc2 @@ -0,0 +1,1178 @@ +#!/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 + +HISTFILE=$HOME/.bh + +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 + +# 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.0.2 + +export WCDHOME=/a + + +# * 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/distro-functions/src/package-manager-abstractions +source /a/bin/log-quiet/logq-function +source /a/bin/small-misc-bash/psg-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 + + + +# * functions + + + +# todo, update this +complete -F _longopt la lower low rlt rld rl lld ts ll dircp ex fcp fct fpst gr + + +anki() { + if which anki &>/dev/null; then + command anki + else + schroot -c anki -- anki + fi +} + +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/ansible-configs >/dev/null + time ansible-playbook -v -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; +} + + +bbk() { # btrbk wrapper + c / + local active=true + systemctl is-active btrbk.timer || active=false + if $active; then + ser disable btrbk.timer + fi + if systemctl is-active btrbk.service; then + $active && ser enable btrbk.timer + echo "cron btrbk is already running" + return 1 + fi + # run latest + install-my-scripts + btrbk-run "$@" | pee cat "systemd-cat -t btrbk-run" + $active && ser enable btrbk.timer +} + +bfg() { java -jar /a/opt/bfg-1.12.14.jar "$@"; } + +bigclock() { + xclock -digital -update 1 -face 'arial black-80:bold' +} + +bpull() { + [[ $1 ]] || return 1 + c / + # run latest + install-my-scripts + switch-mail-host $1 $HOSTNAME | pee cat "systemd-cat -t switch-mail-host" +} +bpush() { + [[ $1 ]] || return 1 + c / + # run latest + install-my-scripts + switch-mail-host $HOSTNAME $1 | pee cat "systemd-cat -t switch-mail-host" +} +lipush() { + rsync $@ --delete-excluded -ahviSAXPH --specials --devices --delete --relative \ + --exclude-from=/p/c/li-rsync-excludes /a/bin /a/exe /a/h /a/c /p/c/machine_specific/li /a/opt/{emacs,emacs-debianstable,mu} root@li:/ +} +lipushnoe() { + rsync $@ --delete-excluded -ahviSAXPH --specials --devices --delete --relative \ + --exclude-from=/p/c/li-rsync-excludes /a/bin /a/exe /a/h /a/c /p/c/machine_specific/li root@li:/ +} + + +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 +} + + + +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 stretch chromium" + CHROMIUM_FLAGS='--enable-remote-extensions' $cmd &r + fi +} + + +dat() { # do all tee, for more complex scripts + tee >(ssh frodo bash -l) >(bash -l) >(ssh x2 bash -l) >(ssh tp bash -l) +} +da() { # do all + local host + "$@" + for host in x2 tp kd; do + ssh $host $(printf "") + 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 +} + + + +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" +} + + +# 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; } + +# 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=( + 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.ghostsq.commander + 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 + fdroidcl update + if fdroidcl search -u | grep ^org.fdroid.fdroid; then + fdroidcl install org.fdroid.fdroid + sleep 5 + 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 + 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 + 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() { + command gpg2 "$@" +} + +gse() { + local email=ian@iankelling.org + if readlink ~/.mu | grep fsf &>/dev/null; then + email=iank@fsf.org + fi + git send-email --notes "--envelope-sender=<$email>" \ + --suppress-cc=self "$@" +} + + +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 +} + + +idea() { + /a/opt/idea-IC-163.7743.44/bin/idea.sh "$@" &r +} + +o() { + if type gvfs-open &> /dev/null ; then + gvfs-open "$@" + else + xdg-open "$@" + fi + # another alternative is run-mailcap +} + +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 -f "$@" | jfilter; } + + +kff() { # keyboardio firmware flash + pushd /a/bin/distro-setup/Arduino/Model01-Firmware + yes $'\n' | make flash + popd +} + + + +lom() { + local l base + if [[ $1 == /* ]]; then + base=${1##*/} + if mountpoint /mnt/$base; then + return 0 + fi + l=$(sudo losetup -f) + sudo losetup $l $1 + if ! sudo cryptsetup luksOpen $l $base; then + sudo losetup -d $l + return 1 + fi + sudo mkdir -p /mnt/$base + sudo mount /dev/mapper/$base /mnt/$base + sudo chown $USER:$USER /mnt/$base + else + base=$1 + sudo umount /mnt/$base + l=$(sudo cryptsetup status /dev/mapper/$base|sed -rn 's/^\s*device:\s*(.*)/\1/p') + sudo cryptsetup luksClose /dev/mapper/$base || return 1 + sudo losetup -d $l + fi +} + + +mbenable() { + local mb=$1 + dst=/m/4e/$mb + src=/m/md/$mb + set -x + [[ -e $src ]] || { set +x; return 1; } + mv -T $src $dst || { set +x; return 1; } + ln -s -T $dst $src + /a/exe/lnf /m/.mu ~ + mu index --maildir=/m/4e + set +x +} +mbdisable() { + local mb=$1 + dst=/m/md/$mb + src=/m/4e/$mb + set -x + [[ -e $src ]] || { set +x; return 1; } + if [[ -L $dst ]]; then rm $dst; fi + mv -T $src $dst + set +x +} + + +mdt() { + markdown "$1" >/tmp/mdtest.html + firefox /tmp/mdtest.html +} + + + +mo() { xset dpms force off; } # monitor off + +net-dev-info() { + e "lspci -nnk|gr -iA2 net" + lspci -nnk|gr -iA2 net + hr + e "s lshw -C network" + hr + s lshw -C network + +} + +nk() { + ser stop NetworkManager + ser stop dnsmasq + s resolvconf -d NetworkManager + ser start dnsmasq + s ifup br0 +} +ngo() { + s ifdown br0 + ser start NetworkManager + sleep 4 + s nmtui-connect +} + +otp() { + oathtool --totp -b "$@" | xclip -selection clipboard +} + + +pakaraoke() { + # from http://askubuntu.com/questions/456021/remove-vocals-from-mp3-and-get-only-instrumentals + pactl load-module module-ladspa-sink sink_name=Karaoke master=alsa_output.usb-Audioengine_Audioengine_D1-00.analog-stereo plugin=karaoke_1409 label=karaoke control=-30 +} + +pfind() { #find *$1* in $PATH + [[ $# != 1 ]] && { echo requires 1 argument; return 1; } + local pathArray + IFS=: pathArray=($PATH); unset IFS + find "${pathArray[@]}" -iname "*$1*" +} + +pick-trash() { + # trash-restore lists everything that has been trashed at or below CWD + # This picks out files just in CWD, not subdirectories, + # which also match grep $1, usually use $1 for a time string + # which you get from running restore-trash once first + local name x ask + local nth=1 + # last condition is to not ask again for ones we skipped + while name="$( echo | restore-trash | gr "$PWD/[^/]\+$" | gr "$1" )" \ + && [[ $name ]] && (( $(wc -l <<<"$name") >= 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() { + s ifdown br0 + s ifup br0 +} + +resolvcat() { + local f + f=/etc/resolv.conf + echo $f:; ccat $f + hr; echo dnsmasq is $(systemctl is-active dnsmasq) + f=/var/run/dnsmasq/resolv.conf + hr; echo $f:; ccat $f + f=/etc/dnsmasq-servers.conf + hr; echo $f:; ccat $f +} + +# 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 +} +r2e() { command r2e -d /p/c/rss2email.json -c /p/c/rss2email.cfg "$@"; } + +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 <= 3 )); then + args+=("$1"); shift + else + args+=("$1" "$2"); shift 2 + fi + ;; + *) + break + ;; + esac + done + remote="$1"; shift + old=false + tmpa=(/p/sshinfo/???????????"$remote") + sshinfo=${tmpa[0]} + if [[ -e $sshinfo ]]; then + tmp=${sshinfo[0]##*/} + info_date=${tmp::11} + type=${info_date: -1} + info_date=${info_date::10} + # debug + #e $(( $(stat -c%Y /b/ds/brc) - $(date -d @$info_date +%s) )) + if (( $(stat -c%Y /b/ds/brc) > $(date -d @$info_date +%s) )); then + old=true + fi + else + tmp=$(command ssh -t "${args[@]}" "$remote" "if test -e /p/sshinfo; then echo yes; fi") || return + if [[ $tmp == yes ]]; then + type=a + else + type=b + old=true + fi + fi + if [[ $type == b ]]; then + if $old; then + RSYNC_RSH="ssh ${args[*]}" rsync -rptL /b/ds/.iank "$remote": + rm -f $sshinfo + sshinfo=/p/sshinfo/$now$type"$remote" + touch $sshinfo + chmod 666 $sshinfo + fi + if (( ${#@} )); then + + # Theres a couple ways to do this. im not sure whats best, + # but relying on bash 4.4+ escape quoting seems most reliable. + + command ssh -t "${args[@]}" "$remote" "INPUTRC=.iank/.inputrc bash --rcfile .iank/.bashrc -c ${@@Q}" + # this way is bad + # command ssh -t "${args[@]}" "$remote" "printf \"%s; exit\" \"$*\" >.iank/brc2 + #INPUTRC=.iank/.inputrc bash --rcfile .iank/.bashrc" + + else + command ssh -t "${args[@]}" "$remote" "INPUTRC=.iank/.inputrc bash --rcfile .iank/.bashrc" + fi + else + BASH_LOGIN_SHELL=true command ssh "$remote" "$@" + fi +} +sss() { # ssh solo + ssh -oControlMaster=no -oControlPath=/ "$@" +} +# kill off old shared socket then ssh +ssk() { + local -a opts=() + while [[ $1 == -* ]]; do + opts+=("$1") + shift + done + m pkill -f "^ssh: /tmp/ssh_mux_${USER}_${1#*@}_22_" + m ssh "${opts[@]}" "$@" +} +# plain limited ssh +ssh() { + BASH_LOGIN_SHELL=true command ssh "$@" +} + + +# 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 + +_dosieve() { + sieve-filter "$@" 2> >(head; tail) >/tmp/testsieve.log && sed -rn '/^Performed actions:/,/^[^ ]/{/^ /p}' /tmp/testsieve.log | sort | uniq -c +} + +# always run this first, edit the test files, then run the following +testsieve() { + _dosieve ~/sieve/maintest.sieve ${1:-INBOX} delete +} +runsieve() { + c ~/sieve; cp personal{test,}.sieve; cp lists{test,}.sieve; cp personalend{test,}.sieve + _dosieve ~/sieve/main.sieve -eW ${1:-INBOX} delete +} + +# mail related +testexim() { + # testmail above calls sendmail, which is a link to exim/postfix. + # its docs dont say a way of adding an argument + # to sendmail to turn on debug output. We could make a wrapper, but + # that is a pain. Exim debug args are documented here: + # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html + # + # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-building_and_installing_exim.html + # note, for exim daemon, you can turn on debug options by + # adding -d, etc to COMMONOPTIONS in + # /etc/default/exim4 + # exim -d -t <<'EOF' + exim -i 'test@zroe.org, t2@zroe.org' <<'EOF' +From: ian@iankelling.org +To: test@zroe.org, t2@zroe.org +Subject: Testing Exim + +This is a test message. +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 "$@" +} + + +tu() { + local s dir + dir="$(dirname "$1")" + 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 "$@" +} + +vpncmd() { + #m s nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*pia.conf") -n -m "$@" + m s nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*client.conf") -n -m "$@" +} +vpnf() { + vpncmd gksudo -u iank "firefox -no-remote -P vpn" &r +} +vpni() { + vpncmd gksudo -u iank "$*" +} +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 & + s 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. + s systemd-tty-ask-password-agent +} + +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 + s systemctl stop $vpn_service@$1 +} + + + + +vspicy() { # usage: VIRSH_DOMAIN + # connect to vms made with virt-install + spicy -p $(sudo virsh dumpxml "$1"|grep " /home/iank/.xscreensaver <<'EOF' +mode: blank +dpmsEnabled: True +dpmsStandby: 0:02:00 +dpmsSuspend: 0:03:00 +dpmsOff: 0:00:00 +timeout: 0:02:00 +lock: True +lockTimeout: 0:03:00 +splash: False +EOF + +} + + +# * stuff that makes sense to be at the end +if [[ "$SUDOD" ]]; then + cd "$SUDOD" + unset SUDOD +elif [[ -d /a ]] && [[ $PWD == "$HOME" ]] && [[ $- == *i* ]]; then + cd /a +fi + + +# best practice +unset IFS + + +# 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 +export ARDUINO_PATH=/a/opt/arduino-1.8.9 + +# 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 + +# taken from default changes to bashrc and bash_profile +path-add --end $HOME/.rvm/bin +path-add --end $HOME/.gem/ruby/2.3.0/bin + + +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 + + +# 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 diff --git a/conflink b/conflink index bbe1312..0dffc22 100755 --- a/conflink +++ b/conflink @@ -2,13 +2,28 @@ source /a/bin/errhandle/err + +usage() { + cat <$t <$t <&2; exit 1; fi + +shopt -s inherit_errexit 2>/dev/null ||: # ignore fail in bash < 4.4 +set -eE -o pipefail +trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR + +[[ $EUID == 0 ]] || exec sudo -E "${BASH_SOURCE[0]}" "$@" + + +wipe=false +while read -r d1 d2; do + tmptime=$(date -d "$d1 $d2" +%s) + # dont consider every matching line, just those in > 60 second intervals + if [[ ! $logtime ]]; then + logtime=$tmptime + elif (( tmptime > logtime + 60 )); then + logtime=$tmptime + else + continue + fi + sec_min=$((logtime - 60)) + sec_max=$((logtime + 60)) + jmin="$(date -d @$sec_min "+%F %H:%M:%S")" + jmax="$(date -d @$sec_max "+%F %H:%M:%S")" + if journalctl -S "$jmin" -U "$jmax" \ + | awk '$6 == "spamd:" && $7 == "restarting"' | grep . &>/dev/null; then + wipe=true + break + fi +done < <(awk '/spam acl condition/ {print $1,$2}' /var/log/exim4/paniclog) +if $wipe; then + regex="^$(date -d @$logtime "+%F %H:%M" )|^${jmin%:*}|^${jmax%:*}" + grep -E "$regex" /var/log/exim4/paniclog >> /var/log/exim4/paniclog-archive + sed -ri "/$regex/d" /var/log/exim4/paniclog +fi diff --git a/filesystem/etc/profile.d/environment.sh b/filesystem/etc/profile.d/environment.sh index 1d49f6a..96f0271 100644 --- a/filesystem/etc/profile.d/environment.sh +++ b/filesystem/etc/profile.d/environment.sh @@ -1,18 +1,18 @@ -if [ -f $HOME/path_add-function ]; then - . $HOME/path_add-function - path_add /usr/sbin /usr/local/sbin /sbin /a/exe /a/opt/bin - path_add --end $HOME/.cabal/bin +if [ -f $HOME/path-add-function ]; then + . $HOME/path-add-function + path-add /usr/sbin /usr/local/sbin /sbin /a/exe /a/opt/bin + path-add --end $HOME/.cabal/bin if [ -r /etc/alternatives/java_sdk ]; then export JAVA_HOME=/etc/alternatives/java_sdk - path_add /etc/alternatives/java_sdk + path-add /etc/alternatives/java_sdk fi export GUIX_PROFILE=/root/.config/guix/current if [[ -e $GUIX_PROFILE/etc/profile ]]; then source $GUIX_PROFILE/etc/profile fi - path_add $HOME/.guix-profile/bin + path-add $HOME/.guix-profile/bin export GUIX_LOCPATH=$HOME/.guix-profile/lib/locale fi diff --git a/filesystem/usr/local/bin/myupgrade b/filesystem/usr/local/bin/myupgrade index 55e7221..712047a 100755 --- a/filesystem/usr/local/bin/myupgrade +++ b/filesystem/usr/local/bin/myupgrade @@ -25,6 +25,7 @@ if [[ -s /var/log/checkrestart.log ]]; then done for x in {30..1}; do if ! fuser /var/lib/dpkg/lock &> /dev/null; then + echo "pid $PID. unattended upgrade, rebooting now" | pee cat "wall -n" /sbin/reboot exit 0 fi diff --git a/machine_specific/btrbk/filesystem/etc/systemd/system/btrbk.service b/machine_specific/btrbk/filesystem/etc/systemd/system/btrbk.service index bd7b6c3..e89a85e 100644 --- a/machine_specific/btrbk/filesystem/etc/systemd/system/btrbk.service +++ b/machine_specific/btrbk/filesystem/etc/systemd/system/btrbk.service @@ -6,4 +6,5 @@ After=multi-user.target Type=oneshot ExecStart=/a/exe/install-my-scripts ExecStart=/a/bin/log-quiet/sysd-mail-once btrbk /usr/local/bin/btrbk-run -q --cron +ExecStart=/bin/sleep 1 ExecStart=/a/exe/install-my-scripts diff --git a/mail-setup b/mail-setup index 87f644a..dbdf8fa 100755 --- a/mail-setup +++ b/mail-setup @@ -743,7 +743,7 @@ EOF # https://selivan.github.io/2017/12/30/systemd-serice-always-restart.html - d=/etc/systemd/system/openvpn@mail + d=/etc/systemd/system/openvpn@mail.service.d mkdir -p $d cat >$d/override.conf <<'EOF' [Service] @@ -755,7 +755,10 @@ RestartSec=1 # StartLimitIntervalSec in recent systemd versions StartLimitInterval=0 EOF - + if ! systemctl cat openvpn@mail.service|grep -xF StartLimitInterval=0 &>/dev/null; then + # needed for the above config to go into effect + systemctl daemon-reexec + fi systemctl enable mailclean.timer @@ -765,7 +768,7 @@ EOF systemctl enable dovecot systemctl restart dovecot -# * not MAIL_HOST + # * not MAIL_HOST else # $HOSTNAME != $MAIL_HOST # remove mail. 2 lines to properly remove whitespace sed -ri -f - /etc/hosts <<'EOF' diff --git a/mailclean b/mailclean index 753529e..04c8f9d 100755 --- a/mailclean +++ b/mailclean @@ -28,10 +28,11 @@ myfind() { # qemu-devel is our biggest list by far, so occasionally # I want to hop into conversations about our mailing # systems there, but I don't need many old messages. -myfind /nocow/user/fsfmd/l/qemu-devel/new -type f -mtime +14 -execdir rm -- '{}' + -myfind /nocow/user/fsfmd/{sec,Spam,Drafts,{rtcc,sysadmin,l/outreachy-mentors}/new} -type f -mtime +100 -execdir rm -- '{}' + -myfind /nocow/user/fsfmd/log -type f -mtime +300 -execdir rm -- '{}' + -myfind /nocow/user/fsfmd/dmarc -type f -mtime +14 -execdir rm -- '{}' + +myfind /m/md/l/qemu-devel/new -type f -mtime +14 -execdir rm -- '{}' + +myfind /m/md/{sec,Spam,Drafts,{rtcc,sysadmin,l/outreachy-mentors}/new} -type f -mtime +100 -execdir rm -- '{}' + +myfind /m/md/log -type f -mtime +300 -execdir rm -- '{}' + +myfind /m/md/dmarc -type f -mtime +14 -execdir rm -- '{}' + +myfind /m/md/fsfalerts -type f -mtime +10 -execdir rm -- '{}' + @@ -44,14 +45,15 @@ for d in ./!(*archive|Drafts)/*(cur|new) ./l/!(*archive)/*(cur|new); do madearchive=false leafdir=${d##*/} md=${d%/*}; md=${md##*/} - archive=${d%/*/*}/${md}-myarchive/$leafdir - archivebase=archive=${d%/*/*}/${md}-myarchive + archivebase=${d%/*/*}/${md}-myarchive + archive=$archivebase/$leafdir for f in $d/1*; do date=$($scriptdir/email-date.py $f) || echo $f [[ $date ]] || continue if (( date < now - 60*60*24*400 )); then if ! $madearchive; then - mkdir -p ${archivebase}{cur,tmp,new} + echo mkdir -p ${archivebase}/{cur,tmp,new} + mkdir -p ${archivebase}/{cur,tmp,new} madearchive=true fi mv $f $archive diff --git a/path-add-function b/path-add-function new file mode 100644 index 0000000..86ae521 --- /dev/null +++ b/path-add-function @@ -0,0 +1,84 @@ +#!/bin/bash +# Copyright (C) 2016 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. + + +# avoiding bashisms so it can be used in edge cases where I don't have bash, +# however, I'm not super confident that I've avoided them all +# +path-add() { + local help="usage: path_add [options] PATH +--help: print this +--end: adds to end of path, which will give it lowest priority +--ifexists: add to path only if directory exists" + local found x y ifexists end loop newpath + ifexists=false + end=false + loop=true + # portable substring matching is ugly http://mywiki.wooledge.org/BashFAQ/041 + while $loop; do + case $1 in + --*) + if [ "$1" = --end ]; then + end=true + elif [ "$1" = --ifexists ]; then + ifexists=true + elif [ "$1" = --help ]; then + echo "$help" + return + fi + shift + ;; + *) + loop=false + ;; + esac + done + # if we arent passed a PATH, just return 0 for convenience + if ! test "$1"; then + return 0 + fi + IFS=: + # build up the path without the components we want to add + for y in $PATH; do + for x in "$@"; do + if [ "$x" = "$y" ]; then + found=true + else + found=false + fi + done + if ! $found; then + if [ ! "$newpath" ]; then + newpath="$y" + else + newpath="$newpath:$y" + fi + fi + done + + unset IFS + PATH="$newpath" + for x in "$@"; do + if ! $ifexists || [ -d "$x" ]; then + if [ ! "$PATH" ]; then + PATH="$x" + elif $end; then + PATH="$PATH:$x" + else + PATH="$x:$PATH" + fi + fi + done +} diff --git a/path_add-function b/path_add-function deleted file mode 100644 index f2f4299..0000000 --- a/path_add-function +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash -# Copyright (C) 2016 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. - - -# avoiding bashisms so it can be used in edge cases where I don't have bash, -# however, I'm not super confident that I've avoided them all -# -path_add() { - local help="usage: path_add [options] PATH ---help: print this ---end: adds to end of path, which will give it lowest priority ---ifexists: add to path only if directory exists" - local found x y ifexists end loop newpath - ifexists=false - end=false - loop=true - # portable substring matching is ugly http://mywiki.wooledge.org/BashFAQ/041 - while $loop; do - case $1 in - --*) - if [ "$1" = --end ]; then - end=true - elif [ "$1" = --ifexists ]; then - ifexists=true - elif [ "$1" = --help ]; then - echo "$help" - return - fi - shift - ;; - *) - loop=false - ;; - esac - done - IFS=: - # build up the path without the components we want to add - for y in $PATH; do - for x in "$@"; do - if [ "$x" = "$y" ]; then - found=true - else - found=false - fi - done - if ! $found; then - if [ ! "$newpath" ]; then - newpath="$y" - else - newpath="$newpath:$y" - fi - fi - done - - unset IFS - PATH="$newpath" - for x in "$@"; do - if ! $ifexists || [ -d "$x" ]; then - if [ ! "$PATH" ]; then - PATH="$x" - elif $end; then - PATH="$PATH:$x" - else - PATH="$x:$PATH" - fi - fi - done -} diff --git a/subdir_files/.config/systemd/user/emacs.service b/subdir_files/.config/systemd/user/emacs.service new file mode 100644 index 0000000..40eda74 --- /dev/null +++ b/subdir_files/.config/systemd/user/emacs.service @@ -0,0 +1,17 @@ +## If your Emacs is installed in a non-standard location, you may need +## to copy this file to a standard directory, eg ~/.config/systemd/user/ . +## If you install this file by hand, change the "Exec" lines below +## to use absolute file names for the executables. +[Unit] +Description=Emacs text editor +Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/ + +[Service] +Type=notify +ExecStart=/usr/local/bin/emacs --fg-daemon +ExecStop=/usr/local/bin/emacsclient --eval "(kill-emacs)" +Environment=SSH_AUTH_SOCK=%t/keyring/ssh +Restart=on-failure + +[Install] +WantedBy=default.target diff --git a/subdir_files/.gnupg/gpg.conf b/subdir_files/.gnupg/gpg.conf index d45a291..7ab724c 100644 --- a/subdir_files/.gnupg/gpg.conf +++ b/subdir_files/.gnupg/gpg.conf @@ -43,9 +43,9 @@ default-key B125F60B7B287FF6A2B7DF8F170AF0E2954295DF #keyserver hkp://pgp.mit.edu #keyserver hkp://keyserver.pgp.com #keyserver hkp://ipv4.pool.sks-keyservers.net -#keyserver hkp://keys.gnupg.net +keyserver hkp://keys.gnupg.net #keyserver hkp://keyserver.ubuntu.com -keyserver hkp://keyring.debian.org +#keyserver hkp://keyring.debian.org # more secure hkps, but had problems with my gpg version #keyserver hkps://hkps.pool.sks-keyservers.net diff --git a/subdir_files/sieve/fsf-test.sieve b/subdir_files/sieve/fsf-test.sieve deleted file mode 100644 index 9c631af..0000000 --- a/subdir_files/sieve/fsf-test.sieve +++ /dev/null @@ -1,29 +0,0 @@ -require [ "regex", "variables", "fileinto", "envelope", "mailbox", "imap4flags", "include" ]; - -if anyof ( - address :is "from" "sysadmin@gnu.org", - address :is "to" "sysadmin-nonrt@gnu.org", - address :is "from" "sysadmin-comment@gnu.org" - ) { - fileinto :create "sysadmin"; - stop; - } -elsif anyof ( - header :contains "list-id" "", - header :is "Return-path" "" - ) { -fileinto :create "rtcc"; - stop; -} - -if anyof ( - header :regex "subject" "mailing list memberships reminder", - address :is "to" "rtbounces@gnu.org", - address :is "to" "faxmaster@fsf.org", - address :is "from" "FaxMaster@fsf.org" - ) { - fileinto :create "log"; - stop; - } - -include :personal "lists"; diff --git a/subdir_files/sieve/fsf.sieve b/subdir_files/sieve/fsf.sieve deleted file mode 100644 index ac31d25..0000000 --- a/subdir_files/sieve/fsf.sieve +++ /dev/null @@ -1,45 +0,0 @@ -require [ "regex", "variables", "fileinto", "envelope", "mailbox", "imap4flags", "include" ]; - -if anyof (header :contains "list-id" "") { - discard; - stop; - } - -if anyof ( - address :is "from" "sysadmin@gnu.org", - address :is "from" "sysadmin-nonrt@gnu.org", - address :is "to" "sysadmin-nonrt@gnu.org", - address :is "from" "sysadmin-comment@gnu.org" - ) { - fileinto :create "sysadmin"; - stop; - } -elsif anyof ( - header :is "Return-path" "" - ) { -fileinto :create "rtcc"; - stop; -} - -if anyof ( - address :is "to" "dmarc-rua@fsf.org" - ) { - fileinto :create "dmarc"; - stop; - } - - - - - -if anyof ( - header :regex "subject" "mailing list memberships reminder", - address :is "to" "rtbounces@gnu.org", - address :is "to" "faxmaster@fsf.org", - address :is "from" "FaxMaster@fsf.org" - ) { - fileinto :create "log"; - stop; - } - -include :personal "lists"; diff --git a/subdir_files/sieve/lists.sieve b/subdir_files/sieve/lists.sieve index 4120c28..ca6984c 100644 --- a/subdir_files/sieve/lists.sieve +++ b/subdir_files/sieve/lists.sieve @@ -28,6 +28,7 @@ if anyof ( header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", + header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", @@ -69,6 +70,7 @@ if anyof ( header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", + header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "") { if header :regex "list-id" "<([a-z_0-9-]+)[.@]" { @@ -92,6 +94,7 @@ if anyof ( header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", + header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", diff --git a/subdir_files/sieve/liststest.sieve b/subdir_files/sieve/liststest.sieve index 4120c28..ca6984c 100644 --- a/subdir_files/sieve/liststest.sieve +++ b/subdir_files/sieve/liststest.sieve @@ -28,6 +28,7 @@ if anyof ( header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", + header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", @@ -69,6 +70,7 @@ if anyof ( header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", + header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "") { if header :regex "list-id" "<([a-z_0-9-]+)[.@]" { @@ -92,6 +94,7 @@ if anyof ( header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", + header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", header :contains "list-id" "", diff --git a/system-status b/system-status index 49f734a..c6f3fe7 100755 --- a/system-status +++ b/system-status @@ -24,8 +24,9 @@ write-status() { glob=(/m/md/bounces/new/*) if [[ -e ${glob[0]} ]]; then chars+=("BOUNCE!") - lo -1 bounce "message in /m/md/bounces/new" + bouncemsg="message in /m/md/bounces/new" fi + lo -1 bounce $bouncemsg glob=(/m/md/alerts/new/* /m/md/alerts/cur/*) if [[ -e ${glob[0]} ]]; then chars+=("ALERT!") @@ -33,17 +34,36 @@ write-status() { if [[ -e /nocow/user/mailtest-failure ]]; then chars+=("MAILPING!") fi + + ## Clean the paniclog, but only up to 4 times per day, or else we + ## should investigate. + loglog=/tmp/panicloglog-$(date --rfc-3339=date) + if [[ -s $loglog ]]; then + spamcount=$(stat -c%s $loglog) + else + spamcount=0 + fi + if (( spamcount <= 4 )); then + if grep -q 'spam acl condition' /var/log/exim4/paniclog; then + printf . >>$loglog + fi + /a/bin/distro-setup/epanic-clean + fi + if [[ -s /var/log/exim4/paniclog ]]; then chars+=("PANIC!") - tail /var/log/exim4/paniclog | lo -1 paniclog + tail -n 20 /var/log/exim4/paniclog | lo -1 paniclog + else + lo -1 paniclog fi source /a/bin/bash_unpublished/source-state if [[ $MAIL_HOST == "$HOSTNAME" ]]; then if [[ $(systemctl is-active btrbk.timer) != active ]]; then chars+=("BTRBK.TIMER!") - lo -60 btrbk.timer "btrbk.timer not enabled" + bbkmsg="btrbk.timer not enabled" fi + lo -60 btrbk.timer $bbkmsg ## check if last snapshot was within an hour vol=o @@ -59,8 +79,9 @@ write-status() { done if (( maxtime < now - 60*60 )); then chars+=("OLD-SNAPSHOT!") - lo -1 old-snapshot "/o snapshot older than 1 hour" + snapshotmsg="/o snapshot older than 1 hour" fi + lo -1 old-snapshot $snapshotmsg fi cat /a/bin/bash_unpublished/source-state >$status_file -- 2.30.2