diff options
author | Andy Fiddaman <omnios@citrus-it.co.uk> | 2020-12-27 17:47:37 +0000 |
---|---|---|
committer | Andy Fiddaman <omnios@citrus-it.co.uk> | 2021-01-30 17:13:33 +0000 |
commit | b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f (patch) | |
tree | 6a37e590faffb9bb9af66887de645c546445036c /usr/src/lib/libshell/common/scripts/shircbot.sh | |
parent | df36e06d12cbf655ddf22339ef8c39fa2b83ebf8 (diff) | |
download | illumos-gate-b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f.tar.gz |
13405 ksh93 update to 2012-08-01
13434 sh: mishandles backslash as last character of a block of input
11750 ksh mkdir builtin doesn't honor special file permissions
9199 ksh93 builtin *grep -v mishandles blank lines, blows up libgcrypt-config
6756 sh (and ksh) have issues with ${1+"$@"}
6520 ksh: sleep could wait forever
4860 ksh93: core in printf
3791 /bin/sh's builtin 'rm' busted: 'rm -f' without arguments returns error
1047 ksh overwrites child core files
880 ksh93 coredumps on 'unset'
499 "interrupted system call" when using "tee" builtin in ksh
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Reviewed by: Dominik Hassler <hadfl@omnios.org>
Approved by: Rich Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src/lib/libshell/common/scripts/shircbot.sh')
-rw-r--r-- | usr/src/lib/libshell/common/scripts/shircbot.sh | 428 |
1 files changed, 0 insertions, 428 deletions
diff --git a/usr/src/lib/libshell/common/scripts/shircbot.sh b/usr/src/lib/libshell/common/scripts/shircbot.sh deleted file mode 100644 index 82903c53b1..0000000000 --- a/usr/src/lib/libshell/common/scripts/shircbot.sh +++ /dev/null @@ -1,428 +0,0 @@ -#!/usr/bin/ksh93 - -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -# - -# -# shircbot - a simple IRC client/bot demo -# - -# Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant -export PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin - -# Make sure all math stuff runs in the "C" locale to avoid problems -# with alternative # radix point representations (e.g. ',' instead of -# '.' in de_DE.*-locales). This needs to be set _before_ any -# floating-point constants are defined in this script). -if [[ "${LC_ALL}" != "" ]] ; then - export \ - LC_MONETARY="${LC_ALL}" \ - LC_MESSAGES="${LC_ALL}" \ - LC_COLLATE="${LC_ALL}" \ - LC_CTYPE="${LC_ALL}" - unset LC_ALL -fi -export LC_NUMERIC=C - -function fatal_error -{ - print -u2 "${progname}: $*" - exit 1 -} - -# Definition for a IRC session class -typeset -T ircsession_t=( - compound server=( - typeset name - integer port - ) - - typeset nick="ksh93irc" - - typeset running=true - - integer fd=-1 - - function createsession - { - set -o xtrace - - _.server.name=$1 - _.server.port=$2 - _.nick=$3 - - redirect {_.fd}<> "/dev/tcp/${_.server.name}/${_.server.port}" - (( $? == 0 )) || { print -n2 $"Could not open server connection." ; return 1 ; } - - printf "fd=%d\n" _.fd - - return 0 - } - - function login - { - { - printf "USER %s %s %s %s\n" "${_.nick}" "${_.nick}" "${_.nick}" "${_.nick}" - printf "NICK %s\n" "${_.nick}" - } >&${_.fd} - - return 0 - } - - function join_channel - { - printf "JOIN %s\n" "$1" >&${_.fd} - - return 0 - } - - function mainloop - { - typeset line - float -S last_tick=0 - # We use the linebuf_t class here since network traffic - # isn't guranteed to fit a single $'\n'-terminated line - # into one TCP package. linebuf_t buffers characters - # until it has one complete line. This avoids the need for - # async I/O normally used by IRC clients - linebuf_t serverbuf - linebuf_t clientbuf - integer fd=${_.fd} - - _.login - - while ${_.running} ; do - while serverbuf.readbuf line <&${fd} ; do - _.dispatch_serverevent "$line" - done - - while clientbuf.readbuf line </dev/stdin ; do - printf "client: %q\n" "${line}" - printf "%s\n" "${line}" >&${fd} - done - - # call mainloop_tick function in intervals to handle - # async events (e.g. automatic /join etc.) - if (( (SECONDS-last_tick) > 5. )) ; then - (( last_tick=SECONDS )) - _.mainloop_tick - fi - done - - return 0 - } - - function mainloop_tick - { - return 0 - } - - function dispatch_serverevent - { - typeset line="$1" - - case "${line}" in - ~(El)PING) - compound ping_args=( - line="$line" - ) - _.serverevent_ping "ping_args" - ;; - ~(El):.*\ PRIVMSG) - compound privmsg_args=( - typeset line="$line" - typeset msguser="${line/~(Elr)([^ ]+) ([^ ]+) ([^ ]+) (.*)/\1}" - typeset msgchannel="${line/~(Elr)([^ ]+) ([^ ]+) ([^ ]+) (.*)/\3}" - typeset msg="${line/~(Elr)([^ ]+) ([^ ]+) ([^ ]+) (.*)/\4}" - ) - _.serverevent_privmsg "privmsg_args" - ;; - ~(El):.*\ INVITE) - compound invite_args=( - typeset line="$line" - typeset inviteuser="${line/~(Elr)([^ ]+) ([^ ]+) ([^ ]+) (.*)/\1}" - typeset invitenick="${line/~(Elr)([^ ]+) ([^ ]+) ([^ ]+) (.*)/\3}" - typeset invitechannel="${line/~(Elr)([^ ]+) ([^ ]+) ([^ ]+) (.*)/\4}" - ) - _.serverevent_invite "invite_args" - ;; - *) - printf "server: %q\n" "${line}" - ;; - esac - - return 0 - } - - function serverevent_privmsg - { - nameref args=$1 - typeset msguser="${args.msguser}" - typeset msgchannel="${args.msgchannel}" - typeset msg="${args.msg}" - - printf "#privms: user=%q, channel=%q, msg=%q\n" "$msguser" "$msgchannel" "$msg" - - return 0 - } - - function serverevent_invite - { - nameref args=$1 - - printf "JOIN %s\n" "${args.invitechannel/:/}" >&${_.fd} - - return 0 - } - - function send_privmsg - { - typeset channel="$1" - typeset msg="$2" - - # Do we have to escape any characters in "msg" ? - printf "PRIVMSG %s :%s\n" "${channel}" "${msg}" >&${_.fd} - - return 0 - } - - function serverevent_ping - { - nameref args=$1 - - printf "PONG %s\n" "${args.line/~(Elr)([^ ]+) ([^ ]+).*/\2}" >&${_.fd} - - return 0 - } -) - -# line buffer class -# The buffer class tries to read characters from the given <fd> until -# it has read a whole line. -typeset -T linebuf_t=( - typeset buf - - function reset - { - _.buf="" - return 0 - } - - function readbuf - { - nameref var=$1 - typeset ch - - while IFS='' read -t 0.2 -N 1 ch ; do - [[ "$ch" == $'\r' ]] && continue - - if [[ "$ch" == $'\n' ]] ; then - var="${_.buf}" - _.reset - return 0 - fi - - _.buf+="$ch" - done - - return 1 - } -) - -function usage -{ - OPTIND=0 - getopts -a "${progname}" "${shircbot_usage}" OPT '-?' - exit 2 -} - -# program start -# (be carefull with builtins here - they are unconditionally available -# in the shell's "restricted" mode) -builtin basename -builtin sum - -typeset progname="${ basename "${0}" ; }" - -typeset -r shircbot_usage=$'+ -[-?\n@(#)\$Id: shircbot (Roland Mainz) 2009-09-09 \$\n] -[-author?Roland Mainz <roland.mainz@sun.com>] -[-author?Roland Mainz <roland.mainz@nrubsig.org>] -[+NAME?shircbot - simple IRC bot demo] -[+DESCRIPTION?\bshircbot\b is a small demo IRC bot which provides - a simple IRC bot with several subcommands.] -[n:nickname?IRC nickname for this bot.]:[nick] -[s:ircserver?IRC servername.]:[servername] -[j:joinchannel?IRC servername.]:[channelname] -[+SEE ALSO?\bksh93\b(1)] -' - -compound config=( - typeset nickname="${LOGNAME}bot" - typeset servername="irc.freenode.net" - integer port=6667 - typeset -a join_channels -) - -while getopts -a "${progname}" "${shircbot_usage}" OPT ; do -# printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|" - case ${OPT} in - n) config.nickname="${OPTARG}" ;; - s) config.servername="${OPTARG}" ;; - j) config.join_channels+=( "${OPTARG}" ) ;; - *) usage ;; - esac -done -shift $((OPTIND-1)) - -# if no channel was provided we join a predefined set of channels -if (( ${#config.join_channels[@]} == 0 )) ; then - if [[ "${config.servername}" == "irc.freenode.net" ]] ; then - config.join_channels+=( "#opensolaris" ) - config.join_channels+=( "#opensolaris-dev" ) - config.join_channels+=( "#opensolaris-arc" ) - config.join_channels+=( "#opensolaris-meeting" ) - config.join_channels+=( "#ospkg" ) - config.join_channels+=( "#ksh" ) - elif [[ "${config.servername}" == ~(E)irc.(sfbay|sweden) ]] ; then - config.join_channels+=( "#onnv" ) - fi -fi - -print "## Start." - -ircsession_t mybot - -# override ircsession_t::serverevent_privmsg with a new method for our bot -function mybot.serverevent_privmsg -{ - nameref args=$1 - typeset msguser="${args.msguser}" - typeset msgchannel="${args.msgchannel}" - typeset msg="${args.msg}" - - printf "#message: user=%q, channel=%q, msg=%q\n" "$msguser" "$msgchannel" "$msg" - - # Check if we get a private message - if [[ "${msgchannel}" == "${_.nick}" ]] ; then - # ${msgchannel} point to our own nick if we got a private message, - # we need to extract the sender's nickname from ${msguser} and put - # it into msgchannel - msgchannel="${msguser/~(El):(.*)!.*/\1}" - else - # check if this is a command for this bot - [[ "$msg" != ~(Eli):${_.nick}:[[:space:]] ]] && return 0 - fi - - # strip beginning (e.g. ":<nick>:" or ":") plus extra spaces - msg="${msg/~(Eli)(:${_.nick})*:[[:space:]]*/}" - - printf "botmsg=%q\n" "$msg" - - case "$msg" in - ~(Eli)date) - _.send_privmsg "$msgchannel" "${ - printf "%(%Y-%m-%d, %Th/%Z)T\n" - }" - ;; - ~(Eli)echo) - _.send_privmsg "$msgchannel" "${msg#*echo}" - ;; - ~(Eli)exitbot) - typeset exitkey="$(print "$msguser" | sum -x sha1)" # this is unwise&&insecure - if [[ "$msg" == *${exitkey}* ]] ; then - _.running=false - fi - ;; - ~(Eli)help) - _.send_privmsg "$msgchannel" "${ - printf "Hello, this is shircbot, written in ksh93 (%s). " "${.sh.version}" - printf "Subcommands are 'say hello', 'math <math-expr>', 'stocks', 'uuid', 'date' and 'echo'." - }" - ;; - ~(Eli)math) - if [[ "${msg}" == ~(E)[\`\$] ]] ; then - # "restricted" shell mode would prevent any damage but we try to be carefull... - _.send_privmsg "$msgchannel" "Syntax error." - else - typeset mathexpr="${msg#*math}" - - printf "Calculating '%s'\n" "${mathexpr}" - _.send_privmsg "$msgchannel" "${ - ( printf 'export PATH=/usr/${RANDOM}/$$/${RANDOM}/foo ; set -o restricted ; printf "%%s = %%.40g\n" "%s" $(( %s ))\n' "${mathexpr}" "${mathexpr}" | source /dev/stdin 2>&1 ) - }" - fi - ;; - ~(Eli)say\ hello) - _.send_privmsg "$msgchannel" "Hello, this is a bot." - ;; - ~(Eli)stocks) - typeset stockmsg tickersymbol - for tickersymbol in "JAVA" "ORCL" "IBM" "AAPL" "HPQ" ; do - stockmsg="$( /usr/sfw/bin/wget -q -O /dev/stdout "http://quote.yahoo.com/d/quotes.csv?f=sl1d1t1c1ohgv&e=.csv&s=${tickersymbol}" 2>&1 )" - _.send_privmsg "$msgchannel" "${tickersymbol}: ${stockmsg//,/ }" - done - ;; - ~(Eli)uuid) - _.send_privmsg "$msgchannel" "${ - print "%(%Y%M%D%S%N)T$((RANDOM))%s\n" "${msguser}" | sum -x sha256 - }" - ;; - esac - - return 0 -} - -# Automatically join the list of channels listed in |config.join_channels| -# after the client is connected to the server for some time -function mybot.mainloop_tick -{ - integer -S autojoin_done=2 - integer i - - if (( autojoin_done-- == 0 && ${#config.join_channels[@]} > 0 )) ; then - print "# Autojoin channels..." - - for ((i=0 ; i < ${#config.join_channels[@]} ; i++ )) ; do - mybot.join_channel "${config.join_channels[i]}" - done - fi - - return 0 -} - -mybot.createsession "${config.servername}" ${config.port} "${config.nickname}" - -# This is a network-facing application - once we've set eveything up -# we set PATH to a random value and switch to the shell's restricted -# mode to make sure noone can escape the jail. -#export PATH=/usr/$RANDOM/foo -#set -o restricted - -mybot.mainloop - -print "## End." - -exit 0 |