#!/bin/sh # irc; Deven Blake 2022; Public domain # I stopped understanding this at 81 lines. alias cat='cat -u' alias sed='sed -u' # defaults DEFAULT_HOST="example.com" PORT=6667 [ -n "$IRC_QUIT_MESSAGE" ] \ || IRC_QUIT_MESSAGE="Bye bye!" # defaults (standard-defined) URI_FRAGMENT_DELIMITER='#' # RFC 3986 argv0="$0" URL="$1" usage(){ printf "Usage: %s [url]\n" "$argv0" exit 1 } one_character_per_line(){ sed 's/./&\n/g' } host_ex_url(){ # filter out scheme URI subcomponent # filter out userinfo URI subcomponent # filter out port # filter out heirarchy path # filter out query # filter out fragment printf "%s\n" "$URL" \ | sed 's/.*:\/\///' \ | sed 's/.*@//' \ | sed 's/:.*$//' \ | sed 's/\/.*$//' \ | sed 's/\?.*$//' \ | sed 's/#.*$//' } port_ex_url(){ # filter out scheme URI subcomponent # filter out userinfo URI subcomponent local_url="$(printf "%s\n" "$URL" \ | sed 's/.*:\/\///' \ | sed 's/.*@//')" # check to ensure there Is a port in the URL # this will also catch if we fucked up if ! [ "$(printf "%s\n" "$local_url" \ | one_character_per_line \ | grep ':' \ | wc -l)" \ = 1 ] then # give up, gracefully printf "%s\n" "$PORT" return 0 fi # filter out query URI subcomponent # filter out heirarchy path # filter out everything preceding the port local_url="$(printf "%s\n" "$local_url" \ | sed 's/\?.*$//' \ | sed 's/\/.*$//' \ | sed 's/.*://')" printf "%s\n" "$local_url" } username_ex_url(){ # only go if there's actually userinfo in the URL # filter out scheme URI subcomponent # filter out everything after userinfo URI subcomponent # filter out password in userinfo, if present printf "%s\n" "$URL" \ | grep '@' \ | sed 's/.*:\/\///' \ | sed 's/@.*$//' \ | sed 's/:.*$//' } [ -n "$URL" ] \ || usage [ -n "$IRC_NICK" ] \ || IRC_NICK="$USER" # check if URL matches /^irc:\/\// if ! printf "%s\n" "$URL" | grep "^irc://" >/dev/null 2>&1; then printf "%s: %s: URL incorrectly formatted or scheme not specified.\n" "$argv0" "$URL" exit 1 fi # easy; the fragment is the last part of the URI CHANNEL="#$(printf "%s\n" "$URL" \ | sed 's/.*#//' )" # not easy PORT="$(port_ex_url)" # slow, so don't rerun a="$(username_ex_url)" [ -z "$a" ] \ || IRC_NICK="$a" HOST="$(host_ex_url)" [ -n "$HOST" ] \ || HOST="$DEFAULT_HOST" if ! TEMP="$(mktemp)" || ! TEMP_FIN="$(mktemp)"; then printf "%s: mktemp: Could not make temporary file.\n" "$argv0" exit 1 fi # RFC 1459 section 4.1.2 printf "NICK %s\n" "$IRC_NICK" >"$TEMP" # RFC 1459 section 4.1.3; USER # not really important printf "USER %s 0 0 :\n" "$IRC_NICK" >>"$TEMP" # RFC 1459 section 4.2.1 printf "JOIN %s\n" "$CHANNEL" >>"$TEMP" # RFC 1459 section 4.1.6 printf "QUIT :%s\n" "$IRC_QUIT_MESSAGE" >"$TEMP_FIN" # RFC 1459 section 4.4.1 sed "s/^/PRIVMSG $CHANNEL :/g" \ | cat "$TEMP" /dev/stdin "$TEMP_FIN" \ | nc "$HOST" "$PORT"