merged .c files, fixed dcc/telnet clients lost on reset, rewrote reset some

This commit is contained in:
joonicks 2018-04-15 21:09:37 +02:00
parent 5f0fdada3e
commit 33f72e424b
18 changed files with 1788 additions and 1903 deletions

6
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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
View File

@ -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 ''

View File

@ -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)

View File

@ -108,7 +108,6 @@ LS const struct
#endif #endif
{ NULL, }}; { NULL, }};
LS struct LS struct
{ {
void *func; void *func;

40
src/h.h
View File

@ -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 */

View File

@ -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 = &current->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 */
}

View File

@ -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
*/ */

View File

@ -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"

View File

@ -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)
{ {

View File

@ -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,&notifylog_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 = &current->notifylist;
readline(fd,&notify_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 = &current->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 = &current->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 */

View File

@ -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 = &current->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 */
}

View File

@ -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();

View File

@ -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,&notifylog_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 = &current->notifylist;
readline(fd,&notify_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 = &current->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 = &current->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 */

View File

@ -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;

View File

@ -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 */

View File

@ -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 */