123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730 |
- #!/bin/bash
- #
- # shellfu embedded: /home/amahdal/local/mydots/dotfiles/imapdomo/utils/imapdomo
- # shellfu version: 0.9.0
- #
-
- # neuter any shellfu and shellfu-get calls
- shellfu() { :; }
- shellfu-get() { echo /dev/null; }
-
- #
- # begin module: d85843c5561356764375c3915e2b411b /usr/local/share/shellfu/include-bash/exit.sh
- #
-
- #!/bin/bash
-
-
- EXIT_OK=0
- EXIT_NO=1
- EXIT_USAGE=2
- EXIT_ERROR=3
- EXIT_PANIC=4
-
-
- exit_ok() {
- #
- # Exit script with success
- #
- exit $EXIT_OK
- }
-
-
- exit_no() {
- #
- # Exit script with answer "no"
- #
- exit $EXIT_NO
- }
-
-
- exit_usage() {
- #
- # Exit script with usage error
- #
- exit $EXIT_USAGE
- }
-
-
- exit_error() {
- #
- # Exit script with generic unexpected error
- #
- exit $EXIT_ERROR
- }
-
-
- exit_panic() {
- #
- # Exit script in panic (e.g. assert failure, sure bug)
- #
- exit $EXIT_PANIC
- }
-
- #
- # end module: d85843c5561356764375c3915e2b411b /usr/local/share/shellfu/include-bash/exit.sh
- #
-
- #
- # begin module: 8ee17c6681d102da92d36f71ef523a55 /usr/local/share/shellfu/include-bash/pretty.sh
- #
-
- #!/bin/bash
-
- shellfu import exit
-
- #
- # Application debug mode
- #
- PRETTY_DEBUG=${PRETTY_DEBUG:-false}
-
- #
- # List of module/function names to exclude from debuging
- #
- # For the sake of readability of your debug dumps, you can set this
- # variable to comma-separated list of module or function names that
- # you don't expect to get useful info from.
- #
- # If the caller has a qualified name (`modname__funcname()`, according
- # to Shellfu naming scheme it's possible to use just module name here
- # to mute all debug from that module (including internal functions).
- # Otherwise, full function name should be listed.
- #
- PRETTY_DEBUG_EXCLUDE=${PRETTY_DEBUG_EXCLUDE:-}
-
- #
- # Application verbosity mode
- #
- PRETTY_VERBOSE=${PRETTY_VERBOSE:-false}
-
- #
- # Name of pretty-printer module
- #
- # Friendly name of module used for decorating output. For
- # example, if the value is NAME, a _pretty_NAME module must
- # exist and be importable. Otherwise pretty will fall back
- # to plain, which is also the default value.
- #
- PRETTY=${PRETTY:-plain}
-
- #
- # Usage mode -- set to 'subcommand' to remove first dash
- #
- PRETTY_USAGE=${PRETTY_USAGE:-}
-
-
- __shellfu_pretty__init() {
- #
- # Import proper submodule
- #
- if shellfu try_import "_pretty_${PRETTY}";
- then
- shellfu import "_pretty_${PRETTY}"
- return 0
- else
- warn "falling back to _pretty_plain"
- PRETTY=plain
- shellfu import "_pretty_${PRETTY}"
- fi
- }
-
-
- ##--------------------##
- ## PRINTING FRONT-END ##
- ##--------------------##
-
- debug() {
- #
- # You already know what it does
- #
- # BTW, following are equivalent:
- #
- # debug "var1=$var1" "var2=$var2" "result=$result"
- # debug -v var1 var2 result
- #
- $PRETTY_DEBUG || return 0
- _pretty__echo "$@"
- }
-
-
- debug_pipe() {
- #
- # Debug the whole pipe.
- #
- while IFS= read -r line;
- do
- debug "|$1: '$line'"
- echos "$line"
- done
- }
-
-
- die() {
- #
- # A fatal error
- #
- _pretty__echo -t
- _pretty__echo "$@"
- exit_error
- }
-
-
- echos() {
- #
- # Safer version of echo able to echo "-n"
- #
- # Traditional echo is broken in that it does not
- # distinguish between string to print and its own switches
- # (-e, -E or -n), leading to unexpected behavior.
- #
- # This echo version circumvents this by using printf.
- #
- printf -- '%s\n' "$@"
- }
-
-
- mkusage() {
- #
- # Echo out usage patterns and (by default) `exit 2`
- #
- # mkusage [-e STATUS] [-E] pattern [patern...]
- #
- # Each pattern is prefixed by "usage: " and a resolved
- # script/function name to produce traditional usage hint.
- # By default, will exit with status *EXIT_USAGE*, you
- # can use `-e STATUS` to specify other number. `-k` can be
- # used as shorthand for `-e 0` (e.g. if user asked for
- # the patterns)
- #
- # Use `-E` to prevent exiting; in that case, the status
- # that would be fed to `exit` will be used as exit status
- # of this function.
- #
- # Use "--" to delimit end of arguments processed by mkusage.
- #
- # Setting PRETTY_USAGE to 'subcommand' has effect that
- # in each call, first hyphen in the script's "own" name is
- # replaced by space; this is used for git-like sub-commands,
- # where the actual binary name is e.g. "git-add" for
- # "git add".
- #
- # Recommended usage is to define usage() in your script and
- # use this in its body. That way you only need to define
- # usage patterns once and skip to them from any place where
- # you detect incorrect usage.
- #
- local es=$EXIT_USAGE
- local doexit=true
- while true; do case "$1" in
- -e) es="$2"; shift 2 || return 2 ;;
- -E) doexit=false; shift ;;
- -k) es=$EXIT_OK; shift ;;
- --) shift; break ;;
- *) break ;;
- esac done
- _pretty__echo -u "$@";
- $doexit && exit "$es"
- return "$es"
- }
-
-
- mkhelp() {
- #
- # Echo out help text
- #
- # mkhelp [-e STATUS] [-E] arg...
- #
- # By default, will exit with status *EXIT_OK*, you
- # can use `-e STATUS` to specify other number.
- #
- # Use `-E` to prevent exiting; in that case, the status
- # that would be fed to `exit` will be used as exit status
- # of this function.
- #
- # Use "--" to delimit end of arguments processed by mkhelp
- #
- local es=$EXIT_OK
- local doexit=true
- while true; do case "$1" in
- -e) es="$2"; shift 2 || return 2 ;;
- -E) doexit=false; shift ;;
- --) shift; break ;;
- *) break ;;
- esac done
- _pretty__echo "$@"
- $doexit && exit "$es"
- return "$es"
- }
-
-
- think() {
- #
- # If verbose is on, think loud
- #
- # Use "-l" to split every parameter to separate line, (useful
- # or longer warnings)
- #
- $PRETTY_VERBOSE || return 0
- _pretty__echo "$@"
- }
-
-
- warn() {
- #
- # Warn them
- #
- # Use "-l" to split every parameter to separate line, (useful
- # or longer warnings)
- #
- _pretty__echo "$@"
- }
-
-
- ##----------##
- ## BACK-END ##
- ##----------##
-
-
- _pretty__cat() {
- #
- # `cat` but without starting a process
- #
- # Used to avoid spanning new process where stream handler is chosen
- # based on some logic
- #
- while IFS= read -r line;
- do echos "$line"; done
- }
-
-
- _pretty__get_caller() {
- #
- # Get first user function and negative index from stack
- #
- local fname
- local nidx="${#FUNCNAME[@]}"
- for fname in "${FUNCNAME[@]}";
- do
- (( nidx-- ))
- _pretty__is_internal && continue
- _pretty__is_frontend && continue
- test "$fname" = "usage" && continue
- echos "$nidx" "$fname"
- return
- done
- }
-
- _pretty__get_frontend() {
- #
- # Get entry point function name from stack
- #
- local fname
- for fname in "${FUNCNAME[@]}";
- do
- _pretty__is_internal && continue
- _pretty__is_frontend && echos "$fname" && return 0
- echo "do not call _pretty_* directly: $fname" >&2
- return "$EXIT_USAGE"
- done
- }
-
- _pretty__is_excluded() {
- #
- # True if $caller is excluded based on PRETTY_DEBUG_EXCLUDE
- #
- # Check PRETTY_DEBUG_EXCLUDE to see if $caller (using only module name
- # part, if possible) should be muted from debugging.
- #
- local listed # item listed in PRETTY_DEBUG_EXCLUDE
- local name # module part of caller's name
- local qualified # is caller "qualified" (ac. to shellfu scheme)?
- name="$caller"
- case "$name" in
- __*__*) qualified=true ;;
- __*) qualified=false ;;
- *__*) qualified=true ;;
- *) qualified=false ;;
- esac
- if $qualified;
- then
- # we'll use only the module part of the name
- name=${name#_} # drop one "internal" prefix
- name=${name#_} # drop yet another one
- name=${name%__*} # drop funcname
- fi
- for listed in ${PRETTY_DEBUG_EXCLUDE//,/ };
- do
- test "$name" = "$listed" && return 0
- done
- return 1
- }
-
- _pretty__is_frontend() {
- #
- # True if $fname is one of our "frontends"
- #
- case "$fname" in
- debug) return 0 ;;
- debug_pipe) return 0 ;;
- die) return 0 ;;
- mkhelp) return 0 ;;
- think) return 0 ;;
- mkusage) return 0 ;;
- warn) return 0 ;;
- esac
- return 1
- }
-
- _pretty__is_internal() {
- #
- # True if $fname is our internal function
- #
- case "$fname" in
- _pretty__*) return 0 ;;
- *) return 1 ;;
- esac
- }
-
- _pretty__echo() {
- #
- # A smarter echo backend
- #
- # A smarter backend for debug, warn, think, die and
- # mkusage.
- #
- # -c cmd echo output of a command
- # -f file echo output of a file (- for stdin)
- # -l line [line...] echo each line separately
- # -t add stack trace to output
- # -u patt [patt...] convert each patt to usage pattern
- # -v var [var...] show contents of each var
- #
- local frontend # who (of pretty.sh) was called (=> prettyprinter choice)
- local caller # which user's function (or script) called it
- # ^ ^ eg. if user calls 'debug hello' from function 'foo', then
- # : :.. * frontend is 'debug'
- # :......... * and caller is 'foo'.
- local caller_nidx # negative stack index of caller
- local caller_is_main # true if caller was main script or main() in it
- local provider # which provider (_pretty__echo_*()) to use
- frontend="$(_pretty__get_frontend)" || exit_usage
- read caller_nidx caller <<<$(_pretty__get_caller)
- test "$frontend" = debug && _pretty__is_excluded "$caller" && return 0
- case $caller_nidx:$caller in
- 0:*) caller_is_main=true; caller="${0##*/}" ;;
- 1:main) caller_is_main=true; caller="${0##*/}" ;;
- *:usage) frontend=mkusage ;;
- *) caller_is_main=false ;;
- esac
- while true; do case $1 in
- -c|--cmd) provider=cmd; shift; break ;;
- -f|--files) provider=files; shift; break ;;
- -l|--lines) provider=lines; shift; break ;;
- -t|--trace) provider=trace; shift; break ;;
- -u|--usage) provider=usage; shift; break ;;
- -v|--vars) provider=vars; shift; break ;;
- *) provider=args; break ;;
- esac done
- _pretty__echo_$provider "$@" \
- | _pretty__$frontend >&2
- }
-
-
- _pretty__echo_args() {
- #
- # The simplest (but safe) printing of args
- #
- echos "$*"
- }
-
-
- _pretty__echo_cmd() {
- #
- # Print command line, launch it and report exit status
- #
- local c=\$
- test "$(id -u)" -eq 0 && c="#"
- echo "$c $*"
- "$@"
- echo "^ exit status: $?"
- }
-
-
- _pretty__echo_files() {
- #
- # Print names and contents of existing files
- #
- local fp
- for fp in "$@";
- do
- if test "$fp" = "-";
- then
- cat
- elif test -s "$fp" || test "$fp" = "/dev/stdin";
- then
- echo "-- $fp --"
- cat "$fp"
- fi
- done
- }
-
-
- _pretty__echo_lines() {
- #
- # Echo each argument as a separate line
- #
- local l;
- for l in "$@"; do _pretty__echo_args "$l"; done
- }
-
-
- _pretty__echo_trace() {
- #
- # Print "decorated" call trace (only in debug mode)
- #
- $PRETTY_DEBUG || return 0
- local depth
- echo "== trace =="
- for depth in $(seq 0 ${#FUNCNAME});
- do
- caller "$depth" || break
- done \
- | tail -n +3 \
- | sed -e '
- s/^\([^ ]\+\) \([^ ]\+\) \(.*\)/\3:\1:\2()/
- # ^line^, ^func^, ^file^
- 1 s/^/ -> /g
- 2,$ s/^/ /
- ' \
- | tac
- }
-
-
- _pretty__echo_help() {
- local oldverbose="$PRETTY_VERBOSE"
- think -l "$@"
- PRETTY_VERBOSE=$oldverbose
- }
-
- _pretty__echo_usage() {
- #
- # Compose conventional usage guide
- #
- # The default mode treats each argument as usage pattern
- # (see below for details). Additional formatting can be
- # conveniently achieved by switching to other modes, which
- # automatically brings necessary headers and indentations
- # where needed.
- #
- # * option mode (`-o`) prints "options:" header and
- # indents next arguments,
- #
- # * command mode (`-c`) prints "commands:" header and
- # indents next arguments,
- #
- # * plain mode (`--`) prints empty line (new paragraph)
- # and turns indentations off.
- #
- # * usage mode (`-u`, active by default), prints
- # "usage:" header, indents next arguments and prefixes
- # them with name of the script.
- #
- # A special case of usage mode is when only single
- # argument is passed to this function; then instead
- # of "usage:" header, this usage pattern is prefixed
- # with the same string.
- #
- # In order to help avoid (rare) conflict between mkusage()
- # switches and your usage patterns, the very first argument,
- # and each argument that comes right after one of these
- # switches are guarranteed not to be interpreted as switch.
- #
- local self # the script name
- local mode=usage # mode
- local esc=1 # escape (take next argument as literal)
- local arg # argument to iterate
- case "$PRETTY_USAGE" in
- subcommand) self="${0##*/}"; self="${self/-/ }" ;;
- *) self="$caller" ;;
- esac
- case $# in
- 0) return 0 ;;
- 1) echo "usage: $self $1"; return 0 ;;
- esac
- echo usage:
- for arg in "$@";
- do
- case $esc:$arg in
- 0:--) shift; mode=plain; esc=1; echo ;;
- 0:-c) shift; mode=indent; esc=1; echo; echo commands: ;;
- 0:-i) shift; mode=indent; esc=1; echo ;;
- 0:-o) shift; mode=indent; esc=1; echo; echo options: ;;
- 0:-u) shift; mode=usage; esc=1 ;;
- *) esc=0
- case $mode in
- usage) echo " $self $arg" ;;
- indent) echo " $arg" ;;
- plain) echos "$arg" ;;
- esac
- ;;
- esac
- done
- }
-
-
- _pretty__echo_vars() {
- #
- # Report value of each named variable
- #
- local varname
- local declare_str
- for varname in "$@";
- do
- if ! _pretty__is_word "$varname";
- then
- warn "unsafe value skipped: $varname";
- continue
- fi
- if declare_str=$(declare -p "$varname" 2>/dev/null);
- then
- _pretty__echo "${declare_str#declare ?? }"
- else
- _pretty__echo "$varname #Unset"
- fi
- done
- }
-
-
- _pretty__is_word() {
- #
- # Check if $1 contains only alphanumeric chars or _
- #
- local tainted="$1"
- local clean=$(tr -c -d '_[:alnum:]' <<< "$tainted")
- test "$tainted" = "$clean"
- }
-
- #
- # end module: 8ee17c6681d102da92d36f71ef523a55 /usr/local/share/shellfu/include-bash/pretty.sh
- #
-
- #
- # begin module: 392f50abe388bd54c01d84ee7b2a0cdd /usr/local/share/shellfu/include-bash/_pretty_plain.sh
- #
-
- #!/bin/bash
-
-
- _pretty__debug() {
- local decor="()"
- $caller_is_main && decor=
- while IFS= read -r line;
- do echo "debug:$caller$decor: $line"; done
- }
-
- _pretty__die() {
- while IFS= read -r line;
- do echo "$line"; done
- }
-
- _pretty__mkhelp() {
- while IFS= read -r line;
- do echo "$line"; done
- }
-
- _pretty__mkusage() {
- while IFS= read -r line;
- do echo "$line"; done
- }
-
- _pretty__think() {
- while IFS= read -r line;
- do echo "$line"; done
- }
-
- _pretty__warn() {
- while IFS= read -r line;
- do echo "$line"; done
- }
-
- #
- # end module: 392f50abe388bd54c01d84ee7b2a0cdd /usr/local/share/shellfu/include-bash/_pretty_plain.sh
- #
-
- #!/bin/bash
-
- . "$(shellfu-get path)" || exit 3
-
- shellfu import pretty
-
- usage() {
- mkusage "[options] ACTION" \
- -o \
- "-c DIR change to DIR before doing anything" \
- "-d turn on debugging mode" \
- -- \
- "imapdomo will try to read .imapdomo/host/HOSTNAME/init.lua and" \
- ".imapdomo/host/HOSTNAME/handlers/ACTION.lua, where HOSTNAME is your" \
- "short hostname (eg. 'foo' in 'foo.example.com')." \
- "" \
- "four valid actions are understood; since you must write handler for" \
- "each action you want to use, the meanings below are purely a guide:" \
- "" \
- " newmail - check for and file new mail" \
- " rewind - re-add messages from FILTER_FAIL back to FILTER_QUEUE" \
- " cleanup - delete or archive old messages" \
- " migrate - move mail between mailboxes" \
- "" \
- "See imapfilter_config(5)) for guide and API reference. Few functions"\
- "are also available in .imapdomo/common.lua"
- }
-
- mkcmd() {
- #
- # Compose imapfilter command
- #
- echo -n "IMAPDOMO_ACTION=$Action"
- echo -n " IMAPFILTER_HOME=$CfgDir"
- echo -n " imapfilter"
- if $Debug
- then
- mkdir -p "$LogDir"
- echo -n " -d $LogDir/debug.log"
- echo -n " -v"
- fi
- echo -n " -c $CfgDir/main.lua"
- }
-
- main() {
- local Action # what to do
- local Debug # true if debugging
- local cmd # imapfilter command
- local CfgDir # config directory
- local LogDir # directory to store logs
- local CdTo # change dir to this before running imapfilter
- CfgDir="$HOME/.imapdomo"
- LogDir="$HOME/.local/share/imapdomo/logs"
- Debug=false
- #shellcheck disable=SC2034
- while true; do case $1 in
- -c) CdTo="$2"; shift 2 || usage ;;
- -d) Debug=true; PRETTY_DEBUG=true; shift ;;
- -*) usage ;;
- *) break ;;
- esac done
- Action="$1"; shift
- grep -qw "$Action" <<< "newmail|rewind|cleanup|migrate" || usage
- cmd=$(mkcmd)
- debug -v cmd
- bash -n <<<"$cmd" || die
- if test -n "$CdTo";
- then
- cd "$CdTo" || die
- fi
- eval "$cmd"
- }
-
- main "$@"
- #
- # end of shellfu-embedded shell script
- #
|