merge /devel and /trunk.... update configure.in. we can start working again on /trunk

This commit is contained in:
Fish 2003-11-18 11:51:09 +00:00
parent 6d3d394d31
commit 66d244268d
74 changed files with 14175 additions and 1973 deletions

119
.gitattributes vendored
View file

@ -2,26 +2,26 @@
/.indent.pro -text
/AUTHORS -text
/BUGS -text
/Bahamut.c -text
/Bahamut.h -text
/Bahamut.c eol=lf
/Bahamut.h eol=lf
/COPYING -text
/CREDITS -text
/ChangeLog -text
/Config -text
/Ircu.c -text
/Ircu.h -text
/Ircu.c eol=lf
/Ircu.h eol=lf
/Makefile.in -text
/Makefile.inc.in -text
/QuantumIRCd.c -text
/QuantumIRCd.h -text
/QuantumIRCd.c eol=lf
/QuantumIRCd.h eol=lf
/README -text
/RELNOTES -text
/TODO -text
/Ultimate.c -text
/Ultimate.h -text
/Unreal.c -text
/Unreal.h -text
/acconfig.h -text
/Ultimate.c eol=lf
/Ultimate.h eol=lf
/Unreal.c eol=lf
/Unreal.h eol=lf
/acconfig.h eol=lf
/aclocal.m4 -text
adns/.indent.pro -text
adns/Makefile -text
@ -39,9 +39,10 @@ adns/setup.c -text
adns/transmit.c -text
adns/tvarith.h -text
adns/types.c -text
/chans.c -text
/conf.c -text
/conf.h -text
/chans.c eol=lf
/chans.h eol=lf
/conf.c eol=lf
/conf.h eol=lf
/config.guess -text
/config.h.in -text
/config.sub -text
@ -50,8 +51,8 @@ adns/types.c -text
/cronchk -text
data/niconfig.db -text
data/tlds.nfo -text
/dl.c -text
/dl.h -text
/dl.c eol=lf
/dl.h eol=lf
dl/.indent.pro -text
dl/Makefile -text
dl/README -text
@ -117,7 +118,8 @@ dl/template/Makefile -text
dl/template/template.c -text
dl/version/Makefile -text
dl/version/version.c -text
/dns.c -text
/dns.c eol=lf
/dns.h eol=lf
doc/FAQ -text
doc/FAQ.pt -text
doc/USERMAN -text
@ -127,19 +129,19 @@ doc/old/INSTALL.pt -text
doc/old/README.pt -text
doc/read-faq -text
doc/read-userman -text
/dotconf.c -text
/dotconf.h -text
/events.h -text
/hash.c -text
/hash.h -text
/hybrid7.c -text
/hybrid7.h -text
/dotconf.c eol=lf
/dotconf.h eol=lf
/events.h eol=lf
/hash.c eol=lf
/hash.h eol=lf
/hybrid7.c eol=lf
/hybrid7.h eol=lf
/install-sh -text
/ircd.c -text
/ircd.h -text
/ircstring.c -text
/ircstring.h -text
/keeper.c -text
/ircd.c eol=lf
/ircd.h eol=lf
/ircstring.c eol=lf
/ircstring.h eol=lf
/keeper.c eol=lf
keeper/.indent.pro -text
keeper/Makefile -text
keeper/keeper.h -text
@ -153,28 +155,46 @@ keeper/kp_set.c -text
keeper/kp_sort.c -text
keeper/kp_util.c -text
keeper/kp_util.h -text
/list.c -text
/list.h -text
/log.c -text
/log.h -text
/liquidircd.c -text
/liquidircd.h -text
/list.c eol=lf
/list.h eol=lf
/log.c eol=lf
/log.h eol=lf
logs/.keepme -text
/main.c -text
/main.c eol=lf
/makeconf -text
/misc.c -text
/mystic.c -text
/mystic.h -text
/neoircd.c -text
/neoircd.h -text
/misc.c eol=lf
/mystic.c eol=lf
/mystic.h eol=lf
/neoircd.c eol=lf
/neoircd.h eol=lf
/neostats.motd -text
/ns_help.c -text
/server.c -text
/services.c -text
/sock.c -text
/sock.h -text
/stats.h -text
/support.c -text
/support.h -text
/timer.c -text
/ns_help.c eol=lf
/ns_help.h eol=lf
/numeric.h -text
pcre/COPYING -text
pcre/Makefile.in eol=lf
pcre/README -text
pcre/config.h.in eol=lf
pcre/dftables.c eol=lf
pcre/get.c eol=lf
pcre/internal.h eol=lf
pcre/maketables.c eol=lf
pcre/pcre.c eol=lf
pcre/pcre.in eol=lf
pcre/study.c eol=lf
/server.c eol=lf
/server.h eol=lf
/services.c eol=lf
/services.h eol=lf
/sock.c eol=lf
/sock.h eol=lf
/stats.h eol=lf
/support.c eol=lf
/support.h eol=lf
/timer.c eol=lf
/timer.h eol=lf
tools/Makefile.in -text
tools/README.kptool -text
tools/cfgtool/Makefile -text
@ -198,4 +218,5 @@ tools/kp_exp.c -text
tools/kp_imp.c -text
tools/kptool.c -text
tools/kptool.h -text
/users.c -text
/users.c eol=lf
/users.h eol=lf

View file

@ -29,10 +29,13 @@
#include "Bahamut.h"
#include "dl.h"
#include "log.h"
#include "server.h"
#include "chans.h"
static char ircd_buf[BUFSIZE];
const char ircd_version[] = "(B)";
const char services_bot_modes[]= "+oS";
IntCommands cmd_list[] = {
/* Command Function srvmsg */
@ -141,14 +144,14 @@ Oper_Modes usr_mds[] = {
,
{UMODE_REGNICK, 'r', 10}
,
{UMODE_SERVICESADMIN, 'a', 200}
{UMODE_SERVICESADMIN, 'a', NS_ULEVEL_ROOT}
,
{UMODE_SERVADMIN, 'A', 100}
,
{UMODE_REGONLY, 'R', 0}
,
/* this is needed for bot support */
{UMODE_SERVICES, 'S', 200}
{UMODE_SERVICES, 'S', NS_ULEVEL_ROOT}
,
{0, 0, 0}
};
@ -441,6 +444,13 @@ sakill_cmd (const char *host, const char *ident, const char *setby, const int le
return 1;
}
int
sinvite_cmd (const char *from, const char *to, const char *chan) {
sts (":%s INVITE %s %s", from, to, chan);
return 1;
}
int
srakill_cmd (const char *host, const char *ident)
{
@ -637,7 +647,7 @@ Srv_Sjoin (char *origin, char **argv, int argc)
}
c = findchan (argv[1]);
/* update the TS time */
Change_Chan_Ts (c, atoi (argv[0]));
ChangeChanTS (c, atoi (argv[0]));
c->modes |= mode1;
if (!list_isempty (tl)) {
if (!list_isfull (c->modeparms)) {
@ -779,7 +789,7 @@ Usr_Away (char *origin, char **argv, int argc)
} else {
Buf = NULL;
}
Do_Away (u, Buf);
UserAway (u, Buf);
if (argc > 0) {
free (Buf);
}
@ -803,7 +813,7 @@ Usr_Topic (char *origin, char **argv, int argc)
c = findchan (argv[0]);
if (c) {
buf = joinbuf (argv, argc, 3);
Change_Topic (argv[1], c, atoi (argv[2]), buf);
ChangeTopic (argv[1], c, atoi (argv[2]), buf);
free (buf);
} else {
nlog (LOG_WARNING, LOG_CORE, "Ehhh, Can't find Channel %s", argv[0]);

View file

@ -28,6 +28,17 @@
/* we support tokens */
#undef HAVE_TOKEN_SUP
/* we dont have svshost support */
#undef GOTSVSHOST
/* we don't have svsjoin support */
#undef GOTSVSJOIN
/* Moved from connectserv so we can use elsewhere */
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define SERVERADMIN_MODE 'a'
#define MSG_PRIVATE "PRIVMSG" /* PRIV */
#define MSG_WHO "WHO" /* WHO -> WHOC */
@ -277,6 +288,7 @@ extern int sakill_cmd (const char *host, const char *ident, const char *setby, c
extern int srakill_cmd (const char *host, const char *ident);
extern int ssvshost_cmd (const char *who, const char *vhost);
extern int ssvskill_cmd (const char *who, const char *reason, ...);
extern int sinvite_cmd (const char *from, const char *to, const char *chan);
void Usr_Version (char *, char **, int argc);
void Usr_ShowMOTD (char *, char **, int argc);

View file

@ -1,5 +1,24 @@
NeoStats ChangeLog - Anything we add/remove/fix/change is in here (even our rants)
=====================================================================================
* NeoStats * Fish (F) & Mark (M)* Version 2.5.9
- import of libpcre into core (M)
- added some defines for common user levels (M)
- added some defines for common errors so functions can better handle failure conditions (M)
- cleanup of default settings and configs - defaults were often set twice! (M)
- fixed debug mode messages given to users under certain conditions (M)
- main command list now in a table to make it easy to add new commands (M)
- shorted some command text by stripping superfluous prefixes (M)
- ns_set_debug disable bug fixed (M)
- ns_set_debug function parameters changed to support command table (M)
- ns_set_debug now requires explicit ON/OFF to make consistent with other commands (M)
- removed chan from __Chan_Message parameters since it is in av[0] anyway (M)
- cleanups of core functions and module API including cleanup of module types and references (M)
- Updated command user levels and associated help text (M)
- Made M's bot message handling and help functions dynamic.. so modules can add/remove commands to the services bot... should make these functions a bit more generic so they could be called from any modules to handle messages. (F)
- imported LiquidIRCd support from ???? (F)
- Admin text filename changed from "stats.admin" to "neostats.admin" (M)
- Added services_bot_modes to each IRCd. This should contain the required ircd specific modes for a services bot (M)
* NeoStats * Fish (F) & Mark (M)* Version 2.5.8
- strncpy replaced by strlcpy - faster and safer (M)
- Replaced redundant strlen calls with faster and safer alternatives (M)

39
Config
View file

@ -8,7 +8,6 @@ IRCD=
#module vars
MODULELIST=""
MSTATSERV=1
MSPAM=0
MLOVESERV=1
MHOSTSERV=1
MMORALESERV=1
@ -139,37 +138,6 @@ while [ $validselection -eq 0 ] ; do
done
echo ""
if [ "$MSPAM" = 1 ] ; then
YN_DEFAULT=yes
else
YN_DEFAULT=no
fi
validselection=0
echo "Do you want to build spam?"
while [ $validselection -eq 0 ] ; do
echo_no_lf "[$YN_DEFAULT] "
if read INPUT ; then : ; else echo "" ; exit 1 ; fi
if [ ! "$INPUT" ] ; then
INPUT=$YN_DEFAULT
fi
case $INPUT in
n*|N*)
MSPAM=0
validselection=1
;;
y*|Y*)
MSPAM=1
HAVEMODS=1
validselection=1
;;
*)
echo 'Please enter "yes" or "no".'
;;
esac
done
echo ""
if [ "$MLOVESERV" = 1 ] ; then
YN_DEFAULT=yes
else
@ -341,13 +309,6 @@ fi
HAVEMOD=1
MODULELIST=$MODULELIST"statserv"
fi
if [ "$MSPAM" = 1 ] ; then
if [ "$HAVEMOD" = 1 ] ; then
MODULELIST="$MODULELIST "
fi
HAVEMOD=1
MODULELIST=$MODULELIST"spam"
fi
if [ "$MLOVESERV" = 1 ] ; then
if [ "$HAVEMOD" = 1 ] ; then
MODULELIST="$MODULELIST "

12
Ircu.c
View file

@ -27,10 +27,14 @@
#include "Ircu.h"
#include "dl.h"
#include "log.h"
#include "users.h"
#include "server.h"
#include "chans.h"
static char ircd_buf[BUFSIZE];
const char ircd_version[] = "(IRCU)";
const char services_bot_modes[]= "+oS";
/* this is the command list and associated functions to run */
IntCommands cmd_list[] = {
@ -136,7 +140,7 @@ Oper_Modes usr_mds[] = {
,
{UMODE_CCONN, 'c', 0}
,
{UMODE_DEBUG, 'd', 200}
{UMODE_DEBUG, 'd', NS_ULEVEL_ROOT}
,
{UMODE_FULL, 'f', 0}
,
@ -798,7 +802,7 @@ Usr_Away (char *origin, char **argv, int argc)
} else {
buf = NULL;
}
Do_Away (u, buf);
UserAway (u, buf);
if (argc > 0) {
free (buf);
}
@ -825,7 +829,7 @@ Usr_Topic (char *origin, char **argv, int argc)
c = findchan (argv[0]);
if (c) {
buf = joinbuf (argv, argc, 2);
Change_Topic (origin, c, me.now, buf);
ChangeTopic (origin, c, me.now, buf);
free (buf);
} else {
nlog (LOG_WARNING, LOG_CORE, "Ehhh, Can't find Channel %s", argv[0]);
@ -884,7 +888,7 @@ Srv_Netinfo (char *origin, char **argv, int argc)
strlcpy (me.netname, argv[7], MAXPASS);
init_ServBot ();
globops (me.name, "Link with Network \2Complete!\2");
Module_Event (EVENT_NETINFO, NULL, 0);
ModuleEvent (EVENT_NETINFO, NULL, 0);
me.synced = 1;
}

4
Ircu.h
View file

@ -25,7 +25,9 @@
#ifndef IRCU_H
#define IRCU_H
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define SERVERADMIN_MODE 'a'
#define MSG_EOB "EOB" /* end of burst */

View file

@ -4,6 +4,7 @@
# makefile originally created by Andy Church.
include Makefile.inc
PCRE_OBJS = pcre/pcre.o pcre/get.o pcre/study.o
OBJS = dns.o chans.o dotconf.o services.o main.o sock.o conf.o ircd.o timer.o \
users.o ns_help.o dl.o list.o hash.o server.o keeper.o log.o misc.o \
@ -23,30 +24,31 @@ DATA = data/tlds.nfo
INCLUDES = config.h dl.h dotconf.h hash.h list.h stats.h Ultimate.h Unreal.h \
adns/adns.h hybrid7.h neoircd.h conf.h log.h Bahamut.h \
Ircu.h mystic.h QuantumIRCd.h sock.h ircd.h \
support.h ircstring.h events.h
support.h ircstring.h events.h liquidircd.h numeric.h pcre.h
BUILDFILES = configure *.in adns/Makefile adns/config.h.in dl/Makefile \
dl/modules.txt RELNOTES install-sh neoircd.c neoircd.h \
hybrid7.c hybrid7.h Ultimate.c Ultimate.h Unreal.c Unreal.h \
makeconf cronchk tools/Makefile.in tools/cfgtool/Makefile \
keeper/Makefile doc/old/* Bahamut.c Ircu.c mystic.c \
QuantumIRCd.c Config
QuantumIRCd.c Config liquidircd.c
TOOLFILES = tools/*.c tools/*.h tools/cfgtool/*.h tools/cfgtool/*.c \
tools/cfgtool/pixmaps/*.xpm
DISTFILES = $(INCLUDES) $(SRCS) $(DATA) $(DOCS) $(DOCS_PROGS) $(CONF) \
$(BUILDFILES) $(TOOLFILES) keeper/*.c keeper/*.h adns/*.c \
adns/adns.h adns/dlist.h adns/internal.h adns/tvarith.h
adns/adns.h adns/dlist.h adns/internal.h adns/tvarith.h \
ns_help.h timer.h users.h chans.h server.h
distdir = @PACKAGE@-@VERSION@
SUBDIRS = doc doc/old data adns logs keeper tools tools/cfgtool \
tools/cfgtool/pixmaps
tools/cfgtool/pixmaps pcre
DISTMOD = cs extauth hostserv loveserv ms spam statserv version template
.c.o:
$(CC) $(NEOINCLUDES) $(CFLAGS) -c $<
all: libadns.a libkeeper.a neostats modules utils
all: libadns.a libkeeper.a libpcre neostats modules utils
modules:
(cd dl; $(MAKE) $@)
@ -57,6 +59,9 @@ libadns.a:
libkeeper.a:
(cd keeper; $(MAKE) $@)
libpcre:
(cd pcre; $(MAKE))
utils:
(cd tools; $(MAKE) $@)
@ -66,11 +71,12 @@ clean:
(cd adns; $(MAKE) $@)
(cd keeper; $(MAKE) $@)
(cd tools; $(MAKE) $@)
(cd pcre; $(MAKE) $@)
/bin/rm -rf *.o neostats *.cache Makefile config.h Makefile.inc *.log *.a
neostats: $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) adns/libadns.a keeper/libkeeper.a -o $@
$(CC) $(LDFLAGS) $(OBJS) adns/libadns.a keeper/libkeeper.a $(PCRE_OBJS) -o $@
install: neostats modules
@rm -rf @prefix@/dl/cs.so

View file

@ -29,10 +29,14 @@
#include "QuantumIRCd.h"
#include "dl.h"
#include "log.h"
#include "users.h"
#include "server.h"
#include "chans.h"
static char ircd_buf[BUFSIZE];
const char ircd_version[] = "(Q)";
const char services_bot_modes[]= "+oS";
IntCommands cmd_list[] = {
/* Command Function srvmsg */
@ -261,11 +265,11 @@ Oper_Modes usr_mds[] = {
,
{UMODE_HIDE, 'x', 0}
,
{UMODE_IRCADMIN, 'Z', 200}
{UMODE_IRCADMIN, 'Z', NS_ULEVEL_ROOT}
,
{UMODE_SERVICESADMIN, 'P', 185}
{UMODE_SERVICESADMIN, 'P', NS_ULEVEL_ADMIN}
,
{UMODE_SERVICES, 'S', 200}
{UMODE_SERVICES, 'S', NS_ULEVEL_ROOT}
,
{UMODE_PROT, 'p', 0}
,
@ -599,6 +603,12 @@ ssvshost_cmd (const char *who, const char *vhost)
return 1;
}
}
int
sinvite_cmd (const char *from, const char *to, const char *chan) {
sts (":%s INVITE %s %s", from, to, chan);
return 1;
}
int
sakill_cmd (const char *host, const char *ident, const char *setby, const int length, const char *reason, ...)
{
@ -973,7 +983,7 @@ Usr_Away (char *origin, char **argv, int argc)
} else {
Buf = NULL;
}
Do_Away (u, Buf);
UserAway (u, Buf);
if (argc > 0) {
free (Buf);
}
@ -997,7 +1007,7 @@ Usr_Topic (char *origin, char **argv, int argc)
c = findchan (argv[0]);
if (c) {
buf = joinbuf (argv, argc, 3);
Change_Topic (argv[1], c, atoi (argv[2]), buf);
ChangeTopic (argv[1], c, atoi (argv[2]), buf);
free (buf);
} else {
nlog (LOG_WARNING, LOG_CORE, "Ehhh, Can't find Channel %s", argv[0]);

View file

@ -31,6 +31,21 @@
/* we have vhost support */
#define GOTSVSVHOST
/* we dont have svsjoin */
#undef GOTSVSJOIN
/* Moved from connectserv so we can use elsewhere */
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define GUESTADMIN_MODE 'G'
#define COSERVERADMIN_MODE 'J'
#define SERVERADMIN_MODE 'A'
#define CONETADMIN_MODE 'n'
#define NETADMIN_MODE 'N'
#define COTECHADMIN_MODE 't'
#define TECHADMIN_MODE 'T' /* Set to a number as we dont use */
#define SERVICESADMIN_MODE 'a'
#define NETSERVICE_MODE 'S'
#define MSG_PRIVATE "PRIVMSG" /* PRIV */
#define TOK_PRIVATE "!" /* 33 */
@ -468,6 +483,7 @@ extern int sakill_cmd (const char *host, const char *ident, const char *setby, c
extern int srakill_cmd (const char *host, const char *ident);
extern int ssvshost_cmd (const char *who, const char *vhost);
extern int ssvskill_cmd (const char *who, const char *reason, ...);
extern int sinvite_cmd (const char *from, const char *to, const char *chan);
void Usr_Version (char *, char **, int argc);
void Usr_ShowMOTD (char *, char **, int argc);

5
README
View file

@ -231,14 +231,13 @@ NeoStats ships with the following modules:
HostServ --enable-modules="hostserv"
LoveServ --enable-modules="loveserv"
MoraleServ --enable-modules="ms"
spam --enable-modules="spam"
StatServ --enable-modules="statserv"
To compile multiple modules combine the enable-modules options together
as follows:
--enable-modules="statserv spam"
(this would enable the statserv and spam modules).
--enable-modules="statserv hostserv"
(this would enable the statserv and hostserv modules).
If you have downloaded additional modules from the NeoStats website,
DO NOT specify them in the enable-modules option. Each module has its

View file

@ -29,13 +29,18 @@
#include "Ultimate.h"
#include "dl.h"
#include "log.h"
#include "users.h"
#include "server.h"
#include "chans.h"
static char ircd_buf[BUFSIZE];
#ifndef ULTIMATE3
const char ircd_version[] = "(UL)";
const char services_bot_modes[]= "+oS";
#else
const char ircd_version[] = "(UL3)";
const char services_bot_modes[]= "+oS";
#endif
IntCommands cmd_list[] = {
@ -270,11 +275,11 @@ Oper_Modes usr_mds[] = {
,
{UMODE_HIDE, 'x', 0}
,
{UMODE_IRCADMIN, 'Z', 200}
{UMODE_IRCADMIN, 'Z', NS_ULEVEL_ROOT}
,
{UMODE_SERVICESADMIN, 'P', 185}
{UMODE_SERVICESADMIN, 'P', NS_ULEVEL_ADMIN}
,
{UMODE_SERVICES, 'S', 200}
{UMODE_SERVICES, 'S', NS_ULEVEL_ROOT}
,
{UMODE_PROT, 'p', 0}
,
@ -327,9 +332,9 @@ Oper_Modes usr_mds[] = {
,
{UMODE_KILLS, 'k', 0}
,
{UMODE_SERVICES, 'S', 200}
{UMODE_SERVICES, 'S', NS_ULEVEL_ROOT}
,
{UMODE_SERVICESADMIN, 'P', 200}
{UMODE_SERVICESADMIN, 'P', NS_ULEVEL_ROOT}
,
{UMODE_RBOT, 'B', 0}
,
@ -337,7 +342,7 @@ Oper_Modes usr_mds[] = {
,
{UMODE_ADMIN, 'z', 70}
,
{UMODE_NETADMIN, 'N', 185}
{UMODE_NETADMIN, 'N', NS_ULEVEL_ADMIN}
,
{UMODE_TECHADMIN, 'T', 190}
,
@ -680,6 +685,15 @@ ssvshost_cmd (const char *who, const char *vhost)
return 1;
}
}
int
sinvite_cmd (const char *from, const char *to, const char *chan) {
sts (":%s INVITE %s %s", from, to, chan);
return 1;
}
int
sakill_cmd (const char *host, const char *ident, const char *setby, const int length, const char *reason, ...)
{
@ -1076,7 +1090,7 @@ Usr_Away (char *origin, char **argv, int argc)
} else {
Buf = NULL;
}
Do_Away (u, Buf);
UserAway (u, Buf);
if (argc > 0) {
free (Buf);
}
@ -1100,7 +1114,7 @@ Usr_Topic (char *origin, char **argv, int argc)
c = findchan (argv[0]);
if (c) {
buf = joinbuf (argv, argc, 3);
Change_Topic (argv[1], c, atoi (argv[2]), buf);
ChangeTopic (argv[1], c, atoi (argv[2]), buf);
free (buf);
} else {
nlog (LOG_WARNING, LOG_CORE, "Ehhh, Can't find Channel %s", argv[0]);
@ -1179,9 +1193,9 @@ Srv_Netinfo (char *origin, char **argv, int argc)
init_ServBot ();
globops (me.name, "Link with Network \2Complete!\2");
#ifdef DEBUG
ns_set_debug (me.chan);
me.debug_mode = 1;
#endif
Module_Event (EVENT_NETINFO, NULL, 0);
ModuleEvent (EVENT_NETINFO, NULL, 0);
me.synced = 1;
}
#endif

View file

@ -31,6 +31,38 @@
/* we have vhost support */
#define GOTSVSVHOST
#ifdef ULTIMATE3
/* we have svsjoin from a30 onwards */
#define GOTSVSJOIN
/* Moved from connectserv so we can use elsewhere */
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define GUESTADMIN_MODE 'G'
#define COSERVERADMIN_MODE 'J'
#define SERVERADMIN_MODE 'A'
#define CONETADMIN_MODE 'n'
#define NETADMIN_MODE 'N'
#define COTECHADMIN_MODE 't'
#define TECHADMIN_MODE 'T' /* Set to a number as we dont use */
#define SERVICESADMIN_MODE 'a'
#define NETSERVICE_MODE 'S'
#else
/* old Ultimate2 doesn't have svsjoin */
#undef SVSJOIN
/* Moved from connectserv so we can use elsewhere */
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define COSERVERADMIN_MODE 'J'
#define SERVERADMIN_MODE 'A'
#define CONETADMIN_MODE 't'
#define NETADMIN_MODE 'N'
#define TECHADMIN_MODE 'T'
#define SERVICESADMIN_MODE 'P'
#define NETSERVICE_MODE 'S'
#define BOT_MODE 'B'
#endif
#define MSG_PRIVATE "PRIVMSG" /* PRIV */
@ -494,6 +526,8 @@ extern int sakill_cmd (const char *host, const char *ident, const char *setby, c
extern int srakill_cmd (const char *host, const char *ident);
extern int ssvshost_cmd (const char *who, const char *vhost);
extern int ssvskill_cmd (const char *who, const char *reason, ...);
extern int sinvite_cmd (const char *from, const char *to, const char *chan);
void Usr_Version (char *, char **, int argc);
void Usr_ShowMOTD (char *, char **, int argc);

View file

@ -29,10 +29,14 @@
#include "Unreal.h"
#include "dl.h"
#include "log.h"
#include "users.h"
#include "server.h"
#include "chans.h"
static char ircd_buf[BUFSIZE];
const char ircd_version[] = "(U)";
const char services_bot_modes[]= "+oS";
IntCommands cmd_list[] = {
/* Command Function srvmsg */
@ -247,7 +251,7 @@ Oper_Modes usr_mds[] = {
,
{UMODE_KILLS, 'k', 0}
,
{UMODE_SERVICES, 'S', 200}
{UMODE_SERVICES, 'S', NS_ULEVEL_ROOT}
,
{UMODE_SADMIN, 'a', 100}
,
@ -267,7 +271,7 @@ Oper_Modes usr_mds[] = {
,
{UMODE_ADMIN, 'A', 70}
,
{UMODE_NETADMIN, 'N', 185}
{UMODE_NETADMIN, 'N', NS_ULEVEL_ADMIN}
,
{UMODE_TECHADMIN, 'T', 190}
,
@ -513,6 +517,13 @@ ssvshost_cmd (const char *who, const char *vhost)
return 1;
}
int
sinvite_cmd (const char *from, const char *to, const char *chan) {
sts (":%s INVITE %s %s", from, to, chan);
return 1;
}
int
ssvsmode_cmd (const char *target, const char *modes)
{
@ -792,7 +803,7 @@ Usr_Away (char *origin, char **argv, int argc)
} else {
buf = NULL;
}
Do_Away (u, buf);
UserAway (u, buf);
if (argc > 0) {
free (buf);
}
@ -818,7 +829,7 @@ Usr_Topic (char *origin, char **argv, int argc)
c = findchan (argv[0]);
if (c) {
buf = joinbuf (argv, argc, 3);
Change_Topic (argv[1], c, atoi (argv[2]), buf);
ChangeTopic (argv[1], c, atoi (argv[2]), buf);
free (buf);
} else {
nlog (LOG_WARNING, LOG_CORE, "Ehhh, Can't find Channel %s", argv[0]);
@ -873,7 +884,7 @@ Srv_Netinfo (char *origin, char **argv, int argc)
snetinfo_cmd ();
init_ServBot ();
globops (me.name, "Link with Network \2Complete!\2");
Module_Event (EVENT_NETINFO, NULL, 0);
ModuleEvent (EVENT_NETINFO, NULL, 0);
me.synced = 1;
}

View file

@ -60,6 +60,20 @@
/* we have vhost support */
#define GOTSVSVHOST
/* we have svsjoin */
#define GOTSVSJOIN
/* Moved from connectserv so we can use elsewhere */
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define COSERVERADMIN_MODE 'C'
#define SERVERADMIN_MODE 'A'
#define NETADMIN_MODE 'N'
#define TECHADMIN_MODE 'T'
#define SERVICESADMIN_MODE 'a'
#define NETSERVICE_MODE 'S'
#define INVISIBLE_MODE 'I'
#define BOT_MODE 'B'
/*
* The tokens are in the ascii character range of 33-127, and we start
@ -486,6 +500,7 @@ extern int ssvskill_cmd (const char *target, const char *reason, ...);
extern int sakill_cmd (const char *host, const char *ident, const char *setby, const int length, const char *reason, ...);
extern int srakill_cmd (const char *host, const char *ident);
extern int SignOn_NewBot (const char *, const char *, const char *, const char *, long);
extern int sinvite_cmd (const char *from, const char *to, const char *chan);
void Usr_Version (char *, char **, int argc);
void Usr_ShowMOTD (char *, char **, int argc);

53
chans.c
View file

@ -26,6 +26,8 @@
#include "dl.h"
#include "hash.h"
#include "log.h"
#include "users.h"
#include "chans.h"
/** @brief Chanmem structure
*
@ -37,6 +39,8 @@ typedef struct Chanmem {
void *moddata[NUM_MODULES];
} Chanmem;
hash_t *ch;
/** @brief initialize the channel data
*
* initializes the channel data and channel hash ch.
@ -65,7 +69,7 @@ init_chan_hash ()
*
*/
void
Change_Chan_Ts (Chans * c, time_t tstime)
ChangeChanTS (Chans * c, time_t tstime)
{
if (!c) {
nlog (LOG_WARNING, LOG_CORE, "Warning, Called Change_Change_Ts with null channel");
@ -90,7 +94,7 @@ Change_Chan_Ts (Chans * c, time_t tstime)
*/
extern void
Change_Topic (char *owner, Chans * c, time_t time, char *topic)
ChangeTopic (char *owner, Chans * c, time_t time, char *topic)
{
char **av;
int ac = 0;
@ -100,9 +104,8 @@ Change_Topic (char *owner, Chans * c, time_t time, char *topic)
AddStringToList (&av, c->name, &ac);
AddStringToList (&av, owner, &ac);
AddStringToList (&av, topic, &ac);
Module_Event (EVENT_TOPICCHANGE, av, ac);
ModuleEvent (EVENT_TOPICCHANGE, av, ac);
free (av);
// FreeList(av, ac);
}
/** @brief Check if a mode is set on a Channel
@ -309,7 +312,7 @@ ChangeChanUserMode (Chans * c, User * u, int add, long mode)
if (!cmn) {
if (me.debug_mode) {
chanalert (s_Services, "ChangeChanUserMode() %s doesn't seem to be in the Chan %s", u->nick, c->name);
chandump (c->name);
ChanDump (c->name);
UserDump (u->nick);
}
return;
@ -412,7 +415,7 @@ kick_chan (User * u, char *chan, User * k)
nlog (LOG_WARNING, LOG_CORE, "NULL user passed to kick_chan u=NULL, chan=%s: %s", chan, recbuf);
if (me.debug_mode) {
chanalert (s_Services, "NULL user passed to kick_chan u=NULL, chan=%s: %s", chan, recbuf);
chandump (chan);
ChanDump (chan);
}
return;
}
@ -420,7 +423,7 @@ kick_chan (User * u, char *chan, User * k)
nlog (LOG_WARNING, LOG_CORE, "NULL user passed to kick_chan k=NULL, chan=%s: %s", chan, recbuf);
if (me.debug_mode) {
chanalert (s_Services, "NULL user passed to kick_chan k=NULL, chan=%s: %s", chan, recbuf);
chandump (chan);
ChanDump (chan);
}
return;
}
@ -435,7 +438,7 @@ kick_chan (User * u, char *chan, User * k)
nlog (LOG_WARNING, LOG_CORE, "Kick: hu, User %s isn't a member of this channel %s", u->nick, chan);
if (me.debug_mode) {
chanalert (s_Services, "Kick: hu, User %s isn't a member of this channel %s", u->nick, chan);
chandump (c->name);
ChanDump (c->name);
UserDump (u->nick);
}
} else {
@ -444,7 +447,8 @@ kick_chan (User * u, char *chan, User * k)
free (cm);
AddStringToList (&av, c->name, &ac);
AddStringToList (&av, u->nick, &ac);
Module_Event (EVENT_KICK, av, ac);
AddStringToList (&av, k->nick, &ac);
ModuleEvent (EVENT_KICK, av, ac);
free (av);
ac = 0;
c->cur_users--;
@ -454,7 +458,8 @@ kick_chan (User * u, char *chan, User * k)
del_bot_from_chan (u->nick, c->name);
AddStringToList (&av, c->name, &ac);
AddStringToList (&av, u->nick, &ac);
Module_Event (EVENT_KICKBOT, av, ac);
AddStringToList (&av, k->nick, &ac);
ModuleEvent (EVENT_KICKBOT, av, ac);
free (av);
ac = 0;
@ -464,7 +469,7 @@ kick_chan (User * u, char *chan, User * k)
nlog (LOG_WARNING, LOG_CORE, "Kick:Hu, User %s claims not to be part of Chan %s", u->nick, chan);
if (me.debug_mode) {
chanalert (s_Services, "Kick: Hu, User %s claims not to be part of Chan %s", u->nick, chan);
chandump (c->name);
ChanDump (c->name);
UserDump (u->nick);
}
} else {
@ -473,7 +478,7 @@ kick_chan (User * u, char *chan, User * k)
nlog (LOG_DEBUG3, LOG_CORE, "Cur Users %s %d (list %d)", c->name, c->cur_users, list_count (c->chanmembers));
if (c->cur_users <= 0) {
AddStringToList (&av, c->name, &ac);
Module_Event (EVENT_DELCHAN, av, ac);
ModuleEvent (EVENT_DELCHAN, av, ac);
free (av);
ac = 0;
del_chan (c);
@ -508,7 +513,7 @@ part_chan (User * u, char *chan)
nlog (LOG_WARNING, LOG_CORE, "NULL user passed to part_chan u=NULL, chan=%s: %s", chan, recbuf);
if (me.debug_mode) {
chanalert (s_Services, "NULL user passed to part_chan u=NULL, chan=%s: %s", chan, recbuf);
chandump (chan);
ChanDump (chan);
}
return;
}
@ -523,7 +528,7 @@ part_chan (User * u, char *chan)
nlog (LOG_WARNING, LOG_CORE, "hu, User %s isn't a member of this channel %s", u->nick, chan);
if (me.debug_mode) {
chanalert (s_Services, "hu, User %s isn't a member of this channel %s", u->nick, chan);
chandump (c->name);
ChanDump (c->name);
UserDump (u->nick);
}
} else {
@ -532,10 +537,9 @@ part_chan (User * u, char *chan)
free (cm);
AddStringToList (&av, c->name, &ac);
AddStringToList (&av, u->nick, &ac);
Module_Event (EVENT_PARTCHAN, av, ac);
ModuleEvent (EVENT_PARTCHAN, av, ac);
free (av);
ac = 0;
// FreeList(av, ac);
c->cur_users--;
}
if (findbot (u->nick)) {
@ -543,7 +547,7 @@ part_chan (User * u, char *chan)
del_bot_from_chan (u->nick, c->name);
AddStringToList (&av, c->name, &ac);
AddStringToList (&av, u->nick, &ac);
Module_Event (EVENT_PARTBOT, av, ac);
ModuleEvent (EVENT_PARTBOT, av, ac);
free (av);
ac = 0;
}
@ -552,7 +556,7 @@ part_chan (User * u, char *chan)
nlog (LOG_WARNING, LOG_CORE, "Hu, User %s claims not to be part of Chan %s", u->nick, chan);
if (me.debug_mode) {
chanalert (s_Services, "Hu, User %s claims not to be part of Chan %s", u->nick, chan);
chandump (c->name);
ChanDump (c->name);
UserDump (u->nick);
}
return;
@ -562,10 +566,9 @@ part_chan (User * u, char *chan)
nlog (LOG_DEBUG3, LOG_CORE, "Cur Users %s %d (list %d)", c->name, c->cur_users, list_count (c->chanmembers));
if (c->cur_users <= 0) {
AddStringToList (&av, c->name, &ac);
Module_Event (EVENT_DELCHAN, av, ac);
ModuleEvent (EVENT_DELCHAN, av, ac);
free (av);
ac = 0;
// FreeList(av, ac);
del_chan (c);
}
}
@ -594,7 +597,7 @@ change_user_nick (Chans * c, char *newnick, char *oldnick)
nlog (LOG_WARNING, LOG_CORE, "change_user_nick() %s isn't a member of %s", oldnick, c->name);
if (me.debug_mode) {
chanalert (s_Services, "change_user_nick() %s isn't a member of %s", oldnick, c->name);
chandump (c->name);
ChanDump (c->name);
UserDump (oldnick);
}
return;
@ -651,7 +654,7 @@ join_chan (User * u, char *chan)
c->modes = 0;
c->tstime = 0;
AddStringToList (&av, c->name, &ac);
Module_Event (EVENT_NEWCHAN, av, ac);
ModuleEvent (EVENT_NEWCHAN, av, ac);
free (av);
ac = 0;
}
@ -666,7 +669,7 @@ join_chan (User * u, char *chan)
nlog (LOG_WARNING, LOG_CORE, "Adding %s to Chan %s when he is already a member?", u->nick, chan);
if (me.debug_mode) {
chanalert (s_Services, "Adding %s to Chan %s when he is already a member?", u->nick, chan);
chandump (c->name);
ChanDump (c->name);
UserDump (u->nick);
}
return;
@ -689,7 +692,7 @@ join_chan (User * u, char *chan)
}
AddStringToList (&av, c->name, &ac);
AddStringToList (&av, u->nick, &ac);
Module_Event (EVENT_JOINCHAN, av, ac);
ModuleEvent (EVENT_JOINCHAN, av, ac);
free (av);
nlog (LOG_DEBUG3, LOG_CORE, "Cur Users %s %d (list %d)", c->name, c->cur_users, list_count (c->chanmembers));
if (findbot (u->nick)) {
@ -711,7 +714,7 @@ join_chan (User * u, char *chan)
void
chandump (char *chan)
ChanDump (char *chan)
{
hnode_t *cn;
lnode_t *cmn;

38
chans.h Normal file
View file

@ -0,0 +1,38 @@
/* NeoStats - IRC Statistical Services
** Copyright (c) 1999-2003 Adam Rutter, Justin Hammond, Mark Hetherington
** http://www.neostats.net/
**
** 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
#ifndef _CHANS_H_
#define _CHANS_H_
void ChanDump (char *chan);
void part_chan (User * u, char *chan);
void join_chan (User * u, char *chan);
void change_user_nick (Chans * c, char *newnick, char *oldnick);
int ChanMode (char *origin, char **av, int ac);
void ChangeTopic (char *, Chans *, time_t t, char *);
void ChangeChanUserMode (Chans * c, User * u, int add, long mode);
void kick_chan (User *, char *, User *);
void ChangeChanTS (Chans * c, time_t tstime);
int init_chan_hash (void);
#endif /* _CHANS_H_ */

View file

@ -138,6 +138,9 @@
/* enable Ircu support */
#undef IRCU
/* enable Ircu support */
#undef LIQUID
/* Version number of package */
#undef VERSION

1607
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -4,8 +4,8 @@ AC_CONFIG_HEADER(config.h)
PACKAGE=NeoStats
AC_DEFINE(MAJOR, 2)
AC_DEFINE(MINOR, 5)
AC_DEFINE(REV, 8)
VERSION=2.5.8
AC_DEFINE(REV, 9)
VERSION=2.5.9
AC_PREFIX_DEFAULT(~/NeoStats)
CFLAGS="$CFLAGS -O2 -g"
@ -33,7 +33,22 @@ LIBS="-g $LIBS"]
dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(sys/time.h unistd.h)
AC_CHECK_HEADERS(sys/time.h unistd.h limits.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_STRUCT_TM
dnl Checks for library functions.
AC_FUNC_FNMATCH
AC_TYPE_SIGNAL
AC_FUNC_STRFTIME
AC_CHECK_FUNCS(strlcpy strlcat strnlen)
AC_CHECK_FUNCS(socket strdup)
AC_CHECK_FUNCS(bcopy memmove strerror)
ADNS_C_GETFUNC(inet_aton,resolv,[
LIBS="-lresolv $LIBS";
@ -72,18 +87,17 @@ else
fi
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_STRUCT_TM
dnl Checks for library functions.
AC_FUNC_FNMATCH
AC_TYPE_SIGNAL
AC_FUNC_STRFTIME
AC_CHECK_FUNCS(strlcpy strlcat strnlen)
AC_CHECK_FUNCS(socket strdup)
PCRE_MAJOR=4
PCRE_MINOR=3
PCRE_DATE=21-May-2003
PCRE_VERSION=${PCRE_MAJOR}.${PCRE_MINOR}
dnl Default values for miscellaneous macros
AC_DEFINE(POSIX_MALLOC_THRESHOLD,10)
dnl check if we are running with Debug....
AC_MSG_CHECKING(Whether to Enable Debuging...)
@ -249,6 +263,28 @@ dnl AC_MSG_ERROR('Sorry IRCu support isnt complete yet')
;;
esac],
AC_MSG_RESULT(no))
dnl check to see if we should enable liquid IRCD Support
AC_MSG_CHECKING(Whether to Enable Liquid IRCD Support...)
AC_ARG_ENABLE(liquid, [ --enable-liquid - enable Liquid IRCD Support],
[ case "$enableval" in
yes)
AC_DEFINE(LIQUID, 1, 'Enable Liquid IRCd Support')
IRCD_FILES_SRC="liquidircd.c"
IRCD_FILES_OBJS="liquidircd.o"
AC_MSG_RESULT(yes)
;;
*)
AC_MSG_RESULT(no)
;;
esac],
AC_MSG_RESULT(no)
)
do_serviceroots=no
AC_MSG_CHECKING(A compatible IRCD is specified)
case "$IRCD_FILES_SRC" in
@ -283,6 +319,9 @@ case "$IRCD_FILES_SRC" in
"neoircd.c")
AC_MSG_RESULT(yes)
;;
"liquidircd.c")
AC_MSG_RESULT(yes)
;;
*)
AC_MSG_RESULT(no)
AC_MSG_ERROR('You must define a IRCD to use. See ./configure --help for more information')
@ -333,7 +372,7 @@ AC_MSG_RESULT(none)
configtool=no
AC_MSG_CHECKING(Enable Building of ConfigTool?)
AC_ARG_ENABLE(configtool,
[--enable-configtool - Endable building of the configtool program (Needs X windows)],
[--enable-configtool - Enable building of the configtool program (Needs X windows)],
[if test "$enableval" = yes; then configtool=yes; else configtool=no; fi])
if test "$configtool" = yes; then
@ -374,6 +413,21 @@ AC_MSG_RESULT(Thats Impressive!!!)
AC_MSG_CHECKING(The Modules that will be compiled)
AC_MSG_RESULT($MODULES)
AC_SUBST(DIRINST)
AC_SUBST(CFLAGS)
AC_SUBST(LDFLAGS)
AC_SUBST(LINK_SIZE)
AC_SUBST(MATCH_LIMIT)
AC_SUBST(NEWLINE)
AC_SUBST(PCRE_MAJOR)
AC_SUBST(PCRE_MINOR)
AC_SUBST(PCRE_DATE)
AC_SUBST(PCRE_VERSION)
AC_SUBST(PCRE_LIB_VERSION)
AC_SUBST(PCRE_POSIXLIB_VERSION)
AC_DEFINE(POSIX_MALLOC_THRESHOLD,10)
AC_SUBST(POSIX_MALLOC_THRESHOLD)
AC_SUBST(UTF8)
AC_SUBST(IRCD_FILES_SRC)
AC_SUBST(IRCD_FILES_OBJS)
@ -384,7 +438,8 @@ AC_SUBST(EXTAUTH_OBJS)
AC_SUBST(PACKAGE)
AC_SUBST(VERSION)
AC_CONFIG_HEADER(adns/config.h)
AC_OUTPUT(Makefile.inc Makefile tools/Makefile)
AC_CONFIG_HEADER(pcre/config.h)
AC_OUTPUT(Makefile.inc Makefile tools/Makefile pcre/Makefile pcre.h:pcre/pcre.in)
echo "(*----------------------------------------------------------*)"
echo "(| Important Instructions |)"
echo "(*----------------------------------------------------------*)"

460
dl.c
View file

@ -41,6 +41,21 @@
*/
Module *ModList[NUM_MODULES];
char segv_location[SEGV_LOCATION_BUFSIZE];
char segv_inmodule[SEGV_INMODULE_BUFSIZE];
/* @brief Module hash list */
static hash_t *mh;
/* @brief Module Socket List hash */
hash_t *sockh;
/* @brief Module Timer hash list */
static hash_t *th;
/* @brief Module Bot hash list */
static hash_t *bh;
/* @brief Module Chan Bot hash list */
static hash_t *bch;
/** @brief Initialise module list hashes
*
* For core use only, initialises module list hashes
@ -50,7 +65,7 @@ Module *ModList[NUM_MODULES];
* @return none
*/
int
__init_mod_list ()
InitModuleHash ()
{
SET_SEGV_LOCATION();
mh = hash_create (NUM_MODULES, 0, 0);
@ -71,6 +86,24 @@ __init_mod_list ()
return NS_SUCCESS;
}
#ifdef DEBUG
void verify_hashes(void)
{
if (hash_verify (sockh) == 0) {
nlog (LOG_CRITICAL, LOG_CORE, "Eeeek, Corruption of the socket hash");
}
if (hash_verify (mh) == 0) {
nlog (LOG_CRITICAL, LOG_CORE, "Eeeek, Corruption of the Module hash");
}
if (hash_verify (bh) == 0) {
nlog (LOG_CRITICAL, LOG_CORE, "Eeeek, Corruption of the Bot hash");
}
if (hash_verify (th) == 0) {
nlog (LOG_CRITICAL, LOG_CORE, "Eeeek, Corruption of the Timer hash");
}
}
#endif /* DEBUG */
/** @brief create new timer
*
* For core use only, creates a timer
@ -79,26 +112,26 @@ __init_mod_list ()
*
* @return pointer to new timer on success, NULL on error
*/
static Mod_Timer *
static ModTimer *
new_timer (char *timer_name)
{
Mod_Timer *t;
ModTimer *mod_tmr;
hnode_t *tn;
SET_SEGV_LOCATION();
nlog (LOG_DEBUG2, LOG_CORE, "New Timer: %s", timer_name);
t = malloc (sizeof (Mod_Timer));
mod_tmr = malloc (sizeof (ModTimer));
if (!timer_name)
strsetnull (t->timername);
strsetnull (mod_tmr->timername);
else
strlcpy (t->timername, timer_name, MAX_MOD_NAME);
tn = hnode_create (t);
strlcpy (mod_tmr->timername, timer_name, MAX_MOD_NAME);
tn = hnode_create (mod_tmr);
if (hash_isfull (th)) {
nlog (LOG_WARNING, LOG_CORE, "new_timer(): Couldn't add new Timer, Hash is Full!");
return NULL;
}
hash_insert (th, tn, timer_name);
return t;
return mod_tmr;
}
/** @brief find timer
@ -109,14 +142,14 @@ new_timer (char *timer_name)
*
* @return pointer to timer if found, NULL if not found
*/
Mod_Timer *
ModTimer *
findtimer (char *timer_name)
{
hnode_t *tn;
tn = hash_lookup (th, timer_name);
if (tn)
return (Mod_Timer *) hnode_get (tn);
return (ModTimer *) hnode_get (tn);
return NULL;
}
@ -134,19 +167,19 @@ findtimer (char *timer_name)
int
add_mod_timer (char *func_name, char *timer_name, char *mod_name, int interval)
{
Mod_Timer *Mod_timer_list;
ModTimer *mod_tmr;
SET_SEGV_LOCATION();
if (dlsym ((int *) get_dl_handle (mod_name), func_name) == NULL) {
nlog (LOG_WARNING, LOG_CORE, "Oh Oh, The Timer Function doesn't exist");
return NS_FAILURE;
}
Mod_timer_list = new_timer (timer_name);
if (Mod_timer_list) {
Mod_timer_list->interval = interval;
Mod_timer_list->lastrun = me.now;
strlcpy (Mod_timer_list->modname, mod_name, MAX_MOD_NAME);
Mod_timer_list->function = dlsym ((int *) get_dl_handle (mod_name), func_name);
mod_tmr = new_timer (timer_name);
if (mod_tmr) {
mod_tmr->interval = interval;
mod_tmr->lastrun = me.now;
strlcpy (mod_tmr->modname, mod_name, MAX_MOD_NAME);
mod_tmr->function = dlsym ((int *) get_dl_handle (mod_name), func_name);
nlog (LOG_DEBUG2, LOG_CORE, "Registered Module %s with timer for Function %s", mod_name, func_name);
return NS_SUCCESS;
}
@ -164,17 +197,17 @@ add_mod_timer (char *func_name, char *timer_name, char *mod_name, int interval)
int
del_mod_timer (char *timer_name)
{
Mod_Timer *list;
ModTimer *mod_tmr;
hnode_t *tn;
SET_SEGV_LOCATION();
tn = hash_lookup (th, timer_name);
if (tn) {
list = hnode_get (tn);
nlog (LOG_DEBUG2, LOG_CORE, "Unregistered Timer function %s from Module %s", timer_name, list->modname);
mod_tmr = hnode_get (tn);
nlog (LOG_DEBUG2, LOG_CORE, "Unregistered Timer function %s from Module %s", timer_name, mod_tmr->modname);
hash_delete (th, tn);
hnode_destroy (tn);
free (list);
free (mod_tmr);
return NS_SUCCESS;
}
return NS_FAILURE;
@ -189,9 +222,9 @@ del_mod_timer (char *timer_name)
* @return none
*/
void
list_module_timer (User * u)
list_timers (User * u, char **av, int ac)
{
Mod_Timer *mod_ptr = NULL;
ModTimer *mod_tmr = NULL;
hscan_t ts;
hnode_t *tn;
@ -199,15 +232,55 @@ list_module_timer (User * u)
prefmsg (u->nick, s_Services, "Module timer List:");
hash_scan_begin (&ts, th);
while ((tn = hash_scan_next (&ts)) != NULL) {
mod_ptr = hnode_get (tn);
prefmsg (u->nick, s_Services, "%s:--------------------------------", mod_ptr->modname);
prefmsg (u->nick, s_Services, "Module Timer Name: %s", mod_ptr->timername);
prefmsg (u->nick, s_Services, "Module Interval: %d", mod_ptr->interval);
prefmsg (u->nick, s_Services, "Time till next Run: %d", mod_ptr->interval - (me.now - mod_ptr->lastrun));
mod_tmr = hnode_get (tn);
prefmsg (u->nick, s_Services, "%s:--------------------------------", mod_tmr->modname);
prefmsg (u->nick, s_Services, "Module Timer Name: %s", mod_tmr->timername);
prefmsg (u->nick, s_Services, "Module Interval: %d", mod_tmr->interval);
prefmsg (u->nick, s_Services, "Time till next Run: %d", mod_tmr->interval - (me.now - mod_tmr->lastrun));
}
prefmsg (u->nick, s_Services, "End of Module timer List");
}
/** @brief run pending module timer functions
*
* NeoStats command to run pending timer functions
*
* @param none
*
* @return none
*/
void
run_mod_timers (void)
{
ModTimer *mod_tmr = NULL;
hscan_t ts;
hnode_t *tn;
/* First, lets see if any modules have a function that is due to run..... */
hash_scan_begin (&ts, th);
while ((tn = hash_scan_next (&ts)) != NULL) {
SET_SEGV_LOCATION();
mod_tmr = hnode_get (tn);
if (me.now - mod_tmr->lastrun > mod_tmr->interval) {
strlcpy (segv_location, mod_tmr->modname, SEGV_LOCATION_BUFSIZE);
SET_SEGV_INMODULE(mod_tmr->modname);
if (setjmp (sigvbuf) == 0) {
if (mod_tmr->function () < 0) {
nlog(LOG_DEBUG2, LOG_CORE, "Deleting Timer %s for Module %s as requested", mod_tmr->timername, mod_tmr->modname);
hash_scan_delete(th, tn);
hnode_destroy(tn);
free(mod_tmr);
} else {
mod_tmr->lastrun = (int) me.now;
}
} else {
nlog (LOG_CRITICAL, LOG_CORE, "setjmp() Failed, Can't call Module %s\n", mod_tmr->modname);
}
CLEAR_SEGV_INMODULE();
}
}
}
/** @brief create a new socket
*
* For core use only, creates a new socket for a module
@ -216,26 +289,26 @@ list_module_timer (User * u)
*
* @return pointer to created socket on success, NULL on error
*/
static Sock_List *
static ModSock *
new_sock (char *sock_name)
{
Sock_List *s;
ModSock *mod_sock;
hnode_t *sn;
SET_SEGV_LOCATION();
nlog (LOG_DEBUG2, LOG_CORE, "New Socket: %s", sock_name);
s = smalloc (sizeof (Sock_List));
nlog (LOG_DEBUG2, LOG_CORE, "New Socket: %mod_sock", sock_name);
mod_sock = smalloc (sizeof (ModSock));
if (!sock_name)
strsetnull (s->sockname);
strsetnull (mod_sock->sockname);
else
strlcpy (s->sockname, sock_name, MAX_MOD_NAME);
sn = hnode_create (s);
strlcpy (mod_sock->sockname, sock_name, MAX_MOD_NAME);
sn = hnode_create (mod_sock);
if (hash_isfull (sockh)) {
nlog (LOG_CRITICAL, LOG_CORE, "Eeek, SocketHash is full, can not add a new socket");
return NULL;
}
hash_insert (sockh, sn, s->sockname);
return s;
hash_insert (sockh, sn, mod_sock->sockname);
return mod_sock;
}
/** \fn @brief find socket
@ -246,7 +319,7 @@ new_sock (char *sock_name)
*
* @return pointer to socket if found, NULL if not found
*/
Sock_List *
ModSock *
findsock (char *sock_name)
{
hnode_t *sn;
@ -273,7 +346,7 @@ findsock (char *sock_name)
int
add_socket (char *readfunc, char *writefunc, char *errfunc, char *sock_name, int socknum, char *mod_name)
{
Sock_List *Sockets_mod_list;
ModSock *mod_sock;
SET_SEGV_LOCATION();
if (readfunc) {
@ -294,15 +367,15 @@ add_socket (char *readfunc, char *writefunc, char *errfunc, char *sock_name, int
return NS_FAILURE;
}
}
Sockets_mod_list = new_sock (sock_name);
Sockets_mod_list->sock_no = socknum;
strlcpy (Sockets_mod_list->modname, mod_name, MAX_MOD_NAME);
Sockets_mod_list->readfnc = dlsym ((int *) get_dl_handle (mod_name), readfunc);
Sockets_mod_list->writefnc = dlsym ((int *) get_dl_handle (mod_name), writefunc);
Sockets_mod_list->errfnc = dlsym ((int *) get_dl_handle (mod_name), errfunc);
Sockets_mod_list->socktype = SOCK_STANDARD;
mod_sock = new_sock (sock_name);
mod_sock->sock_no = socknum;
strlcpy (mod_sock->modname, mod_name, MAX_MOD_NAME);
mod_sock->readfnc = dlsym ((int *) get_dl_handle (mod_name), readfunc);
mod_sock->writefnc = dlsym ((int *) get_dl_handle (mod_name), writefunc);
mod_sock->errfnc = dlsym ((int *) get_dl_handle (mod_name), errfunc);
mod_sock->socktype = SOCK_STANDARD;
nlog (LOG_DEBUG2, LOG_CORE, "Registered Module %s with Standard Socket functions %s", mod_name, Sockets_mod_list->sockname);
nlog (LOG_DEBUG2, LOG_CORE, "Registered Module %s with Standard Socket functions %s", mod_name, mod_sock->sockname);
return NS_SUCCESS;
}
@ -320,7 +393,7 @@ add_socket (char *readfunc, char *writefunc, char *errfunc, char *sock_name, int
int
add_sockpoll (char *beforepoll, char *afterpoll, char *sock_name, char *mod_name, void *data)
{
Sock_List *Sockets_mod_list;
ModSock *mod_sock;
SET_SEGV_LOCATION();
if (beforepoll) {
@ -335,13 +408,13 @@ add_sockpoll (char *beforepoll, char *afterpoll, char *sock_name, char *mod_name
return NS_FAILURE;
}
}
Sockets_mod_list = new_sock (sock_name);
strlcpy (Sockets_mod_list->modname, mod_name, MAX_MOD_NAME);
Sockets_mod_list->socktype = SOCK_POLL;
Sockets_mod_list->beforepoll = dlsym ((int *) get_dl_handle (mod_name), beforepoll);
Sockets_mod_list->afterpoll = dlsym ((int *) get_dl_handle (mod_name), afterpoll);
Sockets_mod_list->data = data;
nlog (LOG_DEBUG2, LOG_CORE, "Registered Module %s with Poll Socket functions %s", mod_name, Sockets_mod_list->sockname);
mod_sock = new_sock (sock_name);
strlcpy (mod_sock->modname, mod_name, MAX_MOD_NAME);
mod_sock->socktype = SOCK_POLL;
mod_sock->beforepoll = dlsym ((int *) get_dl_handle (mod_name), beforepoll);
mod_sock->afterpoll = dlsym ((int *) get_dl_handle (mod_name), afterpoll);
mod_sock->data = data;
nlog (LOG_DEBUG2, LOG_CORE, "Registered Module %s with Poll Socket functions %s", mod_name, mod_sock->sockname);
return NS_SUCCESS;
}
@ -356,17 +429,17 @@ add_sockpoll (char *beforepoll, char *afterpoll, char *sock_name, char *mod_name
int
del_socket (char *sock_name)
{
Sock_List *list;
ModSock *mod_sock;
hnode_t *sn;
SET_SEGV_LOCATION();
sn = hash_lookup (sockh, sock_name);
if (sn) {
list = hnode_get (sn);
nlog (LOG_DEBUG2, LOG_CORE, "Unregistered Socket function %s from Module %s", sock_name, list->modname);
mod_sock = hnode_get (sn);
nlog (LOG_DEBUG2, LOG_CORE, "Unregistered Socket function %s from Module %s", sock_name, mod_sock->modname);
hash_scan_delete (sockh, sn);
hnode_destroy (sn);
free (list);
free (mod_sock);
return NS_SUCCESS;
}
return NS_FAILURE;
@ -381,9 +454,9 @@ del_socket (char *sock_name)
* @return none
*/
void
list_sockets (User * u)
list_sockets (User * u, char **av, int ac)
{
Sock_List *mod_ptr = NULL;
ModSock *mod_sock = NULL;
hscan_t ss;
hnode_t *sn;
@ -391,11 +464,11 @@ list_sockets (User * u)
prefmsg (u->nick, s_Services, "Sockets List: (%d)", hash_count (sockh));
hash_scan_begin (&ss, sockh);
while ((sn = hash_scan_next (&ss)) != NULL) {
mod_ptr = hnode_get (sn);
prefmsg (u->nick, s_Services, "%s:--------------------------------", mod_ptr->modname);
prefmsg (u->nick, s_Services, "Socket Name: %s", mod_ptr->sockname);
if (mod_ptr->socktype == SOCK_STANDARD) {
prefmsg (u->nick, s_Services, "Socket Number: %d", mod_ptr->sock_no);
mod_sock = hnode_get (sn);
prefmsg (u->nick, s_Services, "%s:--------------------------------", mod_sock->modname);
prefmsg (u->nick, s_Services, "Socket Name: %s", mod_sock->sockname);
if (mod_sock->socktype == SOCK_STANDARD) {
prefmsg (u->nick, s_Services, "Socket Number: %d", mod_sock->sock_no);
} else {
prefmsg (u->nick, s_Services, "Poll Interface");
}
@ -414,31 +487,31 @@ void
add_bot_to_chan (char *bot, char *chan)
{
hnode_t *cbn;
Chan_Bot *bc;
ModChanBot *mod_chan_bot;
lnode_t *bmn;
char *botname;
cbn = hash_lookup (bch, chan);
if (!cbn) {
bc = malloc (sizeof (Chan_Bot));
strlcpy (bc->chan, chan, CHANLEN);
bc->bots = list_create (B_TABLE_SIZE);
cbn = hnode_create (bc);
mod_chan_bot = malloc (sizeof (ModChanBot));
strlcpy (mod_chan_bot->chan, chan, CHANLEN);
mod_chan_bot->bots = list_create (B_TABLE_SIZE);
cbn = hnode_create (mod_chan_bot);
if (hash_isfull (bch)) {
nlog (LOG_CRITICAL, LOG_CORE, "eek, bot channel hash is full");
return;
}
hash_insert (bch, cbn, bc->chan);
hash_insert (bch, cbn, mod_chan_bot->chan);
} else {
bc = hnode_get (cbn);
mod_chan_bot = hnode_get (cbn);
}
if (list_isfull (bc->bots)) {
if (list_isfull (mod_chan_bot->bots)) {
nlog (LOG_CRITICAL, LOG_CORE, "Eeek, Bot Channel List is full for Chan %s", chan);
return;
}
botname = sstrdup (bot);
bmn = lnode_create (botname);
list_append (bc->bots, bmn);
list_append (mod_chan_bot->bots, bmn);
return;
}
@ -453,7 +526,7 @@ void
del_bot_from_chan (char *bot, char *chan)
{
hnode_t *cbn;
Chan_Bot *bc;
ModChanBot *mod_chan_bot;
lnode_t *bmn;
char *botname;
@ -462,21 +535,21 @@ del_bot_from_chan (char *bot, char *chan)
nlog (LOG_WARNING, LOG_CORE, "Hu? Can't Find Channel %s for botchanhash", chan);
return;
}
bc = hnode_get (cbn);
bmn = list_find (bc->bots, bot, comparef);
mod_chan_bot = hnode_get (cbn);
bmn = list_find (mod_chan_bot->bots, bot, comparef);
if (!bmn) {
nlog (LOG_WARNING, LOG_CORE, "Hu? Can't find bot %s in %s in botchanhash", bot, chan);
return;
}
list_delete (bc->bots, bmn);
list_delete (mod_chan_bot->bots, bmn);
botname = lnode_get(bmn);
free (botname);
lnode_destroy (bmn);
if (list_isempty (bc->bots)) {
if (list_isempty (mod_chan_bot->bots)) {
/* delete the hash and list because its all over */
hash_delete (bch, cbn);
list_destroy (bc->bots);
free (bc->chan);
list_destroy (mod_chan_bot->bots);
free (mod_chan_bot->chan);
hnode_destroy (cbn);
}
}
@ -484,35 +557,34 @@ del_bot_from_chan (char *bot, char *chan)
/** @brief send a message to a channel bot
*
* @param origin
* @param chan string containing channel name
* @param av
* @param av (note chan string in av[0])
* @param ac
*
* @return none
*/
void
bot_chan_message (char *origin, char *chan, char **av, int ac)
bot_chan_message (char *origin, char **av, int ac)
{
hnode_t *cbn;
Chan_Bot *bc;
ModChanBot *mod_chan_bot;
lnode_t *bmn;
Mod_User *u;
ModUser *mod_usr;
cbn = hash_lookup (bch, chan);
cbn = hash_lookup (bch, av[0]);
if (!cbn) {
/* this isn't bad, just means our bot parted the channel? */
nlog (LOG_DEBUG1, LOG_CORE, "eeeh, Can't find channel %s for BotChanMessage", chan);
nlog (LOG_DEBUG1, LOG_CORE, "eeeh, Can't find channel %s for BotChanMessage", av[0]);
return;
}
bc = hnode_get (cbn);
bmn = list_first (bc->bots);
mod_chan_bot = hnode_get (cbn);
bmn = list_first (mod_chan_bot->bots);
while (bmn) {
u = findbot (lnode_get (bmn));
if (u->chanfunc) {
nlog (LOG_DEBUG2, LOG_CORE, "Running Module for Chanmessage %s", chan);
u->chanfunc (origin, chan, av, ac);
mod_usr = findbot (lnode_get (bmn));
if (mod_usr->chanfunc) {
nlog (LOG_DEBUG2, LOG_CORE, "Running Module for Chanmessage %s", av[0]);
mod_usr->chanfunc (origin, av, ac);
}
bmn = list_next (bc->bots, bmn);
bmn = list_next (mod_chan_bot->bots, bmn);
}
}
@ -523,22 +595,22 @@ bot_chan_message (char *origin, char *chan, char **av, int ac)
* @return none
*/
void
botchandump (User * u)
list_bot_chans (User * u, char **av, int ac)
{
hscan_t hs;
hnode_t *hn;
lnode_t *ln;
Chan_Bot *bc;
ModChanBot *mod_chan_bot;
prefmsg (u->nick, s_Services, "BotChanDump:");
hash_scan_begin (&hs, bch);
while ((hn = hash_scan_next (&hs)) != NULL) {
bc = hnode_get (hn);
prefmsg (u->nick, s_Services, "%s:--------------------------------", bc->chan);
ln = list_first (bc->bots);
mod_chan_bot = hnode_get (hn);
prefmsg (u->nick, s_Services, "%s:--------------------------------", mod_chan_bot->chan);
ln = list_first (mod_chan_bot->bots);
while (ln) {
prefmsg (u->nick, s_Services, "Bot Name: %s", lnode_get (ln));
ln = list_next (bc->bots, ln);
ln = list_next (mod_chan_bot->bots, ln);
}
}
}
@ -549,26 +621,27 @@ botchandump (User * u)
*
* @return none
*/
static Mod_User *
static ModUser *
new_bot (char *bot_name)
{
Mod_User *u;
ModUser *mod_usr;
hnode_t *bn;
SET_SEGV_LOCATION();
nlog (LOG_DEBUG2, LOG_CORE, "New Bot: %s", bot_name);
u = malloc (sizeof (Mod_User));
mod_usr = malloc (sizeof (ModUser));
if (!bot_name)
strsetnull (u->nick);
strsetnull (mod_usr->nick);
else
strlcpy (u->nick, bot_name, MAXNICK);
bn = hnode_create (u);
strlcpy (mod_usr->nick, bot_name, MAXNICK);
bn = hnode_create (mod_usr);
if (hash_isfull (bh)) {
chanalert (s_Services, "Warning ModuleBotlist is full");
return NULL;
}
hash_insert (bh, bn, bot_name);
return u;
hash_insert (bh, bn, mod_usr->nick);
return mod_usr;
}
/** @brief
@ -580,21 +653,21 @@ new_bot (char *bot_name)
int
add_mod_user (char *nick, char *mod_name)
{
Mod_User *Mod_Usr_list;
Module *list_ptr;
ModUser *mod_usr;
Module *mod_ptr;
hnode_t *mn;
SET_SEGV_LOCATION();
Mod_Usr_list = new_bot (nick);
mod_usr = new_bot (nick);
/* add a brand new user */
strlcpy (Mod_Usr_list->nick, nick, MAXNICK);
strlcpy (Mod_Usr_list->modname, mod_name, MAX_MOD_NAME);
strlcpy (mod_usr->nick, nick, MAXNICK);
strlcpy (mod_usr->modname, mod_name, MAX_MOD_NAME);
mn = hash_lookup (mh, mod_name);
if (mn) {
list_ptr = hnode_get (mn);
Mod_Usr_list->function = dlsym (list_ptr->dl_handle, "__Bot_Message");
Mod_Usr_list->chanfunc = dlsym (list_ptr->dl_handle, "__Chan_Message");
mod_ptr = hnode_get (mn);
mod_usr->function = dlsym (mod_ptr->dl_handle, "__BotMessage");
mod_usr->chanfunc = dlsym (mod_ptr->dl_handle, "__ChanMessage");
return NS_SUCCESS;
}
nlog (LOG_WARNING, LOG_CORE, "add_mod_user(): Couldn't Add ModuleBot to List");
@ -607,7 +680,7 @@ add_mod_user (char *nick, char *mod_name)
*
* @return
*/
Mod_User *
ModUser *
findbot (char *bot_name)
{
hnode_t *bn;
@ -615,7 +688,7 @@ findbot (char *bot_name)
SET_SEGV_LOCATION();
bn = hash_lookup (bh, bot_name);
if (bn) {
return (Mod_User *) hnode_get (bn);
return (ModUser *) hnode_get (bn);
}
return NULL;
}
@ -629,16 +702,16 @@ findbot (char *bot_name)
int
del_mod_user (char *bot_name)
{
Mod_User *list;
ModUser *mod_usr;
hnode_t *bn;
SET_SEGV_LOCATION();
bn = hash_lookup (bh, bot_name);
if (bn) {
hash_delete (bh, bn);
list = hnode_get (bn);
mod_usr = hnode_get (bn);
hnode_destroy (bn);
free (list);
free (mod_usr);
return NS_SUCCESS;
}
return NS_FAILURE;
@ -654,7 +727,7 @@ int
bot_nick_change (char *oldnick, char *newnick)
{
User *u;
Mod_User *mod_tmp, *mod_ptr;
ModUser *mod_usr_new, *mod_usr;
SET_SEGV_LOCATION();
/* First, try to find out if the newnick is unique! */
@ -665,14 +738,14 @@ bot_nick_change (char *oldnick, char *newnick)
}
u = finduser (newnick);
if (!u) {
if ((mod_ptr = findbot (oldnick)) != NULL) {
if ((mod_usr = findbot (oldnick)) != NULL) {
nlog (LOG_DEBUG3, LOG_CORE, "Bot %s Changed its nick to %s", oldnick, newnick);
mod_tmp = new_bot (newnick);
mod_usr_new = new_bot (newnick);
/* add a brand new user */
strlcpy (mod_tmp->nick, newnick, MAXNICK);
strlcpy (mod_tmp->modname, mod_ptr->modname, MAX_MOD_NAME);
mod_tmp->function = mod_ptr->function;
strlcpy (mod_usr_new->nick, newnick, MAXNICK);
strlcpy (mod_usr_new->modname, mod_usr->modname, MAX_MOD_NAME);
mod_usr_new->function = mod_usr->function;
/* Now Delete the Old bot nick */
del_mod_user (oldnick);
@ -691,9 +764,9 @@ bot_nick_change (char *oldnick, char *newnick)
* @return
*/
void
list_module_bots (User * u)
list_bots (User * u, char **av, int ac)
{
Mod_User *mod_ptr;
ModUser *mod_usr;
hnode_t *bn;
hscan_t bs;
@ -701,13 +774,94 @@ list_module_bots (User * u)
prefmsg (u->nick, s_Services, "Module Bot List:");
hash_scan_begin (&bs, bh);
while ((bn = hash_scan_next (&bs)) != NULL) {
mod_ptr = hnode_get (bn);
prefmsg (u->nick, s_Services, "Module: %s", mod_ptr->modname);
prefmsg (u->nick, s_Services, "Module Bots: %s", mod_ptr->nick);
mod_usr = hnode_get (bn);
prefmsg (u->nick, s_Services, "Module: %s", mod_usr->modname);
prefmsg (u->nick, s_Services, "Module Bots: %s", mod_usr->nick);
}
prefmsg (u->nick, s_Services, "End of Module Bot List");
}
/** @brief ModuleEvent
*
*
*
* @return none
*/
void
ModuleEvent (char *event, char **av, int ac)
{
Module *module_ptr;
EventFnList *ev_list;
hscan_t ms;
hnode_t *mn;
SET_SEGV_LOCATION();
hash_scan_begin (&ms, mh);
while ((mn = hash_scan_next (&ms)) != NULL) {
module_ptr = hnode_get (mn);
ev_list = module_ptr->event_list;
if (ev_list) {
while (ev_list->cmd_name != NULL) {
/* This goes through each Command */
if (!strcasecmp (ev_list->cmd_name, event)) {
nlog (LOG_DEBUG1, LOG_CORE, "Running Module %s for Comamnd %s -> %s", module_ptr->info->module_name, event, ev_list->cmd_name);
SET_SEGV_LOCATION();
SET_SEGV_INMODULE(module_ptr->info->module_name);
if (setjmp (sigvbuf) == 0) {
if (ev_list->function) ev_list->function (av, ac);
} else {
nlog (LOG_CRITICAL, LOG_CORE, "setjmp() Failed, Can't call Module %s\n", module_ptr->info->module_name);
}
CLEAR_SEGV_INMODULE();
SET_SEGV_LOCATION();
#ifndef VALGRIND
break;
#endif
}
ev_list++;
}
}
}
}
/** @brief
*
*
*
* @return none
*/
void
ModuleFunction (int cmdptr, char *cmd, char* origin, char **av, int ac)
{
Module *module_ptr;
Functions *fn_list;
hscan_t ms;
hnode_t *mn;
hash_scan_begin (&ms, mh);
while ((mn = hash_scan_next (&ms)) != NULL) {
module_ptr = hnode_get (mn);
fn_list = module_ptr->function_list;
while (fn_list->cmd_name != NULL) {
/* This goes through each Command */
if (!strcmp (fn_list->cmd_name, cmd)) {
if (fn_list->srvmsg == cmdptr) {
nlog (LOG_DEBUG1, LOG_CORE, "Running Module %s for Function %s", module_ptr->info->module_name, fn_list->cmd_name);
SET_SEGV_LOCATION();
SET_SEGV_INMODULE(module_ptr->info->module_name);
if (setjmp (sigvbuf) == 0) {
fn_list->function (origin, av, ac);
}
CLEAR_SEGV_INMODULE();
SET_SEGV_LOCATION();
break;
}
}
fn_list++;
}
}
}
/** @brief
*
* @param
@ -730,11 +884,11 @@ load_module (char *modfilename, User * u)
int ac = 0;
int i = 0;
#ifdef OLD_MODULE_EXPORT_SUPPORT
Module_Info *(*mod_get_info) () = NULL;
ModuleInfo *(*mod_get_info) () = NULL;
Functions *(*mod_get_funcs) () = NULL;
EventFnList *(*mod_get_events) () = NULL;
#endif /* OLD_MODULE_EXPORT_SUPPORT */
Module_Info *mod_info_ptr = NULL;
ModuleInfo *mod_info_ptr = NULL;
Functions *mod_funcs_ptr = NULL;
EventFnList *event_fn_ptr = NULL;
Module *mod_ptr = NULL;
@ -886,7 +1040,7 @@ load_module (char *modfilename, User * u)
mod_ptr->info = mod_info_ptr;
mod_ptr->function_list = mod_funcs_ptr;
mod_ptr->dl_handle = dl_handle;
mod_ptr->other_funcs = event_fn_ptr;
mod_ptr->event_list = event_fn_ptr;
/* assign a module number to this module */
i = 0;
@ -943,13 +1097,13 @@ load_module (char *modfilename, User * u)
int
get_dl_handle (char *mod_name)
{
Module *list_ptr;
Module *mod_ptr;
hnode_t *mn;
mn = hash_lookup (mh, mod_name);
if (mn) {
list_ptr = hnode_get (mn);
return (int) list_ptr->dl_handle;
mod_ptr = hnode_get (mn);
return (int) mod_ptr->dl_handle;
}
return 0;
}
@ -984,7 +1138,7 @@ get_mod_num (char *mod_name)
* @return
*/
void
list_module (User * u)
list_modules (User * u, char **av, int ac)
{
Module *mod_ptr = NULL;
hnode_t *mn;
@ -1010,10 +1164,10 @@ list_module (User * u)
int
unload_module (char *module_name, User * u)
{
Module *list;
Mod_User *mod_ptr = NULL;
Mod_Timer *mod_tmr = NULL;
Sock_List *mod_sock = NULL;
Module *mod_ptr;
ModUser *mod_usr;
ModTimer *mod_tmr;
ModSock *mod_sock;
hnode_t *modnode;
hscan_t hscan;
int i;
@ -1056,10 +1210,10 @@ unload_module (char *module_name, User * u)
/* now, see if this Module has any bots with it */
hash_scan_begin (&hscan, bh);
while ((modnode = hash_scan_next (&hscan)) != NULL) {
mod_ptr = hnode_get (modnode);
if (!strcasecmp (mod_ptr->modname, module_name)) {
nlog (LOG_DEBUG1, LOG_CORE, "Module %s had bot %s Registered. Deleting..", module_name, mod_ptr->nick);
del_bot (mod_ptr->nick, "Module Unloaded");
mod_usr = hnode_get (modnode);
if (!strcasecmp (mod_usr->modname, module_name)) {
nlog (LOG_DEBUG1, LOG_CORE, "Module %s had bot %s Registered. Deleting..", module_name, mod_usr->nick);
del_bot (mod_usr->nick, "Module Unloaded");
}
}
@ -1071,11 +1225,11 @@ unload_module (char *module_name, User * u)
i = get_mod_num (module_name);
list = hnode_get (modnode);
mod_ptr = hnode_get (modnode);
SET_SEGV_INMODULE(module_name);
/* call __ModFini (replacement for library __fini() call */
dofini = dlsym ((int *) list->dl_handle, "__ModFini");
dofini = dlsym ((int *) mod_ptr->dl_handle, "__ModFini");
if (dofini) {
(*dofini) ();
}
@ -1087,7 +1241,7 @@ unload_module (char *module_name, User * u)
/* Close module */
SET_SEGV_INMODULE(module_name);
#ifndef VALGRIND
dlclose (list->dl_handle);
dlclose (mod_ptr->dl_handle);
#endif
CLEAR_SEGV_INMODULE();
@ -1096,7 +1250,7 @@ unload_module (char *module_name, User * u)
/* free the module number */
ModList[i] = NULL;
}
free (list);
free (mod_ptr);
return NS_SUCCESS;
}
return NS_FAILURE;

91
dl.h
View file

@ -62,19 +62,18 @@
*
*/
typedef int (*message_function) (char *origin, char **av, int ac);
typedef int (*chan_message_function) (char *origin, char *chan, char **av, int ac);
/** @brief Socket function types
*
*/
typedef int (*socket_function) (int sock_no, char *sockname);
typedef int (*socket_function) (int sock_no, char *sockname);
typedef int (*before_poll_function) (void *data, struct pollfd *);
typedef void (*after_poll_function) (void *data, struct pollfd *, unsigned int);
/** @brief Module socket list structure
*
*/
typedef struct Sock_List {
typedef struct ModSock {
/** Hash code */
long hash;
/** Socket number */
@ -103,17 +102,12 @@ typedef struct Sock_List {
long rmsgs;
/** rbytes */
long rbytes;
}Sock_List;
/* @brief Module Socket List hash
*
*/
hash_t *sockh;
}ModSock;
/** @brief Module Timer structure
*
*/
typedef struct Mod_Timer {
typedef struct ModTimer {
/** Hash code */
long hash;
/** Module name */
@ -126,14 +120,12 @@ typedef struct Mod_Timer {
time_t lastrun;
/** Timer function */
int (*function) ();
}Mod_Timer;
hash_t *th;
}ModTimer;
/** @brief Module User structure
*
*/
typedef struct {
typedef struct ModUser {
/** Hash code */
long hash;
/** Nick */
@ -143,27 +135,23 @@ typedef struct {
/** function */
message_function function;
/** function */
chan_message_function chanfunc;
}Mod_User;
hash_t *bh;
message_function chanfunc;
}ModUser;
/** @brief Channel bot structure
*
*/
typedef struct {
typedef struct ModChanBot {
/** channel name */
char chan[CHANLEN];
/** bot list */
list_t *bots;
}Chan_Bot;
hash_t *bch;
}ModChanBot;
/** @brief Module functions structure
*
*/
typedef struct {
typedef struct Functions {
char *cmd_name;
message_function function;
int srvmsg;
@ -172,15 +160,17 @@ typedef struct {
/** @brief Module Event functions structure
*
*/
typedef struct {
typedef int (*event_function) (char **av, int ac);
typedef struct EventFnList {
char *cmd_name;
int (*function) (char **av, int ac);
event_function function;
}EventFnList;
/** @brief Module Info structure (old style)
*
*/
typedef struct {
typedef struct Module_Info {
char *module_name;
char *module_description;
char *module_version;
@ -189,7 +179,7 @@ typedef struct {
/** @brief Module Info structure (new style)
*
*/
typedef struct {
typedef struct ModuleInfo {
char *module_name;
char *module_description;
char *module_version;
@ -200,50 +190,63 @@ typedef struct {
/** @brief Module structure
*
*/
typedef struct {
Module_Info *info;
typedef struct Module {
ModuleInfo *info;
Functions *function_list;
EventFnList *other_funcs;
EventFnList *event_list;
void *dl_handle;
}Module ;
}Module;
hash_t *mh;
/* @brief Module Socket List hash
*
*/
extern hash_t *sockh;
/*
* Prototypes
*/
int __init_mod_list (void);
int InitModuleHash (void);
void ModuleEvent (char * event, char **av, int ac);
/* Temp define for secureserv */
#define Module_Event ModuleEvent
void ModuleFunction (int cmdptr, char *cmd, char* origin, char **av, int ac);
int load_module (char *path, User * u);
int unload_module (char *module_name, User * u);
int add_ld_path (char *path);
void list_module (User * u);
void list_module_bots (User * u);
void list_modules (User * u, char **av, int ac);
void list_bots (User * u, char **av, int ac);
int add_mod_user (char *nick, char *mod_name);
int del_mod_user (char *nick);
int add_mod_timer (char *func_name, char *timer_name, char *mod_name, int interval);
int del_mod_timer (char *timer_name);
Mod_Timer *findtimer(char *timer_name);
void list_module_timer (User * u);
ModTimer *findtimer(char *timer_name);
void list_timers (User * u, char **av, int ac);
void run_mod_timers (void);
int add_socket (char *readfunc, char *writefunc, char *errfunc, char *sock_name, int socknum, char *mod_name);
int add_sockpoll (char *beforepoll, char *afterpoll, char *sock_name, char *mod_name, void *data);
int del_socket (char *sockname);
void list_sockets (User * u);
Sock_List *findsock (char *sock_name);
Mod_User *findbot (char * bot_name);
void list_sockets (User * u, char **av, int ac);
ModSock *findsock (char *sock_name);
ModUser *findbot (char * bot_name);
int get_dl_handle (char *mod_name);
void add_bot_to_chan (char *bot, char *chan);
void del_bot_from_chan (char *bot, char *chan);
void bot_chan_message (char *origin, char *chan, char **av, int ac);
void botchandump (User * u);
void bot_chan_message (char *origin, char **av, int ac);
void list_bot_chans (User * u, char **av, int ac);
int get_mod_num (char *mod_name);
void unload_modules(void);
int bot_nick_change (char * oldnick, char *newnick);
void verify_hashes(void);
/*
* Module Interface
*/
int __ModInit(int modnum, int apiver);
void __ModFini(void);
int __Bot_Message(char *origin, char **av, int ac);
int __Chan_Message(char *origin, char *chan, char **argv, int argc);
int __BotMessage(char *origin, char **av, int ac);
/* temp define while rename propogates */
#define __Bot_Message __BotMessage
int __ChanMessage(char *origin, char **argv, int argc);
/* temporary define to support for module API backwards compatibility
* old system used function addresses to call into a module to get data addresses

View file

@ -1,6 +1,9 @@
ConnectServ Module for NeoStats 2.x ChangeLog
Shmad & ^Enigma^
==============================================================================
* Version 1.10 * Mark (M) * November 13, 2003
- Moved mode defines to ircd header files (M)
* Version 1.9 * Mark (M) * November 1, 2003
- Message system cleanup (M)
- Nick change messages now include user@host for spotting nick flooders (M)

View file

@ -34,7 +34,7 @@
/* Uncomment this line to disable colours in ConnectServ
channel messages
*/
/*#define DISABLE_COLOUR_SUPPORT*/
/* #define DISABLE_COLOUR_SUPPORT */
#ifdef DISABLE_COLOUR_SUPPORT
char msg_nickchange[]="\2NICK\2 %s (%s@%s) Changed their nick to %s";
@ -104,19 +104,18 @@ char msg_invisible[]="\2%s\2 Is Using \2Invisible Mode\2 (+%c)";
char msg_invisibleoff[]="\2%s\2 Is no longer using \2Invisible Mode\2 (-%c)";
#endif
char s_ConnectServ[MAXNICK];
char *s_ConnectServ;
int cs_new_user(char **av, int ac);
int cs_user_modes(char **av, int ac);
int cs_user_smodes(char **av, int ac);
int cs_del_user(char **av, int ac);
int cs_user_kill(char **av, int ac);
int cs_user_nick(char **av, int ac);
void do_set(User * u, char **av, int ac);
void SaveSettings();
void Loadconfig();
static int cs_new_user(char **av, int ac);
static int cs_user_modes(char **av, int ac);
#ifdef ULTIMATE3
static int cs_user_smodes(char **av, int ac);
#endif
static int cs_del_user(char **av, int ac);
static int cs_user_kill(char **av, int ac);
static int cs_user_nick(char **av, int ac);
static void do_set(User * u, char **av, int ac);
static void LoadConfig(void);
static void cs_version(User * u);
static void cs_set_list(User * u, char **av, int ac);
@ -124,17 +123,31 @@ static void cs_set_signwatch(User * u, char **av, int ac);
static void cs_set_killwatch(User * u, char **av, int ac);
static void cs_set_modewatch(User * u, char **av, int ac);
static void cs_set_nickwatch(User * u, char **av, int ac);
#if 0
/* work in progress */
static void cs_set_nick(User * u, char **av, int ac);
static void cs_set_user(User * u, char **av, int ac);
static void cs_set_host(User * u, char **av, int ac);
static void cs_set_rname(User * u, char **av, int ac);
#endif
struct cs_cfg {
int sign_watch;
int kill_watch;
int mode_watch;
int nick_watch;
int modnum;
char user[MAXUSER];
char host[MAXHOST];
char rname[MAXREALNAME];
} cs_cfg;
static int sign_watch;
static int kill_watch;
static int mode_watch;
static int nick_watch;
static int cs_online = 0;
ModuleInfo __module_info = {
"ConnectServ",
"Network Connection & Mode Monitoring Service",
"1.9",
"1.10",
__DATE__,
__TIME__
};
@ -158,7 +171,7 @@ Functions __module_functions[] = {
{NULL, NULL, 0}
};
int __Bot_Message(char *origin, char **av, int ac)
int __BotMessage(char *origin, char **av, int ac)
{
User *u;
u = finduser(origin);
@ -168,7 +181,7 @@ int __Bot_Message(char *origin, char **av, int ac)
if (!cs_online)
return 1;
if ((UserLevel(u) < 185)) {
if ((UserLevel(u) < NS_ULEVEL_ADMIN)) {
prefmsg(u->nick, s_ConnectServ, "Permission Denied!");
return 1;
}
@ -217,6 +230,17 @@ void do_set(User * u, char **av, int ac)
"Invalid Syntax. /msg %s help set for more info",
s_ConnectServ);
return;
#if 0
/* work in progress */
} else if (!strcasecmp(av[2], "NICK")) {
cs_set_nick(u, av, ac);
} else if (!strcasecmp(av[2], "USER")) {
cs_set_user(u, av, ac);
} else if (!strcasecmp(av[2], "HOST")) {
cs_set_host(u, av, ac);
} else if (!strcasecmp(av[2], "REALNAME")) {
cs_set_rname(u, av, ac);
#endif
} else if (!strcasecmp(av[2], "NICKWATCH")) {
cs_set_nickwatch(u, av, ac);
} else if (!strcasecmp(av[2], "SIGNWATCH")) {
@ -237,42 +261,15 @@ void do_set(User * u, char **av, int ac)
int Online(char **av, int ac)
{
char *user = NULL;
char *host = NULL;
char *rname = NULL;
if (GetConf((void *) &s_ConnectServ, CFGSTR, "Nick") < 0) {
s_ConnectServ = "ConnectServ";
}
if (GetConf((void *) &user, CFGSTR, "User") < 0) {
user = malloc(MAXUSER);
strlcpy(user, "CS", MAXUSER);
}
if (GetConf((void *) &host, CFGSTR, "Host") < 0) {
host = malloc(MAXHOST);
strlcpy(host, me.name, MAXHOST);
}
if (GetConf((void *) &rname, CFGSTR, "RealName") < 0) {
rname = malloc(MAXREALNAME);
strlcpy(rname, "Connection Monitoring Service", MAXREALNAME);
}
if (init_bot
(s_ConnectServ, user, host, rname, "+oS",
(s_ConnectServ, cs_cfg.user, cs_cfg.host, cs_cfg.rname, services_bot_modes,
__module_info.module_name) == -1) {
/* Nick was in use */
strlcat(s_ConnectServ, "_", MAXREALNAME);
init_bot(s_ConnectServ, user, host, rname, "+oS",
init_bot(s_ConnectServ, cs_cfg.user, cs_cfg.host, cs_cfg.rname, services_bot_modes,
__module_info.module_name);
}
cs_online = 1;
if(user)
free(user);
if(host)
free(host);
if(rname)
free(rname);
return 1;
};
@ -298,7 +295,7 @@ EventFnList __module_events[] = {
int __ModInit(int modnum, int apiver)
{
Loadconfig();
LoadConfig();
return 1;
}
@ -346,7 +343,7 @@ int cs_new_user(char **av, int ac)
}
/* Print Connection Notice */
if (u && sign_watch) {
if (u && cs_cfg.sign_watch) {
chanalert(s_ConnectServ, msg_signon,
u->nick, u->username, u->hostname,
u->server->name);
@ -387,7 +384,7 @@ int cs_del_user(char **av, int ac)
QuitMsg = joinbuf(Quit, QuitCount, 2);
/* Local Kill Watch For Signoff */
if (kill_watch) {
if (cs_cfg.kill_watch) {
if (strstr(cmd, "Local kill by") && strstr(cmd, "[")
&& strstr(cmd, "]")) {
@ -407,7 +404,7 @@ int cs_del_user(char **av, int ac)
}
/* Print Disconnection Notice */
if (sign_watch) {
if (cs_cfg.sign_watch) {
chanalert(s_ConnectServ,
msg_signoff,
u->nick, u->username, u->hostname,
@ -434,7 +431,7 @@ int cs_user_modes(char **av, int ac)
if (!cs_online)
return 1;
if (mode_watch != 1)
if (cs_cfg.mode_watch != 1)
return -1;
u = finduser(av[0]);
@ -633,7 +630,7 @@ int cs_user_smodes(char **av, int ac)
SET_SEGV_LOCATION();
if (mode_watch != 1)
if (cs_cfg.mode_watch != 1)
return -1;
u = finduser(av[0]);
@ -787,13 +784,13 @@ int cs_user_kill(char **av, int ac)
if (finduser(Kill[2])) {
/* it was a User who was killed */
if (kill_watch)
if (cs_cfg.kill_watch)
chanalert(s_ConnectServ,
msg_globalkill,
u->nick, u->username, u->hostname,
Kill[0], GlobalMsg);
} else if (findserver(Kill[2])) {
if (kill_watch)
if (cs_cfg.kill_watch)
chanalert(s_ConnectServ,
msg_serverkill,
u->nick, Kill[0], GlobalMsg);
@ -814,7 +811,7 @@ int cs_user_nick(char **av, int ac)
if (!cs_online)
return 1;
if (nick_watch) {
if (cs_cfg.nick_watch) {
u = finduser(av[1]);
if (!u)
return -1;
@ -842,7 +839,7 @@ static void cs_set_nickwatch(User * u, char **av, int ac)
return;
}
if ((!strcasecmp(av[3], "YES")) || (!strcasecmp(av[3], "ON"))) {
nick_watch = 1;
cs_cfg.nick_watch = 1;
chanalert(s_ConnectServ, "\2NICK WATCH\2 Activated by \2%s\2",
u->nick);
nlog(LOG_NORMAL, LOG_MOD, "%s!%s@%s Activated NICK WATCH",
@ -852,7 +849,7 @@ static void cs_set_nickwatch(User * u, char **av, int ac)
"\2NICK WATCH\2 Activated");
} else if ((!strcasecmp(av[3], "NO"))
|| (!strcasecmp(av[3], "OFF"))) {
nick_watch = 0;
cs_cfg.nick_watch = 0;
chanalert(s_ConnectServ,
"\2NICK WATCH\2 Deactivated by \2%s\2", u->nick);
nlog(LOG_NORMAL, LOG_MOD,
@ -883,7 +880,7 @@ static void cs_set_signwatch(User * u, char **av, int ac)
return;
}
if ((!strcasecmp(av[3], "YES")) || (!strcasecmp(av[3], "ON"))) {
sign_watch = 1;
cs_cfg.sign_watch = 1;
chanalert(s_ConnectServ,
"\2SIGNON/SIGNOFF WATCH\2 Activated by \2%s\2",
u->nick);
@ -895,7 +892,7 @@ static void cs_set_signwatch(User * u, char **av, int ac)
"\2SIGNON/SIGNOFF WATCH\2 Activated");
} else if ((!strcasecmp(av[3], "NO"))
|| (!strcasecmp(av[3], "OFF"))) {
sign_watch = 0;
cs_cfg.sign_watch = 0;
chanalert(s_ConnectServ,
"\2SIGNON/SIGNOFF WATCH\2 Deactivated by \2%s\2",
u->nick);
@ -926,7 +923,7 @@ static void cs_set_killwatch(User * u, char **av, int ac)
return;
}
if ((!strcasecmp(av[3], "YES")) || (!strcasecmp(av[3], "ON"))) {
kill_watch = 1;
cs_cfg.kill_watch = 1;
chanalert(s_ConnectServ, "\2KILL WATCH\2 Activated by \2%s\2",
u->nick);
nlog(LOG_NORMAL, LOG_MOD, "%s!%s@%s Activated KILL WATCH",
@ -936,7 +933,7 @@ static void cs_set_killwatch(User * u, char **av, int ac)
"\2KILL WATCH\2 Activated");
} else if ((!strcasecmp(av[3], "NO"))
|| (!strcasecmp(av[3], "OFF"))) {
kill_watch = 0;
cs_cfg.kill_watch = 0;
chanalert(s_ConnectServ,
"\2KILL WATCH\2 Deactivated by \2%s\2", u->nick);
nlog(LOG_NORMAL, LOG_MOD,
@ -966,7 +963,7 @@ static void cs_set_modewatch(User * u, char **av, int ac)
return;
}
if ((!strcasecmp(av[3], "YES")) || (!strcasecmp(av[3], "ON"))) {
mode_watch = 1;
cs_cfg.mode_watch = 1;
chanalert(s_ConnectServ, "\2MODE WATCH\2 Activated by \2%s\2",
u->nick);
nlog(LOG_NORMAL, LOG_MOD, "%s!%s@%s Activated MODE WATCH",
@ -976,7 +973,7 @@ static void cs_set_modewatch(User * u, char **av, int ac)
"\2MODE WATCH\2 Activated");
} else if ((!strcasecmp(av[3], "NO"))
|| (!strcasecmp(av[3], "OFF"))) {
mode_watch = 0;
cs_cfg.mode_watch = 0;
chanalert(s_ConnectServ,
"\2MODE WATCH\2 Deactivated by \2%s\2", u->nick);
nlog(LOG_NORMAL, LOG_MOD,
@ -993,6 +990,78 @@ static void cs_set_modewatch(User * u, char **av, int ac)
}
}
#if 0
/* work in progress */
/*
* Set ConnectServ Nick
*/
static void cs_set_nick(User * u, char **av, int ac)
{
char old_nick[MAXNICK];
SET_SEGV_LOCATION();
if (ac < 4) {
prefmsg(u->nick, s_ConnectServ,
"Invalid Syntax. /msg %s help set for more info",
s_ConnectServ);
return;
}
strlcpy(old_nick, s_ConnectServ, MAXNICK);
strlcpy(s_ConnectServ, av[3], MAXNICK);
SetConf((void *) s_ConnectServ, CFGSTR, "Nick");
if( bot_nick_change(old_nick, s_ConnectServ) == NS_FAILURE)
prefmsg(u->nick, s_ConnectServ, "bot_nick_change failed %s %s", old_nick, s_ConnectServ);
}
/*
* Set ConnectServ User
*/
static void cs_set_user(User * u, char **av, int ac)
{
SET_SEGV_LOCATION();
if (ac < 4) {
prefmsg(u->nick, s_ConnectServ,
"Invalid Syntax. /msg %s help set for more info",
s_ConnectServ);
return;
}
strlcpy(cs_cfg.user, av[3], MAXUSER);
SetConf((void *) cs_cfg.user, CFGSTR, "User");
}
/*
* Set ConnectServ Host
*/
static void cs_set_host(User * u, char **av, int ac)
{
SET_SEGV_LOCATION();
if (ac < 4) {
prefmsg(u->nick, s_ConnectServ,
"Invalid Syntax. /msg %s help set for more info",
s_ConnectServ);
return;
}
strlcpy(cs_cfg.host, av[3], MAXHOST);
SetConf((void *) cs_cfg.host, CFGSTR, "Host");
}
/*
* Set ConnectServ Real Name
*/
static void cs_set_rname(User * u, char **av, int ac)
{
SET_SEGV_LOCATION();
if (ac < 4) {
prefmsg(u->nick, s_ConnectServ,
"Invalid Syntax. /msg %s help set for more info",
s_ConnectServ);
return;
}
strlcpy(cs_cfg.rname, av[3], MAXREALNAME);
SetConf((void *) cs_cfg.rname, CFGSTR, "RealName");
}
#endif
/*
* SET LIST - List current settings
*/
@ -1002,30 +1071,60 @@ static void cs_set_list(User * u, char **av, int ac)
prefmsg(u->nick, s_ConnectServ, "Current %s Settings:",
s_ConnectServ);
prefmsg(u->nick, s_ConnectServ, "SIGNWATCH: %s",
sign_watch ? "Enabled" : "Disabled");
cs_cfg.sign_watch ? "Enabled" : "Disabled");
prefmsg(u->nick, s_ConnectServ, "KILLWATCH: %s",
kill_watch ? "Enabled" : "Disabled");
cs_cfg.kill_watch ? "Enabled" : "Disabled");
prefmsg(u->nick, s_ConnectServ, "MODEWATCH: %s",
mode_watch ? "Enabled" : "Disabled");
cs_cfg.mode_watch ? "Enabled" : "Disabled");
prefmsg(u->nick, s_ConnectServ, "NICKWATCH: %s",
nick_watch ? "Enabled" : "Disabled");
cs_cfg.nick_watch ? "Enabled" : "Disabled");
}
/*
* Load ConnectServ Configuration file and set defaults if does not exist
*/
void Loadconfig()
static void LoadConfig(void)
{
char *temp = NULL;
SET_SEGV_LOCATION();
/* some defaults */
sign_watch = 1;
kill_watch = 1;
mode_watch = 1;
nick_watch = 1;
GetConf((void *) &sign_watch, CFGBOOL, "SignWatch");
GetConf((void *) &kill_watch, CFGBOOL, "KillWatch");
GetConf((void *) &mode_watch, CFGBOOL, "ModeWatch");
GetConf((void *) &nick_watch, CFGBOOL, "NickWatch");
if(GetConf((void *) &cs_cfg.sign_watch, CFGBOOL, "SignWatch")<= 0) {
cs_cfg.sign_watch = 1;
}
if(GetConf((void *) &cs_cfg.kill_watch, CFGBOOL, "KillWatch")<= 0) {
cs_cfg.kill_watch = 1;
}
if(GetConf((void *) &cs_cfg.mode_watch, CFGBOOL, "ModeWatch")<= 0) {
cs_cfg.mode_watch = 1;
}
if(GetConf((void *) &cs_cfg.nick_watch, CFGBOOL, "NickWatch")<= 0) {
cs_cfg.nick_watch = 1;
}
if(GetConf((void *) &temp, CFGSTR, "Nick") < 0) {
strlcpy(s_ConnectServ , "ConnectServ", MAXNICK);
}
else {
strlcpy(s_ConnectServ, temp, MAXNICK);
free(temp);
}
if(GetConf((void *) &temp, CFGSTR, "User") < 0) {
strlcpy(cs_cfg.user, "CS", MAXUSER);
}
else {
strlcpy(cs_cfg.user, temp, MAXUSER);
free(temp);
}
if(GetConf((void *) &temp, CFGSTR, "Host") < 0) {
strlcpy(cs_cfg.host, me.name, MAXHOST);
}
else {
strlcpy(cs_cfg.host, temp, MAXHOST);
free(temp);
}
if(GetConf((void *) &temp, CFGSTR, "RealName") < 0) {
strlcpy(cs_cfg.rname, "Connection Monitoring Service", MAXREALNAME);
}
else {
strlcpy(cs_cfg.rname, temp, MAXREALNAME);
free(temp);
}
}

View file

@ -22,81 +22,3 @@
** NeoStats CVS Identification
** $Id$
*/
/*
** If we're compiled for Ultimate 3.x.x IRCd, use these modes and flags
*/
#if defined(ULTIMATE3) || defined(QUANTUM)
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define GUESTADMIN_MODE 'G'
#define COSERVERADMIN_MODE 'J'
#define SERVERADMIN_MODE 'A'
#define CONETADMIN_MODE 'n'
#define NETADMIN_MODE 'N'
#define COTECHADMIN_MODE 't'
#define TECHADMIN_MODE 'T' /* Set to a number as we dont use */
#define SERVICESADMIN_MODE 'a'
#define NETSERVICE_MODE 'S'
#elif ULTIMATE
/*
** If we are compiled to Use Ultimate 2.8.x use these modes and flags
*/
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define COSERVERADMIN_MODE 'J'
#define SERVERADMIN_MODE 'A'
#define CONETADMIN_MODE 't'
#define NETADMIN_MODE 'N'
#define TECHADMIN_MODE 'T'
#define SERVICESADMIN_MODE 'P'
#define NETSERVICE_MODE 'S'
#define BOT_MODE 'B'
#endif
#ifdef MYSTIC
/*
** If we are compiled to Use Ultimate 2.8.x use these modes and flags
*/
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define COSERVERADMIN_MODE 'J'
#define SERVERADMIN_MODE 'A'
#define CONETADMIN_MODE 't'
#define NETADMIN_MODE 'N'
#define TECHADMIN_MODE 'T'
#define SERVICESADMIN_MODE 'P'
#define NETSERVICE_MODE 'S'
#define BOT_MODE 'B'
#endif
#ifdef UNREAL
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define COSERVERADMIN_MODE 'C'
#define SERVERADMIN_MODE 'A'
#define NETADMIN_MODE 'N'
#define TECHADMIN_MODE 'T'
#define SERVICESADMIN_MODE 'a'
#define NETSERVICE_MODE 'S'
#define INVISIBLE_MODE 'I'
#define BOT_MODE 'B'
#endif
#ifdef HYBRID7
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define SERVERADMIN_MODE 'a'
#endif
#ifdef NEOIRCD
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define SERVERADMIN_MODE 'a'
#endif
#ifdef BAHAMUT
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define SERVERADMIN_MODE 'a'
#endif

View file

@ -33,11 +33,19 @@
static int new_m_version(char *origin, char **av, int ac);
void sr_cb_config(char *arg, int configtype);
extern void ext_auth_list(User *u, char **av, int ac);
const char *sr_help_list[] = {
"Syntax: \2SRLIST\2",
"",
"This command lists the ServiceRoots defined in the configuration file",
NULL
};
ModuleInfo __module_info = {
"extauth",
"ServiceRoots Authentication Module",
"1.1",
"1.2",
__DATE__,
__TIME__
};
@ -89,6 +97,7 @@ int __ModInit(int modnum, int apiver)
"ServiceRoots: ehh, config failed");
/* we can't unload the extauth module so don't return -1 */
}
add_services_cmd("SRLIST", ext_auth_list, 0, NS_ULEVEL_OPER, sr_help_list, "ServiceRoots List");
return 1;
}
@ -101,6 +110,7 @@ void __ModFini()
un = list_next(srconf.ul, un);
}
list_destroy_nodes(srconf.ul);
del_services_cmd("SRLIST");
}
void sr_cb_config(char *arg, int configtype)
@ -133,14 +143,14 @@ void sr_cb_config(char *arg, int configtype)
strlcpy(sru->nick, nick, MAXNICK);
strlcpy(sru->ident, user, MAXUSER);
strlcpy(sru->host, host, MAXHOST);
sru->lvl = 200;
sru->lvl = NS_ULEVEL_ROOT;
} else {
/* old format... Warn, but keep going */
sru = malloc(sizeof(users));
strlcpy(sru->nick, arg, MAXNICK);
strlcpy(sru->ident, "*", MAXUSER);
strlcpy(sru->host, "*", MAXHOST);
sru->lvl = 200;
sru->lvl = NS_ULEVEL_ROOT;
nlog(LOG_WARNING, LOG_CORE,
"Old ServiceRoots Entry Detected. Suggest you upgrade ASAP to <nick>!<ident>@<host> (WildCards are allowed)");
}
@ -181,3 +191,19 @@ extern int __list_auth(User * u)
}
return 1;
}
extern void ext_auth_list(User *u, char **av, int ac) {
lnode_t *un;
struct users *sru;
SET_SEGV_LOCATION();
un = list_first(srconf.ul);
prefmsg(u->nick, s_Services, "ServiceRoots:");
while (un) {
sru = lnode_get(un);
prefmsg(u->nick, s_Services, "%s!%s@%s %d", sru->nick, sru->ident,
sru->host, sru->lvl);
un = list_next(srconf.ul, un);
}
return;
}

View file

@ -168,10 +168,19 @@ void hs_Config()
int hostlen;
SET_SEGV_LOCATION();
hs_cfg.old = 60;
GetConf((void *) &hs_cfg.view, CFGINT, "ViewLevel");
if ((hs_cfg.view > NS_ULEVEL_ROOT) || (hs_cfg.list <= 0))
hs_cfg.view = 100;
GetConf((void *) &hs_cfg.add, CFGINT, "AddLevel");
if ((hs_cfg.add > NS_ULEVEL_ROOT) || (hs_cfg.view <= 0))
hs_cfg.add = 40;
GetConf((void *) &hs_cfg.del, CFGINT, "DelLevel");
if ((hs_cfg.del > NS_ULEVEL_ROOT) || (hs_cfg.del <= 0))
hs_cfg.del = 40;
GetConf((void *) &hs_cfg.list, CFGINT, "ListLevel");
if ((hs_cfg.list > NS_ULEVEL_ROOT) || (hs_cfg.list <= 0))
hs_cfg.list = 40;
GetConf((void *) &hs_cfg.old, CFGINT, "ExpireDays");
if (GetConf((void *) &hs_cfg.regnick, CFGINT, "UnetVhosts") > 0) {
if (GetConf((void *) &ban, CFGSTR, "UnetDomain") > 0) {
@ -184,16 +193,6 @@ void hs_Config()
hs_cfg.vhostdom[0] = '\0';
}
if ((hs_cfg.list > 200) || (hs_cfg.list <= 0))
hs_cfg.list = 40;
if ((hs_cfg.add > 200) || (hs_cfg.view <= 0))
hs_cfg.add = 40;
if ((hs_cfg.del > 200) || (hs_cfg.del <= 0))
hs_cfg.del = 40;
if ((hs_cfg.view > 200) || (hs_cfg.list <= 0))
hs_cfg.view = 100;
/* banned vhosts */
ban = NULL;
GetConf((void *) &ban, CFGSTR, "BannedVhosts");
@ -281,7 +280,7 @@ Functions __module_functions[] = {
{NULL, NULL, 0}
};
int __Bot_Message(char *origin, char **av, int ac)
int __BotMessage(char *origin, char **av, int ac)
{
int t = 0;
User *u;
@ -328,7 +327,7 @@ int __Bot_Message(char *origin, char **av, int ac)
} else if (!strcasecmp(av[2], "ABOUT")) {
privmsg_list(u->nick, s_HostServ, hs_help_about);
return 1;
} else if (!strcasecmp(av[2], "SET") && (UserLevel(u) >= 185)) {
} else if (!strcasecmp(av[2], "SET") && (UserLevel(u) >= NS_ULEVEL_ADMIN)) {
privmsg_list(u->nick, s_HostServ, hs_help_set);
return 1;
} else
@ -385,7 +384,7 @@ int __Bot_Message(char *origin, char **av, int ac)
hs_listban(u);
return 1;
} else if (ac == 4) {
if (UserLevel(u) >= 185) {
if (UserLevel(u) >= NS_ULEVEL_ADMIN) {
if (!strcasecmp(av[2], "ADD")) {
hs_addban(u, av[3]);
return 1;
@ -417,7 +416,7 @@ int __Bot_Message(char *origin, char **av, int ac)
hs_cfg.view);
return 1;
} else if (ac == 3) {
if (UserLevel(u) >= 185) {
if (UserLevel(u) >= NS_ULEVEL_ADMIN) {
if (!strcasecmp(av[2], "RESET")) {
hs_cfg.add = 40;
SetConf((void *) t, CFGINT, "AddLevel");
@ -431,11 +430,11 @@ int __Bot_Message(char *origin, char **av, int ac)
}
prefmsg(u->nick, s_HostServ, "Permission Denied");
} else if (ac == 4) {
if (UserLevel(u) >= 185) {
if (UserLevel(u) >= NS_ULEVEL_ADMIN) {
t = atoi(av[3]);
if ((t <= 0) || (t > 200)) {
if ((t <= 0) || (t > NS_ULEVEL_ROOT)) {
prefmsg(u->nick, s_HostServ,
"Invalid Level. Must be between 1 and 200");
"Invalid Level. Must be between 1 and %d", NS_ULEVEL_ROOT);
return -1;
}
if (!strcasecmp(av[2], "ADD")) {
@ -513,7 +512,7 @@ int __Bot_Message(char *origin, char **av, int ac)
}
hs_chpass(u, av[2], av[3], av[4]);
} else if (!strcasecmp(av[1], "SET")) {
if (UserLevel(u) < 185) {
if (UserLevel(u) < NS_ULEVEL_ADMIN) {
prefmsg(u->nick, s_HostServ, "Permission Denied");
chanalert(s_HostServ, "%s tried set, but permission was denied", u->nick);
return -1;
@ -607,11 +606,11 @@ int Online(char **av, int ac)
if (init_bot
(s_HostServ, user, host, rname, "+oS",
(s_HostServ, user, host, rname, services_bot_modes,
__module_info.module_name) == -1) {
/* Nick was in use */
strlcat(s_HostServ, "_", MAXNICK);
init_bot(s_HostServ, user, host, rname, "+oS",
init_bot(s_HostServ, user, host, rname, services_bot_modes,
__module_info.module_name);
}
if(user)
@ -658,11 +657,6 @@ int __ModInit(int modnum, int apiver)
return -1;
}
hs_cfg.modnum = modnum;
hs_cfg.add = 40;
hs_cfg.del = 40;
hs_cfg.list = 40;
hs_cfg.view = 100;
hs_cfg.old = 60;
hs_Config();
return 1;
}

View file

@ -73,7 +73,7 @@ Functions __module_functions[] = {
};
int __Bot_Message(char *origin, char **av, int ac)
int __BotMessage(char *origin, char **av, int ac)
{
User *u;
char *cmd;
@ -258,12 +258,12 @@ int __Bot_Message(char *origin, char **av, int ac)
int Online(char **av, int ac)
{
if (init_bot
(s_LoveServ, "love", me.name, "Network Love Service", "+oS",
(s_LoveServ, "love", me.name, "Network Love Service", services_bot_modes,
__module_info.module_name) == -1) {
/* Nick was in use!!!! */
s_LoveServ = strcat(s_LoveServ, "_");
init_bot(s_LoveServ, "love", me.name,
"Network Love Service", "+oS",
"Network Love Service", services_bot_modes,
__module_info.module_name);
}
return 1;

View file

@ -300,7 +300,7 @@ To delete a timer:
-----------------------------------<>-----------------------------------
TODO:
int __Chan_Message(char *origin, char *chan, char **argv, int argc)
int __Chan_Message(char *origin, char **argv, int argc)
-----------------------------------<>-----------------------------------
TODO:

View file

@ -69,7 +69,7 @@ Functions __module_functions[] = {
};
int __Bot_Message(char *origin, char **av, int ac)
int __BotMessage(char *origin, char **av, int ac)
{
User *u;
u = finduser(origin);
@ -237,11 +237,11 @@ int Online(char **av, int ac)
{
if (init_bot
(s_MoraleServ, "MS", me.name, "A Network Morale Service",
"+oS", __module_info.module_name) == -1) {
services_bot_modes, __module_info.module_name) == -1) {
/* Nick was in use */
s_MoraleServ = strcat(s_MoraleServ, "_");
init_bot(s_MoraleServ, "MS", me.name,
"A Network Morale Service", "+oS",
"A Network Morale Service", services_bot_modes,
__module_info.module_name);
}
return 1;

View file

@ -62,10 +62,11 @@ Functions __module_functions[] = {
/* an easter egg for all the Neo users */
int __Chan_Message(char *origin, char *chan, char **argv, int argc)
int __ChanMessage(char *origin, char **argv, int argc)
{
FILE *fort;
char *fortune;
char *chan = argv[0];
if (!strcasecmp(argv[1], s_Spam)) {
fort = popen("/usr/games/fortune", "r");
if (fort) {
@ -82,7 +83,7 @@ int __Chan_Message(char *origin, char *chan, char **argv, int argc)
int __Bot_Message(char *origin, char **argv, int argc)
int __BotMessage(char *origin, char **argv, int argc)
{
User *u;
char *buf;

View file

@ -416,7 +416,7 @@ void re_init_bot()
SET_SEGV_LOCATION();
chanalert(s_Services, "Re-Initilizing %s Bot", s_StatServ);
init_bot(s_StatServ, StatServ.user, StatServ.host,
"/msg Statserv HELP", "+oS", SSMNAME);
"/msg Statserv HELP", services_bot_modes, SSMNAME);
}
int s_del_user(char **av, int ac)
{
@ -559,7 +559,7 @@ int Online(char **av, int ac)
{
SET_SEGV_LOCATION();
init_bot(s_StatServ, StatServ.user, StatServ.host, StatServ.rname,
"+oS", SSMNAME);
services_bot_modes, SSMNAME);
StatServ.onchan = 1;
/* now that we are online, setup the timer to save the Stats database every so often */
add_mod_timer("SaveStats", "Save_Stats_DB", SSMNAME, DBSAVETIME);

View file

@ -239,7 +239,7 @@ void __ModFini()
}
int __Bot_Message(char *origin, char **av, int ac)
int __BotMessage(char *origin, char **av, int ac)
{
User *u;
@ -313,9 +313,9 @@ int __Bot_Message(char *origin, char **av, int ac)
else if (!strcasecmp(av[2], "ABOUT"))
privmsg_list(u->nick, s_StatServ, ss_about_help);
else if (!strcasecmp(av[2], "STATS")
&& UserLevel(u) >= 185)
&& UserLevel(u) >= NS_ULEVEL_ADMIN)
privmsg_list(u->nick, s_StatServ, ss_stats_help);
else if (!strcasecmp(av[2], "SET") && UserLevel(u) >= 185)
else if (!strcasecmp(av[2], "SET") && UserLevel(u) >= NS_ULEVEL_ADMIN)
privmsg_list(u->nick, s_StatServ, ss_set_help);
else
prefmsg(u->nick, s_StatServ,
@ -329,7 +329,7 @@ int __Bot_Message(char *origin, char **av, int ac)
chanalert(s_StatServ,
"%s Wanted to see Channel Statistics", u->nick);
} else if (!strcasecmp(av[1], "SET")) {
if (UserLevel(u) >= 185) {
if (UserLevel(u) >= NS_ULEVEL_ADMIN) {
ss_set(u, av, ac);
} else {
prefmsg(u->nick, s_StatServ, "Permission Denied");
@ -368,7 +368,7 @@ int __Bot_Message(char *origin, char **av, int ac)
chanalert(s_StatServ,
"%s Wanted to see the Daily NetStats ", u->nick);
} else if (!strcasecmp(av[1], "FORCEHTML")
&& (UserLevel(u) >= 185)) {
&& (UserLevel(u) >= NS_ULEVEL_ADMIN)) {
nlog(LOG_NOTICE, LOG_MOD,
"%s!%s@%s Forced an update of the NeoStats Statistics HTML file with the most current statistics",
u->nick, u->username, u->hostname);
@ -400,7 +400,7 @@ int __Bot_Message(char *origin, char **av, int ac)
chanalert(s_StatServ, "%s Wanted to see the Bot List",
u->nick);
#endif
} else if (!strcasecmp(av[1], "STATS") && (UserLevel(u) >= 185)) {
} else if (!strcasecmp(av[1], "STATS") && (UserLevel(u) >= NS_ULEVEL_ADMIN)) {
ss_stats(u, av[2], av[3], av[4]);
if (ac < 3) {
chanalert(s_StatServ,
@ -886,7 +886,7 @@ static void makemap(char *uplink, User * u, int level)
s = hnode_get(sn);
ss = findstats(s->name);
if ((level == 0) && (strlen(s->uplink) <= 0)) {
if ((level == 0) && (s->uplink[0] != 0)) {
/* its the root server */
prefmsg(u->nick, s_StatServ,
"\2%-45s [ %d/%d ] [ %d/%d ] [ %ld/%ld ]",
@ -1125,7 +1125,7 @@ static void ss_stats(User * u, char *cmd, char *arg, char *arg2)
hscan_t scan;
SET_SEGV_LOCATION();
if (UserLevel(u) < 185) {
if (UserLevel(u) < NS_ULEVEL_ADMIN) {
nlog(LOG_NORMAL, LOG_MOD, "Access Denied (STATS) to %s",
u->nick);
prefmsg(u->nick, s_StatServ, "Access Denied.");

View file

@ -30,8 +30,9 @@
*/
#include <stdio.h>
#include "dl.h"
#include "stats.h"
#include "dl.h" /* Required for module */
#include "stats.h" /* Required for bot support */
#include "log.h" /* Log systems support */
/**
* A string to hold the name of our bot
@ -80,8 +81,9 @@ Functions __module_functions[] = {
* What do we do with messages in channels
* This is required if you want your module to respond to channel messages
*/
int __Chan_Message(char *origin, char *chan, char **argv, int argc)
int __ChanMessage(char *origin, char **argv, int argc)
{
char *chan = av[0];
return 1;
}
@ -89,18 +91,34 @@ int __Chan_Message(char *origin, char *chan, char **argv, int argc)
* What do we do with messages sent to our bot with /mag
* This is required if you want your module to respond to /msg
*/
int __Bot_Message(char *origin, char **argv, int argc)
int __BotMessage(char *origin, char **argv, int argc)
{
User *u;
char *buf;
u = finduser(origin);
if (!u) {
nlog(LOG_WARNING, LOG_CORE, "Unable to find user %s ", origin);
return -1;
}
buf = joinbuf(argv, argc, 1);
globops(me.name, "Bot recieved %s from (%s!%s@%s)", buf, u->nick, u->username, u->hostname);
chanalert(s_module_bot_name, "Bot recieved %s from (%s!%s@%s)", buf, u->nick, u->username, u->hostname);
nlog(LOG_NORMAL, LOG_MOD, "Bot recieved %s from (%s!%s@%s)", buf, u->nick, u->username, u->hostname);
free(buf);
return 1;
}
/** Online event processing
* What we do when we first come online
* This is required if you want your module to respond to an event on IRC
* see modules.txt for a list of all events available
*/
int Online(char **av, int ac)
{
/* Introduce a bot onto the network */
if (init_bot(s_module_bot_name, "user", me.name, "Real Name", "-x",
__module_info.module_name) == -1) {
/* Nick was in use */
return 0;
}
return 1;
};
@ -120,7 +138,7 @@ EventFnList __module_events[] = {
*/
int __ModInit(int modnum, int apiver)
{
s_module_bot_name = "NeoBot";
s_module_bot_name = "TemplateBot";
return 1;
}

3
dns.c
View file

@ -34,8 +34,9 @@
#include "stats.h"
#include "log.h"
#include <adns.h>
#include "dns.h"
adns_state ads;
/** @brief DNS lookup Struct
* structure containing all pending DNS lookups and the callback functions

30
dns.h Normal file
View file

@ -0,0 +1,30 @@
/* NeoStats - IRC Statistical Services
** Copyright (c) 1999-2003 Adam Rutter, Justin Hammond, Mark Hetherington
** http://www.neostats.net/
**
** 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
#ifndef _DNS_H_
#define _DNS_H_
int init_dns (void);
void do_dns (void);
#endif /* _DNS_H_ */

View file

@ -127,10 +127,8 @@ Contents
7.3.8 BEHAPPY
7.3.9 WONDERFUL
7.3.10 VERSION
8. spam
8.1 About spam
9. ExtAuth
9.1 About ExtAuth
8. ExtAuth
8.1 About ExtAuth
-----------------------------------<>-----------------------------------
@ -348,7 +346,7 @@ Example:
2.3.13 DEBUG
------------
Syntax:
/msg NeoStats DEBUG
/msg NeoStats DEBUG <ON|OFF>
Description:
This toggles the debug command, On a large network, this command
should be used considered dangerous as a large amount of information
@ -1205,25 +1203,9 @@ Example:
-----------------------------------<>-----------------------------------
8. spam
-------
8.1 About spam
--------------
Spam provides a bot to try and catch spammers and mass messagers. It
will sit on the network and echo to the services channel and by wallops
when someone sends it a message and what message they sent.
Currently the spam bot has a fixed name of "sumyungguy".
Send it a message, and watch what happens.
-----------------------------------<>-----------------------------------
9. ExtAuth
8. ExtAuth
----------
9.1 About ExtAuth
8.1 About ExtAuth
-----------------
ExtAuth may be listed as a loaded module, but its not a true module as

View file

@ -27,10 +27,14 @@
#include "hybrid7.h"
#include "dl.h"
#include "log.h"
#include "users.h"
#include "server.h"
#include "chans.h"
static char ircd_buf[BUFSIZE];
const char ircd_version[] = "(H)";
const char services_bot_modes[]= "+oS";
/* this is the command list and associated functions to run */
IntCommands cmd_list[] = {
@ -136,7 +140,7 @@ Oper_Modes usr_mds[] = {
,
{UMODE_CCONN, 'c', 0}
,
{UMODE_DEBUG, 'd', 200}
{UMODE_DEBUG, 'd', NS_ULEVEL_ROOT}
,
{UMODE_FULL, 'f', 0}
,
@ -421,6 +425,11 @@ ssvshost_cmd (const char *who, const char *vhost)
nlog (LOG_NOTICE, LOG_CORE, "Warning. Module %s tried to SVSHOST, which is not supported in Hybrid", segvinmodule);
return 1;
}
int
sinvite_cmd (const char *from, const char *to, const char *chan) {
sts (":%s INVITE %s %s", from, to, chan);
return 1;
}
int
ssvinfo_cmd ()
@ -778,7 +787,7 @@ Usr_Away (char *origin, char **argv, int argc)
} else {
buf = NULL;
}
Do_Away (u, buf);
UserAway (u, buf);
if (argc > 0) {
free (buf);
}
@ -805,7 +814,7 @@ Usr_Topic (char *origin, char **argv, int argc)
c = findchan (argv[0]);
if (c) {
buf = joinbuf (argv, argc, 2);
Change_Topic (origin, c, me.now, buf);
ChangeTopic (origin, c, me.now, buf);
free (buf);
} else {
nlog (LOG_WARNING, LOG_CORE, "Ehhh, Can't find Channel %s", argv[0]);

View file

@ -25,8 +25,20 @@
#ifndef HYBRID7_H
#define HYBRID7_H
/* we dont support tokens */
#undef HAVE_TOKEN_SUP
/* we dont have svshost support */
#undef GOTSVSHOST
/* we don't have svsjoin support */
#undef GOTSVSJOIN
/* Moved from connectserv so we can use elsewhere */
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define SERVERADMIN_MODE 'a'
#define MSG_EOB "EOB" /* end of burst */
#define MSG_PRIVATE "PRIVMSG" /* PRIV */

103
ircd.c
View file

@ -29,6 +29,7 @@
#include "ircd.h"
#include "dl.h"
#include "log.h"
#include "services.h"
/** @brief init_bot
*
@ -37,7 +38,7 @@
* @return NS_SUCCESS if suceeds, NS_FAILURE if not
*/
int
init_bot (char *nick, char *user, char *host, char *rname, char *modes, char *mod_name)
init_bot (char *nick, char *user, char *host, char *rname, const char *modes, char *mod_name)
{
User *u;
char **av;
@ -84,7 +85,7 @@ init_bot (char *nick, char *user, char *host, char *rname, char *modes, char *mo
}
SignOn_NewBot (nick, user, host, rname, Umode);
AddStringToList (&av, nick, &ac);
Module_Event (EVENT_SIGNON, av, ac);
ModuleEvent (EVENT_SIGNON, av, ac);
free (av);
/* restore segv_inmodule from SIGNON */
SET_SEGV_INMODULE(mod_name);
@ -115,49 +116,6 @@ del_bot (char *nick, char *reason)
return NS_SUCCESS;
}
/** @brief Module_Event
*
*
*
* @return none
*/
void
Module_Event (char *event, char **av, int ac)
{
Module *module_ptr;
EventFnList *ev_list;
hscan_t ms;
hnode_t *mn;
SET_SEGV_LOCATION();
hash_scan_begin (&ms, mh);
while ((mn = hash_scan_next (&ms)) != NULL) {
module_ptr = hnode_get (mn);
ev_list = module_ptr->other_funcs;
if (ev_list) {
while (ev_list->cmd_name != NULL) {
/* This goes through each Command */
if (!strcasecmp (ev_list->cmd_name, event)) {
nlog (LOG_DEBUG1, LOG_CORE, "Running Module %s for Comamnd %s -> %s", module_ptr->info->module_name, event, ev_list->cmd_name);
SET_SEGV_LOCATION();
SET_SEGV_INMODULE(module_ptr->info->module_name);
if (setjmp (sigvbuf) == 0) {
if (ev_list->function) ev_list->function (av, ac);
} else {
nlog (LOG_CRITICAL, LOG_CORE, "setjmp() Failed, Can't call Module %s\n", module_ptr->info->module_name);
}
CLEAR_SEGV_INMODULE();
SET_SEGV_LOCATION();
#ifndef VALGRIND
break;
#endif
}
ev_list++;
}
}
}
}
/** @brief split_buf
* Taken from Epona - Thanks!
* Split a buffer into arguments and store the arguments in an
@ -249,11 +207,7 @@ parse (char *line)
int I = 0;
int ac;
char **av;
Module *module_ptr;
Functions *fn_list;
Mod_User *list;
hscan_t ms;
hnode_t *mn;
ModUser *mod_usr;
SET_SEGV_LOCATION();
strip (line);
@ -286,11 +240,11 @@ parse (char *line)
coreLine = line + strlen (line);
#ifdef IRCU
if ((!strcasecmp(line, "SERVER")) || (!strcasecmp(line, "PASS"))) {
strncpy(cmd, line, sizeof(cmd));
strlcpy(cmd, line, sizeof(cmd));
ac = split_buf(coreLine, &av, 1);
cmdptr = 0;
} else {
strncpy(origin, line, sizeof(origin));
strlcpy(origin, line, sizeof(origin));
cmdptr = 1;
line = strpbrk (coreLine, " ");
if (line) {
@ -302,7 +256,7 @@ parse (char *line)
}
#else
strncpy (cmd, line, sizeof (cmd));
strlcpy (cmd, line, sizeof (cmd));
ac = split_buf (coreLine, &av, 1);
#endif
@ -334,10 +288,10 @@ parse (char *line)
free (av);
return;
} else {
list = findbot (av[0]);
mod_usr = findbot (av[0]);
/* Check to see if any of the Modules have this nick Registered */
if (list) {
nlog (LOG_DEBUG1, LOG_CORE, "nicks: %s", list->nick);
if (mod_usr) {
nlog (LOG_DEBUG1, LOG_CORE, "nicks: %s", mod_usr->nick);
if (flood (finduser (origin))) {
free (av);
return;
@ -354,16 +308,16 @@ parse (char *line)
}
SET_SEGV_LOCATION();
SET_SEGV_INMODULE(list->modname);
SET_SEGV_INMODULE(mod_usr->modname);
if (setjmp (sigvbuf) == 0) {
list->function (origin, av, ac);
mod_usr->function (origin, av, ac);
}
CLEAR_SEGV_INMODULE();
SET_SEGV_LOCATION();
free (av);
return;
} else {
bot_chan_message (origin, av[0], av, ac);
bot_chan_message (origin, av, ac);
free (av);
return;
}
@ -383,28 +337,7 @@ parse (char *line)
}
/* K, now Parse it to the Module functions */
SET_SEGV_LOCATION();
hash_scan_begin (&ms, mh);
while ((mn = hash_scan_next (&ms)) != NULL) {
module_ptr = hnode_get (mn);
fn_list = module_ptr->function_list;
while (fn_list->cmd_name != NULL) {
/* This goes through each Command */
if (!strcmp (fn_list->cmd_name, cmd)) {
if (fn_list->srvmsg == cmdptr) {
nlog (LOG_DEBUG1, LOG_CORE, "Running Module %s for Function %s", module_ptr->info->module_name, fn_list->cmd_name);
SET_SEGV_LOCATION();
SET_SEGV_INMODULE(module_ptr->info->module_name);
if (setjmp (sigvbuf) == 0) {
fn_list->function (origin, av, ac);
}
CLEAR_SEGV_INMODULE();
SET_SEGV_LOCATION();
break;
}
}
fn_list++;
}
}
ModuleFunction (cmdptr, cmd, origin, av, ac);
free (av);
}
@ -430,11 +363,11 @@ init_ServBot (void)
SignOn_NewBot (s_Services, Servbot.user, Servbot.host, rname, UMODE_SERVICES);
me.onchan = 1;
AddStringToList (&av, me.uplink, &ac);
Module_Event (EVENT_ONLINE, av, ac);
ModuleEvent (EVENT_ONLINE, av, ac);
free (av);
ac = 0;
AddStringToList (&av, s_Services, &ac);
Module_Event (EVENT_SIGNON, av, ac);
ModuleEvent (EVENT_SIGNON, av, ac);
free (av);
}
@ -457,7 +390,7 @@ dopong (Server * s)
if (!strcmp (me.s->name, s->name))
ping.ulag = me.s->ping;
AddStringToList (&av, s->name, &ac);
Module_Event (EVENT_PONG, av, ac);
ModuleEvent (EVENT_PONG, av, ac);
free (av);
} else {
nlog (LOG_NOTICE, LOG_CORE, "Received PONG from unknown server: %s", recbuf);
@ -479,7 +412,7 @@ flood (User * u)
nlog (LOG_WARNING, LOG_CORE, "Warning, Can't find user for FLOODcheck");
return 0;
}
if (UserLevel (u) >= 40) /* locop or higher */
if (UserLevel (u) >= NS_ULEVEL_OPER) /* locop or higher */
return 0;
if (current - u->t_flood > 10) {
u->t_flood = me.now;

1029
liquidircd.c Normal file

File diff suppressed because it is too large Load diff

356
liquidircd.h Normal file
View file

@ -0,0 +1,356 @@
/* NeoStats - IRC Statistical Services
** Copyright (c) 1999-2003 Adam Rutter, Justin Hammond
** http://www.neostats.net/
**
** Portions Copyright (c) 2000-2001 ^Enigma^
**
** 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
#ifndef LIQUIDIRCD_H
#define LIQUIDIRCD_H
/* we support tokens */
#undef HAVE_TOKEN_SUP
/* we have vhost support */
#define GOTSVSVHOST
/* we don't have svsjoin support */
#undef GOTSVSJOIN
/* Moved from connectserv so we can use elsewhere */
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define SERVERADMIN_MODE 'A'
#define NETADMIN_MODE 'N'
#define TECHADMIN_MODE 'T'
#define SERVICESADMIN_MODE 'a'
#define NETSERVICE_MODE 'S'
#define BOT_MODE 'B'
#define MSG_PRIVATE "PRIVMSG" /* PRIV */
#define MSG_WHO "WHO" /* WHO -> WHOC */
#define MSG_WHOIS "WHOIS" /* WHOI */
#define MSG_WHOWAS "WHOWAS" /* WHOW */
#define MSG_USER "USER" /* USER */
#define MSG_NICK "NICK" /* NICK */
#define MSG_SERVER "SERVER" /* SERV */
#define MSG_LIST "LIST" /* LIST */
#define MSG_TOPIC "TOPIC" /* TOPI */
#define MSG_INVITE "INVITE" /* INVI */
#define MSG_VERSION "VERSION" /* VERS */
#define MSG_QUIT "QUIT" /* QUIT */
#define MSG_SQUIT "SQUIT" /* SQUI */
#define MSG_KILL "KILL" /* KILL */
#define MSG_INFO "INFO" /* INFO */
#define MSG_LINKS "LINKS" /* LINK */
#define MSG_WATCH "WATCH" /* WATCH */
#define MSG_STATS "STATS" /* STAT */
#define MSG_HELP "HELP" /* HELP */
#define MSG_HELPOP "HELPOP" /* HELP */
#define MSG_ERROR "ERROR" /* ERRO */
#define MSG_AWAY "AWAY" /* AWAY */
#define MSG_CONNECT "CONNECT" /* CONN */
#define MSG_PING "PING" /* PING */
#define MSG_PONG "PONG" /* PONG */
#define MSG_OPER "OPER" /* OPER */
#define MSG_PASS "PASS" /* PASS */
#define MSG_WALLOPS "WALLOPS" /* WALL */
#define MSG_TIME "TIME" /* TIME */
#define MSG_NAMES "NAMES" /* NAME */
#define MSG_ADMIN "ADMIN" /* ADMI */
#define MSG_NOTICE "NOTICE" /* NOTI */
#define MSG_JOIN "JOIN" /* JOIN */
#define MSG_PART "PART" /* PART */
#define MSG_LUSERS "LUSERS" /* LUSE */
#define MSG_MOTD "MOTD" /* MOTD */
#define MSG_MODE "MODE" /* MODE */
#define MSG_KICK "KICK" /* KICK */
#define MSG_SERVICE "SERVICE" /* SERV -> SRVI */
#define MSG_USERHOST "USERHOST" /* USER -> USRH */
#define MSG_ISON "ISON" /* ISON */
#define MSG_SQUERY "SQUERY" /* SQUE */
#define MSG_SERVLIST "SERVLIST" /* SERV -> SLIS */
#define MSG_SERVSET "SERVSET" /* SERV -> SSET */
#define MSG_REHASH "REHASH" /* REHA */
#define MSG_RESTART "RESTART" /* REST */
#define MSG_CLOSE "CLOSE" /* CLOS */
#define MSG_DIE "DIE" /* DIE */
#define MSG_HASH "HASH" /* HASH */
#define MSG_DNS "DNS" /* DNS -> DNSS */
#define MSG_SILENCE "SILENCE" /* SILE */
#define MSG_AKILL "AKILL" /* AKILL */
#define MSG_KLINE "KLINE" /* KLINE */
#define MSG_UNKLINE "UNKLINE" /* UNKLINE */
#define MSG_RAKILL "RAKILL" /* RAKILL */
#define MSG_GNOTICE "GNOTICE" /* GNOTICE */
#define MSG_GOPER "GOPER" /* GOPER */
#define MSG_GLOBOPS "GLOBOPS" /* GLOBOPS */
#define MSG_LOCOPS "LOCOPS" /* LOCOPS */
#define MSG_PROTOCTL "PROTOCTL" /* PROTOCTL */
#define MSG_TRACE "TRACE" /* TRAC */
#define MSG_SQLINE "SQLINE" /* SQLINE */
#define MSG_UNSQLINE "UNSQLINE" /* UNSQLINE */
#define MSG_SVSNICK "SVSNICK" /* SVSNICK */
#define MSG_SVSNOOP "SVSNOOP" /* SVSNOOP */
#define MSG_IDENTIFY "IDENTIFY" /* IDENTIFY */
#define MSG_SVSKILL "SVSKILL" /* SVSKILL */
#define MSG_SVSMODE "SVSMODE" /* SVSMODE */
#define MSG_SAMODE "SAMODE" /* SAMODE */
#define MSG_CHATOPS "CHATOPS" /* CHATOPS */
#define MSG_HELPSERV "HELPSERV" /* HELPSERV */
#define MSG_ZLINE "ZLINE" /* ZLINE */
#define MSG_UNZLINE "UNZLINE" /* UNZLINE */
#define MSG_NETINFO "NETINFO" /* NETINFO */
#define MSG_RULES "RULES" /* RULES */
#define MSG_MAP "MAP" /* MAP */
#define MSG_NETG "NETG" /* NETG */
#define MSG_ADCHAT "ADCHAT" /* Adchat */
#define MSG_MAKEPASS "MAKEPASS" /* MAKEPASS */
#define MSG_ADDHUB "ADDHUB" /* ADDHUB */
#define MSG_DELHUB "DELHUB" /* DELHUB */
#define MSG_ADDCNLINE "ADDCNLINE" /* ADDCNLINE */
#define MSG_DELCNLINE "DELCNLINE" /* DELCNLINE */
#define MSG_ADDOPER "ADDOPER" /* ADDOPER */
#define MSG_DELOPER "DELOPER" /* DELOPER */
#define MSG_ADDQLINE "ADDQLINE" /* ADDQLINE */
#define MSG_DELQLINE "DELQLINE" /* DELQLINE */
#define MSG_GSOP "GSOP" /* GSOP */
#define MSG_ISOPER "ISOPER" /* ISOPER */
#define MSG_ADG "ADG" /* ADG */
#define MSG_NMON "NMON" /* NMON */
#define MSG_DALINFO "DALINFO" /* DALnet Credits */
#define MSG_CREDITS "CREDITS" /* UltimateIRCd Credits and "Thanks To" */
#define MSG_OPERMOTD "OPERMOTD" /* OPERMOTD */
#define MSG_REMREHASH "REMREHASH" /* Remote Rehash */
#define MSG_MONITOR "MONITOR" /* MONITOR */
#define MSG_GLINE "GLINE" /* The awesome g-line */
#define MSG_REMGLINE "REMGLINE" /* remove g-line */
#define MSG_STATSERV "STATSERV" /* StatServ */
#define MSG_RULESERV "RULESERV" /* RuleServ */
#define MSG_SNETINFO "SNETINFO" /* SNetInfo */
#define MSG_TSCTL "TSCTL" /* TSCTL */
#define MSG_SVSJOIN "SVSJOIN" /* SVSJOIN */
#define MSG_SAJOIN "SAJOIN" /* SAJOIN */
#define MSG_SDESC "SDESC" /* SDESC */
#define MSG_UNREALINFO "UNREALINFO" /* Unreal Info */
#define MSG_SETHOST "SETHOST" /* sethost */
#define MSG_SETIDENT "SETIDENT" /* set ident */
#define MSG_SETNAME "SETNAME" /* set Realname */
#define MSG_CHGHOST "CHGHOST" /* Changehost */
#define MSG_CHGIDENT "CHGIDENT" /* Change Ident */
#define MSG_RANDQUOTE "RANDQUOTE" /* Random Quote */
#define MSG_ADDQUOTE "ADDQUOTE" /* Add Quote */
#define MSG_ADDGQUOTE "ADDGQUOTE" /* Add Global Quote */
#define MSG_ADDULINE "ADDULINE" /* Adds an U Line to ircd.conf file */
#define MSG_DELULINE "DELULINE" /* Removes an U line from the ircd.conf */
#define MSG_KNOCK "KNOCK" /* Knock Knock - Who's there? */
#define MSG_SETTINGS "SETTINGS" /* Settings */
#define MSG_IRCOPS "IRCOPS" /* Shows Online IRCOps */
#define MSG_SVSPART "SVSPART" /* SVSPART */
#define MSG_SAPART "SAPART" /* SAPART */
#define MSG_VCTRL "VCTRL" /* VCTRL */
#define MSG_GCLIENT "GCLIENT" /* GLIENT */
#define MSG_CHANNEL "CHANNEL" /* CHANNEL */
#define MSG_UPTIME "UPTIME" /* UPTIME */
#define MSG_FAILOPS "FAILOPS" /* FAILOPS */
#define MSG_RPING "RPING" /* RPING */
#define MSG_RPONG "RPONG" /* RPONG */
#define MSG_UPING "UPING" /* UPING */
#define MSG_COPYRIGHT "COPYRIGHT" /* Copyright */
#define MSG_BOTSERV "BOTSERV" /* BOTSERV */
#define MSG_ROOTSERV "ROOTSERV" /* ROOTSERV */
#define MSG_RS "RS"
#define MSG_SVINFO "SVINFO"
#define MSG_CAPAB "CAPAB"
#define MSG_BURST "BURST"
#define MSG_SJOIN "SJOIN"
#define MSG_CLIENT "CLIENT"
#define MSG_SMODE "SMODE"
#define UMODE_INVISIBLE 0x0001 /* makes user invisible */
#define UMODE_OPER 0x0002 /* Operator */
#define UMODE_LOCOP 0x0004 /* Local Operator */
#define UMODE_WALLOP 0x0008 /* */
/* UMODE_SERVICES is actually UMODE_OPER on Bahamut !*/
#define UMODE_SERVICES UMODE_OPER
#define UMODE_REGONLY 0x0010 /* only registered nicks may PM */
#define UMODE_REGNICK 0x0020 /* Nick set by services as registered */
#define UMODE_SERVADMIN 0x0040 /* server admin */
#define UMODE_SERVICESADMIN 0x0080 /* Marks the client as a Services Administrator */
#define UMODE_FAILOP 0x0100 /* */
#define UMODE_HELPOP 0x0200 /* */
#define UMODE_SERVNOTICE 0x0400 /* */
#define UMODE_KILLS 0x0800 /* */
#define UMODE_CLIENT 0x1000 /* */
#define UMODE_FLOOD 0x2000 /* */
#define UMODE_NETADMIN 0x4000 /* */
#define UMODE_TECHADMIN 0x8000 /* */
#define UMODE_KIX 0x10000 /* */
#define UMODE_BOT 0x20000 /* */
#define UMODE_WHOIS 0x40000 /* */
#define UMODE_HIDE 0x80000 /* */
#define SMODE_SSL 0x1 /* */
#define MODE_CHANOP 0x0001
#define MODE_CHANOWNER 0x0002
#define MODE_VOICE 0x0004
#define MODE_PRIVATE 0x0008
#define MODE_SECRET 0x0010
#define MODE_MODERATED 0x0020
#define MODE_TOPICLIMIT 0x0040
#define MODE_INVITEONLY 0x0080
#define MODE_NOPRIVMSGS 0x0100
#define MODE_KEY 0x0200
#define MODE_NONICKCHANGE 0x0400
#define MODE_BAN 0x0800
#define MODE_LIMIT 0x1000
#define MODE_RGSTR 0x2000
#define MODE_RGSTRONLY 0x4000
#define MODE_OPERONLY 0x8000
#define MODE_STRIP 0x10000
#define MODE_LINK 0x20000
#define MODE_NOCOLOR 0x40000
#define MODE_CHANPROT 0x80000
#define MODE_VIP 0x100000
#define MODE_UOP 0x200000
#define MODE_HALFOP 0x400000
#define is_hidden_chan(x) ((x) && (x->modes & (MODE_PRIVATE|MODE_SECRET|MODE_OPERONLY)))
#define is_oper(x) ((x) && ((x->Umode & UMODE_OPER) || (x->Umode & UMODE_LOCOP)))
#undef HAVE_BOT_MODE
#define is_bot(x) ((x) && (x->Umode & UMODE_BOT))
#define is_pub_chan(x) ((x) && (CheckChanMode(x, MODE_PRIVATE) || CheckChanMode(x, MODE_SECRET) || CheckChanMode(x, MODE_RGSTRONLY) || CheckChanMode(x, MODE_OPERONLY) || CheckChanMode(x, MODE_INVITEONLY) || CheckChanMode(x, MODE_KEY)))
struct ircd_srv_ {
int uprot;
int modex;
int nicklg;
int gc;
char cloak[25];
int burst;
int cmdcount;
} ircd_srv;
typedef struct {
long mode;
char flag;
unsigned nickparam:1; /* 1 = yes 0 = no */
unsigned parameters:1;
char sjoin;
} aCtab;
typedef struct {
unsigned long umodes;
char mode;
int level;
} Oper_Modes;
aCtab cFlagTab[33];
Oper_Modes usr_mds[22];
Oper_Modes susr_mds[2];
/* function declarations */
extern void init_ircd ();
extern void chanalert (char *, char *, ...);
extern int sserver_cmd (const char *, const int numeric, const char *);
extern int slogin_cmd (const char *, const int numeric, const char *, const char *);
extern int ssquit_cmd (const char *);
extern int sprotocol_cmd (const char *);
extern int squit_cmd (const char *, const char *);
extern int spart_cmd (const char *, const char *);
extern int sjoin_cmd (const char *, const char *, unsigned long flag);
extern int schmode_cmd (const char *, const char *, const char *, const char *);
extern int snewnick_cmd (const char *, const char *, const char *, const char *, long);
extern int sping_cmd (const char *from, const char *reply, const char *to);
extern int sumode_cmd (const char *who, const char *target, long mode);
extern int snumeric_cmd (const int numeric, const char *target, const char *data, ...);
extern int spong_cmd (const char *reply);
extern int snetinfo_cmd ();
extern int skill_cmd (const char *from, const char *target, const char *reason, ...);
extern int ssmo_cmd (const char *from, const char *umodetarget, const char *msg);
extern int snick_cmd (const char *oldnick, const char *newnick);
extern int sswhois_cmd (const char *target, const char *swhois);
extern int ssvsnick_cmd (const char *target, const char *newnick);
extern int ssvsjoin_cmd (const char *target, const char *chan);
extern int ssvspart_cmd (const char *target, const char *chan);
extern int ssvshost_cmd (const char *who, const char *vhost);
extern int skick_cmd (const char *who, const char *target, const char *chan, const char *reason);
extern int swallops_cmd (const char *who, const char *msg, ...);
extern int vctrl_cmd ();
extern int ssvinfo_cmd ();
extern int sburst_cmd (int b);
extern int sakill_cmd (const char *host, const char *ident, const char *setby, const int length, const char *reason, ...);
extern int srakill_cmd (const char *host, const char *ident);
extern int ssvshost_cmd (const char *who, const char *vhost);
extern int ssvskill_cmd (const char *who, const char *reason, ...);
extern int sinvite_cmd (const char *from, const char *to, const char *chan);
void Usr_Version (char *, char **, int argc);
void Usr_ShowMOTD (char *, char **, int argc);
void Usr_ShowADMIN (char *, char **, int argc);
void Usr_Showcredits (char *, char **, int argc);
void Usr_AddServer (char *, char **, int argc);
void Usr_DelServer (char *, char **, int argc);
void Usr_DelUser (char *, char **, int argc);
void Usr_Mode (char *, char **, int argc);
void Usr_Smode (char *, char **, int argc);
void Usr_Kill (char *, char **, int argc);
void Usr_Pong (char *, char **, int argc);
void Usr_Away (char *, char **, int argc);
void Usr_Nick (char *, char **, int argc);
void Usr_Topic (char *, char **, int argc);
void Usr_Kick (char *, char **, int argc);
void Usr_Join (char *, char **, int argc);
void Usr_Part (char *, char **, int argc);
void Usr_Stats (char *, char **, int argc);
void Usr_Vhost (char *, char **, int argc);
void Srv_Topic (char *, char **, int argc);
void Srv_Ping (char *, char **, int argc);
void Srv_Netinfo (char *, char **, int argc);
void Srv_Pass (char *, char **, int argc);
void Srv_Server (char *, char **, int argc);
void Srv_Squit (char *, char **, int argc);
void Srv_Nick (char *, char **, int argc);
void Srv_Svsnick (char *, char **, int argc);
void Srv_Kill (char *, char **, int argc);
void Srv_Connect (char *, char **, int argc);
void Srv_Svinfo (char *, char **, int argc);
void Srv_Burst (char *origin, char **argv, int argc);
void Srv_Sjoin (char *origin, char **argv, int argc);
void Srv_Tburst (char *origin, char **argv, int argc);
void Srv_Vctrl (char *origin, char **argv, int argc);
void Srv_Client (char *origin, char **argv, int argc);
void Srv_Smode (char *origin, char **argv, int argc);
int SignOn_NewBot (const char *, const char *, const char *, const char *, long);
#endif

22
main.c
View file

@ -36,6 +36,11 @@
#include "conf.h"
#include "keeper.h"
#include "log.h"
#include "sock.h"
#include "users.h"
#include "server.h"
#include "chans.h"
#include "dns.h"
/* this is the name of the services bot */
char s_Services[MAXNICK] = "NeoStats";
@ -51,6 +56,7 @@ static int get_options (int argc, char **argv);
/*! have we forked */
int forked = 0;
static int attempts = 0;
jmp_buf sigvbuf;
/** @brief Main Entry point into program
*
@ -93,7 +99,7 @@ main (int argc, char *argv[])
printf ("Copyright: NeoStats Group. 2000-2003\n");
printf ("Justin Hammond (fish@neostats.net)\n");
printf ("Adam Rutter (shmad@neostats.net)\n");
printf ("Mark (m@neostats.net\n");
printf ("Mark (m@neostats.net)\n");
printf ("-----------------------------------------------\n\n");
}
/* set some defaults before we parse the config file */
@ -119,12 +125,16 @@ main (int argc, char *argv[])
remove (RECV_LOG);
/* initilze our Module subsystem */
if(__init_mod_list () != NS_SUCCESS)
if(InitModuleHash () != NS_SUCCESS)
return EXIT_FAILURE;
/* prepare to catch errors */
setup_signals ();
/* this has to be done before we load modules */
if(init_services () != NS_SUCCESS)
return EXIT_FAILURE;
/* load the config files */
if(ConfLoad () != NS_SUCCESS)
return EXIT_FAILURE;
@ -285,6 +295,8 @@ get_options (int argc, char **argv)
*
* @todo Do a nice shutdown, no thtis crap :)
*/
char msg_sigterm[]="SIGTERM received, shutting down server.";
RETSIGTYPE
serv_die ()
{
@ -292,9 +304,11 @@ serv_die ()
exit(NS_SUCCESS);
#else /* VALGRIND */
User *u;
u = finduser (s_Services);
nlog (LOG_CRITICAL, LOG_CORE, "SIGTERM received, shutting down server.");
ns_shutdown (u, "SIGTERM received");
nlog (LOG_CRITICAL, LOG_CORE, msg_sigterm);
globops (s_Services, msg_sigterm);
do_exit (NS_EXIT_NORMAL, msg_sigterm);
#endif /* VALGRIND */
}

View file

@ -465,9 +465,6 @@ RECONNECT_TIME $NEOCONN
#
# Multiple instances of LOAD_MODULE may be specified
# this loads the Spam Module
#LOAD_MODULE spam
# this is the StatServ Module
#LOAD_MODULE statserv

41
misc.c
View file

@ -130,28 +130,6 @@ HASH (const unsigned char *name, int size_of_table)
return h % size_of_table;
}
/** @brief convert a string to lowercase
*
* makes a string lowercase (DO NOT USE
*
* @param s the string to convert to lowercase. WARNING: the result overwrites this variable
*
* @returns pointer to the lowercase version of s
*
*/
char *
strlower (char *s)
{
char *t;
t = malloc (strlen (s));
strlcpy (t, s, strlen (s));
while (*t) {
*t++ = tolower (*t);
}
return t;
}
/** @brief convert a string to lowercase
*
* makes a string lowercase
@ -196,25 +174,6 @@ AddStringToList (char ***List, char S[], int *C)
(*List)[*C - 1] = S;
}
/** @brief Frees a list created with AddStringToList
*
* Frees the memory used for a string array used with AddStringToList
*
* @param List the array you wish to delete
* @param C the current size of the array as returned by AddStringToList
*
* @returns Nothing
*
*/
void
FreeList (char **List, int C)
{
int i;
for (i = 0; i == C; i++)
free (List[i]);
C = 0;
}
/** @brief
*
* @param

View file

@ -29,10 +29,14 @@
#include "mystic.h"
#include "dl.h"
#include "log.h"
#include "users.h"
#include "server.h"
#include "chans.h"
static char ircd_buf[BUFSIZE];
const char ircd_version[] = "(M)";
const char services_bot_modes[]= "+oS";
IntCommands cmd_list[] = {
/* Command Function srvmsg */
@ -223,9 +227,9 @@ Oper_Modes usr_mds[] = {
,
{UMODE_KILLS, 'k', 0}
,
{UMODE_SERVICES, 'S', 200}
{UMODE_SERVICES, 'S', NS_ULEVEL_ROOT}
,
{UMODE_SERVICESADMIN, 'P', 200}
{UMODE_SERVICESADMIN, 'P', NS_ULEVEL_ROOT}
,
{UMODE_RBOT, 'B', 0}
,
@ -233,7 +237,7 @@ Oper_Modes usr_mds[] = {
,
{UMODE_COADMIN, 'z', 70}
,
{UMODE_NETADMIN, 'N', 185}
{UMODE_NETADMIN, 'N', NS_ULEVEL_ADMIN}
,
{UMODE_TECHADMIN, 'T', 190}
,
@ -503,6 +507,12 @@ ssvshost_cmd (const char *who, const char *vhost)
sts (":%s CHGHOST %s %s", me.name, who, vhost);
return 1;
}
int
sinvite_cmd (const char *from, const char *to, const char *chan) {
sts (":%s INVITE %s %s", from, to, chan);
return 1;
}
int
sakill_cmd (const char *host, const char *ident, const char *setby, const int length, const char *reason, ...)
{
@ -866,7 +876,7 @@ Usr_Away (char *origin, char **argv, int argc)
} else {
Buf = NULL;
}
Do_Away (u, Buf);
UserAway (u, Buf);
if (argc > 0) {
free (Buf);
}
@ -890,7 +900,7 @@ Usr_Topic (char *origin, char **argv, int argc)
c = findchan (argv[0]);
if (c) {
buf = joinbuf (argv, argc, 3);
Change_Topic (argv[1], c, atoi (argv[2]), buf);
ChangeTopic (argv[1], c, atoi (argv[2]), buf);
free (buf);
} else {
nlog (LOG_WARNING, LOG_CORE, "Ehhh, Can't find Channel %s", argv[0]);
@ -963,9 +973,9 @@ Srv_Netinfo (char *origin, char **argv, int argc)
init_ServBot ();
globops (me.name, "Link with Network \2Complete!\2");
#ifdef DEBUG
ns_set_debug (me.chan);
me.debug_mode = 1;
#endif
Module_Event (EVENT_NETINFO, NULL, 0);
ModuleEvent (EVENT_NETINFO, NULL, 0);
me.synced = 1;
}

View file

@ -31,6 +31,22 @@
/* we have vhost support */
#define GOTSVSVHOST
/* we dont have svsjoin */
#define GOTSVSJOIN
/* Moved from connectserv so we can use elsewhere */
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define COSERVERADMIN_MODE 'J'
#define SERVERADMIN_MODE 'A'
#define CONETADMIN_MODE 't'
#define NETADMIN_MODE 'N'
#define TECHADMIN_MODE 'T'
#define SERVICESADMIN_MODE 'P'
#define NETSERVICE_MODE 'S'
#define BOT_MODE 'B'
#define MSG_PRIVATE "PRIVMSG" /* PRIV */
#define TOK_PRIVATE "!" /* 33 */
#define MSG_WHO "WHO" /* WHO -> WHOC */
@ -453,6 +469,7 @@ extern int sburst_cmd (int b);
extern int sakill_cmd (const char *host, const char *ident, const char *setby, const int length, const char *reason, ...);
extern int srakill_cmd (const char *host, const char *ident);
extern int ssvshost_cmd (const char *who, const char *vhost);
extern int sinvite_cmd (const char *from, const char *to, const char *chan);
void Usr_Version (char *, char **, int argc);
void Usr_ShowMOTD (char *, char **, int argc);

View file

@ -27,10 +27,14 @@
#include "neoircd.h"
#include "dl.h"
#include "log.h"
#include "users.h"
#include "server.h"
#include "chans.h"
static char ircd_buf[BUFSIZE];
const char ircd_version[] = "(N)";
const char services_bot_modes[]= "+oS";
/* this is the command list and associated functions to run */
IntCommands cmd_list[] = {
@ -146,7 +150,7 @@ Oper_Modes usr_mds[] = {
,
{UMODE_CCONN, 'c', 0}
,
{UMODE_DEBUG, 'd', 200}
{UMODE_DEBUG, 'd', NS_ULEVEL_ROOT}
,
{UMODE_FULL, 'f', 0}
,
@ -174,7 +178,7 @@ Oper_Modes usr_mds[] = {
,
{UMODE_OPERWALL, 'z', 0}
,
{UMODE_SERVICES, 'S', 200}
{UMODE_SERVICES, 'S', NS_ULEVEL_ROOT}
,
{0, 0, 0}
};
@ -438,6 +442,12 @@ ssvshost_cmd (const char *who, const char *vhost)
return 0;
}
int
sinvite_cmd (const char *from, const char *to, const char *chan) {
sts (":%s INVITE %s %s", from, to, chan);
return 1;
}
int
ssvinfo_cmd ()
{
@ -814,7 +824,7 @@ Usr_Away (char *origin, char **argv, int argc)
} else {
buf = NULL;
}
Do_Away (u, buf);
UserAway (u, buf);
if (argc > 0) {
free (buf);
}
@ -838,7 +848,7 @@ Usr_Topic (char *origin, char **argv, int argc)
c = findchan (argv[0]);
if (c) {
buf = joinbuf (argv, argc, 2);
Change_Topic (argv[1], c, atoi (argv[2]), buf);
ChangeTopic (argv[1], c, atoi (argv[2]), buf);
free (buf);
} else {
nlog (LOG_WARNING, LOG_CORE, "Ehhh, Can't find Channel %s", argv[0]);
@ -898,7 +908,7 @@ Srv_Netinfo (char *origin, char **argv, int argc)
strlcpy (me.netname, argv[7], MAXPASS);
init_ServBot ();
globops (me.name, "Link with Network \2Complete!\2");
Module_Event (EVENT_NETINFO, NULL, 0);
ModuleEvent (EVENT_NETINFO, NULL, 0);
me.synced = 1;
}
@ -979,7 +989,7 @@ Srv_Tburst (char *origin, char **argv, int argc)
c = findchan (argv[1]);
if (c) {
buf = joinbuf (argv, argc, 4);
Change_Topic (argv[3], c, atoi (argv[2]), buf);
ChangeTopic (argv[3], c, atoi (argv[2]), buf);
free (buf);
} else {
nlog (LOG_WARNING, LOG_CORE, "TopicBurst: Ehhh, Can't find Channel %s", argv[1]);

View file

@ -22,14 +22,18 @@
*/
#ifndef HYBRID7_H
#define HYBRID7_H
#ifndef NEOIRCD_H
#define NEOIRCD_H
/* we have vhost support */
#define GOTSVSVHOST
#define GOTSVSJOIN
/* Moved from connectserv so we can use elsewhere */
#define LOCOP_MODE 'O'
#define OPER_MODE 'o'
#define SERVERADMIN_MODE 'a'
#define MSG_EOB "EOB" /* end of burst */
#define MSG_PRIVATE "PRIVMSG" /* PRIV */
@ -300,6 +304,7 @@ extern int seob_cmd (const char *server);
extern int sakill_cmd (const char *host, const char *ident, const char *setby, const int length, const char *reason, ...);
extern int srakill_cmd (const char *host, const char *ident);
extern int SignOn_NewBot (const char *, const char *, const char *, const char *, long);
extern int sinvite_cmd (const char *from, const char *to, const char *chan);
void Usr_Version (char *, char **, int argc);

View file

@ -36,9 +36,9 @@ const char *ns_help[] = {
NULL
};
const char *ns_myuser_help[] = {
const char *ns_sa_help[] = {
"",
"Additional commands for Service Roots",
"Additional commands for Service Admins",
"",
" SHUTDOWN Shutdown NeoStats",
" RELOAD Force NeoStats to reload",
@ -49,24 +49,32 @@ const char *ns_myuser_help[] = {
#ifdef USE_RAW
" RAW Send a raw command from this Server",
#endif
" JUPE Jupiter a Server",
NULL
};
const char *ns_sr_help[] = {
"",
"Additional commands for Service Roots",
"",
" JUPE Jupiter a Server",
" DEBUG Toggles debug mode",
" USERDUMP Debug user table",
" CHANDUMP Debug channel table",
" SERVERDUMP Debug server table",
" MODBOTLIST List of current module bots",
" MODSOCKLIST List of current module sockets",
" MODTIMERLIST List of current module timers",
" MODBOTCHANLIST List of current module bot channels",
" BOTLIST List current module bots",
" SOCKLIST List current module sockets",
" TIMERLIST List current module timers",
" BOTCHANLIST List current module bot channels",
NULL
};
const char *ns_help_on_help[] = {
"",
"To use a command, type",
" \2/msg NeoStats command\2",
"For for more information on a command, type",
" \2/msg NeoStats HELP command\2.",
"To use a command, type",
" \2/msg NeoStats command\2",
"For for more information on a command, type",
" \2/msg NeoStats HELP command\2.",
NULL
};
@ -127,7 +135,7 @@ const char *ns_modlist_help[] = {
};
const char *ns_debug_help[] = {
"Syntax: \2DEBUG\2",
"Syntax: \2DEBUG <ON|OFF>\2",
"",
"Toggles debug mode. When enabled, debugging information is",
"sent to the services channel.",
@ -185,6 +193,7 @@ const char *ns_serverdump_help[] = {
};
const char *ns_chandump_help[] = {
"Syntax: \2CHANDUMP\2",
"Syntax: \2CHANDUMP <channel>\2",
"",
"When in debug mode, Neostats will echo its channel table to",
@ -201,32 +210,32 @@ const char *ns_logs_help[] = {
NULL
};
const char *ns_modbotlist_help[] = {
"Syntax: \2MODBOTLIST\2",
const char *ns_botlist_help[] = {
"Syntax: \2BOTLIST\2",
"",
"NeoStats will send you by notice a list of the current bots",
"being used on the network for each module.",
NULL
};
const char *ns_modsocklist_help[] = {
"Syntax: \2MODSOCKLIST\2",
const char *ns_socklist_help[] = {
"Syntax: \2SOCKLIST\2",
"",
"NeoStats will send you by notice a list of the current",
"sockets being used on the network for each module.",
NULL
};
const char *ns_modtimerlist_help[] = {
"Syntax: \2MODTIMERLIST\2",
const char *ns_timerlist_help[] = {
"Syntax: \2TIMERLIST\2",
"",
"NeoStats will send you by notice a list of the current",
"timer functions being used on the network by each module.",
NULL
};
const char *ns_modbotchanlist_help[] = {
"Syntax: \2MODBOTCHANLIST\2",
const char *ns_botchanlist_help[] = {
"Syntax: \2BOTCHANLIST\2",
"",
"NeoStats will send you by notice a list of the current bots",
"and the channels they are using for each module.",

54
ns_help.h Normal file
View file

@ -0,0 +1,54 @@
/* NeoStats - IRC Statistical Services
** Copyright (c) 1999-2003 Adam Rutter, Justin Hammond, Mark Hetherington
** http://www.neostats.net/
**
** 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
#ifndef _NS_HELP_H_
#define _NS_HELP_H_
/* ns_help.c */
extern const char *ns_help[];
extern const char *ns_help_on_help[];
extern const char *ns_sa_help[];
extern const char *ns_sr_help[];
extern const char *ns_shutdown_help[];
extern const char *ns_reload_help[];
extern const char *ns_logs_help[];
#ifdef USE_RAW
extern const char *ns_raw_help[];
#endif
extern const char *ns_debug_help[];
extern const char *ns_userdump_help[];
extern const char *ns_chandump_help[];
extern const char *ns_serverdump_help[];
extern const char *ns_version_help[];
extern const char *ns_load_help[];
extern const char *ns_unload_help[];
extern const char *ns_modlist_help[];
extern const char *ns_jupe_help[];
extern const char *ns_level_help[];
extern const char *ns_botlist_help[];
extern const char *ns_socklist_help[];
extern const char *ns_timerlist_help[];
extern const char *ns_botchanlist_help[];
extern const char *ns_info_help[];
#endif /* _NS_HELP_H_ */

56
numeric.h Executable file
View file

@ -0,0 +1,56 @@
/* NeoStats - IRC Statistical Services
** Copyright (c) 1999-2003 Adam Rutter, Justin Hammond
** http://www.neostats.net/
**
** Portions Copyright (c) 2000-2001 ^Enigma^
**
** 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
#ifndef _NUMERIC_H_
#define _NUMERIC_H_
/* Numeric used by NeoStats. Need to be in ircd code eventually
*
*/
#define RPL_STATSLINKINFO 211
#define RPL_STATSCOMMANDS 212
#define RPL_STATSCLINE 213
#define RPL_STATSOLDNLINE 214
#define RPL_STATSNLINE RPL_STATSOLDNLINE
#define RPL_ENDOFSTATS 219
#define RPL_STATSLLINE 241
#define RPL_STATSUPTIME 242
#define RPL_STATSOLINE 243
#define RPL_ADMINME 256
#define RPL_ADMINLOC1 257
#define RPL_ADMINLOC2 258
#define RPL_VERSION 351
#define RPL_MOTD 372
#define RPL_MOTDSTART 375
#define RPL_ENDOFMOTD 376
#endif /* _NUMERIC_H_ */

54
pcre/COPYING Normal file
View file

@ -0,0 +1,54 @@
PCRE LICENCE
------------
PCRE is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Written by: Philip Hazel <ph10@cam.ac.uk>
University of Cambridge Computing Service,
Cambridge, England. Phone: +44 1223 334714.
Copyright (c) 1997-2001 University of Cambridge
Permission is granted to anyone to use this software for any purpose on any
computer system, and to redistribute it freely, subject to the following
restrictions:
1. This software 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.
2. The origin of this software must not be misrepresented, either by
explicit claim or by omission. In practice, this means that if you use
PCRE in software that you distribute to others, commercially or
otherwise, you must put a sentence like this
Regular expression support is provided by the PCRE library package,
which is open source software, written by Philip Hazel, and copyright
by the University of Cambridge, England.
somewhere reasonably visible in your documentation and in any relevant
files or online help data or similar. A reference to the ftp site for
the source, that is, to
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
should also be given in the documentation. However, this condition is not
intended to apply to whole chains of software. If package A includes PCRE,
it must acknowledge it, but if package B is software that includes package
A, the condition is not imposed on package B (unless it uses PCRE
independently).
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software.
4. If PCRE is embedded in any software that is released under the GNU
General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
then the terms of that licence shall supersede any condition above with
which it is incompatible.
The documentation for PCRE, supplied in the "doc" directory, is distributed
under the same terms as the software itself.
End

37
pcre/Makefile.in Normal file
View file

@ -0,0 +1,37 @@
#PCRE Makefile
CC=@CC@
CFLAGS=-I.. @CFLAGS@
LDFLAGS= @LDFLAGS@
INCLUDES=-I.. -I.
SOURCES= get.c pcre.c study.c
OBJECTS= get.o pcre.o study.o
DOCS=README.pcre COPYING
all: ${OBJECTS}
.c.o:
$(CC) -c $(CFLAGS) $(INCLUDES) $<
dftables.o: dftables.c maketables.c internal.h ../pcre.h config.h Makefile
$(CC) -c $(CFLAGS) $(INCLUDES) dftables.c
dftables: dftables.o
$(CC) $(LDFLAGS) dftables.o -o dftables
chartables.c: dftables
./dftables >./chartables.c
clean:
/bin/rm -rf *.o Makefile dftables ../pcre.h chartables.c config.h
install:
dist:
$(OBJECTS): Makefile
pcre.o: chartables.c ../pcre.h internal.h ../config.h
get.o: ../pcre.h internal.h ../config.h
study.o: ../pcre.h internal.h ../config.h
dftables.o: ../pcre.h internal.h ../config.h

364
pcre/README Normal file
View file

@ -0,0 +1,364 @@
NOTE:
This is a stripped down version of libpcre for NeoStats. Only the files
required for NeoStats are included in this distribution. IT IS NOT A FULL
COPY OF libpcre. You can obtain full copies of libpcre from www.pcre.org
Original Readme Follows:
README file for PCRE (Perl-compatible regular expression library)
-----------------------------------------------------------------
The latest release of PCRE is always available from
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz
Please read the NEWS file if you are upgrading from a previous release.
PCRE has its own native API, but a set of "wrapper" functions that are based on
the POSIX API are also supplied in the library libpcreposix. Note that this
just provides a POSIX calling interface to PCRE: the regular expressions
themselves still follow Perl syntax and semantics. The header file
for the POSIX-style functions is called pcreposix.h. The official POSIX name is
regex.h, but I didn't want to risk possible problems with existing files of
that name by distributing it that way. To use it with an existing program that
uses the POSIX API, it will have to be renamed or pointed at by a link.
Contributions by users of PCRE
------------------------------
You can find contributions from PCRE users in the directory
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib
where there is also a README file giving brief descriptions of what they are.
Several of them provide support for compiling PCRE on various flavours of
Windows systems (I myself do not use Windows). Some are complete in themselves;
others are pointers to URLs containing relevant files.
Building PCRE on a Unix-like system
-----------------------------------
To build PCRE on a Unix-like system, first run the "configure" command from the
PCRE distribution directory, with your current directory set to the directory
where you want the files to be created. This command is a standard GNU
"autoconf" configuration script, for which generic instructions are supplied in
INSTALL.
Most commonly, people build PCRE within its own distribution directory, and in
this case, on many systems, just running "./configure" is sufficient, but the
usual methods of changing standard defaults are available. For example,
CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local
specifies that the C compiler should be run with the flags '-O2 -Wall' instead
of the default, and that "make install" should install PCRE under /opt/local
instead of the default /usr/local.
If you want to build in a different directory, just run "configure" with that
directory as current. For example, suppose you have unpacked the PCRE source
into /source/pcre/pcre-xxx, but you want to build it in /build/pcre/pcre-xxx:
cd /build/pcre/pcre-xxx
/source/pcre/pcre-xxx/configure
There are some optional features that can be included or omitted from the PCRE
library. You can read more about them in the pcrebuild man page.
. If you want to make use of the support for UTF-8 character strings in PCRE,
you must add --enable-utf8 to the "configure" command. Without it, the code
for handling UTF-8 is not included in the library. (Even when included, it
still has to be enabled by an option at run time.)
. You can build PCRE to recognized CR or NL as the newline character, instead
of whatever your compiler uses for "\n", by adding --newline-is-cr or
--newline-is-nl to the "configure" command, respectively. Only do this if you
really understand what you are doing. On traditional Unix-like systems, the
newline character is NL.
. When called via the POSIX interface, PCRE uses malloc() to get additional
storage for processing capturing parentheses if there are more than 10 of
them. You can increase this threshold by setting, for example,
--with-posix-malloc-threshold=20
on the "configure" command.
. PCRE has a counter which can be set to limit the amount of resources it uses.
If the limit is exceeded during a match, the match fails. The default is ten
million. You can change the default by setting, for example,
--with-match-limit=500000
on the "configure" command. This is just the default; individual calls to
pcre_exec() can supply their own value. There is discussion on the pcreapi
man page.
. The default maximum compiled pattern size is around 64K. You can increase
this by adding --with-link-size=3 to the "configure" command. You can
increase it even more by setting --with-link-size=4, but this is unlikely
ever to be necessary. If you build PCRE with an increased link size, test 2
(and 5 if you are using UTF-8) will fail. Part of the output of these tests
is a representation of the compiled pattern, and this changes with the link
size.
The "configure" script builds five files:
. libtool is a script that builds shared and/or static libraries
. Makefile is built by copying Makefile.in and making substitutions.
. config.h is built by copying config.in and making substitutions.
. pcre-config is built by copying pcre-config.in and making substitutions.
. RunTest is a script for running tests
Once "configure" has run, you can run "make". It builds two libraries called
libpcre and libpcreposix, a test program called pcretest, and the pcregrep
command. You can use "make install" to copy these, the public header files
pcre.h and pcreposix.h, and the man pages to appropriate live directories on
your system, in the normal way.
Running "make install" also installs the command pcre-config, which can be used
to recall information about the PCRE configuration and installation. For
example,
pcre-config --version
prints the version number, and
pcre-config --libs
outputs information about where the library is installed. This command can be
included in makefiles for programs that use PCRE, saving the programmer from
having to remember too many details.
Cross-compiling PCRE on a Unix-like system
------------------------------------------
PCRE needs to compile and run an auxiliary program as part of the building
process. Obviously, if the real compilation is for some other system, it can't
use the same CC and CFLAGS values when it is doing this. For cross compilation,
therefore, you must set CC_FOR_BUILD to the local host's compiler, and you can
set flags in CFLAGS_FOR_BUILD if you need to.
Shared libraries on Unix-like systems
-------------------------------------
The default distribution builds PCRE as two shared libraries and two static
libraries, as long as the operating system supports shared libraries. Shared
library support relies on the "libtool" script which is built as part of the
"configure" process.
The libtool script is used to compile and link both shared and static
libraries. They are placed in a subdirectory called .libs when they are newly
built. The programs pcretest and pcregrep are built to use these uninstalled
libraries (by means of wrapper scripts in the case of shared libraries). When
you use "make install" to install shared libraries, pcregrep and pcretest are
automatically re-built to use the newly installed shared libraries before being
installed themselves. However, the versions left in the source directory still
use the uninstalled libraries.
To build PCRE using static libraries only you must use --disable-shared when
configuring it. For example
./configure --prefix=/usr/gnu --disable-shared
Then run "make" in the usual way. Similarly, you can use --disable-static to
build only shared libraries.
Cross-compiling on a Unix-like system
-------------------------------------
You can specify CC and CFLAGS in the normal way to the "configure" command, in
order to cross-compile PCRE for some other host. However, during the building
process, the dftables.c source file is compiled *and run* on the local host, in
order to generate the default character tables (the chartables.c file). It
therefore needs to be compiled with the local compiler, not the cross compiler.
You can do this by specifying HOST_CC (and if necessary HOST_CFLAGS) when
calling the "configure" command. If they are not specified, they default to the
values of CC and CFLAGS.
Building on non-Unix systems
----------------------------
For a non-Unix system, read the comments in the file NON-UNIX-USE. PCRE has
been compiled on Windows systems and on Macintoshes, but I don't know the
details because I don't use those systems. It should be straightforward to
build PCRE on any system that has a Standard C compiler, because it uses only
Standard C functions.
Testing PCRE
------------
To test PCRE on a Unix system, run the RunTest script that is created by the
configuring process. (This can also be run by "make runtest", "make check", or
"make test".) For other systems, see the instruction in NON-UNIX-USE.
The script runs the pcretest test program (which is documented in its own man
page) on each of the testinput files (in the testdata directory) in turn,
and compares the output with the contents of the corresponding testoutput file.
A file called testtry is used to hold the output from pcretest. To run pcretest
on just one of the test files, give its number as an argument to RunTest, for
example:
RunTest 2
The first file can also be fed directly into the perltest script to check that
Perl gives the same results. The only difference you should see is in the first
few lines, where the Perl version is given instead of the PCRE version.
The second set of tests check pcre_fullinfo(), pcre_info(), pcre_study(),
pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error
detection, and run-time flags that are specific to PCRE, as well as the POSIX
wrapper API. It also uses the debugging flag to check some of the internals of
pcre_compile().
If you build PCRE with a locale setting that is not the standard C locale, the
character tables may be different (see next paragraph). In some cases, this may
cause failures in the second set of tests. For example, in a locale where the
isprint() function yields TRUE for characters in the range 128-255, the use of
[:isascii:] inside a character class defines a different set of characters, and
this shows up in this test as a difference in the compiled code, which is being
listed for checking. Where the comparison test output contains [\x00-\x7f] the
test will contain [\x00-\xff], and similarly in some other cases. This is not a
bug in PCRE.
The third set of tests checks pcre_maketables(), the facility for building a
set of character tables for a specific locale and using them instead of the
default tables. The tests make use of the "fr" (French) locale. Before running
the test, the script checks for the presence of this locale by running the
"locale" command. If that command fails, or if it doesn't include "fr" in the
list of available locales, the third test cannot be run, and a comment is
output to say why. If running this test produces instances of the error
** Failed to set locale "fr"
in the comparison output, it means that locale is not available on your system,
despite being listed by "locale". This does not mean that PCRE is broken.
The fourth test checks the UTF-8 support. It is not run automatically unless
PCRE is built with UTF-8 support. To do this you must set --enable-utf8 when
running "configure". This file can be also fed directly to the perltest script,
provided you are running Perl 5.8 or higher. (For Perl 5.6, a small patch,
commented in the script, can be be used.)
The fifth and final file tests error handling with UTF-8 encoding, and internal
UTF-8 features of PCRE that are not relevant to Perl.
Character tables
----------------
PCRE uses four tables for manipulating and identifying characters. The final
argument of the pcre_compile() function is a pointer to a block of memory
containing the concatenated tables. A call to pcre_maketables() can be used to
generate a set of tables in the current locale. If the final argument for
pcre_compile() is passed as NULL, a set of default tables that is built into
the binary is used.
The source file called chartables.c contains the default set of tables. This is
not supplied in the distribution, but is built by the program dftables
(compiled from dftables.c), which uses the ANSI C character handling functions
such as isalnum(), isalpha(), isupper(), islower(), etc. to build the table
sources. This means that the default C locale which is set for your system will
control the contents of these default tables. You can change the default tables
by editing chartables.c and then re-building PCRE. If you do this, you should
probably also edit Makefile to ensure that the file doesn't ever get
re-generated.
The first two 256-byte tables provide lower casing and case flipping functions,
respectively. The next table consists of three 32-byte bit maps which identify
digits, "word" characters, and white space, respectively. These are used when
building 32-byte bit maps that represent character classes.
The final 256-byte table has bits indicating various character types, as
follows:
1 white space character
2 letter
4 decimal digit
8 hexadecimal digit
16 alphanumeric or '_'
128 regular expression metacharacter or binary zero
You should not alter the set of characters that contain the 128 bit, as that
will cause PCRE to malfunction.
Manifest
--------
The distribution should contain the following files:
(A) The actual source files of the PCRE library functions and their
headers:
dftables.c auxiliary program for building chartables.c
get.c )
maketables.c )
study.c ) source of
pcre.c ) the functions
pcreposix.c )
printint.c )
pcre.in "source" for the header for the external API; pcre.h
is built from this by "configure"
pcreposix.h header for the external POSIX wrapper API
internal.h header for internal use
config.in template for config.h, which is built by configure
(B) Auxiliary files:
AUTHORS information about the author of PCRE
ChangeLog log of changes to the code
INSTALL generic installation instructions
LICENCE conditions for the use of PCRE
COPYING the same, using GNU's standard name
Makefile.in template for Unix Makefile, which is built by configure
NEWS important changes in this release
NON-UNIX-USE notes on building PCRE on non-Unix systems
README this file
RunTest.in template for a Unix shell script for running tests
config.guess ) files used by libtool,
config.sub ) used only when building a shared library
configure a configuring shell script (built by autoconf)
configure.in the autoconf input used to build configure
doc/Tech.Notes notes on the encoding
doc/*.3 man page sources for the PCRE functions
doc/*.1 man page sources for pcregrep and pcretest
doc/html/* HTML documentation
doc/pcre.txt plain text version of the man pages
doc/pcretest.txt plain text documentation of test program
doc/perltest.txt plain text documentation of Perl test program
install-sh a shell script for installing files
ltmain.sh file used to build a libtool script
pcretest.c comprehensive test program
pcredemo.c simple demonstration of coding calls to PCRE
perltest Perl test program
pcregrep.c source of a grep utility that uses PCRE
pcre-config.in source of script which retains PCRE information
testdata/testinput1 test data, compatible with Perl
testdata/testinput2 test data for error messages and non-Perl things
testdata/testinput3 test data for locale-specific tests
testdata/testinput4 test data for UTF-8 tests compatible with Perl
testdata/testinput5 test data for other UTF-8 tests
testdata/testoutput1 test results corresponding to testinput1
testdata/testoutput2 test results corresponding to testinput2
testdata/testoutput3 test results corresponding to testinput3
testdata/testoutput4 test results corresponding to testinput4
testdata/testoutput5 test results corresponding to testinput5
(C) Auxiliary files for Win32 DLL
dll.mk
pcre.def
(D) Auxiliary file for VPASCAL
makevp.bat
Philip Hazel <ph10@cam.ac.uk>
February 2003

61
pcre/config.h.in Normal file
View file

@ -0,0 +1,61 @@
/* define this to enable debug code for this module */
#undef DEBUG
/* Define to empty if the keyword does not work. */
#undef const
/* Define to `unsigned' if <stddef.h> doesn't define size_t. */
#undef size_t
/* The following two definitions are mainly for the benefit of SunOS4, which
doesn't have the strerror() or memmove() functions that should be present in
all Standard C libraries. The macros HAVE_STRERROR and HAVE_MEMMOVE should
normally be defined with the value 1 for other systems, but unfortunately we
can't make this the default because "configure" files generated by autoconf
will only change 0 to 1; they won't change 1 to 0 if the functions are not
found. */
#define HAVE_STRERROR 0
#define HAVE_MEMMOVE 0
/* There are some non-Unix systems that don't even have bcopy(). If this macro
is false, an emulation is used. If HAVE_MEMMOVE is set to 1, the value of
HAVE_BCOPY is not relevant. */
#define HAVE_BCOPY 0
/* The value of NEWLINE determines the newline character. The default is to
leave it up to the compiler, but some sites want to force a particular value.
On Unix systems, "configure" can be used to override this default. */
#ifndef NEWLINE
#define NEWLINE '\n'
#endif
/* The value of LINK_SIZE determines the number of bytes used to store
links as offsets within the compiled regex. The default is 2, which allows for
compiled patterns up to 64K long. This covers the vast majority of cases.
However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for
longer patterns in extreme cases. On Unix systems, "configure" can be used to
override this default. */
#ifndef LINK_SIZE
#define LINK_SIZE 2
#endif
/* The value of MATCH_LIMIT determines the default number of times the match()
function can be called during a single execution of pcre_exec(). (There is a
runtime method of setting a different limit.) The limit exists in order to
catch runaway regular expressions that take for ever to determine that they do
not match. The default is set very large so that it does not accidentally catch
legitimate cases. On Unix systems, "configure" can be used to override this
default default. */
#ifndef MATCH_LIMIT
#define MATCH_LIMIT 10000000
#endif
#undef POSIX_MALLOC_THRESHOLD
#undef HAVE_CRYPT_H

152
pcre/dftables.c Normal file
View file

@ -0,0 +1,152 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/*
PCRE is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Written by: Philip Hazel <ph10@cam.ac.uk>
Copyright (c) 1997-2001 University of Cambridge
-----------------------------------------------------------------------------
Permission is granted to anyone to use this software for any purpose on any
computer system, and to redistribute it freely, subject to the following
restrictions:
1. This software 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.
2. The origin of this software must not be misrepresented, either by
explicit claim or by omission.
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software.
4. If PCRE is embedded in any software that is released under the GNU
General Purpose Licence (GPL), then the terms of that licence shall
supersede any condition above with which it is incompatible.
-----------------------------------------------------------------------------
See the file Tech.Notes for some information on the internals.
*/
/* This is a support program to generate the file chartables.c, containing
character tables of various kinds. They are built according to the default C
locale and used as the default tables by PCRE. Now that pcre_maketables is
a function visible to the outside world, we make use of its code from here in
order to be consistent. */
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "internal.h"
#define DFTABLES /* maketables.c notices this */
#include "maketables.c"
int main(void)
{
int i;
const unsigned char *tables = pcre_maketables();
/* There are two printf() calls here, because gcc in pedantic mode complains
about the very long string otherwise. */
printf(
"/*************************************************\n"
"* Perl-Compatible Regular Expressions *\n"
"*************************************************/\n\n"
"/* This file is automatically written by the dftables auxiliary \n"
"program. If you edit it by hand, you might like to edit the Makefile to \n"
"prevent its ever being regenerated.\n\n");
printf(
"This file is #included in the compilation of pcre.c to build the default\n"
"character tables which are used when no tables are passed to the compile\n"
"function. */\n\n"
"static unsigned char pcre_default_tables[] = {\n\n"
"/* This table is a lower casing table. */\n\n");
printf(" ");
for (i = 0; i < 256; i++)
{
if ((i & 7) == 0 && i != 0) printf("\n ");
printf("%3d", *tables++);
if (i != 255) printf(",");
}
printf(",\n\n");
printf("/* This table is a case flipping table. */\n\n");
printf(" ");
for (i = 0; i < 256; i++)
{
if ((i & 7) == 0 && i != 0) printf("\n ");
printf("%3d", *tables++);
if (i != 255) printf(",");
}
printf(",\n\n");
printf(
"/* This table contains bit maps for various character classes.\n"
"Each map is 32 bytes long and the bits run from the least\n"
"significant end of each byte. The classes that have their own\n"
"maps are: space, xdigit, digit, upper, lower, word, graph\n"
"print, punct, and cntrl. Other classes are built from combinations. */\n\n");
printf(" ");
for (i = 0; i < cbit_length; i++)
{
if ((i & 7) == 0 && i != 0)
{
if ((i & 31) == 0) printf("\n");
printf("\n ");
}
printf("0x%02x", *tables++);
if (i != cbit_length - 1) printf(",");
}
printf(",\n\n");
printf(
"/* This table identifies various classes of character by individual bits:\n"
" 0x%02x white space character\n"
" 0x%02x letter\n"
" 0x%02x decimal digit\n"
" 0x%02x hexadecimal digit\n"
" 0x%02x alphanumeric or '_'\n"
" 0x%02x regular expression metacharacter or binary zero\n*/\n\n",
ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word,
ctype_meta);
printf(" ");
for (i = 0; i < 256; i++)
{
if ((i & 7) == 0 && i != 0)
{
printf(" /* ");
if (isprint(i-8)) printf(" %c -", i-8);
else printf("%3d-", i-8);
if (isprint(i-1)) printf(" %c ", i-1);
else printf("%3d", i-1);
printf(" */\n ");
}
printf("0x%02x", *tables++);
if (i != 255) printf(",");
}
printf("};/* ");
if (isprint(i-8)) printf(" %c -", i-8);
else printf("%3d-", i-8);
if (isprint(i-1)) printf(" %c ", i-1);
else printf("%3d", i-1);
printf(" */\n\n/* End of chartables.c */\n");
return 0;
}
/* End of dftables.c */

349
pcre/get.c Normal file
View file

@ -0,0 +1,349 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/*
This is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language. See
the file Tech.Notes for some information on the internals.
Written by: Philip Hazel <ph10@cam.ac.uk>
Copyright (c) 1997-2003 University of Cambridge
-----------------------------------------------------------------------------
Permission is granted to anyone to use this software for any purpose on any
computer system, and to redistribute it freely, subject to the following
restrictions:
1. This software 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.
2. The origin of this software must not be misrepresented, either by
explicit claim or by omission.
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software.
4. If PCRE is embedded in any software that is released under the GNU
General Purpose Licence (GPL), then the terms of that licence shall
supersede any condition above with which it is incompatible.
-----------------------------------------------------------------------------
*/
/* This module contains some convenience functions for extracting substrings
from the subject string after a regex match has succeeded. The original idea
for these functions came from Scott Wimer <scottw@cgibuilder.com>. */
/* Include the internals header, which itself includes Standard C headers plus
the external pcre header. */
#include "internal.h"
/*************************************************
* Find number for named string *
*************************************************/
/* This function is used by the two extraction functions below, as well
as being generally available.
Arguments:
code the compiled regex
stringname the name whose number is required
Returns: the number of the named parentheses, or a negative number
(PCRE_ERROR_NOSUBSTRING) if not found
*/
int
pcre_get_stringnumber(const pcre *code, const char *stringname)
{
int rc;
int entrysize;
int top, bot;
uschar *nametable;
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
return rc;
if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
return rc;
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
return rc;
bot = 0;
while (top > bot)
{
int mid = (top + bot) / 2;
uschar *entry = nametable + entrysize*mid;
int c = strcmp(stringname, (char *)(entry + 2));
if (c == 0) return (entry[0] << 8) + entry[1];
if (c > 0) bot = mid + 1; else top = mid;
}
return PCRE_ERROR_NOSUBSTRING;
}
/*************************************************
* Copy captured string to given buffer *
*************************************************/
/* This function copies a single captured substring into a given buffer.
Note that we use memcpy() rather than strncpy() in case there are binary zeros
in the string.
Arguments:
subject the subject string that was matched
ovector pointer to the offsets table
stringcount the number of substrings that were captured
(i.e. the yield of the pcre_exec call, unless
that was zero, in which case it should be 1/3
of the offset table size)
stringnumber the number of the required substring
buffer where to put the substring
size the size of the buffer
Returns: if successful:
the length of the copied string, not including the zero
that is put on the end; can be zero
if not successful:
PCRE_ERROR_NOMEMORY (-6) buffer too small
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
*/
int
pcre_copy_substring(const char *subject, int *ovector, int stringcount,
int stringnumber, char *buffer, int size)
{
int yield;
if (stringnumber < 0 || stringnumber >= stringcount)
return PCRE_ERROR_NOSUBSTRING;
stringnumber *= 2;
yield = ovector[stringnumber+1] - ovector[stringnumber];
if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
memcpy(buffer, subject + ovector[stringnumber], yield);
buffer[yield] = 0;
return yield;
}
/*************************************************
* Copy named captured string to given buffer *
*************************************************/
/* This function copies a single captured substring into a given buffer,
identifying it by name.
Arguments:
code the compiled regex
subject the subject string that was matched
ovector pointer to the offsets table
stringcount the number of substrings that were captured
(i.e. the yield of the pcre_exec call, unless
that was zero, in which case it should be 1/3
of the offset table size)
stringname the name of the required substring
buffer where to put the substring
size the size of the buffer
Returns: if successful:
the length of the copied string, not including the zero
that is put on the end; can be zero
if not successful:
PCRE_ERROR_NOMEMORY (-6) buffer too small
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
*/
int
pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,
int stringcount, const char *stringname, char *buffer, int size)
{
int n = pcre_get_stringnumber(code, stringname);
if (n <= 0) return n;
return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
}
/*************************************************
* Copy all captured strings to new store *
*************************************************/
/* This function gets one chunk of store and builds a list of pointers and all
of the captured substrings in it. A NULL pointer is put on the end of the list.
Arguments:
subject the subject string that was matched
ovector pointer to the offsets table
stringcount the number of substrings that were captured
(i.e. the yield of the pcre_exec call, unless
that was zero, in which case it should be 1/3
of the offset table size)
listptr set to point to the list of pointers
Returns: if successful: 0
if not successful:
PCRE_ERROR_NOMEMORY (-6) failed to get store
*/
int
pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
const char ***listptr)
{
int i;
int size = sizeof(char *);
int double_count = stringcount * 2;
char **stringlist;
char *p;
for (i = 0; i < double_count; i += 2)
size += sizeof(char *) + ovector[i+1] - ovector[i] + 1;
stringlist = (char **)(pcre_malloc)(size);
if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
*listptr = (const char **)stringlist;
p = (char *)(stringlist + stringcount + 1);
for (i = 0; i < double_count; i += 2)
{
int len = ovector[i+1] - ovector[i];
memcpy(p, subject + ovector[i], len);
*stringlist++ = p;
p += len;
*p++ = 0;
}
*stringlist = NULL;
return 0;
}
/*************************************************
* Free store obtained by get_substring_list *
*************************************************/
/* This function exists for the benefit of people calling PCRE from non-C
programs that can call its functions, but not free() or (pcre_free)() directly.
Argument: the result of a previous pcre_get_substring_list()
Returns: nothing
*/
void
pcre_free_substring_list(const char **pointer)
{
(pcre_free)((void *)pointer);
}
/*************************************************
* Copy captured string to new store *
*************************************************/
/* This function copies a single captured substring into a piece of new
store
Arguments:
subject the subject string that was matched
ovector pointer to the offsets table
stringcount the number of substrings that were captured
(i.e. the yield of the pcre_exec call, unless
that was zero, in which case it should be 1/3
of the offset table size)
stringnumber the number of the required substring
stringptr where to put a pointer to the substring
Returns: if successful:
the length of the string, not including the zero that
is put on the end; can be zero
if not successful:
PCRE_ERROR_NOMEMORY (-6) failed to get store
PCRE_ERROR_NOSUBSTRING (-7) substring not present
*/
int
pcre_get_substring(const char *subject, int *ovector, int stringcount,
int stringnumber, const char **stringptr)
{
int yield;
char *substring;
if (stringnumber < 0 || stringnumber >= stringcount)
return PCRE_ERROR_NOSUBSTRING;
stringnumber *= 2;
yield = ovector[stringnumber+1] - ovector[stringnumber];
substring = (char *)(pcre_malloc)(yield + 1);
if (substring == NULL) return PCRE_ERROR_NOMEMORY;
memcpy(substring, subject + ovector[stringnumber], yield);
substring[yield] = 0;
*stringptr = substring;
return yield;
}
/*************************************************
* Copy named captured string to new store *
*************************************************/
/* This function copies a single captured substring, identified by name, into
new store.
Arguments:
code the compiled regex
subject the subject string that was matched
ovector pointer to the offsets table
stringcount the number of substrings that were captured
(i.e. the yield of the pcre_exec call, unless
that was zero, in which case it should be 1/3
of the offset table size)
stringname the name of the required substring
stringptr where to put the pointer
Returns: if successful:
the length of the copied string, not including the zero
that is put on the end; can be zero
if not successful:
PCRE_ERROR_NOMEMORY (-6) couldn't get memory
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
*/
int
pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,
int stringcount, const char *stringname, const char **stringptr)
{
int n = pcre_get_stringnumber(code, stringname);
if (n <= 0) return n;
return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
}
/*************************************************
* Free store obtained by get_substring *
*************************************************/
/* This function exists for the benefit of people calling PCRE from non-C
programs that can call its functions, but not free() or (pcre_free)() directly.
Argument: the result of a previous pcre_get_substring()
Returns: nothing
*/
void
pcre_free_substring(const char *pointer)
{
(pcre_free)((void *)pointer);
}
/* End of get.c */

662
pcre/internal.h Normal file
View file

@ -0,0 +1,662 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/* This is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language. See
the file Tech.Notes for some information on the internals.
Written by: Philip Hazel <ph10@cam.ac.uk>
Copyright (c) 1997-2003 University of Cambridge
-----------------------------------------------------------------------------
Permission is granted to anyone to use this software for any purpose on any
computer system, and to redistribute it freely, subject to the following
restrictions:
1. This software 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.
2. The origin of this software must not be misrepresented, either by
explicit claim or by omission.
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software.
4. If PCRE is embedded in any software that is released under the GNU
General Purpose Licence (GPL), then the terms of that licence shall
supersede any condition above with which it is incompatible.
-----------------------------------------------------------------------------
*/
/* This header contains definitions that are shared between the different
modules, but which are not relevant to the outside. */
/* Get the definitions provided by running "configure" */
#include "config.h"
/* When compiling for use with the Virtual Pascal compiler, these functions
need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
option on the command line. */
#ifdef VPCOMPAT
#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
#define memcpy(d,s,n) _memcpy(d,s,n)
#define memmove(d,s,n) _memmove(d,s,n)
#define memset(s,c,n) _memset(s,c,n)
#else /* VPCOMPAT */
/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
is set. Otherwise, include an emulating function for those systems that have
neither (there some non-Unix environments where this is the case). This assumes
that all calls to memmove are moving strings upwards in store, which is the
case in PCRE. */
#if ! HAVE_MEMMOVE
#undef memmove /* some systems may have a macro */
#if HAVE_BCOPY
#define memmove(a, b, c) bcopy(b, a, c)
#else /* HAVE_BCOPY */
void *
pcre_memmove(unsigned char *dest, const unsigned char *src, size_t n)
{
int i;
dest += n;
src += n;
for (i = 0; i < n; ++i) *(--dest) = *(--src);
}
#define memmove(a, b, c) pcre_memmove(a, b, c)
#endif /* not HAVE_BCOPY */
#endif /* not HAVE_MEMMOVE */
#endif /* not VPCOMPAT */
/* PCRE keeps offsets in its compiled code as 2-byte quantities by default.
These are used, for example, to link from the start of a subpattern to its
alternatives and its end. The use of 2 bytes per offset limits the size of the
compiled regex to around 64K, which is big enough for almost everybody.
However, I received a request for an even bigger limit. For this reason, and
also to make the code easier to maintain, the storing and loading of offsets
from the byte string is now handled by the macros that are defined here.
The macros are controlled by the value of LINK_SIZE. This defaults to 2 in
the config.h file, but can be overridden by using -D on the command line. This
is automated on Unix systems via the "configure" command. */
#if LINK_SIZE == 2
#define PUT(a,n,d) \
(a[n] = (d) >> 8), \
(a[(n)+1] = (d) & 255)
#define GET(a,n) \
(((a)[n] << 8) | (a)[(n)+1])
#define MAX_PATTERN_SIZE (1 << 16)
#elif LINK_SIZE == 3
#define PUT(a,n,d) \
(a[n] = (d) >> 16), \
(a[(n)+1] = (d) >> 8), \
(a[(n)+2] = (d) & 255)
#define GET(a,n) \
(((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
#define MAX_PATTERN_SIZE (1 << 24)
#elif LINK_SIZE == 4
#define PUT(a,n,d) \
(a[n] = (d) >> 24), \
(a[(n)+1] = (d) >> 16), \
(a[(n)+2] = (d) >> 8), \
(a[(n)+3] = (d) & 255)
#define GET(a,n) \
(((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
#else
#error LINK_SIZE must be either 2, 3, or 4
#endif
/* Convenience macro defined in terms of the others */
#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE
/* PCRE uses some other 2-byte quantities that do not change when the size of
offsets changes. There are used for repeat counts and for other things such as
capturing parenthesis numbers in back references. */
#define PUT2(a,n,d) \
a[n] = (d) >> 8; \
a[(n)+1] = (d) & 255
#define GET2(a,n) \
(((a)[n] << 8) | (a)[(n)+1])
#define PUT2INC(a,n,d) PUT2(a,n,d), a += 2
/* Standard C headers plus the external interface definition */
#include <ctype.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef PCRE_SPY
#define PCRE_DEFINITION /* Win32 __declspec(export) trigger for .dll */
#endif
#include "pcre.h"
/* In case there is no definition of offsetof() provided - though any proper
Standard C system should have one. */
#ifndef offsetof
#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
#endif
/* These are the public options that can change during matching. */
#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
/* Private options flags start at the most significant end of the four bytes,
but skip the top bit so we can use ints for convenience without getting tangled
with negative values. The public options defined in pcre.h start at the least
significant end. Make sure they don't overlap, though now that we have expanded
to four bytes there is plenty of space. */
#define PCRE_FIRSTSET 0x40000000 /* first_byte is set */
#define PCRE_REQCHSET 0x20000000 /* req_byte is set */
#define PCRE_STARTLINE 0x10000000 /* start after \n for multiline */
#define PCRE_ICHANGED 0x08000000 /* i option changes within regex */
/* Options for the "extra" block produced by pcre_study(). */
#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */
/* Masks for identifying the public options which are permitted at compile
time, run time or study time, respectively. */
#define PUBLIC_OPTIONS \
(PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
PCRE_NO_AUTO_CAPTURE)
#define PUBLIC_EXEC_OPTIONS \
(PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY)
#define PUBLIC_STUDY_OPTIONS 0 /* None defined */
/* Magic number to provide a small check against being handed junk. */
#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
/* Negative values for the firstchar and reqchar variables */
#define REQ_UNSET (-2)
#define REQ_NONE (-1)
/* Flags added to firstbyte or reqbyte; a "non-literal" item is either a
variable-length repeat, or a anything other than literal characters. */
#define REQ_CASELESS 0x0100 /* indicates caselessness */
#define REQ_VARY 0x0200 /* reqbyte followed non-literal item */
/* Miscellaneous definitions */
typedef int BOOL;
#define FALSE 0
#define TRUE 1
/* Escape items that are just an encoding of a particular data value. Note that
ESC_n is defined as yet another macro, which is set in config.h to either \n
(the default) or \r (which some people want). */
#ifndef ESC_e
#define ESC_e 27
#endif
#ifndef ESC_f
#define ESC_f '\f'
#endif
#ifndef ESC_n
#define ESC_n NEWLINE
#endif
#ifndef ESC_r
#define ESC_r '\r'
#endif
/* We can't officially use ESC_t because it is a POSIX reserved identifier
(presumably because of all the others like size_t). */
#ifndef ESC_tee
#define ESC_tee '\t'
#endif
/* These are escaped items that aren't just an encoding of a particular data
value such as \n. They must have non-zero values, as check_escape() returns
their negation. Also, they must appear in the same order as in the opcode
definitions below, up to ESC_z. There's a dummy for OP_ANY because it
corresponds to "." rather than an escape sequence. The final one must be
ESC_REF as subsequent values are used for \1, \2, \3, etc. There is are two
tests in the code for an escape greater than ESC_b and less than ESC_Z to
detect the types that may be repeated. These are the types that consume a
character. If any new escapes are put in between that don't consume a
character, that code will have to change. */
enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W,
ESC_w, ESC_dum1, ESC_C, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF };
/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
contain UTF-8 characters with values greater than 255. */
#define XCL_NOT 0x01 /* Flag: this is a negative class */
#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
#define XCL_END 0 /* Marks end of individual items */
#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
#define XCL_RANGE 2 /* A range (two multibyte chars) follows */
/* Opcode table: OP_BRA must be last, as all values >= it are used for brackets
that extract substrings. Starting from 1 (i.e. after OP_END), the values up to
OP_EOD must correspond in order to the list of escapes immediately above.
Note that whenever this list is updated, the two macro definitions that follow
must also be updated to match. */
enum {
OP_END, /* 0 End of pattern */
/* Values corresponding to backslashed metacharacters */
OP_SOD, /* 1 Start of data: \A */
OP_SOM, /* 2 Start of match (subject + offset): \G */
OP_NOT_WORD_BOUNDARY, /* 3 \B */
OP_WORD_BOUNDARY, /* 4 \b */
OP_NOT_DIGIT, /* 5 \D */
OP_DIGIT, /* 6 \d */
OP_NOT_WHITESPACE, /* 7 \S */
OP_WHITESPACE, /* 8 \s */
OP_NOT_WORDCHAR, /* 9 \W */
OP_WORDCHAR, /* 10 \w */
OP_ANY, /* 11 Match any character */
OP_ANYBYTE, /* 12 Match any byte (\C); different to OP_ANY for UTF-8 */
OP_EODN, /* 13 End of data or \n at end of data: \Z. */
OP_EOD, /* 14 End of data: \z */
OP_OPT, /* 15 Set runtime options */
OP_CIRC, /* 16 Start of line - varies with multiline switch */
OP_DOLL, /* 17 End of line - varies with multiline switch */
OP_CHARS, /* 18 Match string of characters */
OP_NOT, /* 19 Match anything but the following char */
OP_STAR, /* 20 The maximizing and minimizing versions of */
OP_MINSTAR, /* 21 all these opcodes must come in pairs, with */
OP_PLUS, /* 22 the minimizing one second. */
OP_MINPLUS, /* 23 This first set applies to single characters */
OP_QUERY, /* 24 */
OP_MINQUERY, /* 25 */
OP_UPTO, /* 26 From 0 to n matches */
OP_MINUPTO, /* 27 */
OP_EXACT, /* 28 Exactly n matches */
OP_NOTSTAR, /* 29 The maximizing and minimizing versions of */
OP_NOTMINSTAR, /* 30 all these opcodes must come in pairs, with */
OP_NOTPLUS, /* 31 the minimizing one second. */
OP_NOTMINPLUS, /* 32 This set applies to "not" single characters */
OP_NOTQUERY, /* 33 */
OP_NOTMINQUERY, /* 34 */
OP_NOTUPTO, /* 35 From 0 to n matches */
OP_NOTMINUPTO, /* 36 */
OP_NOTEXACT, /* 37 Exactly n matches */
OP_TYPESTAR, /* 38 The maximizing and minimizing versions of */
OP_TYPEMINSTAR, /* 39 all these opcodes must come in pairs, with */
OP_TYPEPLUS, /* 40 the minimizing one second. These codes must */
OP_TYPEMINPLUS, /* 41 be in exactly the same order as those above. */
OP_TYPEQUERY, /* 42 This set applies to character types such as \d */
OP_TYPEMINQUERY, /* 43 */
OP_TYPEUPTO, /* 44 From 0 to n matches */
OP_TYPEMINUPTO, /* 45 */
OP_TYPEEXACT, /* 46 Exactly n matches */
OP_CRSTAR, /* 47 The maximizing and minimizing versions of */
OP_CRMINSTAR, /* 48 all these opcodes must come in pairs, with */
OP_CRPLUS, /* 49 the minimizing one second. These codes must */
OP_CRMINPLUS, /* 50 be in exactly the same order as those above. */
OP_CRQUERY, /* 51 These are for character classes and back refs */
OP_CRMINQUERY, /* 52 */
OP_CRRANGE, /* 53 These are different to the three seta above. */
OP_CRMINRANGE, /* 54 */
OP_CLASS, /* 55 Match a character class, chars < 256 only */
OP_NCLASS, /* 56 Same, but the bitmap was created from a negative
class - the difference is relevant only when a UTF-8
character > 255 is encountered. */
OP_XCLASS, /* 56 Extended class for handling UTF-8 chars within the
class. This does both positive and negative. */
OP_REF, /* 57 Match a back reference */
OP_RECURSE, /* 58 Match a numbered subpattern (possibly recursive) */
OP_CALLOUT, /* 59 Call out to external function if provided */
OP_ALT, /* 60 Start of alternation */
OP_KET, /* 61 End of group that doesn't have an unbounded repeat */
OP_KETRMAX, /* 62 These two must remain together and in this */
OP_KETRMIN, /* 63 order. They are for groups the repeat for ever. */
/* The assertions must come before ONCE and COND */
OP_ASSERT, /* 64 Positive lookahead */
OP_ASSERT_NOT, /* 65 Negative lookahead */
OP_ASSERTBACK, /* 66 Positive lookbehind */
OP_ASSERTBACK_NOT, /* 67 Negative lookbehind */
OP_REVERSE, /* 68 Move pointer back - used in lookbehind assertions */
/* ONCE and COND must come after the assertions, with ONCE first, as there's
a test for >= ONCE for a subpattern that isn't an assertion. */
OP_ONCE, /* 69 Once matched, don't back up into the subpattern */
OP_COND, /* 70 Conditional group */
OP_CREF, /* 71 Used to hold an extraction string number (cond ref) */
OP_BRAZERO, /* 72 These two must remain together and in this */
OP_BRAMINZERO, /* 73 order. */
OP_BRANUMBER, /* 74 Used for extracting brackets whose number is greater
than can fit into an opcode. */
OP_BRA /* 75 This and greater values are used for brackets that
extract substrings up to a basic limit. After that,
use is made of OP_BRANUMBER. */
};
/* WARNING: There is an implicit assumption in study.c that all opcodes are
less than 128 in value. This makes handling UTF-8 character sequences easier.
*/
/* This macro defines textual names for all the opcodes. There are used only
for debugging, in pcre.c when DEBUG is defined, and also in pcretest.c. The
macro is referenced only in printint.c. */
#define OP_NAME_LIST \
"End", "\\A", "\\G", "\\B", "\\b", "\\D", "\\d", \
"\\S", "\\s", "\\W", "\\w", "Any", "Anybyte", "\\Z", "\\z", \
"Opt", "^", "$", "chars", "not", \
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
"*", "*?", "+", "+?", "?", "??", "{", "{", \
"class", "nclass", "xclass", "Ref", "Recurse", "Callout", \
"Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not", \
"AssertB", "AssertB not", "Reverse", "Once", "Cond", "Cond ref",\
"Brazero", "Braminzero", "Branumber", "Bra"
/* This macro defines the length of fixed length operations in the compiled
regex. The lengths are used when searching for specific things, and also in the
debugging printing of a compiled regex. We use a macro so that it can be
incorporated both into pcre.c and pcretest.c without being publicly exposed.
As things have been extended, some of these are no longer fixed lenths, but are
minima instead. For example, the length of a single-character repeat may vary
in UTF-8 mode. The code that uses this table must know about such things. */
#define OP_LENGTHS \
1, /* End */ \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* \A, \G, \B, \B, \D, \d, \S, \s, \W, \w */ \
1, 1, 1, 1, 2, 1, 1, /* Any, Anybyte, \Z, \z, Opt, ^, $ */ \
2, /* Chars - the minimum length */ \
2, /* not */ \
/* Positive single-char repeats */ \
2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** These are */ \
4, 4, 4, /* upto, minupto, exact ** minima */ \
/* Negative single-char repeats */ \
2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \
4, 4, 4, /* NOT upto, minupto, exact */ \
/* Positive type repeats */ \
2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \
4, 4, 4, /* Type upto, minupto, exact */ \
/* Character class & ref repeats */ \
1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
5, 5, /* CRRANGE, CRMINRANGE */ \
33, /* CLASS */ \
33, /* NCLASS */ \
0, /* XCLASS - variable length */ \
3, /* REF */ \
1+LINK_SIZE, /* RECURSE */ \
2, /* CALLOUT */ \
1+LINK_SIZE, /* Alt */ \
1+LINK_SIZE, /* Ket */ \
1+LINK_SIZE, /* KetRmax */ \
1+LINK_SIZE, /* KetRmin */ \
1+LINK_SIZE, /* Assert */ \
1+LINK_SIZE, /* Assert not */ \
1+LINK_SIZE, /* Assert behind */ \
1+LINK_SIZE, /* Assert behind not */ \
1+LINK_SIZE, /* Reverse */ \
1+LINK_SIZE, /* Once */ \
1+LINK_SIZE, /* COND */ \
3, /* CREF */ \
1, 1, /* BRAZERO, BRAMINZERO */ \
3, /* BRANUMBER */ \
1+LINK_SIZE /* BRA */ \
/* The highest extraction number before we have to start using additional
bytes. (Originally PCRE didn't have support for extraction counts highter than
this number.) The value is limited by the number of opcodes left after OP_BRA,
i.e. 255 - OP_BRA. We actually set it a bit lower to leave room for additional
opcodes. */
#define EXTRACT_BASIC_MAX 150
/* A magic value for OP_CREF to indicate the "in recursion" condition. */
#define CREF_RECURSE 0xffff
/* The texts of compile-time error messages are defined as macros here so that
they can be accessed by the POSIX wrapper and converted into error codes. Yes,
I could have used error codes in the first place, but didn't feel like changing
just to accommodate the POSIX wrapper. */
#define ERR1 "\\ at end of pattern"
#define ERR2 "\\c at end of pattern"
#define ERR3 "unrecognized character follows \\"
#define ERR4 "numbers out of order in {} quantifier"
#define ERR5 "number too big in {} quantifier"
#define ERR6 "missing terminating ] for character class"
#define ERR7 "invalid escape sequence in character class"
#define ERR8 "range out of order in character class"
#define ERR9 "nothing to repeat"
#define ERR10 "operand of unlimited repeat could match the empty string"
#define ERR11 "internal error: unexpected repeat"
#define ERR12 "unrecognized character after (?"
#define ERR13 "POSIX named classes are supported only within a class"
#define ERR14 "missing )"
#define ERR15 "reference to non-existent subpattern"
#define ERR16 "erroffset passed as NULL"
#define ERR17 "unknown option bit(s) set"
#define ERR18 "missing ) after comment"
#define ERR19 "parentheses nested too deeply"
#define ERR20 "regular expression too large"
#define ERR21 "failed to get memory"
#define ERR22 "unmatched parentheses"
#define ERR23 "internal error: code overflow"
#define ERR24 "unrecognized character after (?<"
#define ERR25 "lookbehind assertion is not fixed length"
#define ERR26 "malformed number after (?("
#define ERR27 "conditional group contains more than two branches"
#define ERR28 "assertion expected after (?("
#define ERR29 "(?R or (?digits must be followed by )"
#define ERR30 "unknown POSIX class name"
#define ERR31 "POSIX collating elements are not supported"
#define ERR32 "this version of PCRE is not compiled with PCRE_UTF8 support"
#define ERR33 "spare error"
#define ERR34 "character value in \\x{...} sequence is too large"
#define ERR35 "invalid condition (?(0)"
#define ERR36 "\\C not allowed in lookbehind assertion"
#define ERR37 "PCRE does not support \\L, \\l, \\N, \\P, \\p, \\U, \\u, or \\X"
#define ERR38 "number after (?C is > 255"
#define ERR39 "closing ) for (?C expected"
#define ERR40 "recursive call could loop indefinitely"
#define ERR41 "unrecognized character after (?P"
#define ERR42 "syntax error after (?P"
#define ERR43 "two named groups have the same name"
/* All character handling must be done as unsigned characters. Otherwise there
are problems with top-bit-set characters and functions such as isspace().
However, we leave the interface to the outside world as char *, because that
should make things easier for callers. We define a short type for unsigned char
to save lots of typing. I tried "uchar", but it causes problems on Digital
Unix, where it is defined in sys/types, so use "uschar" instead. */
typedef unsigned char uschar;
/* The real format of the start of the pcre block; the index of names and the
code vector run on as long as necessary after the end. */
typedef struct real_pcre {
unsigned long int magic_number;
size_t size; /* Total that was malloced */
const unsigned char *tables; /* Pointer to tables */
unsigned long int options;
unsigned short int top_bracket;
unsigned short int top_backref;
unsigned short int first_byte;
unsigned short int req_byte;
unsigned short int name_entry_size; /* Size of any name items; 0 => none */
unsigned short int name_count; /* Number of name items */
} real_pcre;
/* The format of the block used to store data from pcre_study(). */
typedef struct pcre_study_data {
size_t size; /* Total that was malloced */
uschar options;
uschar start_bits[32];
} pcre_study_data;
/* Structure for passing "static" information around between the functions
doing the compiling, so that they are thread-safe. */
typedef struct compile_data {
const uschar *lcc; /* Points to lower casing table */
const uschar *fcc; /* Points to case-flipping table */
const uschar *cbits; /* Points to character type table */
const uschar *ctypes; /* Points to table of type maps */
const uschar *start_code; /* The start of the compiled code */
uschar *name_table; /* The name/number table */
int names_found; /* Number of entries so far */
int name_entry_size; /* Size of each entry */
int top_backref; /* Maximum back reference */
unsigned int backref_map; /* Bitmap of low back refs */
int req_varyopt; /* "After variable item" flag for reqbyte */
} compile_data;
/* Structure for maintaining a chain of pointers to the currently incomplete
branches, for testing for left recursion. */
typedef struct branch_chain {
struct branch_chain *outer;
uschar *current;
} branch_chain;
/* Structure for items in a linked list that represents an explicit recursive
call within the pattern. */
typedef struct recursion_info {
struct recursion_info *prev; /* Previous recursion record (or NULL) */
int group_num; /* Number of group that was called */
const uschar *after_call; /* "Return value": points after the call in the expr */
const uschar *save_start; /* Old value of md->start_match */
int *offset_save; /* Pointer to start of saved offsets */
int saved_max; /* Number of saved offsets */
} recursion_info;
/* Structure for passing "static" information around between the functions
doing the matching, so that they are thread-safe. */
typedef struct match_data {
unsigned long int match_call_count; /* As it says */
unsigned long int match_limit;/* As it says */
int *offset_vector; /* Offset vector */
int offset_end; /* One past the end */
int offset_max; /* The maximum usable for return data */
const uschar *lcc; /* Points to lower casing table */
const uschar *ctypes; /* Points to table of type maps */
BOOL offset_overflow; /* Set if too many extractions */
BOOL notbol; /* NOTBOL flag */
BOOL noteol; /* NOTEOL flag */
BOOL utf8; /* UTF8 flag */
BOOL endonly; /* Dollar not before final \n */
BOOL notempty; /* Empty string match not wanted */
const uschar *start_code; /* For use when recursing */
const uschar *start_subject; /* Start of the subject string */
const uschar *end_subject; /* End of the subject string */
const uschar *start_match; /* Start of this match attempt */
const uschar *end_match_ptr; /* Subject position at end match */
int end_offset_top; /* Highwater mark at end of match */
int capture_last; /* Most recent capture number */
int start_offset; /* The start offset value */
recursion_info *recursive; /* Linked list of recursion data */
void *callout_data; /* To pass back to callouts */
} match_data;
/* Bit definitions for entries in the pcre_ctypes table. */
#define ctype_space 0x01
#define ctype_letter 0x02
#define ctype_digit 0x04
#define ctype_xdigit 0x08
#define ctype_word 0x10 /* alphameric or '_' */
#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */
/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
of bits for a class map. Some classes are built by combining these tables. */
#define cbit_space 0 /* [:space:] or \s */
#define cbit_xdigit 32 /* [:xdigit:] */
#define cbit_digit 64 /* [:digit:] or \d */
#define cbit_upper 96 /* [:upper:] */
#define cbit_lower 128 /* [:lower:] */
#define cbit_word 160 /* [:word:] or \w */
#define cbit_graph 192 /* [:graph:] */
#define cbit_print 224 /* [:print:] */
#define cbit_punct 256 /* [:punct:] */
#define cbit_cntrl 288 /* [:cntrl:] */
#define cbit_length 320 /* Length of the cbits table */
/* Offsets of the various tables from the base tables pointer, and
total length. */
#define lcc_offset 0
#define fcc_offset 256
#define cbits_offset 512
#define ctypes_offset (cbits_offset + cbit_length)
#define tables_length (ctypes_offset + 256)
/* End of internal.h */

136
pcre/maketables.c Normal file
View file

@ -0,0 +1,136 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/*
PCRE is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Written by: Philip Hazel <ph10@cam.ac.uk>
Copyright (c) 1997-2003 University of Cambridge
-----------------------------------------------------------------------------
Permission is granted to anyone to use this software for any purpose on any
computer system, and to redistribute it freely, subject to the following
restrictions:
1. This software 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.
2. The origin of this software must not be misrepresented, either by
explicit claim or by omission.
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software.
4. If PCRE is embedded in any software that is released under the GNU
General Purpose Licence (GPL), then the terms of that licence shall
supersede any condition above with which it is incompatible.
-----------------------------------------------------------------------------
See the file Tech.Notes for some information on the internals.
*/
/* This file is compiled on its own as part of the PCRE library. However,
it is also included in the compilation of dftables.c, in which case the macro
DFTABLES is defined. */
#ifndef DFTABLES
#include "internal.h"
#endif
/*************************************************
* Create PCRE character tables *
*************************************************/
/* This function builds a set of character tables for use by PCRE and returns
a pointer to them. They are build using the ctype functions, and consequently
their contents will depend upon the current locale setting. When compiled as
part of the library, the store is obtained via pcre_malloc(), but when compiled
inside dftables, use malloc().
Arguments: none
Returns: pointer to the contiguous block of data
*/
const unsigned char *
pcre_maketables(void)
{
unsigned char *yield, *p;
int i;
#ifndef DFTABLES
yield = (unsigned char*)(pcre_malloc)(tables_length);
#else
yield = (unsigned char*)malloc(tables_length);
#endif
if (yield == NULL) return NULL;
p = yield;
/* First comes the lower casing table */
for (i = 0; i < 256; i++) *p++ = tolower(i);
/* Next the case-flipping table */
for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
/* Then the character class tables. Don't try to be clever and save effort
on exclusive ones - in some locales things may be different. Note that the
table for "space" includes everything "isspace" gives, including VT in the
default locale. This makes it work for the POSIX class [:space:]. */
memset(p, 0, cbit_length);
for (i = 0; i < 256; i++)
{
if (isdigit(i))
{
p[cbit_digit + i/8] |= 1 << (i&7);
p[cbit_word + i/8] |= 1 << (i&7);
}
if (isupper(i))
{
p[cbit_upper + i/8] |= 1 << (i&7);
p[cbit_word + i/8] |= 1 << (i&7);
}
if (islower(i))
{
p[cbit_lower + i/8] |= 1 << (i&7);
p[cbit_word + i/8] |= 1 << (i&7);
}
if (i == '_') p[cbit_word + i/8] |= 1 << (i&7);
if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7);
if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7);
if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7);
if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7);
if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7);
if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7);
}
p += cbit_length;
/* Finally, the character type table. In this, we exclude VT from the white
space chars, because Perl doesn't recognize it as such for \s and for comments
within regexes. */
for (i = 0; i < 256; i++)
{
int x = 0;
if (i != 0x0b && isspace(i)) x += ctype_space;
if (isalpha(i)) x += ctype_letter;
if (isdigit(i)) x += ctype_digit;
if (isxdigit(i)) x += ctype_xdigit;
if (isalnum(i) || i == '_') x += ctype_word;
if (strchr("*+?{^.$|()[", i) != 0) x += ctype_meta;
*p++ = x;
}
return yield;
}
/* End of maketables.c */

7596
pcre/pcre.c Normal file

File diff suppressed because it is too large Load diff

184
pcre/pcre.in Normal file
View file

@ -0,0 +1,184 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/* Copyright (c) 1997-2003 University of Cambridge */
#ifndef _PCRE_H
#define _PCRE_H
/* The file pcre.h is build by "configure". Do not edit it; instead
make changes to pcre.in. */
#define PCRE_MAJOR @PCRE_MAJOR@
#define PCRE_MINOR @PCRE_MINOR@
#define PCRE_DATE @PCRE_DATE@
/* Win32 uses DLL by default */
#ifdef _WIN32
# ifdef PCRE_DEFINITION
# ifdef DLL_EXPORT
# define PCRE_DATA_SCOPE __declspec(dllexport)
# endif
# else
# ifndef PCRE_STATIC
# define PCRE_DATA_SCOPE __declspec(dllimport)
# endif
# endif
#endif
#ifndef PCRE_DATA_SCOPE
# define PCRE_DATA_SCOPE extern
#endif
/* Have to include stdlib.h in order to ensure that size_t is defined;
it is needed here for malloc. */
#include <stdlib.h>
/* Allow for C++ users */
#ifdef __cplusplus
extern "C" {
#endif
/* Options */
#define PCRE_CASELESS 0x0001
#define PCRE_MULTILINE 0x0002
#define PCRE_DOTALL 0x0004
#define PCRE_EXTENDED 0x0008
#define PCRE_ANCHORED 0x0010
#define PCRE_DOLLAR_ENDONLY 0x0020
#define PCRE_EXTRA 0x0040
#define PCRE_NOTBOL 0x0080
#define PCRE_NOTEOL 0x0100
#define PCRE_UNGREEDY 0x0200
#define PCRE_NOTEMPTY 0x0400
#define PCRE_UTF8 0x0800
#define PCRE_NO_AUTO_CAPTURE 0x1000
/* Exec-time and get/set-time error codes */
#define PCRE_ERROR_NOMATCH (-1)
#define PCRE_ERROR_NULL (-2)
#define PCRE_ERROR_BADOPTION (-3)
#define PCRE_ERROR_BADMAGIC (-4)
#define PCRE_ERROR_UNKNOWN_NODE (-5)
#define PCRE_ERROR_NOMEMORY (-6)
#define PCRE_ERROR_NOSUBSTRING (-7)
#define PCRE_ERROR_MATCHLIMIT (-8)
#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
/* Request types for pcre_fullinfo() */
#define PCRE_INFO_OPTIONS 0
#define PCRE_INFO_SIZE 1
#define PCRE_INFO_CAPTURECOUNT 2
#define PCRE_INFO_BACKREFMAX 3
#define PCRE_INFO_FIRSTBYTE 4
#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
#define PCRE_INFO_FIRSTTABLE 5
#define PCRE_INFO_LASTLITERAL 6
#define PCRE_INFO_NAMEENTRYSIZE 7
#define PCRE_INFO_NAMECOUNT 8
#define PCRE_INFO_NAMETABLE 9
#define PCRE_INFO_STUDYSIZE 10
/* Request types for pcre_config() */
#define PCRE_CONFIG_UTF8 0
#define PCRE_CONFIG_NEWLINE 1
#define PCRE_CONFIG_LINK_SIZE 2
#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
#define PCRE_CONFIG_MATCH_LIMIT 4
/* Bit flags for the pcre_extra structure */
#define PCRE_EXTRA_STUDY_DATA 0x0001
#define PCRE_EXTRA_MATCH_LIMIT 0x0002
#define PCRE_EXTRA_CALLOUT_DATA 0x0004
/* Types */
struct real_pcre; /* declaration; the definition is private */
typedef struct real_pcre pcre;
/* The structure for passing additional data to pcre_exec(). This is defined in
such as way as to be extensible. */
typedef struct pcre_extra {
unsigned long int flags; /* Bits for which fields are set */
void *study_data; /* Opaque data from pcre_study() */
unsigned long int match_limit; /* Maximum number of calls to match() */
void *callout_data; /* Data passed back in callouts */
} pcre_extra;
/* The structure for passing out data via the pcre_callout_function. We use a
structure so that new fields can be added on the end in future versions,
without changing the API of the function, thereby allowing old clients to work
without modification. */
typedef struct pcre_callout_block {
int version; /* Identifies version of block */
/* ------------------------ Version 0 ------------------------------- */
int callout_number; /* Number compiled into pattern */
int *offset_vector; /* The offset vector */
const char *subject; /* The subject being matched */
int subject_length; /* The length of the subject */
int start_match; /* Offset to start of this match attempt */
int current_position; /* Where we currently are */
int capture_top; /* Max current capture */
int capture_last; /* Most recently closed capture */
void *callout_data; /* Data passed in with the call */
/* ------------------------------------------------------------------ */
} pcre_callout_block;
/* Indirection for store get and free functions. These can be set to
alternative malloc/free functions if required. There is also an optional
callout function that is triggered by the (?) regex item. Some magic is
required for Win32 DLL; it is null on other OS. For Virtual Pascal, these
have to be different again. */
#ifndef VPCOMPAT
PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t);
PCRE_DATA_SCOPE void (*pcre_free)(void *);
PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *);
#else /* VPCOMPAT */
extern void *pcre_malloc(size_t);
extern void pcre_free(void *);
extern int pcre_callout(pcre_callout_block *);
#endif /* VPCOMPAT */
/* Exported PCRE functions */
extern pcre *pcre_compile(const char *, int, const char **,
int *, const unsigned char *);
extern int pcre_config(int, void *);
extern int pcre_copy_named_substring(const pcre *, const char *,
int *, int, const char *, char *, int);
extern int pcre_copy_substring(const char *, int *, int, int,
char *, int);
extern int pcre_exec(const pcre *, const pcre_extra *,
const char *, int, int, int, int *, int);
extern void pcre_free_substring(const char *);
extern void pcre_free_substring_list(const char **);
extern int pcre_fullinfo(const pcre *, const pcre_extra *, int,
void *);
extern int pcre_get_named_substring(const pcre *, const char *,
int *, int, const char *, const char **);
extern int pcre_get_stringnumber(const pcre *, const char *);
extern int pcre_get_substring(const char *, int *, int, int,
const char **);
extern int pcre_get_substring_list(const char *, int *, int,
const char ***);
extern int pcre_info(const pcre *, int *, int *);
extern const unsigned char *pcre_maketables(void);
extern pcre_extra *pcre_study(const pcre *, int, const char **);
extern const char *pcre_version(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* End of pcre.h */

438
pcre/study.c Normal file
View file

@ -0,0 +1,438 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/*
This is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language. See
the file Tech.Notes for some information on the internals.
Written by: Philip Hazel <ph10@cam.ac.uk>
Copyright (c) 1997-2002 University of Cambridge
-----------------------------------------------------------------------------
Permission is granted to anyone to use this software for any purpose on any
computer system, and to redistribute it freely, subject to the following
restrictions:
1. This software 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.
2. The origin of this software must not be misrepresented, either by
explicit claim or by omission.
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software.
4. If PCRE is embedded in any software that is released under the GNU
General Purpose Licence (GPL), then the terms of that licence shall
supersede any condition above with which it is incompatible.
-----------------------------------------------------------------------------
*/
/* Include the internals header, which itself includes Standard C headers plus
the external pcre header. */
#include "internal.h"
/*************************************************
* Set a bit and maybe its alternate case *
*************************************************/
/* Given a character, set its bit in the table, and also the bit for the other
version of a letter if we are caseless.
Arguments:
start_bits points to the bit map
c is the character
caseless the caseless flag
cd the block with char table pointers
Returns: nothing
*/
static void
set_bit(uschar *start_bits, int c, BOOL caseless, compile_data *cd)
{
start_bits[c/8] |= (1 << (c&7));
if (caseless && (cd->ctypes[c] & ctype_letter) != 0)
start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7));
}
/*************************************************
* Create bitmap of starting chars *
*************************************************/
/* This function scans a compiled unanchored expression and attempts to build a
bitmap of the set of initial characters. If it can't, it returns FALSE. As time
goes by, we may be able to get more clever at doing this.
Arguments:
code points to an expression
start_bits points to a 32-byte table, initialized to 0
caseless the current state of the caseless flag
utf8 TRUE if in UTF-8 mode
cd the block with char table pointers
Returns: TRUE if table built, FALSE otherwise
*/
static BOOL
set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless,
BOOL utf8, compile_data *cd)
{
register int c;
/* This next statement and the later reference to dummy are here in order to
trick the optimizer of the IBM C compiler for OS/2 into generating correct
code. Apparently IBM isn't going to fix the problem, and we would rather not
disable optimization (in this module it actually makes a big difference, and
the pcre module can use all the optimization it can get). */
volatile int dummy;
do
{
const uschar *tcode = code + 1 + LINK_SIZE;
BOOL try_next = TRUE;
while (try_next)
{
/* If a branch starts with a bracket or a positive lookahead assertion,
recurse to set bits from within them. That's all for this branch. */
if ((int)*tcode >= OP_BRA || *tcode == OP_ASSERT)
{
if (!set_start_bits(tcode, start_bits, caseless, utf8, cd))
return FALSE;
try_next = FALSE;
}
else switch(*tcode)
{
default:
return FALSE;
/* Skip over callout */
case OP_CALLOUT:
tcode += 2;
break;
/* Skip over extended extraction bracket number */
case OP_BRANUMBER:
tcode += 3;
break;
/* Skip over lookbehind and negative lookahead assertions */
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
tcode += 1+LINK_SIZE;
break;
/* Skip over an option setting, changing the caseless flag */
case OP_OPT:
caseless = (tcode[1] & PCRE_CASELESS) != 0;
tcode += 2;
break;
/* BRAZERO does the bracket, but carries on. */
case OP_BRAZERO:
case OP_BRAMINZERO:
if (!set_start_bits(++tcode, start_bits, caseless, utf8, cd))
return FALSE;
dummy = 1;
do tcode += GET(tcode,1); while (*tcode == OP_ALT);
tcode += 1+LINK_SIZE;
break;
/* Single-char * or ? sets the bit and tries the next item */
case OP_STAR:
case OP_MINSTAR:
case OP_QUERY:
case OP_MINQUERY:
set_bit(start_bits, tcode[1], caseless, cd);
tcode += 2;
#ifdef SUPPORT_UTF8
if (utf8) while ((*tcode & 0xc0) == 0x80) tcode++;
#endif
break;
/* Single-char upto sets the bit and tries the next */
case OP_UPTO:
case OP_MINUPTO:
set_bit(start_bits, tcode[3], caseless, cd);
tcode += 4;
#ifdef SUPPORT_UTF8
if (utf8) while ((*tcode & 0xc0) == 0x80) tcode++;
#endif
break;
/* At least one single char sets the bit and stops */
case OP_EXACT: /* Fall through */
tcode++;
case OP_CHARS: /* Fall through */
tcode++;
case OP_PLUS:
case OP_MINPLUS:
set_bit(start_bits, tcode[1], caseless, cd);
try_next = FALSE;
break;
/* Single character type sets the bits and stops */
case OP_NOT_DIGIT:
for (c = 0; c < 32; c++)
start_bits[c] |= ~cd->cbits[c+cbit_digit];
try_next = FALSE;
break;
case OP_DIGIT:
for (c = 0; c < 32; c++)
start_bits[c] |= cd->cbits[c+cbit_digit];
try_next = FALSE;
break;
case OP_NOT_WHITESPACE:
for (c = 0; c < 32; c++)
start_bits[c] |= ~cd->cbits[c+cbit_space];
try_next = FALSE;
break;
case OP_WHITESPACE:
for (c = 0; c < 32; c++)
start_bits[c] |= cd->cbits[c+cbit_space];
try_next = FALSE;
break;
case OP_NOT_WORDCHAR:
for (c = 0; c < 32; c++)
start_bits[c] |= ~cd->cbits[c+cbit_word];
try_next = FALSE;
break;
case OP_WORDCHAR:
for (c = 0; c < 32; c++)
start_bits[c] |= cd->cbits[c+cbit_word];
try_next = FALSE;
break;
/* One or more character type fudges the pointer and restarts, knowing
it will hit a single character type and stop there. */
case OP_TYPEPLUS:
case OP_TYPEMINPLUS:
tcode++;
break;
case OP_TYPEEXACT:
tcode += 3;
break;
/* Zero or more repeats of character types set the bits and then
try again. */
case OP_TYPEUPTO:
case OP_TYPEMINUPTO:
tcode += 2; /* Fall through */
case OP_TYPESTAR:
case OP_TYPEMINSTAR:
case OP_TYPEQUERY:
case OP_TYPEMINQUERY:
switch(tcode[1])
{
case OP_NOT_DIGIT:
for (c = 0; c < 32; c++)
start_bits[c] |= ~cd->cbits[c+cbit_digit];
break;
case OP_DIGIT:
for (c = 0; c < 32; c++)
start_bits[c] |= cd->cbits[c+cbit_digit];
break;
case OP_NOT_WHITESPACE:
for (c = 0; c < 32; c++)
start_bits[c] |= ~cd->cbits[c+cbit_space];
break;
case OP_WHITESPACE:
for (c = 0; c < 32; c++)
start_bits[c] |= cd->cbits[c+cbit_space];
break;
case OP_NOT_WORDCHAR:
for (c = 0; c < 32; c++)
start_bits[c] |= ~cd->cbits[c+cbit_word];
break;
case OP_WORDCHAR:
for (c = 0; c < 32; c++)
start_bits[c] |= cd->cbits[c+cbit_word];
break;
}
tcode += 2;
break;
/* Character class where all the information is in a bit map: set the
bits and either carry on or not, according to the repeat count. If it was
a negative class, and we are operating with UTF-8 characters, any byte
with the top-bit set is a potentially valid starter because it may start
a character with a value > 255. (This is sub-optimal in that the
character may be in the range 128-255, and those characters might be
unwanted, but that's as far as we go for the moment.) */
case OP_NCLASS:
if (utf8) memset(start_bits+16, 0xff, 16);
/* Fall through */
case OP_CLASS:
{
tcode++;
for (c = 0; c < 32; c++) start_bits[c] |= tcode[c];
tcode += 32;
switch (*tcode)
{
case OP_CRSTAR:
case OP_CRMINSTAR:
case OP_CRQUERY:
case OP_CRMINQUERY:
tcode++;
break;
case OP_CRRANGE:
case OP_CRMINRANGE:
if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5;
else try_next = FALSE;
break;
default:
try_next = FALSE;
break;
}
}
break; /* End of bitmap class handling */
} /* End of switch */
} /* End of try_next loop */
code += GET(code, 1); /* Advance to next branch */
}
while (*code == OP_ALT);
return TRUE;
}
/*************************************************
* Study a compiled expression *
*************************************************/
/* This function is handed a compiled expression that it must study to produce
information that will speed up the matching. It returns a pcre_extra block
which then gets handed back to pcre_exec().
Arguments:
re points to the compiled expression
options contains option bits
errorptr points to where to place error messages;
set NULL unless error
Returns: pointer to a pcre_extra block, with study_data filled in and the
appropriate flag set;
NULL on error or if no optimization possible
*/
pcre_extra *
pcre_study(const pcre *external_re, int options, const char **errorptr)
{
uschar start_bits[32];
pcre_extra *extra;
pcre_study_data *study;
const real_pcre *re = (const real_pcre *)external_re;
uschar *code = (uschar *)re + sizeof(real_pcre) +
(re->name_count * re->name_entry_size);
compile_data compile_block;
*errorptr = NULL;
if (re == NULL || re->magic_number != MAGIC_NUMBER)
{
*errorptr = "argument is not a compiled regular expression";
return NULL;
}
if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
{
*errorptr = "unknown or incorrect option bit(s) set";
return NULL;
}
/* For an anchored pattern, or an unanchored pattern that has a first char, or
a multiline pattern that matches only at "line starts", no further processing
at present. */
if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0)
return NULL;
/* Set the character tables in the block which is passed around */
compile_block.lcc = re->tables + lcc_offset;
compile_block.fcc = re->tables + fcc_offset;
compile_block.cbits = re->tables + cbits_offset;
compile_block.ctypes = re->tables + ctypes_offset;
/* See if we can find a fixed set of initial characters for the pattern. */
memset(start_bits, 0, 32 * sizeof(uschar));
if (!set_start_bits(code, start_bits, (re->options & PCRE_CASELESS) != 0,
(re->options & PCRE_UTF8) != 0, &compile_block)) return NULL;
/* Get a pcre_extra block and a pcre_study_data block. The study data is put in
the latter, which is pointed to by the former, which may also get additional
data set later by the calling program. At the moment, the size of
pcre_study_data is fixed. We nevertheless save it in a field for returning via
the pcre_fullinfo() function so that if it becomes variable in the future, we
don't have to change that code. */
extra = (pcre_extra *)(pcre_malloc)
(sizeof(pcre_extra) + sizeof(pcre_study_data));
if (extra == NULL)
{
*errorptr = "failed to get memory";
return NULL;
}
study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra));
extra->flags = PCRE_EXTRA_STUDY_DATA;
extra->study_data = study;
study->size = sizeof(pcre_study_data);
study->options = PCRE_STUDY_MAPPED;
memcpy(study->start_bits, start_bits, sizeof(start_bits));
return extra;
}
/* End of study.c */

View file

@ -26,9 +26,12 @@
*/
#include "stats.h"
#include "dl.h"
#include "hash.h"
#include "log.h"
hash_t *sh;
static Server *new_server (char * name);
static Server *
@ -76,7 +79,7 @@ AddServer (char *name, char *uplink, int hops)
/* run the module event for a new server. */
AddStringToList (&av, s->name, &ac);
Module_Event (EVENT_NEWSERVER, av, ac);
ModuleEvent (EVENT_NEWSERVER, av, ac);
free (av);
}
@ -101,7 +104,7 @@ DelServer (char *name)
/* run the event for delete server */
AddStringToList (&av, s->name, &ac);
Module_Event (EVENT_SQUIT, av, ac);
ModuleEvent (EVENT_SQUIT, av, ac);
free (av);
hash_delete (sh, sn);
@ -155,7 +158,7 @@ init_server_hash ()
}
void
TimerPings ()
PingServers (void)
{
Server *s;
hscan_t ss;

33
server.h Normal file
View file

@ -0,0 +1,33 @@
/* NeoStats - IRC Statistical Services
** Copyright (c) 1999-2003 Adam Rutter, Justin Hammond, Mark Hetherington
** http://www.neostats.net/
**
** 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
#ifndef _SERVER_H_
#define _SERVER_H_
void AddServer (char *name, char *uplink, int hops);
void DelServer (char *name);
void ServerDump (void);
int init_server_hash (void);
void PingServers (void);
#endif /* _SERVER_H_ */

View file

@ -29,29 +29,142 @@
#include "dl.h"
#include "log.h"
#include "sock.h"
#include "ns_help.h"
#include "users.h"
#include "server.h"
#include "chans.h"
#include "hash.h"
typedef struct bot_cmd {
char cmd[MAXCMDSIZE]; /* command string */
bot_cmd_handler handler; /* handler */
int minparams; /* min num params */
unsigned int ulevel; /* min user level */
const char** helptext; /* pointer to help text */
int internal; /* is this a internal function? */
char onelinehelp[255]; /* single line help for generic help function */
}bot_cmd;
/* hash for command list */
hash_t *botcmds;
static char quitmsg[BUFSIZE];
static char no_reason[]="no reason given";
static void ns_reload (User * u, char *reason);
static void ns_logs (User * u);
static void ns_jupe (User * u, char * server);
void ns_set_debug (char * u);
static void ns_set_debug (User * u, char **av, int ac);
static void ns_shutdown (User * u, char **av, int ac);
static void ns_reload (User * u, char **av, int ac);
static void ns_logs (User * u, char **av, int ac);
static void ns_jupe (User * u, char **av, int ac);
#ifdef USE_RAW
static void ns_raw (User * u, char * message);
static void ns_raw (User * u, char **av, int ac);
#endif
static void ns_user_dump (User * u, char * nick);
static void ns_server_dump (User * u);
static void ns_chan_dump (User * u, char * channel);
static void ns_uptime (User * u);
static void ns_version (User * u);
static void ns_user_dump (User * u, char **av, int ac);
static void ns_server_dump (User * u, char **av, int ac);
static void ns_chan_dump (User * u, char **av, int ac);
static void ns_info (User * u, char **av, int ac);
static void ns_version (User * u, char **av, int ac);
static void ns_show_level (User * u, char **av, int ac);
static void ns_do_help (User * u, char **av, int ac);
static void ns_load_module (User * u, char **av, int ac);
static void ns_unload_module (User * u, char **av, int ac);
bot_cmd ns_commands[]=
{
{"HELP", ns_do_help, 0, 0, ns_help_on_help, 1, "Provides Help on Commands"},
{"LEVEL", ns_show_level, 0, 0, ns_level_help, 1, "Show your permission level for NeoStats."},
{"INFO", ns_info, 0, 0, ns_info_help, 1, "Stats info on NeoStats."},
{"VERSION", ns_version, 0, 0, ns_version_help, 1, "Show NeoStats version information."},
{"SHUTDOWN", ns_shutdown, 0, NS_ULEVEL_ADMIN, ns_shutdown_help, 1, "Shutdown NeoStats"},
{"RELOAD", ns_reload, 0, NS_ULEVEL_ADMIN, ns_reload_help, 1, "Force NeoStats to reload"},
{"LOGS", ns_logs, 0, NS_ULEVEL_OPER, ns_logs_help, 1, "View logfiles"},
{"LOAD", ns_load_module, 1, NS_ULEVEL_ADMIN, ns_load_help, 1, "Load a module"},
{"UNLOAD", ns_unload_module, 1, NS_ULEVEL_ADMIN, ns_unload_help, 1, "Unload a module"},
{"JUPE", ns_jupe, 1, NS_ULEVEL_ADMIN, ns_jupe_help, 1, "Jupiter a Server"},
#ifdef USE_RAW
{"RAW", ns_raw, 0, NS_ULEVEL_ADMIN, ns_raw_help, 1, "Send a raw command from this Server"},
#endif
{"DEBUG", ns_set_debug, 1, NS_ULEVEL_ROOT, ns_debug_help, 1, "Toggles debug mode"},
{"BOTLIST", list_bots, 0, NS_ULEVEL_ROOT, ns_botlist_help, 1, "List current module bots"},
{"SOCKLIST", list_sockets, 0, NS_ULEVEL_ROOT, ns_socklist_help, 1, "List current module sockets"},
{"TIMERLIST", list_timers, 0, NS_ULEVEL_ROOT, ns_timerlist_help, 1, "List current module timers"},
{"BOTCHANLIST", list_bot_chans, 0, NS_ULEVEL_ROOT, ns_botchanlist_help, 1, "List current module bot channels"},
{"MODLIST", list_modules, 0, NS_ULEVEL_ROOT, ns_modlist_help, 1, "List loaded modules"},
{"USERDUMP", ns_user_dump, 0, NS_ULEVEL_ROOT, ns_userdump_help, 1, "Debug user table"},
{"CHANDUMP", ns_chan_dump, 0, NS_ULEVEL_ROOT, ns_chandump_help, 1, "Debug channel table"},
{"SERVERDUMP", ns_server_dump, 0, NS_ULEVEL_ROOT, ns_serverdump_help, 1, "Debug server table"},
{"\0", NULL, 0, 0, NULL, 0, "\0"}
};
int
init_services()
{
bot_cmd *cmd_ptr;
hnode_t *cmdnode;
/* init bot hash first */
botcmds = hash_create(-1, 0, 0);
/* Process command list */
cmd_ptr = ns_commands;
while(cmd_ptr->handler) {
cmdnode = hnode_create(cmd_ptr);
hash_insert(botcmds, cmdnode, cmd_ptr->cmd);
cmd_ptr++;
}
return NS_SUCCESS;
}
int
add_services_cmd(const char cmd[MAXCMDSIZE], bot_cmd_handler handler, int minparams, int ulevel, const char** helptext, const char onelinehelp[255])
{
bot_cmd *cmd_ptr;
hnode_t *cmdnode;
cmd_ptr = malloc(sizeof(bot_cmd));
strlcpy(cmd_ptr->cmd, cmd, MAXCMDSIZE);
cmd_ptr->handler = handler;
cmd_ptr->minparams = minparams;
cmd_ptr->ulevel = ulevel;
cmd_ptr->helptext = helptext;
cmd_ptr->internal = 0;
strlcpy(cmd_ptr->onelinehelp, onelinehelp, 255);
cmdnode = hnode_create(cmd_ptr);
hash_insert(botcmds, cmdnode, cmd_ptr->cmd);
nlog(LOG_DEBUG2, LOG_CORE, "Added a new command %s to Services Bot", cmd);
return 1;
}
int
del_services_cmd(const char cmd[MAXCMDSIZE])
{
bot_cmd *cmd_ptr;
hnode_t *cmdnode;
cmdnode = hash_lookup(botcmds, cmd);
if (cmdnode) {
hash_delete(botcmds, cmdnode);
cmd_ptr = hnode_get(cmdnode);
hnode_destroy(cmdnode);
/* free if its a external (malloc'd) command */
if (cmd_ptr->internal == 0) {
free(cmd_ptr);
}
return NS_SUCCESS;
}
return NS_FAILURE;
}
void
servicesbot (char *nick, char **av, int ac)
{
User *u;
int rval;
char *tmp;
bot_cmd* cmd_ptr;
hnode_t *cmdnode;
u = finduser (nick);
if (!u) {
@ -59,270 +172,86 @@ servicesbot (char *nick, char **av, int ac)
return;
}
SET_SEGV_LOCATION();
me.requests++;
if (me.onlyopers && (UserLevel (u) < 40)) {
/* Check user authority to use this command set */
if (me.onlyopers && (UserLevel (u) < NS_ULEVEL_OPER)) {
prefmsg (u->nick, s_Services, "This service is only available to IRCops.");
chanalert (s_Services, "%s Requested %s, but he is Not an Operator!", u->nick, av[1]);
return;
}
if (!strcasecmp (av[1], "HELP")) {
if (ac > 2) {
chanalert (s_Services, "%s Requested %s Help on %s", u->nick, s_Services, av[2]);
} else {
chanalert (s_Services, "%s Requested %s Help", u->nick, s_Services);
}
if (ac < 3) {
privmsg_list (nick, s_Services, ns_help);
if (UserLevel (u) >= 180)
privmsg_list (nick, s_Services, ns_myuser_help);
privmsg_list (nick, s_Services, ns_help_on_help);
} else if (!strcasecmp (av[2], "VERSION"))
privmsg_list (nick, s_Services, ns_version_help);
else if (!strcasecmp (av[2], "SHUTDOWN")
&& (UserLevel (u) >= 180))
privmsg_list (nick, s_Services, ns_shutdown_help);
else if (!strcasecmp (av[2], "RELOAD")
&& (UserLevel (u) >= 180))
privmsg_list (nick, s_Services, ns_reload_help);
else if (!strcasecmp (av[2], "LOGS")
&& (UserLevel (u) >= 180))
privmsg_list (nick, s_Services, ns_logs_help);
else if (!strcasecmp (av[2], "LOAD")
&& (UserLevel (u) >= 180))
privmsg_list (nick, s_Services, ns_load_help);
else if (!strcasecmp (av[2], "UNLOAD")
&& (UserLevel (u) >= 180))
privmsg_list (nick, s_Services, ns_unload_help);
else if (!strcasecmp (av[2], "MODLIST")
&& (UserLevel (u) >= 180))
privmsg_list (nick, s_Services, ns_modlist_help);
else if (!strcasecmp (av[2], "USERDUMP")
&& (UserLevel (u) >= 180) && (me.debug_mode))
privmsg_list (nick, s_Services, ns_userdump_help);
else if (!strcasecmp (av[2], "CHANDUMP")
&& (UserLevel (u) >= 180) && (me.debug_mode))
privmsg_list (nick, s_Services, ns_chandump_help);
else if (!strcasecmp (av[2], "SERVERDUMP")
&& (UserLevel (u) >= 180) && (me.debug_mode))
privmsg_list (nick, s_Services, ns_serverdump_help);
else if (!strcasecmp (av[2], "JUPE")
&& (UserLevel (u) >= 180))
privmsg_list (nick, s_Services, ns_jupe_help);
#ifdef USE_RAW
else if (!strcasecmp (av[2], "RAW")
&& (UserLevel (u) >= 180))
privmsg_list (nick, s_Services, ns_raw_help);
#endif
else if (!strcasecmp (av[2], "LEVEL"))
privmsg_list (nick, s_Services, ns_level_help);
else if (!strcasecmp (av[2], "DEBUG"))
privmsg_list (nick, s_Services, ns_debug_help);
else if (!strcasecmp (av[2], "MODBOTLIST"))
privmsg_list (nick, s_Services, ns_modbotlist_help);
else if (!strcasecmp (av[2], "MODSOCKLIST"))
privmsg_list (nick, s_Services, ns_modsocklist_help);
else if (!strcasecmp (av[2], "MODTIMERLIST"))
privmsg_list (nick, s_Services, ns_modtimerlist_help);
else if (!strcasecmp (av[2], "MODBOTCHANLIST"))
privmsg_list (nick, s_Services, ns_modbotchanlist_help);
else if (!strcasecmp (av[2], "INFO"))
privmsg_list (nick, s_Services, ns_info_help);
else
prefmsg (nick, s_Services, "Unknown Help Topic: \2%s\2", av[2]);
} else if (!strcasecmp (av[1], "LEVEL")) {
prefmsg (nick, s_Services, "Your Level is %d", UserLevel (u));
} else if (!strcasecmp (av[1], "LOAD")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s tried to LOAD, but is not authorised", nick);
/* Process command list */
cmdnode = hash_lookup(botcmds, av[1]);
if (cmdnode) {
cmd_ptr = hnode_get(cmdnode);
/* Is user authorised to issue this command? */
if (UserLevel (u) < cmd_ptr->ulevel) {
prefmsg (u->nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s tried to use %s, but is not authorised", u->nick, cmd_ptr->cmd);
return;
}
if (ac <= 2) {
prefmsg (nick, s_Services, "Please Specify a Module");
/* First two parameters are bot name and command name so
* subtract 2 to get parameter count */
if((ac - 2) < cmd_ptr->minparams ) {
prefmsg (u->nick, s_Services, "Syntax error: insufficient parameters");
prefmsg (u->nick, s_Services, "/msg %s HELP %s for more information", s_Services, cmd_ptr->cmd);
return;
}
rval = load_module (av[2], u);
if (rval == NS_SUCCESS) {
chanalert (s_Services, "%s Loaded Module %s", u->nick, av[2]);
} else {
chanalert (s_Services, "%s Tried to Load Module %s, but Failed", u->nick, av[2]);
}
} else if (!strcasecmp (av[1], "MODLIST")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s Tried to MODLIST, but is not authorised", nick);
/* Missing handler?! */
if(!cmd_ptr->handler) {
return;
}
list_module (u);
} else if (!strcasecmp (av[1], "UNLOAD")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s Tried to UNLOAD, but is not authorised", nick);
return;
}
if (ac <= 2) {
prefmsg (nick, s_Services, " Please Specify a Module Name");
return;
}
rval = unload_module (av[2], u);
if (rval > 0) {
chanalert (s_Services, "%s Unloaded Module %s", u->nick, av[2]);
}
/* Seems OK so report the command call then call appropriate handler */
chanalert (s_Services, "%s used %s", u->nick, cmd_ptr->cmd);
cmd_ptr->handler(u, av, ac);
return;
} else if (!strcasecmp (av[1], "MODBOTLIST")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s Tried to MODBOTLIST, but is not authorised", nick);
return;
}
list_module_bots (u);
} else if (!strcasecmp (av[1], "MODSOCKLIST")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s Tried to MODSOCKLIST, but is not authorised", nick);
return;
}
list_sockets (u);
} else if (!strcasecmp (av[1], "MODTIMERLIST")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s Tried to MODTIMERLIST, but is not authorised", nick);
return;
}
list_module_timer (u);
} else if (!strcasecmp (av[1], "MODBOTCHANLIST")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s tried to MODBOTCHANLIST, but is not authorised", nick);
return;
}
botchandump (u);
} else if (!strcasecmp (av[1], "INFO")) {
ns_uptime (u);
chanalert (s_Services, "%s Wanted to see %s's info", u->nick, me.name);
} else if (!strcasecmp (av[1], "SHUTDOWN")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s Tried to SHUTDOWN, but is not authorised", nick);
return;
}
if (ac <= 2) {
chanalert (s_Services, "%s Requested SHUTDOWN", u->nick);
ns_shutdown (u, NULL);
} else {
tmp = joinbuf (av, ac, 2);
chanalert (s_Services, "%s Requested SHUTDOWN for: ", u->nick, tmp);
ns_shutdown (u, tmp);
free (tmp);
}
} else if (!strcasecmp (av[1], "VERSION")) {
ns_version (u);
chanalert (s_Services, "%s Wanted to know our version number ", u->nick);
} else if (!strcasecmp (av[1], "RELOAD")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s Tried to RELOAD, but is not authorised", nick);
return;
}
if (ac <= 2) {
prefmsg (nick, s_Services, "You must supply a Reason to Reload");
return;
}
tmp = joinbuf (av, ac, 2);
chanalert (s_Services, "%s Wants me to RELOAD! for %s", u->nick, tmp);
ns_reload (u, tmp);
free (tmp);
} else if (!strcasecmp (av[1], "LOGS")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s Tried to view LOGS, but is not authorised", nick);
return;
}
ns_logs (u);
chanalert (s_Services, "%s Wants to Look at my Logs!!", u->nick);
} else if (!strcasecmp (av[1], "JUPE")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s Tried to JUPE, but is not authorised", nick);
return;
}
if (ac <= 2) {
prefmsg (nick, s_Services, "You must supply a ServerName to Jupe");
return;
}
ns_jupe (u, av[2]);
} else if (!strcasecmp (av[1], "DEBUG")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (u->nick, s_Services, "Permission Denied, you need to be authorised to Enable Debug Mode!");
return;
}
ns_set_debug (u->nick);
} else if (!strcasecmp (av[1], "USERDUMP")) {
if (!me.debug_mode) {
prefmsg (u->nick, s_Services, "\2Error:\2 Debug Mode Disabled");
return;
}
if (ac <= 2) {
ns_user_dump (u, NULL);
} else {
ns_user_dump (u, av[2]);
}
} else if (!strcasecmp (av[1], "CHANDUMP")) {
if (!me.debug_mode) {
prefmsg (u->nick, s_Services, "\2Error:\2 Debug Mode Disabled");
return;
}
if (ac < 3) {
ns_chan_dump (u, NULL);
} else {
ns_chan_dump (u, av[2]);
}
} else if (!strcasecmp (av[1], "SERVERDUMP")) {
if (!me.debug_mode) {
prefmsg (u->nick, s_Services, "\2Error:\2 Debug Mode Disabled");
return;
}
ns_server_dump (u);
} else if (!strcasecmp (av[1], "RAW")) {
if (!(UserLevel (u) >= 180)) {
prefmsg (nick, s_Services, "Permission Denied");
chanalert (s_Services, "%s Tried to use RAW, but is not authorised", nick);
return;
}
#ifdef USE_RAW
tmp = joinbuf (av, ac, 2);
ns_raw (u, tmp);
free (tmp);
return;
#else
prefmsg (nick, s_Services, "Raw is disabled");
return;
#endif
} else {
prefmsg (nick, s_Services, "Unknown Command: \2%s\2", av[1]);
chanalert (s_Services, "%s Reqested %s, but that is an Unknown Command", u->nick, av[1]);
}
/* We have run out of commands so report failure */
prefmsg (u->nick, s_Services, "Syntax error: unknown command: \2%s\2", av[1]);
chanalert (s_Services, "%s requested %s, but that is an unknown command", u->nick, av[1]);
}
void
ns_shutdown (User * u, char *reason)
static void
ns_shutdown (User * u, char **av, int ac)
{
SET_SEGV_LOCATION();
ircsnprintf (quitmsg, BUFSIZE, "%s [%s](%s) requested SHUTDOWN for %s.",
u->nick, u->username, u->hostname,(reason ? reason : no_reason));
char *tmp;
if (ac <= 2) {
ircsnprintf (quitmsg, BUFSIZE, "%s [%s](%s) requested SHUTDOWN for %s.",
u->nick, u->username, u->hostname, no_reason);
} else {
tmp = joinbuf (av, ac, 2);
chanalert (s_Services, "%s Wants me to SHUTDOWN for %s", u->nick, tmp);
ircsnprintf (quitmsg, BUFSIZE, "%s [%s](%s) requested SHUTDOWN for %s.",
u->nick, u->username, u->hostname, tmp);
free (tmp);
}
globops (s_Services, quitmsg);
nlog (LOG_NOTICE, LOG_CORE, quitmsg);
do_exit (NS_EXIT_NORMAL, quitmsg);
}
static void
ns_reload (User * u, char *reason)
ns_reload (User * u, char **av, int ac)
{
SET_SEGV_LOCATION();
char *tmp;
if (ac <= 2) {
prefmsg (u->nick, s_Services, "You must supply a Reason to Reload");
return;
}
tmp = joinbuf (av, ac, 2);
chanalert (s_Services, "%s Wants me to RELOAD! for %s", u->nick, tmp);
ircsnprintf (quitmsg, BUFSIZE, "%s [%s](%s) requested RELOAD for %s.",
u->nick, u->username, u->hostname, (reason ? reason : no_reason));
u->nick, u->username, u->hostname, tmp);
free (tmp);
globops (s_Services, quitmsg);
nlog (LOG_NOTICE, LOG_CORE, quitmsg);
@ -330,7 +259,7 @@ ns_reload (User * u, char *reason)
}
static void
ns_logs (User * u)
ns_logs (User * u, char **av, int ac)
{
#ifdef DEBUG
prefmsg (u->nick, s_Services, "This command is disabled while in DEBUG.");
@ -353,85 +282,73 @@ ns_logs (User * u)
}
static void
ns_jupe (User * u, char *server)
ns_jupe (User * u, char **av, int ac)
{
char infoline[255];
SET_SEGV_LOCATION();
ircsnprintf (infoline, 255, "[Jupitered by %s]", u->nick);
sserver_cmd (server, 1, infoline);
nlog (LOG_NOTICE, LOG_CORE, "%s!%s@%s jupitered %s", u->nick, u->username, u->hostname, server);
chanalert (s_Services, "%s Wants to JUPE this Server %s", u->nick, server);
prefmsg(u->nick, s_Services, "%s has been Jupitered", server);
sserver_cmd (av[2], 1, infoline);
nlog (LOG_NOTICE, LOG_CORE, "%s!%s@%s jupitered %s", u->nick, u->username, u->hostname, av[2]);
chanalert (s_Services, "%s Wants to JUPE this Server %s", u->nick, av[2]);
prefmsg(u->nick, s_Services, "%s has been Jupitered", av[2]);
}
void
ns_set_debug (char *u)
static void
ns_set_debug (User * u, char **av, int ac)
{
SET_SEGV_LOCATION();
if (!me.debug_mode) {
if ((!strcasecmp(av[2], "YES")) || (!strcasecmp(av[2], "ON"))) {
me.debug_mode = 1;
if (u) {
globops (me.name, "\2DEBUG MODE\2 Activated by %s", u);
prefmsg (u, s_Services, "Debuging Mode Enabled!");
} else {
globops (me.name, "\2DEBUG MODE\3 Active");
}
} else {
globops (me.name, "\2DEBUG MODE\2 Activated by %s", u->nick);
prefmsg (u->nick, s_Services, "Debuging Mode Enabled!");
} else if ((!strcasecmp(av[2], "NO")) || (!strcasecmp(av[2], "OFF"))) {
me.debug_mode = 0;
if (!u) {
globops (me.name, "\2DEBUG MODE\2 Deactivated by %s", u);
prefmsg (u, s_Services, "Debuging Mode Disabled");
} else {
globops (me.name, "\2DEBUG MODE\2 Deactivated");
}
globops (me.name, "\2DEBUG MODE\2 Deactivated by %s", u->nick);
prefmsg (u->nick, s_Services, "Debuging Mode Disabled");
} else {
prefmsg(u->nick, s_Services,
"Syntax Error: /msg %s HELP DEBUG for more info",
s_Services);
return;
}
}
#ifdef USE_RAW
static void
ns_raw (User * u, char *message)
ns_user_dump (User * u, char **av, int ac)
{
SET_SEGV_LOCATION();
chanalert (s_Services, "\2RAW COMMAND\2 \2%s\2 Issued a Raw Command!(%s)", u->nick, message);
nlog (LOG_INFO, LOG_CORE, "RAW COMMAND %sIssued a Raw Command!(%s)", u->nick, message);
sts(message);
}
#endif
static void
ns_user_dump (User * u, char *nick)
{
SET_SEGV_LOCATION();
if (!(UserLevel (u) >= 180)) {
prefmsg (u->nick, s_Services, "Permission Denied, you do not have sufficient access rights for this command!");
if (!me.debug_mode) {
prefmsg (u->nick, s_Services, "\2Error:\2 Debug Mode Disabled");
return;
}
chanalert (s_Services, "\2DEBUG\2 \2%s\2 Requested a UserDump!", u->nick);
UserDump (nick);
UserDump (((ac < 3) ? NULL : av[2]));
}
static void
ns_server_dump (User * u)
ns_server_dump (User * u, char **av, int ac)
{
SET_SEGV_LOCATION();
if (!(UserLevel (u) >= 180)) {
prefmsg (u->nick, s_Services, "Permission Denied, you do not have sufficient access rights for this command!");
if (!me.debug_mode) {
prefmsg (u->nick, s_Services, "\2Error:\2 Debug Mode Disabled");
return;
}
chanalert (s_Services, "\2DEBUG\2 \2%s\2 Requested a ServerDump!", u->nick);
ServerDump ();
}
static void
ns_chan_dump (User * u, char *chan)
ns_chan_dump (User * u, char **av, int ac)
{
SET_SEGV_LOCATION();
if (!(UserLevel (u) >= 180)) {
prefmsg (u->nick, s_Services, "Permission Denied, you do not have sufficient access rights for this command!");
if (!me.debug_mode) {
prefmsg (u->nick, s_Services, "\2Error:\2 Debug Mode Disabled");
return;
}
chanalert (s_Services, "\2DEBUG\2 \2%s\2 Requested a ChannelDump!", u->nick);
chandump (chan);
ChanDump (((ac < 3) ? NULL : av[2]));
}
static void
ns_uptime (User * u)
static void
ns_info (User * u, char **av, int ac)
{
int uptime = me.now - me.t_start;
@ -458,10 +375,114 @@ ns_uptime (User * u)
prefmsg (u->nick, s_Services, "End of Information.");
}
static void
ns_version (User * u)
ns_version (User * u, char **av, int ac)
{
SET_SEGV_LOCATION();
prefmsg (u->nick, s_Services, "\2NeoStats Version Information\2");
prefmsg (u->nick, s_Services, "NeoStats Version: %d.%d.%d%s", MAJOR, MINOR, REV, ircd_version);
prefmsg (u->nick, s_Services, "http://www.neostats.net");
}
static void
ns_show_level (User * u, char **av, int ac)
{
prefmsg (u->nick, s_Services, "Your Level is %d", UserLevel (u));
}
static void
ns_do_help (User * u, char **av, int ac)
{
bot_cmd* cmd_ptr;
int curlevel, lowlevel;
hnode_t *cmdnode;
hscan_t hs;
if (ac < 3) {
lowlevel = 0;
curlevel = NS_ULEVEL_OPER;
chanalert (s_Services, "%s Requested %s Help", u->nick, s_Services);
prefmsg(u->nick, s_Services, "The following commands can be used with NeoStats:");
restartlevel:
hash_scan_begin(&hs, botcmds);
while ((cmdnode = hash_scan_next(&hs)) != NULL) {
cmd_ptr = hnode_get(cmdnode);
if ((cmd_ptr->ulevel < curlevel) && (cmd_ptr->ulevel >= lowlevel)) {
prefmsg(u->nick, s_Services, "%-20s %s", cmd_ptr->cmd, cmd_ptr->onelinehelp);
}
}
if (UserLevel(u) >= curlevel) {
switch (curlevel) {
case NS_ULEVEL_OPER:
curlevel = NS_ULEVEL_ADMIN;
lowlevel = NS_ULEVEL_OPER;
prefmsg(u->nick, s_Services, "\2Commands Available to Opers and Above:\2");
goto restartlevel;
case NS_ULEVEL_ADMIN:
curlevel = NS_ULEVEL_ROOT;
lowlevel = NS_ULEVEL_ADMIN;
prefmsg(u->nick, s_Services, "\2Commands Available to Service Admins and Above:\2");
goto restartlevel;
case NS_ULEVEL_ROOT:
curlevel = 201;
lowlevel = 200;
prefmsg(u->nick, s_Services, "\2Commands Available to Service Roots:\2");
goto restartlevel;
default:
break;
}
}
privmsg_list (u->nick, s_Services, ns_help_on_help);
return;
}
chanalert (s_Services, "%s Requested %s Help on %s", u->nick, s_Services, av[2]);
cmdnode = hash_lookup(botcmds, av[2]);
if (cmdnode) {
cmd_ptr = hnode_get(cmdnode);
if (UserLevel (u) < cmd_ptr->ulevel) {
prefmsg (u->nick, s_Services, "Permission Denied");
return;
}
if(!cmd_ptr->helptext) {
/* Missing help text!!! */
return;
}
privmsg_list (u->nick, s_Services, cmd_ptr->helptext);
return;
}
prefmsg (u->nick, s_Services, "Unknown Help Topic: \2%s\2", av[2]);
}
static void
ns_load_module (User * u, char **av, int ac)
{
if (load_module (av[2], u) == NS_SUCCESS) {
chanalert (s_Services, "%s Loaded Module %s", u->nick, av[2]);
} else {
chanalert (s_Services, "%s Tried to Load Module %s, but Failed", u->nick, av[2]);
}
}
static void
ns_unload_module (User * u, char **av, int ac)
{
if (unload_module (av[2], u) > 0) {
chanalert (s_Services, "%s Unloaded Module %s", u->nick, av[2]);
}
}
#ifdef USE_RAW
static void
ns_raw (User * u, char **av, int ac)
{
char *message;
message = joinbuf (av, ac, 2);
SET_SEGV_LOCATION();
chanalert (s_Services, "\2RAW COMMAND\2 \2%s\2 Issued a Raw Command!(%s)", u->nick, message);
nlog (LOG_INFO, LOG_CORE, "RAW COMMAND %sIssued a Raw Command!(%s)", u->nick, message);
sts(message);
free (message);
}
#endif

29
services.h Normal file
View file

@ -0,0 +1,29 @@
/* NeoStats - IRC Statistical Services
** Copyright (c) 1999-2003 Adam Rutter, Justin Hammond, Mark Hetherington
** http://www.neostats.net/
**
** 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
#ifndef _SERVICES_H_
#define _SERVICES_H_
void servicesbot (char *nick, char **av, int ac);
#endif /* _SERVICES_H_ */

33
sock.c
View file

@ -32,12 +32,17 @@
#include <adns.h>
#include "conf.h"
#include "log.h"
#include "timer.h"
#include "dns.h"
static void recvlog (char *line);
static struct sockaddr_in lsa;
static int dobind;
int servsock;
char recbuf[BUFSIZE];
/** @brief Connect to a server
*
* @param host to connect to
@ -49,6 +54,7 @@ static int dobind;
int
ConnectTo (char *host, int port)
{
int ret;
struct hostent *hp;
struct sockaddr_in sa;
int s;
@ -67,11 +73,14 @@ ConnectTo (char *host, int port)
}
if ((hp = gethostbyname (host)) == NULL) {
printf("1\n");
return NS_FAILURE;
}
if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
return NS_FAILURE;
printf("2\n");
}
if (dobind > 0) {
if (bind (s, (struct sockaddr *) &lsa, sizeof (lsa)) < 0) {
nlog (LOG_WARNING, LOG_CORE, "bind(): Warning, Couldn't bind to IP address %s", strerror (errno));
@ -83,7 +92,9 @@ ConnectTo (char *host, int port)
sa.sin_port = htons (port);
bcopy (hp->h_addr, (char *) &sa.sin_addr, hp->h_length);
if (connect (s, (struct sockaddr *) &sa, sizeof (sa)) < 0) {
ret=connect (s, (struct sockaddr *) &sa, sizeof (sa));
if (ret< 0) {
printf("%d %x\n",errno,ret);
close (s);
return NS_FAILURE;
}
@ -105,14 +116,14 @@ read_loop ()
fd_set readfds, writefds, errfds;
char c;
char buf[BUFSIZE];
Sock_List *mod_sock;
ModSock *mod_sock;
struct pollfd *ufds;
int pollsize, pollflag;
hscan_t ss;
hnode_t *sn;
TimeOut = malloc (sizeof (struct timeval));
ufds = malloc((sizeof *ufds) * getmaxsock());
ufds = malloc((sizeof *ufds) * me.maxsocks);
while (1) {
SET_SEGV_LOCATION();
@ -124,7 +135,7 @@ read_loop ()
FD_ZERO (&readfds);
FD_ZERO (&writefds);
FD_ZERO (&errfds);
memset(ufds, 0, (sizeof *ufds) * me.maxsocks);
// memset(ufds, 0, (sizeof *ufds) * me.maxsocks);
pollsize = 0;
FD_SET (servsock, &readfds);
hash_scan_begin (&ss, sockh);
@ -363,20 +374,20 @@ sock_connect (int socktype, unsigned long ipaddr, int port, char *sockname, char
int
sock_disconnect (char *sockname)
{
Sock_List *sock;
ModSock *mod_sock;
fd_set fds;
struct timeval tv;
int i;
sock = findsock (sockname);
if (!sock) {
mod_sock = findsock (sockname);
if (!mod_sock) {
nlog (LOG_WARNING, LOG_CORE, "Warning, Can not find Socket %s in list", sockname);
return NS_FAILURE;
}
/* the following code makes sure its a valid file descriptor */
FD_ZERO (&fds);
FD_SET (sock->sock_no, &fds);
FD_SET (mod_sock->sock_no, &fds);
tv.tv_sec = 0;
tv.tv_usec = 0;
i = select (1, &fds, NULL, NULL, &tv);
@ -384,8 +395,8 @@ sock_disconnect (char *sockname)
nlog (LOG_WARNING, LOG_CORE, "Warning, Bad File Descriptor %s in list", sockname);
return NS_FAILURE;
}
nlog (LOG_DEBUG3, LOG_CORE, "Closing Socket %s with Number %d", sockname, sock->sock_no);
close (sock->sock_no);
nlog (LOG_DEBUG3, LOG_CORE, "Closing Socket %s with Number %d", sockname, mod_sock->sock_no);
close (mod_sock->sock_no);
del_socket (sockname);
return NS_SUCCESS;
}

5
sock.h
View file

@ -26,8 +26,9 @@
#ifndef SOCK_H
#define SOCK_H
int ConnectTo (char * host, int port);
void read_loop (void);
int getmaxsock (void);
void sts (char *fmt, ...);
#endif

145
stats.h
View file

@ -48,6 +48,7 @@
#include <setjmp.h>
#include <assert.h>
#include <adns.h>
#include "pcre.h"
#include "list.h"
#include "hash.h"
#include "config.h"
@ -71,36 +72,13 @@
#include "Bahamut.h"
#elif QUANTUM == 1
#include "QuantumIRCd.h"
#elif LIQUID == 1
#include "liquidircd.h"
#else
#error Error, you must select an IRCD to use. See ./configure --help for more information
#endif
/* Numeric used by NeoStats. Need to be in ircd code eventually
*
*/
#define RPL_STATSLINKINFO 211
#define RPL_STATSCOMMANDS 212
#define RPL_STATSCLINE 213
#define RPL_STATSOLDNLINE 214
#define RPL_STATSNLINE RPL_STATSOLDNLINE
#define RPL_ENDOFSTATS 219
#define RPL_STATSLLINE 241
#define RPL_STATSUPTIME 242
#define RPL_STATSOLINE 243
#define RPL_ADMINME 256
#define RPL_ADMINLOC1 257
#define RPL_ADMINLOC2 258
#define RPL_VERSION 351
#define RPL_MOTD 372
#define RPL_MOTDSTART 375
#define RPL_ENDOFMOTD 376
#include "numeric.h"
/** this is a security hack to give the coders the right levels to debug NeoStats.
* Don't define unless we ask you to
@ -111,7 +89,7 @@
#define MOD_PATH "dl"
#define RECV_LOG "logs/recv.log"
#define MOTD_FILENAME "neostats.motd"
#define ADMIN_FILENAME "stats.admin"
#define ADMIN_FILENAME "neostats.admin"
#define PID_FILENAME "neostats.pid"
#define CHANLEN 50
@ -124,6 +102,7 @@
#define MAXREALNAME 50
#define MODESIZE 53
#define PARAMSIZE MAXNICK+MAXUSER+MAXHOST+10
#define MAXCMDSIZE 15
/* MAXPATH
* used to determine buffer sizes for file system operations
@ -172,7 +151,13 @@
#define NS_SUCCESS 1
#define NS_FAILURE -1
#define NS_ERROR_xxx -2
/* Specific errors beyond SUCCESS/FAILURE so that functions can handle errors
* Treat as unsigned with top bit set to give us a clear distinction from
* other values and use a typedef ENUM so that we can indicate return type */
typedef enum NS_ERR {
NS_ERR_NICK_IN_USE = 0x8000001,
NS_ERR_OUT_OF_MEMORY = 0x8000002,
}NS_ERR ;
/* do_exit call exit type definitions */
typedef enum {
@ -183,6 +168,11 @@ typedef enum {
NS_EXIT_SEGFAULT,
}NS_EXIT_TYPE;
/* NeoStats levels */
#define NS_ULEVEL_ROOT 200
#define NS_ULEVEL_ADMIN 185
#define NS_ULEVEL_OPER 40
#define SEGV_LOCATION_BUFSIZE 255
#ifdef LEAN_AND_MEAN
#define SET_SEGV_LOCATION()
@ -211,20 +201,21 @@ typedef enum {
#define ARRAY_COUNT (a) ((sizeof ((a)) / sizeof ((a)[0]))
int servsock;
extern int servsock;
extern char recbuf[BUFSIZE];
extern char s_Services[MAXNICK];
extern const char ircd_version[];
char recbuf[BUFSIZE];
char segv_location[SEGV_LOCATION_BUFSIZE];
char segv_inmodule[SEGV_INMODULE_BUFSIZE];
jmp_buf sigvbuf;
extern const char services_bot_modes[];
extern char segv_location[SEGV_LOCATION_BUFSIZE];
extern char segv_inmodule[SEGV_INMODULE_BUFSIZE];
extern jmp_buf sigvbuf;
hash_t *sh;
hash_t *uh;
hash_t *ch;
extern hash_t *sh;
extern hash_t *uh;
extern hash_t *ch;
/* this is the dns structure */
adns_state ads;
extern adns_state ads;
/* version info */
extern const char version_date[], version_time[];
@ -355,9 +346,6 @@ struct ping {
} ping;
/* sock.c */
int ConnectTo (char * host, int port);
void read_loop (void);
int getmaxsock (void);
int sock_connect (int socktype, unsigned long ipaddr, int port, char *sockname, char *module, char *func_read, char *func_write, char *func_error);
int sock_disconnect (char *sockname);
@ -371,15 +359,12 @@ void do_exit (NS_EXIT_TYPE exitcode, char* quitmsg);
void fatal_error(char* file, int line, char* func, char* error_text);
#define FATAL_ERROR(error_text) fatal_error(__FILE__, __LINE__, __PRETTY_FUNCTION__,(error_text));
/* misc.c */
void strip (char * line);
void *smalloc (long size);
char *sstrdup (const char * s);
char *strlower (char * s);
char *strlwr (char * s);
void AddStringToList (char ***List, char S[], int *C);
void FreeList (char **List, int C);
void strip_mirc_codes(char *text);
char *sctime (time_t t);
char *sftime (time_t t);
@ -390,9 +375,8 @@ void parse (char* line);
char *joinbuf (char **av, int ac, int from);
int split_buf (char *buf, char ***argv, int colon_special);
int flood (User * u);
int init_bot (char * nick, char * user, char * host, char * rname, char *modes, char * modname);
int init_bot (char * nick, char * user, char * host, char * rname, const char *modes, char * modname);
int del_bot (char * nick, char * reason);
void Module_Event (char * event, char **av, int ac);
/* ircd specific files */
void prefmsg (char * to, const char * from, char * fmt, ...);
@ -401,83 +385,26 @@ void notice (char *to, const char *from, char *fmt, ...);
void privmsg_list (char *to, char *from, const char **text);
void globops (char * from, char * fmt, ...);
/* dl.c */
int bot_nick_change (char * oldnick, char *newnick);
/* timer.c */
void CheckTimers (void);
/* users.c */
void AddUser (const char *nick, const char *user, const char *host, const char *server, const unsigned long ip, const unsigned long TS);
void DelUser (const char *nick);
void AddRealName (const char *nick, const char *realname);
void Change_User (User *u, const char * newnick);
User *finduser (const char *nick);
void UserDump (char *nick);
void part_u_chan (list_t *list, lnode_t *node, void *v);
void UserMode (const char *nick, const char *modes, int smode);
int init_user_hash (void);
int UserLevel (User *u);
void Do_Away (User *u, const char *awaymsg);
void KillUser (const char *nick);
/* server.c */
void AddServer (char *name, char *uplink, int hops);
void DelServer (char *name);
Server *findserver (const char *name);
void ServerDump (void);
int init_server_hash (void);
void TimerPings (void);
/* ns_help.c */
extern const char *ns_help[];
extern const char *ns_help_on_help[];
extern const char *ns_myuser_help[];
extern const char *ns_shutdown_help[];
extern const char *ns_reload_help[];
extern const char *ns_logs_help[];
#ifdef USE_RAW
extern const char *ns_raw_help[];
#endif
extern const char *ns_debug_help[];
extern const char *ns_userdump_help[];
extern const char *ns_chandump_help[];
extern const char *ns_serverdump_help[];
extern const char *ns_version_help[];
extern const char *ns_load_help[];
extern const char *ns_unload_help[];
extern const char *ns_modlist_help[];
extern const char *ns_jupe_help[];
extern const char *ns_level_help[];
extern const char *ns_modbotlist_help[];
extern const char *ns_modsocklist_help[];
extern const char *ns_modtimerlist_help[];
extern const char *ns_modbotchanlist_help[];
extern const char *ns_info_help[];
/* services.c */
void servicesbot (char *nick, char **av, int ac);
void ns_set_debug (char *u);
void ns_shutdown (User * u, char *reason);
/* chans.c */
void chandump (char *chan);
void part_chan (User * u, char *chan);
void join_chan (User * u, char *chan);
void change_user_nick (Chans * c, char *newnick, char *oldnick);
Chans *findchan (char *chan);
int ChanMode (char *origin, char **av, int ac);
void Change_Topic (char *, Chans *, time_t t, char *);
void ChangeChanUserMode (Chans * c, User * u, int add, long mode);
void kick_chan (User *, char *, User *);
void Change_Chan_Ts (Chans * c, time_t tstime);
int CheckChanMode (Chans * c, long mode);
int IsChanMember(Chans *c, User *u);
int init_chan_hash (void);
/* dns.c */
int dns_lookup (char *str, adns_rrtype type, void (*callback) (char *data, adns_answer * a), char *data);
int init_dns (void);
void do_dns (void);
/* services.c */
typedef void (*bot_cmd_handler) (User * u, char **av, int ac);
int add_services_cmd(const char cmd[MAXCMDSIZE], bot_cmd_handler handler, int minparams, int ulevel, const char** helptext, const char onelinehelp[255]);
int init_services();
int del_services_cmd(const char cmd[MAXCMDSIZE]);
#endif

52
timer.c
View file

@ -27,6 +27,7 @@
#include "dl.h"
#include "log.h"
#include "conf.h"
#include "server.h"
static int midnight = 0;
@ -36,52 +37,14 @@ static void TimerMidnight (void);
void
CheckTimers (void)
{
Mod_Timer *mod_ptr = NULL;
time_t current = me.now;
hscan_t ts;
hnode_t *tn;
/* First, lets see if any modules have a function that is due to run..... */
hash_scan_begin (&ts, th);
while ((tn = hash_scan_next (&ts)) != NULL) {
SET_SEGV_LOCATION();
mod_ptr = hnode_get (tn);
if (current - mod_ptr->lastrun > mod_ptr->interval) {
strlcpy (segv_location, mod_ptr->modname, SEGV_LOCATION_BUFSIZE);
SET_SEGV_INMODULE(mod_ptr->modname);
if (setjmp (sigvbuf) == 0) {
if (mod_ptr->function () < 0) {
nlog(LOG_DEBUG2, LOG_CORE, "Deleting Timer %s for Module %s as requested", mod_ptr->timername, mod_ptr->modname);
hash_scan_delete(th, tn);
hnode_destroy(tn);
free(mod_ptr);
} else {
mod_ptr->lastrun = (int) me.now;
}
} else {
nlog (LOG_CRITICAL, LOG_CORE, "setjmp() Failed, Can't call Module %s\n", mod_ptr->modname);
}
CLEAR_SEGV_INMODULE();
}
}
run_mod_timers();
SET_SEGV_LOCATION();
if (current - ping.last_sent > me.pingtime) {
TimerPings ();
if (me.now - ping.last_sent > me.pingtime) {
PingServers ();
flush_keeper();
ping.last_sent = me.now;
#ifdef DEBUG
if (hash_verify (sockh) == 0) {
nlog (LOG_CRITICAL, LOG_CORE, "Eeeek, Corruption of the socket hash");
}
if (hash_verify (mh) == 0) {
nlog (LOG_CRITICAL, LOG_CORE, "Eeeek, Corruption of the Module hash");
}
if (hash_verify (bh) == 0) {
nlog (LOG_CRITICAL, LOG_CORE, "Eeeek, Corruption of the Bot hash");
}
if (hash_verify (th) == 0) {
nlog (LOG_CRITICAL, LOG_CORE, "Eeeek, Corruption of the Timer hash");
}
verify_hashes();
#endif
/* flush log files */
fflush (NULL);
@ -95,7 +58,7 @@ CheckTimers (void)
}
}
void
static void
TimerMidnight (void)
{
nlog (LOG_DEBUG1, LOG_CORE, "Its midnight!!! -> %s", sctime (me.now));
@ -105,8 +68,7 @@ TimerMidnight (void)
static int
is_midnight (void)
{
time_t current = me.now;
struct tm *ltm = localtime (&current);
struct tm *ltm = localtime (&me.now);
if (ltm->tm_hour == 0)
return 1;

29
timer.h Normal file
View file

@ -0,0 +1,29 @@
/* NeoStats - IRC Statistical Services
** Copyright (c) 1999-2003 Adam Rutter, Justin Hammond, Mark Hetherington
** http://www.neostats.net/
**
** 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
#ifndef _TIMER_H_
#define _TIMER_H_
void CheckTimers (void);
#endif /* _TIMER_H_ */

38
users.c
View file

@ -29,9 +29,13 @@
#include "hash.h"
#include "dl.h"
#include "log.h"
#include "users.h"
#include "chans.h"
static void doDelUser (const char *, int);
static User *new_user (const char *);
hash_t *uh;
static void doDelUser (const char *nick, int killflag);
static User *new_user (const char *nick);
static User *
new_user (const char *nick)
@ -107,7 +111,7 @@ AddRealName (const char *nick, const char *realname)
nlog (LOG_DEBUG2, LOG_CORE, "RealName(%s): %s", nick, realname);
strlcpy (u->realname, realname, MAXREALNAME);
AddStringToList (&av, u->nick, &ac);
Module_Event (EVENT_SIGNON, av, ac);
ModuleEvent (EVENT_SIGNON, av, ac);
free (av);
}
@ -131,7 +135,7 @@ DelUser (const char *nick)
}
static void
doDelUser (const char *nick, int i)
doDelUser (const char *nick, int killflag)
{
User *u;
hnode_t *un;
@ -154,16 +158,16 @@ doDelUser (const char *nick, int i)
/* run the event to delete a user */
AddStringToList (&av, u->nick, &ac);
if (i == 0) {
Module_Event (EVENT_SIGNOFF, av, ac);
} else if (i == 1) {
Module_Event (EVENT_KILL, av, ac);
if (killflag == 0) {
ModuleEvent (EVENT_SIGNOFF, av, ac);
} else if (killflag == 1) {
ModuleEvent (EVENT_KILL, av, ac);
}
free (av);
/* if its one of our bots, remove it from the modlist */
if (findbot (u->nick)) {
if (i == 1)
if (killflag == 1)
nlog (LOG_NOTICE, LOG_CORE, "Deleting Bot %s as it was killed", u->nick);
del_mod_user (u->nick);
}
@ -175,7 +179,7 @@ doDelUser (const char *nick, int i)
}
void
Do_Away (User * u, const char *awaymsg)
UserAway (User * u, const char *awaymsg)
{
char **av;
int ac = 0;
@ -183,11 +187,11 @@ Do_Away (User * u, const char *awaymsg)
AddStringToList (&av, u->nick, &ac);
if ((u->is_away == 1) && (!awaymsg)) {
u->is_away = 0;
Module_Event (EVENT_AWAY, av, ac);
ModuleEvent (EVENT_AWAY, av, ac);
} else if ((u->is_away == 0) && (awaymsg)) {
u->is_away = 1;
AddStringToList (&av, (char *) awaymsg, &ac);
Module_Event (EVENT_AWAY, av, ac);
ModuleEvent (EVENT_AWAY, av, ac);
}
free (av);
}
@ -223,7 +227,7 @@ Change_User (User * u, const char *newnick)
hash_insert (uh, un, u->nick);
AddStringToList (&av, u->nick, &ac);
Module_Event (EVENT_NICKCHANGE, av, ac);
ModuleEvent (EVENT_NICKCHANGE, av, ac);
free (av);
free (oldnick);
}
@ -321,9 +325,9 @@ UserLevel (User * u)
#ifdef CODERHACK
/* this is only cause I dun have the right O lines on some of my "Beta" Networks, so I need to hack this in :) */
if (!strcasecmp (u->nick, "FISH"))
tmplvl = 200;
tmplvl = NS_ULEVEL_ROOT;
if (!strcasecmp (u->nick, "SHMAD"))
tmplvl = 200;
tmplvl = NS_ULEVEL_ROOT;
#endif
#endif
@ -380,9 +384,9 @@ UserMode (const char *nick, const char *modes, int smode)
AddStringToList (&av, (char *) modes, &ac);
if (smode > 0) {
Module_Event (EVENT_SMODE, av, ac);
ModuleEvent (EVENT_SMODE, av, ac);
} else {
Module_Event (EVENT_UMODE, av, ac);
ModuleEvent (EVENT_UMODE, av, ac);
}

38
users.h Normal file
View file

@ -0,0 +1,38 @@
/* NeoStats - IRC Statistical Services
** Copyright (c) 1999-2003 Adam Rutter, Justin Hammond, Mark Hetherington
** http://www.neostats.net/
**
** 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
*/
#ifndef _USERS_H_
#define _USERS_H_
void AddUser (const char *nick, const char *user, const char *host, const char *server, const unsigned long ip, const unsigned long TS);
void DelUser (const char *nick);
void AddRealName (const char *nick, const char *realname);
void Change_User (User *u, const char * newnick);
void UserDump (char *nick);
void part_u_chan (list_t *list, lnode_t *node, void *v);
void UserMode (const char *nick, const char *modes, int smode);
int init_user_hash (void);
void UserAway (User *u, const char *awaymsg);
void KillUser (const char *nick);
#endif /* _USERS_H_ */