# Copyright 2021 Mitchell Riedstra # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. setaliases() { alias ls="ls -F"; alias lt="ls -tF"; alias ll="ls -lhF"; alias llt="ls -tlhF"; alias g="grep"; alias m="more"; alias j="jobs"; alias p="pwd"; alias c="column" alias ct="column -t" alias eg='grep -E' alias egv='grep -Ev' alias search='grep -niRIE' alias rot13="tr 'A-Za-z' 'N-ZA-Mn-za-m'" alias setxkbmap-list="man xkeyboard-config" showsshhosts() { cat ~/.ssh/config ~/.ssh/inc/* | awk '/^[hH]ost /{$1=""; print $0}' } # docker-getip $container_id alias docker-getip="docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'" alias xa='xargs -I{}' alias gdb='gdb -q' alias python='/usr/bin/env python3 -q' alias ncmpc='ncmpc -C -M' # Fun fact, Gnucash doesn't play nice when built against musl as a libc... # go figure alias gnucash_locale_fix='export LC_ALL=C; unset LANGUAGE; gnucash' pwgenForBanks() { set -x pwgen -r '[-#{};[:"'"'"'^()?><.|\/,`=]' -ncsy "$@" set +x } if [ "$(uname)" = "OpenBSD" ] ; then sockstat() { fstat | awk ' BEGIN { OFS="\t"; } { if ( NR == 1 ) { print($1, $2, $3, $5, $7, "ADDR"); } if( $0 ~ /tcp|udp/ ) { if(!($0 ~ /[<-]-[->]/)) { l = $1 "\t" $2 "\t" $3 "\t" $5 "\t" $7 "\t"; if($7 == "tcp") { services[$3] = l $9; } else if ($7 == "udp") { services[$3] = l $8; } } } } END { for(service in services) { print(services[service]); } } ' | column -t } ! [ -x "$(which seq 2>/dev/null)" ] && alias seq="echo use jot(1)" fi if [ "$(uname)" = "Linux" ] ; then # Sets capslock to be another control key, only works with PS2 keyboards alias unfuck_capslock='setkeycodes 3a 29' alias bc='bc -q' fi } setcoloraliases() { if [ "$(uname)" = "Linux" ] ; then alias ls="ls --color=auto -F"; alias lm='ls -lh --color=force | more'; elif [ "$(uname)" = "FreeBSD" ] ; then alias ls="ls -FG"; alias lm='CLICOLOR_FORCE="1" ls -l | less -r'; fi if echo "color test" | grep -q --color=auto "color test" >/dev/null 2>&1 ; then alias grep="grep --color=auto"; alias egrep='grep -E --color=auto' alias search='grep -E --color=auto -rnI'; fi #shellcheck disable=SC2139 alias diff="$(command -v diff colordiff 2>/dev/null | tail -n 1)"; alias t='tree -CdL' } setsudoaliases() { # Prefer doas if available, as it's likely to be configured by me over sudo _sudo="$(command -v doas sudo 2>/dev/null | sed 1q)" if [ -x "$_sudo" ] ; then # Package managers # Isn't it amazing how many distros you end up using? alias apt-get="$_sudo apt-get" alias apk="$_sudo apk" alias apt="$_sudo apt" alias apt-file="$_sudo apt-file" alias yum="$_sudo yum" alias dnf="$_sudo dnf" alias pacman="$_sudo pacman" alias xbps-install="$_sudo xbps-install" alias xbps-remove="$_sudo xbps-remove" alias pkg="$_sudo pkg" alias pkg_add="$_sudo pkg_add" # Linux power utilities alias tlp='$_sudo tlp' alias tlp-stat='$_sudo tlp-stat' # Filesystem utilities alias zfs="$_sudo zfs" alias zpool="$_sudo zpool" alias btrfs="$_sudo btrfs" alias mount="$_sudo mount" alias umount="$_sudo umount" fi case $_sudo in *doas*) alias sudo='doas'; ;; esac } # E.g. after `.mkshrc` is called, perhaps in `~/.mkshrc.local` # export GOPATH=$HOME/code/gopath # export GOROOT=$HOME/go/1.13.5 # set_go set_go() { export GOPATH="${GOPATH:-$HOME/go}" export PATH="$GOPATH/bin:$PATH" GOROOT="${GOROOT:-/usr/local/go}" _gobin="${GOROOT}/bin" if [ -e "$_gobin" ] && ! echo "$PATH" | grep -q "$_gobin" ; then export PATH="$_gobin:$PATH" fi } _set_editor() { export EDITOR="$1" export VISUAL="$1" alias vi="$EDITOR" alias vim="$EDITOR" alias edit="$EDITOR" alias e="$EDITOR" } set_editor() { for editor in vim vi ed ; do unalias "$editor" >/dev/null 2>&1 e="$(command -v "$editor")" if [ -n "$e" ] && [ -x "$e" ] ; then _set_editor "$e" fi break done } set_pager() { #shellcheck disable=SC2155 export PAGER="$(command -v cat more less 2>/dev/null | tail -n1)" } set_lang() { export CHARSET="$1"; export LANG="$1"; } # Usage debugstarttls $ipaddr:$port debugstarttls() { openssl s_client -starttls smtp -crlf -connect "$1" "$2" } randmacgen() { if [ "$(uname)" = "FreeBSD" ] ; then LC_COLLATE=c fi tr -c -d '0123456789abcdef' < /dev/urandom \ | head -c 12 \ | sed 's!^M$!!;s!\-!!g;s!\.!!g;s!\(..\)!\1:!g;s!:$!!' echo "" } # First argument is the interface on which to scan ipv6_local_hosts() { if [ -n "$1" ] ; then interface="$1" ping6 -c 3 "ff02::2%$interface" \ | grep 'bytes from' \ | awk '{print $4}' \ | sort \ | uniq \ | sed -e's/:$//' else echo "You need to specify an interface" fi } set_nocaps() { setxkbmap -layout "us,de" setxkbmap -option ctrl:nocaps setxkbmap -option shift:breaks_caps setxkbmap -option numpad:microsoft setxkbmap -option grp:alt_space_toggle } # Usage: dir_oct:file_oct path setperms() { _perm="$1"; shift dir_perms=$(echo "$_perm" | awk -F: '{print $1}') file_perms=$(echo "$_perm" | awk -F: '{print $2}') find "$@" -type f -print0 | xargs -0 chmod "$file_perms" find "$@" -type d -print0 | xargs -0 chmod "$dir_perms" } set_title() { printf $'\033]0;'"%s"$'\007' "$1" } set_my_title() { _load="Load Avg: $(_sys_load)" _free_mem="M Free: $(_sys_memory)" _uptime="Uptime: $(_sys_uptime)" set_title "$(id -un)[$(hostname)] -- $_load $_free_mem $_uptime" } _sys_memory() { ! [ -e "$(command -v vmstat)" ] && return if [ "$(uname)" = "Linux" ] ; then vmstat | tail -n1 | awk '{print $4/1024}' | sed -e's/\..*$//g' elif [ "$(uname)" = "FreeBSD" ] ; then vmstat | tail -n1 | awk '{print $5/1024}' | sed -e's/\..*$//g' elif [ "$(uname)" = "OpenBSD" ] ; then vmstat | sed -n '$p' | awk '{print $4}' | sed 's/M$//' fi } _sys_load() { # Works on BSD too, neat. uptime | sed -E 's/^.*load averages?: ([0-9]+\.[0-9]+).*$/\1/g' } _sys_uptime() { # Took awhile to figure out, but this works on BSD as well uptime | sed -E -e's/^.*up[ ]+//g' -e's/^([^,]*),.*/\1/g' -e's/^([^ ]+)[ ]*(.).*/\1\2/g' } timestamp() { date +%m.%d.%y_%H.%M.%S } checkSSHAgent() { ssh_agent_conf="$HOME/.ssh/agent" if [ -e "$ssh_agent_conf" ] ; then #shellcheck disable=SC1090 . "$ssh_agent_conf" fi #shellcheck disable=SC2009 if ! ps -eo pid | grep -q "$SSH_AGENT_PID" \ || ! [ -e "$ssh_agent_conf" ] \ || [ -z "$SSH_AGENT_PID" ] ; \ then ssh-agent -s | grep -v echo > "$ssh_agent_conf" #shellcheck disable=SC1090 . "$ssh_agent_conf" fi } checkSSHAgentGPG() { export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)" } passenv() { _f="$(mktemp)" pass "$@" > "$_f" #shellcheck disable=SC1090 . "$_f" rm -f "$_f" } ###################################################################### # Tmux utilities _tmux_session() { session="" window_name="" working_directory="$(pwd)" while [ $# -gt 0 ] ; do case $1 in --) shift ; break;; -s) session="$2" ; shift ; shift ;; -n) window_name="$2" ; shift ; shift ;; -w) working_directory="$2" ; shift ; shift ;; *)echo "Invalid option $1" ; return ;; esac ; done cd "$working_directory" || { echo "Cannot change to: $working_directory" ; return; } tmux new-session -s "$session" -n "$window_name" -c "$working_directory" \;\ "$@" } _tmux_dev() { session="" working_directory="$(pwd)" window_name="editor" while [ $# -gt 0 ] ; do case $1 in --) shift ; break;; -s) session="$2" ; shift ; shift ;; -n) window_name="$2" ; shift ; shift ;; -w) working_directory="$2" ; shift ; shift ;; *)echo "Invalid option $1" ; return ;; esac ; done cd "$working_directory" || { echo "Cannot change to: $working_directory" ; return; } _tmux_session -s "$session" -w "$working_directory" -n "$window_name" \ -- \ send-keys -t 0 "$EDITOR" \; send-keys -t 0 Enter \;\ new-window -n "shell" \;\ new-window -n "git" \;\ send-keys -t 0 "git status" \; send-keys -t 0 Enter \;\ "$@" } _tmux_servers_split_commands() { n=0 server_cmds="" while [ $# -gt 0 ] ; do if [ $n -eq 0 ] ; then server_cmds='send-keys "ssh \"'"$1"'\"" \; send-keys Enter \; ' else server_cmds="${server_cmds} split-window \; "'send-keys "ssh \"'"$1"'\"" \; send-keys Enter \; ' fi n="$(echo "$n+1" | bc)" shift done echo "$server_cmds" } _tmux_servers() { session="" working_directory="$HOME" servers="" layout="even-vertical" while [ $# -gt 0 ] ; do case $1 in --) shift ; break;; -s) session="$2" ; shift ; shift ;; -w) working_directory="$2" ; shift ; shift ;; -servers) servers="$2"; shift ; shift ;; -l) layout="$2"; shift ; shift ;; *)echo "Invalid option $1" ; return ;; esac ; done cd "$working_directory" || { echo "Cannot change to: $working_directory" ; return; } layout="select-layout $layout ';' set-window-option synchronize-panes on ';'" eval _tmux_session -s "\$session" -w "\$working_directory" -n "main" \ -- \ $(_tmux_servers_split_commands $servers) \ "$layout" \ "\$@" \ } gitdate() { date="" while [ $# -gt 0 ] ; do case $1 in -d) date="$2" ; shift ; shift ;; *) printf "Bad option: $1... usage:\n$0 -d \"\$date_string\"\n" ; return ;; esac ; done date="$(date --date "$date")" export GIT_AUTHOR_DATE="$date" export GIT_COMMITTER_DATE="$date" echo export GIT_AUTHOR_DATE="$date" echo export GIT_COMMITTER_DATE="$date" } gitdateUnset() { unset GIT_AUTHOR_DATE unset GIT_COMMITTER_DATE } gpgTmpDir() { set -x if echo "$GNUPGHOME" | grep -q "/dev/shm/"; then rm -rvf "$GNUPGHOME" fi #shellcheck disable=SC2155 export GNUPGHOME="$(mktemp -d /dev/shm/GPG.XXXXXX)" set +x } setcolorterminal() { case $TERM in xterm-kitty) # Prevent xterm-kitty from being turned into xterm-256color return; ;; xterm*) export TERM=xterm-256color # printf $'\033]0;'"$(hostname)"$'\007'; ;; screen*) export TERM=screen-256color # printf $'\033k'"$(whoami)"$'\033\\'; ;; esac } setlscolors() { if [ "$(uname)" = "Linux" ] ; then export LS_COLORS='di=36;40:ln=1;31;40:so=32;40:pi=33;40:ex=1;32;40:bd=34;46:cd=34;43:su=0;41:sg=0;46:tw=0;42:ow=0;43:' elif [ "$(uname)" = "FreeBSD" ] ; then export LSCOLORS='gxBxcxdxCxegedabagacad' fi } colormanpages() { export LESS_TERMCAP_mb="" export LESS_TERMCAP_md="" export LESS_TERMCAP_me="" export LESS_TERMCAP_se="" export LESS_TERMCAP_so="" export LESS_TERMCAP_ue="" export LESS_TERMCAP_us="" ## Gentoo is nuts export GROFF_NO_SGR=1 } pkg_switch_branch() { _f="/etc/pkg/FreeBSD.conf" cp $_f ${_f}.orig sed -e's/quarterly/latest/' < ${_f}.orig > ${_f} } # System setup `chroot`, useful mainly on Linux syschroot() { CHDIR=$1 PROG=$2 CUR_PS1="$PS1" PS1="(CHROOT) # " mount -t proc none "$CHDIR/proc" mount -o bind /dev "$CHDIR/dev" mount -o bind /dev/pts "$CHDIR/dev/pts" mount -o bind /sys "$CHDIR/sys" mount -o bind /run "$CHDIR/run" if [ "$PROG" = "/bin/bash" ] ; then PS1="(CHROOT) [ \u@\h \w ] # " fi chroot "$CHDIR" "$PROG" umount "$CHDIR/dev/pts" "$CHDIR/dev" "$CHDIR/sys" "$CHDIR/proc" \ "$CHDIR/run" PS1="$CUR_PS1" } pull() { _f="" _u="" while [ $# -gt 0 ] ; do case $1 in -f) _f="$2"; shift; shift ;; -u) _u="$2"; shift; shift ;; *) echo "pull usage: -f -u "; return ;; esac ; done echo "file: $_f" echo "url: $_u" if [ -z "$_f" ] || [ -z "$_u" ] ; then echo "pull usage: -f -u "; return fi if [ -x "$(command -v wget)" ] ; then wget "$_u" -O "$_f" && return fi if [ -x "$(command -v curl)" ] ; then curl "$_u" -o "$_f" && return fi if [ -x "$(command -v ftp)" ] && [ "$(uname)" = "OpenBSD" ] ; then ftp -o "$_f" "$_u" && return fi if [ -x "$(command -v fetch)" ] && [ "$(uname)" = "FreeBSD" ] ; then fetch "$_u" -o "$_f" && return fi echo "Unable to fetch $_u" >&2 } pulldotfile() { file="$1" if [ -z "$file" ] ; then echo "pulldotfile usage: " echo "Will pull from ${UPDATE_URL}/ and save to:" #shellcheck disable=SC2088 echo "~/." return fi destfile="$(basename "${file}")" pull -u "${UPDATE_URL}${file}" -f "$HOME/.${destfile}" } _make_ssh_dir_if_not_exists() { auth_keys="$HOME/.ssh/authorized_keys" if ! [ -d "$HOME/.ssh" ] ; then mkdir "$HOME/.ssh" ; fi chmod 700 "$HOME/.ssh" chmod 600 "$auth_keys" } _pullkeys() { url="$1"; shift _timestamp="$(timestamp)" _make_ssh_dir_if_not_exists auth_keys="$HOME/.ssh/authorized_keys" mv "$auth_keys" "${auth_keys}.${_timestamp}" || \ echo "Authorized Keys do not currently exist" pull -u "$url" -f "$auth_keys" || \ mv "${auth_keys}.${_timestamp}" "$auth_keys" ssh-keygen -lf "$auth_keys" || \ mv "${auth_keys}.${_timestamp}" "$auth_keys" chmod 600 "$auth_keys" } pullkeys() { file="keys/$1"; shift; url="${UPDATE_URL}${file}" _pullkeys "$url" } pullkeys_github() { _username="$1"; shift; url="https://github.com/${_username}.keys" _pullkeys "$url" } pulltermcolors() { file="$HOME/bin/terminal-colors" if ! [ -d "$HOME/bin" ] ; then mkdir "$HOME/bin" fi pull -u "${UPDATE_URL}/util/terminal-colors" -f "$file" chmod +x "$file" } updatetmuxconf() { pulldotfile "tmux/tmux.conf" pulldotfile "tmux/tmux_helper.sh" if ! [ -e "$HOME/.tmux.conf.local" ] && [ "$(id -u)" -eq 0 ] ; then # If I ever change the color from green this will have to be updated I guess grep 'green' "$HOME/.tmux.conf" | sed -e's/green/red/g' > "$HOME/.tmux.conf.local" elif ! [ -e "$HOME/.tmux.conf.local" ] ; then touch "$HOME/.tmux.conf.local" fi } updategitconf() { file="gitconfig/$1" pull -u "${UPDATE_URL}${file}" -f "$HOME/.gitconfig" } updateshell() { pulldotfile "kshrc" #shellcheck disable=SC1090 . "$HOME/.kshrc" } updatevimrc() { OLDWD="$(pwd)" #shellcheck disable=SC2164 cd "$HOME" git clone --recurse-submodules "$VIM_GIT_URL" .vim exit="$?" cd "$HOME/.vim" || { echo "Cannot cd to .vim dir" ; return; } if [ "$exit" -gt 0 ] ; then git pull origin master git submodule update fi ./link-vimrc.sh #shellcheck disable=SC2164 cd "$OLDWD" } updatevimrc_basic() { pull -u "$VIM_BASIC_URL" -f ~/.vimrc } SHELL_CONFIG=".kshrc" COLOR=0 case "$TERM" in xterm*) COLOR=1;; *256color) COLOR=1;; esac if ! echo "$PATH" | grep -q "$HOME/bin" ; then export PATH="$HOME/bin:$PATH" fi UPDATE_URL="https://git.riedstra.dev/mitch/dotfiles/plain/" VIM_GIT_URL="https://git.riedstra.dev/mitch/vim-cfg" VIM_BASIC_URL="https://git.riedstra.dev/mitch/dotfiles/plain/vimrc" PRELOAD="$HOME/${SHELL_CONFIG}.pre" LOCAL="$HOME/${SHELL_CONFIG}.local" # Don't put any variables below this, as they can't be overridden before the # functions if you do that # Load pre config [ -r "$PRELOAD" ] && . "$PRELOAD" set_pager # note that the use of set_editor and _set_editor on oksh may # change the input mode. ( set -o emacs ) after to go back set_editor # Also, opinionated, hope you like vim/vi # set_go export PASSWORD_STORE_ENABLE_EXTENSIONS=true setaliases setsudoaliases # checkSSHAgent # Support various different shells if [ -n "$KSH_VERSION" ] ; then export HISTFILE="$HOME/.ksh_history" export HISTSIZE=10000 set -o emacs bind ^L=clear-screen #shellcheck disable=SC2155 # if you want PWD # export PS1='\u@\h \$PWD \$ ' export PS1='\u@\h\$ ' if [ $(id -u) -eq 0 ] ; then export PS1='\h\$ ' fi elif [ "$SHELL" = "/bin/sh" ] && [ "$(uname)" = "FreeBSD" ] ; then set -o emacs #shellcheck disable=SC2155 export PS1="$(whoami)"'@\h:\w \$ ' elif [ -n "$BASH" ] ; then HISTFILE="$HOME/.bash_history" HISTSIZE=10000 HISTFILESIZE=10000 shopt -s histappend export PROMPT_COMMAND="history -a; history -c; history -r" # if you want PWD # export PS1='\u@\h \$PWD \$ ' export PS1='\u@\h\$ ' if [ $(id -u) -eq 0 ] ; then export PS1='\h\$ ' fi fi if [ $COLOR -eq 1 ] ; then colormanpages setcolorterminal setcoloraliases setlscolors fi # Include local configuration options [ -r "$LOCAL" ] && . "$LOCAL"