#!/bin/sh VERSION='@version@' PREFIX=@prefix@ if [ -z "$SHIRC_CONF" ]; then SHIRC_CONF="$PREFIX/etc/shirc.conf"; fi # source systemwide config if [ -r "$SHIRC_CONF" ]; then . $SHIRC_CONF; fi # source user local config if [ -r "${HOME}/.shircrc" ]; then . ${HOME}/.shircrc; fi if [ -z "$SHIRC_CHDIR" ]; then SHIRC_CHDIR=/tmp/shirc; fi if [ -z "$2" ]; then echo "- shirc-link version $VERSION -" echo "Usage: "`basename $0`" [@] " exit 1 fi LHOST=`hostname | cut -d. -f1` RHOSTSSH="$1" CHANNEL="$2" RHOST=`echo "${RHOSTSSH}" | cut -d@ -f2` if [ -z "$RHOST" ]; then RHOST=${RHOSTSSH} fi if [ "$3" = "local" ]; then MODE=local # This is not always readable info... # We need a way to prevent endless loops, so IP address # might be a good solution, but.. RADDR=`echo $SSH_CLIENT | awk '{print $1}'` else MODE=connect fi if [ "$4" = "debug" ]; then DEBUG=DEBUG fi trap 'cleanup' 1 5 2 3 9 13 cleanup() { if [ -n "$CLEANINGUP" ]; then return fi CLEANINGUP="yes" opwd=$PWD; cd ${SHIRC_CHDIR}/${CHANNEL}.users for ruser in *@${RHOST}:*; do if [ "$ruser" = "*@${RHOST}:*" ]; then break fi name=`echo "$ruser" | cut -d: -f1` echo "*** ${name} left channel ${CHANNEL}" >&${CHANNELFD} rm $ruser done cd $opwd if [ "$MODE" = "connect" ]; then echo "**** link to ${RHOST} closed" >&$CHANNELFD else # MODE = "local" echo "**** link from ${RHOST} closed" >&$CHANNELFD kill $readpid fi rm -f ${SHIRC_CHDIR}/${CHANNEL}.links/${RHOST} exec 3>&- exit } handshake() { echo "-link- opened" if [ -r ${SHIRC_CHDIR}/${CHANNEL}.topic ]; then echo "-link- topic: "`cat ${SHIRC_CHDIR}/${CHANNEL}.topic` fi ls ${SHIRC_CHDIR}/${CHANNEL}.users/ | cut -d: -f1 | sort -u | grep -v "@${RHOST}" | sed 's/^/-link- user in: /' if [ -n "$DEBUG" ]; then { echo "${LHOST} send: -link- opened" ls ${SHIRC_CHDIR}/${CHANNEL}.users/ | cut -d: -f1 | sort -u | grep -v "@${RHOST}" | sed "s/^/${LHOST} send: -link- user in: /" } >&2 fi } parselink() { while read line; do if [ -n "$DEBUG" ]; then echo "${LHOST} recv: $line" >&2 fi user=`expr "$line" : '^<\([^>]*\)> *.*' 2> /dev/null` if [ -n "$user" ]; then phrase=`expr "$line" : '^<[^>]*> \(.*\)$' 2> /dev/null` echo "<${user}@${RHOST}> ${phrase}" >&$CHANNELFD continue fi user=`expr "$line" : '^\*\*\* \([^ ]*\) ' 2> /dev/null` message=`expr "$line" : '^\*\*\* [^ ]* \(.*\)$' 2> /dev/null` if [ -n "$user" ]; then echo "*** ${user}@${RHOST} $message" >&$CHANNELFD topic=`expr "$message" : '^changed the topic to .\(.*\).$' 2> /dev/null` if [ -n "$topic" ]; then echo "$topic" > ${SHIRC_CHDIR}/${CHANNEL}.topic fi continue fi linkmsg=`expr "$line" : '^-link- \(.*\)' 2> /dev/null` if [ "$linkmsg" = "opened" ]; then if [ "$MODE" = "local" ]; then echo "**** link from ${RHOST} opened by ${LOGNAME}" >&$CHANNELFD else echo "**** link to ${RHOST} opened by ${LOGNAME}" >&$CHANNELFD fi echo "$$" > ${SHIRC_CHDIR}/${CHANNEL}.links/${RHOST} continue fi ruser=`expr "$linkmsg" : 'user in: \(.*\)' 2> /dev/null` if [ -n "$ruser" ]; then touch "${SHIRC_CHDIR}/${CHANNEL}.users/${ruser}@${RHOST}:$$" echo "*** ${ruser}@${RHOST} joined channel ${CHANNEL}" >&$CHANNELFD continue fi ruser=`expr "$linkmsg" : 'user out: \(.*\)' 2> /dev/null` if [ -n "$ruser" ]; then rm "${SHIRC_CHDIR}/${CHANNEL}.users/${ruser}@${RHOST}:$$" echo "*** ${ruser}@${RHOST} left channel ${CHANNEL}" >&$CHANNELFD continue fi topic=`expr "$linkmsg" : 'topic: \(.*\)' 2> /dev/null` if [ -n "$topic" ]; then if [ $MODE = 'connect' ]; then echo "$topic" > ${SHIRC_CHDIR}/${CHANNEL}.topic echo "**** topic@${RHOST}: $topic" >&$CHANNELFD fi continue fi done } parselog() { tail -n0 -f ${SHIRC_CHDIR}/${CHANNEL}.log | { while read line; do if echo "$line" | grep -q "@${RHOST}"; then continue; fi if echo "$line" | grep -q "^\*\*\*\* "; then continue; fi userout=`expr "$line" : '^\*\*\* \([^ ]*\) left channel .*' 2> /dev/null` if [ -n "$userout" ]; then if [ -n "$DEBUG" ]; then echo "${LHOST} send: -link- user out: $userout" >&2 fi echo "-link- user out: $userout" continue; fi userin=`expr "$line" : '^\*\*\* \([^ ]*\) joined channel .*' 2> /dev/null` if [ -n "$userin" ]; then if [ -n "$DEBUG" ]; then echo "${LHOST} send: -link- user in: $userin" >&2 fi echo "-link- user in: $userin" continue; fi if [ -n "$DEBUG" ]; then echo "${LHOST} send: $line" >&2 fi echo "$line" done } } local() { { handshake parselog } & readpid=$! parselink cleanup } connect() { { handshake parselog } | ssh ${RHOSTSSH} "shirc-link ${LHOST} \\${CHANNEL} local ${DEBUG}" | parselink cleanup } mkdir -p ${SHIRC_CHDIR}/${CHANNEL}.users mkdir -p ${SHIRC_CHDIR}/${CHANNEL}.links exec 3>>${SHIRC_CHDIR}/${CHANNEL}.log CHANNELFD=3 if [ "$MODE" = "local" ]; then local else connect fi