mainly changes to keep systems up to date
[distro-setup] / brc2
1 #!/bin/bash
2 # Copyright (C) 2019 Ian Kelling
3 # SPDX-License-Identifier: AGPL-3.0-or-later
4 # this gets sourced. shebang is just for file mode detection
5
6
7 # * settings
8
9 HISTFILE=$HOME/.bh
10
11 source /a/bin/distro-setup/path-add-function
12 path-add /a/exe
13 # add this with absolute paths as needed for better security
14 #path-add --end /path/to/node_modules/.bin
15
16 # pip3 --user things go here:
17 path-add --end ~/.local/bin
18 path-add --ifexists --end /a/work/libremanage
19 path-add --ifexists --end /a/opt/adt-bundle*/tools /a/opt/adt-bundle*/platform-tools
20 path-add --ifexists --end /a/opt/scancode-toolkit-3.0.2
21
22 export WCDHOME=/a
23
24
25 # * include files
26
27 # generated instead of dynamic for the benefit of shellcheck
28 #for x in /a/bin/distro-functions/src/* /a/bin/!(githtml)/*-function?(s); do echo source $x ; done
29 source /a/bin/distro-functions/src/identify-distros
30 source /a/bin/distro-functions/src/package-manager-abstractions
31 source /a/bin/log-quiet/logq-function
32 source /a/bin/small-misc-bash/psg-function
33 # for x in /a/bin/bash_unpublished/source-!(.#*); do echo source $x; done
34 source /a/bin/bash_unpublished/source-semi-priv
35 source /a/bin/bash_unpublished/source-state
36
37 source /a/bin/log-quiet/logq-function
38
39
40
41 # * functions
42
43
44
45 # todo, update this
46 complete -F _longopt la lower low rlt rld rl lld ts ll dircp ex fcp fct fpst gr
47
48
49 anki() {
50 if which anki &>/dev/null; then
51 command anki
52 else
53 schroot -c anki -- anki
54 fi
55 }
56
57 ap() {
58 # pushd in case current directory has an ansible.cfg file
59 pushd /a/xans >/dev/null
60 ansible-playbook -v -l ${1:- $(hostname -f)} site.yml
61 popd >/dev/null
62 }
63 aw() {
64 pushd /a/work/ansible-configs >/dev/null
65 time ansible-playbook -v -i inventory adhoc.yml "$@"
66 popd >/dev/null
67 }
68 ad() {
69 pushd /a/bin/distro-setup/a >/dev/null
70 ansible-playbook site.yml
71 popd >/dev/null
72 }
73
74 astudio() {
75 # googling android emulator libGL error: failed to load driver: r600
76 # lead to http://stackoverflow.com/a/36625175/14456
77 export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1
78 /a/opt/android-studio/bin/studio.sh "$@" &r;
79 }
80
81
82 bbk() { # btrbk wrapper
83 c /
84 local active=true
85 systemctl is-active btrbk.timer || active=false
86 if $active; then
87 ser disable btrbk.timer
88 fi
89 if systemctl is-active btrbk.service; then
90 $active && ser enable btrbk.timer
91 echo "cron btrbk is already running"
92 return 1
93 fi
94 # run latest
95 install-my-scripts
96 btrbk-run "$@" | pee cat "systemd-cat -t btrbk-run"
97 $active && ser enable btrbk.timer
98 }
99
100 bfg() { java -jar /a/opt/bfg-1.12.14.jar "$@"; }
101
102 bigclock() {
103 xclock -digital -update 1 -face 'arial black-80:bold'
104 }
105
106 bpull() {
107 [[ $1 ]] || return 1
108 c /
109 # run latest
110 install-my-scripts
111 switch-mail-host $1 $HOSTNAME | pee cat "systemd-cat -t switch-mail-host"
112 }
113 bpush() {
114 [[ $1 ]] || return 1
115 c /
116 # run latest
117 install-my-scripts
118 switch-mail-host $HOSTNAME $1 | pee cat "systemd-cat -t switch-mail-host"
119 }
120 lipush() {
121 rsync $@ --delete-excluded -ahviSAXPH --specials --devices --delete --relative \
122 --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:/
123 }
124 lipushnoe() {
125 rsync $@ --delete-excluded -ahviSAXPH --specials --devices --delete --relative \
126 --exclude-from=/p/c/li-rsync-excludes /a/bin /a/exe /a/h /a/c /p/c/machine_specific/li root@li:/
127 }
128
129
130 btc() {
131 local f=/etc/bitcoin/bitcoin.conf
132 # importprivkey will timeout if using the default of 15 mins.
133 # upped it to 1 hour.
134 bitcoin-cli -rpcclienttimeout=60000 -$(s grep rpcuser= $f) -$(s grep rpcpassword= $f) "$@"
135 }
136
137 btcusd() { # $1 btc in usd
138 local price
139 price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)"
140 printf "$%s\n" "$price"
141 if [[ $1 ]]; then
142 printf "$%.2f\n" "$(echo "scale=4; $price * $1"| bc -l)"
143 fi
144 }
145 usdbtc() { # $1 usd in btc
146 local price
147 price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)"
148 printf "$%s\n" "$price"
149 if [[ $1 ]]; then
150 # 100 mil satoshi / btc. 8 digits after the 1.
151 printf "%.8f btc\n" "$(echo "scale=10; $1 / $price "| bc -l)"
152 fi
153 }
154 satoshi() { # $1 satoshi in usd
155 local price
156 price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)"
157 price=$(echo "scale=10; $price * 0.00000001"| bc -l)
158 printf "$%f\n" "$price"
159 if [[ $1 ]]; then
160 printf "$%.2f\n" "$(echo "scale=10; $price * $1"| bc -l)"
161 fi
162 }
163
164
165
166 cbfstool () { /a/opt/coreboot/build/cbfstool "$@"; }
167
168
169 cgpl()
170 {
171 if (($#)); then
172 cp /a/bin/data/COPYING "$@"
173 else
174 cp /a/bin/data/COPYING .
175 fi
176 }
177
178 capache()
179 {
180 if (($#)); then
181 cp /a/bin/data/LICENSE "$@"
182 else
183 cp /a/bin/data/LICENSE .
184 fi
185 }
186
187 chrome() {
188 if type -p chromium &>/dev/null; then
189 cmd=chromium
190 else
191 cd
192 cmd="schroot -c stretch chromium"
193 CHROMIUM_FLAGS='--enable-remote-extensions' $cmd &r
194 fi
195 }
196
197
198 dat() { # do all tee, for more complex scripts
199 tee >(ssh frodo bash -l) >(bash -l) >(ssh x2 bash -l) >(ssh tp bash -l)
200 }
201 da() { # do all
202 local host
203 "$@"
204 for host in x2 tp kd; do
205 ssh $host $(printf "")
206 done
207 }
208
209
210 debian_pick_mirror () {
211 # netselect-apt finds a fast mirror.
212 # but we need to replace the mirrors ourselves,
213 # because it doesnt do that. best it can do is
214 # output a basic sources file
215 # here we get the server it found, get the main server we use
216 # then substitute all instances of one for the other in the sources file
217 # and backup original to /etc/apt/sources.list-original.
218 # this is idempotent. the only way to identify debian sources is to
219 # note the original server, so we put it in a comment so we can
220 # identify it later.
221 local file
222 file=$(mktemp -d)/f # safe way to get file name without creating one
223 sudo netselect-apt -o "$file" || return 1
224 url=$(grep ^\\w $file | head -n1 | awk '{print $2}')
225 sudo cp -f /etc/apt/sources.list /etc/apt/sources.list-original
226 sudo sed -ri "/http.us.debian.org/ s@( *[^ #]+ +)[^ ]+([^#]+).*@\1$url\2# http.us.debian.org@" /etc/apt/sources.list
227 sudo apt-get update
228 }
229
230
231
232 envload() { # load environment from a previous: export > file
233 local file=${1:-$HOME/.${USER}_env}
234 eval "$(export | sed 's/^declare -x/export -n/')"
235 while IFS= read -r line; do
236 # declare -x makes variables local to a function
237 eval ${line/#declare -x/export}
238 done < "$file"
239 }
240
241
242 # one that comes with distros is too old for newer devices
243 fastboot() {
244 /a/opt/android-platform-tools/fastboot "$@";
245 }
246
247 kdecd() { /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd; }
248
249 # List of apps to install/update
250 # Create from existing manually installed apps by doing
251 # fdroidcl update
252 # fdroidcl search -i, then manually removing
253 # automatically installed/preinstalled apps
254
255 #
256 # # my attempt at recovering from boot loop:
257 # # in that case, boot to recovery (volume up, home button, power, let go of power after samsun logo)
258 # # then
259 # mount /dev/block/mmcblk0p12 /data
260 # cd /data
261 # find -iname '*appname*'
262 # rm -rf FOUND_DIRS
263 # usually good enough to just rm -rf /data/app/APPNAME
264 #
265 # currently broken:
266 # # causes replicant to crash
267 # org.quantumbadger.redreader
268 # org.kde.kdeconnect_tp
269
270 # not broke, but wont work without gps
271 #com.zoffcc.applications.zanavi
272 # not broke, but not using atm
273 #com.nutomic.syncthingandroid
274 # # doesn\'t work on replicant
275 #net.sourceforge.opencamera
276 #
277 fdroid_pkgs=(
278 de.marmaro.krt.ffupdater
279 me.ccrama.redditslide
280 org.fedorahosted.freeotp
281 at.bitfire.davdroid
282 com.alaskalinuxuser.justnotes
283 com.artifex.mupdf.viewer.app
284 com.danielkim.soundrecorder
285 com.fsck.k9
286 com.ghostsq.commander
287 com.ichi2.anki
288 com.jmstudios.redmoon
289 com.jmstudios.chibe
290 org.kde.kdeconnect_tp
291 com.notecryptpro
292 com.termux
293 cz.martykan.forecastie
294 de.danoeh.antennapod
295 de.blinkt.openvpn
296 de.marmaro.krt.ffupdater
297 eu.siacs.conversations
298 free.rm.skytube.oss
299 im.vector.alpha # riot
300 info.papdt.blackblub
301 me.tripsit.tripmobile
302 net.gaast.giggity
303 net.minetest.minetest
304 net.osmand.plus
305 org.isoron.uhabits
306 org.linphone
307 org.gnu.icecat
308 org.smssecure.smssecure
309 org.yaaic
310 sh.ftp.rocketninelabs.meditationassistant.opensource
311 )
312 # https://forum.xda-developers.com/android/software-hacking/wip-selinux-capable-superuser-t3216394
313 # for maru,
314 #me.phh.superuser
315
316 fdup() {
317 local -A installed updated
318 local p
319 fdroidcl update
320 if fdroidcl search -u | grep ^org.fdroid.fdroid; then
321 fdroidcl install org.fdroid.fdroid
322 sleep 5
323 fdroidcl update
324 fi
325 for p in $(fdroidcl search -i| grep -o "^\S\+"); do
326 installed[$p]=true
327 done
328 for p in $(fdroidcl search -u| grep -o "^\S\+"); do
329 updated[$p]=false
330 done
331 for p in ${fdroid_pkgs[@]}; do
332 if ! ${installed[$p]:-false}; then
333 fdroidcl install $p
334 # sleeps are just me being paranoid since replicant has a history of crashing when certain apps are installed
335 sleep 5
336 fi
337 done
338 for p in ${!installed[@]}; do
339 if ! ${updated[$p]:-true}; then
340 fdroidcl install $p
341 sleep 5
342 fi
343 done
344 }
345
346 firefox-default-profile() {
347 key=Default value=1 section=$1
348 file=/p/c/subdir_files/.mozilla/firefox/profiles.ini
349 sed -ri "/^ *$key/d" "$file"
350 sed -ri "/ *\[$section\]/,/^ *\[[^]]+\]/{/^\s*$key[[:space:]=]/d};/ *\[$section\]/a $key=$value" "$file"
351 }
352 fdhome() { #firefox default home profile
353 firefox-default-profile Profile0
354 }
355
356 fdwork() {
357 firefox-default-profile Profile4
358 }
359
360 ff() {
361 if type -P firefox &>/dev/null; then
362 firefox "$@"
363 else
364 iceweasel "$@"
365 fi
366 }
367
368
369
370 fn() {
371 firefox -P alt "$@" >/dev/null 2>&1
372 }
373
374
375 fsdiff () {
376 local missing=false
377 local dname="${PWD##*/}"
378 local m="/a/tmp/$dname-missing"
379 local d="/a/tmp/$dname-diff"
380 [[ -e $d ]] && rm "$d"
381 [[ -e $m ]] && rm "$m"
382 local msize=0
383 local fsfile
384 while read -r line; do
385 fsfile="$1${line#.}"
386 if [[ -e "$fsfile" ]]; then
387 md5diff "$line" "$fsfile" && tee -a "/a/tmp/$dname-diff" <<< "$fsfile $line"
388 else
389 missing=true
390 echo "$line" >> "$m"
391 msize=$((msize + 1))
392 fi
393 done < <(find . -type f )
394 if $missing; then
395 echo "$m"
396 (( msize <= 100 )) && cat $m
397 fi
398 }
399 fsdiff-test() {
400 # expected output, with different tmp dirs
401 # /tmp/tmp.HDPbwMqdC9/c/d ./c/d
402 # /a/tmp/tmp.qLDkYxBYPM-missing
403 # ./b
404 cd $(mktemp -d)
405 echo ok > a
406 echo nok > b
407 mkdir c
408 echo ok > c/d
409 local x
410 x=$(mktemp -d)
411 mkdir $x/c
412 echo different > $x/c/d
413 echo ok > $x/a
414 fsdiff $x
415 }
416 rename-test() {
417 # test whether missing files were renamed, generally for use with fsdiff
418 # $1 = fsdiff output file, $2 = directory to compare to. pwd = fsdiff dir
419 # echos non-renamed files
420 local x y found
421 unset sums
422 for x in "$2"/*; do
423 { sums+=( "$(md5sum < "$x")" ) ; } 2>/dev/null
424 done
425 while read -r line; do
426 { missing_sum=$(md5sum < "$line") ; } 2>/dev/null
427 renamed=false
428 for x in "${sums[@]}"; do
429 if [[ $missing_sum == "$x" ]]; then
430 renamed=true
431 break
432 fi
433 done
434 $renamed || echo "$line"
435 done < "$1"
436 return 0
437 }
438
439 feh() {
440 # F = fullscren, z = random, Z = auto zoom
441 command feh -FzZ "$@"
442 }
443
444
445
446 fw() {
447 firefox -P default "$@" >/dev/null 2>&1
448 }
449
450
451 gitian() {
452 git config user.email ian@iankelling.org
453 }
454
455
456 # at least in flidas, things rely on gpg being gpg1
457 gpg() {
458 command gpg2 "$@"
459 }
460
461 gse() {
462 local email=ian@iankelling.org
463 if readlink ~/.mu | grep fsf &>/dev/null; then
464 email=iank@fsf.org
465 fi
466 git send-email --notes "--envelope-sender=<$email>" \
467 --suppress-cc=self "$@"
468 }
469
470
471 hstatus() {
472 # do git status on published repos.
473 c /a/bin/githtml
474 for x in *; do
475 cd $(readlink -f $x)/..
476 status=$(i status -s) || pwd
477 if [[ $status ]]; then
478 hr
479 echo $x
480 printf "%s\n" "$status"
481 fi
482 cd /a/bin/githtml
483 done
484 }
485
486
487 idea() {
488 /a/opt/idea-IC-163.7743.44/bin/idea.sh "$@" &r
489 }
490
491 o() {
492 if type gvfs-open &> /dev/null ; then
493 gvfs-open "$@"
494 else
495 xdg-open "$@"
496 fi
497 # another alternative is run-mailcap
498 }
499
500 jfilter() {
501 grep -Evi -e "^(\S+\s+){4}(sudo|sshd|cron)\[\S*:" \
502 -e "^(\S+\s+){4}systemd\[\S*: (starting|started) (btrfsmaintstop|dynamicipupdate|spamd dns bug fix cronjob|rss2email)\.*$"
503 }
504 jtail() {
505 journalctl -n 10000 -f "$@" | jfilter
506 }
507 jr() { journalctl "$@" | jfilter | less ; }
508 jrf() { journalctl -f "$@" | jfilter; }
509
510
511 kff() { # keyboardio firmware flash
512 pushd /a/bin/distro-setup/Arduino/Model01-Firmware
513 yes $'\n' | make flash
514 popd
515 }
516
517
518
519 lom() {
520 local l base
521 if [[ $1 == /* ]]; then
522 base=${1##*/}
523 if mountpoint /mnt/$base; then
524 return 0
525 fi
526 l=$(sudo losetup -f)
527 sudo losetup $l $1
528 if ! sudo cryptsetup luksOpen $l $base; then
529 sudo losetup -d $l
530 return 1
531 fi
532 sudo mkdir -p /mnt/$base
533 sudo mount /dev/mapper/$base /mnt/$base
534 sudo chown $USER:$USER /mnt/$base
535 else
536 base=$1
537 sudo umount /mnt/$base
538 l=$(sudo cryptsetup status /dev/mapper/$base|sed -rn 's/^\s*device:\s*(.*)/\1/p')
539 sudo cryptsetup luksClose /dev/mapper/$base || return 1
540 sudo losetup -d $l
541 fi
542 }
543
544
545 mbenable() {
546 local mb=$1
547 dst=/m/4e/$mb
548 src=/m/md/$mb
549 set -x
550 [[ -e $src ]] || { set +x; return 1; }
551 mv -T $src $dst || { set +x; return 1; }
552 ln -s -T $dst $src
553 /a/exe/lnf /m/.mu ~
554 mu index --maildir=/m/4e
555 set +x
556 }
557 mbdisable() {
558 local mb=$1
559 dst=/m/md/$mb
560 src=/m/4e/$mb
561 set -x
562 [[ -e $src ]] || { set +x; return 1; }
563 if [[ -L $dst ]]; then rm $dst; fi
564 mv -T $src $dst
565 set +x
566 }
567
568
569 mdt() {
570 markdown "$1" >/tmp/mdtest.html
571 firefox /tmp/mdtest.html
572 }
573
574
575
576 mo() { xset dpms force off; } # monitor off
577
578 net-dev-info() {
579 e "lspci -nnk|gr -iA2 net"
580 lspci -nnk|gr -iA2 net
581 hr
582 e "s lshw -C network"
583 hr
584 s lshw -C network
585
586 }
587
588 nk() {
589 ser stop NetworkManager
590 ser stop dnsmasq
591 s resolvconf -d NetworkManager
592 ser start dnsmasq
593 s ifup br0
594 }
595 ngo() {
596 s ifdown br0
597 ser start NetworkManager
598 sleep 4
599 s nmtui-connect
600 }
601
602 otp() {
603 oathtool --totp -b "$@" | xclip -selection clipboard
604 }
605
606
607 pakaraoke() {
608 # from http://askubuntu.com/questions/456021/remove-vocals-from-mp3-and-get-only-instrumentals
609 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
610 }
611
612 pfind() { #find *$1* in $PATH
613 [[ $# != 1 ]] && { echo requires 1 argument; return 1; }
614 local pathArray
615 IFS=: pathArray=($PATH); unset IFS
616 find "${pathArray[@]}" -iname "*$1*"
617 }
618
619 pick-trash() {
620 # trash-restore lists everything that has been trashed at or below CWD
621 # This picks out files just in CWD, not subdirectories,
622 # which also match grep $1, usually use $1 for a time string
623 # which you get from running restore-trash once first
624 local name x ask
625 local nth=1
626 # last condition is to not ask again for ones we skipped
627 while name="$( echo | restore-trash | gr "$PWD/[^/]\+$" | gr "$1" )" \
628 && [[ $name ]] && (( $(wc -l <<<"$name") >= nth )); do
629 name="$(echo "$name" | head -n $nth | tail -n 1 )"
630 read -r -p "$name [Y/n] " ask
631 if [[ ! $ask || $ask == [Yy] ]]; then
632 x=$( echo "$name" | gr -o "^\s*[0-9]*" )
633 echo $x | restore-trash > /dev/null
634 elif [[ $ask == [Nn] ]]; then
635 nth=$((nth+1))
636 else
637 return
638 fi
639 done
640 }
641
642
643 pub() {
644 rld /a/h/_site/ li:/var/www/iankelling.org/html
645 }
646
647
648 pumpa() {
649 # fixes the menu bar in xmonad. this won\'t be needed when xmonad
650 # packages catches up on some changes in future (this is written in
651 # 4/2017)
652 #
653 # geekosaur: so youll want to upgrade to xmonad 0.13 or else use a
654 # locally modified XMonad.Hooks.ManageDocks that doesnt set the
655 # work area; turns out it\'s impossible to set correctly if you are
656 # not a fully EWMH compliant desktop environment
657 #
658 # geekosaur: chrome shows one failure mode, qt/kde another, other
659 # gtk apps a third, ... I came up with a setting that works for me
660 # locally but apparently doesnt work for others, so we joined the
661 # other tiling window managers in giving up on setting it at all
662 #
663 xprop -root -remove _NET_WORKAREA
664 command pumpa &r
665 }
666
667 # reviewboard, used at my old job
668 #rbpipe() { rbt post -o --diff-filename=- "$@"; }
669 #rbp() { rbt post -o "$@"; }
670
671 rebr() {
672 s ifdown br0
673 s ifup br0
674 }
675
676 resolvcat() {
677 local f
678 f=/etc/resolv.conf
679 echo $f:; ccat $f
680 hr; echo dnsmasq is $(systemctl is-active dnsmasq)
681 f=/var/run/dnsmasq/resolv.conf
682 hr; echo $f:; ccat $f
683 f=/etc/dnsmasq-servers.conf
684 hr; echo $f:; ccat $f
685 }
686
687 # only run on MAIL_HOST. simpler to keep this on one system.
688 r2eadd() { # usage: name url
689 # initial setup of rss2email:
690 # r2e new r2e@iankelling.org
691 # that initializes files, and sets default email.
692 # symlink to the config doesnt work, so I copied it to /p/c
693 # and then use cli option to specify explicit path.
694 # Only option changed from default config is to set
695 # force-from = True
696 #
697 # or else for a few feeds, the from address is set by the feed, and
698 # if I fail delivery, then I send a bounce message to that from
699 # address, which makes me be a spammer.
700
701 r2e add $1 "$2" $1@r2e.iankelling.org
702 # get up to date and dont send old entries now:
703 r2e run --no-send $1
704 }
705 r2e() { command r2e -d /p/c/rss2email.json -c /p/c/rss2email.cfg "$@"; }
706
707 rspicy() { # usage: HOST DOMAIN
708 # connect to spice vm remote host. use vspicy for local host
709 local port
710 # shellcheck disable=SC2087
711 port=$(ssh $1<<EOF
712 sudo virsh dumpxml $2|grep "<graphics.*type='spice'" | \
713 sed -rn "s/.*port='([0-9]+).*/\1/p"
714 EOF
715 )
716 if [[ $port ]]; then
717 spicy -h $1 -p $port
718 else
719 echo "error: no port found. check that the domain is running."
720 fi
721 }
722
723
724 scssl() {
725 # s gem install scss-lint
726 pushd /a/opt/thoughtbot-guides
727 git pull --stat
728 popd
729 scss-lint -c /a/opt/thoughtbot-guides/style/sass/.scss-lint.yml "$@"
730 }
731
732 skaraoke() {
733 local tmp out
734 out=${2:-${1%.*}.sh}
735 tmp=$(mktemp -d)
736 script -t -c "mpv --no-config --no-resume-playback --no-terminal --no-audio-display '$1'" $tmp/typescript 2>$tmp/timing
737 # todo, the current sleep seems pretty good, but it
738 # would be nice to have an empirical measurement, or
739 # some better wait to sync up.
740 #
741 # note: --loop-file=no prevents it from hanging if you have that
742 # set to inf the mpv config.
743 # --loop=no prevents it from exit code 3 due to stdin if you
744 # had it set to inf in mpv config.
745 #
746 # args go to mpv, for example --volume=80, 50%
747 cat >$out <<EOFOUTER
748 #!/bin/bash
749 trap "trap - TERM && kill 0" INT TERM ERR; set -e
750 ( sleep .2; scriptreplay <( cat <<'EOF'
751 $(cat $tmp/timing)
752 EOF
753 ) <( cat <<'EOF'
754 $(cat $tmp/typescript)
755 EOF
756 ))&
757 base64 -d - <<'EOF'| mpv --loop=no --loop-file=no --no-terminal --no-audio-display "\$@" -
758 $(base64 "$1")
759 EOF
760 kill 0
761 EOFOUTER
762 rm -r $tmp
763 chmod +x $out
764 }
765
766 smeld() { # ssh meld usage host1 host2 file
767 meld <(ssh $1 cat $3) <(ssh $2 cat $3)
768 }
769
770 spd() {
771 PATH=/usr/local/spdhackfix:$PATH command spd "$@"
772 }
773
774 spend() {
775 s systemctl suspend
776 }
777
778 # ssh, copy my universal config over if needed.
779 sl() {
780 # inspired from https://github.com/Russell91/sshrc
781
782
783 local args info_date info_t type now tmp old sshinfo
784 declare -a args tmpa
785 now=$(date +%s)
786
787 # ssh [-1246Antivivisectionist] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
788 # [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L address]
789 # [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q query_option]
790 # [-R address] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname
791 # [command]
792
793 while [[ $1 ]]; do
794 case "$1" in
795 -[1246AaCfGgKkMNnqsTtVvXxYy])
796 args+=("$1"); shift
797 ;;
798 -[bcDEeFIiLlmOopQRSWw])
799 # -oOption etc is valid
800 if (( ${#1} >= 3 )); then
801 args+=("$1"); shift
802 else
803 args+=("$1" "$2"); shift 2
804 fi
805 ;;
806 *)
807 break
808 ;;
809 esac
810 done
811 remote="$1"; shift
812 old=false
813 tmpa=(/p/sshinfo/???????????"$remote")
814 sshinfo=${tmpa[0]}
815 if [[ -e $sshinfo ]]; then
816 tmp=${sshinfo[0]##*/}
817 info_date=${tmp::11}
818 type=${info_date: -1}
819 info_date=${info_date::10}
820 # debug
821 #e $(( $(stat -c%Y /b/ds/brc) - $(date -d @$info_date +%s) ))
822 if (( $(stat -c%Y /b/ds/brc) > $(date -d @$info_date +%s) )); then
823 old=true
824 fi
825 else
826 tmp=$(command ssh -t "${args[@]}" "$remote" "if test -e /p/sshinfo; then echo yes; fi") || return
827 if [[ $tmp == yes ]]; then
828 type=a
829 else
830 type=b
831 old=true
832 fi
833 fi
834 if [[ $type == b ]]; then
835 if $old; then
836 RSYNC_RSH="ssh ${args[*]}" rsync -rptL /b/ds/.iank "$remote":
837 rm -f $sshinfo
838 sshinfo=/p/sshinfo/$now$type"$remote"
839 touch $sshinfo
840 chmod 666 $sshinfo
841 fi
842 if (( ${#@} )); then
843
844 # Theres a couple ways to do this. im not sure whats best,
845 # but relying on bash 4.4+ escape quoting seems most reliable.
846
847 command ssh -t "${args[@]}" "$remote" "INPUTRC=.iank/.inputrc bash --rcfile .iank/.bashrc -c ${@@Q}"
848 # this way is bad
849 # command ssh -t "${args[@]}" "$remote" "printf \"%s; exit\" \"$*\" >.iank/brc2
850 #INPUTRC=.iank/.inputrc bash --rcfile .iank/.bashrc"
851
852 else
853 command ssh -t "${args[@]}" "$remote" "INPUTRC=.iank/.inputrc bash --rcfile .iank/.bashrc"
854 fi
855 else
856 BASH_LOGIN_SHELL=true command ssh "$remote" "$@"
857 fi
858 }
859 sss() { # ssh solo
860 ssh -oControlMaster=no -oControlPath=/ "$@"
861 }
862 # kill off old shared socket then ssh
863 ssk() {
864 local -a opts=()
865 while [[ $1 == -* ]]; do
866 opts+=("$1")
867 shift
868 done
869 m pkill -f "^ssh: /tmp/ssh_mux_${USER}_${1#*@}_22_"
870 m ssh "${opts[@]}" "$@"
871 }
872 # plain limited ssh
873 ssh() {
874 BASH_LOGIN_SHELL=true command ssh "$@"
875 }
876
877
878 # mail related
879 testmail() {
880 declare -gi _seq; _seq+=1
881 echo "test body" | m mail -s "test mail from $HOSTNAME, $_seq" "${@:-root@localhost}"
882 # for testing to send from an external address, you can do for example
883 # -fian@iank.bid -aFrom:ian@iank.bid web-6fnbs@mail-tester.com
884 # note in exim, you can retry a deferred message
885 # s exim -M MSG_ID
886 # MSG_ID is in /var/log/exim4/mainlog, looks like 1ccdnD-0001nh-EN
887 }
888
889 # to test sieve, use below command. for fsf mail, see offlineimap-sync script
890 # make modifications, then copy to live file, use -eW to actually modify mailbox
891 #
892 # Another option is to use sieve-test SCRIPT MAIL_FILE. note,
893 # sieve-test doesnt know about envelopes, Im not sure if sieve-filter does.
894
895 # sieve with output filter. arg is mailbox, like INBOX.
896 # This depends on dovecot conf, notably mail_location in /etc/dovecot/conf.d/10-mail.conf
897
898 _dosieve() {
899 sieve-filter "$@" 2> >(head; tail) >/tmp/testsieve.log && sed -rn '/^Performed actions:/,/^[^ ]/{/^ /p}' /tmp/testsieve.log | sort | uniq -c
900 }
901
902 # always run this first, edit the test files, then run the following
903 testsieve() {
904 _dosieve ~/sieve/maintest.sieve ${1:-INBOX} delete
905 }
906 runsieve() {
907 c ~/sieve; cp personal{test,}.sieve; cp lists{test,}.sieve; cp personalend{test,}.sieve
908 _dosieve ~/sieve/main.sieve -eW ${1:-INBOX} delete
909 }
910
911 # mail related
912 testexim() {
913 # testmail above calls sendmail, which is a link to exim/postfix.
914 # its docs dont say a way of adding an argument
915 # to sendmail to turn on debug output. We could make a wrapper, but
916 # that is a pain. Exim debug args are documented here:
917 # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
918 #
919 # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-building_and_installing_exim.html
920 # note, for exim daemon, you can turn on debug options by
921 # adding -d, etc to COMMONOPTIONS in
922 # /etc/default/exim4
923 #
924 # to specify recipients other than those in to, cc, bcc, you can use the cli args, eg:
925 # exim -i 'test@zroe.org, t2@zroe.org' <<'EOF'
926 #
927 #
928 exim -d -t <<'EOF'
929 From: i@dmarctest.b8.nz
930 To: mailman@dev.fsf.org
931 Subject: test2
932 Reply-to: rtest@iankelling.org
933
934 This is a test message.
935 EOF
936 }
937
938 # toggle keyboard
939 tk() {
940 # based on
941 # https://askubuntu.com/questions/160945/is-there-a-way-to-disable-a-laptops-internal-keyboard
942 id=$(xinput --list --id-only 'AT Translated Set 2 keyboard')
943 if xinput list | grep -F '∼ AT Translated Set 2 keyboard' &>/dev/null; then
944 echo enabling keyboard
945 # find the first slave keyboard number, they are all the same in my output.
946 # if they werent, worst case we would need to save the slave number somewhere
947 # when it got disabled.
948 slave=$(xinput list | sed -n 's/.*slave \+keyboard (\([0-9]*\)).*/\1/p' | head -n1)
949 xinput reattach $id $slave
950 else
951 xinput float $id
952 fi
953 }
954
955 tm() {
956 # timer in minutes
957 # --no-config
958 (sleep $(calc "$* * 60") && mpv --no-config --volume 50 /a/bin/data/alarm.mp3) > /dev/null 2>&1 &
959 }
960
961 trg() { transmission-remote-gtk&r; }
962 trc() {
963 # example, set global upload limit to 100 kilobytes:
964 # trc -u 100
965 TR_AUTH=":$(jq -r .profiles[0].password ~/.config/transmission-remote-gtk/config.json)" transmission-remote transmission.lan -ne "$@"
966 }
967
968
969 tu() {
970 local s dir
971 dir="$(dirname "$1")"
972 if [[ -e $1 && ! -w $1 || ! -w $(dirname "$1") ]]; then
973 s=s;
974 fi
975 # full path for using in some initial setup steps
976 $s /a/exe/teeu "$@"
977 }
978
979 vpncmd() {
980 #m s nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*pia.conf") -n -m "$@"
981 m s nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*client.conf") -n -m "$@"
982 }
983 vpnf() {
984 vpncmd gksudo -u iank "firefox -no-remote -P vpn" &r
985 }
986 vpni() {
987 vpncmd gksudo -u iank "$*"
988 }
989 vpnbash() {
990 vpncmd bash
991 }
992
993
994 vpn() {
995 if [[ -e /lib/systemd/system/openvpn-client@.service ]]; then
996 local vpn_service=openvpn-client
997 else
998 local vpn_service=openvpn
999 fi
1000
1001 [[ $1 ]] || { echo need arg; return 1; }
1002 journalctl --unit=$vpn_service@$1 -f -n0 &
1003 s systemctl start $vpn_service@$1
1004 # sometimes the ask-password agent does not work and needs a delay.
1005 sleep .5
1006 # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=779240
1007 # noticed around 8-2017 after update from around stretch release
1008 # on debian testing, even though the bug is much older.
1009 s systemd-tty-ask-password-agent
1010 }
1011
1012 vpnoff() {
1013 [[ $1 ]] || { echo need arg; return 1; }
1014 if [[ -e /lib/systemd/system/openvpn-client@.service ]]; then
1015 local vpn_service=openvpn-client
1016 else
1017 local vpn_service=openvpn
1018 fi
1019 s systemctl stop $vpn_service@$1
1020 }
1021
1022
1023
1024
1025 vspicy() { # usage: VIRSH_DOMAIN
1026 # connect to vms made with virt-install
1027 spicy -p $(sudo virsh dumpxml "$1"|grep "<graphics.*type='spice'"|\
1028 sed -r "s/.*port='([0-9]+).*/\1/")
1029 }
1030
1031 wian() {
1032 cat-new-files /m/4e/INBOX/new
1033 }
1034
1035 wtr() { curl wttr.in/boston; }
1036
1037 xevkb() { xev -event keyboard; }
1038
1039 # * misc stuff
1040
1041 # from curl cheat.sh/:bash_completion
1042 _cheatsh_complete_curl()
1043 {
1044 local cur prev opts
1045 _get_comp_words_by_ref -n : cur
1046
1047 COMPREPLY=()
1048 #cur="${COMP_WORDS[COMP_CWORD]}"
1049 prev="${COMP_WORDS[COMP_CWORD-1]}"
1050 opts="$(curl -s cheat.sh/:list | sed s@^@cheat.sh/@)"
1051
1052 if [[ ${cur} == cheat.sh/* ]] ; then
1053 COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
1054 __ltrim_colon_completions "$cur"
1055 return 0
1056 fi
1057 }
1058 complete -F _cheatsh_complete_curl curl
1059
1060
1061
1062
1063 reset-konsole() {
1064 # we also have a file in /a/c/...konsole...
1065 local f=$HOME/.config/konsolerc
1066 setini DefaultProfile profileian.profile "Desktop Entry" $f
1067 setini Favorites profileian.profile "Favorite Profiles" $f
1068 setini ShowMenuBarByDefault false KonsoleWindow $f
1069 setini TabBarPosition Top TabBar $f
1070 }
1071
1072 reset-sakura() {
1073 while -r read k v; do
1074 # shellcheck disable=SC2154
1075 setini $k $v sakura /a/c/subdir_files/.config/sakura/sakura.conf
1076 done <<'EOF'
1077 colorset1_back rgb(33,37,39
1078 less_questions true
1079 audible_bell No
1080 visible_bell No
1081 disable_numbered_tabswitch true
1082 scroll_lines 10000000
1083 scrollbar true
1084 EOF
1085 }
1086
1087 reset-xscreensaver() {
1088 # except for spash, i set these by setting gui options in
1089 # xscreensaver-command -demo
1090 # then finding the corresponding option in .xscreensaver
1091 # spash, i happened to notice in .xscreensaver
1092 #
1093 # dpmsOff, monitor doesnt come back on using old free software supported nvidia card
1094 cat > /home/iank/.xscreensaver <<'EOF'
1095 mode: blank
1096 dpmsEnabled: True
1097 dpmsStandby: 0:02:00
1098 dpmsSuspend: 0:03:00
1099 dpmsOff: 0:00:00
1100 timeout: 0:02:00
1101 lock: True
1102 lockTimeout: 0:03:00
1103 splash: False
1104 EOF
1105
1106 }
1107
1108
1109 # * stuff that makes sense to be at the end
1110 if [[ "$SUDOD" ]]; then
1111 cd "$SUDOD"
1112 unset SUDOD
1113 elif [[ -d /a ]] && [[ $PWD == "$HOME" ]] && [[ $- == *i* ]]; then
1114 cd /a
1115 fi
1116
1117
1118 # best practice
1119 unset IFS
1120
1121
1122 # for mitmproxy to get a newer python.
1123 # commented until i want to use it because it
1124 # noticably slows bash startup
1125 #
1126
1127 mypyenvinit () {
1128 if [[ $EUID == 0 || ! -e ~/.pyenv/bin ]]; then
1129 echo "error: dont be root. make sure pyenv is installed"
1130 return 1
1131 fi
1132 export PATH="$HOME/.pyenv/bin:$PATH"
1133 eval "$(pyenv init -)"
1134 eval "$(pyenv virtualenv-init -)"
1135 }
1136
1137
1138 export GOPATH=$HOME/go
1139 path-add $GOPATH/bin
1140 path-add /usr/local/go/bin
1141
1142 # I have the git repo and a release. either one should work.
1143 # I have both because I was trying to solve an issue that
1144 # turned out to be unrelated.
1145 # ARDUINO_PATH=/a/opt/Arduino/build/linux/work
1146 export ARDUINO_PATH=/a/opt/arduino-1.8.9
1147
1148 # They want to be added to the start, but i think
1149 # that should be avoided unless we really need it.
1150 path-add --end ~/.npm-global
1151
1152 path-add --end $HOME/.cargo/bin
1153
1154 # taken from default changes to bashrc and bash_profile
1155 path-add --end $HOME/.rvm/bin
1156 path-add --end $HOME/.gem/ruby/2.3.0/bin
1157
1158
1159 export BASEFILE_DIR=/a/bin/fai-basefiles
1160
1161 #export ANDROID_HOME=/a/opt/android-home
1162 # https://f-droid.org/en/docs/Installing_the_Server_and_Repo_Tools/
1163 #export USE_SDK_WRAPPER=yes
1164 #PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools
1165
1166 # didnt get drush working, if I did, this seems like the
1167 # only good thing to include for it.
1168 # Include Drush completion.
1169 # if [ -f "/home/ian/.drush/drush.complete.sh" ] ; then
1170 # source /home/ian/.drush/drush.complete.sh
1171 # fi
1172
1173
1174 # https://wiki.archlinux.org/index.php/Xinitrc#Autostart_X_at_login
1175 # i added an extra condition as gentoo xorg guide says depending on
1176 # $DISPLAY is fragile.
1177 if [[ ! $DISPLAY && $XDG_VTNR == 1 ]] && shopt -q login_shell && isarch; then
1178 exec startx
1179 fi
1180
1181
1182 # ensure no bad programs appending to this file will have an affect
1183 return 0