123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- #!/bin/bash
-
-
- usage() {
- local self # our name
- self=$(basename "$0")
- echo "usage: $self [options] message" >&2
- echo "usage: $self [options] [-l max_lines] [-L max_width] -f message_file|-" >&2
- echo "options: [-h host] [-p port] [-n nick] [-c context] [-u user]" >&2
- exit 2
- }
-
- mkcommands() {
- local user="$1"
- local nick="$2"
- local message
- echo "NICK $nick"
- echo "USER $nick 8 * :notifirc bot"
- while read -r message;
- do
- echo "PRIVMSG $user :$message"
- done
- echo "QUIT"
- }
-
- mknick() {
- case "$context" in
- "") echo "$nick" ;;
- *) echo "$nick|$context" ;;
- esac
- }
-
- die() {
- local msg="fatal: $1"
- log "$msg"
- log "-----END *-----"
- echo "$msg" >&2
- exit 3
- }
-
- warn() {
- local msg="warning: $1"
- echo "$msg" >&2
- log "$msg"
- }
-
- log_pipe() {
- local line
- while IFS= read -r line;
- do
- log "$line"
- done
- }
-
- log() {
- echo "$1" >>"$logfile"
- }
-
- load_defaults() {
- local rcfile=$1
- test -e "$rcfile" || return 0
- test -f "$rcfile" || {
- warn "defaults file is not a file: $rcfile"
- return 3
- }
- test -r "$rcfile" || {
- warn "defaults file not readable: $rcfile"
- return 3
- }
- bash -n "$rcfile" || {
- warn "syntax error in defaults file: $rcfile"
- return 3
- }
- . "$rcfile" || {
- warn "error in defaults file: $rcfile"
- return 3
- }
- }
-
- trim() {
- local limit_l=$1
- local limit_c=$2
- local lines_read=0
- local suff=""
- while true;
- do
- test $lines_read -ge "$limit_l" && break
- IFS= read -r line || break
- (( lines_read++ ))
- test ${#line} -gt "$limit_c" && suff=…
- line=${line:0:$limit_c}$suff
- echo "$line"
- done
- }
-
- choose_logfile() {
- local path
- {
- echo /var/log/notifirc.log
- echo "$HOME/.notifirc.log"
- echo /tmp/notifirc.log
- } \
- | while read -r path;
- do
- if test -w "$(dirname "$path")" \
- || test -w "$path";
- then
- echo "$path"
- break
- fi
- done
- }
-
- main() {
- local context nick host port user message logfile msgfile
- local f_maxlines=3 f_maxwidth=80
-
- logfile=$(choose_logfile)
- test -n "$logfile" || {
- echo "could not find writable logfile location" >&2
- echo "logging will be off!" >&2
- logfile=/dev/null
- }
-
- load_defaults /etc/notifirc.rc
- load_defaults "$HOME/.notifirc.rc"
-
- while true; do case $1 in
- -c) context=$2; shift 2 || usage ;;
- -f) msgfile=$2; shift 2 || usage ;;
- -h) host=$2; shift 2 || usage ;;
- -l) f_maxlines=$2; shift 2 || usage ;;
- -L) f_maxwidth=$2; shift 2 || usage ;;
- -n) nick=$2; shift 2 || usage ;;
- -p) port=$2; shift 2 || usage ;;
- -u) user=$2; shift 2 || usage ;;
- --) shift; break ;;
- -*) usage ;;
- *) break ;;
- esac done
- message="$*"
-
- test -n "$host" || usage
- test -n "$port" || usage
- test -n "$user" || usage
- test -n "$nick" || nick="notifirc"
- test -z "$message$msgfile" && usage
-
- log "-----BEGIN sending notification-----"
- log "host='$host'"
- log "port='$port'"
- log "nick='$nick'"
- log "context='$context'"
- log "user='$user'"
- log "msgfile='$msgfile'"
- log "f_maxlines='$f_maxlines'"
- log "f_maxwidth='$f_maxwidth'"
- log "message='$message'"
- {
- test -n "$message" && printf '%s\n' "$message"
- test -n "$msgfile" && grep . "$msgfile" | trim "$f_maxlines" "$f_maxwidth"
- } \
- | mkcommands "$user" "$(mknick)" \
- | nc "$host" "$port" 2>&1 \
- | log_pipe
- log "-----END sending notification-----"
- }
-
- main "$@"
|