#!/bin/bash set -e mode="${1}" ip="${2}" port="${3}" nick="${4}" print_usage() { echo "${1}" echo "${0} [NICK]" echo "Modes: interactive (intr), send, receive (rec)" exit } [ -z "${ip}" ] && print_usage 'No IP given.' [ -z "${port}" ] && print_usage 'No port given.' [ -z "${5}" ] || print_usage 'Too many arguments.' [ -z "${nick}" ] || nick="<${nick}> " open_socket() { exec 3<> "/dev/tcp/${ip}/${port}" } close_socket() { exec 3>&- } send_message() { open_socket echo "${1}" >&3 close_socket } get_message() { open_socket echo "${1}" >&3 cat <&3 || true close_socket } case "${mode}" in intr) ;& interactive) ;; send) open_socket text="${nick}$(cat)" send_message "0${text}" close_socket exit ;; rec) ;& receive) length="$(get_message 1)" open_socket echo -n 2 >&3 head -c "${length}" <&3 close_socket exit ;; *) echo Unknown mode exit esac while :; do read cmd case "${cmd}" in I) b="" while :; do read c [[ "${c}" != "." ]] || break if [ -z ${b} ]; then b="${c}" else b="${b}"$'\n'"${c}" fi done send_message 0"${nick}${b}" ;; i) read a send_message 0"${nick}${a}" ;; p) length="$(get_message 1)" if [ -z "${length}" ]; then echo !; else open_socket echo -n 2 >&3 head -c "${length}" <&3 | sed -e 's/\x1B/ESC/g' close_socket fi ;; q) exit ;; *) echo ? ;; esac done