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
mech.trivscore
trivia/megatrivia.txt
*.log
*.stats
# developer files
.use_size
conf
debug*
*.log
*.stats
github
src/calc.c
src/x
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
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/net.c src/note.c src/notify.c src/ons.c src/parse.c src/partyline.c src/perl.c src/prot.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/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/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
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)
* 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
* Fixed: Missing ifdef BOTNET in user.c
* 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|;
" < 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() {
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
@ -1539,16 +1529,28 @@ if [ -w ./myconfig -o ! -e ./myconfig ]; then
save_myconfig
fi
echo ''
echo 'All done. You can now "make install"'
if [ ! "$cores" = 1 ]; then
echo "For speedy compiling, use \`\`make -j$cores''"
if [ "$install" = yes ]; then
make $makejobs -C src energymech
exit
fi
echo ''
echo "Your chosen ./configure options have been saved to ./myconfig"
echo 'if you wish to save ./myconfig in its current state, chmod -w ./myconfig'
echo ''
echo 'Submit your bugreports at https://github.com/MadCamel/energymech/issues'
echo ''
echo 'You have read the README file I hope?'
echo ''
if [ "$compile" = yes ]; then
make $makejobs -C src energymech
exit
fi
$out ''
$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
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 \
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 \
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 \
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
@ -78,6 +78,8 @@ usercombo.h: gencmd
githash.h: gencmd
./gencmd githash.h
global.h: githash.h
install: $(INSTALLNAME)
$(CHMOD) $(INSTALLMODE) $(INSTALLNAME)
$(MV) $(INSTALLNAME) $(INSTALLDIR)
@ -107,12 +109,12 @@ mega-install: mega $(SRCFILES) $(INCS) usage.h
$(MV) $(INSTALLNAME) $(INSTALLDIR)
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)
@sz@ size $(INSTALLNAME)
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)
@sz@ size $(INSTALLNAME)
@ -188,9 +190,6 @@ io.o: io.c $(INCS)
irc.o: irc.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
kicksay.o: kicksay.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
main.o: main.c $(INCS) githash.h
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -DGENDATE="`./gencmd date`" $(CPROF) $(PYINCLUDE)
@ -200,9 +199,6 @@ net.o: net.c $(INCS)
note.o: note.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
notify.o: notify.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
ons.o: ons.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
@ -239,9 +235,6 @@ tcl.o: tcl.c $(INCS)
toybox.o: toybox.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
trivia.o: trivia.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
uptime.o: uptime.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)

View File

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

40
src/h.h
View File

@ -576,7 +576,7 @@ LS void do_banlist(COMMAND_ARGS) __page(CMD1_SEG);
#ifdef PYTHON
#ifdef DEBUG_C
#if defined(DEBUG_C) || defined(MEGA_C)
PyObject *python_hook(PyObject *self, PyObject *args, PyObject *keywds);
PyObject *python_unhook(PyObject *self, PyObject *args, PyObject *keywds);
#endif
@ -655,7 +655,7 @@ LS void do_urlhist(COMMAND_ARGS) __page(CMD1_SEG);
LS int tcl_timer_jump(Hook *hook);
LS int tcl_parse_jump(char *from, char *rest, Hook *hook);
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[]);
#endif
//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 */
LS int read_bigcharset_callback(char *rest);
LS int read_bigcharset(char *fname);
LS int read_ascii(char *rest);
LS int read_bigcharset_callback(char *);
LS int read_bigcharset(char *);
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_random_msg(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_ascii(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 */

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.
*/
#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
#include "config.h"
@ -28,6 +84,8 @@
#include "text.h"
#include "mcmd.h"
#endif /* ifdef-else MEGA_C */
/*
* 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
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;
}
//if (!stringcmp(rest,telnetprompt)) // another bot sent me its telnetprompt // dont assume identical prompts
// return;
#ifdef NETCFG
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,10 +598,110 @@ void chanban_action(char *nick, char *channel, Shit *shit)
#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)
@ -797,3 +897,132 @@ void do_banlist(COMMAND_ARGS)
to_user(from,"There are no active bans on %s",to);
#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;
#endif /* TELNET */
#define mkaxx(x) (0x40404040 + (0x0f0f & x) + ((0xf0f0 & x) << 12))
#define getaxx(x) (((x & 0x0f0f0000) >> 12) | (x & 0x00000f0f))
char *recover_client(char *env)
{
union {
uint32_t num[2];
char asc[8];
} axx;
struct sockaddr_in sai;
Client *client;
User *user;
char *p,*handle;
int guid,fd,sz;
int guid = 0,fd = 0,sz;
guid = fd = 0;
p = env;
/*
* get the guid number
*/
while(*p >= '0' && *p <= '9')
{
guid = (guid * 10) + (*p - '0');
p++;
}
if (*p != ':')
if (env[8] != ':')
return(env);
p++;
/*
* get the fd number
*/
while(*p >= '0' && *p <= '9')
{
fd = (fd * 10) + (*p - '0');
p++;
}
if (*p != ':')
return(env);
p++;
memcpy(axx.asc,env,8); // compiler is not stupid and will optimize the shit out of this
guid = getaxx(axx.num[0]);
fd = getaxx(axx.num[1]);
handle = p;
handle = p = (env = env + 9);
while(*p)
{
if (*p == ' ' || *p == 0)
@ -150,22 +137,21 @@ found_user:
char *recover_debug(char *env)
{
union {
uint32_t num;
char asc[4];
} axx;
struct stat s;
char *p;
debug_fd = 0;
p = env;
if (env[4] != ' ' && env[4] != 0)
return(env);
/*
* get the fd number
*/
while(*p >= '0' && *p <= '9')
{
debug_fd = (debug_fd * 10) + (*p - '0');
p++;
}
if (*p != ' ' && *p != 0)
return(env);
memcpy(axx.asc,env,4); // compiler is not stupid and will optimize the shit out of this
debug_fd = getaxx(axx.num);
if (fstat(debug_fd,&s) < 0)
{
@ -176,71 +162,57 @@ char *recover_debug(char *env)
else
{
dodebug = TRUE;
debug("(recover_debug) debug fd recovered\n");
debug("(recover_debug) {%i} debug fd recovered\n",debug_fd);
CoreClient.sock = debug_fd;
}
return(p);
return(env+4);
}
#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)
{
union {
uint32_t num[4];
char asc[16];
} axx;
struct sockaddr_in sai;
char *p;
int guid,fd,sz;
int guid = 0,fd = 0,sz;
#ifdef IRCD_EXTENSIONS
int ircx = 0;
#endif /* IRCD_EXTENSIONS */
guid = fd = 0;
p = env;
/*
* get the guid number
*/
while(*p >= '0' && *p <= '9')
switch(*env++)
{
guid = (guid * 10) + (*p - '0');
p++;
}
if (*p != ':')
case 'x':
sz = 8;
break;
case 'X':
sz = 12;
break;
default:
return(env);
p++;
/*
* get the fd number
*/
while(*p >= '0' && *p <= '9')
{
fd = (fd * 10) + (*p - '0');
p++;
}
#ifndef IRCD_EXTENSIONS
if (*p != ' ' && *p != 0)
if (env[sz] != ' ' && env[sz] != 0)
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
if (*p == ':' && *(p+1) == 'X')
{
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);
ircx = getaxx(axx.num[2]);
#ifdef DEBUG
debug("(recover_server) guid = %i; fd = %i, ircx = %i\n",guid,fd,ircx);
#endif /* DEBUG */
@ -254,7 +226,7 @@ char *recover_server(char *env)
if (getsockname(fd,(struct sockaddr*)&sai,&sz) < 0)
{
close(fd);
return(p);
return(env);
}
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");
killsock(fd);
}
return(p);
return(env);
}
#ifdef IRCD_EXTENSIONS
/*
#define IRCX_WALLCHOPS 1
#define IRCX_WALLVOICES 2
#define IRCX_IMODE 4
#define IRCX_EMODE 8
*/
#endif /* 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 } )
void recover_reset(void)
{
@ -329,17 +293,23 @@ void recover_reset(void)
default:
env++;
}
while(*env == ' ')
env++;
}
}
/*
*
* commands
*
-+=====================================================================================================================+-
reset.c commands
-+=====================================================================================================================+-
*/
void do_reset(COMMAND_ARGS)
{
union {
uint32_t num[8];
char asc[32];
} axx;
Client *client;
Mech *backup;
char env[MSGLEN];
@ -372,16 +342,16 @@ void do_reset(COMMAND_ARGS)
*env = 0;
p = stringcat(env,STR_MECHRESET);
n = 0;
#ifdef DEBUG
/*
* debug stuff
*/
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);
n++;
}
#endif /* DEBUG */
/*
@ -393,15 +363,17 @@ void do_reset(COMMAND_ARGS)
if ((current->connect == CN_ONLINE) && ((MSGLEN - (p - env)) > 25))
{
unset_closeonexec(current->sock);
if (n)
*(p++) = ' ';
axx.num[0] = mkaxx(current->guid);
axx.num[1] = mkaxx(current->sock);
#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 */
sprintf(p,"f%i:%i",current->guid,current->sock);
axx.num[2] = 0;
sprintf(p," fx%s",axx.asc);
#endif /* IRCD_EXTENSIONS */
p = STREND(p);
n++;
to_server("PING :OT%lu\n",current->ontime);
}
for(client=current->clientlist;client;client=client->next)
@ -417,16 +389,16 @@ void do_reset(COMMAND_ARGS)
if ((MSGLEN - (p - env)) > sz)
{
unset_closeonexec(client->sock);
if (n)
*(p++) = ' ';
axx.num[0] = mkaxx(current->guid);
axx.num[1] = mkaxx(client->sock);
axx.num[2] = 0;
#ifdef TELNET
sprintf(p,(client->flags & DCC_TELNET) ? "t%i:%i:%s" : "c%i:%i:%s",
current->guid,current->sock,client->user->name);
sprintf(p,(client->flags & DCC_TELNET) ? " t%s:%s" : " c%s:%s",
axx.asc,client->user->name);
#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 */
p = STREND(p);
n++;
}
}
}
@ -436,7 +408,7 @@ void do_reset(COMMAND_ARGS)
debug("(do_reset) %s [%i]\n",env,(int)(p - env));
#endif /* DEBUG */
mechresetenv = (n) ? env : NULL;
mechresetenv = (*env) ? env : NULL;
do_exec = TRUE;
mech_exec();

View File

@ -21,8 +21,6 @@
#define SEEN_C
#include "config.h"
#ifdef SEEN
#include "defines.h"
#include "structs.h"
#include "global.h"
@ -30,6 +28,612 @@
#include "text.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)
{
Seen *seen;
@ -213,9 +817,9 @@ step_two:
}
/*
*
* commands for seen features
*
-+=====================================================================================================================+-
seen.c commands
-+=====================================================================================================================+-
*/
void do_seen(COMMAND_ARGS)
@ -312,3 +916,121 @@ void do_seen(COMMAND_ARGS)
}
#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
int modcount;
int guid;
uint16_t guid;
int tick;
int addsession;
#endif /* BOTNET */
@ -519,7 +519,7 @@ typedef struct Mech
{
struct Mech *next;
int guid; /* globally uniqe ID */
uint16_t guid; /* globally uniqe ID */
int connect;
int sock;
struct in_addr ip; /* for DCC */
@ -656,7 +656,7 @@ typedef struct BotInfo
{
struct BotInfo *next;
int guid;
uint16_t guid;
int hops;
char *version;
@ -678,7 +678,7 @@ typedef struct BotNet
* 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 rsid; /* remote session id */
@ -709,7 +709,7 @@ typedef struct NetCfg
{
struct NetCfg *next;
int guid;
uint16_t guid;
uint16_t port;
uint16_t linked; //:1;
@ -762,7 +762,7 @@ typedef struct Hook
struct Hook *next;
int (*func)();
int guid; /* guid filter */
uint16_t guid; /* guid filter */
int flags;
union {
void *any;

View File

@ -29,6 +29,36 @@
#include "text.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 FONT_EXTENSION ".bigchars"
@ -160,12 +190,522 @@ int read_ascii(char *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)
{
/*
@ -465,3 +1005,80 @@ pick_randnum:
}
#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 */