mirror of
https://github.com/EnergyMech/energymech.git
synced 2025-12-17 15:36:50 +00:00
merged .c files, fixed dcc/telnet clients lost on reset, rewrote reset some
This commit is contained in:
parent
5f0fdada3e
commit
33f72e424b
6
.gitignore
vendored
6
.gitignore
vendored
@ -32,15 +32,13 @@ root.zone*
|
|||||||
trick.conf
|
trick.conf
|
||||||
mech.trivscore
|
mech.trivscore
|
||||||
trivia/megatrivia.txt
|
trivia/megatrivia.txt
|
||||||
|
*.log
|
||||||
|
*.stats
|
||||||
|
|
||||||
# developer files
|
# developer files
|
||||||
.use_size
|
.use_size
|
||||||
conf
|
conf
|
||||||
debug*
|
debug*
|
||||||
*.log
|
|
||||||
*.stats
|
|
||||||
github
|
|
||||||
|
|
||||||
src/calc.c
|
src/calc.c
|
||||||
src/x
|
src/x
|
||||||
src/y
|
src/y
|
||||||
|
|||||||
6
Makefile
6
Makefile
@ -56,10 +56,10 @@ TESTFILES = config/cc.c config/endian.c config/inet_addr.c config/inet_aton.c co
|
|||||||
TRIVFILES = trivia/mkindex.c
|
TRIVFILES = trivia/mkindex.c
|
||||||
|
|
||||||
SRCFILES = src/alias.c src/auth.c src/bounce.c src/channel.c src/core.c src/ctcp.c src/debug.c src/dns.c \
|
SRCFILES = src/alias.c src/auth.c src/bounce.c src/channel.c src/core.c src/ctcp.c src/debug.c src/dns.c \
|
||||||
src/function.c src/gencmd.c src/greet.c src/help.c src/hostinfo.c src/irc.c src/kicksay.c src/main.c src/mega.c \
|
src/function.c src/gencmd.c src/greet.c src/help.c src/hostinfo.c src/irc.c src/main.c \
|
||||||
src/net.c src/note.c src/notify.c src/ons.c src/parse.c src/partyline.c src/perl.c src/prot.c \
|
src/net.c src/note.c src/ons.c src/parse.c src/partyline.c src/perl.c src/prot.c \
|
||||||
src/python.c src/reset.c src/seen.c src/shit.c src/io.c src/spy.c src/tcl.c \
|
src/python.c src/reset.c src/seen.c src/shit.c src/io.c src/spy.c src/tcl.c \
|
||||||
src/toybox.c src/trivia.c src/uptime.c src/user.c src/vars.c src/web.c \
|
src/toybox.c src/uptime.c src/user.c src/vars.c src/web.c \
|
||||||
src/lib/md5.c src/lib/md5.h src/lib/string.c
|
src/lib/md5.c src/lib/md5.h src/lib/string.c
|
||||||
|
|
||||||
HDRFILES = src/defines.h src/global.h src/h.h src/settings.h src/structs.h src/text.h src/usage.h
|
HDRFILES = src/defines.h src/global.h src/h.h src/settings.h src/structs.h src/text.h src/usage.h
|
||||||
|
|||||||
2
VERSIONS
2
VERSIONS
@ -1,5 +1,7 @@
|
|||||||
3.1 -- WORK IN PROGRESS (~April, 2018)
|
3.1 -- WORK IN PROGRESS (~April, 2018)
|
||||||
|
|
||||||
|
* Fixed: Issue #25, clients lost when doing reset, no more
|
||||||
|
* Fixed: compiler warnings and missing defines/conflicting defines with certain options
|
||||||
* Added: configure now saves the options selected in ./myconfig for later re-use
|
* Added: configure now saves the options selected in ./myconfig for later re-use
|
||||||
* Fixed: Missing ifdef BOTNET in user.c
|
* Fixed: Missing ifdef BOTNET in user.c
|
||||||
* Added: Git version hash included in version string if git environment is found.
|
* Added: Git version hash included in version string if git environment is found.
|
||||||
|
|||||||
46
configure
vendored
46
configure
vendored
@ -1499,16 +1499,6 @@ s|@PTSIZE_DEFINE64@|$PTSIZE_DEFINE64|;
|
|||||||
s|@UNALIGNED_MEM@|$UNALIGNED_MEM|;
|
s|@UNALIGNED_MEM@|$UNALIGNED_MEM|;
|
||||||
" < src/config.h.in >> src/config.h
|
" < src/config.h.in >> src/config.h
|
||||||
|
|
||||||
if [ "$install" = yes ]; then
|
|
||||||
make $makejobs -C src energymech
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$compile" = yes ]; then
|
|
||||||
make $makejobs -C src energymech
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
save_myconfig() {
|
save_myconfig() {
|
||||||
names="alias botnet bounce chanban ctcp dccfile debug dynamode dyncmd greet hostinfo idwrap ircd_ext libmusl md5
|
names="alias botnet bounce chanban ctcp dccfile debug dynamode dyncmd greet hostinfo idwrap ircd_ext libmusl md5
|
||||||
netcfg newbie note notify perl profiling python rawdns redirect seen session sha stats suppress tcl
|
netcfg newbie note notify perl profiling python rawdns redirect seen session sha stats suppress tcl
|
||||||
@ -1539,16 +1529,28 @@ if [ -w ./myconfig -o ! -e ./myconfig ]; then
|
|||||||
save_myconfig
|
save_myconfig
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ''
|
if [ "$install" = yes ]; then
|
||||||
echo 'All done. You can now "make install"'
|
make $makejobs -C src energymech
|
||||||
if [ ! "$cores" = 1 ]; then
|
exit
|
||||||
echo "For speedy compiling, use \`\`make -j$cores''"
|
|
||||||
fi
|
fi
|
||||||
echo ''
|
|
||||||
echo "Your chosen ./configure options have been saved to ./myconfig"
|
if [ "$compile" = yes ]; then
|
||||||
echo 'if you wish to save ./myconfig in its current state, chmod -w ./myconfig'
|
make $makejobs -C src energymech
|
||||||
echo ''
|
exit
|
||||||
echo 'Submit your bugreports at https://github.com/MadCamel/energymech/issues'
|
fi
|
||||||
echo ''
|
|
||||||
echo 'You have read the README file I hope?'
|
$out ''
|
||||||
echo ''
|
$out 'All done. You can now "make install"'
|
||||||
|
if [ ! "$cores" = 1 ]; then
|
||||||
|
$out "For speedy compiling, use \`\`make -j$cores''"
|
||||||
|
fi
|
||||||
|
$out ''
|
||||||
|
$out "Your chosen ./configure options have been saved to ./myconfig"
|
||||||
|
$out 'if you wish to save ./myconfig in its current state, chmod -w ./myconfig'
|
||||||
|
$out ''
|
||||||
|
$out 'Submit your bugreports at https://github.com/MadCamel/energymech/issues'
|
||||||
|
$out ''
|
||||||
|
$out 'You have read the README file I hope?'
|
||||||
|
$out ''
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -48,14 +48,14 @@ INCS = $(BASEINCLUDES) mcmd.h text.h usercombo.h
|
|||||||
TESTFILES = aliastest safepathtest
|
TESTFILES = aliastest safepathtest
|
||||||
|
|
||||||
OFILES = alias.o auth.o bounce.o channel.o core.o ctcp.o debug.o dns.o function.o greet.o \
|
OFILES = alias.o auth.o bounce.o channel.o core.o ctcp.o debug.o dns.o function.o greet.o \
|
||||||
help.o hostinfo.o io.o irc.o kicksay.o main.o net.o note.o notify.o ons.o parse.o partyline.o \
|
help.o hostinfo.o io.o irc.o main.o net.o note.o ons.o parse.o partyline.o \
|
||||||
perl.o prot.o python.o reset.o seen.o shit.o spy.o tcl.o toybox.o \
|
perl.o prot.o python.o reset.o seen.o shit.o spy.o tcl.o toybox.o \
|
||||||
trivia.o uptime.o user.o vars.o web.o lib/string.o @MD5_O@ @SHA_O@
|
uptime.o user.o vars.o web.o lib/string.o @MD5_O@ @SHA_O@
|
||||||
|
|
||||||
SRCFILES = alias.c auth.c bounce.c channel.c core.c ctcp.c debug.c dns.c function.c greet.c \
|
SRCFILES = alias.c auth.c bounce.c channel.c core.c ctcp.c debug.c dns.c function.c greet.c \
|
||||||
help.c hostinfo.c io.c irc.c kicksay.c main.c net.c note.c notify.c ons.c parse.c partyline.c \
|
help.c hostinfo.c io.c irc.c main.c net.c note.c ons.c parse.c partyline.c \
|
||||||
perl.c prot.c python.c reset.c seen.c shit.c spy.c tcl.c toybox.c \
|
perl.c prot.c python.c reset.c seen.c shit.c spy.c tcl.c toybox.c \
|
||||||
trivia.c uptime.c user.c vars.c web.c lib/string.c @MD5_C@ @SHA_C@
|
uptime.c user.c vars.c web.c lib/string.c @MD5_C@ @SHA_C@
|
||||||
|
|
||||||
.PHONY: all clean mega-install mega mega-static test commands
|
.PHONY: all clean mega-install mega mega-static test commands
|
||||||
|
|
||||||
@ -78,6 +78,8 @@ usercombo.h: gencmd
|
|||||||
githash.h: gencmd
|
githash.h: gencmd
|
||||||
./gencmd githash.h
|
./gencmd githash.h
|
||||||
|
|
||||||
|
global.h: githash.h
|
||||||
|
|
||||||
install: $(INSTALLNAME)
|
install: $(INSTALLNAME)
|
||||||
$(CHMOD) $(INSTALLMODE) $(INSTALLNAME)
|
$(CHMOD) $(INSTALLMODE) $(INSTALLNAME)
|
||||||
$(MV) $(INSTALLNAME) $(INSTALLDIR)
|
$(MV) $(INSTALLNAME) $(INSTALLDIR)
|
||||||
@ -107,12 +109,12 @@ mega-install: mega $(SRCFILES) $(INCS) usage.h
|
|||||||
$(MV) $(INSTALLNAME) $(INSTALLDIR)
|
$(MV) $(INSTALLNAME) $(INSTALLDIR)
|
||||||
|
|
||||||
mega: $(SRCFILES) $(INCS) usage.h
|
mega: $(SRCFILES) $(INCS) usage.h
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o $(INSTALLNAME) mega.c -DGENDATE="`./gencmd date`" -I. $(LPROF) $(LIBS) $(LDSCRIPT) $(PYINCLUDE) $(TCLINCLUDE) $(I_PERL) $(L_PERL)
|
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o $(INSTALLNAME) main.c -DMEGA_C -DGENDATE="`./gencmd date`" -I. $(LPROF) $(LIBS) $(LDSCRIPT) $(PYINCLUDE) $(TCLINCLUDE) $(I_PERL) $(L_PERL)
|
||||||
#@oc@ $(CROSS_COMPILE)objcopy -R .note -R .comment $(INSTALLNAME)
|
#@oc@ $(CROSS_COMPILE)objcopy -R .note -R .comment $(INSTALLNAME)
|
||||||
@sz@ size $(INSTALLNAME)
|
@sz@ size $(INSTALLNAME)
|
||||||
|
|
||||||
mega-static: $(SRCFILES) $(INCS) usage.h
|
mega-static: $(SRCFILES) $(INCS) usage.h
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o $(INSTALLNAME) mega.c -DGENDATE="`./gencmd date`" -I. $(LPROF) $(LIBS) $(LDSCRIPT) $(PYINCLUDE) $(TCLINCLUDE) $(I_PERL) $(L_PERL) -static
|
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o $(INSTALLNAME) main.c -DMEGA_C -DGENDATE="`./gencmd date`" -I. $(LPROF) $(LIBS) $(LDSCRIPT) $(PYINCLUDE) $(TCLINCLUDE) $(I_PERL) $(L_PERL) -static
|
||||||
#@oc@ $(CROSS_COMPILE)objcopy -R .note -R .comment $(INSTALLNAME)
|
#@oc@ $(CROSS_COMPILE)objcopy -R .note -R .comment $(INSTALLNAME)
|
||||||
@sz@ size $(INSTALLNAME)
|
@sz@ size $(INSTALLNAME)
|
||||||
|
|
||||||
@ -188,9 +190,6 @@ io.o: io.c $(INCS)
|
|||||||
irc.o: irc.c $(INCS)
|
irc.o: irc.c $(INCS)
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
||||||
|
|
||||||
kicksay.o: kicksay.c $(INCS)
|
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
|
||||||
|
|
||||||
main.o: main.c $(INCS) githash.h
|
main.o: main.c $(INCS) githash.h
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -DGENDATE="`./gencmd date`" $(CPROF) $(PYINCLUDE)
|
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -DGENDATE="`./gencmd date`" $(CPROF) $(PYINCLUDE)
|
||||||
|
|
||||||
@ -200,9 +199,6 @@ net.o: net.c $(INCS)
|
|||||||
note.o: note.c $(INCS)
|
note.o: note.c $(INCS)
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
||||||
|
|
||||||
notify.o: notify.c $(INCS)
|
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
|
||||||
|
|
||||||
ons.o: ons.c $(INCS)
|
ons.o: ons.c $(INCS)
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
||||||
|
|
||||||
@ -239,9 +235,6 @@ tcl.o: tcl.c $(INCS)
|
|||||||
toybox.o: toybox.c $(INCS)
|
toybox.o: toybox.c $(INCS)
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
||||||
|
|
||||||
trivia.o: trivia.c $(INCS)
|
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
|
||||||
|
|
||||||
uptime.o: uptime.c $(INCS)
|
uptime.o: uptime.c $(INCS)
|
||||||
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
|
||||||
|
|
||||||
|
|||||||
@ -108,7 +108,6 @@ LS const struct
|
|||||||
#endif
|
#endif
|
||||||
{ NULL, }};
|
{ NULL, }};
|
||||||
|
|
||||||
|
|
||||||
LS struct
|
LS struct
|
||||||
{
|
{
|
||||||
void *func;
|
void *func;
|
||||||
|
|||||||
40
src/h.h
40
src/h.h
@ -576,7 +576,7 @@ LS void do_banlist(COMMAND_ARGS) __page(CMD1_SEG);
|
|||||||
|
|
||||||
#ifdef PYTHON
|
#ifdef PYTHON
|
||||||
|
|
||||||
#ifdef DEBUG_C
|
#if defined(DEBUG_C) || defined(MEGA_C)
|
||||||
PyObject *python_hook(PyObject *self, PyObject *args, PyObject *keywds);
|
PyObject *python_hook(PyObject *self, PyObject *args, PyObject *keywds);
|
||||||
PyObject *python_unhook(PyObject *self, PyObject *args, PyObject *keywds);
|
PyObject *python_unhook(PyObject *self, PyObject *args, PyObject *keywds);
|
||||||
#endif
|
#endif
|
||||||
@ -655,7 +655,7 @@ LS void do_urlhist(COMMAND_ARGS) __page(CMD1_SEG);
|
|||||||
LS int tcl_timer_jump(Hook *hook);
|
LS int tcl_timer_jump(Hook *hook);
|
||||||
LS int tcl_parse_jump(char *from, char *rest, Hook *hook);
|
LS int tcl_parse_jump(char *from, char *rest, Hook *hook);
|
||||||
LS void tcl_dcc_complete(Client *client, int cps);
|
LS void tcl_dcc_complete(Client *client, int cps);
|
||||||
#ifdef DEBUG_C
|
#if defined(DEBUG_C) || defined(MEGA_C)
|
||||||
LS int tcl_hook(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
|
LS int tcl_hook(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
|
||||||
#endif
|
#endif
|
||||||
//LS int tcl_unhook(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
|
//LS int tcl_unhook(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
|
||||||
@ -673,32 +673,30 @@ LS void do_tcl(COMMAND_ARGS) __page(CMD1_SEG);
|
|||||||
|
|
||||||
/* toybox.c */
|
/* toybox.c */
|
||||||
|
|
||||||
LS int read_bigcharset_callback(char *rest);
|
LS int read_bigcharset_callback(char *);
|
||||||
LS int read_bigcharset(char *fname);
|
LS int read_bigcharset(char *);
|
||||||
LS int read_ascii(char *rest);
|
LS int read_ascii(char *);
|
||||||
|
LS void trivia_week_toppers(void);
|
||||||
|
LS void hint_one(void);
|
||||||
|
LS void hint_two(void);
|
||||||
|
LS void hint_three(void);
|
||||||
|
LS void trivia_cleanup(void);
|
||||||
|
LS void trivia_check(Chan *, char *);
|
||||||
|
LS void trivia_no_answer(void);
|
||||||
|
LS char *random_question(char *);
|
||||||
|
LS void trivia_question(void);
|
||||||
|
LS void trivia_tick(void);
|
||||||
|
LS void write_triviascore(void);
|
||||||
|
LS int trivia_score_callback(char *);
|
||||||
|
LS void read_triviascore(void);
|
||||||
LS void do_bigsay(COMMAND_ARGS) __page(CMD1_SEG);
|
LS void do_bigsay(COMMAND_ARGS) __page(CMD1_SEG);
|
||||||
LS void do_random_msg(COMMAND_ARGS) __page(CMD1_SEG);
|
LS void do_random_msg(COMMAND_ARGS) __page(CMD1_SEG);
|
||||||
LS void do_randtopic(COMMAND_ARGS) __page(CMD1_SEG);
|
LS void do_randtopic(COMMAND_ARGS) __page(CMD1_SEG);
|
||||||
LS void do_8ball(COMMAND_ARGS) __page(CMD1_SEG);
|
LS void do_8ball(COMMAND_ARGS) __page(CMD1_SEG);
|
||||||
LS void do_ascii(COMMAND_ARGS) __page(CMD1_SEG);
|
LS void do_ascii(COMMAND_ARGS) __page(CMD1_SEG);
|
||||||
LS void do_rand(COMMAND_ARGS) __page(CMD1_SEG);
|
LS void do_rand(COMMAND_ARGS) __page(CMD1_SEG);
|
||||||
|
LS void do_trivia(COMMAND_ARGS) __page(CMD1_SEG);
|
||||||
|
|
||||||
/* trivia.c */
|
|
||||||
|
|
||||||
void trivia_week_toppers(void);
|
|
||||||
void hint_one(void);
|
|
||||||
void hint_two(void);
|
|
||||||
void hint_three(void);
|
|
||||||
void trivia_cleanup(void);
|
|
||||||
void trivia_check(Chan *chan, char *rest);
|
|
||||||
void trivia_no_answer(void);
|
|
||||||
char *random_question(char *triv_rand);
|
|
||||||
void trivia_question(void);
|
|
||||||
void trivia_tick(void);
|
|
||||||
void write_triviascore(void);
|
|
||||||
int trivia_score_callback(char *rest);
|
|
||||||
void read_triviascore(void);
|
|
||||||
void do_trivia(COMMAND_ARGS) __page(CMD1_SEG);
|
|
||||||
|
|
||||||
/* uptime.c */
|
/* uptime.c */
|
||||||
|
|
||||||
|
|||||||
264
src/kicksay.c
264
src/kicksay.c
@ -1,264 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
EnergyMech, IRC bot software
|
|
||||||
Parts Copyright (c) 1997-2004 proton
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#define KICKSAY_C
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
#include "structs.h"
|
|
||||||
#include "global.h"
|
|
||||||
#include "h.h"
|
|
||||||
#include "text.h"
|
|
||||||
#include "mcmd.h"
|
|
||||||
|
|
||||||
KickSay *find_kicksay(char *text, char *channel)
|
|
||||||
{
|
|
||||||
KickSay *kick,*save;
|
|
||||||
int num,best;
|
|
||||||
|
|
||||||
save = NULL;
|
|
||||||
best = 0;
|
|
||||||
for(kick=current->kicklist;kick;kick=kick->next)
|
|
||||||
{
|
|
||||||
if (!channel || *kick->chan == '*' || !stringcasecmp(channel,kick->chan))
|
|
||||||
{
|
|
||||||
num = num_matches(kick->mask,text);
|
|
||||||
if (num > best)
|
|
||||||
{
|
|
||||||
best = num;
|
|
||||||
save = kick;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(save);
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_kicksay(Chan *chan, ChanUser *doer, char *text)
|
|
||||||
{
|
|
||||||
KickSay *kick,*save;
|
|
||||||
char *mask;
|
|
||||||
int action;
|
|
||||||
|
|
||||||
save = NULL;
|
|
||||||
action = -1;
|
|
||||||
for(kick=current->kicklist;kick;kick=kick->next)
|
|
||||||
{
|
|
||||||
if (*kick->chan == '*' || !stringcasecmp(chan->name,kick->chan))
|
|
||||||
{
|
|
||||||
if (!matches(kick->mask,text))
|
|
||||||
{
|
|
||||||
if (kick->action > action)
|
|
||||||
{
|
|
||||||
action = kick->action;
|
|
||||||
save = kick;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (save)
|
|
||||||
{
|
|
||||||
if (!action)
|
|
||||||
{
|
|
||||||
if (doer->flags & CU_KSWARN)
|
|
||||||
action = 1;
|
|
||||||
if (!(doer->flags & CU_KSWARN))
|
|
||||||
{
|
|
||||||
doer->flags |= CU_KSWARN;
|
|
||||||
to_server("NOTICE %s :%s\n",doer->nick,save->reason);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (action > 1)
|
|
||||||
{
|
|
||||||
mask = format_uh(get_nuh(doer),FUH_USERHOST);
|
|
||||||
if (action > 2)
|
|
||||||
{
|
|
||||||
add_shit("Auto KS",chan->name,mask,save->reason,2,now+3600);
|
|
||||||
}
|
|
||||||
if (!(doer->flags & CU_BANNED))
|
|
||||||
{
|
|
||||||
doer->flags |= CU_BANNED;
|
|
||||||
send_mode(chan,90,QM_RAWMODE,'+','b',mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (action && !(doer->flags & CU_KICKED))
|
|
||||||
{
|
|
||||||
doer->flags |= CU_KICKED;
|
|
||||||
send_kick(chan,CurrentNick,FMT_PLAIN,save->reason);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_kicksay(KickSay *kick)
|
|
||||||
{
|
|
||||||
KickSay **pp;
|
|
||||||
|
|
||||||
pp = ¤t->kicklist;
|
|
||||||
while(*pp)
|
|
||||||
{
|
|
||||||
if (*pp == kick)
|
|
||||||
{
|
|
||||||
*pp = kick->next;
|
|
||||||
Free((char**)&kick);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pp = &(*pp)->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void purge_kicklist(void)
|
|
||||||
{
|
|
||||||
while(current->kicklist)
|
|
||||||
remove_kicksay(current->kicklist);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* kicksay commands
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef NEWBIE
|
|
||||||
char *ks_actions[MAX_KS_LEVEL+1] = { "warn (0)","kick (1)","kickban (2)","autoshit (3)" };
|
|
||||||
#else
|
|
||||||
char *ks_actions[MAX_KS_LEVEL+1] = { "warn","kick","kickban","autoshit" };
|
|
||||||
#endif /* NEWBIE */
|
|
||||||
|
|
||||||
void do_kicksay(COMMAND_ARGS)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* on_msg checks: CARGS
|
|
||||||
*/
|
|
||||||
KickSay *kick;
|
|
||||||
char *channel,*mask;
|
|
||||||
int inum;
|
|
||||||
|
|
||||||
channel = chop(&rest);
|
|
||||||
if (!channel)
|
|
||||||
{
|
|
||||||
if (!current->kicklist)
|
|
||||||
{
|
|
||||||
to_user(from,"Kicksay list is empty");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (partyline_only_command(from))
|
|
||||||
return;
|
|
||||||
|
|
||||||
table_buffer("\037channel\037\t\037action\037\t\037string\037\t\037kick reason\037");
|
|
||||||
for(kick=current->kicklist;kick;kick=kick->next)
|
|
||||||
{
|
|
||||||
table_buffer(FMT_4XSTRTAB,kick->chan,ks_actions[kick->action],kick->mask,kick->reason);
|
|
||||||
}
|
|
||||||
table_send(from,2);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ischannel(channel) || *channel == '*')
|
|
||||||
{
|
|
||||||
|
|
||||||
if (get_useraccess(from,channel) < cmdaccess)
|
|
||||||
return;
|
|
||||||
|
|
||||||
inum = DEFAULT_KS_LEVEL;
|
|
||||||
if (*rest != '"')
|
|
||||||
{
|
|
||||||
inum = asc2int(chop(&rest));
|
|
||||||
if (errno || inum < 0 || inum > MAX_KS_LEVEL)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mask = get_token(&rest,"\"");
|
|
||||||
|
|
||||||
if (!mask || !*mask)
|
|
||||||
goto usage;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* check for previously existing kicks
|
|
||||||
*/
|
|
||||||
if ((kick = find_kicksay(mask,channel)) != NULL)
|
|
||||||
{
|
|
||||||
to_user(from,"I'm already kicking on \"%s\"",kick->mask);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dig out the reason (the rest)
|
|
||||||
*/
|
|
||||||
while(rest && *rest == ' ')
|
|
||||||
rest++;
|
|
||||||
if (!*rest)
|
|
||||||
goto usage;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* add it to the list
|
|
||||||
*/
|
|
||||||
set_mallocdoer(do_kicksay);
|
|
||||||
kick = (KickSay*)Calloc(sizeof(KickSay) + StrlenX(channel,mask,rest,NULL));
|
|
||||||
|
|
||||||
kick->next = current->kicklist;
|
|
||||||
current->kicklist = kick;
|
|
||||||
kick->action = inum;
|
|
||||||
|
|
||||||
if (!matches("\\*?*\\*",mask))
|
|
||||||
kick->chan = stringcpy(kick->mask,mask) + 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
kick->mask[0] = '*';
|
|
||||||
stringcpy(kick->mask+1,mask);
|
|
||||||
kick->chan = stringcat(kick->mask,MATCH_ALL) + 1;
|
|
||||||
}
|
|
||||||
kick->reason = stringcpy(kick->chan,channel) + 1;
|
|
||||||
stringcpy(kick->reason,rest);
|
|
||||||
|
|
||||||
to_user(from,"Now kicking on \"%s\" on %s",mask,channel);
|
|
||||||
current->ul_save++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
usage:
|
|
||||||
usage(from); /* usage for CurrentCmd->name */
|
|
||||||
}
|
|
||||||
|
|
||||||
void do_rkicksay(COMMAND_ARGS)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* on_msg checks: CARGS
|
|
||||||
*/
|
|
||||||
KickSay *kick;
|
|
||||||
char *channel;
|
|
||||||
|
|
||||||
channel = chop(&rest); /* cant be NULL (CARGS) */
|
|
||||||
if (!ischannel(channel) && *channel != '*')
|
|
||||||
goto usage;
|
|
||||||
|
|
||||||
if (!*rest)
|
|
||||||
goto usage;
|
|
||||||
|
|
||||||
if (!(kick = find_kicksay(rest,channel)))
|
|
||||||
{
|
|
||||||
to_user(from,"I'm not kicking on that");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
to_user(from,"No longer kicking on %s",kick->mask);
|
|
||||||
remove_kicksay(kick);
|
|
||||||
current->ul_save++;
|
|
||||||
return;
|
|
||||||
usage:
|
|
||||||
usage(from); /* usage for CurrentCmd->name */
|
|
||||||
}
|
|
||||||
58
src/main.c
58
src/main.c
@ -18,6 +18,62 @@
|
|||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
#ifdef MEGA_C
|
||||||
|
#define MAIN_C
|
||||||
|
#include "config.h"
|
||||||
|
#include "defines.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "global.h"
|
||||||
|
#ifdef TCL
|
||||||
|
#include <tcl.h>
|
||||||
|
#endif
|
||||||
|
#include "h.h"
|
||||||
|
#include "text.h"
|
||||||
|
#include "mcmd.h"
|
||||||
|
#undef MAIN_C
|
||||||
|
#define VARS_C
|
||||||
|
#include "settings.h"
|
||||||
|
#undef VARS_C
|
||||||
|
|
||||||
|
#include "alias.c"
|
||||||
|
#include "auth.c"
|
||||||
|
#include "bounce.c"
|
||||||
|
#include "channel.c"
|
||||||
|
#include "core.c"
|
||||||
|
#include "ctcp.c"
|
||||||
|
#include "debug.c"
|
||||||
|
#undef DEBUG_C
|
||||||
|
#include "dns.c"
|
||||||
|
#include "function.c"
|
||||||
|
#include "greet.c"
|
||||||
|
#include "help.c"
|
||||||
|
#include "hostinfo.c"
|
||||||
|
#include "io.c"
|
||||||
|
#include "irc.c"
|
||||||
|
#include "lib/string.c"
|
||||||
|
#include "net.c"
|
||||||
|
#include "note.c"
|
||||||
|
#include "ons.c"
|
||||||
|
#include "parse.c"
|
||||||
|
#include "partyline.c"
|
||||||
|
#if defined(TCL) && defined(PERL)
|
||||||
|
#undef STRINGIFY
|
||||||
|
#endif
|
||||||
|
#include "perl.c"
|
||||||
|
#include "prot.c"
|
||||||
|
#include "python.c"
|
||||||
|
#include "reset.c"
|
||||||
|
#include "seen.c"
|
||||||
|
#include "shit.c"
|
||||||
|
#include "spy.c"
|
||||||
|
#include "tcl.c"
|
||||||
|
#include "toybox.c"
|
||||||
|
#include "uptime.c"
|
||||||
|
#include "user.c"
|
||||||
|
#include "vars.c"
|
||||||
|
#include "web.c"
|
||||||
|
#else /* ifdef MEGA_C */
|
||||||
|
|
||||||
#define MAIN_C
|
#define MAIN_C
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@ -28,6 +84,8 @@
|
|||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "mcmd.h"
|
#include "mcmd.h"
|
||||||
|
|
||||||
|
#endif /* ifdef-else MEGA_C */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we generally try to mess around as little as possible here
|
* we generally try to mess around as little as possible here
|
||||||
*/
|
*/
|
||||||
|
|||||||
50
src/mega.c
50
src/mega.c
@ -1,50 +0,0 @@
|
|||||||
#define MAIN_C
|
|
||||||
#include "config.h"
|
|
||||||
#include "defines.h"
|
|
||||||
#include "structs.h"
|
|
||||||
#include "global.h"
|
|
||||||
#include "h.h"
|
|
||||||
#include "text.h"
|
|
||||||
#include "mcmd.h"
|
|
||||||
#undef MAIN_C
|
|
||||||
#define VARS_C
|
|
||||||
#include "settings.h"
|
|
||||||
#undef VARS_C
|
|
||||||
|
|
||||||
#include "alias.c"
|
|
||||||
#include "auth.c"
|
|
||||||
#include "bounce.c"
|
|
||||||
#include "channel.c"
|
|
||||||
#include "core.c"
|
|
||||||
#include "ctcp.c"
|
|
||||||
#include "debug.c"
|
|
||||||
#include "dns.c"
|
|
||||||
#include "function.c"
|
|
||||||
#include "greet.c"
|
|
||||||
#include "help.c"
|
|
||||||
#include "hostinfo.c"
|
|
||||||
#include "io.c"
|
|
||||||
#include "irc.c"
|
|
||||||
#include "kicksay.c"
|
|
||||||
#include "lib/string.c"
|
|
||||||
#include "main.c"
|
|
||||||
#include "net.c"
|
|
||||||
#include "note.c"
|
|
||||||
#include "notify.c"
|
|
||||||
#include "ons.c"
|
|
||||||
#include "parse.c"
|
|
||||||
#include "partyline.c"
|
|
||||||
#include "perl.c"
|
|
||||||
#include "prot.c"
|
|
||||||
#include "python.c"
|
|
||||||
#include "reset.c"
|
|
||||||
#include "seen.c"
|
|
||||||
#include "shit.c"
|
|
||||||
#include "spy.c"
|
|
||||||
#include "tcl.c"
|
|
||||||
#include "toybox.c"
|
|
||||||
#include "trivia.c"
|
|
||||||
#include "uptime.c"
|
|
||||||
#include "user.c"
|
|
||||||
#include "vars.c"
|
|
||||||
#include "web.c"
|
|
||||||
@ -1354,8 +1354,13 @@ void parse_botnet(BotNet *bn, char *rest)
|
|||||||
#ifdef TELNET
|
#ifdef TELNET
|
||||||
if (bn->status == BN_UNKNOWN)
|
if (bn->status == BN_UNKNOWN)
|
||||||
{
|
{
|
||||||
if (!stringcmp(rest,telnetprompt)) // another bot sent me its telnetprompt
|
if (rest[0] == 'B' && rest[1] == 'B' && (attrtab[(uchar)rest[2]] & NUM))
|
||||||
|
{
|
||||||
|
basicBanner(bn,rest+2);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
//if (!stringcmp(rest,telnetprompt)) // another bot sent me its telnetprompt // dont assume identical prompts
|
||||||
|
// return;
|
||||||
#ifdef NETCFG
|
#ifdef NETCFG
|
||||||
if (strncmp(rest,"netcfg ",7) == 0)
|
if (strncmp(rest,"netcfg ",7) == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
753
src/notify.c
753
src/notify.c
@ -1,753 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
EnergyMech, IRC bot software
|
|
||||||
Copyright (c) 2001-2004 proton
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#define NOTIFY_C
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#ifdef NOTIFY
|
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
#include "structs.h"
|
|
||||||
#include "global.h"
|
|
||||||
#include "h.h"
|
|
||||||
#include "text.h"
|
|
||||||
|
|
||||||
#define CHOOSE_NUMBER 25
|
|
||||||
#define CHOOSE_MOVETO (CHOOSE_NUMBER - 2)
|
|
||||||
|
|
||||||
#define LOGFILENAMEFMT "notify-guid%i.log"
|
|
||||||
#define LOGFILENAMEBUF 32 /* need to recalculate this if LOGFILENAMEFMT is changed */
|
|
||||||
|
|
||||||
LS Notify **endoflist;
|
|
||||||
LS int lock_ison = FALSE;
|
|
||||||
|
|
||||||
void purge_notify(void)
|
|
||||||
{
|
|
||||||
Notify *nf;
|
|
||||||
nfLog *nlog;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* empty the notifylist
|
|
||||||
*/
|
|
||||||
while(current->notifylist)
|
|
||||||
{
|
|
||||||
nf = current->notifylist;
|
|
||||||
current->notifylist = nf->next;
|
|
||||||
while(nf->log)
|
|
||||||
{
|
|
||||||
nlog = nf->log;
|
|
||||||
nf->log = nlog->next;
|
|
||||||
Free((char**)&nlog);
|
|
||||||
}
|
|
||||||
Free((char**)&nf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int mask_check(Notify *nf, char *userhost)
|
|
||||||
{
|
|
||||||
char *mask,*rest;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* no mask (NULL)
|
|
||||||
*/
|
|
||||||
if (!nf->mask)
|
|
||||||
return(NF_MASKONLINE);
|
|
||||||
|
|
||||||
ret = NF_NOMATCH;
|
|
||||||
if (nf->endofmask)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* multiple masks separated by spaces
|
|
||||||
*/
|
|
||||||
mask = rest = nf->mask;
|
|
||||||
chop(&rest);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* single mask
|
|
||||||
*/
|
|
||||||
if (!matches(nf->mask,userhost))
|
|
||||||
ret = NF_MASKONLINE;
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
while(mask)
|
|
||||||
{
|
|
||||||
if (!matches(mask,userhost))
|
|
||||||
{
|
|
||||||
ret = NF_MASKONLINE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mask = chop(&rest);
|
|
||||||
}
|
|
||||||
if (nf->endofmask)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* undo the chop()'s
|
|
||||||
*/
|
|
||||||
for(mask=nf->mask;mask<nf->endofmask;mask++)
|
|
||||||
{
|
|
||||||
if (*mask == 0)
|
|
||||||
*mask = ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
void send_ison(void)
|
|
||||||
{
|
|
||||||
Notify *nf,*chosen[CHOOSE_NUMBER];
|
|
||||||
char isonmsg[MSGLEN];
|
|
||||||
char *p,*src;
|
|
||||||
int i,x,period;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dont send nicks to ISON too often
|
|
||||||
*/
|
|
||||||
period = current->setting[INT_ISONDELAY].int_var;
|
|
||||||
x = now - current->lastnotify;
|
|
||||||
if ((x < period) || (lock_ison && (x < 600)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
current->lastnotify = now;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the nature of the code makes it so that the first NULL is
|
|
||||||
* pushed further down the list as more entries are added,
|
|
||||||
* so no need to blank the whole list
|
|
||||||
*/
|
|
||||||
chosen[0] = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* select the oldest (CHOOSE_NUMBER) nicks for an update
|
|
||||||
*/
|
|
||||||
for(nf=current->notifylist;nf;nf=nf->next)
|
|
||||||
{
|
|
||||||
for(i=0;i<CHOOSE_NUMBER;i++)
|
|
||||||
{
|
|
||||||
if (!chosen[i] || (chosen[i]->checked > nf->checked))
|
|
||||||
{
|
|
||||||
for(x=CHOOSE_MOVETO;x>=i;x--)
|
|
||||||
chosen[x+1] = chosen[x];
|
|
||||||
chosen[i] = nf;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (chosen[0])
|
|
||||||
{
|
|
||||||
p = isonmsg;
|
|
||||||
for(i=0;i<CHOOSE_NUMBER;i++)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* drop out once the end-of-chosen-list NULL is found
|
|
||||||
*/
|
|
||||||
if (!chosen[i])
|
|
||||||
break;
|
|
||||||
chosen[i]->checked = 1;
|
|
||||||
src = chosen[i]->nick;
|
|
||||||
if (i) *(p++) = ' ';
|
|
||||||
while((*p = *(src++))) p++;
|
|
||||||
}
|
|
||||||
to_server("ISON :%s\n",isonmsg);
|
|
||||||
lock_ison = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void catch_ison(char *rest)
|
|
||||||
{
|
|
||||||
Notify *nf;
|
|
||||||
char whoismsg[MSGLEN];
|
|
||||||
char *nick,*dst;
|
|
||||||
|
|
||||||
lock_ison = FALSE;
|
|
||||||
*whoismsg = 0;
|
|
||||||
dst = whoismsg;
|
|
||||||
while((nick = chop(&rest)))
|
|
||||||
{
|
|
||||||
for(nf=current->notifylist;nf;nf=nf->next)
|
|
||||||
{
|
|
||||||
if (!nickcmp(nf->nick,nick))
|
|
||||||
{
|
|
||||||
nf->checked = now;
|
|
||||||
/*
|
|
||||||
* /whois user to get user@host + realname
|
|
||||||
*/
|
|
||||||
if (nf->status == NF_OFFLINE)
|
|
||||||
{
|
|
||||||
if (*whoismsg) *(dst++) = ',';
|
|
||||||
*dst = 0;
|
|
||||||
dst = stringcat(dst,nf->nick);
|
|
||||||
nf->status = NF_WHOIS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*whoismsg)
|
|
||||||
to_server("WHOIS %s\n",whoismsg);
|
|
||||||
|
|
||||||
for(nf=current->notifylist;nf;nf=nf->next)
|
|
||||||
{
|
|
||||||
if (nf->checked == 1)
|
|
||||||
{
|
|
||||||
nf->checked = now;
|
|
||||||
if (nf->status >= NF_WHOIS)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* close the log entry for this online period
|
|
||||||
*/
|
|
||||||
if (nf->log && nf->log->signon && !nf->log->signoff)
|
|
||||||
nf->log->signoff = now;
|
|
||||||
/*
|
|
||||||
* announce that the user is offline if its a mask match
|
|
||||||
*/
|
|
||||||
if (nf->status == NF_MASKONLINE)
|
|
||||||
send_spy(SPYSTR_STATUS,"Notify: %s is offline",nf->nick);
|
|
||||||
nf->status = NF_OFFLINE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void catch_whois(char *nick, char *userhost, char *realname)
|
|
||||||
{
|
|
||||||
Notify *nf;
|
|
||||||
nfLog *nlog;
|
|
||||||
|
|
||||||
if (!realname || !*realname)
|
|
||||||
realname = "unknown";
|
|
||||||
|
|
||||||
for(nf=current->notifylist;nf;nf=nf->next)
|
|
||||||
{
|
|
||||||
if ((nf->status == NF_WHOIS) && !nickcmp(nf->nick,nick))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* put in a new log entry
|
|
||||||
*/
|
|
||||||
set_mallocdoer(catch_whois);
|
|
||||||
nlog = (nfLog*)Calloc(sizeof(nfLog) + Strlen2(userhost,realname)); // realname is never NULL
|
|
||||||
nlog->signon = now;
|
|
||||||
nlog->next = nf->log;
|
|
||||||
nf->log = nlog;
|
|
||||||
nlog->realname = stringcat(nlog->userhost,userhost) + 1;
|
|
||||||
stringcpy(nlog->realname,realname);
|
|
||||||
/*
|
|
||||||
* if there is a mask, we need a match to announce the online status
|
|
||||||
*/
|
|
||||||
nf->status = mask_check(nf,userhost);
|
|
||||||
if (nf->status == NF_MASKONLINE)
|
|
||||||
send_spy(SPYSTR_STATUS,"Notify: %s (%s) is online",nf->nick,userhost);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* saving and loading notify information
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
int notifylog_callback(char *rest)
|
|
||||||
{
|
|
||||||
Notify *nf;
|
|
||||||
nfLog *nlog,**pp;
|
|
||||||
time_t on,off;
|
|
||||||
char *nick,*userhost;
|
|
||||||
|
|
||||||
if (*rest == COMMENT_CHAR)
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
nick = chop(&rest);
|
|
||||||
|
|
||||||
on = asc2int(chop(&rest));
|
|
||||||
if (errno)
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
off = asc2int(chop(&rest));
|
|
||||||
if (errno)
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
userhost = chop(&rest);
|
|
||||||
|
|
||||||
if (rest && *rest == ':')
|
|
||||||
rest++;
|
|
||||||
if (!*rest)
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
for(nf=current->notifylist;nf;nf=nf->next)
|
|
||||||
{
|
|
||||||
if (!nickcmp(nick,nf->nick))
|
|
||||||
{
|
|
||||||
pp = &nf->log;
|
|
||||||
while(*pp)
|
|
||||||
{
|
|
||||||
if ((*pp)->signon < on)
|
|
||||||
break;
|
|
||||||
pp = &(*pp)->next;
|
|
||||||
}
|
|
||||||
set_mallocdoer(notifylog_callback);
|
|
||||||
nlog = (nfLog*)Calloc(sizeof(nfLog) + Strlen2(userhost,rest)); // rest is never NULL
|
|
||||||
nlog->signon = on;
|
|
||||||
nlog->signoff = off;
|
|
||||||
nlog->next = *pp;
|
|
||||||
*pp = nlog;
|
|
||||||
nlog->realname = stringcat(nlog->userhost,userhost) + 1;
|
|
||||||
stringcpy(nlog->realname,rest);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_notifylog(void)
|
|
||||||
{
|
|
||||||
char fname[LOGFILENAMEBUF];
|
|
||||||
int fd;
|
|
||||||
#ifdef DEBUG
|
|
||||||
int dd;
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
sprintf(fname,LOGFILENAMEFMT,current->guid);
|
|
||||||
if ((fd = open(fname,O_RDONLY)) < 0)
|
|
||||||
return;
|
|
||||||
#ifdef DEBUG
|
|
||||||
dd = dodebug;
|
|
||||||
dodebug = FALSE;
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
readline(fd,¬ifylog_callback); /* readline closes fd */
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
dodebug = dd;
|
|
||||||
#endif /* DEBUG */
|
|
||||||
}
|
|
||||||
|
|
||||||
void write_notifylog(void)
|
|
||||||
{
|
|
||||||
Notify *nf;
|
|
||||||
nfLog *nlog;
|
|
||||||
char fname[LOGFILENAMEBUF];
|
|
||||||
int fd;
|
|
||||||
#ifdef DEBUG
|
|
||||||
int dd;
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
sprintf(fname,LOGFILENAMEFMT,current->guid);
|
|
||||||
if ((fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC,NEWFILEMODE)) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
dd = dodebug;
|
|
||||||
dodebug = FALSE;
|
|
||||||
#endif /* DEBUG */
|
|
||||||
for(nf=current->notifylist;nf;nf=nf->next)
|
|
||||||
{
|
|
||||||
to_file(fd,COMMENT_STRCHR "\n" COMMENT_STRCHR " Nick: %s\n",nf->nick);
|
|
||||||
if (nf->info)
|
|
||||||
to_file(fd,COMMENT_STRCHR " Note: %s\n",nf->info);
|
|
||||||
if (nf->mask)
|
|
||||||
to_file(fd,COMMENT_STRCHR " Mask: %s\n",nf->mask);
|
|
||||||
to_file(fd,COMMENT_STRCHR "\n");
|
|
||||||
for(nlog=nf->log;nlog;nlog=nlog->next)
|
|
||||||
{
|
|
||||||
to_file(fd,"%s %lu %lu %s :%s\n",nf->nick,nlog->signon,
|
|
||||||
(nlog->signoff) ? nlog->signoff : now,
|
|
||||||
nlog->userhost,nlog->realname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
#ifdef DEBUG
|
|
||||||
dodebug = dd;
|
|
||||||
#endif /* DEBUG */
|
|
||||||
}
|
|
||||||
|
|
||||||
int notify_callback(char *rest)
|
|
||||||
{
|
|
||||||
Notify *nf;
|
|
||||||
char *nick;
|
|
||||||
char *src,*dst;
|
|
||||||
char *lspace;
|
|
||||||
|
|
||||||
errno = EINVAL;
|
|
||||||
|
|
||||||
if (!rest || *rest == COMMENT_CHAR)
|
|
||||||
return(FALSE);
|
|
||||||
fix_config_line(rest);
|
|
||||||
if ((nick = chop(&rest)) == NULL)
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
debug("(notify_callback) parsing %s `%s'\n",nick,nullstr(rest));
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
lspace = rest - 1;
|
|
||||||
src = dst = rest;
|
|
||||||
while(*src)
|
|
||||||
{
|
|
||||||
if (*src == ' ')
|
|
||||||
{
|
|
||||||
if (!lspace)
|
|
||||||
{
|
|
||||||
lspace = dst;
|
|
||||||
*(dst++) = *src;
|
|
||||||
}
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (*src == ':' && lspace)
|
|
||||||
{
|
|
||||||
*lspace = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lspace = NULL;
|
|
||||||
*(dst++) = *(src++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*src == ':')
|
|
||||||
*(src++) = 0;
|
|
||||||
if (!*src)
|
|
||||||
src = NULL;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
debug("(notify_callback) creating struct\n");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* nick = nick
|
|
||||||
* rest = mask(s) or *rest == 0
|
|
||||||
* src = description or NULL
|
|
||||||
*/
|
|
||||||
set_mallocdoer(notify_callback);
|
|
||||||
nf = (Notify*)Calloc(sizeof(Notify) + StrlenX(nick,rest,src,NULL));
|
|
||||||
dst = stringcat(nf->nick,nick);
|
|
||||||
if (*rest)
|
|
||||||
{
|
|
||||||
nf->mask = dst + 1;
|
|
||||||
dst = stringcat(nf->mask,rest);
|
|
||||||
if (STRCHR(nf->mask,' '))
|
|
||||||
nf->endofmask = dst;
|
|
||||||
}
|
|
||||||
if (src)
|
|
||||||
{
|
|
||||||
nf->info = dst + 1;
|
|
||||||
stringcpy(nf->info,src);
|
|
||||||
}
|
|
||||||
/* put it at the end of notifylist */
|
|
||||||
*endoflist = nf;
|
|
||||||
endoflist = &nf->next;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int read_notify(char *filename)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
if (!filename)
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
if ((fd = open(filename,O_RDONLY)) < 0)
|
|
||||||
return(FALSE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* save online logs
|
|
||||||
*/
|
|
||||||
if (current->notifylist)
|
|
||||||
write_notifylog();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* delete the whole list
|
|
||||||
*/
|
|
||||||
purge_notify();
|
|
||||||
|
|
||||||
endoflist = ¤t->notifylist;
|
|
||||||
readline(fd,¬ify_callback); /* readline closes fd */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* read back online logs
|
|
||||||
*/
|
|
||||||
read_notifylog();
|
|
||||||
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* commands...
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define NF_OPTIONS 7
|
|
||||||
|
|
||||||
LS const char notify_opt[NF_OPTIONS][10] =
|
|
||||||
{
|
|
||||||
"-ALL",
|
|
||||||
"-NOMATCH",
|
|
||||||
"-RELOAD",
|
|
||||||
"-FULL",
|
|
||||||
"-SEEN",
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NFF_ALL 1
|
|
||||||
#define NFF_NOMATCH 2
|
|
||||||
#define NFF_RELOAD 4
|
|
||||||
#define NFF_FULL 8
|
|
||||||
#define NFF_SEEN 16
|
|
||||||
|
|
||||||
LS int nf_header;
|
|
||||||
|
|
||||||
void nfshow_brief(Notify *nf)
|
|
||||||
{
|
|
||||||
time_t when;
|
|
||||||
char mem[40];
|
|
||||||
char *s;
|
|
||||||
int d,h,m;
|
|
||||||
|
|
||||||
if (nf->status == NF_NOMATCH)
|
|
||||||
s = " nickname in use";
|
|
||||||
else
|
|
||||||
if (nf->status >= NF_WHOIS)
|
|
||||||
s = " online now";
|
|
||||||
else
|
|
||||||
if (nf->log && nf->log->signoff)
|
|
||||||
{
|
|
||||||
s = mem;
|
|
||||||
when = now - nf->log->signoff;
|
|
||||||
d = when / 86400;
|
|
||||||
h = (when -= d * 86400) / 3600;
|
|
||||||
m = (when -= h * 3600) / 60;
|
|
||||||
sprintf(mem,"%2i day%1s %02i:%02i ago",d,EXTRA_CHAR(d),h,m);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
s = " never seen";
|
|
||||||
|
|
||||||
if (!nf_header)
|
|
||||||
to_user(global_from,"\037nick\037 \037last seen\037 \037note\037");
|
|
||||||
to_user(global_from,(nf->info) ? "%-9s %-22s %s" : "%-9s %s",
|
|
||||||
nf->nick,s,nf->info);
|
|
||||||
nf_header++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nfshow_full(Notify *nf)
|
|
||||||
{
|
|
||||||
char mem[MSGLEN];
|
|
||||||
nfLog *nlog;
|
|
||||||
char *s,*opt;
|
|
||||||
|
|
||||||
if (nf_header)
|
|
||||||
to_user(global_from," ");
|
|
||||||
to_user(global_from,(nf->status == NF_MASKONLINE) ? "Nick: \037%s\037" : "Nick: %s",nf->nick);
|
|
||||||
if (nf->info)
|
|
||||||
to_user(global_from,"Note: %s",nf->info);
|
|
||||||
if (nf->mask)
|
|
||||||
to_user(global_from,"Mask: %s",nf->mask);
|
|
||||||
if (nf->log)
|
|
||||||
{
|
|
||||||
to_user(global_from,"Online history:");
|
|
||||||
for(nlog=nf->log;nlog;nlog=nlog->next)
|
|
||||||
{
|
|
||||||
opt = mem;
|
|
||||||
s = time2away(nlog->signon);
|
|
||||||
if (s[1] == ':')
|
|
||||||
*(opt++) = ' ';
|
|
||||||
*opt = 0;
|
|
||||||
opt = stringcat(opt,s);
|
|
||||||
while(opt < (mem+18))
|
|
||||||
*(opt++) = ' ';
|
|
||||||
*opt = 0;
|
|
||||||
opt = stringcat(opt," -- ");
|
|
||||||
if (nlog->signoff)
|
|
||||||
{
|
|
||||||
s = time2away(nlog->signoff);
|
|
||||||
if (s[1] == ':')
|
|
||||||
*(opt++) = ' ';
|
|
||||||
*opt = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s = " online now";
|
|
||||||
}
|
|
||||||
opt = stringcat(opt,s);
|
|
||||||
while(opt < (mem+41))
|
|
||||||
*(opt++) = ' ';
|
|
||||||
*opt = 0;
|
|
||||||
s = (nlog->realname) ? "%s: %s (%s)" : "%s: %s";
|
|
||||||
to_user(global_from,s,mem,nlog->userhost,nlog->realname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nf_header++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sub_notifynick(char *from, char *rest)
|
|
||||||
{
|
|
||||||
Notify *nf,**pp;
|
|
||||||
char *nick;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
nick = chop(&rest);
|
|
||||||
if (!nick)
|
|
||||||
{
|
|
||||||
usage(from);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
pp = ¤t->notifylist;
|
|
||||||
while(*pp)
|
|
||||||
{
|
|
||||||
nf = *pp;
|
|
||||||
if (!nickcmp(nick,nf->nick))
|
|
||||||
{
|
|
||||||
*pp = nf->next;
|
|
||||||
Free((char**)&nf);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pp = &nf->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!i)
|
|
||||||
to_user(from,"Nick not found: %s",nick);
|
|
||||||
else
|
|
||||||
to_user(from,"Nick removed from notify: %s",nick);
|
|
||||||
}
|
|
||||||
|
|
||||||
void do_notify(COMMAND_ARGS)
|
|
||||||
{
|
|
||||||
char message[MSGLEN];
|
|
||||||
Notify *nf;
|
|
||||||
nfLog *nlog;
|
|
||||||
char *opt;
|
|
||||||
int n,flags;
|
|
||||||
|
|
||||||
global_from = from;
|
|
||||||
flags = nf_header = 0;
|
|
||||||
*message = 0;
|
|
||||||
|
|
||||||
if (*rest)
|
|
||||||
{
|
|
||||||
while((opt = chop(&rest)))
|
|
||||||
{
|
|
||||||
if (!stringcmp(opt,"+"))
|
|
||||||
{
|
|
||||||
endoflist = ¤t->notifylist;
|
|
||||||
while(*endoflist)
|
|
||||||
endoflist = &(*endoflist)->next;
|
|
||||||
notify_callback(rest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!stringcmp(opt,"-"))
|
|
||||||
{
|
|
||||||
sub_notifynick(from,rest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for(n=0;n<NF_OPTIONS;n++)
|
|
||||||
{
|
|
||||||
if (!stringcasecmp(notify_opt[n],opt))
|
|
||||||
{
|
|
||||||
flags |= (1 << n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (n>=NF_OPTIONS)
|
|
||||||
{
|
|
||||||
for(nf=current->notifylist;nf;nf=nf->next)
|
|
||||||
{
|
|
||||||
if (!nickcmp(opt,nf->nick))
|
|
||||||
{
|
|
||||||
if (flags & NFF_FULL)
|
|
||||||
nfshow_full(nf);
|
|
||||||
else
|
|
||||||
nfshow_brief(nf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!nf)
|
|
||||||
{
|
|
||||||
if (*message)
|
|
||||||
stringcat(message,", ");
|
|
||||||
stringcat(message,opt);
|
|
||||||
}
|
|
||||||
nf_header++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*message)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
debug("(do_notify) dumping errnames\n");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
to_user(from,"User%s not found: %s",(STRCHR(message,',')) ? "s" : "",message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nf_header)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (flags & NFF_RELOAD)
|
|
||||||
{
|
|
||||||
opt = current->setting[STR_NOTIFYFILE].str_var;
|
|
||||||
if (opt && read_notify(opt))
|
|
||||||
{
|
|
||||||
flags = get_useraccess(from,"");
|
|
||||||
send_spy(SPYSTR_STATUS,"Notify: %s reloaded by %s[%i]",
|
|
||||||
opt,CurrentNick,flags);
|
|
||||||
to_user(from,"notify list read from file %s",opt);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
to_user(from,"notify list could not be read from file %s",nullstr(opt));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(nf=current->notifylist;nf;nf=nf->next)
|
|
||||||
{
|
|
||||||
if ((nf->status == NF_MASKONLINE) || (flags & NFF_ALL) || ((flags & NFF_NOMATCH) && (nf->status == NF_NOMATCH)))
|
|
||||||
goto show_it;
|
|
||||||
if ((flags & NFF_SEEN) && nf->log)
|
|
||||||
{
|
|
||||||
for(nlog=nf->log;nlog;nlog=nlog->next)
|
|
||||||
{
|
|
||||||
if (mask_check(nf,nlog->userhost) == NF_MASKONLINE)
|
|
||||||
goto show_it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
show_it:
|
|
||||||
if (flags & NFF_FULL)
|
|
||||||
nfshow_full(nf);
|
|
||||||
else
|
|
||||||
nfshow_brief(nf);
|
|
||||||
}
|
|
||||||
if (!nf_header)
|
|
||||||
{
|
|
||||||
to_user(from,"no notify users are online");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* NOTIFY */
|
|
||||||
237
src/prot.c
237
src/prot.c
@ -598,11 +598,111 @@ void chanban_action(char *nick, char *channel, Shit *shit)
|
|||||||
|
|
||||||
#endif /* CHANBAN */
|
#endif /* CHANBAN */
|
||||||
|
|
||||||
|
KickSay *find_kicksay(char *text, char *channel)
|
||||||
|
{
|
||||||
|
KickSay *kick,*save;
|
||||||
|
int num,best;
|
||||||
|
|
||||||
|
save = NULL;
|
||||||
|
best = 0;
|
||||||
|
for(kick=current->kicklist;kick;kick=kick->next)
|
||||||
|
{
|
||||||
|
if (!channel || *kick->chan == '*' || !stringcasecmp(channel,kick->chan))
|
||||||
|
{
|
||||||
|
num = num_matches(kick->mask,text);
|
||||||
|
if (num > best)
|
||||||
|
{
|
||||||
|
best = num;
|
||||||
|
save = kick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(save);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_kicksay(Chan *chan, ChanUser *doer, char *text)
|
||||||
|
{
|
||||||
|
KickSay *kick,*save;
|
||||||
|
char *mask;
|
||||||
|
int action;
|
||||||
|
|
||||||
|
save = NULL;
|
||||||
|
action = -1;
|
||||||
|
for(kick=current->kicklist;kick;kick=kick->next)
|
||||||
|
{
|
||||||
|
if (*kick->chan == '*' || !stringcasecmp(chan->name,kick->chan))
|
||||||
|
{
|
||||||
|
if (!matches(kick->mask,text))
|
||||||
|
{
|
||||||
|
if (kick->action > action)
|
||||||
|
{
|
||||||
|
action = kick->action;
|
||||||
|
save = kick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (save)
|
||||||
|
{
|
||||||
|
if (!action)
|
||||||
|
{
|
||||||
|
if (doer->flags & CU_KSWARN)
|
||||||
|
action = 1;
|
||||||
|
if (!(doer->flags & CU_KSWARN))
|
||||||
|
{
|
||||||
|
doer->flags |= CU_KSWARN;
|
||||||
|
to_server("NOTICE %s :%s\n",doer->nick,save->reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action > 1)
|
||||||
|
{
|
||||||
|
mask = format_uh(get_nuh(doer),FUH_USERHOST);
|
||||||
|
if (action > 2)
|
||||||
|
{
|
||||||
|
add_shit("Auto KS",chan->name,mask,save->reason,2,now+3600);
|
||||||
|
}
|
||||||
|
if (!(doer->flags & CU_BANNED))
|
||||||
|
{
|
||||||
|
doer->flags |= CU_BANNED;
|
||||||
|
send_mode(chan,90,QM_RAWMODE,'+','b',mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action && !(doer->flags & CU_KICKED))
|
||||||
|
{
|
||||||
|
doer->flags |= CU_KICKED;
|
||||||
|
send_kick(chan,CurrentNick,FMT_PLAIN,save->reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_kicksay(KickSay *kick)
|
||||||
|
{
|
||||||
|
KickSay **pp;
|
||||||
|
|
||||||
|
pp = ¤t->kicklist;
|
||||||
|
while(*pp)
|
||||||
|
{
|
||||||
|
if (*pp == kick)
|
||||||
|
{
|
||||||
|
*pp = kick->next;
|
||||||
|
Free((char**)&kick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pp = &(*pp)->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void purge_kicklist(void)
|
||||||
|
{
|
||||||
|
while(current->kicklist)
|
||||||
|
remove_kicksay(current->kicklist);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
-+=====================================================================================================================+-
|
||||||
* prot.c commands
|
prot.c commands
|
||||||
*
|
-+=====================================================================================================================+-
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void do_opdeopme(COMMAND_ARGS)
|
void do_opdeopme(COMMAND_ARGS)
|
||||||
{
|
{
|
||||||
@ -797,3 +897,132 @@ void do_banlist(COMMAND_ARGS)
|
|||||||
to_user(from,"There are no active bans on %s",to);
|
to_user(from,"There are no active bans on %s",to);
|
||||||
#endif /* IRCD_EXTENSIONS */
|
#endif /* IRCD_EXTENSIONS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NEWBIE
|
||||||
|
char *ks_actions[MAX_KS_LEVEL+1] = { "warn (0)","kick (1)","kickban (2)","autoshit (3)" };
|
||||||
|
#else
|
||||||
|
char *ks_actions[MAX_KS_LEVEL+1] = { "warn","kick","kickban","autoshit" };
|
||||||
|
#endif /* NEWBIE */
|
||||||
|
|
||||||
|
void do_kicksay(COMMAND_ARGS)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* on_msg checks: CARGS
|
||||||
|
*/
|
||||||
|
KickSay *kick;
|
||||||
|
char *channel,*mask;
|
||||||
|
int inum;
|
||||||
|
|
||||||
|
channel = chop(&rest);
|
||||||
|
if (!channel)
|
||||||
|
{
|
||||||
|
if (!current->kicklist)
|
||||||
|
{
|
||||||
|
to_user(from,"Kicksay list is empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (partyline_only_command(from))
|
||||||
|
return;
|
||||||
|
|
||||||
|
table_buffer("\037channel\037\t\037action\037\t\037string\037\t\037kick reason\037");
|
||||||
|
for(kick=current->kicklist;kick;kick=kick->next)
|
||||||
|
{
|
||||||
|
table_buffer(FMT_4XSTRTAB,kick->chan,ks_actions[kick->action],kick->mask,kick->reason);
|
||||||
|
}
|
||||||
|
table_send(from,2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ischannel(channel) || *channel == '*')
|
||||||
|
{
|
||||||
|
|
||||||
|
if (get_useraccess(from,channel) < cmdaccess)
|
||||||
|
return;
|
||||||
|
|
||||||
|
inum = DEFAULT_KS_LEVEL;
|
||||||
|
if (*rest != '"')
|
||||||
|
{
|
||||||
|
inum = asc2int(chop(&rest));
|
||||||
|
if (errno || inum < 0 || inum > MAX_KS_LEVEL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = get_token(&rest,"\"");
|
||||||
|
|
||||||
|
if (!mask || !*mask)
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check for previously existing kicks
|
||||||
|
*/
|
||||||
|
if ((kick = find_kicksay(mask,channel)) != NULL)
|
||||||
|
{
|
||||||
|
to_user(from,"I'm already kicking on \"%s\"",kick->mask);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dig out the reason (the rest)
|
||||||
|
*/
|
||||||
|
while(rest && *rest == ' ')
|
||||||
|
rest++;
|
||||||
|
if (!*rest)
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add it to the list
|
||||||
|
*/
|
||||||
|
set_mallocdoer(do_kicksay);
|
||||||
|
kick = (KickSay*)Calloc(sizeof(KickSay) + StrlenX(channel,mask,rest,NULL));
|
||||||
|
|
||||||
|
kick->next = current->kicklist;
|
||||||
|
current->kicklist = kick;
|
||||||
|
kick->action = inum;
|
||||||
|
|
||||||
|
if (!matches("\\*?*\\*",mask))
|
||||||
|
kick->chan = stringcpy(kick->mask,mask) + 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kick->mask[0] = '*';
|
||||||
|
stringcpy(kick->mask+1,mask);
|
||||||
|
kick->chan = stringcat(kick->mask,MATCH_ALL) + 1;
|
||||||
|
}
|
||||||
|
kick->reason = stringcpy(kick->chan,channel) + 1;
|
||||||
|
stringcpy(kick->reason,rest);
|
||||||
|
|
||||||
|
to_user(from,"Now kicking on \"%s\" on %s",mask,channel);
|
||||||
|
current->ul_save++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
usage:
|
||||||
|
usage(from); /* usage for CurrentCmd->name */
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_rkicksay(COMMAND_ARGS)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* on_msg checks: CARGS
|
||||||
|
*/
|
||||||
|
KickSay *kick;
|
||||||
|
char *channel;
|
||||||
|
|
||||||
|
channel = chop(&rest); /* cant be NULL (CARGS) */
|
||||||
|
if (!ischannel(channel) && *channel != '*')
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
if (!*rest)
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
if (!(kick = find_kicksay(rest,channel)))
|
||||||
|
{
|
||||||
|
to_user(from,"I'm not kicking on that");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
to_user(from,"No longer kicking on %s",kick->mask);
|
||||||
|
remove_kicksay(kick);
|
||||||
|
current->ul_save++;
|
||||||
|
return;
|
||||||
|
usage:
|
||||||
|
usage(from); /* usage for CurrentCmd->name */
|
||||||
|
}
|
||||||
|
|||||||
192
src/reset.c
192
src/reset.c
@ -30,42 +30,29 @@
|
|||||||
LS int client_type = DCC_ACTIVE;
|
LS int client_type = DCC_ACTIVE;
|
||||||
#endif /* TELNET */
|
#endif /* TELNET */
|
||||||
|
|
||||||
|
#define mkaxx(x) (0x40404040 + (0x0f0f & x) + ((0xf0f0 & x) << 12))
|
||||||
|
#define getaxx(x) (((x & 0x0f0f0000) >> 12) | (x & 0x00000f0f))
|
||||||
|
|
||||||
char *recover_client(char *env)
|
char *recover_client(char *env)
|
||||||
{
|
{
|
||||||
|
union {
|
||||||
|
uint32_t num[2];
|
||||||
|
char asc[8];
|
||||||
|
} axx;
|
||||||
struct sockaddr_in sai;
|
struct sockaddr_in sai;
|
||||||
Client *client;
|
Client *client;
|
||||||
User *user;
|
User *user;
|
||||||
char *p,*handle;
|
char *p,*handle;
|
||||||
int guid,fd,sz;
|
int guid = 0,fd = 0,sz;
|
||||||
|
|
||||||
guid = fd = 0;
|
if (env[8] != ':')
|
||||||
p = env;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get the guid number
|
|
||||||
*/
|
|
||||||
while(*p >= '0' && *p <= '9')
|
|
||||||
{
|
|
||||||
guid = (guid * 10) + (*p - '0');
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if (*p != ':')
|
|
||||||
return(env);
|
return(env);
|
||||||
p++;
|
|
||||||
|
|
||||||
/*
|
memcpy(axx.asc,env,8); // compiler is not stupid and will optimize the shit out of this
|
||||||
* get the fd number
|
guid = getaxx(axx.num[0]);
|
||||||
*/
|
fd = getaxx(axx.num[1]);
|
||||||
while(*p >= '0' && *p <= '9')
|
|
||||||
{
|
|
||||||
fd = (fd * 10) + (*p - '0');
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if (*p != ':')
|
|
||||||
return(env);
|
|
||||||
p++;
|
|
||||||
|
|
||||||
handle = p;
|
handle = p = (env = env + 9);
|
||||||
while(*p)
|
while(*p)
|
||||||
{
|
{
|
||||||
if (*p == ' ' || *p == 0)
|
if (*p == ' ' || *p == 0)
|
||||||
@ -150,22 +137,21 @@ found_user:
|
|||||||
|
|
||||||
char *recover_debug(char *env)
|
char *recover_debug(char *env)
|
||||||
{
|
{
|
||||||
|
union {
|
||||||
|
uint32_t num;
|
||||||
|
char asc[4];
|
||||||
|
} axx;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
char *p;
|
|
||||||
|
|
||||||
debug_fd = 0;
|
debug_fd = 0;
|
||||||
p = env;
|
|
||||||
|
|
||||||
|
if (env[4] != ' ' && env[4] != 0)
|
||||||
|
return(env);
|
||||||
/*
|
/*
|
||||||
* get the fd number
|
* get the fd number
|
||||||
*/
|
*/
|
||||||
while(*p >= '0' && *p <= '9')
|
memcpy(axx.asc,env,4); // compiler is not stupid and will optimize the shit out of this
|
||||||
{
|
debug_fd = getaxx(axx.num);
|
||||||
debug_fd = (debug_fd * 10) + (*p - '0');
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if (*p != ' ' && *p != 0)
|
|
||||||
return(env);
|
|
||||||
|
|
||||||
if (fstat(debug_fd,&s) < 0)
|
if (fstat(debug_fd,&s) < 0)
|
||||||
{
|
{
|
||||||
@ -176,71 +162,57 @@ char *recover_debug(char *env)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
dodebug = TRUE;
|
dodebug = TRUE;
|
||||||
debug("(recover_debug) debug fd recovered\n");
|
debug("(recover_debug) {%i} debug fd recovered\n",debug_fd);
|
||||||
CoreClient.sock = debug_fd;
|
CoreClient.sock = debug_fd;
|
||||||
}
|
}
|
||||||
return(p);
|
return(env+4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
//execve( ./energymech, argv = { ./energymech <NULL> <NULL> <NULL> <NULL> }, envp = { MECHRESET=d3 f1881:2:X12 f99:4:X12 } )
|
/*
|
||||||
|
(do_reset) mkaxx(3) = C@@@
|
||||||
|
(do_reset) ircx mkaxx(12) = L@@@
|
||||||
|
(do_reset) sock mkaxx(2) = B@@@
|
||||||
|
(do_reset) guid mkaxx(1881) = IGE@
|
||||||
|
[StS] {2} PING :OT1523818405
|
||||||
|
(do_reset) MECHRESET=dC@@@ fXIGE@B@@@L@@@ tIGE@F@@@:joo [44]
|
||||||
|
execve( ./energymech, argv = { ./energymech <NULL> <NULL> <NULL> <NULL> }, envp = { MECHRESET=dC@@@ fXIGE@B@@@L@@@ tIGE@F@@@:joo } )
|
||||||
|
*/
|
||||||
|
|
||||||
char *recover_server(char *env)
|
char *recover_server(char *env)
|
||||||
{
|
{
|
||||||
|
union {
|
||||||
|
uint32_t num[4];
|
||||||
|
char asc[16];
|
||||||
|
} axx;
|
||||||
struct sockaddr_in sai;
|
struct sockaddr_in sai;
|
||||||
char *p;
|
char *p;
|
||||||
int guid,fd,sz;
|
int guid = 0,fd = 0,sz;
|
||||||
#ifdef IRCD_EXTENSIONS
|
#ifdef IRCD_EXTENSIONS
|
||||||
int ircx = 0;
|
int ircx = 0;
|
||||||
#endif /* IRCD_EXTENSIONS */
|
#endif /* IRCD_EXTENSIONS */
|
||||||
|
|
||||||
guid = fd = 0;
|
switch(*env++)
|
||||||
p = env;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get the guid number
|
|
||||||
*/
|
|
||||||
while(*p >= '0' && *p <= '9')
|
|
||||||
{
|
{
|
||||||
guid = (guid * 10) + (*p - '0');
|
case 'x':
|
||||||
p++;
|
sz = 8;
|
||||||
}
|
break;
|
||||||
if (*p != ':')
|
case 'X':
|
||||||
|
sz = 12;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return(env);
|
return(env);
|
||||||
p++;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get the fd number
|
|
||||||
*/
|
|
||||||
while(*p >= '0' && *p <= '9')
|
|
||||||
{
|
|
||||||
fd = (fd * 10) + (*p - '0');
|
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
#ifndef IRCD_EXTENSIONS
|
if (env[sz] != ' ' && env[sz] != 0)
|
||||||
if (*p != ' ' && *p != 0)
|
|
||||||
return(env);
|
return(env);
|
||||||
#endif /* ! IRCD_EXTENSIONS */
|
|
||||||
|
|
||||||
|
memcpy(axx.asc,env,sz); // compiler is not stupid and will optimize the shit out of this
|
||||||
|
env += sz;
|
||||||
|
guid = getaxx(axx.num[0]);
|
||||||
|
fd = getaxx(axx.num[1]);
|
||||||
#ifdef IRCD_EXTENSIONS
|
#ifdef IRCD_EXTENSIONS
|
||||||
if (*p == ':' && *(p+1) == 'X')
|
ircx = getaxx(axx.num[2]);
|
||||||
{
|
|
||||||
p += 2;
|
|
||||||
/*
|
|
||||||
* get the ircx flags number
|
|
||||||
*/
|
|
||||||
while(*p >= '0' && *p <= '9')
|
|
||||||
{
|
|
||||||
ircx = (ircx * 10) + (*p - '0');
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if (*p != ' ' && *p != 0)
|
|
||||||
return(env);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (*p != ' ' && *p != 0)
|
|
||||||
return(env);
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
debug("(recover_server) guid = %i; fd = %i, ircx = %i\n",guid,fd,ircx);
|
debug("(recover_server) guid = %i; fd = %i, ircx = %i\n",guid,fd,ircx);
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
@ -254,7 +226,7 @@ char *recover_server(char *env)
|
|||||||
if (getsockname(fd,(struct sockaddr*)&sai,&sz) < 0)
|
if (getsockname(fd,(struct sockaddr*)&sai,&sz) < 0)
|
||||||
{
|
{
|
||||||
close(fd);
|
close(fd);
|
||||||
return(p);
|
return(env);
|
||||||
}
|
}
|
||||||
for(current=botlist;current;current=current->next)
|
for(current=botlist;current;current=current->next)
|
||||||
{
|
{
|
||||||
@ -282,19 +254,11 @@ char *recover_server(char *env)
|
|||||||
to_file(fd,"QUIT :I'm no longer wanted *cry*\n");
|
to_file(fd,"QUIT :I'm no longer wanted *cry*\n");
|
||||||
killsock(fd);
|
killsock(fd);
|
||||||
}
|
}
|
||||||
return(p);
|
return(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef IRCD_EXTENSIONS
|
//(do_reset) MECHRESET=dC@@@ fXIGE@A@@@L@@@ tIGE@F@@@:joo [44]
|
||||||
|
//execve( ./energymech, argv = { ./energymech <NULL> <NULL> <NULL> <NULL> }, envp = { MECHRESET=dC@@@ fXIGE@A@@@L@@@ tIGE@F@@@:joo } )
|
||||||
/*
|
|
||||||
#define IRCX_WALLCHOPS 1
|
|
||||||
#define IRCX_WALLVOICES 2
|
|
||||||
#define IRCX_IMODE 4
|
|
||||||
#define IRCX_EMODE 8
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* IRCD_EXTENSIONS */
|
|
||||||
|
|
||||||
void recover_reset(void)
|
void recover_reset(void)
|
||||||
{
|
{
|
||||||
@ -329,17 +293,23 @@ void recover_reset(void)
|
|||||||
default:
|
default:
|
||||||
env++;
|
env++;
|
||||||
}
|
}
|
||||||
|
while(*env == ' ')
|
||||||
|
env++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
-+=====================================================================================================================+-
|
||||||
* commands
|
reset.c commands
|
||||||
*
|
-+=====================================================================================================================+-
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void do_reset(COMMAND_ARGS)
|
void do_reset(COMMAND_ARGS)
|
||||||
{
|
{
|
||||||
|
union {
|
||||||
|
uint32_t num[8];
|
||||||
|
char asc[32];
|
||||||
|
} axx;
|
||||||
Client *client;
|
Client *client;
|
||||||
Mech *backup;
|
Mech *backup;
|
||||||
char env[MSGLEN];
|
char env[MSGLEN];
|
||||||
@ -372,16 +342,16 @@ void do_reset(COMMAND_ARGS)
|
|||||||
|
|
||||||
*env = 0;
|
*env = 0;
|
||||||
p = stringcat(env,STR_MECHRESET);
|
p = stringcat(env,STR_MECHRESET);
|
||||||
n = 0;
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/*
|
/*
|
||||||
* debug stuff
|
* debug stuff
|
||||||
*/
|
*/
|
||||||
if (dodebug && (debug_fd >= 0))
|
if (dodebug && (debug_fd >= 0))
|
||||||
{
|
{
|
||||||
sprintf(p,"d%i",debug_fd);
|
axx.num[0] = mkaxx(debug_fd);
|
||||||
|
axx.num[1] = 0;
|
||||||
|
sprintf(p,"d%s",axx.asc);
|
||||||
p = STREND(p);
|
p = STREND(p);
|
||||||
n++;
|
|
||||||
}
|
}
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
/*
|
/*
|
||||||
@ -393,15 +363,17 @@ void do_reset(COMMAND_ARGS)
|
|||||||
if ((current->connect == CN_ONLINE) && ((MSGLEN - (p - env)) > 25))
|
if ((current->connect == CN_ONLINE) && ((MSGLEN - (p - env)) > 25))
|
||||||
{
|
{
|
||||||
unset_closeonexec(current->sock);
|
unset_closeonexec(current->sock);
|
||||||
if (n)
|
axx.num[0] = mkaxx(current->guid);
|
||||||
*(p++) = ' ';
|
axx.num[1] = mkaxx(current->sock);
|
||||||
#ifdef IRCD_EXTENSIONS
|
#ifdef IRCD_EXTENSIONS
|
||||||
sprintf(p,"f%i:%i:X%i",current->guid,current->sock,current->ircx_flags);
|
axx.num[2] = mkaxx(current->ircx_flags);
|
||||||
|
axx.num[3] = 0;
|
||||||
|
sprintf(p," fX%s",axx.asc);
|
||||||
#else /* IRCD_EXTENSIONS */
|
#else /* IRCD_EXTENSIONS */
|
||||||
sprintf(p,"f%i:%i",current->guid,current->sock);
|
axx.num[2] = 0;
|
||||||
|
sprintf(p," fx%s",axx.asc);
|
||||||
#endif /* IRCD_EXTENSIONS */
|
#endif /* IRCD_EXTENSIONS */
|
||||||
p = STREND(p);
|
p = STREND(p);
|
||||||
n++;
|
|
||||||
to_server("PING :OT%lu\n",current->ontime);
|
to_server("PING :OT%lu\n",current->ontime);
|
||||||
}
|
}
|
||||||
for(client=current->clientlist;client;client=client->next)
|
for(client=current->clientlist;client;client=client->next)
|
||||||
@ -417,16 +389,16 @@ void do_reset(COMMAND_ARGS)
|
|||||||
if ((MSGLEN - (p - env)) > sz)
|
if ((MSGLEN - (p - env)) > sz)
|
||||||
{
|
{
|
||||||
unset_closeonexec(client->sock);
|
unset_closeonexec(client->sock);
|
||||||
if (n)
|
axx.num[0] = mkaxx(current->guid);
|
||||||
*(p++) = ' ';
|
axx.num[1] = mkaxx(client->sock);
|
||||||
|
axx.num[2] = 0;
|
||||||
#ifdef TELNET
|
#ifdef TELNET
|
||||||
sprintf(p,(client->flags & DCC_TELNET) ? "t%i:%i:%s" : "c%i:%i:%s",
|
sprintf(p,(client->flags & DCC_TELNET) ? " t%s:%s" : " c%s:%s",
|
||||||
current->guid,current->sock,client->user->name);
|
axx.asc,client->user->name);
|
||||||
#else
|
#else
|
||||||
sprintf(p,"c%i:%i:%s",current->guid,current->sock,client->user->name);
|
sprintf(p," c%s:%s",axx.asc,client->user->name);
|
||||||
#endif /* TELNET */
|
#endif /* TELNET */
|
||||||
p = STREND(p);
|
p = STREND(p);
|
||||||
n++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -436,7 +408,7 @@ void do_reset(COMMAND_ARGS)
|
|||||||
debug("(do_reset) %s [%i]\n",env,(int)(p - env));
|
debug("(do_reset) %s [%i]\n",env,(int)(p - env));
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
mechresetenv = (n) ? env : NULL;
|
mechresetenv = (*env) ? env : NULL;
|
||||||
|
|
||||||
do_exec = TRUE;
|
do_exec = TRUE;
|
||||||
mech_exec();
|
mech_exec();
|
||||||
|
|||||||
734
src/seen.c
734
src/seen.c
@ -21,8 +21,6 @@
|
|||||||
#define SEEN_C
|
#define SEEN_C
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef SEEN
|
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
@ -30,6 +28,612 @@
|
|||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "mcmd.h"
|
#include "mcmd.h"
|
||||||
|
|
||||||
|
#ifdef NOTIFY
|
||||||
|
|
||||||
|
#define CHOOSE_NUMBER 25
|
||||||
|
#define CHOOSE_MOVETO (CHOOSE_NUMBER - 2)
|
||||||
|
|
||||||
|
#define LOGFILENAMEFMT "notify-guid%i.log"
|
||||||
|
#define LOGFILENAMEBUF 32 /* need to recalculate this if LOGFILENAMEFMT is changed */
|
||||||
|
|
||||||
|
#define NFF_ALL 1
|
||||||
|
#define NFF_NOMATCH 2
|
||||||
|
#define NFF_RELOAD 4
|
||||||
|
#define NFF_FULL 8
|
||||||
|
#define NFF_SEEN 16
|
||||||
|
|
||||||
|
#define NF_OPTIONS 7
|
||||||
|
|
||||||
|
LS const char notify_opt[NF_OPTIONS][10] =
|
||||||
|
{
|
||||||
|
"-ALL",
|
||||||
|
"-NOMATCH",
|
||||||
|
"-RELOAD",
|
||||||
|
"-FULL",
|
||||||
|
"-SEEN",
|
||||||
|
};
|
||||||
|
|
||||||
|
LS Notify **endoflist;
|
||||||
|
LS int lock_ison = FALSE;
|
||||||
|
LS int nf_header;
|
||||||
|
|
||||||
|
void purge_notify(void)
|
||||||
|
{
|
||||||
|
Notify *nf;
|
||||||
|
nfLog *nlog;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* empty the notifylist
|
||||||
|
*/
|
||||||
|
while(current->notifylist)
|
||||||
|
{
|
||||||
|
nf = current->notifylist;
|
||||||
|
current->notifylist = nf->next;
|
||||||
|
while(nf->log)
|
||||||
|
{
|
||||||
|
nlog = nf->log;
|
||||||
|
nf->log = nlog->next;
|
||||||
|
Free((char**)&nlog);
|
||||||
|
}
|
||||||
|
Free((char**)&nf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int mask_check(Notify *nf, char *userhost)
|
||||||
|
{
|
||||||
|
char *mask,*rest;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* no mask (NULL)
|
||||||
|
*/
|
||||||
|
if (!nf->mask)
|
||||||
|
return(NF_MASKONLINE);
|
||||||
|
|
||||||
|
ret = NF_NOMATCH;
|
||||||
|
if (nf->endofmask)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* multiple masks separated by spaces
|
||||||
|
*/
|
||||||
|
mask = rest = nf->mask;
|
||||||
|
chop(&rest);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* single mask
|
||||||
|
*/
|
||||||
|
if (!matches(nf->mask,userhost))
|
||||||
|
ret = NF_MASKONLINE;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
while(mask)
|
||||||
|
{
|
||||||
|
if (!matches(mask,userhost))
|
||||||
|
{
|
||||||
|
ret = NF_MASKONLINE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mask = chop(&rest);
|
||||||
|
}
|
||||||
|
if (nf->endofmask)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* undo the chop()'s
|
||||||
|
*/
|
||||||
|
for(mask=nf->mask;mask<nf->endofmask;mask++)
|
||||||
|
{
|
||||||
|
if (*mask == 0)
|
||||||
|
*mask = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_ison(void)
|
||||||
|
{
|
||||||
|
Notify *nf,*chosen[CHOOSE_NUMBER];
|
||||||
|
char isonmsg[MSGLEN];
|
||||||
|
char *p,*src;
|
||||||
|
int i,x,period;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dont send nicks to ISON too often
|
||||||
|
*/
|
||||||
|
period = current->setting[INT_ISONDELAY].int_var;
|
||||||
|
x = now - current->lastnotify;
|
||||||
|
if ((x < period) || (lock_ison && (x < 600)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
current->lastnotify = now;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the nature of the code makes it so that the first NULL is
|
||||||
|
* pushed further down the list as more entries are added,
|
||||||
|
* so no need to blank the whole list
|
||||||
|
*/
|
||||||
|
chosen[0] = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* select the oldest (CHOOSE_NUMBER) nicks for an update
|
||||||
|
*/
|
||||||
|
for(nf=current->notifylist;nf;nf=nf->next)
|
||||||
|
{
|
||||||
|
for(i=0;i<CHOOSE_NUMBER;i++)
|
||||||
|
{
|
||||||
|
if (!chosen[i] || (chosen[i]->checked > nf->checked))
|
||||||
|
{
|
||||||
|
for(x=CHOOSE_MOVETO;x>=i;x--)
|
||||||
|
chosen[x+1] = chosen[x];
|
||||||
|
chosen[i] = nf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (chosen[0])
|
||||||
|
{
|
||||||
|
p = isonmsg;
|
||||||
|
for(i=0;i<CHOOSE_NUMBER;i++)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* drop out once the end-of-chosen-list NULL is found
|
||||||
|
*/
|
||||||
|
if (!chosen[i])
|
||||||
|
break;
|
||||||
|
chosen[i]->checked = 1;
|
||||||
|
src = chosen[i]->nick;
|
||||||
|
if (i) *(p++) = ' ';
|
||||||
|
while((*p = *(src++))) p++;
|
||||||
|
}
|
||||||
|
to_server("ISON :%s\n",isonmsg);
|
||||||
|
lock_ison = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void catch_ison(char *rest)
|
||||||
|
{
|
||||||
|
Notify *nf;
|
||||||
|
char whoismsg[MSGLEN];
|
||||||
|
char *nick,*dst;
|
||||||
|
|
||||||
|
lock_ison = FALSE;
|
||||||
|
*whoismsg = 0;
|
||||||
|
dst = whoismsg;
|
||||||
|
while((nick = chop(&rest)))
|
||||||
|
{
|
||||||
|
for(nf=current->notifylist;nf;nf=nf->next)
|
||||||
|
{
|
||||||
|
if (!nickcmp(nf->nick,nick))
|
||||||
|
{
|
||||||
|
nf->checked = now;
|
||||||
|
/*
|
||||||
|
* /whois user to get user@host + realname
|
||||||
|
*/
|
||||||
|
if (nf->status == NF_OFFLINE)
|
||||||
|
{
|
||||||
|
if (*whoismsg) *(dst++) = ',';
|
||||||
|
*dst = 0;
|
||||||
|
dst = stringcat(dst,nf->nick);
|
||||||
|
nf->status = NF_WHOIS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*whoismsg)
|
||||||
|
to_server("WHOIS %s\n",whoismsg);
|
||||||
|
|
||||||
|
for(nf=current->notifylist;nf;nf=nf->next)
|
||||||
|
{
|
||||||
|
if (nf->checked == 1)
|
||||||
|
{
|
||||||
|
nf->checked = now;
|
||||||
|
if (nf->status >= NF_WHOIS)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* close the log entry for this online period
|
||||||
|
*/
|
||||||
|
if (nf->log && nf->log->signon && !nf->log->signoff)
|
||||||
|
nf->log->signoff = now;
|
||||||
|
/*
|
||||||
|
* announce that the user is offline if its a mask match
|
||||||
|
*/
|
||||||
|
if (nf->status == NF_MASKONLINE)
|
||||||
|
send_spy(SPYSTR_STATUS,"Notify: %s is offline",nf->nick);
|
||||||
|
nf->status = NF_OFFLINE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void catch_whois(char *nick, char *userhost, char *realname)
|
||||||
|
{
|
||||||
|
Notify *nf;
|
||||||
|
nfLog *nlog;
|
||||||
|
|
||||||
|
if (!realname || !*realname)
|
||||||
|
realname = "unknown";
|
||||||
|
|
||||||
|
for(nf=current->notifylist;nf;nf=nf->next)
|
||||||
|
{
|
||||||
|
if ((nf->status == NF_WHOIS) && !nickcmp(nf->nick,nick))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* put in a new log entry
|
||||||
|
*/
|
||||||
|
set_mallocdoer(catch_whois);
|
||||||
|
nlog = (nfLog*)Calloc(sizeof(nfLog) + Strlen2(userhost,realname)); // realname is never NULL
|
||||||
|
nlog->signon = now;
|
||||||
|
nlog->next = nf->log;
|
||||||
|
nf->log = nlog;
|
||||||
|
nlog->realname = stringcat(nlog->userhost,userhost) + 1;
|
||||||
|
stringcpy(nlog->realname,realname);
|
||||||
|
/*
|
||||||
|
* if there is a mask, we need a match to announce the online status
|
||||||
|
*/
|
||||||
|
nf->status = mask_check(nf,userhost);
|
||||||
|
if (nf->status == NF_MASKONLINE)
|
||||||
|
send_spy(SPYSTR_STATUS,"Notify: %s (%s) is online",nf->nick,userhost);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* saving and loading notify information
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
int notifylog_callback(char *rest)
|
||||||
|
{
|
||||||
|
Notify *nf;
|
||||||
|
nfLog *nlog,**pp;
|
||||||
|
time_t on,off;
|
||||||
|
char *nick,*userhost;
|
||||||
|
|
||||||
|
if (*rest == COMMENT_CHAR)
|
||||||
|
return(FALSE);
|
||||||
|
|
||||||
|
nick = chop(&rest);
|
||||||
|
|
||||||
|
on = asc2int(chop(&rest));
|
||||||
|
if (errno)
|
||||||
|
return(FALSE);
|
||||||
|
|
||||||
|
off = asc2int(chop(&rest));
|
||||||
|
if (errno)
|
||||||
|
return(FALSE);
|
||||||
|
|
||||||
|
userhost = chop(&rest);
|
||||||
|
|
||||||
|
if (rest && *rest == ':')
|
||||||
|
rest++;
|
||||||
|
if (!*rest)
|
||||||
|
return(FALSE);
|
||||||
|
|
||||||
|
for(nf=current->notifylist;nf;nf=nf->next)
|
||||||
|
{
|
||||||
|
if (!nickcmp(nick,nf->nick))
|
||||||
|
{
|
||||||
|
pp = &nf->log;
|
||||||
|
while(*pp)
|
||||||
|
{
|
||||||
|
if ((*pp)->signon < on)
|
||||||
|
break;
|
||||||
|
pp = &(*pp)->next;
|
||||||
|
}
|
||||||
|
set_mallocdoer(notifylog_callback);
|
||||||
|
nlog = (nfLog*)Calloc(sizeof(nfLog) + Strlen2(userhost,rest)); // rest is never NULL
|
||||||
|
nlog->signon = on;
|
||||||
|
nlog->signoff = off;
|
||||||
|
nlog->next = *pp;
|
||||||
|
*pp = nlog;
|
||||||
|
nlog->realname = stringcat(nlog->userhost,userhost) + 1;
|
||||||
|
stringcpy(nlog->realname,rest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_notifylog(void)
|
||||||
|
{
|
||||||
|
char fname[LOGFILENAMEBUF];
|
||||||
|
int fd;
|
||||||
|
#ifdef DEBUG
|
||||||
|
int dd;
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
sprintf(fname,LOGFILENAMEFMT,current->guid);
|
||||||
|
if ((fd = open(fname,O_RDONLY)) < 0)
|
||||||
|
return;
|
||||||
|
#ifdef DEBUG
|
||||||
|
dd = dodebug;
|
||||||
|
dodebug = FALSE;
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
readline(fd,¬ifylog_callback); /* readline closes fd */
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
dodebug = dd;
|
||||||
|
#endif /* DEBUG */
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_notifylog(void)
|
||||||
|
{
|
||||||
|
Notify *nf;
|
||||||
|
nfLog *nlog;
|
||||||
|
char fname[LOGFILENAMEBUF];
|
||||||
|
int fd;
|
||||||
|
#ifdef DEBUG
|
||||||
|
int dd;
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
sprintf(fname,LOGFILENAMEFMT,current->guid);
|
||||||
|
if ((fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC,NEWFILEMODE)) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
dd = dodebug;
|
||||||
|
dodebug = FALSE;
|
||||||
|
#endif /* DEBUG */
|
||||||
|
for(nf=current->notifylist;nf;nf=nf->next)
|
||||||
|
{
|
||||||
|
to_file(fd,COMMENT_STRCHR "\n" COMMENT_STRCHR " Nick: %s\n",nf->nick);
|
||||||
|
if (nf->info)
|
||||||
|
to_file(fd,COMMENT_STRCHR " Note: %s\n",nf->info);
|
||||||
|
if (nf->mask)
|
||||||
|
to_file(fd,COMMENT_STRCHR " Mask: %s\n",nf->mask);
|
||||||
|
to_file(fd,COMMENT_STRCHR "\n");
|
||||||
|
for(nlog=nf->log;nlog;nlog=nlog->next)
|
||||||
|
{
|
||||||
|
to_file(fd,"%s %lu %lu %s :%s\n",nf->nick,nlog->signon,
|
||||||
|
(nlog->signoff) ? nlog->signoff : now,
|
||||||
|
nlog->userhost,nlog->realname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
#ifdef DEBUG
|
||||||
|
dodebug = dd;
|
||||||
|
#endif /* DEBUG */
|
||||||
|
}
|
||||||
|
|
||||||
|
int notify_callback(char *rest)
|
||||||
|
{
|
||||||
|
Notify *nf;
|
||||||
|
char *nick;
|
||||||
|
char *src,*dst;
|
||||||
|
char *lspace;
|
||||||
|
|
||||||
|
errno = EINVAL;
|
||||||
|
|
||||||
|
if (!rest || *rest == COMMENT_CHAR)
|
||||||
|
return(FALSE);
|
||||||
|
fix_config_line(rest);
|
||||||
|
if ((nick = chop(&rest)) == NULL)
|
||||||
|
return(FALSE);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
debug("(notify_callback) parsing %s `%s'\n",nick,nullstr(rest));
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
lspace = rest - 1;
|
||||||
|
src = dst = rest;
|
||||||
|
while(*src)
|
||||||
|
{
|
||||||
|
if (*src == ' ')
|
||||||
|
{
|
||||||
|
if (!lspace)
|
||||||
|
{
|
||||||
|
lspace = dst;
|
||||||
|
*(dst++) = *src;
|
||||||
|
}
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (*src == ':' && lspace)
|
||||||
|
{
|
||||||
|
*lspace = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lspace = NULL;
|
||||||
|
*(dst++) = *(src++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*src == ':')
|
||||||
|
*(src++) = 0;
|
||||||
|
if (!*src)
|
||||||
|
src = NULL;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
debug("(notify_callback) creating struct\n");
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nick = nick
|
||||||
|
* rest = mask(s) or *rest == 0
|
||||||
|
* src = description or NULL
|
||||||
|
*/
|
||||||
|
set_mallocdoer(notify_callback);
|
||||||
|
nf = (Notify*)Calloc(sizeof(Notify) + StrlenX(nick,rest,src,NULL));
|
||||||
|
dst = stringcat(nf->nick,nick);
|
||||||
|
if (*rest)
|
||||||
|
{
|
||||||
|
nf->mask = dst + 1;
|
||||||
|
dst = stringcat(nf->mask,rest);
|
||||||
|
if (STRCHR(nf->mask,' '))
|
||||||
|
nf->endofmask = dst;
|
||||||
|
}
|
||||||
|
if (src)
|
||||||
|
{
|
||||||
|
nf->info = dst + 1;
|
||||||
|
stringcpy(nf->info,src);
|
||||||
|
}
|
||||||
|
/* put it at the end of notifylist */
|
||||||
|
*endoflist = nf;
|
||||||
|
endoflist = &nf->next;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_notify(char *filename)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (!filename)
|
||||||
|
return(FALSE);
|
||||||
|
|
||||||
|
if ((fd = open(filename,O_RDONLY)) < 0)
|
||||||
|
return(FALSE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* save online logs
|
||||||
|
*/
|
||||||
|
if (current->notifylist)
|
||||||
|
write_notifylog();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* delete the whole list
|
||||||
|
*/
|
||||||
|
purge_notify();
|
||||||
|
|
||||||
|
endoflist = ¤t->notifylist;
|
||||||
|
readline(fd,¬ify_callback); /* readline closes fd */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read back online logs
|
||||||
|
*/
|
||||||
|
read_notifylog();
|
||||||
|
|
||||||
|
return(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfshow_brief(Notify *nf)
|
||||||
|
{
|
||||||
|
time_t when;
|
||||||
|
char mem[40];
|
||||||
|
char *s;
|
||||||
|
int d,h,m;
|
||||||
|
|
||||||
|
if (nf->status == NF_NOMATCH)
|
||||||
|
s = " nickname in use";
|
||||||
|
else
|
||||||
|
if (nf->status >= NF_WHOIS)
|
||||||
|
s = " online now";
|
||||||
|
else
|
||||||
|
if (nf->log && nf->log->signoff)
|
||||||
|
{
|
||||||
|
s = mem;
|
||||||
|
when = now - nf->log->signoff;
|
||||||
|
d = when / 86400;
|
||||||
|
h = (when -= d * 86400) / 3600;
|
||||||
|
m = (when -= h * 3600) / 60;
|
||||||
|
sprintf(mem,"%2i day%1s %02i:%02i ago",d,EXTRA_CHAR(d),h,m);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s = " never seen";
|
||||||
|
|
||||||
|
if (!nf_header)
|
||||||
|
to_user(global_from,"\037nick\037 \037last seen\037 \037note\037");
|
||||||
|
to_user(global_from,(nf->info) ? "%-9s %-22s %s" : "%-9s %s",
|
||||||
|
nf->nick,s,nf->info);
|
||||||
|
nf_header++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfshow_full(Notify *nf)
|
||||||
|
{
|
||||||
|
char mem[MSGLEN];
|
||||||
|
nfLog *nlog;
|
||||||
|
char *s,*opt;
|
||||||
|
|
||||||
|
if (nf_header)
|
||||||
|
to_user(global_from," ");
|
||||||
|
to_user(global_from,(nf->status == NF_MASKONLINE) ? "Nick: \037%s\037" : "Nick: %s",nf->nick);
|
||||||
|
if (nf->info)
|
||||||
|
to_user(global_from,"Note: %s",nf->info);
|
||||||
|
if (nf->mask)
|
||||||
|
to_user(global_from,"Mask: %s",nf->mask);
|
||||||
|
if (nf->log)
|
||||||
|
{
|
||||||
|
to_user(global_from,"Online history:");
|
||||||
|
for(nlog=nf->log;nlog;nlog=nlog->next)
|
||||||
|
{
|
||||||
|
opt = mem;
|
||||||
|
s = time2away(nlog->signon);
|
||||||
|
if (s[1] == ':')
|
||||||
|
*(opt++) = ' ';
|
||||||
|
*opt = 0;
|
||||||
|
opt = stringcat(opt,s);
|
||||||
|
while(opt < (mem+18))
|
||||||
|
*(opt++) = ' ';
|
||||||
|
*opt = 0;
|
||||||
|
opt = stringcat(opt," -- ");
|
||||||
|
if (nlog->signoff)
|
||||||
|
{
|
||||||
|
s = time2away(nlog->signoff);
|
||||||
|
if (s[1] == ':')
|
||||||
|
*(opt++) = ' ';
|
||||||
|
*opt = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s = " online now";
|
||||||
|
}
|
||||||
|
opt = stringcat(opt,s);
|
||||||
|
while(opt < (mem+41))
|
||||||
|
*(opt++) = ' ';
|
||||||
|
*opt = 0;
|
||||||
|
s = (nlog->realname) ? "%s: %s (%s)" : "%s: %s";
|
||||||
|
to_user(global_from,s,mem,nlog->userhost,nlog->realname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nf_header++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sub_notifynick(char *from, char *rest)
|
||||||
|
{
|
||||||
|
Notify *nf,**pp;
|
||||||
|
char *nick;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nick = chop(&rest);
|
||||||
|
if (!nick)
|
||||||
|
{
|
||||||
|
usage(from);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
pp = ¤t->notifylist;
|
||||||
|
while(*pp)
|
||||||
|
{
|
||||||
|
nf = *pp;
|
||||||
|
if (!nickcmp(nick,nf->nick))
|
||||||
|
{
|
||||||
|
*pp = nf->next;
|
||||||
|
Free((char**)&nf);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pp = &nf->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!i)
|
||||||
|
to_user(from,"Nick not found: %s",nick);
|
||||||
|
else
|
||||||
|
to_user(from,"Nick removed from notify: %s",nick);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ifdef NOTIFY */
|
||||||
|
|
||||||
|
#ifdef SEEN
|
||||||
|
|
||||||
int write_seenlist(void)
|
int write_seenlist(void)
|
||||||
{
|
{
|
||||||
Seen *seen;
|
Seen *seen;
|
||||||
@ -213,10 +817,10 @@ step_two:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
-+=====================================================================================================================+-
|
||||||
* commands for seen features
|
seen.c commands
|
||||||
*
|
-+=====================================================================================================================+-
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void do_seen(COMMAND_ARGS)
|
void do_seen(COMMAND_ARGS)
|
||||||
{
|
{
|
||||||
@ -312,3 +916,121 @@ void do_seen(COMMAND_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SEEN */
|
#endif /* SEEN */
|
||||||
|
|
||||||
|
#ifdef NOTIFY
|
||||||
|
|
||||||
|
void do_notify(COMMAND_ARGS)
|
||||||
|
{
|
||||||
|
char message[MSGLEN];
|
||||||
|
Notify *nf;
|
||||||
|
nfLog *nlog;
|
||||||
|
char *opt;
|
||||||
|
int n,flags;
|
||||||
|
|
||||||
|
global_from = from;
|
||||||
|
flags = nf_header = 0;
|
||||||
|
*message = 0;
|
||||||
|
|
||||||
|
if (*rest)
|
||||||
|
{
|
||||||
|
while((opt = chop(&rest)))
|
||||||
|
{
|
||||||
|
if (!stringcmp(opt,"+"))
|
||||||
|
{
|
||||||
|
endoflist = ¤t->notifylist;
|
||||||
|
while(*endoflist)
|
||||||
|
endoflist = &(*endoflist)->next;
|
||||||
|
notify_callback(rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!stringcmp(opt,"-"))
|
||||||
|
{
|
||||||
|
sub_notifynick(from,rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(n=0;n<NF_OPTIONS;n++)
|
||||||
|
{
|
||||||
|
if (!stringcasecmp(notify_opt[n],opt))
|
||||||
|
{
|
||||||
|
flags |= (1 << n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n>=NF_OPTIONS)
|
||||||
|
{
|
||||||
|
for(nf=current->notifylist;nf;nf=nf->next)
|
||||||
|
{
|
||||||
|
if (!nickcmp(opt,nf->nick))
|
||||||
|
{
|
||||||
|
if (flags & NFF_FULL)
|
||||||
|
nfshow_full(nf);
|
||||||
|
else
|
||||||
|
nfshow_brief(nf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!nf)
|
||||||
|
{
|
||||||
|
if (*message)
|
||||||
|
stringcat(message,", ");
|
||||||
|
stringcat(message,opt);
|
||||||
|
}
|
||||||
|
nf_header++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*message)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
debug("(do_notify) dumping errnames\n");
|
||||||
|
#endif /* DEBUG */
|
||||||
|
to_user(from,"User%s not found: %s",(STRCHR(message,',')) ? "s" : "",message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nf_header)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (flags & NFF_RELOAD)
|
||||||
|
{
|
||||||
|
opt = current->setting[STR_NOTIFYFILE].str_var;
|
||||||
|
if (opt && read_notify(opt))
|
||||||
|
{
|
||||||
|
flags = get_useraccess(from,"");
|
||||||
|
send_spy(SPYSTR_STATUS,"Notify: %s reloaded by %s[%i]",
|
||||||
|
opt,CurrentNick,flags);
|
||||||
|
to_user(from,"notify list read from file %s",opt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
to_user(from,"notify list could not be read from file %s",nullstr(opt));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(nf=current->notifylist;nf;nf=nf->next)
|
||||||
|
{
|
||||||
|
if ((nf->status == NF_MASKONLINE) || (flags & NFF_ALL) || ((flags & NFF_NOMATCH) && (nf->status == NF_NOMATCH)))
|
||||||
|
goto show_it;
|
||||||
|
if ((flags & NFF_SEEN) && nf->log)
|
||||||
|
{
|
||||||
|
for(nlog=nf->log;nlog;nlog=nlog->next)
|
||||||
|
{
|
||||||
|
if (mask_check(nf,nlog->userhost) == NF_MASKONLINE)
|
||||||
|
goto show_it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
show_it:
|
||||||
|
if (flags & NFF_FULL)
|
||||||
|
nfshow_full(nf);
|
||||||
|
else
|
||||||
|
nfshow_brief(nf);
|
||||||
|
}
|
||||||
|
if (!nf_header)
|
||||||
|
{
|
||||||
|
to_user(from,"no notify users are online");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NOTIFY */
|
||||||
|
|||||||
@ -276,7 +276,7 @@ typedef struct User
|
|||||||
|
|
||||||
#ifdef BOTNET
|
#ifdef BOTNET
|
||||||
int modcount;
|
int modcount;
|
||||||
int guid;
|
uint16_t guid;
|
||||||
int tick;
|
int tick;
|
||||||
int addsession;
|
int addsession;
|
||||||
#endif /* BOTNET */
|
#endif /* BOTNET */
|
||||||
@ -519,7 +519,7 @@ typedef struct Mech
|
|||||||
{
|
{
|
||||||
struct Mech *next;
|
struct Mech *next;
|
||||||
|
|
||||||
int guid; /* globally uniqe ID */
|
uint16_t guid; /* globally uniqe ID */
|
||||||
int connect;
|
int connect;
|
||||||
int sock;
|
int sock;
|
||||||
struct in_addr ip; /* for DCC */
|
struct in_addr ip; /* for DCC */
|
||||||
@ -656,7 +656,7 @@ typedef struct BotInfo
|
|||||||
{
|
{
|
||||||
struct BotInfo *next;
|
struct BotInfo *next;
|
||||||
|
|
||||||
int guid;
|
uint16_t guid;
|
||||||
int hops;
|
int hops;
|
||||||
|
|
||||||
char *version;
|
char *version;
|
||||||
@ -678,7 +678,7 @@ typedef struct BotNet
|
|||||||
* they are copied partially in that order in net.c
|
* they are copied partially in that order in net.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int guid; /* remote bot guid */
|
uint16_t guid; /* remote bot guid */
|
||||||
int lsid; /* local session id */
|
int lsid; /* local session id */
|
||||||
int rsid; /* remote session id */
|
int rsid; /* remote session id */
|
||||||
|
|
||||||
@ -709,7 +709,7 @@ typedef struct NetCfg
|
|||||||
{
|
{
|
||||||
struct NetCfg *next;
|
struct NetCfg *next;
|
||||||
|
|
||||||
int guid;
|
uint16_t guid;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
uint16_t linked; //:1;
|
uint16_t linked; //:1;
|
||||||
|
|
||||||
@ -762,7 +762,7 @@ typedef struct Hook
|
|||||||
struct Hook *next;
|
struct Hook *next;
|
||||||
|
|
||||||
int (*func)();
|
int (*func)();
|
||||||
int guid; /* guid filter */
|
uint16_t guid; /* guid filter */
|
||||||
int flags;
|
int flags;
|
||||||
union {
|
union {
|
||||||
void *any;
|
void *any;
|
||||||
|
|||||||
617
src/toybox.c
617
src/toybox.c
@ -29,6 +29,36 @@
|
|||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "mcmd.h"
|
#include "mcmd.h"
|
||||||
|
|
||||||
|
#ifdef TRIVIA
|
||||||
|
|
||||||
|
#define TRIV_WAIT_QUESTION 0
|
||||||
|
#define TRIV_HINT_TWO 1
|
||||||
|
#define TRIV_HINT_THREE 2
|
||||||
|
#define TRIV_NO_ANSWER 3
|
||||||
|
|
||||||
|
#define TRIV_HINT_DELAY 15
|
||||||
|
|
||||||
|
#define TRIV_HINT_DELAY_STR1 "15"
|
||||||
|
#define TRIV_HINT_DELAY_STR2 "30"
|
||||||
|
|
||||||
|
#define TRIV_METACHARS " .,-'%&/?!:;\""
|
||||||
|
|
||||||
|
#define DAY_IN_SECONDS (24*60*60)
|
||||||
|
#define WEEK_IN_SECONDS (7*24*60*60)
|
||||||
|
|
||||||
|
LS TrivScore *lastwinner;
|
||||||
|
LS Chan *triv_chan = NULL;
|
||||||
|
LS Strp *triv_answers = NULL;
|
||||||
|
LS time_t triv_ask_time;
|
||||||
|
LS time_t triv_next_time = 0;
|
||||||
|
LS time_t triv_weektop10;
|
||||||
|
LS int triv_mode;
|
||||||
|
LS int triv_score;
|
||||||
|
LS int triv_streak;
|
||||||
|
LS int triv_halt_flag;
|
||||||
|
|
||||||
|
#endif /* TRIVIA */
|
||||||
|
|
||||||
#define BIGSAY_DEFAULTFONT "default"
|
#define BIGSAY_DEFAULTFONT "default"
|
||||||
#define FONT_EXTENSION ".bigchars"
|
#define FONT_EXTENSION ".bigchars"
|
||||||
|
|
||||||
@ -160,12 +190,522 @@ int read_ascii(char *rest)
|
|||||||
to_user_q(global_from,FMT_PLAIN,rest);
|
to_user_q(global_from,FMT_PLAIN,rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TRIVIA
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* trivia scorings
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void trivia_week_toppers(void)
|
||||||
|
{
|
||||||
|
char triv_str[MSGLEN];
|
||||||
|
TrivScore *chosen[10];
|
||||||
|
TrivScore *su;
|
||||||
|
char *p;
|
||||||
|
int week;
|
||||||
|
int i,x;
|
||||||
|
|
||||||
|
chosen[0] = NULL;
|
||||||
|
week = (now + (3 * DAY_IN_SECONDS)) / WEEK_IN_SECONDS;
|
||||||
|
|
||||||
|
for(su=scorelist;su;su=su->next)
|
||||||
|
{
|
||||||
|
if (su->week_nr != week)
|
||||||
|
continue;
|
||||||
|
for(i=0;i<10;i++)
|
||||||
|
{
|
||||||
|
if (!chosen[i] || (chosen[i]->score_wk < su->score_wk))
|
||||||
|
{
|
||||||
|
for(x=8;x>=i;x--)
|
||||||
|
chosen[x+1] = chosen[x];
|
||||||
|
chosen[i] = su;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chosen[0])
|
||||||
|
{
|
||||||
|
p = triv_str;
|
||||||
|
for(i=0;i<10;i++)
|
||||||
|
{
|
||||||
|
if (!chosen[i])
|
||||||
|
break;
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
*(p++) = ' ';
|
||||||
|
*(p++) = ' ';
|
||||||
|
}
|
||||||
|
sprintf(p,"#%i: %s (%ipts)",i+1,chosen[i]->nick,chosen[i]->score_wk);
|
||||||
|
p = STREND(p);
|
||||||
|
}
|
||||||
|
to_server("PRIVMSG %s :This Weeks Top 10: %s\n",triv_chan->name,triv_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void hint_one(void)
|
||||||
|
{
|
||||||
|
char triv_str[MSGLEN];
|
||||||
|
char *src,*dst;
|
||||||
|
|
||||||
|
sprintf(triv_str,"PRIVMSG %s :1st hint: ",triv_chan->name);
|
||||||
|
dst = STREND(triv_str);
|
||||||
|
src = triv_answers->p;
|
||||||
|
while(*src)
|
||||||
|
{
|
||||||
|
if (STRCHR(TRIV_METACHARS,*src))
|
||||||
|
*(dst++) = *src;
|
||||||
|
else
|
||||||
|
*(dst++) = triv_qchar;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
*dst = 0;
|
||||||
|
to_server("%s Question score: %i points\n",triv_str,triv_score);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hint_two(void)
|
||||||
|
{
|
||||||
|
char triv_str[MSGLEN];
|
||||||
|
char *src,*dst;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
sprintf(triv_str,"PRIVMSG %s :2nd hint: ",triv_chan->name);
|
||||||
|
dst = STREND(triv_str);
|
||||||
|
src = triv_answers->p;
|
||||||
|
|
||||||
|
n = asc2int(src);
|
||||||
|
if (!errno)
|
||||||
|
{
|
||||||
|
if (n > 99 && *src) *(dst++) = *(src++);
|
||||||
|
if (n > 999 && *src) *(dst++) = *(src++);
|
||||||
|
if (n > 9999 && *src) *(dst++) = *(src++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n = strlen(src);
|
||||||
|
if (n > 2 && *src) *(dst++) = *(src++);
|
||||||
|
if (n > 4 && *src) *(dst++) = *(src++);
|
||||||
|
if (n > 6 && *src) *(dst++) = *(src++);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(*src)
|
||||||
|
{
|
||||||
|
if (STRCHR(TRIV_METACHARS,*src))
|
||||||
|
*(dst++) = *src;
|
||||||
|
else
|
||||||
|
*(dst++) = triv_qchar;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
*dst = 0;
|
||||||
|
to_server("%s " TRIV_HINT_DELAY_STR2 " seconds remaining.\n",triv_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hint_three(void)
|
||||||
|
{
|
||||||
|
char triv_str[MSGLEN];
|
||||||
|
char *src,*dst;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
sprintf(triv_str,"PRIVMSG %s :3rd hint: ",triv_chan->name);
|
||||||
|
dst = STREND(triv_str);
|
||||||
|
src = triv_answers->p;
|
||||||
|
|
||||||
|
n = asc2int(src);
|
||||||
|
if (!errno)
|
||||||
|
{
|
||||||
|
if (n > 9 && *src) *(dst++) = *(src++);
|
||||||
|
if (n > 99 && *src) *(dst++) = *(src++);
|
||||||
|
if (n > 999 && *src) *(dst++) = *(src++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n = strlen(src);
|
||||||
|
if (n > 1 && *src) *(dst++) = *(src++);
|
||||||
|
if (n > 3 && *src) *(dst++) = *(src++);
|
||||||
|
if (n > 4 && *src) *(dst++) = *(src++);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(*src)
|
||||||
|
{
|
||||||
|
if (STRCHR(TRIV_METACHARS "aeiouyAEIOUY",*src))
|
||||||
|
*(dst++) = *src;
|
||||||
|
else
|
||||||
|
*(dst++) = triv_qchar;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
*dst = 0;
|
||||||
|
to_server("%s " TRIV_HINT_DELAY_STR1 " seconds remaining.\n",triv_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void trivia_cleanup(void)
|
||||||
|
{
|
||||||
|
Strp *ans;
|
||||||
|
|
||||||
|
triv_mode = TRIV_WAIT_QUESTION;
|
||||||
|
triv_next_time = now + triv_qdelay;
|
||||||
|
while((ans = triv_answers))
|
||||||
|
{
|
||||||
|
triv_answers = ans->next;
|
||||||
|
Free((char**)&ans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trivia_check(Chan *chan, char *rest)
|
||||||
|
{
|
||||||
|
TrivScore *su;
|
||||||
|
Strp *ans;
|
||||||
|
int week;
|
||||||
|
|
||||||
|
if (chan != triv_chan)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(ans=triv_answers;ans;ans=ans->next)
|
||||||
|
{
|
||||||
|
if (!stringcasecmp(ans->p,rest))
|
||||||
|
goto have_answer;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
have_answer:
|
||||||
|
week = (now + (3 * DAY_IN_SECONDS)) / WEEK_IN_SECONDS;
|
||||||
|
|
||||||
|
for(su=scorelist;su;su=su->next)
|
||||||
|
{
|
||||||
|
if (!nickcmp(su->nick,CurrentNick))
|
||||||
|
{
|
||||||
|
su->score_mo += triv_score;
|
||||||
|
|
||||||
|
if (su->week_nr == week)
|
||||||
|
su->score_wk += triv_score;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (su->week_nr == (week - 1))
|
||||||
|
su->score_last_wk = su->score_wk;
|
||||||
|
else
|
||||||
|
su->score_last_wk = 0;
|
||||||
|
su->week_nr = week;
|
||||||
|
su->score_wk = triv_score;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!su)
|
||||||
|
{
|
||||||
|
set_mallocdoer(trivia_check);
|
||||||
|
su = (TrivScore*)Calloc(sizeof(TrivScore) + strlen(CurrentNick));
|
||||||
|
su->next = scorelist;
|
||||||
|
scorelist = su;
|
||||||
|
su->score_wk = su->score_mo = triv_score;
|
||||||
|
su->week_nr = week;
|
||||||
|
/* su->month_nr = 0; * fix this */
|
||||||
|
stringcpy(su->nick,CurrentNick);
|
||||||
|
}
|
||||||
|
|
||||||
|
to_server("PRIVMSG %s :Yes, %s! got the answer -> %s <- in %i seconds, and gets %i points!\n",
|
||||||
|
triv_chan->name,CurrentNick,triv_answers->p,
|
||||||
|
(int)(now - triv_ask_time),triv_score);
|
||||||
|
|
||||||
|
if (su == lastwinner)
|
||||||
|
{
|
||||||
|
triv_streak++;
|
||||||
|
if (su->score_wk == su->score_mo)
|
||||||
|
{
|
||||||
|
to_server("PRIVMSG %s :%s has won %i in a row! Total score this Week: %i points\n",
|
||||||
|
triv_chan->name,CurrentNick,triv_streak,su->score_wk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
to_server("PRIVMSG %s :%s has won %i in a row! Total score this Week: %i points, and this Month: %i points\n",
|
||||||
|
triv_chan->name,CurrentNick,triv_streak,su->score_wk,su->score_mo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastwinner = su;
|
||||||
|
triv_streak = 1;
|
||||||
|
if (su->score_wk == su->score_mo)
|
||||||
|
{
|
||||||
|
to_server("PRIVMSG %s :%s has won the question! Total score this Week: %i points\n",
|
||||||
|
triv_chan->name,CurrentNick,su->score_wk);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
to_server("PRIVMSG %s :%s has won the question! Total score this Week: %i points, and this Month: %i points\n",
|
||||||
|
triv_chan->name,CurrentNick,su->score_wk,su->score_mo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trivia_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void trivia_no_answer(void)
|
||||||
|
{
|
||||||
|
to_server("PRIVMSG %s :Time's up! The answer was -> %s <-\n",
|
||||||
|
triv_chan->name,triv_answers->p);
|
||||||
|
|
||||||
|
trivia_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
char *random_question(char *triv_rand)
|
||||||
|
{
|
||||||
|
char *p,tmpname[120];
|
||||||
|
off_t sz;
|
||||||
|
int fd,ifd;
|
||||||
|
int n;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int off;
|
||||||
|
int sz;
|
||||||
|
|
||||||
|
} entry;
|
||||||
|
|
||||||
|
if (STRCHR(triv_qfile,'/') || strlen(triv_qfile) > 100) // really bad filenames...
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
stringcat(stringcpy(tmpname,"trivia/"),triv_qfile);
|
||||||
|
|
||||||
|
if ((fd = open(tmpname,O_RDONLY)) < 0)
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
debug("(random_question) %s: %s\n",tmpname,strerror(errno));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return(NULL);
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
stringcpy(triv_rand,tmpname);
|
||||||
|
if ((p = STRCHR(triv_rand,'.')) == NULL)
|
||||||
|
p = STREND(triv_rand);
|
||||||
|
stringcpy(p,".index");
|
||||||
|
|
||||||
|
if ((ifd = open(triv_rand,O_RDONLY)) < 0)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
sz = lseek(ifd,0,SEEK_END);
|
||||||
|
sz = sz / sizeof(entry);
|
||||||
|
n = RANDOM(1,sz);
|
||||||
|
n--;
|
||||||
|
|
||||||
|
lseek(ifd,(n * sizeof(entry)),SEEK_SET);
|
||||||
|
if (read(ifd,&entry,sizeof(entry)) == -1)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
lseek(fd,entry.off,SEEK_SET);
|
||||||
|
if (read(fd,triv_rand,entry.sz) == -1)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
triv_rand[entry.sz] = 0;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
close(ifd);
|
||||||
|
|
||||||
|
return(triv_rand);
|
||||||
|
}
|
||||||
|
|
||||||
|
void trivia_question(void)
|
||||||
|
{
|
||||||
|
char buffer[MSGLEN];
|
||||||
|
char *question,*answer,*rest;
|
||||||
|
|
||||||
|
if (triv_halt_flag)
|
||||||
|
{
|
||||||
|
to_server("PRIVMSG %s :Trivia has been stopped!\n",triv_chan->name);
|
||||||
|
goto stop_trivia;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rest = random_question(buffer)) == NULL)
|
||||||
|
{
|
||||||
|
bad_question:
|
||||||
|
to_server("PRIVMSG %s :Bad Question File\n",triv_chan->name);
|
||||||
|
stop_trivia:
|
||||||
|
trivia_cleanup();
|
||||||
|
triv_chan = NULL;
|
||||||
|
triv_next_time = 0;
|
||||||
|
triv_halt_flag = FALSE;
|
||||||
|
short_tv &= ~TV_TRIVIA;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
question = get_token(&rest,MATCH_ALL);
|
||||||
|
|
||||||
|
while((answer = get_token(&rest,MATCH_ALL)))
|
||||||
|
append_strp(&triv_answers,answer);
|
||||||
|
|
||||||
|
if (triv_answers == NULL)
|
||||||
|
goto bad_question;
|
||||||
|
|
||||||
|
triv_score = (RANDOM(2,9) + RANDOM(2,10) + RANDOM(2,10)) / 3;
|
||||||
|
triv_ask_time = now;
|
||||||
|
|
||||||
|
if (now > (triv_weektop10 + 1200))
|
||||||
|
{
|
||||||
|
trivia_week_toppers();
|
||||||
|
triv_weektop10 = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
to_server("PRIVMSG %s :%s\n",triv_chan->name,question);
|
||||||
|
hint_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
void trivia_tick(void)
|
||||||
|
{
|
||||||
|
Chan *chan;
|
||||||
|
Mech *bot;
|
||||||
|
|
||||||
|
if (triv_next_time && (now >= triv_next_time))
|
||||||
|
{
|
||||||
|
for(bot=botlist;bot;bot=bot->next)
|
||||||
|
{
|
||||||
|
for(chan=bot->chanlist;chan;chan=chan->next)
|
||||||
|
{
|
||||||
|
if (triv_chan == chan)
|
||||||
|
{
|
||||||
|
current = bot;
|
||||||
|
triv_next_time = now + TRIV_HINT_DELAY;
|
||||||
|
switch(triv_mode)
|
||||||
|
{
|
||||||
|
case TRIV_WAIT_QUESTION:
|
||||||
|
trivia_question();
|
||||||
|
break;
|
||||||
|
case TRIV_HINT_TWO:
|
||||||
|
hint_two();
|
||||||
|
break;
|
||||||
|
case TRIV_HINT_THREE:
|
||||||
|
hint_three();
|
||||||
|
break;
|
||||||
|
case TRIV_NO_ANSWER:
|
||||||
|
trivia_no_answer();
|
||||||
|
return; /* dont increment with triv_mode */
|
||||||
|
}
|
||||||
|
triv_mode++;
|
||||||
|
#ifdef DEBUG
|
||||||
|
current = NULL;
|
||||||
|
#endif /* DEBUG */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* File operations
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void write_triviascore(void)
|
||||||
|
{
|
||||||
|
TrivScore *su;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (scorelist)
|
||||||
|
{
|
||||||
|
if ((fd = open(TRIVIASCOREFILE,O_WRONLY|O_TRUNC|O_CREAT,NEWFILEMODE)) < 0)
|
||||||
|
return;
|
||||||
|
to_file(fd,COMMENT_STRCHR " nick score_wk score_mo score_last_wk score_last_mo\n");
|
||||||
|
for(su=scorelist;su;su=su->next)
|
||||||
|
{
|
||||||
|
to_file(fd,"%s %i %i %i %i %i %i\n",su->nick,su->score_wk,su->score_mo,
|
||||||
|
su->score_last_wk,su->score_last_mo,su->week_nr,su->month_nr);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int trivia_score_callback(char *rest)
|
||||||
|
{
|
||||||
|
TrivScore *su;
|
||||||
|
char *nick,*wk,*mo,*lwk,*lmo,*wnr,*mnr;
|
||||||
|
int score_wk,score_mo,score_last_wk,score_last_mo;
|
||||||
|
int week_nr,month_nr;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (*rest != COMMENT_CHAR)
|
||||||
|
{
|
||||||
|
nick = chop(&rest);
|
||||||
|
wk = chop(&rest);
|
||||||
|
mo = chop(&rest);
|
||||||
|
lwk = chop(&rest);
|
||||||
|
lmo = chop(&rest);
|
||||||
|
wnr = chop(&rest);
|
||||||
|
mnr = chop(&rest);
|
||||||
|
|
||||||
|
if (mnr)
|
||||||
|
{
|
||||||
|
score_wk = asc2int(wk);
|
||||||
|
err = errno;
|
||||||
|
score_mo = asc2int(mo);
|
||||||
|
err += errno;
|
||||||
|
score_last_wk = asc2int(lwk);
|
||||||
|
err += errno;
|
||||||
|
score_last_mo = asc2int(lmo);
|
||||||
|
err += errno;
|
||||||
|
week_nr = asc2int(wnr);
|
||||||
|
err += errno;
|
||||||
|
month_nr = asc2int(mnr);
|
||||||
|
err += errno;
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
set_mallocdoer(trivia_score_callback);
|
||||||
|
su = (TrivScore*)Calloc(sizeof(TrivScore) + strlen(nick));
|
||||||
|
su->next = scorelist;
|
||||||
|
scorelist = su;
|
||||||
|
su->score_wk = score_wk;
|
||||||
|
su->score_mo = score_mo;
|
||||||
|
su->score_last_wk = score_last_wk;
|
||||||
|
su->score_last_mo = score_last_mo;
|
||||||
|
su->week_nr = week_nr;
|
||||||
|
su->month_nr = month_nr;
|
||||||
|
stringcpy(su->nick,nick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_triviascore(void)
|
||||||
|
{
|
||||||
|
TrivScore *su;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if ((fd = open(TRIVIASCOREFILE,O_RDONLY)) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while(scorelist)
|
||||||
|
{
|
||||||
|
su = scorelist;
|
||||||
|
scorelist = su->next;
|
||||||
|
Free((char**)&su);
|
||||||
|
}
|
||||||
|
|
||||||
|
readline(fd,&trivia_score_callback); /* readline closes fd */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TRIVIA */
|
||||||
|
|
||||||
|
/*
|
||||||
|
-+=====================================================================================================================+-
|
||||||
|
toybox.c commands
|
||||||
|
-+=====================================================================================================================+-
|
||||||
|
*/
|
||||||
|
|
||||||
void do_bigsay(COMMAND_ARGS)
|
void do_bigsay(COMMAND_ARGS)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -465,3 +1005,80 @@ pick_randnum:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* TOYBOX */
|
#endif /* TOYBOX */
|
||||||
|
|
||||||
|
#ifdef TRIVIA
|
||||||
|
|
||||||
|
void do_trivia(COMMAND_ARGS)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* on_msg checks CAXS + CARGS
|
||||||
|
*/
|
||||||
|
Chan *chan;
|
||||||
|
int uaccess;
|
||||||
|
|
||||||
|
uaccess = get_maxaccess(from);
|
||||||
|
|
||||||
|
if ((chan = find_channel_ac(to)) == NULL)
|
||||||
|
{
|
||||||
|
if (uaccess) to_user(from,ERR_CHAN,to);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stringcasecmp(rest,"start"))
|
||||||
|
{
|
||||||
|
if (triv_chan)
|
||||||
|
{
|
||||||
|
if (triv_chan == chan)
|
||||||
|
{
|
||||||
|
triv_halt_flag = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (uaccess) to_user(from,"trivia is already activated on %s!",
|
||||||
|
(get_useraccess(from,triv_chan->name)) ? triv_chan->name : "another channel");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
to_server("PRIVMSG %s :Trivia starting! Get ready...\n",chan->name);
|
||||||
|
triv_chan = chan;
|
||||||
|
triv_mode = TRIV_WAIT_QUESTION;
|
||||||
|
triv_next_time = now + triv_qdelay;
|
||||||
|
triv_weektop10 = now;
|
||||||
|
lastwinner = NULL;
|
||||||
|
short_tv |= TV_TRIVIA;
|
||||||
|
if (!scorelist)
|
||||||
|
{
|
||||||
|
read_triviascore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!stringcasecmp(rest,"stop"))
|
||||||
|
{
|
||||||
|
if (chan == triv_chan)
|
||||||
|
{
|
||||||
|
if (chan == triv_chan)
|
||||||
|
to_server("PRIVMSG %s :Trivia shutting down...\n",chan->name);
|
||||||
|
triv_halt_flag = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!stringcasecmp(rest,"top10"))
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (triv_chan)
|
||||||
|
{
|
||||||
|
uaccess = get_authaccess(from,triv_chan->name);
|
||||||
|
if (now > (triv_weektop10 + 300))
|
||||||
|
n = 1;
|
||||||
|
else
|
||||||
|
n = uaccess;
|
||||||
|
|
||||||
|
if (n)
|
||||||
|
{
|
||||||
|
trivia_week_toppers();
|
||||||
|
if (!uaccess) triv_weektop10 = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* TRIVIA */
|
||||||
|
|||||||
643
src/trivia.c
643
src/trivia.c
@ -1,643 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
EnergyMech, IRC bot software
|
|
||||||
Copyright (c) 2001-2004 proton
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#define TRIVIA_C
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#ifdef TRIVIA
|
|
||||||
#include "defines.h"
|
|
||||||
#include "structs.h"
|
|
||||||
#include "global.h"
|
|
||||||
#include "h.h"
|
|
||||||
#include "text.h"
|
|
||||||
#include "mcmd.h"
|
|
||||||
|
|
||||||
#define TRIV_WAIT_QUESTION 0
|
|
||||||
#define TRIV_HINT_TWO 1
|
|
||||||
#define TRIV_HINT_THREE 2
|
|
||||||
#define TRIV_NO_ANSWER 3
|
|
||||||
|
|
||||||
#define TRIV_HINT_DELAY 15
|
|
||||||
|
|
||||||
#define TRIV_HINT_DELAY_STR1 "15"
|
|
||||||
#define TRIV_HINT_DELAY_STR2 "30"
|
|
||||||
|
|
||||||
#define TRIV_METACHARS " .,-'%&/?!:;\""
|
|
||||||
|
|
||||||
#define DAY_IN_SECONDS (24*60*60)
|
|
||||||
#define WEEK_IN_SECONDS (7*24*60*60)
|
|
||||||
|
|
||||||
LS TrivScore *lastwinner;
|
|
||||||
LS Chan *triv_chan = NULL;
|
|
||||||
LS Strp *triv_answers = NULL;
|
|
||||||
LS time_t triv_ask_time;
|
|
||||||
LS time_t triv_next_time = 0;
|
|
||||||
LS time_t triv_weektop10;
|
|
||||||
LS int triv_mode;
|
|
||||||
LS int triv_score;
|
|
||||||
LS int triv_streak;
|
|
||||||
LS int triv_halt_flag;
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* scorings
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void trivia_week_toppers(void)
|
|
||||||
{
|
|
||||||
char triv_str[MSGLEN];
|
|
||||||
TrivScore *chosen[10];
|
|
||||||
TrivScore *su;
|
|
||||||
char *p;
|
|
||||||
int week;
|
|
||||||
int i,x;
|
|
||||||
|
|
||||||
chosen[0] = NULL;
|
|
||||||
week = (now + (3 * DAY_IN_SECONDS)) / WEEK_IN_SECONDS;
|
|
||||||
|
|
||||||
for(su=scorelist;su;su=su->next)
|
|
||||||
{
|
|
||||||
if (su->week_nr != week)
|
|
||||||
continue;
|
|
||||||
for(i=0;i<10;i++)
|
|
||||||
{
|
|
||||||
if (!chosen[i] || (chosen[i]->score_wk < su->score_wk))
|
|
||||||
{
|
|
||||||
for(x=8;x>=i;x--)
|
|
||||||
chosen[x+1] = chosen[x];
|
|
||||||
chosen[i] = su;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chosen[0])
|
|
||||||
{
|
|
||||||
p = triv_str;
|
|
||||||
for(i=0;i<10;i++)
|
|
||||||
{
|
|
||||||
if (!chosen[i])
|
|
||||||
break;
|
|
||||||
if (i)
|
|
||||||
{
|
|
||||||
*(p++) = ' ';
|
|
||||||
*(p++) = ' ';
|
|
||||||
}
|
|
||||||
sprintf(p,"#%i: %s (%ipts)",i+1,chosen[i]->nick,chosen[i]->score_wk);
|
|
||||||
p = STREND(p);
|
|
||||||
}
|
|
||||||
to_server("PRIVMSG %s :This Weeks Top 10: %s\n",triv_chan->name,triv_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void hint_one(void)
|
|
||||||
{
|
|
||||||
char triv_str[MSGLEN];
|
|
||||||
char *src,*dst;
|
|
||||||
|
|
||||||
sprintf(triv_str,"PRIVMSG %s :1st hint: ",triv_chan->name);
|
|
||||||
dst = STREND(triv_str);
|
|
||||||
src = triv_answers->p;
|
|
||||||
while(*src)
|
|
||||||
{
|
|
||||||
if (STRCHR(TRIV_METACHARS,*src))
|
|
||||||
*(dst++) = *src;
|
|
||||||
else
|
|
||||||
*(dst++) = triv_qchar;
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
*dst = 0;
|
|
||||||
to_server("%s Question score: %i points\n",triv_str,triv_score);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hint_two(void)
|
|
||||||
{
|
|
||||||
char triv_str[MSGLEN];
|
|
||||||
char *src,*dst;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
sprintf(triv_str,"PRIVMSG %s :2nd hint: ",triv_chan->name);
|
|
||||||
dst = STREND(triv_str);
|
|
||||||
src = triv_answers->p;
|
|
||||||
|
|
||||||
n = asc2int(src);
|
|
||||||
if (!errno)
|
|
||||||
{
|
|
||||||
if (n > 99 && *src) *(dst++) = *(src++);
|
|
||||||
if (n > 999 && *src) *(dst++) = *(src++);
|
|
||||||
if (n > 9999 && *src) *(dst++) = *(src++);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
n = strlen(src);
|
|
||||||
if (n > 2 && *src) *(dst++) = *(src++);
|
|
||||||
if (n > 4 && *src) *(dst++) = *(src++);
|
|
||||||
if (n > 6 && *src) *(dst++) = *(src++);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(*src)
|
|
||||||
{
|
|
||||||
if (STRCHR(TRIV_METACHARS,*src))
|
|
||||||
*(dst++) = *src;
|
|
||||||
else
|
|
||||||
*(dst++) = triv_qchar;
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
*dst = 0;
|
|
||||||
to_server("%s " TRIV_HINT_DELAY_STR2 " seconds remaining.\n",triv_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hint_three(void)
|
|
||||||
{
|
|
||||||
char triv_str[MSGLEN];
|
|
||||||
char *src,*dst;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
sprintf(triv_str,"PRIVMSG %s :3rd hint: ",triv_chan->name);
|
|
||||||
dst = STREND(triv_str);
|
|
||||||
src = triv_answers->p;
|
|
||||||
|
|
||||||
n = asc2int(src);
|
|
||||||
if (!errno)
|
|
||||||
{
|
|
||||||
if (n > 9 && *src) *(dst++) = *(src++);
|
|
||||||
if (n > 99 && *src) *(dst++) = *(src++);
|
|
||||||
if (n > 999 && *src) *(dst++) = *(src++);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
n = strlen(src);
|
|
||||||
if (n > 1 && *src) *(dst++) = *(src++);
|
|
||||||
if (n > 3 && *src) *(dst++) = *(src++);
|
|
||||||
if (n > 4 && *src) *(dst++) = *(src++);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(*src)
|
|
||||||
{
|
|
||||||
if (STRCHR(TRIV_METACHARS "aeiouyAEIOUY",*src))
|
|
||||||
*(dst++) = *src;
|
|
||||||
else
|
|
||||||
*(dst++) = triv_qchar;
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
*dst = 0;
|
|
||||||
to_server("%s " TRIV_HINT_DELAY_STR1 " seconds remaining.\n",triv_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void trivia_cleanup(void)
|
|
||||||
{
|
|
||||||
Strp *ans;
|
|
||||||
|
|
||||||
triv_mode = TRIV_WAIT_QUESTION;
|
|
||||||
triv_next_time = now + triv_qdelay;
|
|
||||||
while((ans = triv_answers))
|
|
||||||
{
|
|
||||||
triv_answers = ans->next;
|
|
||||||
Free((char**)&ans);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trivia_check(Chan *chan, char *rest)
|
|
||||||
{
|
|
||||||
TrivScore *su;
|
|
||||||
Strp *ans;
|
|
||||||
int week;
|
|
||||||
|
|
||||||
if (chan != triv_chan)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(ans=triv_answers;ans;ans=ans->next)
|
|
||||||
{
|
|
||||||
if (!stringcasecmp(ans->p,rest))
|
|
||||||
goto have_answer;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
have_answer:
|
|
||||||
week = (now + (3 * DAY_IN_SECONDS)) / WEEK_IN_SECONDS;
|
|
||||||
|
|
||||||
for(su=scorelist;su;su=su->next)
|
|
||||||
{
|
|
||||||
if (!nickcmp(su->nick,CurrentNick))
|
|
||||||
{
|
|
||||||
su->score_mo += triv_score;
|
|
||||||
|
|
||||||
if (su->week_nr == week)
|
|
||||||
su->score_wk += triv_score;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (su->week_nr == (week - 1))
|
|
||||||
su->score_last_wk = su->score_wk;
|
|
||||||
else
|
|
||||||
su->score_last_wk = 0;
|
|
||||||
su->week_nr = week;
|
|
||||||
su->score_wk = triv_score;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!su)
|
|
||||||
{
|
|
||||||
set_mallocdoer(trivia_check);
|
|
||||||
su = (TrivScore*)Calloc(sizeof(TrivScore) + strlen(CurrentNick));
|
|
||||||
su->next = scorelist;
|
|
||||||
scorelist = su;
|
|
||||||
su->score_wk = su->score_mo = triv_score;
|
|
||||||
su->week_nr = week;
|
|
||||||
/* su->month_nr = 0; * fix this */
|
|
||||||
stringcpy(su->nick,CurrentNick);
|
|
||||||
}
|
|
||||||
|
|
||||||
to_server("PRIVMSG %s :Yes, %s! got the answer -> %s <- in %i seconds, and gets %i points!\n",
|
|
||||||
triv_chan->name,CurrentNick,triv_answers->p,
|
|
||||||
(int)(now - triv_ask_time),triv_score);
|
|
||||||
|
|
||||||
if (su == lastwinner)
|
|
||||||
{
|
|
||||||
triv_streak++;
|
|
||||||
if (su->score_wk == su->score_mo)
|
|
||||||
{
|
|
||||||
to_server("PRIVMSG %s :%s has won %i in a row! Total score this Week: %i points\n",
|
|
||||||
triv_chan->name,CurrentNick,triv_streak,su->score_wk);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
to_server("PRIVMSG %s :%s has won %i in a row! Total score this Week: %i points, and this Month: %i points\n",
|
|
||||||
triv_chan->name,CurrentNick,triv_streak,su->score_wk,su->score_mo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lastwinner = su;
|
|
||||||
triv_streak = 1;
|
|
||||||
if (su->score_wk == su->score_mo)
|
|
||||||
{
|
|
||||||
to_server("PRIVMSG %s :%s has won the question! Total score this Week: %i points\n",
|
|
||||||
triv_chan->name,CurrentNick,su->score_wk);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
to_server("PRIVMSG %s :%s has won the question! Total score this Week: %i points, and this Month: %i points\n",
|
|
||||||
triv_chan->name,CurrentNick,su->score_wk,su->score_mo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trivia_cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void trivia_no_answer(void)
|
|
||||||
{
|
|
||||||
to_server("PRIVMSG %s :Time's up! The answer was -> %s <-\n",
|
|
||||||
triv_chan->name,triv_answers->p);
|
|
||||||
|
|
||||||
trivia_cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
char *random_question(char *triv_rand)
|
|
||||||
{
|
|
||||||
char *p,tmpname[120];
|
|
||||||
off_t sz;
|
|
||||||
int fd,ifd;
|
|
||||||
int n;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
int off;
|
|
||||||
int sz;
|
|
||||||
|
|
||||||
} entry;
|
|
||||||
|
|
||||||
if (STRCHR(triv_qfile,'/') || strlen(triv_qfile) > 100) // really bad filenames...
|
|
||||||
return(NULL);
|
|
||||||
|
|
||||||
stringcat(stringcpy(tmpname,"trivia/"),triv_qfile);
|
|
||||||
|
|
||||||
if ((fd = open(tmpname,O_RDONLY)) < 0)
|
|
||||||
#ifdef DEBUG
|
|
||||||
{
|
|
||||||
debug("(random_question) %s: %s\n",tmpname,strerror(errno));
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return(NULL);
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
stringcpy(triv_rand,tmpname);
|
|
||||||
if ((p = STRCHR(triv_rand,'.')) == NULL)
|
|
||||||
p = STREND(triv_rand);
|
|
||||||
stringcpy(p,".index");
|
|
||||||
|
|
||||||
if ((ifd = open(triv_rand,O_RDONLY)) < 0)
|
|
||||||
return(NULL);
|
|
||||||
|
|
||||||
sz = lseek(ifd,0,SEEK_END);
|
|
||||||
sz = sz / sizeof(entry);
|
|
||||||
n = RANDOM(1,sz);
|
|
||||||
n--;
|
|
||||||
|
|
||||||
lseek(ifd,(n * sizeof(entry)),SEEK_SET);
|
|
||||||
if (read(ifd,&entry,sizeof(entry)) == -1)
|
|
||||||
return(NULL);
|
|
||||||
|
|
||||||
lseek(fd,entry.off,SEEK_SET);
|
|
||||||
if (read(fd,triv_rand,entry.sz) == -1)
|
|
||||||
return(NULL);
|
|
||||||
|
|
||||||
triv_rand[entry.sz] = 0;
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
close(ifd);
|
|
||||||
|
|
||||||
return(triv_rand);
|
|
||||||
}
|
|
||||||
|
|
||||||
void trivia_question(void)
|
|
||||||
{
|
|
||||||
char buffer[MSGLEN];
|
|
||||||
char *question,*answer,*rest;
|
|
||||||
|
|
||||||
if (triv_halt_flag)
|
|
||||||
{
|
|
||||||
to_server("PRIVMSG %s :Trivia has been stopped!\n",triv_chan->name);
|
|
||||||
goto stop_trivia;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rest = random_question(buffer)) == NULL)
|
|
||||||
{
|
|
||||||
bad_question:
|
|
||||||
to_server("PRIVMSG %s :Bad Question File\n",triv_chan->name);
|
|
||||||
stop_trivia:
|
|
||||||
trivia_cleanup();
|
|
||||||
triv_chan = NULL;
|
|
||||||
triv_next_time = 0;
|
|
||||||
triv_halt_flag = FALSE;
|
|
||||||
short_tv &= ~TV_TRIVIA;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
question = get_token(&rest,MATCH_ALL);
|
|
||||||
|
|
||||||
while((answer = get_token(&rest,MATCH_ALL)))
|
|
||||||
append_strp(&triv_answers,answer);
|
|
||||||
|
|
||||||
if (triv_answers == NULL)
|
|
||||||
goto bad_question;
|
|
||||||
|
|
||||||
triv_score = (RANDOM(2,9) + RANDOM(2,10) + RANDOM(2,10)) / 3;
|
|
||||||
triv_ask_time = now;
|
|
||||||
|
|
||||||
if (now > (triv_weektop10 + 1200))
|
|
||||||
{
|
|
||||||
trivia_week_toppers();
|
|
||||||
triv_weektop10 = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
to_server("PRIVMSG %s :%s\n",triv_chan->name,question);
|
|
||||||
hint_one();
|
|
||||||
}
|
|
||||||
|
|
||||||
void trivia_tick(void)
|
|
||||||
{
|
|
||||||
Chan *chan;
|
|
||||||
Mech *bot;
|
|
||||||
|
|
||||||
if (triv_next_time && (now >= triv_next_time))
|
|
||||||
{
|
|
||||||
for(bot=botlist;bot;bot=bot->next)
|
|
||||||
{
|
|
||||||
for(chan=bot->chanlist;chan;chan=chan->next)
|
|
||||||
{
|
|
||||||
if (triv_chan == chan)
|
|
||||||
{
|
|
||||||
current = bot;
|
|
||||||
triv_next_time = now + TRIV_HINT_DELAY;
|
|
||||||
switch(triv_mode)
|
|
||||||
{
|
|
||||||
case TRIV_WAIT_QUESTION:
|
|
||||||
trivia_question();
|
|
||||||
break;
|
|
||||||
case TRIV_HINT_TWO:
|
|
||||||
hint_two();
|
|
||||||
break;
|
|
||||||
case TRIV_HINT_THREE:
|
|
||||||
hint_three();
|
|
||||||
break;
|
|
||||||
case TRIV_NO_ANSWER:
|
|
||||||
trivia_no_answer();
|
|
||||||
return; /* dont increment with triv_mode */
|
|
||||||
}
|
|
||||||
triv_mode++;
|
|
||||||
#ifdef DEBUG
|
|
||||||
current = NULL;
|
|
||||||
#endif /* DEBUG */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* File operations
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void write_triviascore(void)
|
|
||||||
{
|
|
||||||
TrivScore *su;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
if (scorelist)
|
|
||||||
{
|
|
||||||
if ((fd = open(TRIVIASCOREFILE,O_WRONLY|O_TRUNC|O_CREAT,NEWFILEMODE)) < 0)
|
|
||||||
return;
|
|
||||||
to_file(fd,COMMENT_STRCHR " nick score_wk score_mo score_last_wk score_last_mo\n");
|
|
||||||
for(su=scorelist;su;su=su->next)
|
|
||||||
{
|
|
||||||
to_file(fd,"%s %i %i %i %i %i %i\n",su->nick,su->score_wk,su->score_mo,
|
|
||||||
su->score_last_wk,su->score_last_mo,su->week_nr,su->month_nr);
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int trivia_score_callback(char *rest)
|
|
||||||
{
|
|
||||||
TrivScore *su;
|
|
||||||
char *nick,*wk,*mo,*lwk,*lmo,*wnr,*mnr;
|
|
||||||
int score_wk,score_mo,score_last_wk,score_last_mo;
|
|
||||||
int week_nr,month_nr;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (*rest != COMMENT_CHAR)
|
|
||||||
{
|
|
||||||
nick = chop(&rest);
|
|
||||||
wk = chop(&rest);
|
|
||||||
mo = chop(&rest);
|
|
||||||
lwk = chop(&rest);
|
|
||||||
lmo = chop(&rest);
|
|
||||||
wnr = chop(&rest);
|
|
||||||
mnr = chop(&rest);
|
|
||||||
|
|
||||||
if (mnr)
|
|
||||||
{
|
|
||||||
score_wk = asc2int(wk);
|
|
||||||
err = errno;
|
|
||||||
score_mo = asc2int(mo);
|
|
||||||
err += errno;
|
|
||||||
score_last_wk = asc2int(lwk);
|
|
||||||
err += errno;
|
|
||||||
score_last_mo = asc2int(lmo);
|
|
||||||
err += errno;
|
|
||||||
week_nr = asc2int(wnr);
|
|
||||||
err += errno;
|
|
||||||
month_nr = asc2int(mnr);
|
|
||||||
err += errno;
|
|
||||||
|
|
||||||
if (!err)
|
|
||||||
{
|
|
||||||
set_mallocdoer(trivia_score_callback);
|
|
||||||
su = (TrivScore*)Calloc(sizeof(TrivScore) + strlen(nick));
|
|
||||||
su->next = scorelist;
|
|
||||||
scorelist = su;
|
|
||||||
su->score_wk = score_wk;
|
|
||||||
su->score_mo = score_mo;
|
|
||||||
su->score_last_wk = score_last_wk;
|
|
||||||
su->score_last_mo = score_last_mo;
|
|
||||||
su->week_nr = week_nr;
|
|
||||||
su->month_nr = month_nr;
|
|
||||||
stringcpy(su->nick,nick);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_triviascore(void)
|
|
||||||
{
|
|
||||||
TrivScore *su;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
if ((fd = open(TRIVIASCOREFILE,O_RDONLY)) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while(scorelist)
|
|
||||||
{
|
|
||||||
su = scorelist;
|
|
||||||
scorelist = su->next;
|
|
||||||
Free((char**)&su);
|
|
||||||
}
|
|
||||||
|
|
||||||
readline(fd,&trivia_score_callback); /* readline closes fd */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void do_trivia(COMMAND_ARGS)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* on_msg checks CAXS + CARGS
|
|
||||||
*/
|
|
||||||
Chan *chan;
|
|
||||||
int uaccess;
|
|
||||||
|
|
||||||
uaccess = get_maxaccess(from);
|
|
||||||
|
|
||||||
if ((chan = find_channel_ac(to)) == NULL)
|
|
||||||
{
|
|
||||||
if (uaccess) to_user(from,ERR_CHAN,to);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stringcasecmp(rest,"start"))
|
|
||||||
{
|
|
||||||
if (triv_chan)
|
|
||||||
{
|
|
||||||
if (triv_chan == chan)
|
|
||||||
{
|
|
||||||
triv_halt_flag = FALSE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (uaccess) to_user(from,"trivia is already activated on %s!",
|
|
||||||
(get_useraccess(from,triv_chan->name)) ? triv_chan->name : "another channel");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
to_server("PRIVMSG %s :Trivia starting! Get ready...\n",chan->name);
|
|
||||||
triv_chan = chan;
|
|
||||||
triv_mode = TRIV_WAIT_QUESTION;
|
|
||||||
triv_next_time = now + triv_qdelay;
|
|
||||||
triv_weektop10 = now;
|
|
||||||
lastwinner = NULL;
|
|
||||||
short_tv |= TV_TRIVIA;
|
|
||||||
if (!scorelist)
|
|
||||||
{
|
|
||||||
read_triviascore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (!stringcasecmp(rest,"stop"))
|
|
||||||
{
|
|
||||||
if (chan == triv_chan)
|
|
||||||
{
|
|
||||||
if (chan == triv_chan)
|
|
||||||
to_server("PRIVMSG %s :Trivia shutting down...\n",chan->name);
|
|
||||||
triv_halt_flag = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (!stringcasecmp(rest,"top10"))
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
if (triv_chan)
|
|
||||||
{
|
|
||||||
uaccess = get_authaccess(from,triv_chan->name);
|
|
||||||
if (now > (triv_weektop10 + 300))
|
|
||||||
n = 1;
|
|
||||||
else
|
|
||||||
n = uaccess;
|
|
||||||
|
|
||||||
if (n)
|
|
||||||
{
|
|
||||||
trivia_week_toppers();
|
|
||||||
if (!uaccess) triv_weektop10 = now;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TRIVIA */
|
|
||||||
Loading…
x
Reference in New Issue
Block a user