#!/bin/bash # IOSH version 0.8.1. # Copyright (C) 2006 Matous Jan Fialka. # Released under the terms of GNU/GPL. # RUNNING VIA XINETD (file: /etc/xinetd.d/iosh) # service iosh # { # disable = no # type = UNLISTED # protocol = tcp # port = 2323 # socket_type = stream # wait = no # server = /path/to/in.ioshd # user = root # } # RUNNING VIA NETCAT (can be run by ordinary user) # /path/to/{nc|netcat} -l localhost -p 2323 -c /path/to/in.ioshd # TELNET I/O FUNCTIONS twait() { local BYTE= local SEQN= while : do BYTE= IFS= read -s -r -n 1 -t ${2:-1} BYTE if [[ "$BYTE" == '' ]] then return 1 fi SEQN="$SEQN$BYTE" if [[ "$SEQN" == "$1" ]] then return 0 fi done } techo() { echo -e -n "$@" } tln() { techo '\r\n' } tbs() { local COUNT=0 while : do techo '\b \b' if [[ $COUNT = ${1:-0} ]] then break fi let COUNT++ done } techoln() { techo "$@" tln } tlnecho() { tln techo "$@" } tlnecholn() { tlnecho "$@" tln } treadln() # CODE INPUT TIMEOUT/CLOSE DESCRIPTION # 0 + - input if no timeout/close # 1 + + input if timeout/close # 2 - + no input if timeout/close # 3 - - no input if no timeout/close { local TIME=${1:-0} local LINE=${2:-REPLY} local BYTE=${3:-REPLY_LASTKEY} local LENG=0 local EXIT=0 local TEMP="" while : do LENG="${!LINE}" LENG=${#LENG} if [[ $TIME == 0 ]] then IFS= read -s -r -n 1 $BYTE else IFS= read -s -r -n 1 -t $TIME $BYTE fi EXIT=$? if [[ $EXIT != 0 ]] then break fi if [[ "${!BYTE}" == $'\t' ]] then break fi case "${!BYTE}" in [ ]|"?") break ;; [- -]) continue ;; []) if [[ $LENG > 0 ]] then tbs let LENG-- TEMP="${!LINE}" export $LINE="${TEMP:0:$LENG}" fi continue ;; \\) techo "${!BYTE}" let LENG++ export $LINE="${!LINE}${!BYTE}${!BYTE}" continue ;; *) techo "${!BYTE}" let LENG++ export $LINE="${!LINE}${!BYTE}" continue ;; esac done if [[ $LENG > 0 ]] then if [[ $EXIT != 0 ]] then return 1 fi else if [[ $EXIT != 0 ]] then return 2 else return 3 fi fi return 0 } # TELNET NEGOTIATION # IAC WILL SUPPRESS-GO-AHEAD # IAC DO SUPPRESS-GO-AHEAD # IAC WILL ECHO # IAC DO ECHO techo $'\xFF'$'\xFB'$'\x01' twait $'\xFF'$'\xFD'$'\x01' || NOTEL=1 techo $'\xFF'$'\xFB'$'\x03' twait $'\xFF'$'\xFD'$'\x03' || NOTEL=1 # APPLICATION BANNER tln banner () { techoln 'Hello, this is IOSH (version 0.8.1).' techoln 'Copyright 2006 Matous Jan Fialka (license GNU/GPL).' tln } banner # WARNING ABOUT INVALID TELNET CLIENT if [[ $NOTEL == 1 ]] then tln techoln 'WARNING: Using invalid Telnet client?' fi # APPLICATION STARTUP HINT tln techoln "Type 'help' to get help." tln # APPLICATION LOOP while : do techo "IOSH> $COMMAND" treadln 180 COMMAND LASTKEY ECODE=$? if [[ $ECODE == 1 || $ECODE == 2 ]] then tln break fi case "$LASTKEY" in [$'\t'?]) tln continue ;; []) tln break ;; [ ]) techo '\e[2J\e[0;0H' continue ;; []) COMMAND= techo '\e[2K\r' continue ;; [ ]) tln ;; esac if [[ $ECODE == 3 ]] then continue fi case "$COMMAND" in help) techoln 'help banner clear quit' tln ;; banner) banner ;; clear) techo '\e[2J\e[0;0H' ;; quit) break ;; *) techoln "% Unknown command '$COMMAND'! Try 'help'." tln ;; esac COMMAND= done # THE END exit $ECODE