-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpancakes
executable file
·141 lines (114 loc) · 4.25 KB
/
pancakes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env bash
# writen by Ivan c00kiemon5ter Kanakarakis ~ <ivan.kanak[at]gmail.com>
path="$(dirname "$0")"
conf="${path}/sugar.conf"
cmds="${path}/donuts"
declare -A servers
# check configuration
if [[ ! -r "${conf}" ]] || ! source "${conf}"
then
printf -- 'error: cannot read configuration: %s\n' "${conf}"
exit 1
fi
# check commands
if [[ ! -r "${cmds}" ]]
then
printf -- 'error: cannot read commands: %s\n' "${cmds}"
exit 1
fi
# set raw flag
if [[ "$1" == '-r' ]]
then declare -r -i RAW=1
else declare -r -i RAW=0
fi
# set default values
: "${prefix:="${HOME}/irc"}"
: "${nickname:=pancakes}"
: "${realname:=cookiebot}"
: "${mode:=+i}"
: "${hostname:=cookiebox}"
: "${servername:=biscuit}"
: "${port:=6667}"
for server in "${!servers[@]}"
do
mkdir -p "${prefix}/${server}/${nickname}"
exec {ircfd}<>"${prefix}/${server}/${server}.err" 2>&${ircfd}-
# open connection to irc server - skip if failure
if exec {ircfd}<>/dev/tcp/${server}/${port}
then
printf -- 'opened connection to server %s:%d\n' "${server}" "${port}"
else
printf -- 'unable to open connection to server %s:%d\n' "${server}" "${port}"
continue
fi
{ # identify to server
[[ -n "${passwd}" ]] && printf -- 'PASS %s\n' "${passwd}"
printf -- 'NICK %s\n' "${nickname}"
printf -- 'USER %s %s %s :%s\n' "${nickname}" "${hostname}" "${servername}" "${realname}"
printf -- 'MODE %s %s\n' "${nickname}" "${mode}"
} >&${ircfd}
# wait to get authed with the server
while read -r -u ${ircfd}
do
(( RAW )) && printf -- '%s\n' "$REPLY" >> "${prefix}/${server}/raw.log"
set -- ${REPLY//$'\r'/}
[[ "$1" == 'PING' ]] && printf -- 'PONG %s\n' "$2" >&${ircfd} && continue
[[ "$2" == '001' ]] && break
done && printf -- 'authed with server %s:%d\n' "${server}" "${port}"
# join the channels
for channel in ${servers[${server}]}
do
printf -- 'joining channel %s on %s:%d\n' "${channel}" "${server}" "${port}"
printf -- 'JOIN %s\n' "${channel}" >&${ircfd}
mkdir -p "${prefix}/${server}/${channel}"
fifo="${prefix}/${server}/${channel}/in"
# create fifo to talk to channel
rm -f "${fifo}"
if ! mkfifo "${fifo}"
then
printf -- 'error: cannot create fifo %s for channel %s on %s:%d\n' "${fifo}" "${channel}" "${server}" "${port}"
continue
fi
exec {fffd}<>"${fifo}"
# read fifo input and print to appropriate channel
while read -r -u ${fffd}
do printf -- 'PRIVMSG %s :%s\n' "${channel}" "${REPLY}" >&${ircfd}
done &
printf -- 'ACTION %s\n' "Heya peoples :]" >&${fffd}
printf -- 'you can talk to %s through %s\n' "${channel}" "${fifo}"
done
(
trap 'exec {ircfd}>&-; rm -f ${prefix}/${server}/*/in; kill -TERM 0;' EXIT
# read raw irc feedback and process messages
while read -r -u ${ircfd}
do
read -r nick action chan mesg <<< "${REPLY%}"
# cleanup tokens
nick="${nick%\!*}"
nick="${nick#:}"
mesg="${mesg#:}"
[[ -e "${prefix}/${server}/${chan}" ]] || mkdir -p "${prefix}/${server}/${chan}"
(( RAW )) && printf -- '%s\n' "$REPLY" >> "${prefix}/${server}/raw.log"
(( RAW )) && printf -- '%s\n' "$REPLY" >> "${prefix}/${server}/${chan}/raw.log"
# keep connection alive and save feedback to log
if [[ "$nick" == 'PING' ]]
then printf -- 'PONG %s\n' "$2" >&${ircfd} && continue
else printf -- '%s <%s> %s\n' "$(date +"%F %R")" "${nick}" "${mesg}" >> "${prefix}/${server}/${chan}/out"
fi
# handle parts and joins
if [[ "${action}" == 'PART' ]]
then mesg='!PART'
elif [[ "${action}" == 'JOIN' ]]
then mesg='!JOIN'
elif [[ "${action}" != 'PRIVMSG' ]]
then continue
fi
# pick up urls and send a !url cmd if not a command already
[[ "${mesg}" =~ ^[^\!]*https?:// ]] && mesg='!url '"${mesg}"
# execute if command otherwise skip
[[ "${nick}" != "${nickname}" && "${mesg}" =~ ^\!.+ ]] || continue
exec "${cmds}" "${mesg#\!}" "${chan#}" "${nick#}" "${nickname}" "${prefix}" "${server}" | cut -c -255 >&${ircfd} &
done
) &
done