123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/bin/bash
  2. usage() {
  3. echo "usage: $(basename "$0") [-h host] [-p port] [-n nick] [-c context] [-u user] message" >&2
  4. exit 2
  5. }
  6. mkcommands() {
  7. local user="$1"
  8. local message="$2"
  9. local nick="$3"
  10. echo "NICK $nick"
  11. echo "USER $nick 8 * :notifirc bot"
  12. echo "PRIVMSG $user :$message"
  13. echo "QUIT"
  14. }
  15. mknick() {
  16. case "$context" in
  17. "") echo "$nick" ;;
  18. *) echo "$nick|$context" ;;
  19. esac
  20. }
  21. die() {
  22. local msg="fatal: $1"
  23. log "$msg"
  24. log "-----END *-----"
  25. echo "$msg" >&2
  26. exit 3
  27. }
  28. warn() {
  29. local msg="warning: $1"
  30. echo "$msg" >&2
  31. log "$msg"
  32. }
  33. log_pipe() {
  34. local line
  35. while IFS= read line;
  36. do
  37. log "$line"
  38. done
  39. }
  40. log() {
  41. echo "$1" >>"$logfile"
  42. }
  43. load_defaults() {
  44. local rcfile=$1
  45. test -e "$rcfile" || return 0
  46. test -f "$rcfile" || {
  47. warn "defaults file is not a file: $rcfile"
  48. return 3
  49. }
  50. test -r "$rcfile" || {
  51. warn "defaults file not readable: $rcfile"
  52. return 3
  53. }
  54. bash -n "$rcfile" || {
  55. warn "syntax error in defaults file: $rcfile"
  56. return 3
  57. }
  58. . "$rcfile" || {
  59. warn "error in defaults file: $rcfile"
  60. return 3
  61. }
  62. }
  63. choose_logfile() {
  64. local path
  65. {
  66. echo /var/log/notifirc.log
  67. echo "$HOME/.notifirc.log"
  68. echo /tmp/notifirc.log
  69. } \
  70. | while read path;
  71. do
  72. if test -w "$(dirname "$path")" \
  73. || test -w "$path";
  74. then
  75. echo "$path"
  76. break
  77. fi
  78. done
  79. }
  80. main() {
  81. local context nick host port user message logfile
  82. logfile=$(choose_logfile)
  83. test -n "$logfile" || {
  84. echo "could not find writable logfile location" >&2
  85. echo "logging will be off!" >&2
  86. logfile=/dev/null
  87. }
  88. load_defaults /etc/notifirc.rc
  89. load_defaults "$HOME/.notifirc.rc"
  90. while true; do case $1 in
  91. -c) context=$2; shift 2 || usage ;;
  92. -h) host=$2; shift 2 || usage ;;
  93. -n) nick=$2; shift 2 || usage ;;
  94. -p) port=$2; shift 2 || usage ;;
  95. -u) user=$2; shift 2 || usage ;;
  96. --) shift; break ;;
  97. -*) usage ;;
  98. *) break ;;
  99. esac done
  100. message="$*"
  101. test -n "$host" || usage
  102. test -n "$port" || usage
  103. test -n "$user" || usage
  104. test -n "$nick" || nick="notifirc"
  105. test -n "$message" || usage
  106. log "-----BEGIN sending notification-----"
  107. log "host='$host'"
  108. log "port='$port'"
  109. log "nick='$nick'"
  110. log "context='$context'"
  111. log "user='$user'"
  112. log "message='$message'"
  113. mkcommands "$user" "$message" "$(mknick)" \
  114. | nc "$host" "$port" 2>&1 \
  115. | log_pipe
  116. log "-----END sending notification-----"
  117. }
  118. main "$@"