dot

packages and services management
Log | Files | Refs | README

commit 2140b487497463dde6d55a625ef989928abb2ad0
parent fbb118a2d6d1659cf5ba515663b474fb414b509b
Author: josuah <mail@josuah.net>
Date:   Sun, 25 Sep 2016 19:42:56 -0400

Simplified, improved implementation of irc.

Diffstat:
Mbin/irc | 159++++++++++++++++++++++++++++++++++++-------------------------------------------
1 file changed, 73 insertions(+), 86 deletions(-)

diff --git a/bin/irc b/bin/irc @@ -11,7 +11,7 @@ NICK="${NICK-$(whoami)}" FULLNAME='With netcat and a script as a client' -NICK_LEN=14 +NICK_LEN=12 NL=' ' CR="$(printf '\015')" C_A="$(printf '\001')" DIR="$HOME/.cache/irc" @@ -42,10 +42,13 @@ connect() mkdir -p "$srv" [ -p "$srv/IN" ] || mkfifo "$srv/IN" - tail -f "$srv/IN" | nc "$srv" 6667 | output "$srv" & + # Connect to irc server, send command from the pipe, parse the messages. + tail -f "$srv/IN" | nc "$srv" 6667 | while IFS= read -r msg + do parse_message "$srv" + done & write "$srv" "NICK $user" - write "$srv" "USER $(whoami) +i * :$FULLNAME" + write "$srv" "USER $user +i * :$FULLNAME" printf "$user" > "$srv/NICK" } @@ -130,86 +133,74 @@ input() # SPACE = %x20 ; space character # crlf = %x0D %x0A ; "carriage return" "linefeed" # -output() +parse_message() { local srv="$1" - while read msg - do - # Parse server message - local prefix='' nick='' cmd='' trail='' sep='' - local params='' middle='' chan='' user="$(tail "$srv/NICK")" - - # Prefix - msg="${msg#$CR}" msg="${msg%$CR}" - if [ -z "${msg##:*}" ] - then - prefix="${msg%% *}" prefix="${prefix#:}" - [ -z "${prefix%%*!*}" ] && nick="${prefix%%!*}" - msg="${msg#* }" - fi + # Parse server message + local prefix='' nick='' cmd='' trail='' sep='' + local params='' middle='' chan='' user="$(tail "$srv/NICK")" + + # Prefix + msg="${msg#$CR}" msg="${msg%$CR}" + if [ -z "${msg##:*}" ] + then + prefix="${msg%% *}" prefix="${prefix#:}" + [ -z "${prefix%%*!*}" ] && nick="${prefix%%!*}" + msg="${msg#* }" + fi - # Command - cmd="${msg%% *}" msg="${msg#* }" - - # Parameters - [ -z "${msg##* *}" ] && params="${msg# *}" - if [ -z "${msg##:*}" ] - then - trail="${params#:}" - elif [ -z "${msg##*:*}" ] - then - trail="${params#*:}" - middle="${params%%:*}" - else - middle="$params" - fi + # Command + cmd="${msg%% *}" msg="${msg#* }" - # Channel and extra command action - case "$cmd" in - JOIN ) chan="$trail" ;; - PART ) chan="$middle" ;; - PRIVMSG ) - if [ "$middle" = "$user" ] - then chan="$nick" - else chan="$middle" - fi - ;; - NICK ) chan="SERVER" - if [ "$nick" = "$user" ] - then printf '%s\n' "$trail" > "$srv/NICK" - fi - ;; - QUIT | NOTICE | [0-9][0-9][0-9] | * | '' ) - chan=SERVER - ;; - esac + # Parameters + [ -z "${msg##* *}" ] && params="${msg# *}" + case "$msg" in + :* ) trail="${params#:}" ;; + *:* ) trail="${params#*:}" middle="${params%%:*}" ;; + * | '' ) middle="$params" ;; + esac - # Execute action - case "$cmd" in - PING ) - write "$srv" "PONG $trail" - ;; - QUIT | NICK | JOIN ) - for chan in "$srv/#"* "$srv/SERVER" - do chan="${chan#$srv}" - print_msg "$nick" "$trail" "$cmd" "$srv" \ - "$chan" >> "$srv/$chan" - done - ;; - *) - print_msg "$nick" "$trail" "$cmd" "$srv" "$chan" \ - >> "$srv/$chan" - ;; - esac + # Channel and extra command action + case "$cmd" in + JOIN ) chan="$trail" ;; + PART ) chan="$middle" ;; + PRIVMSG ) + if [ "$middle" = "$user" ] + then chan="$nick" + else chan="$middle" + fi + ;; + NICK ) chan="SERVER" + if [ "$nick" = "$user" ] + then printf '%s\n' "$trail" > "$srv/NICK" + fi + ;; + QUIT | NOTICE | [0-9][0-9][0-9] | * | '' ) + chan=SERVER + ;; + esac - # Bot actions - case "$trail" in - 'VERSION' ) - write "$srv" "PRIVMSG $nick :VERSION nc + sh" - ;; - esac - done + # Execute action + case "$cmd" in + PING ) + write "$srv" "PONG $trail" + ;; + QUIT | NICK | JOIN ) + find "$srv" -name '#*' -o -name "SERVER" | while read chan + do print_msg "$nick" "$trail" "$cmd" "$srv" "${chan#$srv}" \ + >> "$chan" + done + ;; + *) + print_msg "$nick" "$trail" "$cmd" "$srv" "$chan" >> "$srv/$chan" + ;; + esac + + # Bot actions + case "$trail" in + 'VERSION' ) write "$srv" "PRIVMSG $nick :VERSION nc + sh" ;; + esac } # @@ -221,14 +212,10 @@ print_msg() local user="$(tail "$srv/NICK")" last_cmd last_nick case "$cmd" in - QUIT ) cmd='<' ;; - JOIN ) cmd='>' ;; - PRIVMSG ) cmd='|' ;; - NOTICE ) cmd='!' ;; - PART ) cmd='~' ;; - ERROR ) cmd='X' ;; - MODE ) cmd='+' ;; - NICK ) cmd='=' ;; + ( QUIT ) cmd='<' ;; ( JOIN ) cmd='>' ;; + ( PRIVMSG ) cmd='|' ;; ( NOTICE ) cmd='!' ;; + ( PART ) cmd='~' ;; ( ERROR ) cmd='X' ;; + ( MODE ) cmd='+' ;; ( NICK ) cmd='=' ;; esac # Single line separator at the right place. @@ -240,12 +227,12 @@ print_msg() last_cmd="$(tail -n 1 "$srv/$chan" | cut -c $(($NICK_LEN + 2))-)" last_cmd="${last_cmd%% *}" - if [ "$cmd" = '|' -a "$last_nick" != "$nick" -o "$cmd" != "$last_cmd" ] + if [ "$cmd" = '|' ] && [ "$last_nick" != "$nick" ] || [ "$cmd" != "$last_cmd" ] then printf "%${NICK_LEN}s |\n" fi # Print the message - printf '%s\n' "$trail" | fold -s -w $((78 - $NICK_LEN - ${#cmd})) \ + printf '%s\n' "$trail" | fold -s -w $((80 - $NICK_LEN - ${#cmd})) \ | while read line do printf "%${NICK_LEN}s %1s %s\n" "$nick" "$cmd" "$line"