Advertisement
devinteske

My .bash_profile

May 29th, 2018 (edited)
4,299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 80.84 KB | None | 0 0
  1. # -*- tab-width:  4 -*- ;; Emacs
  2. # vi: set tabstop=8     :: Vi/ViM
  3. #
  4. # .bash_profile
  5. #   Author:      Devin Teske <dteske@freebsd.org>
  6. #   Last Change: 2021 Mar 16
  7. #
  8. ############################################################ GLOBALS
  9.  
  10. #
  11. # Global exit status variables
  12. #
  13. export SUCCESS=0
  14. export FAILURE=1
  15.  
  16. #
  17. # Are we running interactively?
  18. #
  19. interactive=
  20. case "$-" in
  21. *i*) interactive=1
  22. esac
  23.  
  24. #
  25. # Is filename globbing enabled?
  26. #
  27. if [ "$ZSH_NAME" ]; then
  28.     glob=
  29.     setopt shwordsplit
  30. else
  31.     glob=1
  32.     case "$SHELLOPTS" in noglob|*:noglob:*|*:noglob) glob= ;; esac
  33. fi
  34.  
  35. #
  36. # OS Specifics
  37. # NB: Requires uname(1) -- from base system
  38. #
  39. : ${UNAME_s:=$(uname -s)}
  40. : ${UNAME_r:=$(uname -r)}
  41. : ${UNAME_p:=$(uname -p)}
  42. : ${MESSAGES:=/var/log/messages}
  43. case "$UNAME_s" in
  44. Linux) Linux=$( lsb_release -si 2> /dev/null ) ;;
  45. esac
  46.  
  47. #
  48. # Fix lolcat to work properly in local XTerm
  49. #
  50. [ "$TERM" != "${TERM#xterm}" -a ! "$SSH_CLIENT" ] && stty tab0
  51.  
  52. #
  53. # bash(1) builtin's we should pass to $LOLCAT [lolcat]
  54. #
  55. LOL_BUILTINS='cd dirs echo help popd printf pushd pwd shopt times type'
  56. _LOL_BUILTINS=
  57. [ "$glob" ] && set -f
  58. for _prog in $LOL_BUILTINS; do
  59.     _LOL_BUILTINS="$_LOL_BUILTINS|$_prog"
  60. done
  61. unset _prog
  62. _LOL_BUILTINS="${_LOL_BUILTINS#|}"
  63. [ "$glob" ] && set +f
  64.  
  65. #
  66. # External programs we should NOT pass to $LOLCAT [lolcat]
  67. #
  68. NOLOL_PROGS='
  69.     adduser arc
  70.     *bash bashbug bc bitchx bsdconfig bsdinstall
  71.     condy cscope csh cvsbug
  72.     dd dialog dpv
  73.     edit edquota ee emacs* env etcupdate ex
  74.     freebsd-update fsdb *ftp fvwm-bug
  75.     *gdb*
  76.     *hx
  77.     iftop irssi
  78.     *key *keys
  79.     lldb *login lolcat ls
  80.     Mail mail* *man* mping
  81.     nano ngctl nvi
  82.     perlbug perlthanks pico pppctl
  83.     rcp *run
  84.     sade *scp screen sh shgid sr srvi *ssh* su sudo* sysinstall systat
  85.     talk tcsh *telnet tmux tzsetup
  86.     vi *view vigr *vim* vipw visudo
  87.     watch
  88.     zsh
  89. ' # NOLOL_PROGS
  90. _NOLOL_PROGS=
  91. [ "$glob" ] && set -f
  92. for _prog in $NOLOL_PROGS; do
  93.     _NOLOL_PROGS="$_NOLOL_PROGS|$_prog"
  94. done
  95. unset _prog
  96. _NOLOL_PROGS="${_NOLOL_PROGS#|}"
  97. [ "$glob" ] && set +f
  98.  
  99. #
  100. # Commands we should pass to $LOLCAT [lolcat]
  101. #
  102. LOL_CMDS='
  103.     # One case pattern per-line; no inline comments
  104.     # NB: Whitespace needs to be escaped or quoted
  105.     # NB: Patterns implicitly allow trailing args
  106.  
  107.     # FreeBSD commands
  108.     "wpa_cli [a-z]*"
  109.  
  110.     # FreeBSD pkg(8) commands
  111.     "pkg annotate -y"
  112.     "pkg annotate "*" -y"
  113.     "pkg annotate --yes"
  114.     "pkg annotate "*" --yes"
  115.     "pkg autoremove -y"
  116.     "pkg autoremove "*" -y"
  117.     "pkg autoremove --yes"
  118.     "pkg autoremove "*" --yes"
  119.     "pkg check -y"
  120.     "pkg check "*" -y"
  121.     "pkg check --yes"
  122.     "pkg check "*" --yes"
  123.     "pkg clean -y"
  124.     "pkg clean "*" -y"
  125.     "pkg clean --yes"
  126.     "pkg clean "*" --yes"
  127.     "pkg delete -y"
  128.     "pkg delete "*" -y"
  129.     "pkg delete --yes"
  130.     "pkg delete "*" --yes"
  131.     "pkg fetch -y"
  132.     "pkg fetch "*" -y"
  133.     "pkg fetch --yes"
  134.     "pkg fetch "*" --yes"
  135.     "pkg install -y"
  136.     "pkg install "*" -y"
  137.     "pkg install --yes"
  138.     "pkg install "*" --yes"
  139.     "pkg lock -y"
  140.     "pkg lock "*" -y"
  141.     "pkg lock --yes"
  142.     "pkg lock "*" --yes"
  143.     "pkg remove -y"
  144.     "pkg remove "*" -y"
  145.     "pkg remove --yes"
  146.     "pkg remove "*" --yes"
  147.     "pkg unlock -y"
  148.     "pkg unlock "*" -y"
  149.     "pkg unlock --yes"
  150.     "pkg unlock "*" --yes"
  151.     "pkg upgrade -y"
  152.     "pkg upgrade "*" -y"
  153.     "pkg upgrade --yes"
  154.     "pkg upgrade "*" --yes"
  155.  
  156.     # VCS commands
  157.     "cvs ci -m"
  158.     "cvs ci "*" -m"
  159.     "cvs commit -m"
  160.     "cvs commit "*" -m"
  161.     "git commit -m"
  162.     "git commit "*" -m"
  163.     "git commit --message"
  164.     "git commit "*" --message"
  165.     "git commit --no-edit"
  166.     "git commit "*" --no-edit"
  167.     "git revert --no-edit"
  168.     "git revert "*" --no-edit"
  169.     "p4 branch -"[dio]
  170.     "p4 branch "*" -"[dio]
  171.     "p4 change -"[dio]
  172.     "p4 change "*" -"[dio]
  173.     "p4 changelist -"[dio]
  174.     "p4 changelist "*" -"[dio]
  175.     "p4 client -"[dio]
  176.     "p4 client "*" -"[dio]
  177.     "p4 depot -"[dio]
  178.     "p4 depot "*" -"[dio]
  179.     "p4 job -"[dio]
  180.     "p4 job "*" -"[dio]
  181.     "p4 label -"[dio]
  182.     "p4 label "*" -"[dio]
  183.     "p4 protect -"[io]
  184.     "p4 protect "*" -"[io]
  185.     "p4 resolve -a"[mty]
  186.     "p4 resolve "*" -a"[mty]
  187.     "p4 stream -"[dio]
  188.     "p4 stream "*" -"[dio]
  189.     "p4 submit -"[di]
  190.     "p4 submit "*" -"[di]
  191.     "p4 user -"[dio]
  192.     "p4 user "*" -"[dio]
  193.     "p4 workspace -"[dio]
  194.     "p4 workspace "*" -"[dio]
  195.     "svn ci -m"
  196.     "svn ci "*" -m"
  197.     "svn ci --message"
  198.     "svn ci "*" --message"
  199.     "svn ci --non-interactive"
  200.     "svn ci "*" --non-interactive"
  201.     "svn commit -m"
  202.     "svn commit "*" -m"
  203.     "svn commit --message"
  204.     "svn commit "*" --message"
  205.     "svn commit --non-interactive"
  206.     "svn ci "*" --non-interactive"
  207.     "svnlite ci -m"
  208.     "svnlite ci "*" -m"
  209.     "svnlite ci --message"
  210.     "svnlite ci "*" --message"
  211.     "svnlite ci --non-interactive"
  212.     "svnlite ci "*" --non-interactive"
  213.     "svnlite commit -m"
  214.     "svnlite commit "*" -m"
  215.     "svnlite commit --message"
  216.     "svnlite commit "*" --message"
  217.     "svnlite commit --non-interactive"
  218.     "svnlite ci "*" --non-interactive"
  219.  
  220. ' # LOL_CMDS
  221. _LOL_CMDS=$( echo "$LOL_CMDS" |
  222.     while read -r _cmd; do
  223.         [ "${_cmd:-x}" = "${_cmd#\#}" ] || continue
  224.         echo -n "|$_cmd|$_cmd\[\$IFS]*"
  225.     done
  226. )
  227. _LOL_CMDS="${_LOL_CMDS#|}"
  228.  
  229. #
  230. # Commands we should NOT pass to $LOLCAT [lolcat]
  231. #
  232. NOLOL_CMDS='
  233.     # One case pattern per-line; no inline comments
  234.     # NB: Whitespace needs to be escaped or quoted
  235.     # NB: Patterns implicitly allow trailing args
  236.  
  237.     # Commands containing pipe
  238.     *"|"*
  239.  
  240.     # General commands that launch $EDITOR or behave interactively
  241.     "crontab -e"
  242.     "crontab "*" -e"
  243.     "sdiff -o"
  244.     "sdiff "*" -o"
  245.  
  246.     # FreeBSD specific commands that launch $EDITOR or behave interactively
  247.     "bsdlabel -e"
  248.     "camcontrol modepage "*" -e"
  249.     "disklabel -e"
  250.     "gbde init "*" -i"
  251.     "gvinum create"
  252.     "make config"
  253.     "make import"
  254.     "wpa_cli"
  255.  
  256.     # FreeBSD pkg(8) commands that either prompt or show progress
  257.     "pkg annotate"
  258.     "pkg autoremove"
  259.     "pkg check"
  260.     "pkg clean"
  261.     "pkg delete"
  262.     "pkg fetch"
  263.     "pkg install"
  264.     "pkg lock"
  265.     "pkg remove"
  266.     "pkg shell"
  267.     "pkg unlock"
  268.     "pkg upgrade"
  269.  
  270.     # VCS commands that launch $EDITOR or behave interactively
  271.     "cvs ci"
  272.     "cvs commit"
  273.     "git commit"
  274.     "git help"
  275.     "git rebase -i"
  276.     "git rebase "*" -i"
  277.     "git rebase --interactive"
  278.     "git rebase "*" --interactive"
  279.     "git revert"
  280.     "p4 attribute -i"
  281.     "p4 attribute "*" -i"
  282.     "p4 branch"
  283.     "p4 change"
  284.     "p4 changelist"
  285.     "p4 client"
  286.     "p4 depot"
  287.     "p4 job"
  288.     "p4 label"
  289.     "p4 login"
  290.     "p4 passwd"
  291.     "p4 protect"
  292.     "p4 resolve"
  293.     "p4 stream"
  294.     "p4 submit"
  295.     "p4 user"
  296.     "p4 workspace"
  297.     "svn ci"
  298.     "svn commit"
  299.     "svnlite ci"
  300.     "svnlite commit"
  301.  
  302.     # Other commands that behave interactively
  303.     "make chroot_shell"
  304.     "make "*" chroot_shell"
  305.     "make distclean"
  306.     "make "*" distclean"
  307.     "make remove_chroot"
  308.     "make "*" remove_chroot"
  309.  
  310. ' # NOLOL_CMDS
  311. _NOLOL_CMDS=$( echo "$NOLOL_CMDS" |
  312.     while read -r _cmd; do
  313.         [ "${_cmd:-x}" = "${_cmd#\#}" ] || continue
  314.         echo -n "|$_cmd|$_cmd\[\$IFS]*"
  315.     done
  316. )
  317. _NOLOL_CMDS="${_NOLOL_CMDS#|}"
  318.  
  319. #
  320. # Where are apache's log files?
  321. #
  322. case "$UNAME_s" in
  323. FreeBSD)
  324.     case "$UNAME_r" in
  325.     4.8-*)
  326.         : ${APACHE_ERROR_LOG:=/usr/local/www/logs/error_log}
  327.         : ${APACHE_ACCESS_LOG:=/usr/local/www/logs/access_log}
  328.         : ${APACHE_ERROR_LOG_SA:=$APACHE_ERROR_LOG}
  329.         : ${APACHE_ACCESS_LOG_SA:=$APACHE_ACCESS_LOG}
  330.         : ${APACHE_SSL_ERROR_LOG:=/usr/local/www/logs/ssl_error_log}
  331.         : ${APACHE_SSL_ACCESS_LOG:=/usr/local/www/logs/ssl_access_log}
  332.         ;;
  333.     8.3-*)
  334.         : ${APACHE_ERROR_LOG:=/var/log/httpd-error.log}
  335.         : ${APACHE_ACCESS_LOG:=/var/log/httpd-access.log}
  336.         : ${APACHE_ERROR_LOG_SA:=$APACHE_ERROR_LOG}
  337.         : ${APACHE_ACCESS_LOG_SA:=$APACHE_ACCESS_LOG}
  338.         : ${APACHE_SSL_ERROR_LOG:=/var/log/httpd-ssl_error.log}
  339.         : ${APACHE_SSL_ACCESS_LOG:=/var/log/httpd-ssl_request.log}
  340.         ;;
  341.     *)
  342.         : ${APACHE_ERROR_LOG:=/usr/local/apache2/logs/error_log}
  343.         : ${APACHE_ACCESS_LOG:=/usr/local/apache2/logs/access_log}
  344.         : ${APACHE_ERROR_LOG_SA:=$APACHE_ERROR_LOG}
  345.         : ${APACHE_ACCESS_LOG_SA:=$APACHE_ACCESS_LOG}
  346.         : ${APACHE_SSL_ERROR_LOG:=/usr/local/apache2/logs/ssl_error_log}
  347.         : ${APACHE_SSL_ACCESS_LOG:=/usr/local/apache2/logs/ssl_access_log}
  348.         ;;
  349.     esac
  350.     ;;
  351. Linux)
  352.     case "$Linux" in
  353.     Ubuntu)
  354.         etc_httpd=/etc/apache2
  355.         error_log=error.log access_log=access.log
  356.         internal_error_log=internal_error_log
  357.         internal_access_log=internal_access_log
  358.         ssl_error_log=ssl_error_log
  359.         ssl_access_log=ssl_access_log
  360.         ;;
  361.     CentOS)
  362.         etc_httpd=/etc/httpd
  363.         error_log=error_log access_log=access_log
  364.         internal_error_log=internal_error_log
  365.         internal_access_log=internal_access_log
  366.         ssl_error_log=ssl_error_log
  367.         ssl_access_log=ssl_access_log
  368.         ;;
  369.     *)
  370.         etc_httpd=/etc/httpd
  371.         [ -d "$etc_httpd" ] || etc_httpd=/etc/apache2
  372.         error_log=error_log access_log=access_log
  373.         internal_error_log=internal_error_log
  374.         internal_access_log=internal_access_log
  375.         ssl_error_log=ssl_error_log
  376.         ssl_access_log=ssl_access_log
  377.     esac
  378.     : ${APACHE_ERROR_LOG:=$etc_httpd/logs/$error_log}
  379.     : ${APACHE_ACCESS_LOG:=$etc_httpd/logs/$access_log}
  380.     : ${APACHE_ERROR_LOG_SA:=$etc_httpd/logs/$internal_error_log}
  381.     : ${APACHE_ACCESS_LOG_SA:=$etc_httpd/logs/$internal_access_log}
  382.     : ${APACHE_SSL_ERROR_LOG:=$etc_httpd/logs/$ssl_error_log}
  383.     : ${APACHE_SSL_ACCESS_LOG:=$etc_httpd/logs/$ssl_access_log}
  384.     ;;
  385. CYGWIN*)
  386.     : ${APACHE_ERROR_LOG:=/var/log/apache2/error_log}
  387.     : ${APACHE_ACCESS_LOG:=/var/log/apache2/access_log}
  388.     : ${APACHE_ERROR_LOG_SA:=$APACHE_ERROR_LOG}
  389.     : ${APACHE_ACCESS_LOG_SA:=$APACHE_ACCESS_LOG}
  390.     : ${APACHE_SSL_ERROR_LOG:=/var/log/apache2/ssl_error_log}
  391.     : ${APACHE_SSL_ACCESS_LOG:=/var/log/apache2/ssl_access_log}
  392.     ;;
  393. esac
  394.  
  395. #
  396. # Set DISPLAY for Xming/XQuartz
  397. #
  398. case "$UNAME_s" in
  399. Darwin*)
  400.     export DISPLAY=:0.0
  401.     ;;
  402. CYGWIN*)
  403.     export DISPLAY=localhost:0
  404.     ;;
  405. esac
  406.  
  407. #
  408. # For dialog(1) and Xdialog(1) menus -- mainly cvspicker in FUNCTIONS below
  409. #
  410. DIALOG_MENU_TAGS="123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  411.  
  412. #
  413. # Default directory to store dialog(1) and Xdialog(1) temporary files
  414. #
  415. : ${DIALOG_TMPDIR:="/tmp"}
  416.  
  417. #
  418. # cvspicker export commands (one per-line)
  419. #
  420. CVSPICKER_EXPORTS="
  421.     CVS_RSH=ssh CVSROOT=cvs.vicor.com:/repos/projects
  422.     CVS_RSH=ssh CVSROOT=mp1.yvod.com:/CVSbase/iPhoneApps
  423.     CVS_RSH=ssh CVSROOT=:ext:devinteske@druidbsd.cvs.sourceforge.net:/cvsroot/druidbsd
  424.     CVS_RSH=ssh CVSROOT=dcvs.freebsd.org:/home/dcvs
  425.     CVS_RSH=ssh CVSROOT=pcvs.freebsd.org:/home/pcvs
  426.     CVS_RSH=ssh CVSROOT=projcvs.freebsd.org:/home/projcvs
  427.     CVS_RSH=ssh CVSROOT=ncvs.freebsd.org:/home/ncvs
  428. " # END-QUOTE
  429.  
  430. #
  431. # perforce settings
  432. #
  433. export P4CONFIG=P4CONFIG
  434.  
  435. #
  436. # route(8) helper settings (see routes() et al., in FUNCTIONS)
  437. #
  438. # NB: ROUTES_${NAME} syntax is "DOMAIN ROUTE_ARGS" where:
  439. #   NAME        1st arg to routes() (converted to upper-case)
  440. #   DOMAIN      Domain prefix to match in hosts(5)
  441. #   ROUTE_ARGS  Arguments to pass to route(8) for matched entries
  442. #
  443. case "$UNAME_s" in
  444. FreeBSD)
  445.     pptp_iface=$( service pptp iface 2> /dev/null )
  446.     ROUTES_PANZURA=".pixel8networks.com -iface ${pptp_iface:-tun0}"
  447.     unset pptp_iface
  448.     ;;
  449. *) ROUTES_PANZURA=".pixel8networks.com -iface ppp0"
  450. esac
  451. ROUTES_VICOR=".vicor.com 10.242.182.1"
  452.  
  453. ############################################################ FUNCTIONS
  454.  
  455. unalias quietly 2> /dev/null
  456. quietly() { "$@" > /dev/null 2>&1; }
  457.  
  458. quietly unalias have
  459. have() { type "$@" > /dev/null 2>&1; }
  460.  
  461. quietly unalias eval2
  462. eval2() {
  463.     if [ "$LOLCAT" ]; then
  464.         echo "$*" | $LOLCAT
  465.     else
  466.         echo "$*"
  467.     fi
  468.     eval "$@"
  469. }
  470.  
  471. quietly unalias spool
  472. spool()
  473. {
  474.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  475.     local path="$( which qmon )"
  476.     if [ ! "$path" ]; then
  477.         echo "$FUNCNAME: qmon not installed" >&2
  478.         return $FAILURE
  479.     fi
  480.     eval2 cd "${path%/bin/*}/default/spool"
  481. }
  482.  
  483. # setvar $var_to_set [$value]
  484. #
  485. # Implement setvar for shells unlike FreeBSD sh(1).
  486. #
  487. if ! have setvar; then
  488. setvar()
  489. {
  490.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  491.     [ $# -gt 0 ] || return ${SUCCESS:-0}
  492.     local __setvar_var_to_set="$1" __setvar_right="$2" __setvar_left=
  493.     case $# in
  494.     1) unset "$__setvar_var_to_set"
  495.        return $? ;;
  496.     2) : fall through ;;
  497.     *) echo "$FUNCNAME: too many arguments" >&2
  498.        return ${FAILURE:-1}
  499.     esac
  500.     case "$__setvar_var_to_set" in *[!0-9A-Za-z_]*)
  501.         echo "$FUNCNAME: $__setvar_var_to_set: bad variable name" >&2
  502.         return 2
  503.     esac
  504.     while case "$__setvar_r" in *\'*) : ;; *) false ; esac
  505.     do
  506.         __setvar_left="$__setvar_left${__setvar_right%%\'*}'\\''"
  507.         __setvar_right="${__setvar_right#*\'}"
  508.     done
  509.     __setvar_left="$__setvar_left${__setvar_right#*\'}"
  510.     eval "$__setvar_var_to_set='$__setvar_left'"
  511. }
  512. fi
  513.  
  514. # lolexec [$command [$args ...]]
  515. #
  516. # Create a wrapper function for $command, sending output to `lolcat' (or
  517. # `cowsay') transparently. To make this execute for all commands, automatically
  518. # sending all output to lolcat, make this function the DEBUG trap.
  519. #
  520. # For example:
  521. #   trap lolexec DEBUG
  522. #
  523. # When trapped as the DEBUG routine in bash, any/all command lines that...
  524. #   + Do NOT contain the pipe character
  525. #   + Do NOT start with an exclamation point by-itself (e.g., "! top")
  526. # ... will have their output sent to lolcat.
  527. #
  528. # NB: Requires awk(1) -- from base system
  529. #
  530. if [ "$ZSH_NAME" ]; then
  531.     preexec() { lolexec "$1"; }
  532.     precmd() { trap - DEBUG; }
  533.     type_t() {
  534.         case "$( builtin type "$@" 2> /dev/null )" in
  535.         *" is a shell function") builtin echo function ;;
  536.         *" is an alias for "*) builtin echo alias ;;
  537.         *" is a shell builtin") builtin echo builtin ;;
  538.         *" is a reserved word") builtin echo keyword ;;
  539.         *" is /"*) builtin echo file ;;
  540.         *) builtin echo unknown
  541.         esac
  542.     }
  543. else
  544.     type_t() { builtin type -t "$@" 2> /dev/null; }
  545.     LOLEXEC='[ "$( trap -p DEBUG )" ]'
  546.     LOLEXEC="$LOLEXEC || trap \"trap - DEBUG; lolexec\" DEBUG"
  547. fi
  548. alias -- +lol='trap - DEBUG; +lolcat'
  549. alias -- -lol='-lolcat'
  550. quietly unalias -lolcat
  551. -lolcat()
  552. {
  553.     if [ $# -lt 1 -o ! "$*" ]; then
  554.         unset PROMPT_COMMAND
  555.         return $SUCCESS
  556.     fi
  557.  
  558.     local cmd
  559.     for cmd in "$@"; do
  560.         _NOLOL_CMDS="$_NOLOL_CMDS|$cmd|$cmd\[\$IFS]*"
  561.     done
  562. }
  563. case "$UNAME_s" in
  564. Darwin) -lol ls ;;
  565. esac
  566. quietly unalias +lolcat
  567. +lolcat()
  568. {
  569.     PROMPT_COMMAND="$LOLEXEC"
  570.     LOLCAT="${*:-$LOLCAT}"
  571. }
  572. quietly unalias lolexec
  573. lolexec()
  574. {
  575.     builtin [ "$ZSH_NAME" ] && builtin local FUNCNAME="$funcstack[1]"
  576.     builtin export OLDPWD # Required for `cd -' and `pushd -'
  577.     builtin local _lolcat="$LOLCAT" _lc=
  578.     builtin local _prog _register=1
  579.     builtin local cmd fprog prefix=_${FUNCNAME}_ prog=
  580.     case "$_LOLFUNC" in
  581.     ""|$FUNCNAME) builtin : fall through ;;
  582.     *)
  583.         builtin unset -f $_LOLFUNC 2> /dev/null
  584.         type_t $prefix$_LOLFUNC > /dev/null 2>&1 &&
  585.             builtin eval "$( builtin type $prefix$_LOLFUNC |
  586.                 builtin command awk -v prefix=$prefix '
  587.                     NR == 2 { sub("^" prefix, ""); print }
  588.                     NR > 2
  589.             ' )"
  590.     esac
  591.     _LOLFUNC=
  592.     case "$_lolcat" in
  593.     "") builtin [ $# -eq 0 ] || builtin [ "$ZSH_NAME" ] || "$@"
  594.         builtin return ;;
  595.     *lolcat) _lc=1 ;;
  596.     esac
  597.     if builtin [ "$ZSH_NAME" ]; then
  598.         cmd="$1"
  599.     else
  600.         case "$#" in
  601.         0) cmd=$( history 1 ) || builtin return
  602.            cmd="${cmd#*[0-9]  }" ;;
  603.         *) cmd="$*"
  604.         esac
  605.     fi
  606.     builtin [ "$cmd" ] || builtin return
  607.     builtin export LOL_CMD="$cmd"
  608.     builtin eval "case \"\$cmd\" in
  609.     $_LOL_CMDS) builtin : fall through ;;
  610.     $_NOLOL_CMDS)
  611.         builtin [ \$# -eq 0 ] || builtin [ \"\$ZSH_NAME\" ] || \"\$@\"
  612.         builtin return
  613.     esac"
  614.     for prog in $cmd; do
  615.         builtin [ "$prog" = "!" ] || builtin break
  616.         builtin [ $# -eq 0 ] || builtin [ "$ZSH_NAME" ] || "$@"
  617.         builtin return
  618.     done
  619.     case "$prog" in
  620.     ""|*[^[:alnum:]_]*)
  621.         builtin [ $# -eq 0 ] || builtin [ "$ZSH_NAME" ] || "$@"
  622.         builtin return
  623.     esac
  624.     _prog=$prog
  625.     while builtin [ "$( type_t $prog 2> /dev/null )" = alias ]; do
  626.         fprog=$( builtin type $prog )
  627.         fprog="${fprog#*\`}"
  628.         fprog="${fprog%\'}"
  629.         for prog in $fprog; do
  630.             builtin [ "$prog" = "!" ] || builtin break
  631.             builtin [ $# -eq 0 ] || builtin [ "$ZSH_NAME" ] || "$@"
  632.             builtin return
  633.         done
  634.         builtin [ "$prog" = "$_prog" ] && builtin break # infinite loop
  635.         _prog=$prog
  636.     done
  637.     if builtin [ "$prog" = "$FUNCNAME" -o ! "${prog#type_t}" ]; then
  638.         builtin [ $# -eq 0 ] || builtin [ "$ZSH_NAME" ] || "$@"
  639.         builtin return
  640.     fi
  641.     case "$( type_t $prog 2> /dev/null )" in
  642.     alias|file) # blacklist
  643.         builtin eval "case \"\$prog\" in
  644.         $_NOLOL_PROGS)
  645.             builtin [ \$# -eq 0 ] || builtin [ \"\$ZSH_NAME\" ] ||
  646.                 \"\$@\"
  647.             builtin return
  648.         esac"
  649.         fprog="builtin command $prog"
  650.         _LOLFUNC=$prog
  651.         builtin [ "$_lc" ] && case "$prog" in
  652.         *less|*more) # [bz,lz,xz,z]less [z]more
  653.             builtin eval "function $prog()
  654.             {
  655.                 $fprog \"\$@\" | $LOLCAT -f |
  656.                     builtin command less -R
  657.             }"
  658.             _register= ;;
  659.         ping*) # l2ping ping ping6
  660.             _lolcat="$_lolcat -a" ;;
  661.         tail) # check for `-f' or `-F'
  662.             case "$cmd" in
  663.             *[$IFS]-[fF]|*[$IFS]-[fF][$IFS]*) _lolcat="$_lolcat -a"
  664.             esac ;;
  665.         esac
  666.         ;;
  667.     builtin|keyword) # whitelist
  668.         builtin eval "case \"\$prog\" in
  669.         $_LOL_BUILTINS) builtin : fall through ;;
  670.         *)
  671.             builtin [ \$# -eq 0 ] || builtin [ \"\$ZSH_NAME\" ] ||
  672.                 \"\$@\"
  673.             builtin return
  674.         esac"
  675.         fprog="builtin $prog"
  676.         _LOLFUNC=$prog ;;
  677.     function) # overlay
  678.         builtin [ "$_lc" ] && case "$prog" in
  679.         tlog|tm|taal|tael) # wrappers to `tail -F'
  680.             _lolcat="$_lolcat -a" ;;
  681.         esac
  682.         builtin eval "$prefix$( builtin type $prog |
  683.             builtin command awk 'NR>1' )"
  684.         fprog="$prefix$prog"
  685.         _LOLFUNC=$prog ;;
  686.     *) # unknown
  687.         builtin [ $# -eq 0 ] || builtin [ "$ZSH_NAME" ] || "$@"
  688.         builtin return
  689.     esac
  690.     builtin [ "$LOLDEBUG" ] && builtin echo \
  691.         "$FUNCNAME: prog=[$prog] fprog=[$fprog] cmd=[$cmd]" >&2
  692.     builtin [ "$_register" ] && builtin eval "function $prog()
  693.     {
  694.         exec 3>&1
  695.         local cwd=\"\${D0:-\${DIRSTACK[0]:-\$( builtin pwd )}}\"
  696.         builtin local meta=\"\$( exec 4>&1; (
  697.             $fprog \"\$@\"
  698.             builtin echo \"\$?:\$( builtin pwd )\" >&4
  699.         ) | $_lolcat >&3 )\"
  700.         builtin local ret=\"\${meta%%:*}\" chdir=\"\${meta#*:}\"
  701.         case \"$prog\" in
  702.         dirstack_wrap) builtin \"\$@\" ;;
  703.         pushd|popd) builtin $prog \"\$@\" ;;
  704.         *) builtin [ \"\$cwd\" != \"\$chdir\" ] &&
  705.             builtin cd \"\$chdir\"
  706.         esac > /dev/null 2>&1
  707.         builtin type dirstack2d > /dev/null 2>&1 &&
  708.             builtin [ \"\$cwd\" != \"\$chdir\" ] && dirstack2d
  709.         builtin return \$ret
  710.     }"
  711.     builtin [ $# -eq 0 ] || builtin [ "$ZSH_NAME" ] || "$@"
  712. }
  713.  
  714. if have cowsay; then
  715. # cowsay
  716. #
  717. # Default arguments for cowsay
  718. #
  719. cowsay()
  720. {
  721.     local wrap=-n
  722.     [ $# -gt 0 ] && wrap="-W $(( ${COLUMNS:-80} - 3 ))"
  723.     command cowsay $wrap "$@"
  724. }
  725.  
  726. # unicornsay
  727. #
  728. # Cows are boring
  729. #
  730. # NB: unicorn.cow obtained from https://github.com/schacon/cowsay/pull/13
  731. # Special Thanks to: Sven Wittevrongel (@CupOfTea696)
  732. #
  733. unicornsay()
  734. {
  735.     local wrap=-n
  736.     [ $# -gt 0 ] && wrap="-W $(( ${COLUMNS:-80} - 3 ))"
  737.     command cowsay -f ~/bin/unicorn.cow $wrap "$@"
  738. }
  739. fi # have cowsay
  740.  
  741. if have cowthink; then
  742. # cowthink
  743. #
  744. # Default arguments for cowthink
  745. #
  746. cowthink()
  747. {
  748.     local wrap=-n
  749.     [ $# -gt 0 ] && wrap="-W $(( ${COLUMNS:-80} - 3 ))"
  750.     command cowthink $wrap "$@"
  751. }
  752.  
  753. # unicornthink
  754. #
  755. # Cows are boring
  756. #
  757. # NB: unicorn.cow obtained from https://github.com/schacon/cowsay/pull/13
  758. # Special Thanks to: Sven Wittevrongel (@CupOfTea696)
  759. #
  760. unicornthink()
  761. {
  762.     local wrap=-n
  763.     [ $# -gt 0 ] && wrap="-W $(( ${COLUMNS:-80} - 3 ))"
  764.     command cowthink -f ~/bin/unicorn.cow $wrap "$@"
  765. }
  766. fi # have cowthink
  767.  
  768. # path_munge $entry ...
  769. #
  770. # Add $entry to $PATH if not already added.
  771. #
  772. quietly unalias path_munge
  773. path_munge()
  774. {
  775.     while [ $# -gt 0 ]; do
  776.         [ ! "$1" ] && shift && continue
  777.         ( PATH="$PATH:"
  778.           while [ "$PATH" ]; do
  779.             [ "${PATH%%:*}" = "$1" ] && exit ${SUCCESS:-0}
  780.             PATH="${PATH#*:}"
  781.           done
  782.           exit ${FAILURE:-1}
  783.         ) || export PATH="$PATH${PATH:+:}$1"
  784.         shift
  785.     done
  786. }
  787.  
  788. # fprintf $fd $fmt [ $opts ... ]
  789. #
  790. # Like printf, except allows you to print to a specific file-descriptor. Useful
  791. # for printing to stderr (fd=2) or some other known file-descriptor.
  792. #
  793. quietly unalias fprintf
  794. fprintf()
  795. {
  796.     local fd=$1
  797.     [ $# -gt 1 ] || return ${FAILURE:-1}
  798.     shift 1
  799.     printf "$@" >&$fd
  800. }
  801.  
  802. quietly unalias eprintf
  803. eprintf() { fprintf 2 "$@"; }
  804.  
  805. # pidof [-s] $process_name ...
  806. #
  807. # Print the pid(s) of each process matching the given name(s). If the `-s'
  808. # option is passed, only the first matching pid is returned.
  809. #
  810. # NB: Requires ps(1) awk(1) -- from base system
  811. #
  812. quietly unalias pidof
  813. pidof()
  814. {
  815.     local pids=
  816.     local single=0
  817.  
  818.     local OPTIND flag
  819.     while getopts s flag "$@"; do
  820.         case "$flag" in
  821.         s) single=1;;
  822.         esac
  823.     done
  824.     shift $(( $OPTIND - 1 ))
  825.  
  826.     local process_name process_pids=
  827.     while [ $# -gt 0 ]; do
  828.         process_name="$1"
  829.         process_pids=$(
  830.             ps axo pid=,ucomm= |
  831.             awk -v pattern="$process_name" \
  832.                 -v single=$single \
  833.             '
  834.                 BEGIN { space = "" }
  835.                 ( $2 ~ pattern ) \
  836.                 {
  837.                     printf "%c%s", space, $1
  838.                     if ( single ) exit
  839.                     space = " "
  840.                 }
  841.             '
  842.         )
  843.         pids="$pids${pids:+ }$process_pids"
  844.         shift
  845.     done
  846.  
  847.     [ "$pids" ] && echo "$pids"
  848. }
  849.  
  850. # settitle $title ...
  851. #
  852. # Set the title of your ANSI-compatible shell window.
  853. #
  854. quietly unalias settitle
  855. settitle()
  856. {
  857.     printf "\e]2;$*\a\e]1;$*\a\e]0;$*\a";
  858. }
  859.  
  860. # ssh-agent [ssh-agent options]
  861. #
  862. # Override ``ssh-agent'' to call a function (you can always call the real
  863. # binary by executing /usr/bin/ssh-agent) that launches a background ssh-agent
  864. # that times-out in 30 minutes.
  865. #
  866. # Will evaluate the output of /usr/bin/ssh-agent (the real ssh-agent) called
  867. # with either a known-secure set of arguments (if none are provided) or the
  868. # unmodified arguments to this functin.
  869. #
  870. # Purpose is to prevent memorizing something like ``eval "$( ssh-agent ... )"''
  871. # but instead simply ``ssh-agent [...]''.
  872. #
  873. # This allows you to, for example:
  874. #
  875. #   ssh-agent
  876. #   : do some ssh-add
  877. #   : do some commits
  878. #   ssh-agent -k
  879. #   : or instead of ``ssh-agent -k'' just wait 30m for it to die
  880. #
  881. # NB: Requires /usr/bin/ssh-agent -- from base system
  882. #
  883. quietly unalias ssh-agent
  884. ssh-agent()
  885. {
  886.     [ $# -gt 0 ] || set -- -t 1800
  887.     eval "$( /usr/bin/ssh-agent "$@" )"
  888. }
  889.  
  890. # ssh-agent-dup [-aqn]
  891. #
  892. # Connect to an open/active ssh-agent session available to the currently
  893. # authenticated user. If more than one ssh-agent is available and the `-n' flag
  894. # is not given, provide a menu list of open/active sessions available. Allows
  895. # the user to quickly duplicate access to an ssh-agent launched in another
  896. # interactive session on the same machine or for switching between agents.
  897. #
  898. # This allows you to, for example:
  899. #
  900. #   (in shell session A)
  901. #   ssh-agent
  902. #   (in shell session B)
  903. #   ssh-agent-dup
  904. #   (now both sessions A and B can use the same agent)
  905. #
  906. # No menu is presented if only a single agent session is available (the open
  907. # session is duplicated for the active shell session). If more than one agent
  908. # is available, a menu is presented. The menu choice becomes the active agent.
  909. #
  910. # If `-a' is present, list all readable agent sockets, not just those owned by
  911. # the currently logged-in user.
  912. #
  913. # If `-q' is present, do not list agent nor keys.
  914. #
  915. # If `-n' is present, run non-interactively (good for scripts; pedantic).
  916. #
  917. # NB: Requires dialog_menutag() dialog_menutag2help() eval2() have()
  918. #     -- from this file
  919. # NB: Requires $DIALOG_TMPDIR $DIALOG_MENU_TAGS -- from this file
  920. # NB: Requires awk(1) cat(1) grep(1) id(1) ls(1) ps(1) ssh-add(1) stat(1)
  921. #     -- from base system
  922. #
  923. quietly unalias ssh-agent-dup
  924. ssh-agent-dup()
  925. {
  926.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  927.     local t=1s # ssh-add(1) timeout
  928.     local list_all= quiet= interactive=1 noninteractive=
  929.     local sockets=
  930.     local owner socket socket_owner pid current_user
  931.  
  932.     local OPTIND=1 OPTARG flag
  933.     while getopts anq flag; do
  934.         case "$flag" in
  935.         a) list_all=1 ;;
  936.         n) noninteractive=1 interactive= ;;
  937.         q) quiet=1 ;;
  938.         \?|*)
  939.             [ "$noninteractive" ] ||
  940.                 echo "$FUNCNAME [-aq]" | ${LOLCAT:-cat} >&2
  941.             return ${FAILURE:-1}
  942.         esac
  943.     done
  944.     shift $(( $OPTIND - 1 ))
  945.  
  946.     case "$UNAME_s" in
  947.     *BSD) owner="-f%Su" ;;
  948.     *) owner="-c%U"
  949.     esac
  950.  
  951.     current_user=$( id -nu )
  952.     for socket in /tmp/ssh-*/agent.[0-9]*; do
  953.         # Must exist as a socket
  954.         [ -S "$socket" ] || continue
  955.  
  956.         # Must end in numbers-only (after trailing dot)
  957.         pid="${socket##*.}"
  958.         [ "$pid" -a "$pid" = "${pid#*[!0-9]}" ] || continue
  959.         pid=$(( $pid + 1 )) # socket num is one below agent PID
  960.  
  961.         # Must be a running pid and an ssh or ssh-agent
  962.         if ! [ "$( ps -p $pid -o ucomm= 2> /dev/null )" = ssh-agent ]
  963.         then
  964.             # This could be a forwarded agent
  965.             pid=$(( $pid - 1 ))
  966.             [ "$( ps -p $pid -o ucomm= 2> /dev/null )" = sshd ] ||
  967.                 continue
  968.         fi
  969.  
  970.         # Must be owned by the current user unless `-a' is used
  971.         # NB: When `-a' is used, the socket still has to be readable
  972.         if [ ! "$list_all" ]; then
  973.             socket_owner=$( stat $owner "$socket" 2> /dev/null ) ||
  974.                 continue
  975.             [ "$socket_owner" = "$current_user" ] || continue
  976.         fi
  977.  
  978.         sockets="$sockets $socket"
  979.     done
  980.  
  981.     sockets="${sockets# }"
  982.     if [ ! "$sockets" ]; then
  983.         if [ ! "$noninteractive" ]; then
  984.             local msg="$FUNCNAME: No agent sockets available"
  985.             echo "$msg" | ${LOLCAT:-cat} >&2
  986.         fi
  987.         return ${FAILURE:-1}
  988.     fi
  989.     if [ "${sockets}" = "${sockets%% *}" ]; then
  990.         # Only one socket found
  991.         pid=$(( ${sockets##*.} + 1 ))
  992.         if [ "$( ps -p $pid -o ucomm= 2> /dev/null )" = ssh-agent ]
  993.         then
  994.             eval${interactive:+2} export \
  995.                 SSH_AUTH_SOCK="$sockets" \
  996.                 SSH_AGENT_PID="$pid"
  997.         else
  998.             # This could be a forwarded agent
  999.             pid=$(( $pid - 1 ))
  1000.             if [ "$( ps -p $pid -o ucomm= 2> /dev/null )" = sshd ]
  1001.             then
  1002.                 eval${interactive:+2} export \
  1003.                     SSH_AUTH_SOCK="$sockets" \
  1004.                     SSH_AGENT_PID="$pid"
  1005.             else
  1006.                 eval${interactive:+2} export \
  1007.                     SSH_AUTH_SOCK="$sockets"
  1008.             fi
  1009.         fi
  1010.         [ "$SSH_AGENT_PID" -a ! "$quiet" ] && # show process
  1011.             [ "$interactive" ] &&
  1012.             ps -p "$SSH_AGENT_PID" | ${LOLCAT:-cat}
  1013.         # dump fingerprints from newly configured agent
  1014.         if ! [ "$quiet" -o "$noninteractive" ]; then
  1015.             echo "# NB: Use \`ssh-agent -k' to kill this agent"
  1016.             timeout $t ssh-add -l
  1017.         fi | ${LOLCAT:-cat}
  1018.         return ${SUCCESS:-0}
  1019.     fi
  1020.  
  1021.     # There's more than one agent available
  1022.     [ "$noninteractive" ] && return ${FAILURE:-1}
  1023.  
  1024.     #
  1025.     # If we don't have dialog(1), just print the possible values
  1026.     #
  1027.     if ! have dialog; then
  1028.         local prefix="%3s"
  1029.         local fmt="$prefix %5s %-20s %s\n"
  1030.         local num=0 choice
  1031.         local identities nloaded
  1032.  
  1033.         sockets=$( command ls -tr $sockets ) # ascending order by age
  1034.         printf "$fmt" "" PID USER+NKEYS COMMAND
  1035.         for socket in $sockets; do
  1036.             num=$(( $num + 1 ))
  1037.             pid=$(( ${socket##*.} + 1 ))
  1038.             ucomm=$( ps -p $pid -o ucomm= 2> /dev/null )
  1039.             [ "$ucomm" = ssh-agent ] || pid=$(( $pid - 1 ))
  1040.             nkeys=0
  1041.             identities=$( SSH_AUTH_SOCK="$socket" \
  1042.                 timeout $t ssh-add -l
  1043.             ) && nkeys=$( echo "$identities" | grep -c . )
  1044.             printf "$fmt" $num: "$pid" \
  1045.                 "$( ps -p $pid -o user= )"+"$nkeys" \
  1046.                 "$( ps -p $pid -o command= )" | ${LOLCAT:-cat}
  1047.         done
  1048.         echo
  1049.         echo -n "Select a number [$num]: " | ${LOLCAT:-cat}
  1050.         read choice
  1051.         : ${choice:=$num}
  1052.         case "$choice" in
  1053.         ""|*[!0-9]*)
  1054.             echo "$FUNCNAME: Invalid choice [$choice]" |
  1055.                 ${LOLCAT:-cat} >&2
  1056.             return ${FAILURE:-1} ;;
  1057.         esac
  1058.         if [ $choice -gt $num -o $choice -lt 1 ]; then
  1059.             echo "$FUNCNAME: Choice out of range [$choice]" |
  1060.                 ${LOLCAT:-cat} >&2
  1061.             return ${FAILURE:-1}
  1062.         fi
  1063.         set -- $sockets
  1064.         eval socket=\"\${$choice}\"
  1065.  
  1066.         pid=$(( ${socket##*.} + 1 ))
  1067.         if [ "$( ps -p $pid -o ucomm= 2> /dev/null )" = ssh-agent ]
  1068.         then
  1069.             eval2 export \
  1070.                 SSH_AUTH_SOCK="$socket" \
  1071.                 SSH_AGENT_PID="$pid"
  1072.         else
  1073.             # This could be a forwarded agent
  1074.             pid=$(( $pid - 1 ))
  1075.             if [ "$( ps -p $pid -o ucomm= 2> /dev/null )" = sshd ]
  1076.             then
  1077.                 eval2 export \
  1078.                     SSH_AUTH_SOCK="$socket" \
  1079.                     SSH_AGENT_PID="$pid"
  1080.             else
  1081.                 eval2 export SSH_AUTH_SOCK="$socket"
  1082.             fi
  1083.         fi
  1084.     else
  1085.         local menu_list=
  1086.  
  1087.         sockets=$( command ls -1t $sockets ) # descending order by age
  1088.         menu_list=$( echo "$sockets" |
  1089.             awk -v t="$t" -v tags="$DIALOG_MENU_TAGS" '
  1090.             {
  1091.                 if (++tagn > length(tags)) exit
  1092.                 if (!match($0, /[[:digit:]]+$/)) next
  1093.                 pid = substr($0, RSTART, RLENGTH) + 1
  1094.                 cmd = sprintf("ps -p %u -o user=", pid)
  1095.                 cmd | getline user
  1096.                 close(cmd)
  1097.                 cmd = sprintf("ps -p %u -o command=", pid)
  1098.                 cmd | getline command
  1099.                 close(cmd)
  1100.                 nloaded = 0
  1101.                 cmd = "SSH_AUTH_SOCK=" $0 \
  1102.                     " timeout " t " ssh-add -l"
  1103.                 while (cmd | getline identity) {
  1104.                     nloaded += identity ~ /^[[:digit:]]/
  1105.                 }
  1106.                 close(cmd)
  1107.                 printf "'\'%s\'\ \'%s\'\ \'%s\''\n",
  1108.                     substr(tags, tagn, 1),
  1109.                     sprintf("pid %u %s+%u %s",
  1110.                         pid, user, nloaded, command),
  1111.                     sprintf("export %s %s",
  1112.                         "SSH_AUTH_SOCK=" $0,
  1113.                         "SSH_AGENT_PID=" pid)
  1114.             }'
  1115.         )
  1116.  
  1117.         local prompt="Pick an ssh-agent to duplicate (user+nkeys):"
  1118.         eval dialog \
  1119.             --clear --title "'$FUNCNAME'" --item-help \
  1120.             --menu "'$prompt'" 17 55 9 $menu_list \
  1121.             2> "$DIALOG_TMPDIR/dialog.menu.$$"
  1122.         local retval=$?
  1123.  
  1124.         # Return if "Cancel" was chosen (-1) or ESC was pressed (255)
  1125.         [ $retval -eq ${SUCCESS:-0} ] || return $retval
  1126.  
  1127.         local tag="$( dialog_menutag )"
  1128.         eval2 $( eval dialog_menutag2help "'$tag'" $menu_list )
  1129.     fi
  1130.  
  1131.     # Attempt to show the running agent
  1132.     [ "$SSH_AGENT_PID" -a ! "$quiet" ] &&
  1133.         ps -p "$SSH_AGENT_PID" | ${LOLCAT:-cat}
  1134.  
  1135.     # Attempt to dump fingerprints from newly configured agent
  1136.     if [ ! "$quiet" ]; then
  1137.         echo "# NB: Use \`$FUNCNAME' to select a different agent"
  1138.         echo "# NB: Use \`ssh-agent -k' to kill this agent"
  1139.         timeout $t ssh-add -l
  1140.     fi | ${LOLCAT:-cat}
  1141. }
  1142.  
  1143. # openkey [-hv]
  1144. #
  1145. # Mounts my F.o thumb
  1146. #
  1147. # NB: Requires eprintf() have() -- from this file
  1148. # NB: Requires awk(1) df(1) id(1) mount(8) -- from base system
  1149. #
  1150. quietly unalias openkey
  1151. openkey()
  1152. {
  1153.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  1154.     [ "$UNAME_s" = "FreeBSD" ] ||
  1155.         { echo "$FUNCNAME: FreeBSD only!" >&2; return 1; }
  1156.     local OPTIND=1 OPTARG flag verbose= sudo=
  1157.     while getopts hv flag; do
  1158.         case "$flag" in
  1159.         v) verbose=1 ;;
  1160.         *) local optfmt="\t%-4s %s\n"
  1161.            eprintf "Usage: $FUNCNAME [-hv]\n"
  1162.            eprintf "OPTIONS:\n"
  1163.            eprintf "$optfmt" "-h" \
  1164.                    "Print this text to stderr and return."
  1165.            eprintf "$optfmt" "-v" \
  1166.                    "Print verbose debugging information."
  1167.            return ${FAILURE:-1}
  1168.         esac
  1169.     done
  1170.     shift $(( $OPTIND - 1 ))
  1171.     if [ "$( id -u )" != "0" ]; then
  1172.         if have sr; then
  1173.             sudo=sr
  1174.         elif have sudo; then
  1175.             sudo=sudo
  1176.         fi || {
  1177.             eprintf "$FUNCNAME: not enough privileges\n"
  1178.             return ${FAILURE:-1}
  1179.         }
  1180.     fi
  1181.     df -l /mnt | awk '
  1182.         $NF == "/mnt" { exit found++ } END { exit !found }
  1183.     ' || ${verbose:+eval2} $sudo mount /mnt || return
  1184.     local nfail=3
  1185.     while [ $nfail -gt 0 ]; do
  1186.         /mnt/mount.sh -d${verbose:+v} && break
  1187.         nfail=$(( $nfail - 1 ))
  1188.     done
  1189.     [ "$verbose" ] && df -hT /mnt/* | ( awk '
  1190.         NR == 1 { print > "/dev/stderr"; next } 1
  1191.     ' | sort -u ) 2>&1
  1192.     return ${SUCCESS:-0}
  1193. }
  1194.  
  1195. # closekey [-ehv]
  1196. #
  1197. # Unmounts my F.o thumb
  1198. #
  1199. # NB: Requires eprintf() have() -- from this file
  1200. # NB: Requires awk(1) camcontrol(8) df(1) id(1) umount(8) -- from base system
  1201. #
  1202. quietly unalias closekey
  1203. closekey()
  1204. {
  1205.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  1206.     local OPTIND=1 OPTARG flag eject= verbose= sudo=
  1207.     while getopts ehv flag; do
  1208.         case "$flag" in
  1209.         e) eject=1 ;;
  1210.         v) verbose=1 ;;
  1211.         *) local optfmt="\t%-4s %s\n"
  1212.            eprintf "Usage: $FUNCNAME [-ehv]\n"
  1213.            eprintf "OPTIONS:\n"
  1214.            eprintf "$optfmt" "-e" \
  1215.                    "Eject USB media (using \`camcontrol eject')."
  1216.            eprintf "$optfmt" "-h" \
  1217.                    "Print this text to stderr and return."
  1218.            eprintf "$optfmt" "-v" \
  1219.                    "Print verbose debugging information."
  1220.            return ${FAILURE:-1}
  1221.         esac
  1222.     done
  1223.     shift $(( $OPTIND - 1 ))
  1224.     if [ "$( id -u )" != "0" ]; then
  1225.         if have sr; then
  1226.             sudo=sr
  1227.         elif have sudo; then
  1228.             sudo=sudo
  1229.         fi || {
  1230.             eprintf "$FUNCNAME: not enough privileges\n"
  1231.             return ${FAILURE:-1}
  1232.         }
  1233.     fi
  1234.     [ ! -f "/mnt/umount.sh" ] ||
  1235.         ${verbose:+eval2} /mnt/umount.sh ${verbose:+-v} || return
  1236.     [ ! "$eject" ] || daN=$( df -l /mnt | awk '
  1237.         $NF == "/mnt" && match($0, "^/dev/[[:alpha:]]+[[:digit:]]+") {
  1238.             print substr($0, 6, RLENGTH - 5)
  1239.             exit found++
  1240.         } END { exit ! found }
  1241.     ' ) || daN=$(
  1242.         [ "$sudo" -a "$verbose" ] && echo $sudo camcontrol devlist >&2
  1243.         $sudo camcontrol devlist | awk '
  1244.         BEGIN {
  1245.             camfmt = "^<%s>[[:space:]]+[^(]*"
  1246.  
  1247.             disk[nfind = 0] = "da[[:digit:]]+"
  1248.             find[nfind++] = "USB Flash Disk 1100"
  1249.  
  1250.             #disk[nfind] = "device_pattern"
  1251.             #find[nfind++] = "model_pattern"
  1252.         }
  1253.         found = 0
  1254.         {
  1255.             for (n = 0; n < nfind; n++)
  1256.             {
  1257.                 if (!match($0, sprintf(camfmt, find[n])))
  1258.                     continue
  1259.                 devicestr = substr($0, RSTART + RLENGTH + 1)
  1260.                 gsub(/\).*/, "", devicestr)
  1261.                 ndevs = split(devicestr, devices, /,/)
  1262.                 for (d = 1; d <= ndevs; d++) {
  1263.                     if (devices[d] !~ "^" disk[n] "$")
  1264.                         continue
  1265.                     found = 1
  1266.                     break
  1267.                 }
  1268.                 if (found) break
  1269.             }
  1270.         }
  1271.         found && $0 = devices[d] { print; exit }
  1272.         END { exit !found }
  1273.     ' ) || return
  1274.     ! df -l /mnt | awk '$NF=="/mnt"{exit found++}END{exit !found}' ||
  1275.         ${verbose:+eval2} $sudo umount /mnt || return
  1276.     [ "$eject" -a "$daN" ] &&
  1277.         ${verbose:+eval2} $sudo camcontrol eject "$daN"
  1278.     return ${SUCCESS:-0}
  1279. }
  1280.  
  1281. # loadkeys [OPTIONS] [key ...]
  1282. #
  1283. # Load my SSH private keys from my F.o thumb. The `key' argument is to the
  1284. # SSH private keyfile's suffix; in example, "sf" for "id_rsa.sf" or "f.o" for
  1285. # "id_rsa.f.o" or "gh" for "id_rsa.gh".
  1286. #
  1287. # For example, to load the Sourceforge.net key, F.o key, and Github key:
  1288. #   loadkeys sf f.o gh
  1289. #
  1290. # OPTIONS:
  1291. #   -c           Close USB media after loading keys.
  1292. #   -e           Close and eject USB media after loading keys.
  1293. #   -h           Print this text to stderr and return.
  1294. #   -k           Kill running ssh-agent(1) and launch new one.
  1295. #   -n           Start a new ssh-agent, ignoring current one.
  1296. #   -t timeout   Timeout. Only used if starting ssh-agent(1).
  1297. #   -v           Print verbose debugging information.
  1298. #
  1299. # NB: Requires closekey() colorize() eprintf() openkey() quietly() ssh-agent()
  1300. #     ssh-agent-dup() -- from this file
  1301. # NB: Requires awk(1) kill(1) ps(1) ssh-add(1) -- from base system
  1302. #
  1303. quietly unalias loadkeys
  1304. loadkeys()
  1305. {
  1306.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  1307.     local OPTIND=1 OPTARG flag close= eject= kill= new= timeout= verbose=
  1308.     while getopts cehknt:v flag; do
  1309.         case "$flag" in
  1310.         c) close=1 ;;
  1311.         e) close=1 eject=1 ;;
  1312.         k) kill=1 ;;
  1313.         n) new=1 ;;
  1314.         v) verbose=1 ;;
  1315.         t) timeout="$OPTARG" ;;
  1316.         *) local optfmt="\t%-12s %s\n"
  1317.            eprintf "Usage: $FUNCNAME [OPTIONS] [key ...]\n"
  1318.            eprintf "OPTIONS:\n"
  1319.            eprintf "$optfmt" "-c" \
  1320.                    "Close USB media after loading keys."
  1321.            eprintf "$optfmt" "-e" \
  1322.                    "Close and eject USB media after loading keys."
  1323.            eprintf "$optfmt" "-h" \
  1324.                    "Print this text to stderr and return."
  1325.            eprintf "$optfmt" "-k" \
  1326.                    "Kill running ssh-agent(1) and launch new one."
  1327.            eprintf "$optfmt" "-n" \
  1328.                    "Start a new ssh-agent, ignoring current one."
  1329.            eprintf "$optfmt" "-t timeout" \
  1330.                    "Timeout. Only used if starting ssh-agent(1)."
  1331.            eprintf "$optfmt" "-v" \
  1332.                    "Print verbose debugging information."
  1333.            return ${FAILURE:-1}
  1334.         esac
  1335.     done
  1336.     shift $(( $OPTIND - 1 ))
  1337.     [ "$kill" ] && quietly ssh-agent -k
  1338.     if [ "$new" ]; then
  1339.         ssh-agent ${timeout:+-t"$timeout"} ||
  1340.             return ${FAILURE:-1}
  1341.     elif quietly kill -0 "$SSH_AGENT_PID"; then
  1342.         : already running
  1343.     elif [ "$SSH_AUTH_SOCK" ] && quietly ssh-add -l; then
  1344.         eval2 export SSH_AGENT_PID=$( lsof -t -- $SSH_AUTH_SOCK )
  1345.     else
  1346.         if ! ssh-agent-dup -q; then
  1347.             ssh-agent ${timeout:+-t"$timeout"} ||
  1348.                 return ${FAILURE:-1}
  1349.         fi
  1350.     fi
  1351.     ps -p "$SSH_AGENT_PID" || return ${FAILURE:-1}
  1352.     local suffix file show= load_required=
  1353.     [ $# -eq 0 ] && load_required=1
  1354.     for suffix in "$@"; do
  1355.         file="/mnt/keys/id_rsa.$suffix"
  1356.         ssh-add -l | awk -v file="$file" '
  1357.             gsub(/(^[0-9]+ [[:xdigit:]:]+ | \(.*\).*$)/, "") &&
  1358.                 $0 == file { exit found++ }
  1359.             END { exit !found }
  1360.         ' && show="$show${show:+|}$suffix" && continue # already loaded
  1361.         load_required=1
  1362.         break
  1363.     done
  1364.     ssh-add -l | colorize -c 36 "/mnt/keys/id_rsa\\.($show)([[:space:]]|$)"
  1365.     [ "$load_required" ] || return ${SUCCESS:-0}
  1366.     openkey ${verbose:+-v} || return ${FAILURE:-1}
  1367.     [ "$verbose" ] && ssh-add -l
  1368.     local loaded_new=
  1369.     if [ $# -gt 0 ]; then
  1370.         for suffix in "$@"; do
  1371.             file="/mnt/keys/id_rsa.$suffix"
  1372.             [ -f "$file" ] || continue
  1373.             ssh-add -l | awk -v file="$file" '
  1374.                 gsub(/(^[0-9]+ [[:xdigit:]:]+ | \(.*\).*$)/,
  1375.                     "") && $0 == file { exit found++ }
  1376.                 END { exit !found }
  1377.             ' && continue
  1378.             ssh-add "$file" || continue
  1379.             loaded_new=1
  1380.             show="$show${show:+|}$suffix"
  1381.         done
  1382.     else
  1383.         for file in /mnt/keys/id_rsa.*; do
  1384.             [ -e "$file" ] || continue
  1385.             [ "$file" != "${file%.[Pp][Uu][Bb]}" ] && continue
  1386.             ssh-add -l | awk -v file="$file" '
  1387.                 gsub(/(^[0-9]+ [[:xdigit:]:]+ | \(.*\).*$)/,
  1388.                     "") && $0 == file { exit found++ }
  1389.                 END { exit !found }
  1390.             ' && continue
  1391.             ssh-add "$file" || continue
  1392.             loaded_new=1
  1393.             show="$show${show:+|}${file#/mnt/keys/id_rsa.}"
  1394.         done
  1395.     fi
  1396.     [ "$close" ] && closekey ${verbose:+-v} ${eject:+-e}
  1397.     [ "$loaded_new" ] && ssh-add -l |
  1398.         colorize -c 36 "/mnt/keys/id_rsa\\.($show)([[:space:]]|$)"
  1399. }
  1400.  
  1401. # unloadkeys [OPTIONS] [key ...]
  1402. #
  1403. # Unload my SSH private keys from my F.o thumb. The `key' argument is to the
  1404. # SSH private keyfile's suffix; in example, "sf" for "id_rsa.sf" or "f.o" for
  1405. # "id_rsa.f.o" or "gh" for "id_rsa.gh".
  1406. #
  1407. # For example, to unload the Sourceforge.net key, F.o key, and Github key:
  1408. #   unloadkeys sf f.o gh
  1409. #
  1410. # OPTIONS:
  1411. #   -a           Unload all keys.
  1412. #   -c           Close USB media after unloading keys.
  1413. #   -e           Close and eject USB media after unloading keys.
  1414. #   -h           Print this text to stderr and return.
  1415. #   -v           Print verbose debugging information.
  1416. #
  1417. # NB: Requires closekey() colorize() eprintf() openkey() quietly()
  1418. #     -- from this file
  1419. # NB: Requires awk(1) ps(1) ssh-add(1) -- from base system
  1420. #
  1421. quietly unalias unloadkeys
  1422. unloadkeys()
  1423. {
  1424.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  1425.     local OPTIND=1 OPTARG flag all= close= eject= verbose=
  1426.     while getopts acehv flag; do
  1427.         case "$flag" in
  1428.         a) all=1 ;;
  1429.         c) close=1 ;;
  1430.         e) close=1 eject=1 ;;
  1431.         v) verbose=1 ;;
  1432.         *) local optfmt="\t%-12s %s\n"
  1433.            eprintf "Usage: $FUNCNAME [OPTIONS] [key ...]\n"
  1434.            eprintf "OPTIONS:\n"
  1435.            eprintf "$optfmt" "-a" "Unload all keys."
  1436.            eprintf "$optfmt" "-c" \
  1437.                    "Close USB media after loading keys."
  1438.            eprintf "$optfmt" "-e" \
  1439.                    "Close and eject USB media after loading keys."
  1440.            eprintf "$optfmt" "-h" \
  1441.                    "Print this text to stderr and return."
  1442.            eprintf "$optfmt" "-v" \
  1443.                    "Print verbose debugging information."
  1444.            return ${FAILURE:-1}
  1445.         esac
  1446.     done
  1447.     shift $(( $OPTIND - 1 ))
  1448.     local suffix file show= unload_required=
  1449.     if [ "$all" ]; then
  1450.         unload_required=1
  1451.         shift $#
  1452.     fi
  1453.     for suffix in "$@"; do
  1454.         file="/mnt/keys/id_rsa.$suffix"
  1455.         ssh-add -l | awk -v file="$file" '
  1456.             gsub(/(^[0-9]+ [[:xdigit:]:]+ | \(.*\).*$)/, "") &&
  1457.                 $0 == file { exit found++ }
  1458.             END { exit !found }
  1459.         ' || continue # not loaded
  1460.         show="$show${show:+|}$suffix"
  1461.         unload_required=1
  1462.         break
  1463.     done
  1464.     ssh-add -l | colorize -c 31 "/mnt/keys/id_rsa\\.($show)([[:space:]]|$)"
  1465.     [ "$unload_required" ] || return ${SUCCESS:-0}
  1466.     openkey ${verbose:+-v} || return ${FAILURE:-1}
  1467.     [ "$verbose" ] && ssh-add -l
  1468.     if [ "$all" ]; then
  1469.         ssh-add -D
  1470.     else
  1471.         for suffix in "$@"; do
  1472.             file="/mnt/keys/id_rsa.$suffix"
  1473.             [ -f "$file" ] || continue
  1474.             ssh-add -l | awk -v file="$file" '
  1475.                 gsub(/(^[0-9]+ [[:xdigit:]:]+ | \(.*\).*$)/,
  1476.                     "") && $0 == file { exit found++ }
  1477.                 END { exit !found }
  1478.             ' || continue
  1479.             ssh-add -d "$file"
  1480.         done
  1481.     fi
  1482.     [ "$close" ] && closekey ${verbose:+-v} ${eject:+-e}
  1483.     [ "$all" ] || ssh-add -l |
  1484.         colorize -c 36 "/mnt/keys/id_rsa\\.($show)([[:space:]]|$)"
  1485. }
  1486.  
  1487. # zless [OPTIONS] $file ...
  1488. #
  1489. # Allow quick paging of gzip-compressed files. Any options passed in-addition
  1490. # to the filename pertain to zcat(1).
  1491. #
  1492. # NOTE: Some systems provide zless as an actual utility. For those systems,
  1493. # we'll fallback to the actual utility opposed to this function.
  1494. #
  1495. if ! have zless; then
  1496.     zless()
  1497.     {
  1498.         zcat "$@" | less
  1499.     }
  1500. fi
  1501.  
  1502. # zlog $logfile [$pattern]
  1503. #
  1504. # A general purpose log searching function. Given $log base pathname, this
  1505. # function will search for all occurrences of $pattern in $logfile and
  1506. # $logfile.N.gz [FreeBSD] or $logfile.N [Linux] (preserving reverse-chrono-
  1507. # logical order, searching oldest logfiles first).
  1508. #
  1509. # If $pattern is NULL or omitted, all lines are returned.
  1510. #
  1511. # NOTE: $pattern is an awk regular expression.
  1512. #
  1513. quietly unalias zlog
  1514. zlog()
  1515. {
  1516.     local logfile="$1" pattern="$2"
  1517.     local logfiles="$logfile" gzlogfiles="" n=0
  1518.     local sudo= needsudo=
  1519.  
  1520.     #
  1521.     # Check for two conditions where we would need sudo
  1522.     # 1. If the log file is not readable
  1523.     # 2. If the parent directory is not readable/traversable
  1524.     #
  1525.     [ -r "$logfile" ] || needsudo=1
  1526.     case "$logfile" in
  1527.     */*) [ -r "${logfile%/*}" ] || needsudo=1;;
  1528.     esac
  1529.  
  1530.     if [ "$needsudo" ]; then
  1531.         if [ "$UNAME_s" = "Linux" -a "$Linux" = "Ubuntu" ]; then
  1532.             sudo=sudo
  1533.         else
  1534.             if have sr; then
  1535.                 sudo=sr
  1536.             elif have sudo; then
  1537.                 sudo=sudo
  1538.             fi
  1539.         fi
  1540.     fi
  1541.  
  1542.     case "$UNAME_s" in
  1543.     FreeBSD)
  1544.         #
  1545.         # FreeBSD rotates logs in the following fashion:
  1546.         #
  1547.         # FILENAME        DESCRIPTION
  1548.         # logfile         current log file
  1549.         # logfile.0.gz    most-recently rotated log file
  1550.         # logfile.1.gz    second-most recently rotated log file
  1551.         #
  1552.         local n=0
  1553.         if [ "$needsudo" ]; then
  1554.             while $sudo [ -f "$logfile.$n.gz" ]; do
  1555.                 gzlogfiles="$logfile.$n.gz $gzlogfiles"
  1556.                 n=$(( $n + 1 ))
  1557.             done
  1558.             if [ ! "$gzlogfiles" ]; then
  1559.                 n=0
  1560.                 while $sudo [ -f "$logfile.$n.bz2" ]; do
  1561.                     gzlogfiles="$logfile.$n.bz2 $gzlogfiles"
  1562.                     n=$(( $n + 1 ))
  1563.                 done
  1564.             fi
  1565.         else
  1566.             while [ -f "$logfile.$n.gz" ]; do
  1567.                 [ -r "$logfile.$n.gz" ] || needsudo=1
  1568.                 gzlogfiles="$logfile.$n.gz $gzlogfiles"
  1569.                 n=$(( $n + 1 ))
  1570.             done
  1571.             if [ ! "$gzlogfiles" ]; then
  1572.                 n=0
  1573.                 while $sudo [ -f "$logfile.$n.bz2" ]; do
  1574.                     gzlogfiles="$logfile.$n.bz2 $gzlogfiles"
  1575.                     n=$(( $n + 1 ))
  1576.                 done
  1577.             fi
  1578.         fi
  1579.         ;;
  1580.     Linux)
  1581.         #
  1582.         # Linux rotates logs in the following fashion:
  1583.         #
  1584.         # FILENAME     DESCRIPTION
  1585.         # logfile      current log file
  1586.         # logfile.1    most-recently rotated log file
  1587.         # logfile.2    second-most recently rotated log file
  1588.         #
  1589.         local n=1
  1590.         if [ "$needsudo" ]; then
  1591.             while $sudo [ -f "$logfile.$n" ]; do
  1592.                 logfiles="$logfile.$n $logfiles"
  1593.                 n=$(( $n + 1 ))
  1594.             done
  1595.         else
  1596.             while [ -f "$logfile.$n" ]; do
  1597.                 [ -r "$logfile.$n" ] || needsudo=1
  1598.                 logfiles="$logfile.$n $logfiles"
  1599.                 n=$(( $n + 1 ))
  1600.             done
  1601.         fi
  1602.         ;;
  1603.     esac
  1604.  
  1605.     if [ "$gzlogfiles" ]; then
  1606.         $sudo zcat $gzlogfiles \
  1607.             | sh -c "cat; cat $logfiles" \
  1608.             | awk "/$pattern/ {print}"
  1609.     else
  1610.         $sudo cat $logfiles \
  1611.             | awk "/$pattern/ {print}"
  1612.     fi
  1613. }
  1614.  
  1615. # zlog_summary $logfile [-d1,2,3] [$pattern]
  1616. #
  1617. # A wrapper around the zlog general purpose log searching function designed to
  1618. # provide a brief summary containing the following information:
  1619. #   - The first line matching $pattern
  1620. #   - The timestamp of the first occurrence
  1621. #   - The timestamp of the last occurrence
  1622. #   - How many occurrences were found
  1623. #     NOTE: Also counts "last message repeated N times" entries
  1624. #
  1625. # NOTE: If $pattern is NULL or omitted, the first/oldest log-entry is printed.
  1626. #       In addition, the timestamps in the summary will instead be the first
  1627. #       (oldest) and last (newest) entry, respectively. This serves as a sort
  1628. #       of brief look at the date-range spanning the individual log files.
  1629. #
  1630. # NOTE: $pattern is an awk regular expression.
  1631. #
  1632. # By default, it is assumed that the date/time fields to be displayed are the
  1633. # first, second, and third fields of each log entry, separated by whitespace.
  1634. # For example, /var/log/messages has the following first three fields:
  1635. #
  1636. #   Jun  5 04:02:10
  1637. #
  1638. # However, not all logfiles display date/time entries in the above manner.
  1639. # Therefore, the following options can be passed to customize which line-fields
  1640. # (and how many) are displayed for the date/time:
  1641. #
  1642. # For example, the Apache error_log displays the date/time in five pieces:
  1643. #
  1644. #   [Sun May 31 04:02:14 2009]
  1645. #
  1646. # So to display the proper values for date-range outputs when parsing the
  1647. # Apache error_log, you should pass the following parameters:
  1648. #
  1649. #   -d1,2,3,4,5
  1650. #
  1651. # You can optionally pass `-dNF' to print the whole line.
  1652. #
  1653. # NB: Requires zlog() -- from this file
  1654. # NB: Requires awk(1) -- from base system
  1655. #
  1656. quietly unalias zlog_summary
  1657. zlog_summary()
  1658. {
  1659.     local logfile="$1"
  1660.     local datetime="1,2,3"
  1661.  
  1662.     shift 1 # logfile
  1663.  
  1664.     local OPTIND flag
  1665.     while getopts d: flag; do
  1666.         case "$flag" in
  1667.         d) datetime="$OPTARG";;
  1668.         esac
  1669.     done
  1670.     shift $(( $OPTIND - 1 ))
  1671.  
  1672.     local pattern="$1"
  1673.     zlog "$logfile" |
  1674.         awk -v pattern="$pattern" -v datetime="$datetime" '
  1675.     BEGIN {
  1676.         hr = sprintf("%-60s", "")
  1677.         gsub(" ", "-", hr)
  1678.         count = init = crepeat = 0
  1679.         last = ""
  1680.         ndt = split(datetime, dt, /,/)
  1681.     }
  1682.     {
  1683.         if ($0 !~ pattern && !crepeat) next
  1684.         else if (crepeat)
  1685.         {
  1686.             if ($0 !~ /repeated/) {
  1687.                 crepeat = 0
  1688.                 next
  1689.             }
  1690.             count += $8
  1691.             if (length(datetime) <= 0) next
  1692.             last = ""
  1693.             for (n = 1; n <= ndt; n++) last = sprintf("%s%s%s",
  1694.                 last, (length(last) > 0 ? " " : ""), $dt[n])
  1695.             next
  1696.         }
  1697.         count++
  1698.         if (!init)
  1699.         {
  1700.             print hr
  1701.             print $0
  1702.             print hr
  1703.             printf(" 1st:")
  1704.             if (length(datetime) > 0)
  1705.                 for (n = 1; n <= ndt; n++)
  1706.                     printf(" %s", $dt[n])
  1707.             printf("\n")
  1708.             init = 1
  1709.         }
  1710.         crepeat = 1
  1711.         if (length(datetime) > 0) {
  1712.             last = ""
  1713.             for (n = 1; n <= ndt; n++) last = sprintf("%s%s%s",
  1714.                 last, (length(last) > 0 ? " " : ""), $dt[n])
  1715.         }
  1716.     }
  1717.     END {
  1718.         print "Last: " last
  1719.         print "Total Occurrences: " count
  1720.         print hr
  1721.     }
  1722.     ' # END-QUOTE
  1723. }
  1724.  
  1725. # zlog_usage [$FUNCNAME]
  1726. #
  1727. # Print usage statement for zlog_wrapper family of functions.
  1728. #
  1729. # NB: Requires eprintf() -- from this file
  1730. #
  1731. quietly unalias zlog_usage
  1732. zlog_usage()
  1733. {
  1734.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  1735.     local func="${1:-$FUNCNAME}"
  1736.     local optfmt='\t%-12s %s\n'
  1737.  
  1738.     eprintf "Usage: %s [OPTIONS] [PATTERN]\n" "$func"
  1739.     eprintf "Arguments:\n"
  1740.     eprintf "$optfmt" "PATTERN" \
  1741.             "Awk(1) regular expression pattern to search logfile for."
  1742.  
  1743.     eprintf "\n"
  1744.  
  1745.     eprintf "Options:\n"
  1746.     eprintf "$optfmt" "-h" \
  1747.             "Print this usage statement and exit."
  1748.     eprintf "$optfmt" "-v" \
  1749.             "Verbose. Show individual matching lines."
  1750.     eprintf "$optfmt" "-d1,2,3" \
  1751.             "Comma-separated list of field numbers to display as the"
  1752.     eprintf "$optfmt" "" \
  1753.             "date/time when providing summary output (ignored if \`-v'"
  1754.     eprintf "$optfmt" "" \
  1755.             "is passed). Default is 1,2,3. A value of \`NF' prints the"
  1756.     eprintf "$optfmt" "" \
  1757.             "entire line."
  1758.  
  1759.     eprintf "\n"
  1760.  
  1761.     return ${FAILURE:-1}
  1762. }
  1763.  
  1764. # zlog_wrapper $FUNCNAME $logfile [OPTIONS] [$pattern]
  1765. #
  1766. # A wrapper for the zlog/zlog_summary functions.
  1767. #
  1768. # NB: Requires zlog() zlog_summary() zlog_usage() -- from this file
  1769. #
  1770. quietly unalias zlog_wrapper
  1771. zlog_wrapper()
  1772. {
  1773.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  1774.     local func="${1:-$FUNCNAME}"
  1775.     local logfile="$2"
  1776.     local datetime=
  1777.     local verbose=
  1778.  
  1779.     shift 2 # func/logfile
  1780.  
  1781.     local OPTIND flag
  1782.     while getopts d:hv flag; do
  1783.         case "$flag" in
  1784.         d) datetime="$OPTARG";;
  1785.         v) verbose=1;;
  1786.         h|\?)
  1787.             zlog_usage "$func"
  1788.             return ${FAILURE:-1}
  1789.             ;;
  1790.         esac
  1791.     done
  1792.     shift $(( $OPTIND - 1 ))
  1793.  
  1794.     if [ "$verbose" ]; then
  1795.         zlog "$logfile" "$@"
  1796.     else
  1797.         zlog_summary "$logfile" ${datetime:+-d"$datetime"} "$@"
  1798.     fi
  1799. }
  1800.  
  1801. # tlog $log [OPTIONS]
  1802. #
  1803. # A general purpose wrapper to tail(1) that checks if the destination logfile
  1804. # is readable by you. If the file is readable by your effective UID, this
  1805. # command is equivalent to execute "tail -F [options] $log", otherwise one of
  1806. # sudo(8) or sr(8) is used to provide root-privileges to read the logfile.
  1807. #
  1808. # NB: Requires eval2() have() -- from this file
  1809. # NB: Requires tail(1) -- from base system
  1810. #
  1811. quietly unalias tlog
  1812. tlog()
  1813. {
  1814.     local logfile="$1"
  1815.     local sudo= needsudo=
  1816.     shift 1 # logfile
  1817.  
  1818.     #
  1819.     # Check for two conditions where we would need sudo
  1820.     # 1. If the log file is not readable
  1821.     # 2. If the parent directory is not readable/traversable
  1822.     #
  1823.     [ -r "$logfile" ] || needsudo=1
  1824.     case "$logfile" in
  1825.     */*) [ -r "${logfile%/*}" ] || needsudo=1;;
  1826.     esac
  1827.  
  1828.     if [ "$needsudo" ]; then
  1829.         if have sr; then
  1830.             sudo=sr
  1831.         elif have sudo; then
  1832.             sudo=sudo
  1833.         fi
  1834.     fi
  1835.  
  1836.     eval2 ${needsudo:+$sudo} tail -F "$@" "$logfile"
  1837. }
  1838.  
  1839. # dialog_menutag
  1840. #
  1841. # Obtain the menutag chosen by the user from the most recently displayed
  1842. # dialog(1) menu and clean up any temporary files.
  1843. #
  1844. # NB: Requires quietly() -- from this file
  1845. # NB: Requires $DIALOG_TMPDIR -- from this file
  1846. # NB: Requires rm(1) -- from base system
  1847. #
  1848. quietly unalias dialog_menutag
  1849. dialog_menutag()
  1850. {
  1851.     local tmpfile="$DIALOG_TMPDIR/dialog.menu.$$"
  1852.  
  1853.     [ -f "$tmpfile" ] || return ${FAILURE:-1}
  1854.  
  1855.     cat "$tmpfile" 2> /dev/null
  1856.     quietly rm -f "$tmpfile"
  1857.  
  1858.     return ${SUCCESS:-0}
  1859. }
  1860.  
  1861. # dialog_menutag2item $tag_chosen $tag1 $item1 $tag2 $item2 ...
  1862. #
  1863. # To use the `--menu' option of dialog(1) you must pass an ordered list of
  1864. # tag/item pairs on the command-line. When the user selects a menu option the
  1865. # tag for that item is printed to stderr.
  1866. #
  1867. # This function allows you to dereference the tag chosen by the user back into
  1868. # the item associated with said tag.
  1869. #
  1870. # Pass the tag chosen by the user as the first argument, followed by the
  1871. # ordered list of tag/item pairs (HINT: use the same tag/item list as was
  1872. # passed to dialog(1) for consistency).
  1873. #
  1874. # If the tag cannot be found, NULL is returned.
  1875. #
  1876. quietly unalias dialog_menutag2item
  1877. dialog_menutag2item()
  1878. {
  1879.     local tag="$1" tagn item
  1880.     shift 1
  1881.  
  1882.     while [ $# -gt 0 ]; do
  1883.         tagn="$1"
  1884.         item="$2"
  1885.         shift 2
  1886.  
  1887.         if [ "$tag" = "$tagn" ]; then
  1888.             echo "$item"
  1889.             return ${SUCCESS:-0}
  1890.         fi
  1891.     done
  1892.     return ${FAILURE:-1}
  1893. }
  1894.  
  1895. # dialog_menutag2help $tag_chosen $tag1 $item1 $help1 \
  1896. #                                   $tag2 $item2 $help2
  1897. #
  1898. # To use the `--menu' option of dialog(1) with the `--item-help' option, you
  1899. # must pass an ordered list of tag/item/help triplets on the command-line. When
  1900. # the user selects a menu option the tag for that item is printed to stderr.
  1901. #
  1902. # This function allows you to dereference the tag chosen by the user back into
  1903. # the help associated with said tag (item is discarded/ignored).
  1904. #
  1905. # Pass the tag chosen by the user as the first argument, followed by the
  1906. # ordered list of tag/item/help triplets (HINT: use the same tag/item/help list
  1907. # as was passed to dialog(1) for consistency).
  1908. #
  1909. # If the tag cannot be found, NULL is returned.
  1910. #
  1911. dialog_menutag2help()
  1912. {
  1913.     local tag="$1" tagn help
  1914.     shift 1 # tag
  1915.  
  1916.     while [ $# -gt 0 ]; do
  1917.         tagn="$1"
  1918.         help="$3"
  1919.         shift 3 # tagn/item/help
  1920.  
  1921.         if [ "$tag" = "$tagn" ]; then
  1922.             echo "$help"
  1923.             return ${SUCCESS:-0}
  1924.         fi
  1925.     done
  1926.     return ${FAILURE:-1}
  1927. }
  1928.  
  1929. # cvspicker
  1930. #
  1931. # Display a menu of CVS servers to which you have access to. Selecting an entry
  1932. # configures your environment for access to said CVS server.
  1933. #
  1934. # NB: Requires dialog_menutag() dialog_menutag2help() -- from this file
  1935. # NB: Requires $CVSPICKER_EXPORTS $DIALOG_MENU_TAGS -- from this file
  1936. # NB: Requires awk(1) dialog(1) -- from base system
  1937. #
  1938. quietly unalias cvspicker
  1939. cvspicker()
  1940. {
  1941.     if ! have dialog; then
  1942.         echo "$CVSPICKER_EXPORTS"
  1943.         return ${FAILURE:-1}
  1944.     fi
  1945.     local menu_list
  1946.     menu_list=$(
  1947.         echo "$CVSPICKER_EXPORTS" |
  1948.         awk -v tags="$DIALOG_MENU_TAGS" '
  1949.         !/^[[:space:]]*(#|$)/ {
  1950.             if (++tagn > length(tags)) exit
  1951.             sub(/^[[:space:]]*/, "")
  1952.             sub(/[[:space:]]*$/, "")
  1953.             printf "'\''%s'\'' '\''%s'\''\n",
  1954.                    substr(tags, tagn, 1), $0
  1955.         }'
  1956.     )
  1957.  
  1958.     eval dialog \
  1959.         --clear --title "'CVSPicker'" \
  1960.         --menu "'Pick a CVS_RSH/CVSROOT pair:'" 17 55 9 \
  1961.         $menu_list \
  1962.         2> "$DIALOG_TMPDIR/dialog.menu.$$"
  1963.     local retval=$?
  1964.  
  1965.     # Return if "Cancel" was chosen (-1) or ESC was pressed (255)
  1966.     [ $retval -eq ${SUCCESS:-0} ] || return $retval
  1967.  
  1968.     local tag="$( dialog_menutag )"
  1969.     eval2 export $( eval dialog_menutag2item "'$tag'" $menu_list )
  1970. }
  1971.  
  1972. # hgrep ...
  1973. #
  1974. # Use in-place of grep(1) whenever you want to preserve the first line of
  1975. # output (often the header when viewing output from ps(1), lsof(8), df(1),
  1976. # netstat(8), arp(8), lsmod(8), route(8), free(1), and many many others).
  1977. #
  1978. # NB: Requires grep(1) head(1) -- from base system
  1979. #
  1980. quietly unalias hgrep
  1981. hgrep()
  1982. {
  1983.     local timeout=0
  1984.  
  1985.     [ "$BASH_VERSION" ] && timeout=1
  1986.  
  1987.     if [ $# -gt 1 ]; then
  1988.         local arg
  1989.         for arg in "$@"; do
  1990.             [ -f "$arg" ] && head -1 "$arg" && break
  1991.         done
  1992.     else
  1993.     (
  1994.         IFS=;
  1995.         read -r -t $timeout LINE
  1996.         printf "\e[1m%s\e[0m\n" "$LINE"
  1997.     )
  1998.     fi
  1999.  
  2000.     grep "$@"
  2001. }
  2002.  
  2003. # myshopts [OPTIONS]
  2004. #
  2005. # Configures/Displays your desired shopt(1) options. The following environment
  2006. # variables should be configured to enable/disable desired options:
  2007. #
  2008. # Options:
  2009. #   -h   Print this usage statement and exit.
  2010. #   -v   Verbose. Print the state of desired options regardless of
  2011. #        whether their states have changed or not. If passed twice,
  2012. #        (e.g., `-vv' or `-v -v') the values of each variable will
  2013. #        be printed while processing each for options.
  2014. #
  2015. # Environment:
  2016. #   BASH2345_SHOPT_ENABLE
  2017. #   BASH2345_SHOPT_DISABLE
  2018. #       Each line represents a single option, with the first word on
  2019. #       each line representing the option and the remainder of the
  2020. #       line being comments you make up. A line can also be nothing
  2021. #       but a comment if it begins with the pound-sign (#), after any
  2022. #       length of whitespace.
  2023. #
  2024. #       For each option, the option will either be disabled if it is
  2025. #       added to the "*_DISABLE" variable or enabled if added to the
  2026. #       "*_ENABLE" variable.
  2027. #
  2028. #       If a variable is changed from its current state and you are
  2029. #       logged in interactively, a line showing the current state of
  2030. #       each option will be printed.
  2031. #
  2032. #   BASH45_SHOPT_ENABLE
  2033. #   BASH45_SHOPT_ENABLE
  2034. #       These variables are like the above but are for options that
  2035. #       are specific to version 4.x of bash(1). These options will
  2036. #       not be enabled/disabled unless BASH_VERSION is 4.*, prevent-
  2037. #       ing errors about unknown options in older versions of bash.
  2038. #
  2039. # NB: Requires eprintf() myshopts_usage() -- from this file
  2040. # NB: Requires awk(1) -- from base system
  2041. #
  2042. quietly unalias myshopts_usage
  2043. myshopts_usage()
  2044. {
  2045.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  2046.     local optfmt='\t%-4s %s\n'
  2047.     local envfmt='\t%s\t%s\n'
  2048.  
  2049.     eprintf "Usage: %s [OPTIONS]\n" "$FUNCNAME"
  2050.     eprintf "Options:\n"
  2051.     eprintf "$optfmt" "-h" \
  2052.             "Print this usage statement and exit."
  2053.     eprintf "$optfmt" "-v" \
  2054.             "Verbose. Print the state of desired options regardless of"
  2055.     eprintf "$optfmt" "" \
  2056.             "whether their states have changed or not. If passed twice,"
  2057.     eprintf "$optfmt" "" \
  2058.             "(e.g., \`-vv' or \`-v -v') the values of each variable will"
  2059.     eprintf "$optfmt" "" \
  2060.             "be printed while processing each for options."
  2061.  
  2062.     eprintf "\n"
  2063.  
  2064.     eprintf "Environment:\n"
  2065.     eprintf "$envfmt" "BASH2345_SHOPT_ENABLE" ""
  2066.     eprintf "$envfmt" "BASH2345_SHOPT_DISABLE" ""
  2067.     eprintf "$envfmt" "" \
  2068.             "Each line represents a single option, with the first word on"
  2069.     eprintf "$envfmt" "" \
  2070.             "each line representing the option and the remainder of the"
  2071.     eprintf "$envfmt" "" \
  2072.             "line being comments you make up. A line can also be nothing"
  2073.     eprintf "$envfmt" "" \
  2074.             "but a comment if it begins with the pound-sign (#), after any"
  2075.     eprintf "$envfmt" "" \
  2076.             "length of whitespace."
  2077.     eprintf "\n"
  2078.     eprintf "$envfmt" "" \
  2079.             "For each option, the option will either be disabled if it is"
  2080.     eprintf "$envfmt" "" \
  2081.             'added to the "*_DISABLE" variable or enabled if added to the'
  2082.     eprintf "$envfmt" "" \
  2083.             '"*_ENABLE" variable.'
  2084.     eprintf "\n"
  2085.     eprintf "$envfmt" "" \
  2086.             "If a variable is changed from its current state and you are"
  2087.     eprintf "$envfmt" "" \
  2088.             "logged in interactively, a line showing the current state of"
  2089.     eprintf "$envfmt" "" \
  2090.             "each option will be printed."
  2091.     eprintf "\n"
  2092.     eprintf "$envfmt" "BASH45_SHOPT_ENABLE" ""
  2093.     eprintf "$envfmt" "BASH45_SHOPT_DISABLE" ""
  2094.     eprintf "$envfmt" "" \
  2095.             "These variables are like the above but are for options that"
  2096.     eprintf "$envfmt" "" \
  2097.             "are specific to version 4.x of bash(1). These options will"
  2098.     eprintf "$envfmt" "" \
  2099.             "not be enabled/disabled unless BASH_VERSION is 4.*, prevent-"
  2100.     eprintf "$envfmt" "" \
  2101.             "ing errors about unknown options in older versions of bash."
  2102.  
  2103.     return ${FAILURE:-1}
  2104. }
  2105. quietly unalias myshopts
  2106. myshopts()
  2107. {
  2108.     local verbose=
  2109.     local OPTIND flag
  2110.     while getopts hv flag; do
  2111.         case "$flag" in
  2112.         v) verbose=$(( ${verbose:-0} + 1 ));;
  2113.         h|\?) myshopts_usage
  2114.               return ${FAILURE:-1} ;;
  2115.         esac
  2116.     done
  2117.     shift $(( $OPTIND - 1 ))
  2118.  
  2119.     #
  2120.     # Process user-defined environment variables into our options-lists.
  2121.     #
  2122.     local shopt_enable_list="" shopt_disable_list="" options_list var
  2123.     case "$BASH_VERSION" in
  2124.     2.*|3.*|4.*|5.*)
  2125.         #
  2126.         # Bash version 2, 3, or 4 shopt(1) variables to be ENABLED
  2127.         #
  2128.         options_list=$( echo "$BASH2345_SHOPT_ENABLE" |
  2129.                             awk '!/^[[:space:]]*($|#)/{print $1}' )
  2130.         if [ "$options_list" ]; then
  2131.             [ ${verbose:-0} -ge 2 ] &&
  2132.                 eprintf "BASH2345_SHOPT_ENABLE='%s'\n" \
  2133.                         "$BASH2345_SHOPT_ENABLE"
  2134.             for var in $options_list; do
  2135.                 shopt_enable_list="$shopt_enable_list $var"
  2136.             done
  2137.         fi
  2138.  
  2139.         #
  2140.         # Bash version 2, 3, or 4 shopt(1) variables to be DISABLED
  2141.         #
  2142.         options_list=$( echo "$BASH2345_SHOPT_DISABLE" |
  2143.                             awk '!/^[[:space:]]*(#|$)/{print $1}' )
  2144.         if [ "$options_list" ]; then
  2145.             [ ${verbose:-0} -ge 2 ] &&
  2146.                 eprintf "BASH2345_SHOPT_DISABLE='%s'\n" \
  2147.                         "$BASH2345_SHOPT_DISABLE"
  2148.             for var in $options_list; do
  2149.                 shopt_disable_list="$shopt_disable_list $var"
  2150.             done
  2151.         fi
  2152.     esac
  2153.     case "$BASH_VERSION" in
  2154.     4.*|5.*)
  2155.         #
  2156.         # Bash version 4 shopt(1) variables to be ENABLED
  2157.         #
  2158.         options_list=$( echo "$BASH45_SHOPT_ENABLE" |
  2159.                             awk '!/^[[:space:]]*($|#)/{print $1}' )
  2160.         if [ "$options_list" ]; then
  2161.             [ ${verbose:-0} -ge 2 ] &&
  2162.                 eprintf "BASH45_SHOPT_ENABLE='%s'\n" \
  2163.                         "$BASH45_SHOPT_ENABLE"
  2164.             for var in $options_list; do
  2165.                 shopt_enable_list="$shopt_enable_list $var"
  2166.             done
  2167.         fi
  2168.  
  2169.         #
  2170.         # Bash version 4 shopt(1) variables to be DISABLED
  2171.         #
  2172.         options_list=$( echo "$BASH45_SHOPT_DISABLE" |
  2173.                             awk '!/^[[:space:]]*($|#)/{print $1}' )
  2174.         if [ "$options_list" ]; then
  2175.             [ ${verbose:-0} -ge 2 ] &&
  2176.                 eprintf "BASH45_SHOPT_DISABLE='%s'\n" \
  2177.                         "$BASH45_SHOPT_DISABLE"
  2178.             for var in $options_list; do
  2179.                 shopt_disable_list="$shopt_disable_list $var"
  2180.             done
  2181.         fi
  2182.     esac
  2183.  
  2184.     #
  2185.     # Toggle the values of variables controlling optional shell behavior.
  2186.     # NOTE: These will be implicitly ignored for non-interactive sessions
  2187.     # NOTE: Capture the current value for later before changing the value
  2188.     #
  2189.     for var in $shopt_enable_list; do
  2190.         shopt -q $var
  2191.         eval local ${var}_before=$?
  2192.         shopt -s $var
  2193.     done
  2194.     for var in $shopt_disable_list; do
  2195.         shopt -q $var
  2196.         eval local ${var}_before=$?
  2197.         shopt -u $var
  2198.     done
  2199.  
  2200.     #
  2201.     # If we're running interactively (or verbosity is requested), show
  2202.     # which shell options have been enabled/disabled.
  2203.     #
  2204.     if [ "$interactive" -o "$verbose" ]; then
  2205.         for var in $shopt_enable_list $shopt_disable_list; do
  2206.             if [ "$verbose" ]; then
  2207.                 if [ "$LOLCAT" ]; then
  2208.                     shopt $var | $LOLCAT
  2209.                 else
  2210.                     shopt $var
  2211.                 fi
  2212.             else
  2213.                 # Report on values that changed state
  2214.                 shopt -q $var
  2215.                 if ! eval [ \$${var}_before -eq $? ]; then
  2216.                     if [ "$LOLCAT" ]; then
  2217.                         shopt $var | $LOLCAT
  2218.                     else
  2219.                         shopt $var
  2220.                     fi
  2221.                 fi
  2222.             fi
  2223.         done
  2224.     fi
  2225. }
  2226.  
  2227. #
  2228. # CVS functions
  2229. #
  2230. # NB: Requires cvs(1) file(1) find(1) xargs(1) -- from base system
  2231. #
  2232. quietly unalias cvs_admin_binaries
  2233. cvs_admin_binaries()
  2234. {
  2235.     local recursive= undo=
  2236.     local gnu_xargs=
  2237.  
  2238.     case "$UNAME_s" in
  2239.     Linux|CYGWIN*) gnu_xargs=1;;
  2240.     esac
  2241.  
  2242.     local OPTIND flag
  2243.     while getopts ru flag; do
  2244.         case "$flag" in
  2245.         r) recursive=1;;
  2246.         u) undo=1;;
  2247.         esac
  2248.     done
  2249.     shift $(( $OPTIND - 1 ))
  2250.  
  2251.     ( if [ "$recursive" ]; then
  2252.         find . -type f ! -path '*/CVS/*'
  2253.       else
  2254.         find . -mindepth 1 -maxdepth 1 -type f
  2255.       fi
  2256.     ) | (
  2257.         while read file; do
  2258.             filetype=$( file -b "$file" )
  2259.             case "$filetype" in
  2260.             *ICC*|*ELF*|*data*|*font*|*icon*|*image*|*archive*)
  2261.                 echo "$file";;
  2262.             esac
  2263.         done
  2264.     ) | (
  2265.         if [ "$undo" ]; then
  2266.             xargs ${gnu_xargs:+-r} cvs admin -kkv
  2267.         else
  2268.             xargs ${gnu_xargs:+-r} cvs admin -ko
  2269.         fi
  2270.     )
  2271. }
  2272. alias cvs_admin_binaries_undo='cvs_admin_binaries -u'
  2273. quietly unalias cvs_add_recursive
  2274. cvs_add_recursive()
  2275. {
  2276.     local gnu_xargs=
  2277.  
  2278.     case "$UNAME_s" in
  2279.     Linux|CYGWIN*) gnu_xargs=1;;
  2280.     esac
  2281.  
  2282.     ( [ $# -gt 0 ] || set -- .
  2283.       while [ $# -gt 0 ]; do
  2284.         find "$1" -type d
  2285.         shift 1
  2286.       done
  2287.     ) | (
  2288.         while read dir; do
  2289.             # Skip invalid directories
  2290.             case "$dir" in
  2291.             .) continue;;
  2292.             *) [ "${dir##*/}" != "CVS" ] || continue;;
  2293.             esac
  2294.  
  2295.             # Add the directory
  2296.             cvs add "$dir"
  2297.  
  2298.             # Add regular files from this directory
  2299.             find "$dir" -type f -mindepth 1 -maxdepth 1 |
  2300.                 xargs ${gnu_xargs:+-r} cvs add
  2301.         done
  2302.     )
  2303. }
  2304. quietly unalias cvs_rm_recursive
  2305. cvs_rm_recursive()
  2306. {
  2307.     local gnu_xargs=
  2308.  
  2309.     case "$UNAME_s" in
  2310.     Linux|CYGWIN*) gnu_xargs=1;;
  2311.     esac
  2312.  
  2313.     ( [ $# -gt 0 ] || set -- .
  2314.       while [ $# -gt 0 ]; do
  2315.         find "$1" -type d
  2316.         shift 1
  2317.       done
  2318.     ) | (
  2319.         while read dir; do
  2320.             # Skip invalid directories
  2321.             case "$dir" in
  2322.             .) continue;;
  2323.             *) [ "${dir##*/}" != "CVS" ] || continue;;
  2324.             esac
  2325.  
  2326.             # Remove regular files from this directory
  2327.             find "$dir" -type f -mindepth 1 -maxdepth 1 |
  2328.                 xargs ${gnu_xargs:+-r} cvs rm -f
  2329.         done
  2330.     )
  2331. }
  2332.  
  2333. # dirstack2d
  2334. #
  2335. # Create a series of $D# environment variables based on ${DIRSTACK[#]} array
  2336. # items -- for quick[er] access to directories in the stack.
  2337. #
  2338. # NB: Requires awk(1) -- from base system
  2339. #
  2340. quietly unalias dirstack2d
  2341. dirstack2d()
  2342. {
  2343.     # Unset current $D# variables
  2344.     unset $( set | command awk -F= '/^D[[:digit:]]+=/{print $1}' )
  2345.  
  2346.     #
  2347.     # Recreate $D# variables from $DIRSTACK array
  2348.     #
  2349.     local n=0
  2350.     while [ $n -lt ${#DIRSTACK[@]} ]; do
  2351.         eval D$n=\"\${DIRSTACK[$n]}\"
  2352.  
  2353.         # Expand leading ~ to $HOME
  2354.         case "${DIRSTACK[$n]}" in
  2355.         \~|\~/*)
  2356.             eval D$n=\"\${D$n\#?}\"
  2357.             eval D$n=\"\$HOME\$D$n\"
  2358.         esac
  2359.  
  2360.         n=$(( $n + 1 ))
  2361.     done
  2362. }
  2363.  
  2364. # dirstack_wrap builtin [options]
  2365. #
  2366. # Simple wrapper to execute dirstack2d after forking to some builtin.
  2367. #
  2368. # NB: Requires dirstack2d() -- from this file
  2369. #
  2370. quietly unalias dirstack_wrap
  2371. dirstack_wrap()
  2372. {
  2373.     local bi="$1"
  2374.     shift
  2375.     builtin $bi "$@"
  2376.     dirstack2d
  2377. }
  2378.  
  2379. #
  2380. # Dirstack wrapper aliases
  2381. # NB: Requires dirstack_wrap() -- from this file
  2382. #
  2383. alias pushd='dirstack_wrap pushd'
  2384. alias  popd='dirstack_wrap popd'
  2385. alias  dirs='dirstack_wrap dirs'
  2386. alias    cd='dirstack_wrap cd'
  2387.  
  2388. # colorize [-c ANSI] [-e ANSI] pattern
  2389. #
  2390. # Colorize text matching pattern with ANSI sequence (default is `31;1' for red-
  2391. # bold). Non-matching lines are printed as-is.
  2392. #
  2393. # NB: Requires awk(1) -- from base system
  2394. #
  2395. colorize()
  2396. {
  2397.     local OPTIND=1 OPTARG flag
  2398.     local ti=
  2399.     local te=
  2400.  
  2401.     while getopts c:e: flag; do
  2402.         case "$flag" in
  2403.         c) ti="$OPTARG" ;;
  2404.         e) te="$OPTARG" ;;
  2405.         esac
  2406.     done
  2407.     shift $(( $OPTIND - 1 ))
  2408.  
  2409.     awk -v ti="${ti:-31;1}" -v te="${te:-39;22}" -v pattern="$1" '
  2410.         gsub(pattern, "\033[" ti "m&\033[" te "m")||1
  2411.     ' # END-QUOTE
  2412. }
  2413.  
  2414. #
  2415. # Perforce helpers
  2416. #
  2417. # NB: Requires devel/p4 -- from ports collection
  2418. # NB: Requires awk(1) find(1) sed(1) -- from base system
  2419. #
  2420. quietly unalias p4up
  2421. p4up()
  2422. {
  2423.     find "${1:-.}" -not -type d |
  2424.         sed -e 's/%/%25/g;s/@/%40/g;s/#/%23/g;s/\*/%2A/g' |
  2425.         p4 -x - have 2>&1 |
  2426.         awk '/not on client/&&sub(/ - .*/,"")' |
  2427.                 p4 -x - opened 2>&1 |
  2428.                 awk '/not opened on this client/&&sub(/ - .*/,"")' |
  2429.         sed -e 's/%40/@/g;s/%23/#/g;s/%2A/*/g;s/%25/%/g' |
  2430.         sed -e 's/[[:space:]"'\''\\]/\\&/g'
  2431. }
  2432. quietly unalias p4changes2
  2433. p4changes2()
  2434. {
  2435.     local verbose=
  2436.     [ "$1" = "-v" ] && verbose=1 && shift 1
  2437.     [ "$1" ] || return 1
  2438.     local cmd="p4 changes \"//...@>$1,@<=${2:-now}\""
  2439.     [ "$verbose" ] && cmd="$cmd | awk '{system(\"p4 describe -s \" \$2)}'"
  2440.     echo ">>> $cmd" && eval "$cmd"
  2441. }
  2442. quietly unalias p4getrevs
  2443. p4getrevs()
  2444. {
  2445.     local func=p4getrevs OPTIND=1 OPTARG flag
  2446.     local allrevs=1 revs= get_info= quiet=
  2447.     while getopts iqR: flag; do
  2448.         case "$flag" in
  2449.         i) get_info=1 ;;
  2450.         q) quiet=1 ;;
  2451.         R) revs="$OPTARG" allrevs= ;;
  2452.         esac
  2453.     done
  2454.     shift $(( $OPTIND - 1 ))
  2455.     if [ $# -lt 1 ] || ! [ "$revs" -o "$allrevs" ]; then
  2456.         echo "Usage: $func [-i] [-q] [-R rev[,...]] file ..." >&2
  2457.         return ${FAILURE:-1}
  2458.     fi
  2459.     local file p4path change
  2460.     for file in "$@"; do
  2461.         p4path=$( p4 where "$file" | awk '$0 = $1' ) || continue
  2462.         [ "$allrevs" ] && revs=$( p4 filelog "$file" | awk '
  2463.             $1 == "..." && $2 ~ /^#[[:digit:]]+$/ {
  2464.                 revs = substr($2,2) "," revs
  2465.             }
  2466.             END { sub(/,$/,"",revs); print revs }
  2467.         ' )
  2468.         echo -n "$revs" | awk 'gsub(/,/, " ")||1' | xargs -rn1 sh -c '
  2469.             info_getter="$1" file="$2" p4path="$3"
  2470.             get_info="$4" quiet="$5" revnum="$6"
  2471.             output_file="${file##*/}.$revnum"
  2472.             info_file="${output_file}-info"
  2473.             file_url="http://perforce/@@$p4path?rev1=$revnum"
  2474.             have() { type "$@" > /dev/null 2>&1; }
  2475.             get_revision() {
  2476.                 local cmd=:
  2477.                 if have fetch; then
  2478.                     cmd="fetch ${quiet:+-q} -o"
  2479.                 elif have wget; then
  2480.                     cmd="wget ${quiet:+-q} -O"
  2481.                 elif have curl; then
  2482.                     cmd="curl ${quiet:+-s} -o"
  2483.                 fi
  2484.                 eval $cmd \"\$output_file\" \"\$file_url\"
  2485.             }
  2486.             get_info() {
  2487.                 local change
  2488.                 change=$( p4 filelog "$file#$revnum" |
  2489.                     awk "$info_getter" ) || return
  2490.                 p4 describe -s "$change" | awk "
  2491.                     sub(/^\t+/, \"\"),sub(/^\t+/,\"\")||1
  2492.                 " > "$info_file"
  2493.             }
  2494.             [ -e "$output_file" ] || get_revision
  2495.             [ "$get_info" -a ! -e "$info_file" ] && get_info
  2496.         ' /bin/sh '
  2497.             $1$3 == "...change" && $4 ~ /^[[:digit:]]+$/ {
  2498.                 print $4; exit
  2499.             }
  2500.         ' "$file" "$p4path" "$get_info" "$quiet"
  2501.     done
  2502. }
  2503.  
  2504. #
  2505. # Git helpers
  2506. #
  2507. quietly unalias gitup
  2508. gitup()
  2509. {
  2510.     git status "$@" | awk '!/^#?\t([a-z ]+: +)?\.\.\//'
  2511. }
  2512.  
  2513. #
  2514. # route(8) helpers
  2515. #
  2516. routes_awk='
  2517. BEGIN {
  2518.     columns["host"] = 0
  2519.     domain_len = length(domain)
  2520. }
  2521. !/^[[:space:]]*(#|$)/ &&
  2522.     match($0, /^[^[:space:]]+[[:space:]]+[^[:space:]]/) &&
  2523.     n = split(substr($0, RSTART + RLENGTH - 1), hosts) &&
  2524. 1 {
  2525.     addr = $1
  2526.     for (i = 1; i <= n; i++)
  2527.     {
  2528.         host = hosts[i]
  2529.         host_len = length(host)
  2530.         if (host_len <= domain_len) next
  2531.         host_domain = substr(host, host_len - domain_len + 1)
  2532.         if (host_domain != domain) next
  2533.  
  2534.         short_host_len = host_len - domain_len
  2535.         if (short_host_len > columns["host"])
  2536.             columns["host"] = short_host_len
  2537.         cmd = sprintf("%s route %s %s %s 2>&1",
  2538.             sudo, route_action, addr, route_args)
  2539.         output = ""
  2540.         lines  = 0
  2541.         while (cmd | getline input) {
  2542.             lines++
  2543.             output = sprintf("%s%s%s",
  2544.                 output, output ? "\n" : "", input)
  2545.         }
  2546.         close(cmd)
  2547.         short_hosts[addr] = substr(host, 1, short_host_len)
  2548.         full_hosts[addr] = host
  2549.         cmd_output[addr] = output
  2550.         cmd_lines[addr] = lines
  2551.         next
  2552.     }
  2553. }
  2554. END {
  2555.     for (addr in cmd_output) {
  2556.         short_host = short_hosts[addr]
  2557.         host = full_hosts[addr]
  2558.         output = cmd_output[addr]
  2559.         lines = cmd_lines[addr]
  2560.         if (lines <= 1) {
  2561.             sub(/^[[:space:]]*/, "", output)
  2562.             printf "%-*s => %s\n", columns["host"],
  2563.                 short_host, output
  2564.         } else {
  2565.             printf "%s:\n", host
  2566.             gsub(/\n/, "&\t", output)
  2567.             printf "\t%s\n", output
  2568.         }
  2569.     }
  2570. }
  2571. '
  2572. routes()
  2573. {
  2574.     [ "$ZSH_NAME" ] && local FUNCNAME="$funcstack[1]"
  2575.     local usage="$FUNCNAME %s {add|up|down|delete|reload|show|get}\n"
  2576.     local hosts_file="${ETC_HOSTS:-${HOSTS:-/etc/hosts}}"
  2577.     local name="$1" action="$2" _name domain route_args
  2578.     [ "$name" -a "$action" ] || {
  2579.         printf "Usage: $usage" "${name:-name}" >&2
  2580.         return $FAILURE
  2581.     }
  2582.     _name=$( echo "${name%%[!a-zA-Z0-9_]*}" | tr '[:lower:]' '[:upper:]' )
  2583.     eval routes=\"\$ROUTES_$_name\"
  2584.     [ "$routes" ] || {
  2585.         printf "%s:%u: variable ROUTES_%s unset or NULL!\n" \
  2586.             "$FUNCNAME" "$LINENO" "$_name" >&2
  2587.         return $FAILURE
  2588.     }
  2589.     read domain route_args <<-EOF
  2590.     $routes
  2591.     EOF
  2592.     case "$action" in
  2593.     [Uu][Pp]|[Aa][Dd][Dd])
  2594.         awk -v sudo="sr" \
  2595.             -v route_action="add" -v route_args="$route_args" \
  2596.             -v domain="$domain" "$routes_awk" "$hosts_file" ;;
  2597.     [Dd][Oo][Ww][Nn]|[Dd][Ee][Ll][Ee][Tt][Ee])
  2598.         awk -v sudo="sr" -v route_action="delete" -v route_args="" \
  2599.             -v domain="$domain" "$routes_awk" "$hosts_file" ;;
  2600.     [Rr][Ee][Ll][Oo][Aa][Dd])
  2601.         $FUNCNAME $_name down && $FUNCNAME $_name up ;;
  2602.     [Ss][Hh][Oo][Ww]|[Gg][Ee][Tt])
  2603.         awk -v route_action="-nv get" -v route_args="| tail -1" \
  2604.             -v domain="$domain" "$routes_awk" "$hosts_file" ;;
  2605.     *)
  2606.         printf "Usage: $usage" "${name:-name}" >&2
  2607.         return $FAILURE
  2608.     esac
  2609. }
  2610.  
  2611. ############################################################ SHELL BEHAVIOR
  2612.  
  2613. #
  2614. # Set prompt style
  2615. #
  2616. case "$HOSTNAME" in
  2617. *.*.*.*) export HOSTID="${HOSTNAME%.*.*}" ;;
  2618. *.*.*) export HOSTID="${HOSTNAME%%.*}" ;;
  2619. *) export HOSTID="$HOSTNAME"
  2620. esac
  2621. if [ "$ZSH_NAME" ]; then
  2622.     export PS1=$'\e[1m'"%F{green}$USER@$HOSTID %F{blue}%~ %#%f "$'\e[22m'
  2623. else
  2624.     export PS1='\[\e[32;1m\]$USER@$HOSTID \[\e[34m\]\W \$\[\e[0m\] '
  2625. fi
  2626. [ "$interactive" ] && PROMPT_COMMAND="$LOLEXEC"
  2627.  
  2628. #
  2629. # lolcat integration
  2630. #
  2631. have lolcat && LOLCAT=lolcat
  2632.  
  2633. #
  2634. # If we became root via sudo(8), preserve $HOME
  2635. #
  2636. [ "$SUDO_USER" != "root" ] && export HOME="$( eval echo ~$SUDO_USER )"
  2637.  
  2638. #
  2639. # Set the window title for terminals such as "xterm", "rxvt", and others
  2640. #
  2641. [ "$interactive" ] \
  2642.     && [ "$TERM" != "linux" ] \
  2643.     && [ "$TERM" != "cons25" ] \
  2644.     && settitle "$USER@${HOSTNAME%.*.*}" "${PWD/#$HOME/~}"
  2645.  
  2646. #
  2647. # Fixup $PATH
  2648. #
  2649. export PATH="$HOME/bin:$HOME/Desktop/bin${PATH:+:}$PATH"
  2650. path_munge /sbin /usr/sbin /usr/local/sbin /usr/games
  2651.  
  2652. # Fixup $PATH on Mac OS X Lion
  2653. [ -d "/Developer/usr/bin" ] && path_munge /Developer/usr/bin
  2654.  
  2655. # Latest Apple Developer Tools move cvs once-again, this time
  2656. # XCode 4.3.1 places cvs inside itself -- March 17th, 2012
  2657. [ -f "/Applications/Xcode.app/Contents/Developer/usr/bin/cvs" ] &&
  2658.     path_munge /Applications/Xcode.app/Contents/Developer/usr/bin
  2659.  
  2660. #
  2661. # Make new files group-writable by default
  2662. #
  2663. umask 002
  2664.  
  2665. #
  2666. # shopt(1) options to enable/disable.
  2667. #
  2668. BASH2345_SHOPT_ENABLE='
  2669.     cdspell        inline correction of minor errors in cd
  2670.     checkwinsize   live tracking of $COLUMNS and $LINES
  2671.     histreedit     editing of a failed history expansion
  2672.     histverify     inline history expansion
  2673. '
  2674. BASH2345_SHOPT_DISABLE='
  2675.     # none to report at this time
  2676. '
  2677. BASH45_SHOPT_ENABLE='
  2678.     dirspell     directory spell correction on tab-completion
  2679. '
  2680. BASH45_SHOPT_DISABLE='
  2681.     # none to report at this time
  2682. '
  2683. myshopts # see `myshopts -h'
  2684.  
  2685. ############################################################ ALIASES
  2686.  
  2687. # timecat
  2688. #
  2689. # Used for timing adhoc duties or timing cat operations.
  2690. #
  2691. alias tc="time cat"
  2692. alias timecat="time cat"
  2693.  
  2694. # stuff | dim
  2695. #
  2696. # Make stdout appear "dimmed" in the terminal, allowing errors to stand out.
  2697. #
  2698. alias dim="sed -e s/^/$'\e'[2m/\;s/\$/$'\e'[0m/"
  2699.  
  2700. #
  2701. # zlog_wrapper aliases (see zlog_wrapper in FUNCTIONS above)
  2702. #
  2703. # !!!the below usage statement is generated from zlog_usage above!!!
  2704. # Usage: ALIAS [OPTIONS] [PATTERN]
  2705. # Arguments:
  2706. #   PATTERN    Awk(1) regular expression pattern to search logfile for.
  2707. #
  2708. # Options:
  2709. #   -h         Print this usage statement and exit.
  2710. #   -v         Verbose. Show individual matching lines.
  2711. #   -d1,2,3    Comma-separated list of field numbers to display as the
  2712. #              date/time when providing summary output (ignored if `-v'
  2713. #              is passed). Default is 1,2,3. A value of `NF' prints the
  2714. #              entire line.
  2715. #
  2716. alias messages='zlog_wrapper messages "$MESSAGES"'
  2717. alias aelog='zlog_wrapper aelog "$APACHE_ERROR_LOG" -d1,2,3,4,5'
  2718. alias aalog='zlog_wrapper aalog "$APACHE_ACCESS_LOG" -d4,5,1'
  2719. alias aelog_sa='zlog_wrapper aelog_sa "$APACHE_ERROR_LOG_SA" -d1,2,3,4,5'
  2720. alias aalog_sa='zlog_wrapper aalog_sa "$APACHE_ACCESS_LOG_SA" -d4,5,1'
  2721. alias aselog='zlog_wrapper aselog "$APACHE_SSL_ERROR_LOG" -d1,2,3,4,5'
  2722. alias asalog='zlog_wrapper asalog "$APACHE_SSL_ACCESS_LOG" -d4,5,1'
  2723.  
  2724. #
  2725. # tlog aliases (see tlog in FUNCTIONS above)
  2726. #
  2727. # Usage: ALIAS [OPTIONS]
  2728. # Options are sent to tail(1).
  2729. #
  2730. alias tm='tlog "$MESSAGES"'
  2731. alias tael='tlog "$APACHE_ERROR_LOG"'
  2732. alias taal='tlog "$APACHE_ACCESS_LOG"'
  2733. alias tael_sa='tlog "$APACHE_ERROR_LOG_SA"'
  2734. alias taal_sa='tlog "$APACHE_ACCESS_LOG_SA"'
  2735. alias tasel='tlog "$APACHE_SSL_ERROR_LOG"'
  2736. alias tasal='tlog "$APACHE_SSL_ACCESS_LOG"'
  2737.  
  2738. #
  2739. # Random keepalive [ka] alias (based on system-availability of various
  2740. # fun utilities).
  2741. #
  2742. if [ "$BASH_VERSION" ]; then
  2743. declare -a ka=()
  2744. have worms   && ka[${#ka[@]}]="worms -d 25"
  2745. have rain    && ka[${#ka[@]}]="rain -d 50"
  2746. have grdc    && ka[${#ka[@]}]="grdc"
  2747. have fortune && ka[${#ka[@]}]="
  2748.     ( stty -kerninfo
  2749.       trap 'kill -9 \$sleeppid' SIGINFO
  2750.       trap exit SIGINT
  2751.       while :;do
  2752.         case \"\$LOLCAT\" in
  2753.         *lolcat) fortune |
  2754.             sed -e 's/^[[:space:]]\{1,\}/ /' | \$LOLCAT -a ;;
  2755.         *) fortune | \${LOLCAT:-cat}
  2756.         esac
  2757.         sleep 80 & sleeppid=\$!
  2758.         wait \$sleeppid
  2759.         echo --
  2760.       done
  2761.     ) 2> /dev/null"
  2762. [ ${#ka[@]} -gt 0 ] || ka[0]="while :;do echo -n .;sleep 80;done"
  2763. alias ka='eval "${ka[$(($RANDOM/(32769/${#ka[@]})))]}"'
  2764. fi
  2765.  
  2766. #
  2767. # dbcat alias for reading Berkeley DB database files (based on system-
  2768. # availability of standard utilities).
  2769. #
  2770. dbutil=false
  2771. dbflags=
  2772. if have "db_dump"; then
  2773.     # RHEL/CentOS/Cygwin
  2774.     dbutil="db_dump"
  2775.     db185util="db_dump185"
  2776.     dbflags="-p"
  2777. elif have "db_dump-4.6"; then
  2778.     # FreeBSD-8.x
  2779.     dbutil="db_dump-4.6"
  2780.     db185util="db_dump185-4.6"
  2781.     dbflags="-p"
  2782. elif have "db_dump-4.2"; then
  2783.     # FreeBSD-4.11
  2784.     dbutil="db_dump-4.2"
  2785.     db185util="db_dump185-4.2"
  2786.     dbflags="-p"
  2787. elif have "db3_dump"; then
  2788.     # FreeBSD-4.8
  2789.     dbutil="db3_dump"
  2790.     db185util="db3_dump185"
  2791.     dbflags="-p"
  2792. elif have "db"; then
  2793.     # Legacy
  2794.     dbutil="db"
  2795. fi
  2796. alias dbcat="/bin/sh -c '"'
  2797.     while [ $# -gt 0 ]; do
  2798.         dbfile="$1"
  2799.         shift
  2800.         type=$( file "$dbfile" ) || continue
  2801.         echo "$type" | awk \
  2802.             -v dbfile="$dbfile" \
  2803.             -v dbutil="'"$dbutil"'" \
  2804.             -v db185util="'"$db185util"'" \
  2805.             -v dbflags="'"$dbflags${dbflags:+ }"'" \
  2806.         '\'\\\'\''
  2807.             BEGIN { isdb = 0 }
  2808.             /: Berkeley DB / \
  2809.             {
  2810.                 isdb = 1
  2811.                 if ( dbutil == "db" ) {
  2812.                     sub(/.*\(/, "")
  2813.                     sub(/,.*/, "")
  2814.                     dbutil = dbutil " " tolower($0)
  2815.                 }
  2816.                 else if ( $0 ~ /1.8[45]/ )
  2817.                     dbutil = db185util
  2818.                 system(dbutil " " dbflags dbfile)
  2819.             }
  2820.             END { exit ! isdb }
  2821.         '\'\\\'\''
  2822.     done'\'" -- /bin/sh"
  2823.  
  2824. #
  2825. # Alias for becoming root while maintaining shell customizations.
  2826. #
  2827. if have sr; then
  2828.     flags=
  2829.     sr=$( which sr 2> /dev/null )
  2830.     if [ -L "$sr" ]; then
  2831.         if have readlink; then
  2832.             sr=$( readlink -f "$sr" )
  2833.         elif have realpath; then
  2834.             sr=$( realpath "$sr" )
  2835.         elif have perl; then
  2836.             sr=$( perl -le '
  2837.                 use Cwd;
  2838.                 print Cwd::abs_path(@ARGV);
  2839.             ' -- "$sr" )
  2840.         fi
  2841.         [ "${sr##*/}" = sudo ] && flags="-E"
  2842.     fi
  2843.     alias srsu="sr $flags env $SHELL --rcfile $HOME/.bash_profile"
  2844. elif have sudo; then
  2845.     alias srsu="sudo -E env $SHELL --rcfile $HOME/.bash_profile"
  2846. elif have su; then
  2847.     alias srsu="su -m root --rcfile $HOME/.bash_profile"
  2848. fi
  2849.  
  2850. #
  2851. # Editor settings (in order of preference)
  2852. #
  2853. if have vim; then
  2854.     export EDITOR=vim
  2855.     alias vi='vim'
  2856. elif have vi; then
  2857.     export EDITOR=vi
  2858. elif have ee; then
  2859.     export EDITOR=ee
  2860. elif have nano; then
  2861.     export EDITOR=nano
  2862. elif have pico; then
  2863.     export EDITOR=pico
  2864. elif have emacs; then
  2865.     export EDITOR=emacs
  2866. fi
  2867. alias edit="$EDITOR"
  2868.  
  2869. #
  2870. # Alias for editing a file as root maintaining vi customizations
  2871. #
  2872. if have sr; then
  2873.     alias srvi='sr env HOME="$HOME" $EDITOR'
  2874. elif have sudo; then
  2875.     alias srvi='sudo env HOME="$HOME" $EDITOR'
  2876. fi
  2877.  
  2878. #
  2879. # Alias for machines without sr
  2880. #
  2881. have sr || alias sr="sudo"
  2882.  
  2883. #
  2884. # Forthisms
  2885. #
  2886. # I was spending a lot of time in Forth while writing loader_menu for FreeBSD,
  2887. # and couldn't stop myself from using these to no-end of pain. So I decided to
  2888. # add the below to ease my pain.
  2889. #
  2890. alias .s="ls"
  2891.  
  2892. #
  2893. # View man(1) pages with vim(1)
  2894. #
  2895. have vim && alias man="man -P \"sh -c 'col -b | vim -c \\\"set ft=man nomod nolist\\\" -'\""
  2896.  
  2897. #
  2898. # View man(1) pages with lolcat
  2899. #
  2900. have lolcat && alias lolman="man -P 'col -b | lolcat -f | less -R'"
  2901.  
  2902. #
  2903. # diff-specific vim(1) alias
  2904. #
  2905. quietly unalias dview
  2906. alias dview="vim +/'^\\(Index\\|diff\\|--\\|@@\\|====\\).*' +'set hls' +'set syntax=diff' -R"
  2907.  
  2908. #
  2909. # diff-specific
  2910. #
  2911. alias dsumm="awk '"'NR<3{next}/^-/{p++}/^+/{m++}END{printf "+%u/-%u\n",p,m}'\'
  2912.  
  2913. #
  2914. # Abbreviations
  2915. #
  2916. alias b=basename
  2917. alias d=date
  2918. alias di='dirs -v'
  2919. alias h=history
  2920. alias j=jobs
  2921. alias la='ls -al'
  2922. alias ll='ls -l'
  2923. alias lt='ls -Altr'
  2924. alias pd=pushd
  2925. alias po=popd
  2926. alias z=suspend
  2927. alias bx=BitchX
  2928.  
  2929. #
  2930. # OS-specific Aliases/functions (until they can be generalized)
  2931. #
  2932. case "$UNAME_s" in
  2933. Linux|CYGWIN*)
  2934.     #
  2935.     # Force sort(1) to NOT ignore leading dots
  2936.     # NB: Is Linux brain-dead? or just high on crack?
  2937.     #
  2938.     export LC_COLLATE=C
  2939.  
  2940.     #
  2941.     # Make ls(1) colorful (customized by $HOME/.dir_colors)
  2942.     #
  2943.     alias ls='ls --color=tty -ACF'
  2944.  
  2945.     #
  2946.     # X-related aliases
  2947.     #
  2948.     alias Xsession="/etc/X11/xdm/Xsession"
  2949.     alias xsession="Xsession"
  2950.  
  2951.     #
  2952.     # ps(1) related
  2953.     #
  2954.     pst()
  2955.     {
  2956.         ps axo lstart,pid,ppid,uid,tt,stat,time,command "$@" | awk '
  2957.         BEGIN {
  2958.             getline
  2959.             match($0, /.*STARTED/)
  2960.             print "   STARTED", substr($0, RSTART + RLENGTH)
  2961.         }
  2962.         {
  2963.             date = substr($0, 0, RLENGTH)
  2964.             (cmd = "date -d \"" date "\" +%s") | getline sec
  2965.             close(cmd)
  2966.             printf "%-10s %s\n", sec, substr($0, RLENGTH + 1)
  2967.         }'
  2968.     }
  2969.  
  2970.     vmstat1()
  2971.     {
  2972.         vmstat 1 | awk '/^procs/{printf "%5s %33s %9s %11s %11s %s\n", "-" (procs = $1), "---------" (memory = $2), (swap = $3), "--" (io = $4), "----" (systm = $5), "--" (cpu = $6);next}{printf "%3s %2s %7s %9s %8s %9s %4s %4s %6s %6s %6s %6s %2s %2s %3s %2s %3s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17}'
  2973.     }
  2974.     ;;
  2975. FreeBSD|Darwin)
  2976.     #
  2977.     # boottime: Prints the date/time (format based on current locale)
  2978.     #           that the system booted (resolution is 1-second).
  2979.     # bootsec:  Prints the number of seconds since the epoch (see `%s'
  2980.     #           format in date(1)) that was recorded during boot,
  2981.     #           allowing you to use the `-r seconds' syntax of date(1)
  2982.     #           to represent the boottime in any desired format.
  2983.     #
  2984.     kbt="sysctl kern.boottime"
  2985.     alias boottime="$kbt | sed -e 's/.*} //'"
  2986.     alias bootsec="$kbt | sed -e 's/.* sec = \([0-9]\{1,\}\).*/\1/'"
  2987.     unset kbt
  2988.  
  2989.     #
  2990.     # bootfile: Prints the path to the running kernel.
  2991.     #
  2992.     alias bootfile="sysctl -n kern.bootfile"
  2993.  
  2994.     #
  2995.     # Make ls(1) colorful (customized by $LSCOLORS -- see ls(1))
  2996.     #
  2997.     alias ls="ls -AGCF"
  2998.     export LSCOLORS="Exfxcxdxbxegedabagacad"
  2999.  
  3000.     #
  3001.     # X-related aliases
  3002.     #
  3003.     alias Xsession="/usr/X11R6/lib/X11/xdm/Xsession"
  3004.     alias xsession="Xsession"
  3005.  
  3006.     #
  3007.     # ps(1) related
  3008.     #
  3009.     pst()
  3010.     {
  3011.         ps axo lstart,pid,ppid,uid,tt,stat,time,command "$@" | awk '
  3012.         BEGIN {
  3013.             (cmd = "date +%c") | getline cdate
  3014.             clen = length(cdate)
  3015.             close(cmd)
  3016.         }
  3017.         !/^-/ {
  3018.             if ($1 != (sdate = "STARTED"))
  3019.             {
  3020.                 cdate = substr($0, 0, clen)
  3021.                 cmd = "date -j -f %c \"" cdate "\" +%s"
  3022.                 cmd | getline sdate
  3023.                 close(cmd)
  3024.             }
  3025.             printf "%-10s %s\n", sdate, substr($0, clen + 1)
  3026.         }'
  3027.     }
  3028.     ;;
  3029. esac
  3030.  
  3031. #
  3032. # ssh(1) helpers
  3033. #
  3034. alias sshk="ssh -t vm11 . .bash_profile '&&' ssh -At eskarina ssh -At localhost ssh -A"
  3035. alias sad="\ssh-agent-dup"
  3036.  
  3037. ############################################################ COMPLETION
  3038.  
  3039. _ssh()
  3040. {
  3041.     local file files=
  3042.     for file in \
  3043.         ~/.ssh/config ~/.ssh/config.d/* \
  3044.         ~/.ssh/known_hosts /etc/ssh/known_hosts \
  3045.     ; do [ -e "$file" ] && files="$files $file"; done
  3046.     [ ! "$files" ] || COMPREPLY=( $( compgen -W "$( awk '
  3047.         FILENAME ~ /config/ && tolower($1) == "host" {
  3048.             for (n = 2; n <= NF; n++) if ($n !~ /[?*]/) print $n
  3049.         }
  3050.         FILENAME ~ /hosts/ {
  3051.             for (n = split($1, hosts, /,/); n > 0; n--) {
  3052.                 if ((len = length(hosts[n])) < 1) continue
  3053.                 if ((host = hosts[n]) ~ /^\[.*\]$/)
  3054.                     host = substr(host, 2, len - 2)
  3055.                 print host
  3056.             }
  3057.         }
  3058.     ' $files 2> /dev/null )" -- ${COMP_WORDS[COMP_CWORD]} ) ) || : ok
  3059. }
  3060. [ "$ZSH_NAME" ] || complete -F _ssh ssh
  3061.  
  3062. ############################################################ MISCELLANEOUS
  3063.  
  3064. #
  3065. # cvs(1) settings
  3066. #
  3067. export CVS_RSH=ssh CVSROOT=cvs.vicor.com:/repos/projects
  3068.  
  3069. #
  3070. # BitchX(1) settings
  3071. #
  3072. export IRCNICK=dteske
  3073. #export IRCSERVER=frenode.net
  3074. export IRCSERVER=irc.prison.net
  3075. export IRCNAME=dteske
  3076.  
  3077. #
  3078. # jail_build(8) settings
  3079. #
  3080. export JAIL_BUILD_DESTDIR=/raid1/jails
  3081.  
  3082. #
  3083. # Override the default password prompt for sudo(8). This helps differentiate
  3084. # the sudo(8) password prompt from others such as su(1), ssh(1), and login(1).
  3085. #
  3086. export SUDO_PROMPT='[sudo] Password:'
  3087.  
  3088. #
  3089. # Manual pages with color
  3090. #
  3091. export LESS_TERMCAP_mb=$'\e[31m'      # turn on blinking
  3092. export LESS_TERMCAP_md=$'\e[31m'      # turn on bold (extra bright)
  3093. export LESS_TERMCAP_me=$'\e[m'        # turn off all attributes
  3094. export LESS_TERMCAP_so=$'\e[1;33;44m' # begin standout mode
  3095. export LESS_TERMCAP_se=$'\e[m'        # exit standout mode
  3096. export LESS_TERMCAP_us=$'\e[1;34m'    # begin underline mode
  3097. export LESS_TERMCAP_ue=$'\e[m'        # exit underline mode
  3098.  
  3099. #
  3100. # Quietly attach to running ssh-agent(1) unless agent already given
  3101. #
  3102. if [ ! "$SSH_AUTH_SOCK" ]; then
  3103.     if [ "$interactive" ]; then
  3104.         ssh-agent-dup
  3105.     else
  3106.         quietly ssh-agent-dup -n || :
  3107.     fi
  3108. fi
  3109.  
  3110. ################################################################################
  3111. # END
  3112. ################################################################################
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement