-}
-
-
-lcn() { locate -i "*$**"; }
-
-lld() { ll -d "$@"; }
-
-low() { # make filenames all lowercase
- local x y
- for x in "$@"; do
- y=$(tr "[A-Z]" "[a-z]" <<<"$x")
- [[ $y != $x ]] && mv "$x" "$y"
- done
-}
-
-
-
-
-lower() { # make first letter of filenames lowercase.
- local x
- for x in "$@"; do
- if [[ ${x::1} == [A-Z] ]]; then
- y=$(tr "[A-Z]" "[a-z]" <<<"${x::1}")"${x:1}"
- safe_rename "$x" "$y"
- fi
- done
-}
-
-
-k() { # history search
- grep -P --binary-files=text "$@" ${HISTFILE:-~/.bash_history} | tail -n 40;
-}
-
-
-make-targets() {
- # show make targets, via http://stackoverflow.com/questions/3063507/list-goals-targets-in-gnu-make
- make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'
-}
-
-
-mkc() {
- mkdir "$1"
- c "$1"
-}
-
-mkdir() { command mkdir -p "$@"; }
-
-pithos() {
- cd /
- export PYTHONPATH=/a/opt/Pithosfly
- python3 -m pithos&r
-}
-
-pakaraoke() {
- # from http://askubuntu.com/questions/456021/remove-vocals-from-mp3-and-get-only-instrumentals
- pactl load-module module-ladspa-sink sink_name=Karaoke master=alsa_output.usb-Audioengine_Audioengine_D1-00.analog-stereo plugin=karaoke_1409 label=karaoke control=-30
-}
-
-
-pfind() { #find *$1* in $PATH
- [[ $# != 1 ]] && { echo requires 1 argument; return 1; }
- local pathArray
- IFS=: pathArray=($PATH); unset IFS
- find "${pathArray[@]}" -iname "*$1*"
-}
-
-pick-trash() {
- # trash-restore lists everything that has been trashed at or below CWD
- # This picks out files just in CWD, not subdirectories,
- # which also match grep $1, usually use $1 for a time string
- # which you get from running restore-trash once first
- local name x ask
- local nth=1
- # last condition is to not ask again for ones we skipped
- while name="$( echo | restore-trash | gr "$PWD/[^/]\+$" | gr "$1" )" \
- && [[ $name ]] && (( $(wc -l <<<"$name") >= nth )); do
- name="$(echo "$name" | head -n $nth | tail -n 1 )"
- read -p "$name [Y/n] " ask
- if [[ ! $ask || $ask == [Yy] ]]; then
- x=$( echo "$name" | gr -o "^\s*[0-9]*" )
- echo $x | restore-trash > /dev/null
- elif [[ $ask == [Nn] ]]; then
- nth=$((nth+1))
- else
- return
- fi
- done
-}
-
-postconfin() {
- local MAPFILE
- mapfile -t
- local s
- [[ $EUID == 0 ]] || s=s
- $s postconf -ev "${MAPFILE[@]}"
-}
-
-pub() {
- rld /a/h/_site/ li:/var/www/iankelling.org/html
-}
-
-pubip() { curl -4s https://icanhazip.com; }
-whatismyip() { pubip; }
-
-
-pwgen() {
- # -m = min length
- # -x = max length
- # -t = print pronunciation
- apg -m 12 -x 16 -t
-}
-
-
-q() { # start / launch a program in the backround and redir output to null
- "$@" &> /dev/null &
-}
-
-r() {
- exit "$@" 2>/dev/null
-}
-
-rbpipe() { rbt post -o --diff-filename=- "$@"; }
-rbp() { rbt post -o "$@"; }
-
-rl() {
- # rsync, root is required to keep permissions right.
- # rsync --archive --human-readable --verbose --itemize-changes --checksum \(-ahvic\) \
- # --no-times --delete
- # basically, make an exact copy, use checksums instead of file times to be more accurate
- rsync -ahvic --delete "$@"
-}
-rld() {
- # like rlu, but don't delete files on the target end which
- # do not exist on the original end.
- rsync -ahvic "$@"
-}
-complete -F _rsync -o nospace rld rl rlt
-
-rlt() {
- # rl without preserving modification time.
- rsync -ahvic --delete --no-t "$@"
-}
-
-rlu() { # [OPTS] HOST PATH
- # eg rlu -opts frodo /testpath
- # useful for selectively sending dirs which have been synced with unison,
- # where the path is the same on both hosts.
- opts=("${@:1:$#-2}") # 1 to last -2
- path="${@:$#}" # last
- host="${@:$#-1:1}" # last -1
- if [[ $path == .* ]]; then echo error: need absolut path; return 1; fi
- # rync here uses checksum instead of time so we don't mess with
- # unison relying on time as much. g is for group, same reason
- # to keep up with unison.
- s rsync -rlpchviog --relative "${opts[@]}" "$path" "root@$host:/";
-}
-
-
-rspicy() { # usage: HOST DOMAIN
- # connect to spice vm remote host. use vspicy for local host
- local port=$(ssh $1<<EOF
-sudo virsh dumpxml $2|grep "<graphics.*type='spice'" | \
- sed -rn "s/.*port='([0-9]+).*/\1/p"
-EOF
- )
- if [[ $port ]]; then
- spicy -h $1 -p $port
- else
- echo "error: no port found. check that the domain is running."
- fi
-}
-
-s() {
- # background
- # I use a function because otherwise we can't use in a script,
- # can't assign to variable.
- #
- # note: gksudo is recommended for X apps because it does not set the
- # home directory to the same, and thus apps writing to ~ fuck things up
- # with root owned files.
- #
- if [[ $EUID != 0 || $1 == -* ]]; then
- SUDOD="$PWD" sudo -i "$@"
- else
- "$@"
- fi
-}
-
-safe_rename() {
- if [[ $# != 2 ]]; then
- echo safe_rename error: $# args, need 2 >2
- return 1
- elif [[ $1 != $2 ]]; then
- if [[ -e $2 ]]; then
- echo Cannot rename "$1" to "$2" as it already exists.
- else
- mv "$1" "$2"
- fi
- fi
-}
-
-
-sb() { # sudo bash -c
- # use sb instead of s is for sudo redirections,
- # eg. sb 'echo "ok fine" > /etc/file'
- local SUDOD="$PWD"
- sudo -i bash -c "$@"
-}
-complete -F _root_command s sb
-
-scssl() {
- # s gem install scss-lint
- pushd /a/opt/thoughtbot-guides
- git pull --stat
- popd
- scss-lint -c /a/opt/thoughtbot-guides/style/sass/.scss-lint.yml "$@"
-}
-
-ser() {
- local s; [[ $EUID != 0 ]] && s=sudo
- if type -p systemctl &>/dev/null; then
- $s systemctl $1 $2
- else
- $s service $2 $1
- fi
-}
-
-sgo() { # service go
- service=$1
- ser restart $service
- if type -p systemctl &>/dev/null; then
- ser enable $service
- fi
-}
-
-
-shellck() {
- # 2086 = unquoted $var
- # 2046 = unquoted $(cmd)
- # i had -x as an arg, but debian testing(stretch) doesn't support it
- shellcheck -e 2086,2046,2068,2006,2119 "$@"
-}
-
-
-slog() {
- # log with script. timing is $1.t and script is $1.s
- # -l to save to ~/typescripts/
- # -t to add a timestamp to the filenames
- local logdir do_stamp arg_base
- (( $# >= 1 )) || { echo "arguments wrong"; return 1; }
- logdir="/a/dt/"
- do_stamp=false
- while getopts "lt" option
- do
- case $option in
- l ) arg_base=$logdir ;;
- t ) do_stamp=true ;;
- esac
- done
- shift $(($OPTIND - 1))
- arg_base+=$1
- [[ -e $logdir ]] || mkdir -p $logdir
- $do_stamp && arg_base+=$(date +%F.%T%z)
- script -t $arg_base.s 2> $arg_base.t
-}
-splay() { # script replay
- #logRoot="$HOME/typescripts/"
- #scriptreplay "$logRoot$1.t" "$logRoot$1.s"
- scriptreplay "$1.t" "$1.s"
-}
-
-sr() {
- # sudo redo. be aware, this command may not work right on strange distros or earlier software
- if [[ $# == 0 ]]; then
- sudo -E bash -c -l "$(history -p '!!')"
- else
- echo this command redos last history item. no argument is accepted
- fi
-}
-
-srm () {
- # with -ll, less secure but faster.
- command srm -ll "$@"
-}
-
-srun() {
- scp $2 $1:/tmp
- ssh $1 /tmp/${2##*/} "${@:2}"
-}
-
-swap() {
- local tmp
- tmp=$(mktemp)
- mv $1 $tmp
- mv $2 $1
- mv $tmp $2
-}
-
-t() {
- local x
- local -a args
- if type -t trash-put >/dev/null; then
- # skip args that don't exist, or else trash-put will have an error
- for x in "$@"; do
- if [[ -e $x || -L $x ]]; then
- args+=("$x")
- fi
- done
- [[ ! ${args[@]} ]] || trash-put "${args[@]}"
- else
- rm -rf "$@"
- fi
-}
-
-
-tclock() {
- clear
- date +%l:%_M
- len=60
- # this goes to full width
- #len=${1:-$((COLUMNS -7))}
- x=1
- while true; do
- if (( x == len )); then
- end=true
- d="$(date +%l:%_M) "
- else
- end=false
- d=$(date +%l:%M:%_S)
- fi
- echo -en "\r"
- echo -n "$d"
- for ((i=0; i<x; i++)); do
- if (( i % 6 )); then
- echo -n _
- else
- echo -n .
- fi
- done
- if $end; then
- echo
- x=1
- else
- x=$((x+1))
- fi
- sleep 5
- done
-}
-
-
-te() {
- # test existence / exists
- local ret=0
- for x in "$@"; do
- [[ -e "$x" || -L "$x" ]] || ret=1
- done
- return $ret
-}
-
-testmail() {
- declare -gi _seq; _seq+=1
- echo "test body" | m mail -s "test mail from $HOSTNAME, $_seq" "${1:-root@localhost}"
-}
-
-tm() {
- # timer in minutes
- (sleep $(calc "$@ * 60") && mpv --volume 50 /a/bin/data/alarm.mp3 --loop=no) > /dev/null 2>&1 &
-}
-
-ts() { # start editing a new file
- [[ $# != 1 ]] && echo "I need a filename." && return 1
- local quiet
- if [[ $- != *i* ]]; then
- quiet=true
- fi
- if [[ $1 == *.c ]]; then
- e '#include <stdio.h>' >"$1"
- e '#include <stdlib.h>' >>"$1"
- e 'int main(int argc, char * argv[]) {' >>"$1"
- e ' printf( "hello world\n");' >>"$1"
- e ' return 0;' >>"$1"
- e '}' >>"$1"
- e "${1%.c}: $1" > Makefile
- e " g++ -ggdb -std=gnu99 -o ${1%.c} $<" >> Makefile
- e "#!/bin/bash" >run.sh
- e "./${1%.c}" >>run.sh
- chmod +x run.sh
- elif [[ $1 == *.java ]]; then
- e "public class ${1%.*} {" >"$1"
- e ' public static void main(String[] args) {' >>"$1"
- e ' System.out.println("Hello, world!");' >>"$1"
- e ' }' >>"$1"
- e '}' >>"$1"
- else
- echo "#!/bin/bash" > "$1"
- chmod +x "$1"
- fi
- [[ $quiet ]] || g "$1"
-}
-
-
-tu() {
- local s;
- local dir="$(dirname "$1")"
- if [[ -e $1 && ! -w $1 || ! -w $(dirname "$1") ]]; then
- s=s;
- fi
- $s teeu "$@"
-}
-
-tx() { # toggle set -x, and the prompt so it doesn't spam
- if [[ $- == *x* ]]; then
- set +x
- PROMPT_COMMAND=prompt_command
- else
- unset PROMPT_COMMAND
- PS1="\w \$ "
- set -x
- fi
-}
-
-psvpn() {
- # show all processes in the vpn network namespace.
- # blank entries appear to be subprocesses/threads of transmission daemon
- ps -w | head -n 1
- s find -L /proc/[1-9]*/task/*/ns/net -samefile /run/netns/vpn | cut -d/ -f5 | \
- while read l; do
- x=$(ps -w --no-headers -p $l);
- if [[ $x ]]; then echo "$x"; else echo $l; fi;
- done
-}
-
-m() { printf "%s\n" "$*"; "$@"; }
-
-vpnbash() {
- m s nsenter -t $(pgrep openvpn) -n -m bash
-}
-
-netnsvpn() {
- # todo, make a function to kill all processes in the network namespace.
-
- # manually run vpn so it stays within a network namespace,
- # until I get it all wired up with systemd.
- if ! s ip netns list | awk '{print $1}' | grep -Fx vpn &>/dev/null; then
- newns vpn start || return 1
- fi
-
- s iptables-restore <<'EOF'
-# some traffic leaked, so I recreated the rules here being
-# a little more specific. We could also do the reverse rules
-# for input, but meh.
-# todo: try out rules for process owner. reject all
-# packes by transmission-daemon, which are not from brvpn
-*filter
-:INPUT ACCEPT
-:FORWARD ACCEPT
-:OUTPUT ACCEPT
-# -i = interface
-# -d = destination
-# -p = protocol
-# -m = (match, aka extended match module), enabling the next rule
--A FORWARD -i brvpn -d 192.168.1.1 -p udp -m udp --dport 53 -j ACCEPT
--A FORWARD -i brvpn -d 192.168.1.1 -p tcp -m tcp --dport 53 -j ACCEPT
--A FORWARD -i brvpn -d 192.168.1.0/24 -p tcp -m tcp --dport 9091 -j ACCEPT
--A FORWARD -i brvpn -p udp -m udp --dport 1194:1195 -j ACCEPT
--A FORWARD -i brvpn -j REJECT
-# prevent transmission daemon from doing anything outside it's
-# network namespace.
--A OUTPUT -m owner --uid-owner debian-transmission -j REJECT
-COMMIT
-EOF
- local pid
- pid=$(< /run/openvpn/client.pid)
- local vpn_on=false
- if [[ $pid ]]; then
- if [[ -e /proc/$pid ]]; then
- vpn_on=true
- else
- vpn_on=false
- s rm -f /run/openvpn/client.pid
- fi
- fi
- # for testing of disabled firewall rules, run this:
- #s ip netns exec vpn iptables -P OUTPUT ACCEPT
- s ip netns exec vpn iptables-restore <<'EOF'
-# format from iptables-save. [0:0] are comments of packet-count/byte-count
-# which I removed
-*filter
-:INPUT DROP
-:FORWARD ACCEPT
-:OUTPUT DROP
-# from ip route, we can deduce that traffic goes to the
-# local 10.8.0.x tun0, then to the normal interface.
-# For the normal interface, we allow only some ports:
-# dns, vpn, transmission-remote.
-# dns is only used to resolve the vpn server ip on initial
-# connection.
-# rules are mirror on input and output, just for extra safety,
-# although just having output should do fine.
-
-# We could also firewall from outside the nat, for example like this,
-# but I'm thinking this is simpler.
-#-A FORWARD -i brvpn -p udp -m udp --dport 1194:1195 -j ACCEPT
-#-A FORWARD -i brvpn -j REJECT
-
-# help prevent dns leaks, openvpn runs as root
--A OUTPUT -p udp -m udp --dport 53 -m owner --uid-owner root -j ACCEPT
--A INPUT -p udp -m udp --dport 53 -m owner --uid-owner root -j ACCEPT
-
--A OUTPUT -p tcp -m tcp --dport 53 -m owner --uid-owner root -j ACCEPT
--A INPUT -p tcp -m tcp --dport 53 -m owner --uid-owner root -j ACCEPT
-
--A OUTPUT -p tcp -m tcp --sport 9091 -j ACCEPT
--A INPUT -p tcp -m tcp --dport 9091 -j ACCEPT
-
-# 1195 is used for the secondary vpn server
--A OUTPUT -p udp -m udp --dport 1194:1195 -j ACCEPT
--A INPUT -p udp -m udp --dport 1194:1195 -j ACCEPT
-
--A OUTPUT -o tun0 -j ACCEPT
--A INPUT -i tun0 -j ACCEPT
-COMMIT
-EOF
- $vpn_on || s ip netns exec vpn /usr/sbin/openvpn --daemon ovpn --status /run/openvpn/%i.status 10 --cd /etc/openvpn --config /etc/openvpn/client.conf --writepid /run/openvpn/client.pid
-}
-
-
-
-vc() {
- [[ $1 ]] || { e "$0: error, expected cmd to run"; return 1; }
- gksudo -- ip netns exec vpn gksudo -u ${SUDO_USER:-$USER} "$@"
-}
-
-transmission-stop() {
- local pid=$(cat /var/lib/transmission-daemon/transmission-daemon.pid)
- if [[ $pid ]]; then
- sudo kill $pid
- else
- psg transmission-daemon
- fi
-}
-
-
-trg() { transmission-remote-gtk&r; }
-
-# transmission() {
-# local pid=$(cat /var/lib/transmission-daemon/transmission-daemon.pid)
-# if [[ $pid && -e /proc/$pid ]]; then
-# echo "noop. already running."
-# return
-# fi
-
-# local NAME=transmission-daemon
-# local DAEMON=/usr/bin/$NAME
-# local duser=debian-transmission
-
-# [ -e /etc/default/$NAME ] && . /etc/default/$NAME
-# s ip netns exec vpn sudo -u $duser ionice -c 3 nice -n 19 $DAEMON $OPTIONS
-# }
-
-virshrm() {
- for x in "$@"; do virsh destroy "$x"; virsh undefine "$x"; done
-}
-
-vm-set-listen(){
- local t=$(mktemp)
- local vm=$1
- local ip=$2
- s virsh dumpxml $vm | sed -r "s/(<listen.*address=')([^']+)/\1$ip/" | \
- sed -r "s/listen='[^']+/listen='$ip/"> $t
- s virsh undefine $vm
- s virsh define $t
-}
-
-
-vmshare() {
- vm-set-listen $1 0.0.0.0
-}
-
-
-vmunshare() {
- vm-set-listen $1 127.0.0.1
-}
-
-vpn() {
- s systemctl start openvpn@client&
- journalctl --unit=openvpn@client -f -n0
-}
-
-
-vpnoff() {
- s systemctl stop openvpn@client
-}
-
-
-vrm() {
- virsh destroy $1
- virsh undefine $1
-}
-
-
-
-vspicy() { # usage: VIRSH_DOMAIN
- # connect to vms made with virt-install
- spicy -p $(sudo virsh dumpxml "$1"|grep "<graphics.*type='spice'"|\
- sed -r "s/.*port='([0-9]+).*/\1/")
-}
-
-
-whatismyip() { curl ipecho.net/plain ; echo; }
-
-
-#############################
-######### misc stuff ########
-#############################
-
-if [[ $- == *i* ]]; then
- # commands to run when bash exits normally
- trap "hl" EXIT
-fi
-
-
-# temporary variables to test colorization
-# some copied from gentoo /etc/bash/bashrc,
-use_color=false
-# dircolors --print-database uses its own built-in database
-# instead of using /etc/DIR_COLORS. Try to use the external file
-# first to take advantage of user additions.
-safe_term=${TERM//[^[:alnum:]]/?} # sanitize TERM
-match_lhs=""
-[[ -f ~/.dir_colors ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
-[[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
-[[ -z ${match_lhs} ]] \
- && type -P dircolors >/dev/null \
- && match_lhs=$(dircolors --print-database)
-# test if our $TERM is in the TERM values in dircolor
-[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true
-
-
-if ${use_color} && [[ $- == *i* ]]; then
-
- if [[ $XTERM_VERSION == Cygwin* ]]; then
- get_term_color() {
- for x in "$@"; do
- case $x in
- underl) echo -n $'\E[4m' ;;
- bold) echo -n $'\E[1m' ;;
- red) echo -n $'\E[31m' ;;
- green) echo -n $'\E[32m' ;;
- blue) echo -n $'\E[34m' ;;
- cyan) echo -n $'\E[36m' ;;
- yellow) echo -n $'\E[33m' ;;
- purple) echo -n $'\E[35m' ;;
- nocolor) echo -n $'\E(B\E[m' ;;
- esac
- done
- }
-
- else
- get_term_color() {
- for x in "$@"; do
- case $x in
- underl) echo -n $(tput smul) ;;
- bold) echo -n $(tput bold) ;;
- red) echo -n $(tput setaf 1) ;;
- green) echo -n $(tput setaf 2) ;;
- blue) echo -n $(tput setaf 4) ;;
- cyan) echo -n $(tput setaf 6) ;;
- yellow) echo -n $(tput setaf 3) ;;
- purple) echo -n $(tput setaf 5) ;;
- nocolor) echo -n $(tput sgr0) ;; # no font attributes
- esac
- done
- }