dot

packages and services management
Log | Files | Refs | README

commit dd36b18f747fe9546a38a36bcb3a601175bff90f
parent f3ddbd2d706ed4015cbcd992276518c64b88cf6d
Author: sshbio <jd@ssh.bio>
Date:   Sun, 31 Jul 2016 22:48:30 +0200

irc: simplified, and made like ii

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

diff --git a/bin/irc b/bin/irc @@ -11,23 +11,18 @@ FULLNAME='With netcat and a script as a client' IRC_DIR="$HOME/.cache/irc" FORMAT='%14s %1s %s\n' LINES="$(stty size | cut -d ' ' -f 2)" - +NL=' +' # Server interaction #------------------------------------------------------------------------------- # -# For each server, the #servers variable contains a list of servers and -# associated pid (NC, TAIL). All element is assumed to not contain any space. -# - -# # Write a message to $in in this for format: '\n${message}\r'. # write() { - local message="$1" - local server="$2" + local message="$1" server="$2" printf '\r%s\n' "$message" >> "$IRC_DIR/$server/in" } @@ -38,12 +33,10 @@ write() open_connection() { local server="$1" - local in="$IRC_DIR/$server/in" out="$IRC_DIR/$server/out" + local in="$IRC_DIR/$server/in" mkdir -p "$IRC_DIR/$server" - [ -p "$in" ] || mkfifo "$in" - printf '' > "$IRC_DIR/$server/channel" - printf '' > "$IRC_DIR/$server/channels" + [ -p "$in" ] || mkfifo "$in" tail -f "$in" | nc "$server" 6667 | output "$server" & @@ -51,79 +44,61 @@ open_connection() write "USER pipe +i * :$FULLNAME" "$server" } - -# Input -#------------------------------------------------------------------------------- -# -# Manage the user input. The $in file act as an history for the input. -# - -# -# Read a single character from stdin and prints it -# -get_char() -{ - local old=$(stty -g) - stty raw -echo - dd bs=1 count=1 2>/dev/null - stty $old -} - # # Parse command from user input and execute corresponding actions. # -parse_command() +input() { - local command="$1" server="$(get_server)" channel="${get_channel}" + local SERVER CHANNEL msg - if [ -z "${command##/*}" ] - then - argument="${command#* }" - command="${command#/}" - command="${command%% *}" - else - argument="$command" - command='' - fi - command="$(printf %s "$command" | tr [a-z] [A-Z])" - - case "$command" in - MSG ) - write "PRIVMSG $( \ - printf '%s' "$argument" | cut -d ' ' -f 1 \ - ) :$( \ - printf '%s' "$argument" | cut -d ' ' -f 2- \ - )" "$server" - ;; - JOIN ) - write "JOIN $argument" "$server" - set_channel "$argument" - ;; - SERVER | CONNECT ) - if [ -z "$(get_servers | grep -F "$argument")" ] - then open_connection "$argument" + while read command + do + + if [ -z "${command##/*}" ] + then + argument="${command#* }" + command="${command#/}" + command="${command%% *}" + else + argument="$command" + command='' fi - set_server "$argument" - ;; - '' ) - msg="PRIVMSG $channel :$argument" - write "$msg" "$server" - printf ':%s!localhost %s\n' "$NICK" "$msg" \ - >> "$IRC_DIR/$server/out" - ;; - * ) - write "$command $argument" "$server" - ;; - esac + + command="$(printf %s "$command" | tr [a-z] [A-Z])" + + case "$command" in + MSG ) + write "PRIVMSG $( \ + printf '%s' "$argument" | cut -d ' ' -f 1 \ + ) :$( \ + printf '%s' "$argument" | cut -d ' ' -f 2- \ + )" "$SERVER" + ;; + J | JOIN ) + CHANNEL="$argument" + write "JOIN $argument" "$SERVER" + ;; + SERVER | CONNECT ) + if [ "$(ps ax | grep -F "$SERVER")" ] + then + SERVER="$argument" + open_connection "$SERVER" + fi + ;; + '' ) + msg="PRIVMSG $CHANNEL :$argument" + write "$msg" "$SERVER" + printf ':%s!localhost %s\n' "$NICK" "$msg" \ + | output "$SERVER" + ;; + * ) + write "$command $argument" "$SERVER" + ;; + esac + done } -# Output -#------------------------------------------------------------------------------- -# -# Manages which channel to show and update the interface -# -# https://tools.ietf.org/html/rfc2812: # # The extracted message is parsed into the components <prefix>,<command> and # list of parameters (<params>). @@ -146,16 +121,17 @@ parse_command() # output() { - local server="$1" + local SERVER="$1" NICK while read message do - local prefix='' nick='' command='' - local params='' middle='' trailing='' channel='' + local prefix='' nick='' command='' params='' middle='' + local trailing='' channel='' + message="${message% }" case "$message" in - PING* ) write "PONG${message#PING}" "$server" ;; - *'ACTION'* ) printf 'ACTION!!!' 1>&2 ;; + PING* ) write "PONG${message#PING}" "$SERVER" ;; + *'VERSION'* ) printf 'VERSION!\n' 1>&2 ;; * ) if [ -z "${message##:*}" ] then @@ -168,129 +144,49 @@ output() command="${message%% *}" message="${message#* }" params="${message# *}" - middle="${message%% :*}" - [ -z "${params%%* :*}" ] && trailing="$( - printf '%s' "${params#* :}" | sed -r ' + middle="${message% }" + middle="${message%%:*}" + [ -z "${params%%*:*}" ] && trailing="$( + printf '%s' "${params#*:}" | sed -r ' s/([^]*)/\1/g s/([^]*)/\1/g ')" channel="${middle%% *}" - [ "$channel" = '*' ] && channel='root' + [ \ + "$channel" = '*' \ + -o -z "$channel" \ + -o "$channel" = "$NICK" \ + ] && channel=SERVER case "$command" in - QUIT ) command='<'; channel="$(get_channel)" ;; + QUIT ) command='<' ;; JOIN ) command='>' ;; PRIVMSG ) command='|' ;; NOTICE ) command='!' ;; - NICK ) command='=' ;; PART ) command='~' ;; ERROR ) command='X' ;; MODE ) command='+' ;; + NICK ) command='=' + [ "$nick" = "$NICK" ] && NICK="$trailing" + ;; esac printf "$FORMAT" "$nick" "$command" "$trailing" \ - | tee # "$out" + | tee -a "$IRC_DIR/$SERVER/$channel" ;; esac done } -# Servers -#------------------------------------------------------------------------------- - -set_server() -{ - local server="$1" - printf '%s' "$server" > "$IRC_DIR/server" -} - -get_server() -{ - local path="$IRC_DIR/server" - [ -f "$path" ] && tee < "$path" -} - -get_servers() -{ - ps ax -o args | sed -rn 's/^nc (.*) 6667/\1/ p' -} - -next_server() -{ - local next="$(get_servers | sed -n "/$(get_server)/ { n; p }")" - [ -z "$next" ] && next="$(get_servers | sed 1q)" - set_server "$next" -} - - -# Channels -#------------------------------------------------------------------------------- - -set_channel() -{ - local channel="$1" - local server="$(get_server)" - - printf '%s' "$channel" > "$IRC_DIR/$server/channel" - - if [ -z "$(grep -F "$channel" "$IRC_DIR/$server/channels")" ] - then printf '%s\n' "$channel" >> "$IRC_DIR/$server/channels" - fi -} - -get_channel() -{ - local path="$IRC_DIR/$(get_server)/channel" - [ -f "$path" ] && tee < "$path" -} - -get_channels() -{ - local path="$IRC_DIR/$(get_server)/channels" - [ -f "$path" ] && tee < "$path" -} - -next_channel() -{ - local channels="$(get_channels)" - - if [ ! -z "$channels" ] - then - local next="$(printf '%s' "$channels" \ - | sed -n "/$(get_channel)/ { n; p }")" - [ -z "$next" ] && next="$(printf '%s' "$channels" | sed '1q')" - [ -z "$next" ] || set_channel "$next" - fi -} - -prev_channel() -{ - local channels="$(get_channels)" - - if [ ! -z "$channels" ] - then - local prev="$(printf '%s' "$channels" \ - | sed -n "/$(get_channel)/ { g; 1! p }; h")" - [ -z "$prev" ] && prev="$(printf '%s' "$channels" \ - | sed -n '$ p')" - [ -z "$prev" ] || set_channel "$prev" - fi -} - - # Algorythm #------------------------------------------------------------------------------- -# Remove irc dir +# Prepare the irc log directory [ -d "$IRC_DIR" ] || mkdir -p "$IRC_DIR" -# Clean status variables -printf '' > "$IRC_DIR/input" -printf '' > "$IRC_DIR/server" - # Kill background jobs if exiting trap 'kill -9 0' INT EXIT # Start listenning the user input -while read command; do parse_command "$command"; done +input