various fixes
[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 ## for yarn, etc
16 #path-add --end /usr/lib/node_modules/corepack/shims/
17
18 # pip3 --user things go here:
19 path-add --end ~/.local/bin
20 path-add --ifexists --end /a/work/libremanage
21 path-add --ifexists --end /a/opt/adt-bundle*/tools /a/opt/adt-bundle*/platform-tools
22 path-add --ifexists --end /a/opt/scancode-toolkit-3.10.
23
24 case $HOSTNAME in
25 sy|bo)
26 # https://askubuntu.com/questions/1254544/vlc-crashes-when-opening-any-file-ubuntu-20-04
27 if grep -qE '^VERSION_CODENAME="(nabia|focal)"' /etc/os-release &>/dev/null; then
28 export MESA_LOADER_DRIVER_OVERRIDE=i965
29 fi
30 ;;
31 esac
32
33
34 export WCDHOME=/a
35
36
37 case $EUID in
38 0)
39 SL_SSH_ARGS="-F $HOME/.ssh/confighome"
40 ;;
41 esac
42
43
44 # * include files
45
46 # generated instead of dynamic for the benefit of shellcheck
47 #for x in /a/bin/distro-functions/src/* /a/bin/!(githtml)/*-function?(s); do echo source $x ; done
48 source /a/bin/distro-functions/src/identify-distros
49 source /a/bin/log-quiet/logq-function
50 # for x in /a/bin/bash_unpublished/source-!(.#*); do echo source $x; done
51 source /a/bin/bash_unpublished/source-semi-priv
52 source /a/bin/bash_unpublished/source-state
53
54 source /a/bin/log-quiet/logq-function
55 if [[ -s /a/opt/alacritty/extra/completions/alacritty.bash ]]; then
56 source /a/opt/alacritty/extra/completions/alacritty.bash
57 fi
58
59
60 # * functions
61
62 multimic() {
63 local i
64 local -a sources
65
66 m pactl unload-module module-loopback
67 m pactl unload-module module-null-sink
68 m pactl unload-module module-remap-source
69
70 sources=($(pacmd list-sources | sed -rn 's/.*name: <([^>]+).*/\1/p'))
71
72 if (( ! $# )); then
73 i=0
74 for s in ${sources[@]}; do
75 e $i $s
76 i=$(( i+1 ))
77 done
78 read -r l
79 set -- $l
80 fi
81 m pactl load-module module-null-sink sink_name=ianinput sink_properties=device.description=ianinputs
82 for i; do
83 m pactl load-module module-loopback source=${sources[i]} sink_dont_move=true sink=ianinput
84 done
85 pactl load-module module-remap-source source_name=iancombine master=ianinput.monitor source_properties=device.description=iancombine
86 }
87
88 hstest() {
89 install-my-scripts
90 d=$(mktemp -d)
91 sed '/^ *IdentityFile/d' ~/.ssh/config >$d/config
92 s command ssh -F $d/config -i /q/root/h "$@"
93 }
94
95 hrtest() {
96 install-my-scripts
97 d=$(mktemp -d)
98 sed '/^ *IdentityFile/d' ~/.ssh/config >$d/config
99 s rsync -e "ssh -F $d/config -i /q/root/h" "$@"
100 }
101
102
103 slemacs() {
104 local arg rtime v
105 arg="$1"
106 remote="$2"
107 if [[ $arg == [89]0Etiona* ]]; then
108 v=${arg::1}
109 rtime=${arg#*Etiona} # remote time
110 if [[ ! $rtime ]]; then
111 rtime=0
112 fi
113 dir=/a/opt/emacs-trisquel${v}-nox/.iank
114 ltime=$(stat -c%Y $dir/e/e/.emacs.d/init.el)
115 if (( ltime > rtime )); then
116 m rsync -rptL --delete --filter=". /b/ds/sl/rsync-filter" $dir "$remote":/home/iank
117 fi
118 fi
119 }
120
121 sle() { # sl emacs
122 local f=/home/iank/.emacs.d/init.el
123 sl --sl-test-cmd ". /etc/os-release ; printf %s \${VERSION//[^a-zA-Z0-9]/}; test -e $f && stat -c%Y $f" --sl-test-hook slemacs "$@"
124 }
125 ccomp ssh sle
126
127 # Run this manually after .emacs.d changes. Otherwise, to check if
128 # files changed with find takes 90ms. sl normally only adds 25ms. We
129 # could cut it down to 10ms if we put things on a btrfs filesystem and
130 # looked for changes there, or used some inotify thing, but that seems
131 # like too much work.
132 egh() { # emacs gnuhope
133 RSYNC_RSH=ssh m rsync -rptL --delete --filter=". /b/ds/sl/rsync-filter" /a/opt/emacs-trisquel9-nox/.iank lists2d.fsf.org:.ianktrisquel_9
134 RSYNC_RSH=ssh m rsync -rptL --delete --filter=". /b/ds/sl/rsync-filter" /a/opt/emacs-trisquel8-nox/.iank lists2d.fsf.org:/home/iank
135 }
136 ekw() {
137 local shell="bash -s"
138 if [[ $HOSTNAME != kw ]]; then
139 shell="ssh kw.office.fsf.org"
140 bbk -m /a -t kw
141 fi
142 $shell <<'EOF'
143 sudo mkdir /root/.ianktrisquel_9
144 sudo rsync -rptL --delete --filter=". /b/ds/sl/rsync-filter" /a/opt/emacs-trisquel9-nox/.iank /root/.ianktrisquel_9
145 rsync -rptL --delete --filter=". /b/ds/sl/rsync-filter" /a/opt/emacs-trisquel8-nox/.iank /home/iank
146 EOF
147 }
148
149 # usage mkschroot [-] distro codename packages
150 # - means no piping in of sources.list
151 mkschroot() {
152 local force=false
153 while [[ $1 == -* ]]; do
154 case $1 in
155 -f) force=true; shift ;;
156 -s)
157 sources="$2"
158 if [[ ! -s $sources ]]; then
159 echo mkschroot: error: sources file $sources does not exist or is empty
160 return 1
161 fi
162 shift 2
163 ;;
164 esac
165 done
166 distro=$1
167 shift
168 case $distro in
169 trisquel)
170 repo=http://mirror.fsf.org/trisquel/
171 ;;
172 ubuntu)
173 repo=http://archive.ubuntu.com/ubuntu/
174 ;;
175 debian)
176 repo=http://deb.debian.org/debian/
177 ;;
178 esac
179 n=$1
180
181 shift
182 if ! $force && schroot -l | grep -xFq chroot:$n; then
183 echo "$0: $n schroot already installed, skipping"
184 return 0
185 fi
186 apps=($@)
187 d=/nocow/schroot/$n
188 sd /etc/schroot/chroot.d/$n.conf <<EOF
189 [$n]
190 description=$n
191 type=directory
192 directory=$d
193 profile=desktop
194 preserve-environment=true
195 users=$USER,user2
196 EOF
197 cd
198 if [[ ! -e $d/bin ]]; then
199 sudo mkdir -p $d
200 # resolvconf otherwise schroot fails with
201 # cp: not writing through dangling symlink '/var/run/schroot/mount/flidas-7a2362e0-81b3-4848-92c1-610203ef5976/etc/resolv.conf'
202 sudo debootstrap --exclude=resolvconf $n $d $repo
203 fi
204 if [[ $sources ]]; then
205 sudo install -m 644 $sources $d/etc/apt/sources.list
206 fi
207 sudo chroot $d apt-get update
208 sudo DEBIAN_FRONTEND=noninteractive chroot $d apt-get -y dist-upgrade --purge --auto-remove
209 sudo cp -P {,$d}/etc/localtime
210 if (( ${#apps[@]} )); then
211 sudo DEBIAN_FRONTEND=noninteractive schroot -c $n -- apt-get install --allow-unauthenticated -y ${apps[@]}
212 fi
213 }
214
215
216 # note: this is incomplete and untested.
217 # https://wiki.archlinux.org/index.php/Install_Arch_Linux_from_existing_Linux#Creating_a_chroot
218 mkarchchroot() {
219 local tarball mirror
220 mirror=https://mirrors.edge.kernel.org/archlinux/iso/latest/
221 tarball=$(curl -s $mirror | sed -nr 's/.*"(archlinux-bootstrap-.*-x86_64.tar.gz)".*/\1/p')
222 wget -O /tmp/arch.tar.gz https://mirrors.edge.kernel.org/archlinux/iso/latest/$tarball
223 s mkdir -p /nocow/schroot/arch
224 cd _/nocow/schroot/arch
225 s sed -i '/## United States/,/^$/s,^#,,' etc/pacman.d/mirrorlist
226 # error: could not determine cachedir mount point /var/cache/pacman/pkg
227 s sed -i /^CheckSpace/d etc/pacman.conf
228 chroot . /bin/bash -s <<'EOF'
229 pacman-key --init
230 pacman-key --populate archlinux
231 pacman -Syyu
232 EOF
233 # example of building an aur package:
234 # pacman -Sy base-devel wget
235 # useradd -m iank
236 # f=$target/etc/sudoers
237 # line='iank ALL=(ALL) NOPASSWD: ALL'
238 # if [[ ! -e $f ]] || ! grep -xF "$line" $f; then
239 # echo "$line" >> $f
240 # fi
241 # su iank
242 # wget https://aur.archlinux.org/cgit/aur.git/snapshot/anbox-image-gapps.tar.gz
243 # tar xzf anbox-image-gapps.tar.gz
244 # cd anbox-image-gapps
245 # makepkg -s
246 }
247
248
249 # clock back in to timetrack from last entry
250 tback() {
251 sqlite3 /p/.timetrap.db "update entries set end = NULL where id = (select max(id) from entries);"
252 }
253
254 # sshfs example:
255 # s sshfs bu@$host:/bu/home/md /bu/mnt -o reconnect,ServerAliveInterval=20,ServerAliveCountMax=30 -o allow_other
256
257 eqgo() {
258 enn -M $(exiqgrep -i)
259 }
260 eqgo1() {
261 enn -M $(exiqgrep -i|h1)
262 }
263
264
265 gnupload(){
266 /a/f/gnulib/build-aux/gnupload "$@"
267 }
268
269 abrowserrmcompat() {
270 local f
271 ngset
272 f=(/p/c/firefox*/compatibility.ini)
273 if (( ${#f[@]} )); then
274 rm ${f[@]}
275 fi
276 ngreset
277 }
278 ngset() {
279 if shopt nullglob >/dev/null; then
280 ngreset=false
281 else
282 shopt -s nullglob
283 ngreset=true
284 fi
285 }
286 ngreset() {
287 if $ngreset; then
288 shopt -u nullglob
289 fi
290 }
291
292 checkre() {
293 s checkrestart -b /a/bin/ds/checkrestart-blacklist -pv
294 }
295
296 cp-blocked-domains-to-brains() {
297 cp /a/f/ans/roles/exim/files/mx/simple/etc/exim4/bad-sender_domains /a/f/brains/sysadmin/kb/blocked_email_domains.mdwn
298 }
299 cp-blocked-domains-to-ansible() {
300 cp /a/f/brains/sysadmin/kb/blocked_email_domains.mdwn /a/f/ans/roles/exim/files/mx/simple/etc/exim4/bad-sender_domains
301 }
302
303
304 anki() {
305 # crashes on adding new cards in t9
306 schroot -c buster -- anki
307 }
308
309 acat() {
310 ngset
311 hrcat /m/md/alerts/{cur,new}/*
312 ngreset
313 hr; echo bk; hr
314 ssh bk.b8.nz "shopt -s nullglob; hrcat /m/md/INBOX/new/* /m/md/INBOX/cur/*"
315 }
316 aclear() {
317 ngset
318 rm -f /m/md/alerts/{cur,new}/*
319 ngreset
320 ssh bk.b8.nz "shopt -s nullglob; rm -f /m/md/INBOX/new/* /m/md/INBOX/cur/*"
321 system-status _
322 }
323
324 alerts() {
325 find /var/local/cron-errors /home/iank/cron-errors /sysd-mail-once-state -type f
326 }
327 ralerts() { # remote alerts
328 local ret shell
329 # this list is duplicated in check-remote-mailqs
330 for h in bk je li frodo kwwg x3wg x2wg kdwg sywg; do
331 echo $h:
332 shell="ssh $h"
333 if [[ $HOSTNAME == "${h%wg}" ]]; then
334 shell=
335 fi
336 ret=0
337 $shell find /var/local/cron-errors /home/iank/cron-errors /sysd-mail-once-state -type f || ret=$?
338 if (( ret )); then
339 echo ret:$ret
340 fi
341 done
342 }
343
344 ap() {
345 # pushd in case current directory has an ansible.cfg file
346 pushd /a/xans >/dev/null
347 ansible-playbook -v -l ${1:- $(hostname -f)} site.yml
348 popd >/dev/null
349 }
350 aw() {
351 pushd /a/work/ans >/dev/null
352 time ansible-playbook -v -i inventory adhoc.yml "$@"
353 popd >/dev/null
354 }
355 ad() {
356 pushd /a/bin/distro-setup/a >/dev/null
357 ansible-playbook site.yml "$@"
358 popd >/dev/null
359 }
360
361 astudio() {
362 # googling android emulator libGL error: failed to load driver: r600
363 # lead to http://stackoverflow.com/a/36625175/14456
364 export ANDROID_EMULATOR_USE_SYSTEM_LIBS=1
365 /a/opt/android-studio/bin/studio.sh "$@" &r;
366 }
367
368 # note, to check for glue records
369 # First, find some the .org nameservers:
370 # dig +trace iankelling.org
371 # then, query one:
372 # dig ns1.iankelling.org @b0.org.afilias-nst.org.
373
374 # Now, compare for a domain that does have glue records setup (note the A
375 # and AAAA records in ADDITIONAL SECTION, those are glue records like the
376 # one I'm asking for):
377
378 # $ dig ns1.gnu.org @b0.org.afilias-nst.org.
379
380 # todo: make sm pull/push use systemd instead of the journal cat command
381 bbk() { # btrbk wrapper
382 local ret=0
383 c /
384 local active=true
385 systemctl is-active btrbk.timer || active=false
386 if $active; then
387 ser stop btrbk.timer
388 fi
389 if [[ $(systemctl is-active btrbk.service ||:) != inactive ]]; then
390 echo "cron btrbk is already running"
391 if $active; then ser start btrbk.timer; fi
392 return 1
393 fi
394 # run latest
395 install-my-scripts
396 # todo: consider changing this to srun and having the args come
397 # from a file like /etc/default/btrbk, like is done in exim
398 s jrun btrbk-run "$@"
399 if $active; then
400 if (( ret )); then
401 echo bbk: WARNING: btrbk.timer not restarted due to failure
402 else
403 ser start btrbk.timer
404 fi
405 fi
406 return $ret
407 }
408
409 faimon() {
410 fai-monitor | pee cat "fai-monitor-gui -"
411 }
412
413 bfg() { java -jar /a/opt/bfg-1.12.14.jar "$@"; }
414
415 bigclock() {
416 xclock -digital -update 1 -face 'arial black-80:bold'
417 }
418
419 nnn() { /a/opt/nnn -H "$@"; }
420
421 locat() { # log-once cat
422 local files
423 ngset
424 files=(/var/local/cron-errors/* /home/iank/cron-errors/* /sysd-mail-once-state/*)
425 case ${#files[@]} in
426 0) : ;;
427 1)
428 echo ${files[0]}
429 head ${files[0]}
430 ;;
431 *)
432 head ${files[@]}
433 ;;
434 esac
435 ngreset
436 }
437
438 # duplicated somewhat below.
439 jrun() { # journal run. run args, log to journal, tail and grep the journal.
440 # Note, an alternative without systemd would be something like ts.
441 # Note, I tried using systemd-cat, but this seems obviously better,
442 # and that seemed to have a problem exiting during a systemctl daemon-reload
443 local cmd_name jr_pid s
444 ret=0
445 cmd_name=${1##*/}
446 cmd=$1
447 if [[ $cmd != /* ]]; then
448 cmd=$(which $1)
449 fi
450 journalctl -qn2 -f -u "$cmd_name" &
451 # Guess of time needed to avoid missing initial lines.
452 # .5 was not reliable. 1 was not reliable. 2 was not reliable
453 sleep 3
454 # We kill this in prompt-command for the case that we ctrl-c the
455 # systemd-cat. i dont know any way to trap ctrl-c and still run the
456 # normal action for it. There might be a way, unsure.
457 jr_pid=$!
458 # note, we could have a version that does system --user, but if for example
459 # it does sudo ssh, that will leave a process around that we can't kill
460 # and it will leave the unit hanging around in a failed state needing manual
461 # killing of the process.
462 m s systemd-run --uid $(id -u) --gid $(id -g) \
463 -E SSH_AUTH_SOCK=/run/openssh_agent \
464 --unit "$cmd_name" --wait --collect "$cmd" "${@:2}" || ret=$?
465 # This justs lets the journal output its last line
466 # before the prompt comes up.
467 sleep .5
468 kill $jr_pid &>/dev/null ||:
469 unset jr_pid
470 fg &>/dev/null ||:
471 }
472 # service run, and watch the output
473 srun() {
474 local unit
475 ret=0
476 unit=$1
477 journalctl -qn2 -f -u $unit &
478 systemctl start $unit
479 sleep 2
480 kill $jr_pid &>/dev/null ||:
481 unset jr_pid
482 fg &>/dev/null ||:
483 }
484
485 sm() {
486 local tmp keyhash
487 c /
488 # run latest
489 keyhash=$(s ssh-keygen -lf /root/.ssh/home | awk '{print $2}')
490 tmp=$(s ssh-add -l | awk '$2 == "'$keyhash'"')
491 if [[ ! $tmp ]]; then
492 s ssh-add /root/.ssh/home
493 fi
494 install-my-scripts
495 s jrun switch-mail-host "$@"
496 return $ret
497 }
498
499 # shellcheck disable=SC2120
500 lipush() {
501 # note, i had --delete-excluded, but that deletes all files in --exclude-from on
502 # the remote site, which doesn't make sense, so not sure why i had it.
503 local p a
504 # excluding emacs for now
505 #p=(/a/opt/{emacs-debian11{,-nox},mu,emacs} /a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts})
506 p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts})
507 a="-ahviSAXPH --specials --devices --delete --relative --exclude-from=/p/c/li-rsync-excludes"
508 ret=0
509 for h in li je bk; do
510 m s rsync "$@" $a ${p[@]} /p/c/machine_specific/$h root@$h.b8.nz:/
511 ## only li is debian11
512 #p[0]=/a/opt/emacs-trisuqel10
513 #p[1]=/a/opt/emacs-trisquel10-nox
514 done
515 m s rsync "$@" -ahviSAXPH root@li.b8.nz:/a/h/proposed-comments/ /a/h/proposed-comments || ret=$?
516 return $ret
517 }
518 bkpush() { # no emacs. for running faster.
519 p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts})
520 a="-ahviSAXPH --specials --devices --delete --relative --exclude-from=/p/c/li-rsync-excludes"
521 ret=0
522 m rsync "$@" $a ${p[@]} /p/c/machine_specific/bk root@bk.b8.nz:/ || ret=$?
523 return $ret
524 }
525 jepush() { # no emacs. for running faster.
526 p=(/a/bin /a/exe /a/h /a/c /p/c/machine_specific/vps{,.hosts})
527 a="-ahviSAXPH --specials --devices --delete --relative --exclude-from=/p/c/li-rsync-excludes"
528 ret=0
529 m rsync "$@" $a ${p[@]} /p/c/machine_specific/je root@je.b8.nz:/ || ret=$?
530 return $ret
531 }
532
533 bindpush() {
534 dsign iankelling.org expertpathologyreview.com zroe.org amnimal.ninja
535 lipush
536 for h in li bk; do
537 m sl $h <<'EOF'
538 source ~/.bashrc
539 m dnsup
540 EOF
541 done
542 }
543 bindpushb8() {
544 lipush
545 for h in li bk; do
546 m sl $h <<'EOF'
547 source ~/.bashrc
548 m dnsb8
549 EOF
550 done
551 }
552
553 dnsup() {
554 conflink -f
555 m ser reload named
556 }
557 dnsb8() {
558 local f=/var/lib/bind/db.b8.nz
559 m ser stop named
560 m sleep 1
561 m sudo rm -fv $f.jnl
562 m sudo install -m 644 -o bind -g bind /p/c/machine_specific/vps/bind-initial/db.b8.nz $f
563 m ser restart named
564 }
565 dnsecgen() {
566 # keys generated like this
567 # because of https://ftp.isc.org/isc/dnssec-guide/dnssec-guide.pdf
568 # https://blog.apnic.net/2019/05/23/how-to-deploying-dnssec-with-bind-and-ubuntu-server/
569
570 # key length is longer than that guide because
571 # we are using those at fsf and when old key lengths
572 # become insecure, I want some extra time to update.
573 # dnsecgen (in brc2)
574
575 local zone=$1
576 dnssec-keygen -a RSASHA256 -b 2048 $zone
577 dnssec-keygen -f KSK -a RSASHA256 -b 4096 $zone
578 for f in K$zone.*.key; do
579 # eg Kb8.nz.+008+47995.key tag=47995
580 # in dnsimple, you add the long string from this.
581 # in gandi, you add the long string from the .key file,
582 # then see that the digest matches the ds.
583 echo "tag is the number after DS"
584 dnssec-dsfromkey -a SHA-256 $f
585 done
586 # For b8.nz, we let bind read the keys and sign, and
587 # right now they have root ownership, so let them
588 # get group read.
589 chmod g+r *.private
590 }
591 dsign() {
592 # create .signed file
593 # note: full paths probably not needed.
594 local arg
595 for arg; do
596 local zone=${arg#db.}
597 local dir=/p/c/machine_specific/vps/filesystem/var/lib/bind
598 dnssec-signzone -S -e +31536000 -o $zone -K $dir -d $dir $dir/db.$zone
599 done
600 }
601
602
603 #### begin bitcoin related things
604 btc() {
605 local f=/etc/bitcoin/bitcoin.conf
606 # importprivkey will timeout if using the default of 15 mins.
607 # upped it to 1 hour.
608 bitcoin-cli -rpcclienttimeout=60000 -$(s grep rpcuser= $f) -$(s grep rpcpassword= $f) "$@"
609 }
610 btcusd() { # $1 btc in usd
611 local price
612 price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)"
613 printf "$%s\n" "$price"
614 if [[ $1 ]]; then
615 printf "$%.2f\n" "$(echo "scale=4; $price * $1"| bc -l)"
616 fi
617 }
618 usdbtc() { # $1 usd in btc
619 local price
620 price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)"
621 printf "$%s\n" "$price"
622 if [[ $1 ]]; then
623 # 100 mil satoshi / btc. 8 digits after the 1.
624 printf "%.8f btc\n" "$(echo "scale=10; $1 / $price "| bc -l)"
625 fi
626 }
627 satoshi() { # $1 satoshi in usd
628 local price
629 price="$(curl -s https://api.coinbase.com/v2/prices/BTC-USD/spot | jq -r .data.amount)"
630 price=$(echo "scale=10; $price * 0.00000001"| bc -l)
631 printf "$%f\n" "$price"
632 if [[ $1 ]]; then
633 printf "$%.2f\n" "$(echo "scale=10; $price * $1"| bc -l)"
634 fi
635 }
636 #### end bitcoin related things
637
638
639
640 cbfstool () { /a/opt/coreboot/build/cbfstool "$@"; }
641
642
643 cgpl()
644 {
645 if (($#)); then
646 cp /a/bin/data/COPYING "$@"
647 else
648 cp /a/bin/data/COPYING .
649 fi
650 }
651
652 capache()
653 {
654 if (($#)); then
655 cp /a/bin/data/LICENSE "$@"
656 else
657 cp /a/bin/data/LICENSE .
658 fi
659 }
660
661 chrome() {
662 if type -p chromium &>/dev/null; then
663 cmd=chromium
664 else
665 cd /
666 cmd="schroot -c bullseye chromium"
667 CHROMIUM_FLAGS='--enable-remote-extensions' $cmd &r
668 fi
669 }
670
671
672 # do all tee.
673 # pipe to this, or just type like a shell
674 # todo: test this
675 dat() {
676 tee >(ssh frodo.b8.nz) >(ssh x2) >(ssh tp.b8.nz) >(ssh kw) >(ssh tp.b8.nz)
677 }
678 da() { # do all
679 local host
680 for host in x2 kw tp.b8.nz x3.b8.nz frodo.b8.nz; do
681 ssh $host "$@"
682 done
683 }
684
685
686 debian_pick_mirror () {
687 # netselect-apt finds a fast mirror.
688 # but we need to replace the mirrors ourselves,
689 # because it doesnt do that. best it can do is
690 # output a basic sources file
691 # here we get the server it found, get the main server we use
692 # then substitute all instances of one for the other in the sources file
693 # and backup original to /etc/apt/sources.list-original.
694 # this is idempotent. the only way to identify debian sources is to
695 # note the original server, so we put it in a comment so we can
696 # identify it later.
697 local file
698 file=$(mktemp -d)/f # safe way to get file name without creating one
699 sudo netselect-apt -o "$file" || return 1
700 url=$(grep ^\\w $file | head -n1 | awk '{print $2}')
701 sudo cp -f /etc/apt/sources.list /etc/apt/sources.list-original
702 sudo sed -ri "/http.us.debian.org/ s@( *[^ #]+ +)[^ ]+([^#]+).*@\1$url\2# http.us.debian.org@" /etc/apt/sources.list
703 sudo apt-get update
704 }
705 digme() {
706 digdiff @ns{1,2}.iankelling.org "$@"
707 }
708
709 tsr() { # ts run
710 "$@" |& ts || return $?
711 }
712
713 dup() {
714 local ran_d
715 ran_d=false
716 system-status _
717 case $PS1 in
718 *[\ \]]D\ *)
719 pushd /
720 /b/ds/distro-begin |& ts || return $?
721 /b/ds/distro-end |& ts || return $?
722 popd
723 ran_d=true
724 ;;&
725 *[\ \]]DB\ *)
726 pushd /
727 /b/ds/distro-begin |& ts || return $?
728 popd
729 ran_d=true
730 ;;
731 *[\ \]]DE\ *)
732 pushd /
733 /b/ds/distro-end |& ts || return $?
734 popd
735 ran_d=true
736 ;;&
737 *CONFLINK*)
738 if ! $ran_d; then
739 conflink
740 fi
741 ;;
742 esac
743 system-status _
744 }
745
746 envload() { # load environment from a previous: export > file
747 local file=${1:-$HOME/.${USER}_env}
748 eval "$(export | sed 's/^declare -x/export -n/')"
749 while IFS= read -r line; do
750 # declare -x makes variables local to a function
751 eval ${line/#declare -x/export}
752 done < "$file"
753 }
754
755 failfunc() { asdf a b c; }
756 failfunc2() { failfunc d e f; }
757
758 # one that comes with distros is too old for newer devices
759 fastboot() {
760 /a/opt/android-platform-tools/fastboot "$@";
761 }
762
763 kdecd() { /usr/lib/x86_64-linux-gnu/libexec/kdeconnectd; }
764
765 bat() {
766 cat /sys/class/power_supply/BAT0/capacity
767 }
768
769 # List of apps to install/update
770 # Create from existing manually installed apps by doing
771 # fdroidcl update
772 # fdroidcl search -i, then manually removing
773 # automatically installed/preinstalled apps
774
775 #
776 # # my attempt at recovering from boot loop:
777 # # in that case, boot to recovery (volume up, home button, power, let go of power after samsun logo)
778 # # then
779 # mount /dev/block/mmcblk0p12 /data
780 # cd /data
781 # find -iname '*appname*'
782 # rm -rf FOUND_DIRS
783 # usually good enough to just rm -rf /data/app/APPNAME
784 #
785 # currently broken:
786 # # causes replicant to crash
787 # org.quantumbadger.redreader
788 # org.kde.kdeconnect_tp
789
790 # not broke, but wont work without gps
791 #com.zoffcc.applications.zanavi
792 # not broke, but not using atm
793 #com.nutomic.syncthingandroid
794 # # doesn\'t work on replicant
795 #net.sourceforge.opencamera
796 #
797 fdroid_pkgs=(
798 net.mullvad.mullvadvpn
799 org.schabi.newpipe
800 io.github.subhamtyagi.lastlauncher
801 io.anuke.mindustry
802 com.biglybt.android.client
803 de.marmaro.krt.ffupdater
804 me.ccrama.redditslide
805 org.fedorahosted.freeotp
806 at.bitfire.davdroid
807 com.alaskalinuxuser.justnotes
808 com.artifex.mupdf.viewer.app
809 com.danielkim.soundrecorder
810 com.fsck.k9
811 com.ichi2.anki
812 com.jmstudios.redmoon
813 com.jmstudios.chibe
814 org.kde.kdeconnect_tp
815 com.notecryptpro
816 com.termux
817 cz.martykan.forecastie
818 de.danoeh.antennapod
819 de.blinkt.openvpn
820 de.marmaro.krt.ffupdater
821 eu.siacs.conversations
822 free.rm.skytube.oss
823 im.vector.alpha # riot
824 info.papdt.blackblub
825 me.tripsit.tripmobile
826 net.gaast.giggity
827 net.minetest.minetest
828 net.osmand.plus
829 org.isoron.uhabits
830 org.linphone
831 org.gnu.icecat
832 org.smssecure.smssecure
833 org.yaaic
834 sh.ftp.rocketninelabs.meditationassistant.opensource
835 )
836 # https://forum.xda-developers.com/android/software-hacking/wip-selinux-capable-superuser-t3216394
837 # for maru,
838 #me.phh.superuser
839
840 fdup() {
841 local -A installed updated
842 local p
843 # tried putting this in go buildscript cronjob,
844 # but it failed with undefined: os.UserCacheDir. I expect its due to
845 # an environment variable missing, but its easier just to stick it here.
846 m go get -u mvdan.cc/fdroidcl || return 1
847 m fdroidcl update
848 if fdroidcl search -u | grep ^org.fdroid.fdroid; then
849 fdroidcl install org.fdroid.fdroid
850 sleep 5
851 m fdroidcl update
852 fi
853 for p in $(fdroidcl search -i| grep -o "^\S\+"); do
854 installed[$p]=true
855 done
856 for p in $(fdroidcl search -u| grep -o "^\S\+"); do
857 updated[$p]=false
858 done
859 for p in ${fdroid_pkgs[@]}; do
860 if ! ${installed[$p]:-false}; then
861 m fdroidcl install $p
862 # sleeps are just me being paranoid since replicant has a history of crashing when certain apps are installed
863 sleep 5
864 fi
865 done
866 for p in ${!installed[@]}; do
867 if ! ${updated[$p]:-true}; then
868 m fdroidcl install $p
869 sleep 5
870 fi
871 done
872 }
873
874 firefox-default-profile() {
875 key=Default value=1 section=$1
876 file=/p/c/subdir_files/.mozilla/firefox/profiles.ini
877 sed -ri "/^ *$key/d" "$file"
878 sed -ri "/ *\[$section\]/,/^ *\[[^]]+\]/{/^\s*$key[[:space:]=]/d};/ *\[$section\]/a $key=$value" "$file"
879 }
880 fdhome() { #firefox default home profile
881 firefox-default-profile Profile0
882 }
883
884 fdwork() {
885 firefox-default-profile Profile4
886 }
887
888 ff() {
889 if type -P firefox &>/dev/null; then
890 firefox "$@"
891 else
892 iceweasel "$@"
893 fi
894 }
895
896 fn() {
897 firefox -P alt "$@" >/dev/null 2>&1
898 }
899
900
901 fsdiff () {
902 local missing=false
903 local dname="${PWD##*/}"
904 local m="/a/tmp/$dname-missing"
905 local d="/a/tmp/$dname-diff"
906 [[ -e $d ]] && rm "$d"
907 [[ -e $m ]] && rm "$m"
908 local msize=0
909 local fsfile
910 while read -r line; do
911 fsfile="$1${line#.}"
912 if [[ -e "$fsfile" ]]; then
913 md5diff "$line" "$fsfile" && tee -a "/a/tmp/$dname-diff" <<< "$fsfile $line"
914 else
915 missing=true
916 echo "$line" >> "$m"
917 msize=$((msize + 1))
918 fi
919 done < <(find . -type f )
920 if $missing; then
921 echo "$m"
922 (( msize <= 100 )) && cat $m
923 fi
924 }
925 fsdiff-test() {
926 # expected output, with different tmp dirs
927 # /tmp/tmp.HDPbwMqdC9/c/d ./c/d
928 # /a/tmp/tmp.qLDkYxBYPM-missing
929 # ./b
930 cd $(mktemp -d)
931 echo ok > a
932 echo nok > b
933 mkdir c
934 echo ok > c/d
935 local x
936 x=$(mktemp -d)
937 mkdir $x/c
938 echo different > $x/c/d
939 echo ok > $x/a
940 fsdiff $x
941 }
942 rename-test() {
943 # test whether missing files were renamed, generally for use with fsdiff
944 # $1 = fsdiff output file, $2 = directory to compare to. pwd = fsdiff dir
945 # echos non-renamed files
946 local x y found
947 unset sums
948 for x in "$2"/*; do
949 { sums+=( "$(md5sum < "$x")" ) ; } 2>/dev/null
950 done
951 while read -r line; do
952 { missing_sum=$(md5sum < "$line") ; } 2>/dev/null
953 renamed=false
954 for x in "${sums[@]}"; do
955 if [[ $missing_sum == "$x" ]]; then
956 renamed=true
957 break
958 fi
959 done
960 $renamed || echo "$line"
961 done < "$1"
962 return 0
963 }
964
965 feh() {
966 # F = fullscren, z = random, Z = auto zoom
967 command feh -FzZ "$@"
968 }
969
970
971
972 fw() {
973 firefox -P default "$@" >/dev/null 2>&1
974 }
975
976 gitian() {
977 git config user.email ian@iankelling.org
978 }
979
980 # at least in flidas, things rely on gpg being gpg1
981 gpg() {
982 if type -P gpg2 &>/dev/null; then
983 command gpg2 "$@"
984 else
985 command gpg "$@"
986 fi
987 }
988
989 gse() {
990 local email=ian@iankelling.org
991 git send-email --notes "--envelope-sender=<$email>" \
992 --suppress-cc=self "$@"
993 }
994
995 gup() { /a/f/gnulib/build-aux/gnupload "$@"; }
996
997 dejagnu() { /a/opt/dejagnu/dejagnu "$@"; }
998
999 hstatus() {
1000 # do git status on published repos.
1001 c /a/bin/githtml
1002 for x in *; do
1003 cd $(readlink -f $x)/..
1004 status=$(i status -s) || pwd
1005 if [[ $status ]]; then
1006 hr
1007 echo $x
1008 printf "%s\n" "$status"
1009 fi
1010 cd /a/bin/githtml
1011 done
1012 }
1013
1014 # work log
1015 wlog() {
1016 local day now i
1017 for (( i=0; i<60; i++ )); do
1018 day=$( date +%F -d @$((EPOCHSECONDS - 86400*i )) )
1019 date "+%a %b %d" -d @$((EPOCHSECONDS - 86400*i )) | tr '\n' ' '
1020 /a/opt/timetrap/bin/t d -ftotal -s $day -e $day all -m '^w|lunch$'
1021 done
1022 }
1023 to() { t out -a "$@"; }
1024 ti() { t in -a "$@"; }
1025 tl() {
1026 to "$*"
1027 t s lunch
1028 t in -a "$*"
1029 m t out -a $(date +%F.%T -d @$(( $(date -d "$(echo $*|sed 's/[_.]/ /g')" +%s) + 60*45 )) )
1030 t s w
1031 }
1032
1033 arbttlog() { arbtt-dump "$@" | grep -v '( )\|Current Desktop' | sed -rn '/^[^ ]/{N;s/^(.{21})([0-9]*)[0-9]{3}m.*\(\*/\1\2/;s/^(.{21})[0-9]*.*\(\*/\1/;s/\n//;p}' ; }
1034
1035 idea() {
1036 /a/opt/idea-IC-163.7743.44/bin/idea.sh "$@" &r
1037 }
1038
1039 ilogs() {
1040 ssh root@iankelling.org "cd /var/lib/znc/moddata/log/iank/freenode/ && hr && for x in \#$1/*; do base=\${x##*/}; files=(); for f in $@; do tmp=\#\$f/\$base; if [[ -e \$tmp ]]; then files+=(\#\$f/\$base); fi; done; sed \"s/^./\${base%log}/\" \${files[@]}|sort -n; hr; done"
1041 }
1042
1043 ilog() {
1044 chan=${1:-#fsfsys}
1045 # use * instead of -r since that does sorted order
1046 ssh root@iankelling.org "for n in freenode libera; do cd /var/lib/znc/moddata/log/iank/\$n/$chan && hr && for x in *; do echo \$x; sed \"s/^./\${x%log}/\" \$x; hr; done; done" | less +G
1047 }
1048
1049 o() {
1050 if type gio &> /dev/null ; then
1051 gio open "$@"
1052 elif type gvfs-open &> /dev/null ; then
1053 gvfs-open "$@"
1054 else
1055 xdg-open "$@"
1056 fi
1057 # another alternative is run-mailcap
1058 }
1059 ccomp xdg-open o
1060
1061 # jfilter() {
1062 # grep -Evi -e "^(\S+\s+){4}(sudo|sshd|cron)\[\S*:" \
1063 # -e "^(\S+\s+){4}systemd\[\S*: (starting|started) (btrfsmaintstop|dynamicipupdate|spamd dns bug fix cronjob|rss2email)\.*$"
1064 # }
1065 # jtail() {
1066 # journalctl -n 10000 -f "$@" | jfilter
1067 # }
1068 # jr() { journalctl "$@" | jfilter | less ; }
1069 # jrf() { journalctl -n 200 -f "$@" | jfilter; }
1070
1071 jr() { journalctl "$@" ; }
1072 jrf() { journalctl -n 200 -f "$@" ; }
1073
1074
1075 ccomp journalctl jtail jr jrf
1076
1077 kff() { # keyboardio firmware flash
1078 pushd /a/bin/distro-setup/Arduino/Model01-Firmware
1079 yes $'\n' | make flash
1080 popd
1081 }
1082
1083 wgkey() {
1084 local umask_orig name
1085 if (( $# != 1 )); then
1086 e expected 1 arg >&2
1087 return 1
1088 fi
1089 name=$1
1090 umask_orig=$(umask)
1091 umask 0077
1092 wg genkey | tee $name-priv.key | wg pubkey > $name-pub.key
1093 umask $umask_orig
1094 }
1095 wghole() {
1096 if (( $# != 2 )); then
1097 e expected 2 arg of hostname, ip suffix >&2
1098 return 1
1099 fi
1100 local host ipsuf umask_orig
1101 host=$1
1102 ipsuf=$2
1103 mkdir -p /p/c/machine_specific/$host/filesystem/etc/wireguard
1104 cd /p/c/machine_specific/$host/filesystem/etc/wireguard
1105 umask_orig=$(umask)
1106 umask 0077
1107 wg genkey | tee hole-priv.key | wg pubkey > hole-pub.key
1108 cat >wghole.conf <<EOF
1109 [Interface]
1110 # contents hole-priv.key
1111 PrivateKey = $(cat hole-priv.key)
1112 ListenPort = 1194
1113 Address = 10.8.0.$ipsuf/24
1114 # https://dev.to/tangramvision/what-they-don-t-tell-you-about-setting-up-a-wireguard-vpn-1h2g
1115 # ||: makes the systemd service not fail due to the failed command
1116 PostUp = ping -c1 10.8.0.1 ||:
1117
1118 [Peer]
1119 # li. called wgmail on that server
1120 PublicKey = CTFsje45qLAU44AbX71Vo+xFJ6rt7Cu6+vdMGyWjBjU=
1121 AllowedIPs = 10.8.0.0/24
1122 Endpoint = 72.14.176.105:1194
1123 PersistentKeepalive = 25
1124 EOF
1125 umask $umask_orig
1126 # old approach. systemd seems to work fine and cleaner.
1127 rm -f ../network/interfaces.d/wghole
1128 cedit -q $host /p/c/machine_specific/li/filesystem/etc/wireguard/wgmail.conf <<EOF || [[ $? == 1 ]]
1129 [Peer]
1130 PublicKey = $(cat hole-pub.key)
1131 AllowedIPs = 10.8.0.$ipsuf/32
1132 EOF
1133 cd - >/dev/null
1134 }
1135
1136
1137 mns() { # mount namespace
1138 ns=$1
1139 shift
1140 s mkdir -p /root/mount_namespaces
1141 if ! s mountpoint /root/mount_namespaces >/dev/null; then
1142 m s mount --bind /root/mount_namespaces /root/mount_namespaces
1143 fi
1144 m s mount --make-private /root/mount_namespaces
1145 if [[ ! -e /root/mount_namespaces/$ns ]]; then
1146 s touch /root/mount_namespaces/$ns
1147 fi
1148 if ! s mountpoint /root/mount_namespaces/$ns >/dev/null; then
1149 m unshare --propagation slave --mount=/root/mount_namespaces/$ns /bin/true
1150 fi
1151 m sudo -E /usr/bin/nsenter --mount=/root/mount_namespaces/$ns "$@"
1152 }
1153
1154 mnsnonet() {
1155 ns=$1
1156 if ! s ip netns list | grep -Fx nonet &>/dev/null; then
1157 s ip netns add nonet
1158 fi
1159 mns $ns --net=/var/run/netns/nonet sudo -E -u iank /bin/bash
1160 }
1161
1162
1163 lom() {
1164 local l base
1165 if [[ $1 == /* ]]; then
1166 base=${1##*/}
1167 if mountpoint -q /mnt/$base; then
1168 return 0
1169 fi
1170 l=$(losetup -j $1 | sed -rn 's/^([^ ]+): .*/\1/p' | head -n1 ||:)
1171 if [[ ! $l ]]; then
1172 l=$(sudo losetup -f)
1173 m sudo losetup $l $1
1174 fi
1175 if ! sudo cryptsetup status /dev/mapper/$base &>/dev/null; then
1176 if ! sudo cryptsetup luksOpen $l $base; then
1177 m sudo losetup -d $l
1178 return 1
1179 fi
1180 fi
1181 m sudo mkdir -p /mnt/$base
1182 m mns mount /dev/mapper/$base /mnt/$base
1183 m mns chown $USER:$USER /mnt/$base
1184 else
1185 base=$1
1186 if mns mountpoint /mnt/$base &>/dev/null; then
1187 m mns umount /mnt/$base
1188 fi
1189 if sudo cryptsetup status /dev/mapper/$base &>/dev/null; then
1190 if ! m sudo cryptsetup luksClose /dev/mapper/$base; then
1191 echo lom: failed cryptsetup luksClose /dev/mapper/$base
1192 return 1
1193 fi
1194 fi
1195 l=$(losetup -l --noheadings | awk '$6 ~ /\/'$1'$/ {print $1}')
1196 if [[ $l ]]; then
1197 m sudo losetup -d $l
1198 else
1199 echo lom: warning: no loopback device found
1200 fi
1201 fi
1202 }
1203
1204 # mu personality. for original, just run mp. for 2, run mp 2.
1205 # this is partly duplicated in mail-setup
1206 mp() {
1207 local dead=false
1208 for s in {1..5}; do
1209 if ! killall mu; then
1210 dead=true
1211 break
1212 fi
1213 sleep 1
1214 done
1215 if ! $dead; then
1216 echo error: mu not dead
1217 m psg mu
1218 return 1
1219 fi
1220 suf=$1
1221 set -- /m/mucache ~/.cache/mu /m/.mu ~/.config/mu
1222 while (($#)); do
1223 target=$1$suf
1224 f=$2
1225 shift 2
1226 if [[ -e $f && ! -L $f ]]; then
1227 m rm -rf $f
1228 fi
1229 m ln -sf -T $target $f
1230 done
1231 }
1232
1233 # these might need a mu index or something added.
1234 mbenable() {
1235 local mb=$1
1236 dst=/m/4e/$mb
1237 src=/m/md/$mb
1238 [[ -e $src ]] || { echo "src:$src does not exist"; return 1; }
1239 m mv -T $src $dst
1240 m ln -s -T $dst $src
1241 }
1242 mb2enable() {
1243 local mb
1244 for mb; do
1245 dst=/m/4e2/$mb
1246 link=/m/md/$mb
1247 src=/m/md/$mb
1248 if [[ ! -e $src || -L $src ]]; then
1249 src=/m/4e/$mb
1250 fi
1251 [[ -e $src ]] || { echo "src:$src does not exist"; return 1; }
1252 m mv -T $src $dst
1253 m ln -sf -T $dst $link
1254 done
1255 }
1256 mbdisable() {
1257 local mb=$1
1258 dst=/m/md/$mb
1259 src=/m/4e/$mb
1260 set -x
1261 [[ -e $src ]] || { set +x; return 1; }
1262 if [[ -L $dst ]]; then rm $dst; fi
1263 mv -T $src $dst
1264 set +x
1265 }
1266
1267
1268 mdt() {
1269 markdown "$1" >/tmp/mdtest.html
1270 firefox /tmp/mdtest.html
1271 }
1272
1273 mo() { xset dpms force off; } # monitor off
1274
1275 mpvd() {
1276 mpv --profile=d "$@";
1277 }
1278 mpvs() {
1279 mpv --profile=s "$@";
1280 }
1281
1282 myirc() {
1283 if [[ ! $1 ]]; then
1284 set -- fsf-office
1285 fi
1286 local d1 d2
1287 d=( /var/lib/znc/moddata/log/iank/{freenode,libera} )
1288 # use * instead of -r since that does sorted order
1289 ssh root@iankelling.org "for f in ${d[@]}; do cd \$f/#$1; grep '\<iank.*' *; done" | cut --complement -c12-16
1290 }
1291 mypidgin() {
1292 c /p/c/.purple/logs/jabber/iank@fsf.org/office@conference.fsf.org.chat
1293 for x in *.html; do html2text -o ${x%.html}.txt $x; done;
1294 grep -A1 ') iank:' *.txt | sed -r 's/^(.{10})[^ ]*\.txt:\(?([^ ]*)[[:space:]](..). iank:/\1_\2_\3/;s/^[^ ]*\.txt-//;/^--$/d;s/^[^ ]*\.txt:\((.{2}).(.{2}).(.{4}) (.{8}) (.{2})\)?/\3-\1-\2_\4_\5/' | sed -n 'x;1d;0~2{G;s/\n/ /;p};${x;p}'
1295 }
1296 allmyirc() {
1297 local d
1298 d=/var/lib/znc/moddata/log/iank/freenode
1299 ssh root@iankelling.org "cd $d; find . -mtime -60 -type f -exec grep '\<iank.*' {} +" | sed -r 's,^..([^/]*)/(.{11})(.{5})(.{8}).,\2\4 \1,' | sort
1300 }
1301
1302 mygajim() {
1303 local time time_sec time_pretty
1304 sqlite3 -separator ' ' /p/c/subdir_files/.local/share/gajim/logs.db "select time, message from logs where contact_name = 'iank' and jid_id = 17;" | while read -r time l; do
1305 case $time in
1306 16*) : ;;
1307 *) continue ;;
1308 esac
1309 if ! time_pretty=$(date +%F.%R -d @$time); then
1310 echo bad time: $time
1311 return 1
1312 fi
1313 echo $time_pretty "$l"
1314 time_sec=${time%%.*}
1315 # only look at the last 18 days. generally just use this for timesheet.
1316 if (( time_sec < EPOCHSECONDS - 60 * 60 * 24 * 18 )); then break; fi
1317 done
1318 }
1319
1320 allmygajim() {
1321 sqlite3 -separator ' ' /p/c/subdir_files/.local/share/gajim/logs.db "select time, message from logs where contact_name = 'iank'" | less
1322 }
1323
1324 gajlogs() {
1325 sqlite3 -separator ' ' /p/c/subdir_files/.local/share/gajim/logs.db "select time, message from logs" | less
1326 }
1327
1328 net-dev-info() {
1329 e "lspci -nnk|gr -iA2 net"
1330 lspci -nnk|gr -iA2 net
1331 hr
1332 e "s lshw -C network"
1333 hr
1334 sudo lshw -C network
1335 }
1336
1337 nk() {
1338 ser stop NetworkManager
1339 ser disable NetworkManager
1340 ser stop NetworkManager-wait-online.service
1341 ser disable NetworkManager-wait-online.service
1342 ser stop dnsmasq
1343 sudo resolvconf -d NetworkManager
1344 # ser start dnsmasq
1345 sudo ifup br0
1346 }
1347 ngo() {
1348 sudo ifdown br0
1349 ser start NetworkManager
1350 sleep 4
1351 sudo nmtui-connect
1352 }
1353
1354 otp() {
1355 oathtool --totp -b "$*" | xclip -selection clipboard
1356 }
1357 j() {
1358 "$@" |& pee "xclip -r -selection clipboard"
1359 }
1360
1361
1362 pakaraoke() {
1363 # from http://askubuntu.com/questions/456021/remove-vocals-from-mp3-and-get-only-instrumentals
1364 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
1365 }
1366
1367 pfind() { #find *$1* in $PATH
1368 [[ $# != 1 ]] && { echo requires 1 argument; return 1; }
1369 local pathArray
1370 IFS=: pathArray=($PATH); unset IFS
1371 find "${pathArray[@]}" -iname "*$1*"
1372 }
1373
1374 pick-trash() {
1375 # trash-restore lists everything that has been trashed at or below CWD
1376 # This picks out files just in CWD, not subdirectories,
1377 # which also match grep $1, usually use $1 for a time string
1378 # which you get from running restore-trash once first
1379 local name x ask
1380 local nth=1
1381 # last condition is to not ask again for ones we skipped
1382 while name="$( echo | restore-trash | gr "$PWD/[^/]\+$" | gr "$1" )" \
1383 && [[ $name ]] && (( $(wc -l <<<"$name") >= nth )); do
1384 name="$(echo "$name" | head -n $nth | tail -n 1 )"
1385 read -r -p "$name [Y/n] " ask
1386 if [[ ! $ask || $ask == [Yy] ]]; then
1387 x=$( echo "$name" | gr -o "^\s*[0-9]*" )
1388 echo $x | restore-trash > /dev/null
1389 elif [[ $ask == [Nn] ]]; then
1390 nth=$((nth+1))
1391 else
1392 return
1393 fi
1394 done
1395 }
1396
1397
1398 pub() {
1399 rld /a/h/_site/ li:/var/www/iankelling.org/html
1400 }
1401
1402
1403 pumpa() {
1404 # fixes the menu bar in xmonad. this won\'t be needed when xmonad
1405 # packages catches up on some changes in future (this is written in
1406 # 4/2017)
1407 #
1408 # geekosaur: so youll want to upgrade to xmonad 0.13 or else use a
1409 # locally modified XMonad.Hooks.ManageDocks that doesnt set the
1410 # work area; turns out it\'s impossible to set correctly if you are
1411 # not a fully EWMH compliant desktop environment
1412 #
1413 # geekosaur: chrome shows one failure mode, qt/kde another, other
1414 # gtk apps a third, ... I came up with a setting that works for me
1415 # locally but apparently doesnt work for others, so we joined the
1416 # other tiling window managers in giving up on setting it at all
1417 #
1418 xprop -root -remove _NET_WORKAREA
1419 command pumpa & r
1420 }
1421
1422 # reviewboard, used at my old job
1423 #rbpipe() { rbt post -o --diff-filename=- "$@"; }
1424 #rbp() { rbt post -o "$@"; }
1425
1426 rebr() {
1427 sudo ifdown br0
1428 sudo ifup br0
1429 }
1430
1431
1432 # only run on MAIL_HOST. simpler to keep this on one system.
1433 r2eadd() { # usage: name url
1434 # initial setup of rss2email:
1435 # r2e new r2e@iankelling.org
1436 # that initializes files, and sets default email.
1437 # symlink to the config doesnt work, so I copied it to /p/c
1438 # and then use cli option to specify explicit path.
1439 # Only option changed from default config is to set
1440 # force-from = True
1441 #
1442 # or else for a few feeds, the from address is set by the feed, and
1443 # if I fail delivery, then I send a bounce message to that from
1444 # address, which makes me be a spammer.
1445
1446 r2e add $1 "$2" $1@r2e.iankelling.org
1447 # get up to date and dont send old entries now:
1448 r2e run --no-send $1
1449 }
1450 r2e() { command r2e -d /p/c/rss2email.json -c /p/c/rss2email.cfg "$@"; }
1451
1452 rspicy() { # usage: HOST DOMAIN
1453 # connect to spice vm remote host. use vspicy for local host
1454 local port
1455 # shellcheck disable=SC2087
1456 port=$(ssh $1<<EOF
1457 sudo virsh dumpxml $2|grep "<graphics.*type='spice'" | \
1458 sed -rn "s/.*port='([0-9]+).*/\1/p"
1459 EOF
1460 )
1461 if [[ $port ]]; then
1462 spicy -h $1 -p $port
1463 else
1464 echo "error: no port found. check that the domain is running."
1465 fi
1466 }
1467
1468
1469 scssl() {
1470 # s gem install scss-lint
1471 pushd /a/opt/thoughtbot-guides
1472 git pull --stat
1473 popd
1474 scss-lint -c /a/opt/thoughtbot-guides/style/sass/.scss-lint.yml "$@"
1475 }
1476
1477 skbrc() {
1478 sk -e 2120,245 /b/ds/brc /b/ds/brc2
1479 }
1480
1481 skaraoke() {
1482 local tmp out
1483 out=${2:-${1%.*}.sh}
1484 tmp=$(mktemp -d)
1485 script -t -c "mpv --no-config --no-resume-playback --no-terminal --no-audio-display '$1'" $tmp/typescript 2>$tmp/timing
1486 # todo, the current sleep seems pretty good, but it
1487 # would be nice to have an empirical measurement, or
1488 # some better wait to sync up.
1489 #
1490 # note: --loop-file=no prevents it from hanging if you have that
1491 # set to inf the mpv config.
1492 # --loop=no prevents it from exit code 3 due to stdin if you
1493 # had it set to inf in mpv config.
1494 #
1495 # args go to mpv, for example --volume=80, 50%
1496 cat >$out <<EOFOUTER
1497 #!/bin/bash
1498 trap "trap - TERM && kill 0" INT TERM ERR; set -e
1499 ( sleep .2; scriptreplay <( cat <<'EOF'
1500 $(cat $tmp/timing)
1501 EOF
1502 ) <( cat <<'EOF'
1503 $(cat $tmp/typescript)
1504 EOF
1505 ))&
1506 base64 -d - <<'EOF'| mpv --loop=no --loop-file=no --no-terminal --no-audio-display "\$@" -
1507 $(base64 "$1")
1508 EOF
1509 kill 0
1510 EOFOUTER
1511 rm -r $tmp
1512 chmod +x $out
1513 }
1514
1515 smeld() { # ssh meld usage host1 host2 file
1516 meld <(ssh $1 cat $3) <(ssh $2 cat $3)
1517 }
1518
1519 spd() {
1520 PATH=/usr/local/spdhackfix:$PATH command spd "$@"
1521 }
1522
1523 spend() {
1524 sudo systemctl suspend
1525 }
1526
1527 spamf() { # spamtest on FILE
1528 local spamcpre spamdpid
1529
1530 if (( $# != 1 )); then
1531 e spamtest error: expected 1 arg, filename >&2
1532 return 1
1533 fi
1534
1535 spamdpid=$(systemctl status spamassassin| sed -n '/^ *Main PID:/s/[^0-9]//gp')
1536 spamcpre="nsenter -t $spamdpid -n -m"
1537 s $spamcpre sudo -u Debian-exim spamassassin -t --cf='score PYZOR_CHECK 0' <"$1"
1538 }
1539
1540
1541 # mail related
1542 testmail() {
1543 declare -gi _seq; _seq+=1
1544 echo "test body" | m mail -s "test mail from $HOSTNAME, $_seq" "${@:-root@localhost}"
1545 # for testing to send from an external address, you can do for example
1546 # -fian@iank.bid -aFrom:ian@iank.bid web-6fnbs@mail-tester.com
1547 # note in exim, you can retry a deferred message
1548 # s exim -M MSG_ID
1549 # MSG_ID is in /var/log/exim4/mainlog, looks like 1ccdnD-0001nh-EN
1550 }
1551
1552 # to test sieve, use below command. for fsf mail, see offlineimap-sync script
1553 # make modifications, then copy to live file, use -eW to actually modify mailbox
1554 #
1555 # Another option is to use sieve-test SCRIPT MAIL_FILE. note,
1556 # sieve-test doesnt know about envelopes, Im not sure if sieve-filter does.
1557
1558 # sieve with output filter. arg is mailbox, like INBOX.
1559 # This depends on dovecot conf, notably mail_location in /etc/dovecot/conf.d/10-mail.conf
1560
1561 # always run this first, edit the test files, then run the following
1562 testsieve() {
1563 sieve-filter ~/sieve/maintest.sieve ${1:-INBOX} delete 2> >(head; tail) >/tmp/testsieve.log && sed -rn '/^Performed actions:/,/^[^ ]/{/^ /p}' /tmp/testsieve.log | sort | uniq -c
1564 }
1565 runsieve() {
1566 c ~/sieve; cp personal{test,}.sieve; cp lists{test,}.sieve; cp personalend{test,}.sieve
1567 sieve-filter -eWv ~/sieve/maintest.sieve ${1:-INBOX} delete &> /tmp/testsieve.log
1568 sed -r '/^info: filtering:/{h;d};/^info: msgid=$/N;/^info: msgid=.*left message in mailbox [^ ]+$/d;/^info: msgid=/{H;g};/^info: message kept in source mailbox.$/d' /tmp/testsieve.log
1569 }
1570
1571 # usage:
1572 # alertme SUBJECT
1573 # printf "subject\nbody\n" | alertme
1574 alertme() {
1575 if [[ -t 0 ]]; then
1576 exim -t <<EOF
1577 From: alertme@b8.nz
1578 To: alerts@iankelling.org
1579 Subject: $*
1580 EOF
1581 else
1582 read sub
1583 { cat <<EOF
1584 From: alertme@b8.nz
1585 To: alerts@iankelling.org
1586 Subject: $sub
1587
1588 EOF
1589 cat
1590 } | exim -t
1591 fi
1592 }
1593 daylertme() {
1594 if [[ -t 0 ]]; then
1595 exim -t <<EOF
1596 From: alertme@b8.nz
1597 To: daylert@iankelling.org
1598 Subject: $*
1599 EOF
1600 else
1601 read sub
1602 { cat <<EOF
1603 From: alertme@b8.nz
1604 To: daylert@iankelling.org
1605 Subject: $sub
1606
1607 EOF
1608 cat
1609 } | exim -t
1610 fi
1611 }
1612
1613 # alert when a page goes live. not urgent.
1614 alert200() {
1615 url="$1"
1616 tmpdir="$(mktemp -d)"
1617 cd $tmpdir
1618 while true; do
1619 if torsocks wget -q "$url"; then
1620 alertme $tmpdir
1621 fi
1622 sleep $(( 600 + RANDOM % 300 ))
1623 done
1624 }
1625
1626
1627 # mail related
1628 testexim() {
1629 # testmail above calls sendmail, which is a link to exim/postfix.
1630 # its docs dont say a way of adding an argument
1631 # to sendmail to turn on debug output. We could make a wrapper, but
1632 # that is a pain. Exim debug args are documented here:
1633 # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html
1634 #
1635 # http://www.exim.org/exim-html-current/doc/html/spec_html/ch-building_and_installing_exim.html
1636 # note, for exim daemon, you can turn on debug options by
1637 # adding -d, etc to COMMONOPTIONS in
1638 # /etc/default/exim4
1639 #
1640 # to specify recipients other than those in to, cc, bcc, you can use the cli args, eg:
1641 # exim -t 'test@zroe.org, t2@zroe.org' <<'EOF'
1642 #
1643 # -t = get recipient from header
1644 exim -d -t <<'EOF'
1645 From: i@dmarctest.b8.nz
1646 To: mailman@dev.fsf.org
1647 Subject: test2
1648 Reply-to: rtest@iankelling.org
1649
1650 This is a test message.
1651 EOF
1652 }
1653
1654 # toggle keyboard
1655 tk() {
1656 # based on
1657 # https://askubuntu.com/questions/160945/is-there-a-way-to-disable-a-laptops-internal-keyboard
1658 id=$(xinput --list --id-only 'AT Translated Set 2 keyboard')
1659 if xinput list | grep -F '∼ AT Translated Set 2 keyboard' &>/dev/null; then
1660 echo enabling keyboard
1661 # find the first slave keyboard number, they are all the same in my output.
1662 # if they werent, worst case we would need to save the slave number somewhere
1663 # when it got disabled.
1664 slave=$(xinput list | sed -n 's/.*slave \+keyboard (\([0-9]*\)).*/\1/p' | head -n1)
1665 xinput reattach $id $slave
1666 else
1667 xinput float $id
1668 fi
1669 }
1670
1671 tm() {
1672 # timer in minutes
1673 # --no-config
1674 (sleep $(calc "$* * 60") && mpv --no-config --volume 50 /a/bin/data/alarm.mp3) > /dev/null 2>&1 &
1675 }
1676
1677 trg() { transmission-remote-gtk & r; }
1678 trc() {
1679 # example, set global upload limit to 100 kilobytes:
1680 # trc -u 100
1681 TR_AUTH=":$(jq -r .profiles[0].password ~/.config/transmission-remote-gtk/config.json)" transmission-remote transmission.lan -ne "$@"
1682 }
1683
1684 trysleep() {
1685 retries="$1"
1686 sleepsecs="$2"
1687 shift 2
1688 for (( i=0; i < retries - 1; i++ )); do
1689 if "$@"; then
1690 return 0
1691 fi
1692 sleep $sleepsecs
1693 done
1694 "$@"
1695 }
1696
1697
1698 tu() {
1699 local s
1700 if [[ -e $1 && ! -w $1 || ! -w $(dirname "$1") ]]; then
1701 s=s;
1702 fi
1703 # full path for using in some initial setup steps
1704 $s /a/exe/teeu "$@"
1705 }
1706
1707 enn() {
1708 local ecmd pid
1709
1710 ecmd="/usr/sbin/exim4 -C /etc/exim4/my.conf"
1711 if ip a show veth1-mail &>/dev/null; then
1712 s $ecmd "$@"
1713 return
1714 fi
1715 pid=$(pgrep -f "/usr/sbin/exim4 -bd -q30m -C /etc/exim4/my.conf"|h1)
1716 m s nsenter -t $pid -n -m $ecmd "$@"
1717 }
1718
1719 sdnbash() { # systemd namespace bash
1720 local unit=$1
1721 m sudo nsenter -t $(systemctl show --property MainPID --value $unit) -n -m sudo -u $USER -i bash
1722 }
1723
1724 mailnnbash() {
1725 m sudo nsenter -t $(systemctl show --property MainPID --value mailnn) -n -m sudo -u $USER -i bash
1726 }
1727
1728 mailvpnbash() {
1729 m sudo nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*mail.conf") -n -m sudo -u $USER -i bash
1730 }
1731 eximbash() {
1732 local pid
1733 pid=$(pgrep -f "/usr/sbin/exim4 -bd -q30m -C /etc/exim4/my.conf"|h1)
1734 if [[ ! $pid ]]; then
1735 echo "eximbash: failed to find exim pid. systemctl -n 30 status exim4:"
1736 systemctl status exim4
1737 fi
1738 m sudo nsenter -t $pid -n -m
1739 }
1740 spamnn() {
1741 local spamdpid
1742 spamdpid=$(systemctl show --property MainPID --value spamassassin)
1743 m sudo nsenter -t $spamdpid -n -m sudo -u Debian-exim spamassassin "$@"
1744 }
1745 unboundbash() {
1746 m sudo nsenter -t $(systemctl status unbound| sed -n '/^ *Main PID:/s/[^0-9]//gp') -n -m sudo -u $USER -i bash
1747 }
1748
1749 mailnncheck() {
1750 local p pid ns mailnn
1751 # mailvpn would belong on the list if using openvpn
1752 for p in mailnn unbound dovecot spamassassin exim4 radicale; do
1753 case $p in
1754 exim4|radicale)
1755 pid=$(ps -eo pid,cgroup | grep /system.slice/$p.service | awk '{print $1}')
1756 ;;
1757 *)
1758 pid=$(s systemctl show --property MainPID --value $p)
1759 ;;
1760 esac
1761 echo p=$p pid=$pid
1762 if [[ ! $pid ]]; then
1763 echo failed to find pid for $p
1764 continue
1765 fi
1766 if ! ns=$(s readlink /proc/$pid/ns/net); then
1767 echo failed to find ns for $p pid=$pid
1768 continue
1769 fi
1770 if [[ $mailnn ]]; then
1771 if [[ $ns != "$mailnn" ]]; then
1772 echo "$p ns $ns != $mailnn"
1773 fi
1774 else
1775 mailnn=$ns
1776 fi
1777 done
1778
1779 }
1780
1781
1782 vpncmd() {
1783 m sudo -E env "PATH=$PATH" nsenter -t $(pgrep -f "/usr/sbin/openvpn .* --config /etc/openvpn/.*client.conf") -n -m "$@"
1784 }
1785 vpnf() {
1786 sudo -v
1787 vpncmd sudo -E -u iank env "PATH=$PATH" abrowser -no-remote -P vpn &
1788 sleep 5
1789 r
1790 }
1791 vpn2f() {
1792 sudo -v
1793 vpncmd sudo -u iank env "PATH=$PATH" abrowser -no-remote -P vpn2 & r
1794 }
1795
1796 vpni() {
1797 vpncmd sudo -u iank env "PATH=$PATH" "$@"
1798 }
1799 vpnbash() {
1800 vpncmd bash
1801 }
1802
1803
1804 vpn() {
1805 if [[ -e /lib/systemd/system/openvpn-client@.service ]]; then
1806 local vpn_service=openvpn-client
1807 else
1808 local vpn_service=openvpn
1809 fi
1810
1811 [[ $1 ]] || { echo need arg; return 1; }
1812 journalctl --unit=$vpn_service@$1 -f -n0 &
1813 # sometimes the journal doesnt open until after the vpn output
1814 # has happened. hoping this fixes that.
1815 sleep 1
1816 sudo systemctl start $vpn_service@$1
1817 # sometimes the ask-password agent does not work and needs a delay.
1818 sleep .5
1819 # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=779240
1820 # noticed around 8-2017 after update from around stretch release
1821 # on debian testing, even though the bug is much older.
1822 sudo systemd-tty-ask-password-agent
1823 }
1824
1825 fixu() {
1826 ls -lad /run/user/1000
1827 s chmod 700 /run/user/1000; s chown iank.iank /run/user/1000
1828 }
1829
1830 # systemctl is-enabled / status / cat says nothing, instead theres
1831 # some obscure symlink. paths copied from man systemd.unit.
1832 # possibly also usefull, but incomplete, doesnt show units not loaded in memory:
1833 # seru list-dependencies --reverse --all UNIT
1834 sysd-deps() {
1835 local f
1836 local -a dirs search
1837 ngset
1838
1839 case $1 in
1840 u)
1841 search=(
1842 ~/.config/systemd/user.control/*
1843 $XDG_RUNTIME_DIR/systemd/user.control/*
1844 $XDG_RUNTIME_DIR/systemd/transient/*
1845 $XDG_RUNTIME_DIR/systemd/generator.early/*
1846 ~/.config/systemd/user/*
1847 /etc/systemd/user/*
1848 $XDG_RUNTIME_DIR/systemd/user/*
1849 /run/systemd/user/*
1850 $XDG_RUNTIME_DIR/systemd/generator/*
1851 ~/.local/share/systemd/user/*
1852 /usr/lib/systemd/user/*
1853 $XDG_RUNTIME_DIR/systemd/generator.late/*
1854 )
1855 ;;
1856 *)
1857 search=(
1858 /etc/systemd/system.control/*
1859 /run/systemd/system.control/*
1860 /run/systemd/transient/*
1861 /run/systemd/generator.early/*
1862 /etc/systemd/system/*
1863 /etc/systemd/systemd.attached/*
1864 /run/systemd/system/*
1865 /run/systemd/systemd.attached/*
1866 /run/systemd/generator/*
1867 /lib/systemd/system/*
1868 /run/systemd/generator.late/*
1869 )
1870 ;;
1871 esac
1872 for f in "${search[@]}"; do
1873 [[ -d $f ]] || continue
1874 case $f in
1875 *.requires|*.wants)
1876 dirs+=("$f")
1877 ;;
1878 esac
1879 done
1880 # dirs is just so we write out the directory names, ls does it when there is 2 or more dirs.
1881 case ${#dirs[@]} in
1882 1)
1883 echo "${dirs[0]}:"
1884 ll "${dirs[@]}"
1885 ;;
1886 0) : ;;
1887 *)
1888 ll "${dirs[@]}"
1889 ;;
1890 esac
1891 ngreset
1892 }
1893
1894 fixvpndns() {
1895 local link istls
1896 read _ link _ istls < <(resolvectl dnsovertls tunfsf)
1897 case $istls in
1898 yes|no) : ;;
1899 *) echo fixvpndns error: unexpected istls value: $istls >&2; return 1 ;;
1900 esac
1901 s busctl call org.freedesktop.resolve1 /org/freedesktop/resolve1 org.freedesktop.resolve1.Manager SetLinkDNSOverTLS is $link no
1902 }
1903
1904 vpnoff() {
1905 [[ $1 ]] || { echo need arg; return 1; }
1906 if [[ -e /lib/systemd/system/openvpn-client@.service ]]; then
1907 local vpn_service=openvpn-client
1908 else
1909 local vpn_service=openvpn
1910 fi
1911 sudo systemctl stop $vpn_service@$1
1912 }
1913 vpnoffc() { # vpn off client
1914 ser stop openvpn-client-tr@client
1915 }
1916 vpnc() {
1917 ser start openvpn-client-tr@client
1918 }
1919
1920
1921 vspicy() { # usage: VIRSH_DOMAIN
1922 # connect to vms made with virt-install
1923 spicy -p $(sudo virsh dumpxml "$1"|grep "<graphics.*type='spice'"|\
1924 sed -r "s/.*port='([0-9]+).*/\1/")
1925 }
1926
1927 wian() {
1928 cat-new-files /m/4e/INBOX/new
1929 }
1930
1931 wtr() { curl wttr.in/boston; }
1932
1933 xevkb() { xev -event keyboard; }
1934
1935 # * misc stuff
1936
1937 vrun() {
1938 printf "running: %s\n" "$*"
1939 "$@"
1940 }
1941
1942 f=/a/f/ansible-configs/files/common/etc/fsf-workstation-bashrc.sh
1943 if [[ -e $f ]]; then
1944 # shellcheck disable=SC1090
1945 source $f
1946 fi
1947
1948 electrum() {
1949 # https://electrum.readthedocs.io/en/latest/tor.html
1950 # https://github.com/spesmilo/electrum-docs/issues/129
1951 s rsync -ptog --chown bitcoin:bitcoin ~/.Xauthority /var/lib/bitcoind/.Xauthority
1952 sudo -u bitcoin DISPLAY=$DISPLAY XAUTHORITY=/var/lib/bitcoind/.Xauthority /a/opt/electrum-4.2.1-x86_64.AppImage -p socks5:localhost:9050
1953 }
1954 monero() {
1955 sudo -u bitcoin DISPLAY=$DISPLAY XAUTHORITY=/var/lib/bitcoind/.Xauthority /a/opt/monero-gui-v0.17.3.2/monero-wallet-gui
1956 }
1957
1958
1959 reset-konsole() {
1960 # we also have a file in /a/c/...konsole...
1961 local f=$HOME/.config/konsolerc
1962 setini DefaultProfile profileian.profile "Desktop Entry" $f
1963 setini Favorites profileian.profile "Favorite Profiles" $f
1964 setini ShowMenuBarByDefault false KonsoleWindow $f
1965 setini TabBarPosition Top TabBar $f
1966 }
1967
1968 reset-sakura() {
1969 while read -r k v; do
1970 # shellcheck disable=SC2154
1971 setini $k $v sakura /a/c/subdir_files/.config/sakura/sakura.conf
1972 done <<'EOF'
1973 colorset1_back rgb(33,37,39)
1974 less_questions true
1975 audible_bell No
1976 visible_bell No
1977 disable_numbered_tabswitch true
1978 scroll_lines 10000000
1979 scrollbar true
1980 EOF
1981 }
1982
1983 # make a page of links found in the files $@. redirect output
1984 linkhtml() {
1985 gr -oh 'https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)' "$@" | \
1986 rev | sort -u | rev | sed 's,.*,<a href="\0">\0</a><br\>,'
1987 }
1988
1989 reset-xscreensaver() {
1990 # except for spash, i set these by setting gui options in
1991 # xscreensaver-command -demo
1992 # then finding the corresponding option in .xscreensaver
1993 # spash, i happened to notice in .xscreensaver
1994 #
1995 # dpmsOff, monitor doesnt come back on using old free software supported nvidia card
1996 cat > /home/iank/.xscreensaver <<'EOF'
1997 mode: blank
1998 dpmsEnabled: True
1999 dpmsStandby: 0:07:00
2000 dpmsSuspend: 0:08:00
2001 dpmsOff: 0:00:00
2002 timeout: 0:05:00
2003 lock: True
2004 lockTimeout: 0:06:00
2005 splash: False
2006 EOF
2007
2008 }
2009
2010
2011 # * stuff that makes sense to be at the end
2012 if [[ "$SUDOD" ]]; then
2013 # allow failure, for example if we are sudoing into a user with diffferent/lesser permissions.
2014 cd "$SUDOD" ||:
2015 unset SUDOD
2016 elif [[ -d /a ]] && [[ $PWD == "$HOME" ]] && [[ $- == *i* ]]; then
2017 cd /a
2018 fi
2019
2020
2021
2022
2023 # for mitmproxy to get a newer python.
2024 # commented until i want to use it because it
2025 # noticably slows bash startup
2026 #
2027
2028 mypyenvinit () {
2029 if [[ $EUID == 0 || ! -e ~/.pyenv/bin ]]; then
2030 echo "error: dont be root. make sure pyenv is installed"
2031 return 1
2032 fi
2033 export PATH="$HOME/.pyenv/bin:$PATH"
2034 eval "$(pyenv init -)"
2035 eval "$(pyenv virtualenv-init -)"
2036 }
2037
2038
2039 export GOPATH=$HOME/go
2040 path-add $GOPATH/bin
2041 path-add /usr/local/go/bin
2042
2043 # I have the git repo and a release. either one should work.
2044 # I have both because I was trying to solve an issue that
2045 # turned out to be unrelated.
2046 # ARDUINO_PATH=/a/opt/Arduino/build/linux/work
2047 export ARDUINO_PATH=/a/opt/arduino-1.8.15
2048 export KALEIDOSCOPE_DIR=/a/opt/Kaleidoscope
2049
2050 # They want to be added to the start, but i think
2051 # that should be avoided unless we really need it.
2052 path-add --end ~/.npm-global
2053
2054
2055 path-add --end $HOME/.cargo/bin
2056
2057 if type -P rg &>/dev/null; then
2058 # --no-messages because of annoying errors on broken symlinks
2059 rg() { command rg --no-messages -L -i -M 300 --no-ignore "$@" || return $?; }
2060 #fails if not exist. ignore
2061 complete -r rg 2>/dev/null ||:
2062 else
2063 alias rg=grr
2064 fi
2065
2066
2067
2068 # taken from default changes to bashrc and bash_profile
2069 path-add --end --ifexists $HOME/.rvm/bin
2070 # also had ruby bin dir, but moved that to environment.sh
2071 # so its included in overall env
2072
2073
2074 export BASEFILE_DIR=/a/bin/fai-basefiles
2075
2076 #export ANDROID_HOME=/a/opt/android-home
2077 # https://f-droid.org/en/docs/Installing_the_Server_and_Repo_Tools/
2078 #export USE_SDK_WRAPPER=yes
2079 #PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools
2080
2081 # didnt get drush working, if I did, this seems like the
2082 # only good thing to include for it.
2083 # Include Drush completion.
2084 # if [ -f "/home/ian/.drush/drush.complete.sh" ] ; then
2085 # source /home/ian/.drush/drush.complete.sh
2086 # fi
2087
2088
2089 # best practice
2090 unset IFS
2091
2092 # https://wiki.archlinux.org/index.php/Xinitrc#Autostart_X_at_login
2093 # i added an extra condition as gentoo xorg guide says depending on
2094 # $DISPLAY is fragile.
2095 if [[ ! $DISPLAY && $XDG_VTNR == 1 ]] && shopt -q login_shell && isarch; then
2096 exec startx
2097 fi
2098
2099
2100 # ensure no bad programs appending to this file will have an affect
2101 return 0