mirror of git://git.acid.vegas/unrealircd.git
Updated to 6.0.3
This commit is contained in:
parent
4e71d6fead
commit
252e8547f4
|
@ -9,7 +9,6 @@ extras/c-ares*
|
||||||
config.status
|
config.status
|
||||||
extras/ircdcron/ircd.cron
|
extras/ircdcron/ircd.cron
|
||||||
extras/ircdcron/ircdchk
|
extras/ircdcron/ircdchk
|
||||||
src/modules/snomasks/Makefile
|
|
||||||
src/modules/chanmodes/Makefile
|
src/modules/chanmodes/Makefile
|
||||||
src/modules/extbans/Makefile
|
src/modules/extbans/Makefile
|
||||||
src/modules/usermodes/Makefile
|
src/modules/usermodes/Makefile
|
||||||
|
|
32
Config
32
Config
|
@ -18,7 +18,24 @@
|
||||||
|
|
||||||
# some bits edited by baafie on March 17 2004, every change marked.
|
# some bits edited by baafie on March 17 2004, every change marked.
|
||||||
|
|
||||||
|
# Remove trailing slash in paths (if any)
|
||||||
|
FIX_PATHNAMES () {
|
||||||
|
BASEPATH="${BASEPATH%/}"
|
||||||
|
BINDIR="${BINDIR%/}"
|
||||||
|
DATADIR="${DATADIR%/}"
|
||||||
|
CONFDIR="${CONFDIR%/}"
|
||||||
|
MODULESDIR="${MODULESDIR%/}"
|
||||||
|
LOGDIR="${LOGDIR%/}"
|
||||||
|
CACHEDIR="${CACHEDIR%/}"
|
||||||
|
DOCDIR="${DOCDIR%/}"
|
||||||
|
TMPDIR="${TMPDIR%/}"
|
||||||
|
PRIVATELIBDIR="${PRIVATELIBDIR%/}"
|
||||||
|
SSLDIR="${SSLDIR%/}"
|
||||||
|
CURLDIR="${CURLDIR%/}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create and run the ./configure command with the appropriate
|
||||||
|
# options based on the users settings.
|
||||||
RUN_CONFIGURE () {
|
RUN_CONFIGURE () {
|
||||||
ARG=" "
|
ARG=" "
|
||||||
|
|
||||||
|
@ -72,6 +89,7 @@ fi
|
||||||
ARG="$ARG--with-bindir=$BINDIR "
|
ARG="$ARG--with-bindir=$BINDIR "
|
||||||
ARG="$ARG--with-datadir=$DATADIR "
|
ARG="$ARG--with-datadir=$DATADIR "
|
||||||
ARG="$ARG--with-pidfile=$DATADIR/unrealircd.pid "
|
ARG="$ARG--with-pidfile=$DATADIR/unrealircd.pid "
|
||||||
|
ARG="$ARG--with-controlfile=$DATADIR/unrealircd.ctl "
|
||||||
ARG="$ARG--with-confdir=$CONFDIR "
|
ARG="$ARG--with-confdir=$CONFDIR "
|
||||||
ARG="$ARG--with-modulesdir=$MODULESDIR "
|
ARG="$ARG--with-modulesdir=$MODULESDIR "
|
||||||
ARG="$ARG--with-logdir=$LOGDIR "
|
ARG="$ARG--with-logdir=$LOGDIR "
|
||||||
|
@ -292,6 +310,7 @@ while [ $# -ge 1 ] ; do
|
||||||
if [ -f "config.settings" ] ; then
|
if [ -f "config.settings" ] ; then
|
||||||
. ./config.settings
|
. ./config.settings
|
||||||
fi
|
fi
|
||||||
|
FIX_PATHNAMES
|
||||||
RUN_CONFIGURE
|
RUN_CONFIGURE
|
||||||
cd "$UNREALCWD"
|
cd "$UNREALCWD"
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -356,7 +375,7 @@ echo "We will now ask you a number of questions. You can just press ENTER to acc
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# This needs to be updated each release so auto-upgrading works for settings, modules, etc!!:
|
# This needs to be updated each release so auto-upgrading works for settings, modules, etc!!:
|
||||||
UNREALRELEASES="unrealircd-6.0.1 unrealircd-6.0.0 unrealircd-6.0.0-rc2 unrealircd-6.0.0-rc1 unrealircd-6.0.0-beta4 unrealircd-6.0.0-beta3 unrealircd-6.0.0-beta2 unrealircd-6.0.0-beta1 unrealircd-5.2.3 unrealircd-5.2.2 unrealircd-5.2.1.1 unrealircd-5.2.1 unrealircd-5.2.1-rc1 unrealircd-5.2.0.2 unrealircd-5.2.0.1 unrealircd-5.2.0 unrealircd-5.2.0-rc1 unrealircd-5.0.9.1 unrealircd-5.0.9 unrealircd-5.0.9-rc1 unrealircd-5.0.8 unrealircd-5.0.8-rc1 unrealircd-5.0.7 unrealircd-5.0.7-rc1 unrealircd-5.0.6"
|
UNREALRELEASES="unrealircd-6.0.2 unrealircd-6.0.1.1 unrealircd-6.0.1 unrealircd-6.0.0 unrealircd-6.0.0-rc2 unrealircd-6.0.0-rc1 unrealircd-6.0.0-beta4 unrealircd-6.0.0-beta3 unrealircd-6.0.0-beta2 unrealircd-6.0.0-beta1 unrealircd-5.2.3 unrealircd-5.2.2 unrealircd-5.2.1.1 unrealircd-5.2.1 unrealircd-5.2.1-rc1 unrealircd-5.2.0.2 unrealircd-5.2.0.1 unrealircd-5.2.0 unrealircd-5.2.0-rc1 unrealircd-5.0.9.1 unrealircd-5.0.9 unrealircd-5.0.9-rc1 unrealircd-5.0.8 unrealircd-5.0.8-rc1 unrealircd-5.0.7 unrealircd-5.0.7-rc1 unrealircd-5.0.6"
|
||||||
if [ -f "config.settings" ]; then
|
if [ -f "config.settings" ]; then
|
||||||
. ./config.settings
|
. ./config.settings
|
||||||
else
|
else
|
||||||
|
@ -701,11 +720,12 @@ while [ -z "$TEST" ] ; do
|
||||||
TEST="$GEOIP"
|
TEST="$GEOIP"
|
||||||
echo ""
|
echo ""
|
||||||
echo "GeoIP is a feature that allows converting an IP address to a location (country)"
|
echo "GeoIP is a feature that allows converting an IP address to a location (country)"
|
||||||
echo "You have three options in UnrealIRCd:"
|
echo "Possible build options:"
|
||||||
echo " classic: This is the DEFAULT geoip engine that should work on all systems"
|
echo " classic: This is the DEFAULT geoip engine. It should work on all systems"
|
||||||
echo "libmaxminddb: This uses the libmaxminddb library. If you want to use it then"
|
echo " and receives automatic updates."
|
||||||
|
echo "libmaxminddb: This uses the libmaxminddb library. If you want to use this, then"
|
||||||
echo " you need to install the libmaxminddb library on your system first"
|
echo " you need to install the libmaxminddb library on your system first"
|
||||||
echo " none: Don't built with any geoip feature"
|
echo " none: Don't build with any geoip library (geoip-csv is still built)"
|
||||||
echo "Choose one of: classic, libmaxminddb, none"
|
echo "Choose one of: classic, libmaxminddb, none"
|
||||||
echo $n "[$TEST] -> $c"
|
echo $n "[$TEST] -> $c"
|
||||||
read cc
|
read cc
|
||||||
|
@ -814,6 +834,8 @@ if [ -z "$EXTRAPARA" ]; then
|
||||||
EXTRAPARA="$TEST"
|
EXTRAPARA="$TEST"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
FIX_PATHNAMES
|
||||||
|
|
||||||
rm -f config.settings
|
rm -f config.settings
|
||||||
cat > config.settings << __EOF__
|
cat > config.settings << __EOF__
|
||||||
#
|
#
|
||||||
|
|
|
@ -179,13 +179,13 @@ depend:
|
||||||
install: all
|
install: all
|
||||||
$(INSTALL) -m 0700 -d $(DESTDIR)@BINDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@BINDIR@
|
||||||
$(INSTALL) -m 0700 src/ircd $(DESTDIR)@BINDIR@/unrealircd
|
$(INSTALL) -m 0700 src/ircd $(DESTDIR)@BINDIR@/unrealircd
|
||||||
|
$(INSTALL) -m 0700 src/unrealircdctl $(DESTDIR)@BINDIR@/unrealircdctl
|
||||||
$(INSTALL) -m 0700 extras/unrealircd-upgrade-script $(DESTDIR)@BINDIR@/unrealircd-upgrade-script
|
$(INSTALL) -m 0700 extras/unrealircd-upgrade-script $(DESTDIR)@BINDIR@/unrealircd-upgrade-script
|
||||||
$(INSTALL) -m 0700 -d $(DESTDIR)@DOCDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@DOCDIR@
|
||||||
$(INSTALL) -m 0600 doc/Authors doc/coding-guidelines doc/tao.of.irc doc/KEYS doc/RELEASE-NOTES.md $(DESTDIR)@DOCDIR@
|
$(INSTALL) -m 0600 doc/Authors doc/coding-guidelines doc/tao.of.irc doc/KEYS doc/RELEASE-NOTES.md $(DESTDIR)@DOCDIR@
|
||||||
$(INSTALL) -m 0700 -d $(DESTDIR)@CONFDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@CONFDIR@
|
||||||
$(INSTALL) -m 0600 doc/conf/*.conf $(DESTDIR)@CONFDIR@
|
$(INSTALL) -m 0600 doc/conf/*.conf $(DESTDIR)@CONFDIR@
|
||||||
$(INSTALL) -m 0600 doc/conf/*.motd $(DESTDIR)@CONFDIR@
|
$(INSTALL) -m 0600 doc/conf/*.motd $(DESTDIR)@CONFDIR@
|
||||||
$(INSTALL) -m 0600 doc/conf/modules.sources.list $(DESTDIR)@CONFDIR@ ; \
|
|
||||||
$(INSTALL) -m 0700 unrealircd $(DESTDIR)@SCRIPTDIR@
|
$(INSTALL) -m 0700 unrealircd $(DESTDIR)@SCRIPTDIR@
|
||||||
$(INSTALL) -m 0700 -d $(DESTDIR)@MODULESDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@MODULESDIR@
|
||||||
@rm -f $(DESTDIR)@MODULESDIR@/*.so 1>/dev/null 2>&1
|
@rm -f $(DESTDIR)@MODULESDIR@/*.so 1>/dev/null 2>&1
|
||||||
|
|
|
@ -165,8 +165,7 @@ CFLAGS=$(DBGCFLAG) $(STDOPTIONS) /FS /MP1 /c /Fosrc/
|
||||||
CFLAGSST=$(DBGCFLAGST) $(STDOPTIONS) /FS /MP1 /c /Fosrc/
|
CFLAGSST=$(DBGCFLAGST) $(STDOPTIONS) /FS /MP1 /c /Fosrc/
|
||||||
LFLAGS=kernel32.lib user32.lib gdi32.lib shell32.lib ws2_32.lib advapi32.lib \
|
LFLAGS=kernel32.lib user32.lib gdi32.lib shell32.lib ws2_32.lib advapi32.lib \
|
||||||
dbghelp.lib oldnames.lib comctl32.lib comdlg32.lib $(STDLIBS) \
|
dbghelp.lib oldnames.lib comctl32.lib comdlg32.lib $(STDLIBS) \
|
||||||
/def:UnrealIRCd.def /implib:UnrealIRCd.lib \
|
/nologo $(DBGLFLAG)
|
||||||
/nologo $(DBGLFLAG) /out:UnrealIRCd.exe
|
|
||||||
MODCFLAGS=$(MODDBGCFLAG) $(STDOPTIONS) /D DYNAMIC_LINKING /D MODULE_COMPILE
|
MODCFLAGS=$(MODDBGCFLAG) $(STDOPTIONS) /D DYNAMIC_LINKING /D MODULE_COMPILE
|
||||||
MODLFLAGS=/link /def:src/modules/module.def UnrealIRCd.lib ws2_32.lib $(STDLIBS)
|
MODLFLAGS=/link /def:src/modules/module.def UnrealIRCd.lib ws2_32.lib $(STDLIBS)
|
||||||
|
|
||||||
|
@ -174,10 +173,10 @@ INCLUDES=./include/struct.h ./include/config.h ./include/sys.h \
|
||||||
./include/common.h ./include/version.h ./include/h.h ./include/numeric.h \
|
./include/common.h ./include/version.h ./include/h.h ./include/numeric.h \
|
||||||
./include/msg.h ./include/setup.h ./include/dynconf.h
|
./include/msg.h ./include/setup.h ./include/dynconf.h
|
||||||
|
|
||||||
EXP_OBJ_FILES=src/channel.obj src/send.obj src/socket.obj \
|
EXP_OBJ_FILES=src/ircd_vars.obj src/channel.obj src/send.obj src/socket.obj \
|
||||||
src/conf.obj src/conf_preprocessor.obj \
|
src/conf.obj src/proc_io_server.obj src/conf_preprocessor.obj \
|
||||||
src/fdlist.obj src/dbuf.obj \
|
src/fdlist.obj src/dbuf.obj \
|
||||||
src/hash.obj src/parse.obj src/ircd.obj \
|
src/hash.obj src/parse.obj \
|
||||||
src/whowas.obj \
|
src/whowas.obj \
|
||||||
src/misc.obj src/match.obj src/crule.obj \
|
src/misc.obj src/match.obj src/crule.obj \
|
||||||
src/debug.obj src/support.obj src/list.obj \
|
src/debug.obj src/support.obj src/list.obj \
|
||||||
|
@ -194,7 +193,7 @@ EXP_OBJ_FILES=src/channel.obj src/send.obj src/socket.obj \
|
||||||
src/utf8.obj src/log.obj $(CURLOBJ)
|
src/utf8.obj src/log.obj $(CURLOBJ)
|
||||||
|
|
||||||
OBJ_FILES=$(EXP_OBJ_FILES) src/gui.obj src/service.obj src/windebug.obj src/rtf.obj \
|
OBJ_FILES=$(EXP_OBJ_FILES) src/gui.obj src/service.obj src/windebug.obj src/rtf.obj \
|
||||||
src/editor.obj src/win.obj
|
src/editor.obj src/win.obj src/ircd.obj src/proc_io_client.obj
|
||||||
|
|
||||||
DLL_FILES=\
|
DLL_FILES=\
|
||||||
src/modules/account-notify.dll \
|
src/modules/account-notify.dll \
|
||||||
|
@ -411,7 +410,7 @@ DLL_FILES=\
|
||||||
src/modules/whox.dll
|
src/modules/whox.dll
|
||||||
|
|
||||||
|
|
||||||
ALL: CONF UNREALSVC.EXE UnrealIRCd.exe MODULES
|
ALL: CONF unrealircdctl.exe UNREALSVC.EXE UnrealIRCd.exe MODULES
|
||||||
|
|
||||||
CLEAN:
|
CLEAN:
|
||||||
-@del /Q /S *.dll *.exe *.obj *.pdb *.res *.lib *.exp *.ilk src\version.c >NUL
|
-@del /Q /S *.dll *.exe *.obj *.pdb *.res *.lib *.exp *.ilk src\version.c >NUL
|
||||||
|
@ -424,21 +423,27 @@ CONF:
|
||||||
$(CC) src/windows/config.c
|
$(CC) src/windows/config.c
|
||||||
-@config.exe
|
-@config.exe
|
||||||
|
|
||||||
UnrealIRCd.exe: $(OBJ_FILES) src/windows/win.res
|
UnrealIRCd.exe: $(OBJ_FILES) src/ircd.obj src/windows/win.res
|
||||||
$(LINK) $(LFLAGS) $(OBJ_FILES) src/windows/win.res /MAP
|
$(LINK) $(LFLAGS) /out:UnrealIRCd.exe /def:UnrealIRCd.def /implib:UnrealIRCd.lib $(OBJ_FILES) src/windows/win.res /MAP
|
||||||
-@erase src\windows\win.res
|
-@erase src\windows\win.res
|
||||||
$(MT) -manifest src\windows\UnrealIRCd.exe.manifest -outputresource:UnrealIRCd.exe;1
|
$(MT) -manifest src\windows\UnrealIRCd.exe.manifest -outputresource:UnrealIRCd.exe;1
|
||||||
!IFNDEF DEBUGEXTRA
|
|
||||||
@echo Standard version built
|
unrealircdctl.exe: $(OBJ_FILES) src/unrealircdctl.obj src/proc_io_client.obj
|
||||||
!ELSE
|
$(LINK) $(LFLAGS) /SUBSYSTEM:CONSOLE /out:unrealircdctl.exe $(OBJ_FILES) src/unrealircdctl.obj
|
||||||
@echo Extra-Debug version built ...
|
$(MT) -manifest src\windows\unrealircdctl.exe.manifest -outputresource:unrealircdctl.exe;1
|
||||||
!ENDIF
|
|
||||||
|
# alternative option -- FIXME: REMOVE / CHOOSE
|
||||||
|
#unrealircdctl.exe: $(OBJ_FILES) src/unrealircdctl.obj src/proc_io_client.obj src/windows/unrealircdctl.res
|
||||||
|
# $(LINK) $(LFLAGS) /out:unrealircdctl.exe $(OBJ_FILES) src/unrealircdctl.obj src/windows/unrealircdctl.res
|
||||||
|
|
||||||
#Source files
|
#Source files
|
||||||
|
|
||||||
src/version.obj: src/version.c
|
src/version.obj: src/version.c
|
||||||
$(CC) $(CFLAGS) src/version.c
|
$(CC) $(CFLAGS) src/version.c
|
||||||
|
|
||||||
|
src/ircd_vars.obj: src/ircd_vars.c $(INCLUDES)
|
||||||
|
$(CC) $(CFLAGS) src/ircd_vars.c
|
||||||
|
|
||||||
src/parse.obj: src/parse.c $(INCLUDES)
|
src/parse.obj: src/parse.c $(INCLUDES)
|
||||||
$(CC) $(CFLAGS) src/parse.c
|
$(CC) $(CFLAGS) src/parse.c
|
||||||
|
|
||||||
|
@ -485,6 +490,12 @@ src/dns.obj: src/dns.c $(INCLUDES)
|
||||||
src/conf.obj: src/conf.c $(INCLUDES)
|
src/conf.obj: src/conf.c $(INCLUDES)
|
||||||
$(CC) $(CFLAGS) src/conf.c
|
$(CC) $(CFLAGS) src/conf.c
|
||||||
|
|
||||||
|
src/proc_io_server.obj: src/proc_io_server.c $(INCLUDES)
|
||||||
|
$(CC) $(CFLAGS) src/proc_io_server.c
|
||||||
|
|
||||||
|
src/proc_io_client.obj: src/proc_io_client.c $(INCLUDES)
|
||||||
|
$(CC) $(CFLAGS) src/proc_io_client.c
|
||||||
|
|
||||||
src/conf_preprocessor.obj: src/conf_preprocessor.c $(INCLUDES)
|
src/conf_preprocessor.obj: src/conf_preprocessor.c $(INCLUDES)
|
||||||
$(CC) $(CFLAGS) src/conf_preprocessor.c
|
$(CC) $(CFLAGS) src/conf_preprocessor.c
|
||||||
|
|
||||||
|
@ -540,6 +551,9 @@ src/win.obj: src/windows/win.c $(INCLUDES)
|
||||||
src/unrealsvc.obj: src/windows/unrealsvc.c $(INCLUDES)
|
src/unrealsvc.obj: src/windows/unrealsvc.c $(INCLUDES)
|
||||||
$(CC) $(CFLAGSST) src/windows/unrealsvc.c
|
$(CC) $(CFLAGSST) src/windows/unrealsvc.c
|
||||||
|
|
||||||
|
src/unrealircdctl.obj: src/unrealircdctl.c $(INCLUDES)
|
||||||
|
$(CC) $(CFLAGS) src/unrealircdctl.c
|
||||||
|
|
||||||
src/modules.obj: src/modules.c $(INCLUDES)
|
src/modules.obj: src/modules.c $(INCLUDES)
|
||||||
$(CC) $(CFLAGS) src/modules.c
|
$(CC) $(CFLAGS) src/modules.c
|
||||||
|
|
||||||
|
@ -623,6 +637,10 @@ src/windows/unrealsvc.res: src/windows/unrealsvc.rc
|
||||||
$(RC) /l 0x409 /fosrc/windows/unrealsvc.res /i ./include /i ./src \
|
$(RC) /l 0x409 /fosrc/windows/unrealsvc.res /i ./include /i ./src \
|
||||||
/d NDEBUG src/windows/unrealsvc.rc
|
/d NDEBUG src/windows/unrealsvc.rc
|
||||||
|
|
||||||
|
src/windows/unrealircdctl.res: src/windows/unrealircdctl.rc
|
||||||
|
$(RC) /l 0x409 /fosrc/windows/unrealircdctl.res /i ./include /i ./src \
|
||||||
|
/d NDEBUG src/windows/unrealircdctl.rc
|
||||||
|
|
||||||
################# Modules #################
|
################# Modules #################
|
||||||
|
|
||||||
CUSTOMMODULE: src/modules/third/$(MODULEFILE).c
|
CUSTOMMODULE: src/modules/third/$(MODULEFILE).c
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.69 for unrealircd 6.0.1.1.
|
# Generated by GNU Autoconf 2.69 for unrealircd 6.0.3.
|
||||||
#
|
#
|
||||||
# Report bugs to <https://bugs.unrealircd.org/>.
|
# Report bugs to <https://bugs.unrealircd.org/>.
|
||||||
#
|
#
|
||||||
|
@ -580,8 +580,8 @@ MAKEFLAGS=
|
||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='unrealircd'
|
PACKAGE_NAME='unrealircd'
|
||||||
PACKAGE_TARNAME='unrealircd'
|
PACKAGE_TARNAME='unrealircd'
|
||||||
PACKAGE_VERSION='6.0.1.1'
|
PACKAGE_VERSION='6.0.3'
|
||||||
PACKAGE_STRING='unrealircd 6.0.1.1'
|
PACKAGE_STRING='unrealircd 6.0.3'
|
||||||
PACKAGE_BUGREPORT='https://bugs.unrealircd.org/'
|
PACKAGE_BUGREPORT='https://bugs.unrealircd.org/'
|
||||||
PACKAGE_URL='https://unrealircd.org/'
|
PACKAGE_URL='https://unrealircd.org/'
|
||||||
|
|
||||||
|
@ -659,6 +659,7 @@ PKG_CONFIG_LIBDIR
|
||||||
PKG_CONFIG_PATH
|
PKG_CONFIG_PATH
|
||||||
PKG_CONFIG
|
PKG_CONFIG
|
||||||
LDFLAGS_PRIVATELIBS
|
LDFLAGS_PRIVATELIBS
|
||||||
|
CONTROLFILE
|
||||||
PIDFILE
|
PIDFILE
|
||||||
DOCDIR
|
DOCDIR
|
||||||
PERMDATADIR
|
PERMDATADIR
|
||||||
|
@ -752,6 +753,7 @@ with_tmpdir
|
||||||
with_datadir
|
with_datadir
|
||||||
with_docdir
|
with_docdir
|
||||||
with_pidfile
|
with_pidfile
|
||||||
|
with_controlfile
|
||||||
with_privatelibdir
|
with_privatelibdir
|
||||||
with_maxconnections
|
with_maxconnections
|
||||||
with_no_operoverride
|
with_no_operoverride
|
||||||
|
@ -1345,7 +1347,7 @@ if test "$ac_init_help" = "long"; then
|
||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures unrealircd 6.0.1.1 to adapt to many kinds of systems.
|
\`configure' configures unrealircd 6.0.3 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
|
@ -1411,7 +1413,7 @@ fi
|
||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of unrealircd 6.0.1.1:";;
|
short | recursive ) echo "Configuration of unrealircd 6.0.3:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
|
@ -1460,6 +1462,7 @@ Optional Packages:
|
||||||
--with-datadir=path Specify the directory where permanent data is stored
|
--with-datadir=path Specify the directory where permanent data is stored
|
||||||
--with-docdir=path Specify the directory where documentation is stored
|
--with-docdir=path Specify the directory where documentation is stored
|
||||||
--with-pidfile=path Specify the path of the pid file
|
--with-pidfile=path Specify the path of the pid file
|
||||||
|
--with-controlfile=path Specify the path of the control socket
|
||||||
--with-privatelibdir=path
|
--with-privatelibdir=path
|
||||||
Specify the directory where private libraries are
|
Specify the directory where private libraries are
|
||||||
stored. Disable when building a package for a distro
|
stored. Disable when building a package for a distro
|
||||||
|
@ -1586,7 +1589,7 @@ fi
|
||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
unrealircd configure 6.0.1.1
|
unrealircd configure 6.0.3
|
||||||
generated by GNU Autoconf 2.69
|
generated by GNU Autoconf 2.69
|
||||||
|
|
||||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
@ -1955,7 +1958,7 @@ cat >config.log <<_ACEOF
|
||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by unrealircd $as_me 6.0.1.1, which was
|
It was created by unrealircd $as_me 6.0.3, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
|
@ -2363,7 +2366,7 @@ _ACEOF
|
||||||
|
|
||||||
|
|
||||||
# Minor version number (e.g.: Z in X.Y.Z)
|
# Minor version number (e.g.: Z in X.Y.Z)
|
||||||
UNREAL_VERSION_MINOR="1"
|
UNREAL_VERSION_MINOR="3"
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
#define UNREAL_VERSION_MINOR $UNREAL_VERSION_MINOR
|
#define UNREAL_VERSION_MINOR $UNREAL_VERSION_MINOR
|
||||||
|
@ -2373,7 +2376,7 @@ _ACEOF
|
||||||
# The version suffix such as a beta marker or release candidate
|
# The version suffix such as a beta marker or release candidate
|
||||||
# marker. (e.g.: -rcX for unrealircd-3.2.9-rcX). This macro is a
|
# marker. (e.g.: -rcX for unrealircd-3.2.9-rcX). This macro is a
|
||||||
# string instead of an integer because it contains arbitrary data.
|
# string instead of an integer because it contains arbitrary data.
|
||||||
UNREAL_VERSION_SUFFIX=".1"
|
UNREAL_VERSION_SUFFIX=""
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
#define UNREAL_VERSION_SUFFIX "$UNREAL_VERSION_SUFFIX"
|
#define UNREAL_VERSION_SUFFIX "$UNREAL_VERSION_SUFFIX"
|
||||||
|
@ -6548,6 +6551,25 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Check whether --with-controlfile was given.
|
||||||
|
if test "${with_controlfile+set}" = set; then :
|
||||||
|
withval=$with_controlfile;
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define CONTROLFILE "$withval"
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
CONTROLFILE="$withval"
|
||||||
|
else
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define CONTROLFILE "$HOME/unrealircd/data/unrealircd.ctl"
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
CONTROLFILE="$HOME/unrealircd/data/unrealircd.ctl"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check whether --with-privatelibdir was given.
|
# Check whether --with-privatelibdir was given.
|
||||||
if test "${with_privatelibdir+set}" = set; then :
|
if test "${with_privatelibdir+set}" = set; then :
|
||||||
withval=$with_privatelibdir;
|
withval=$with_privatelibdir;
|
||||||
|
@ -6589,6 +6611,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Check whether --with-maxconnections was given.
|
# Check whether --with-maxconnections was given.
|
||||||
if test "${with_maxconnections+set}" = set; then :
|
if test "${with_maxconnections+set}" = set; then :
|
||||||
withval=$with_maxconnections; ac_fd=$withval
|
withval=$with_maxconnections; ac_fd=$withval
|
||||||
|
@ -7438,7 +7461,7 @@ fi
|
||||||
|
|
||||||
if test "$has_system_pcre2" = "no"; then :
|
if test "$has_system_pcre2" = "no"; then :
|
||||||
|
|
||||||
pcre2_version="10.36"
|
pcre2_version="10.39"
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: extracting PCRE2 regex library" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: extracting PCRE2 regex library" >&5
|
||||||
$as_echo "extracting PCRE2 regex library" >&6; }
|
$as_echo "extracting PCRE2 regex library" >&6; }
|
||||||
cur_dir=`pwd`
|
cur_dir=`pwd`
|
||||||
|
@ -7455,7 +7478,7 @@ fi
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: configuring PCRE2 regex library" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: configuring PCRE2 regex library" >&5
|
||||||
$as_echo "configuring PCRE2 regex library" >&6; }
|
$as_echo "configuring PCRE2 regex library" >&6; }
|
||||||
cd pcre2-$pcre2_version
|
cd pcre2-$pcre2_version
|
||||||
./configure --enable-jit --enable-shared --disable-unicode --prefix=$cur_dir/extras/pcre2 --libdir=$PRIVATELIBDIR || exit 1
|
./configure --enable-jit --enable-shared --prefix=$cur_dir/extras/pcre2 --libdir=$PRIVATELIBDIR || exit 1
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: compiling PCRE2 regex library" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: compiling PCRE2 regex library" >&5
|
||||||
$as_echo "compiling PCRE2 regex library" >&6; }
|
$as_echo "compiling PCRE2 regex library" >&6; }
|
||||||
$ac_cv_prog_MAKER || exit 1
|
$ac_cv_prog_MAKER || exit 1
|
||||||
|
@ -7798,7 +7821,7 @@ fi
|
||||||
|
|
||||||
if test "$has_system_cares" = "no"; then :
|
if test "$has_system_cares" = "no"; then :
|
||||||
|
|
||||||
cares_version="1.17.2"
|
cares_version="1.18.1"
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: extracting c-ares resolver library" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: extracting c-ares resolver library" >&5
|
||||||
$as_echo "extracting c-ares resolver library" >&6; }
|
$as_echo "extracting c-ares resolver library" >&6; }
|
||||||
cur_dir=`pwd`
|
cur_dir=`pwd`
|
||||||
|
@ -9391,7 +9414,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by unrealircd $as_me 6.0.1.1, which was
|
This file was extended by unrealircd $as_me 6.0.3, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
|
@ -9454,7 +9477,7 @@ _ACEOF
|
||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
unrealircd config.status 6.0.1.1
|
unrealircd config.status 6.0.3
|
||||||
configured by $0, generated by GNU Autoconf 2.69,
|
configured by $0, generated by GNU Autoconf 2.69,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
|
19
configure.ac
19
configure.ac
|
@ -7,7 +7,7 @@ dnl src/windows/unrealinst.iss
|
||||||
dnl doc/Config.header
|
dnl doc/Config.header
|
||||||
dnl src/version.c.SH
|
dnl src/version.c.SH
|
||||||
|
|
||||||
AC_INIT([unrealircd], [6.0.1.1], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/])
|
AC_INIT([unrealircd], [6.0.3], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/])
|
||||||
AC_CONFIG_SRCDIR([src/ircd.c])
|
AC_CONFIG_SRCDIR([src/ircd.c])
|
||||||
AC_CONFIG_HEADER([include/setup.h])
|
AC_CONFIG_HEADER([include/setup.h])
|
||||||
AC_CONFIG_AUX_DIR([autoconf])
|
AC_CONFIG_AUX_DIR([autoconf])
|
||||||
|
@ -34,13 +34,13 @@ UNREAL_VERSION_MAJOR=["0"]
|
||||||
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MAJOR], [$UNREAL_VERSION_MAJOR], [Major version number (e.g.: Y for X.Y.Z)])
|
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MAJOR], [$UNREAL_VERSION_MAJOR], [Major version number (e.g.: Y for X.Y.Z)])
|
||||||
|
|
||||||
# Minor version number (e.g.: Z in X.Y.Z)
|
# Minor version number (e.g.: Z in X.Y.Z)
|
||||||
UNREAL_VERSION_MINOR=["1"]
|
UNREAL_VERSION_MINOR=["3"]
|
||||||
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MINOR], [$UNREAL_VERSION_MINOR], [Minor version number (e.g.: Z for X.Y.Z)])
|
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MINOR], [$UNREAL_VERSION_MINOR], [Minor version number (e.g.: Z for X.Y.Z)])
|
||||||
|
|
||||||
# The version suffix such as a beta marker or release candidate
|
# The version suffix such as a beta marker or release candidate
|
||||||
# marker. (e.g.: -rcX for unrealircd-3.2.9-rcX). This macro is a
|
# marker. (e.g.: -rcX for unrealircd-3.2.9-rcX). This macro is a
|
||||||
# string instead of an integer because it contains arbitrary data.
|
# string instead of an integer because it contains arbitrary data.
|
||||||
UNREAL_VERSION_SUFFIX=[".1"]
|
UNREAL_VERSION_SUFFIX=[""]
|
||||||
AC_DEFINE_UNQUOTED([UNREAL_VERSION_SUFFIX], ["$UNREAL_VERSION_SUFFIX"], [Version suffix such as a beta marker or release candidate marker. (e.g.: -rcX for unrealircd-3.2.9-rcX)])
|
AC_DEFINE_UNQUOTED([UNREAL_VERSION_SUFFIX], ["$UNREAL_VERSION_SUFFIX"], [Version suffix such as a beta marker or release candidate marker. (e.g.: -rcX for unrealircd-3.2.9-rcX)])
|
||||||
|
|
||||||
AC_PATH_PROG(RM,rm)
|
AC_PATH_PROG(RM,rm)
|
||||||
|
@ -484,6 +484,12 @@ AC_ARG_WITH(pidfile, [AS_HELP_STRING([--with-pidfile=path],[Specify the path of
|
||||||
[AC_DEFINE_UNQUOTED([PIDFILE], ["$HOME/unrealircd/data/unrealircd.pid"], [Define the path of the pid file])
|
[AC_DEFINE_UNQUOTED([PIDFILE], ["$HOME/unrealircd/data/unrealircd.pid"], [Define the path of the pid file])
|
||||||
PIDFILE="$HOME/unrealircd/data/unrealircd.pid"])
|
PIDFILE="$HOME/unrealircd/data/unrealircd.pid"])
|
||||||
|
|
||||||
|
AC_ARG_WITH(controlfile, [AS_HELP_STRING([--with-controlfile=path],[Specify the path of the control socket])],
|
||||||
|
[AC_DEFINE_UNQUOTED([CONTROLFILE], ["$withval"], [Define the path of the control socket])
|
||||||
|
CONTROLFILE="$withval"],
|
||||||
|
[AC_DEFINE_UNQUOTED([CONTROLFILE], ["$HOME/unrealircd/data/unrealircd.ctl"], [Define the path of the control socket])
|
||||||
|
CONTROLFILE="$HOME/unrealircd/data/unrealircd.ctl"])
|
||||||
|
|
||||||
dnl Ensure that this “feature” can be disabled as it makes it harder to package unrealircd.
|
dnl Ensure that this “feature” can be disabled as it makes it harder to package unrealircd.
|
||||||
dnl Users have always been able to specify “./configure LDFLAGS=-Wl,-rpath,/path/to/blah”—binki
|
dnl Users have always been able to specify “./configure LDFLAGS=-Wl,-rpath,/path/to/blah”—binki
|
||||||
AC_ARG_WITH(privatelibdir, [AS_HELP_STRING([--with-privatelibdir=path],[Specify the directory where private libraries are stored. Disable when building a package for a distro])],
|
AC_ARG_WITH(privatelibdir, [AS_HELP_STRING([--with-privatelibdir=path],[Specify the directory where private libraries are stored. Disable when building a package for a distro])],
|
||||||
|
@ -514,6 +520,7 @@ dnl well, Because DATADIR conflicts with the Windows SDK header files.. amazing.
|
||||||
AC_SUBST(PERMDATADIR)
|
AC_SUBST(PERMDATADIR)
|
||||||
AC_SUBST(DOCDIR)
|
AC_SUBST(DOCDIR)
|
||||||
AC_SUBST(PIDFILE)
|
AC_SUBST(PIDFILE)
|
||||||
|
AC_SUBST(CONTROLFILE)
|
||||||
AC_SUBST(LDFLAGS_PRIVATELIBS)
|
AC_SUBST(LDFLAGS_PRIVATELIBS)
|
||||||
|
|
||||||
AC_ARG_WITH(maxconnections, [AS_HELP_STRING([--with-maxconnections=size], [Specify the max file descriptors to use])],
|
AC_ARG_WITH(maxconnections, [AS_HELP_STRING([--with-maxconnections=size], [Specify the max file descriptors to use])],
|
||||||
|
@ -576,7 +583,7 @@ AS_IF([test "x$PRIVATELIBDIR" != "x"], [rm -f "$PRIVATELIBDIR/"libpcre2*])],[has
|
||||||
|
|
||||||
AS_IF([test "$has_system_pcre2" = "no"], [
|
AS_IF([test "$has_system_pcre2" = "no"], [
|
||||||
dnl REMEMBER TO CHANGE WITH A NEW PCRE2 RELEASE!
|
dnl REMEMBER TO CHANGE WITH A NEW PCRE2 RELEASE!
|
||||||
pcre2_version="10.36"
|
pcre2_version="10.39"
|
||||||
AC_MSG_RESULT(extracting PCRE2 regex library)
|
AC_MSG_RESULT(extracting PCRE2 regex library)
|
||||||
cur_dir=`pwd`
|
cur_dir=`pwd`
|
||||||
cd extras
|
cd extras
|
||||||
|
@ -593,7 +600,7 @@ else
|
||||||
fi
|
fi
|
||||||
AC_MSG_RESULT(configuring PCRE2 regex library)
|
AC_MSG_RESULT(configuring PCRE2 regex library)
|
||||||
cd pcre2-$pcre2_version
|
cd pcre2-$pcre2_version
|
||||||
./configure --enable-jit --enable-shared --disable-unicode --prefix=$cur_dir/extras/pcre2 --libdir=$PRIVATELIBDIR || exit 1
|
./configure --enable-jit --enable-shared --prefix=$cur_dir/extras/pcre2 --libdir=$PRIVATELIBDIR || exit 1
|
||||||
AC_MSG_RESULT(compiling PCRE2 regex library)
|
AC_MSG_RESULT(compiling PCRE2 regex library)
|
||||||
$ac_cv_prog_MAKER || exit 1
|
$ac_cv_prog_MAKER || exit 1
|
||||||
AC_MSG_RESULT(installing PCRE2 regex library)
|
AC_MSG_RESULT(installing PCRE2 regex library)
|
||||||
|
@ -716,7 +723,7 @@ AS_IF([test "$has_system_cares" = "no"], [
|
||||||
dnl REMEMBER TO CHANGE WITH A NEW C-ARES RELEASE!
|
dnl REMEMBER TO CHANGE WITH A NEW C-ARES RELEASE!
|
||||||
dnl NOTE: when changing this here, ALSO change it in extras/curlinstall
|
dnl NOTE: when changing this here, ALSO change it in extras/curlinstall
|
||||||
dnl and in the comment in this file around line 400!
|
dnl and in the comment in this file around line 400!
|
||||||
cares_version="1.17.2"
|
cares_version="1.18.1"
|
||||||
AC_MSG_RESULT(extracting c-ares resolver library)
|
AC_MSG_RESULT(extracting c-ares resolver library)
|
||||||
cur_dir=`pwd`
|
cur_dir=`pwd`
|
||||||
cd extras
|
cd extras
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
\___/|_| |_|_| \___|\__,_|_|\___/\_| \_| \____/\__,_|
|
\___/|_| |_|_| \___|\__,_|_|\___/\_| \_| \____/\__,_|
|
||||||
|
|
||||||
Configuration Program
|
Configuration Program
|
||||||
for UnrealIRCd 6.0.1.1
|
for UnrealIRCd 6.0.3
|
||||||
|
|
||||||
This program will help you to compile your IRC server, and ask you
|
This program will help you to compile your IRC server, and ask you
|
||||||
questions regarding the compile-time settings of it during the process.
|
questions regarding the compile-time settings of it during the process.
|
||||||
|
|
|
@ -1,8 +1,139 @@
|
||||||
|
UnrealIRCd 6.0.3
|
||||||
|
=================
|
||||||
|
|
||||||
|
A number of serious issues were discovered in UnrealIRCd 6. Among these is
|
||||||
|
an issue which will likely crash the IRCd sooner or later if you /REHASH
|
||||||
|
with any active clients connected.
|
||||||
|
We suggest everyone who is running UnrealIRCd 6 to upgrade to 6.0.3.
|
||||||
|
|
||||||
|
If you are already running UnrealIRCd 6 then read below. Otherwise, jump
|
||||||
|
straight to the [summary about UnrealIRCd 6](#Summary) to learn more
|
||||||
|
about UnrealIRCd 6.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
* Crash in `WATCH` if the IRCd has been rehashed at least once. After doing
|
||||||
|
a `REHASH` with active clients it will likely corrupt memory. It may take
|
||||||
|
several days until after the rehash for the crash to occur, or even
|
||||||
|
weeks/months on smaller networks (accidental triggering, that is).
|
||||||
|
* A `REHASH` with certain remote includes setups could cause a crash or
|
||||||
|
other weird and confusing problems such as complaining about unable
|
||||||
|
to open an ipv6-database or missing snomask configuration.
|
||||||
|
This only affected some people with remote includes, not all.
|
||||||
|
* Potential out-of-bounds write in sending code. In practice it seems
|
||||||
|
harmless on most servers but this cannot be 100% guaranteed.
|
||||||
|
* Unlikely triggered log message would log uninitialized stack data to the
|
||||||
|
log file or send it to ircops.
|
||||||
|
* Channel ops could not remove halfops from a user (`-h`).
|
||||||
|
* After using the `RESTART` command (not recommended) the new IRCd was
|
||||||
|
often no longer writing to log files.
|
||||||
|
* Fix compile problem if you choose to use cURL remote includes but don't
|
||||||
|
have cURL on the system and ask UnrealIRCd to compile cURL.
|
||||||
|
|
||||||
|
Enhancements:
|
||||||
|
* The default text log format on disk changed. It now includes the server
|
||||||
|
name where the event was generated. Without this, it was sometimes
|
||||||
|
difficult to trace problems, since previously it sometimes looked like
|
||||||
|
there was a problem on your server when it was actually another server
|
||||||
|
on the network.
|
||||||
|
* Old log format: `[DATE TIME] subsystem.EVENT_ID loglevel: ........`
|
||||||
|
* New log format: `[DATE TIME] servername subsystem.EVENT_ID loglevel: ........`
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* Any MOTD lines added by services via
|
||||||
|
[`SVSMOTD`](https://www.unrealircd.org/docs/MOTD_and_Rules#SVSMOTD)
|
||||||
|
are now shown at the end of the MOTD-on-connect (unless using a shortmotd).
|
||||||
|
Previously the lines were only shown if you manually ran the `MOTD` command.
|
||||||
|
|
||||||
|
Developers and protocol:
|
||||||
|
* `LIST C<xx` now means: filter on channels that are created less
|
||||||
|
than `xx` minutes ago. This is the opposite of what we had earlier.
|
||||||
|
`LIST T<xx` is now supported as well (topic changed in last xx minutes),
|
||||||
|
it was already advertised in ELIST but support was not enabled previously.
|
||||||
|
|
||||||
|
UnrealIRCd 6.0.2
|
||||||
|
-----------------
|
||||||
|
UnrealIRCd 6.0.2 comes with several nice feature enhancements along with
|
||||||
|
some fixes. It also includes a fix for a crash bug that can be triggered
|
||||||
|
by ordinary users.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
* Fix crash that can be triggered by regular users if you have any `deny dcc`
|
||||||
|
blocks in the config or any spamfilters with the `d` (DCC) target.
|
||||||
|
NOTE: You don't *have* to upgrade to 6.0.2 to fix this, you can also
|
||||||
|
hot-patch this issue without restart, see the news announcement.
|
||||||
|
* Windows: fix crash with IPv6 clients (local or remote) due to GeoIP lookup
|
||||||
|
* Fix infinite hang on "Loading IRCd configuration" if DNS is not working.
|
||||||
|
For example if the 1st DNS server in `/etc/resolv.conf` is down or refusing
|
||||||
|
requests.
|
||||||
|
* Some `MODE` server-to-server commands were missing a timestamp at the end,
|
||||||
|
even though this is mandatory for modes coming from a server.
|
||||||
|
* The [channeldb](https://www.unrealircd.org/docs/Set_block#set::channeldb)
|
||||||
|
module now converts letter extbans to named extbans (eg `~a` to `~account`).
|
||||||
|
Previously it did not, which caused letter extbans to appear in the banlist.
|
||||||
|
Later on, when linking servers, this would cause duplicate entries to appear
|
||||||
|
as well, with both the old and new format. The extbans were still effective
|
||||||
|
though, so this is mostly a visual +b/+e/+I list issue.
|
||||||
|
* Some [Extended Server Bans](https://www.unrealircd.org/docs/Extended_server_bans)
|
||||||
|
were not working correctly for WEBIRC proxies. In particular, a server ban
|
||||||
|
or exempt (ELINE) on `~country:XX` was only checked against the WEBIRC proxy.
|
||||||
|
|
||||||
|
Enhancements:
|
||||||
|
* Support for [logging to a channel](https://www.unrealircd.org/docs/Log_block#Logging_to_a_channel).
|
||||||
|
Similar to snomasks but then for channels.
|
||||||
|
* Command line interface changes:
|
||||||
|
* The [CLI tool](https://www.unrealircd.org/docs/Command_Line_Interface) now
|
||||||
|
communicates to the running UnrealIRCd process via a UNIX socket to
|
||||||
|
send commands and retrieve output.
|
||||||
|
* The command `./unrealircd rehash` will now show the rehash output,
|
||||||
|
including warnings and errors, and return a proper exit code.
|
||||||
|
* The same for `./unrealircd reloadtls`
|
||||||
|
* New command `./unrealircd status` to show if UnrealIRCd is running, the
|
||||||
|
version, channel and user count, ..
|
||||||
|
* The command `./unrealircd genlinkblock` is now
|
||||||
|
[documented](https://www.unrealircd.org/docs/Linking_servers_(genlinkblock))
|
||||||
|
and is referred to from the
|
||||||
|
[Linking servers tutorial](https://www.unrealircd.org/docs/Tutorial:_Linking_servers).
|
||||||
|
* On Windows in the `C:\Program Files\UnrealIRCd 6\bin` directory there is
|
||||||
|
now an `unrealircdctl.exe` that can be used to do similar things to what
|
||||||
|
you can do on *NIX. Supported operations are: `rehash`, `reloadtls`,
|
||||||
|
`mkpasswd`, `gencloak` and `spkifp`.
|
||||||
|
* New option [set::server-notice-show-event](https://www.unrealircd.org/docs/Set_block#set::server-notice-show-event)
|
||||||
|
which can be set to `no` to hide the event information (eg `connect.LOCAL_CLIENT_CONNECT`)
|
||||||
|
in server notices. This can be overridden per-oper in the
|
||||||
|
[Oper block](https://www.unrealircd.org/docs/Oper_block) via oper::server-notice-show-event.
|
||||||
|
* Support for IRC over UNIX sockets (on the same machine), if you specify a
|
||||||
|
file in the [listen block](https://www.unrealircd.org/docs/Listen_block)
|
||||||
|
instead of an ip/port. This probably won't be used much, but the option is
|
||||||
|
there. Users will show up with a host of `localhost` and IP `127.0.0.1` to
|
||||||
|
keep things simple.
|
||||||
|
* The `MAP` command now shows percentages of users
|
||||||
|
* Add `WHO` option to search clients by time connected (eg. `WHO <300 t` to
|
||||||
|
search for less than 300 seconds)
|
||||||
|
* Rate limiting of `MODE nick -x` and `-t` via new `vhost-flood` option in
|
||||||
|
[set::anti-flood block](https://www.unrealircd.org/docs/Anti-flood_settings).
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* Update Russian `help.ru.conf`.
|
||||||
|
|
||||||
|
Developers and protocol:
|
||||||
|
* People packaging UnrealIRCd (eg. to an .rpm/.deb):
|
||||||
|
* Be sure to pass the new `--with-controlfile` configure option
|
||||||
|
* There is now an `unrealircdctl` tool that the `unrealircd` shell script
|
||||||
|
uses, it is expected to be in `bindir`.
|
||||||
|
* `SVSMODE #chan -b nick` will now correctly remove extbans that prevent `nick`
|
||||||
|
from joining. This fixes a bug where it would remove too much (for `~time`)
|
||||||
|
or not remove extbans (most other extbans, eg `~account`).
|
||||||
|
`SVSMODE #chan -b` has also been fixed accordingly (remove all bans
|
||||||
|
preventing joins).
|
||||||
|
Note that all these commands do not remove bans that do not affect joins,
|
||||||
|
such as `~quiet` or `~text`.
|
||||||
|
* For module coders: setting the `EXTBOPT_CHSVSMODE` flag in `extban.options`
|
||||||
|
is no longer useful, the flag is ignored. We now decide based on
|
||||||
|
`BANCHK_JOIN` being in `extban.is_banned_events` if the ban should be
|
||||||
|
removed or not upon SVS(2)MODE -b.
|
||||||
|
|
||||||
UnrealIRCd 6.0.1.1
|
UnrealIRCd 6.0.1.1
|
||||||
===================
|
-------------------
|
||||||
If you are already running UnrealIRCd 6 then read below on the
|
|
||||||
changes between 6.0.0 and 6.0.1(.1). Otherwise, jump straight to the
|
|
||||||
[summary about UnrealIRCd 6](#Summary) to learn more about UnrealIRCd 6.
|
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
* In 6.0.1.1: extended bans were not properly synced between U5 and U6.
|
* In 6.0.1.1: extended bans were not properly synced between U5 and U6.
|
||||||
|
@ -89,6 +220,8 @@ Enhancements
|
||||||
* Colors are enabled by default in snomask server notices, these can be disabled via
|
* Colors are enabled by default in snomask server notices, these can be disabled via
|
||||||
[set::server-notice-colors](https://www.unrealircd.org/docs/Set_block#set::server-notice-colors)
|
[set::server-notice-colors](https://www.unrealircd.org/docs/Set_block#set::server-notice-colors)
|
||||||
and also in [oper::server-notice-colors](https://www.unrealircd.org/docs/Oper_block)
|
and also in [oper::server-notice-colors](https://www.unrealircd.org/docs/Oper_block)
|
||||||
|
* Support for [logging to a channel](https://www.unrealircd.org/docs/Log_block#Logging_to_a_channel).
|
||||||
|
Similar to snomasks but then for channels. *Requires UnrealIRCd 6.0.2 or later*
|
||||||
* Almost all channel modes are modularized
|
* Almost all channel modes are modularized
|
||||||
* Only the three list modes (+b/+e/+I) are still in the core
|
* Only the three list modes (+b/+e/+I) are still in the core
|
||||||
* The five [level modes](https://www.unrealircd.org/docs/Channel_Modes#Access_levels)
|
* The five [level modes](https://www.unrealircd.org/docs/Channel_Modes#Access_levels)
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
https://modules.unrealircd.org/modules.list
|
|
|
@ -1,228 +1,50 @@
|
||||||
/* Server bans snomask - 'b' */
|
|
||||||
log {
|
log {
|
||||||
source {
|
source {
|
||||||
|
!debug;
|
||||||
|
blacklist;
|
||||||
|
chgcmds;
|
||||||
|
connect.LOCAL_CLIENT_CONNECT;
|
||||||
|
connect.LOCAL_CLIENT_DISCONNECT;
|
||||||
|
connect.REMOTE_CLIENT_CONNECT;
|
||||||
|
connect.REMOTE_CLIENT_DISCONNECT;
|
||||||
|
dcc;
|
||||||
|
flood;
|
||||||
|
kill;
|
||||||
|
link;
|
||||||
|
nick.QLINE_NICK_LOCAL_ATTEMPT;
|
||||||
|
nick.QLINE_NICK_REMOTE;
|
||||||
|
nomatch;
|
||||||
|
oper;
|
||||||
|
operoverride;
|
||||||
|
sacmds;
|
||||||
tkl.BAN_REALNAME;
|
tkl.BAN_REALNAME;
|
||||||
|
tkl.RMTKL_COMMAND;
|
||||||
|
tkl.SPAMFILTER_MATCH;
|
||||||
tkl.TKL_ADD;
|
tkl.TKL_ADD;
|
||||||
tkl.TKL_DEL;
|
tkl.TKL_DEL;
|
||||||
tkl.TKL_ADD_TEMPSHUN;
|
tkl.TKL_ADD_TEMPSHUN;
|
||||||
tkl.TKL_DEL_TEMPSHUN;
|
tkl.TKL_DEL_TEMPSHUN;
|
||||||
tkl.TKL_EXPIRE;
|
tkl.TKL_EXPIRE;
|
||||||
tkl.RMTKL_COMMAND;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Blacklist snomask: 'B' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
blacklist;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask B;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Local client connects snomask - 'c' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
connect.LOCAL_CLIENT_CONNECT;
|
|
||||||
connect.LOCAL_CLIENT_DISCONNECT;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remote client connects snomask - 'C' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
connect.REMOTE_CLIENT_CONNECT;
|
|
||||||
connect.REMOTE_CLIENT_DISCONNECT;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask C;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DCC rejections snomask - 'd' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
dcc;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Debug snomask (not recommended) - 'D' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
debug;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask D;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Floods snomask - 'f' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
flood;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Join, parts, kicks - 'j' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
// TODO: these don't exist yet..
|
|
||||||
join.LOCAL_CLIENT_JOIN;
|
|
||||||
join.REMOTE_CLIENT_JOIN;
|
|
||||||
part.LOCAL_CLIENT_PART;
|
|
||||||
part.REMOTE_CLIENT_PART;
|
|
||||||
kick.LOCAL_CLIENT_KICK;
|
|
||||||
kick.REMOTE_CLIENT_KICK;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Kill snomask */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
kill;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Local nick changes snomask - 'n' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
nick.LOCAL_NICK_CHANGE;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remote nick changes snomask - 'N' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
nick.REMOTE_NICK_CHANGE;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask N;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Deny nick (QLINE) rejections snomask - 'q' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
nick.QLINE_NICK_LOCAL_ATTEMPT;
|
|
||||||
nick.QLINE_NICK_REMOTE;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask q;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Spamfilter hits snomask - 'S' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
tkl.SPAMFILTER_MATCH;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask S;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IRCOp overriding in channels (OperOverride) - 'o' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
operoverride;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask o;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IRCOp changing user properties or forcing users to do things - 'O' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
chgcmds;
|
|
||||||
sacmds;
|
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask O;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* VHOST usage - 'v' */
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
vhost;
|
vhost;
|
||||||
}
|
}
|
||||||
destination {
|
destination { snomask o; }
|
||||||
snomask v;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Snomask s (server notices) - the "catch all" snomask for all other things */
|
|
||||||
log {
|
log {
|
||||||
source {
|
source {
|
||||||
link;
|
|
||||||
oper;
|
|
||||||
!debug;
|
!debug;
|
||||||
nomatch;
|
flood;
|
||||||
}
|
|
||||||
destination {
|
|
||||||
snomask s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* These log sources are sent to all servers (globally).
|
|
||||||
* These are generally two categories:
|
|
||||||
* 1) Things that affect the network as a whole, eg linking
|
|
||||||
* 2) Things that otherwise cannot be logged by a remote server
|
|
||||||
* that may interest ircops. Eg: a spamfilter match,
|
|
||||||
* since that would otherwise not be propagated.
|
|
||||||
*/
|
|
||||||
log {
|
|
||||||
source {
|
|
||||||
/* All link messages affect the network so
|
|
||||||
* these should be global. Except for the
|
|
||||||
* link connecting... and timeout while
|
|
||||||
* connecting.. messages, which can be noisy.
|
|
||||||
*/
|
|
||||||
link;
|
link;
|
||||||
!link.LINK_CONNECTING;
|
!link.LINK_CONNECTING;
|
||||||
!link.LINK_CONNECT_TIMEOUT;
|
!link.LINK_CONNECT_TIMEOUT;
|
||||||
!link.SERVER_LINKED_REMOTE;
|
!link.SERVER_LINKED_REMOTE;
|
||||||
!link.SERVER_LINKED;
|
!link.SERVER_LINKED;
|
||||||
/* All oper up/downs */
|
|
||||||
oper;
|
oper;
|
||||||
/* Flood messages, important to keep an eye on, network-wide */
|
samode.SAMODE_COMMAND;
|
||||||
flood;
|
|
||||||
/* TEMPSHUN: these are otherwise missing for snomask 'b' */
|
|
||||||
tkl.TKL_ADD_TEMPSHUN;
|
tkl.TKL_ADD_TEMPSHUN;
|
||||||
tkl.TKL_DEL_TEMPSHUN;
|
tkl.TKL_DEL_TEMPSHUN;
|
||||||
/* Spamfilter matches: needed for snomask 'S' */
|
|
||||||
tkl.SPAMFILTER_MATCH;
|
tkl.SPAMFILTER_MATCH;
|
||||||
/* Critical issue: */
|
|
||||||
tls.TLS_CERT_EXPIRING;
|
tls.TLS_CERT_EXPIRING;
|
||||||
/* SAMODE: needed for snomask 'o' */
|
|
||||||
samode.SAMODE_COMMAND;
|
|
||||||
/* Never any debug messages */
|
|
||||||
!debug;
|
|
||||||
}
|
}
|
||||||
destination {
|
destination { remote; }
|
||||||
remote;
|
}
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,5 +3,6 @@ include "https://USERNAME:PASSWORD@HOSTNAME:PORT/except.conf";
|
||||||
include "https://USERNAME:PASSWORD@HOSTNAME:PORT/ircd.conf";
|
include "https://USERNAME:PASSWORD@HOSTNAME:PORT/ircd.conf";
|
||||||
include "https://USERNAME:PASSWORD@HOSTNAME:PORT/modules.conf";
|
include "https://USERNAME:PASSWORD@HOSTNAME:PORT/modules.conf";
|
||||||
include "https://USERNAME:PASSWORD@HOSTNAME:PORT/opers.conf";
|
include "https://USERNAME:PASSWORD@HOSTNAME:PORT/opers.conf";
|
||||||
|
include "https://USERNAME:PASSWORD@HOSTNAME:PORT/snomasks.conf";
|
||||||
include "https://USERNAME:PASSWORD@HOSTNAME:PORT/spamfilter.conf";
|
include "https://USERNAME:PASSWORD@HOSTNAME:PORT/spamfilter.conf";
|
||||||
me { name "example.supernets.org"; info "SuperNETS IRC Network"; sid XXX; }
|
me { name "example.supernets.org"; info "SuperNETS IRC Network"; sid XXX; }
|
|
@ -17,11 +17,6 @@ class servers { pingfreq 120; maxclients 10; sendq 1M; connfreq 30; }
|
||||||
allow { mask *; class clients; maxperip 2; global-maxperip 2; }
|
allow { mask *; class clients; maxperip 2; global-maxperip 2; }
|
||||||
allow { mask 127.0.0.1; class clients; maxperip 10; global-maxperip 10; }
|
allow { mask 127.0.0.1; class clients; maxperip 10; global-maxperip 10; }
|
||||||
|
|
||||||
#require authentication {
|
|
||||||
# mask *@*;
|
|
||||||
# reason "8,4 E N T E R T H E V O I D ";
|
|
||||||
#}
|
|
||||||
|
|
||||||
listen { ip *; port 6667; options { clientsonly; } }
|
listen { ip *; port 6667; options { clientsonly; } }
|
||||||
listen { ip *; port 6697; options { clientsonly; tls; } }
|
listen { ip *; port 6697; options { clientsonly; tls; } }
|
||||||
listen { ip *; port REDACTED; options { serversonly; tls; } }
|
listen { ip *; port REDACTED; options { serversonly; tls; } }
|
||||||
|
@ -45,13 +40,13 @@ link irc.supernets.org {
|
||||||
|
|
||||||
log {
|
log {
|
||||||
source { error; fatal; warn; }
|
source { error; fatal; warn; }
|
||||||
destination { file "ircd.log" { maxsize 10M; } }
|
destination { file "ircd.log" { maxsize 5M; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
log {
|
#log {
|
||||||
source { all; }
|
# source { all; }
|
||||||
destination { channel "#REDACTED" }
|
# destination { channel "#REDACTED" }
|
||||||
}
|
#}
|
||||||
|
|
||||||
tld { mask *@*; motd remote.motd; rules remote.motd; options { remote; } }
|
tld { mask *@*; motd remote.motd; rules remote.motd; options { remote; } }
|
||||||
|
|
||||||
|
@ -95,7 +90,7 @@ set {
|
||||||
gline-address "enterthevoid@supernets.org";
|
gline-address "enterthevoid@supernets.org";
|
||||||
modes-on-connect "+iIpTx";
|
modes-on-connect "+iIpTx";
|
||||||
modes-on-oper "+Hq";
|
modes-on-oper "+Hq";
|
||||||
snomask-on-oper "+bBcCfksSoO";
|
snomask-on-oper "+o";
|
||||||
modes-on-join "+ns";
|
modes-on-join "+ns";
|
||||||
level-on-join "op";
|
level-on-join "op";
|
||||||
restrict-usermodes "ips";
|
restrict-usermodes "ips";
|
||||||
|
@ -127,7 +122,7 @@ set {
|
||||||
"REDACTED";
|
"REDACTED";
|
||||||
"REDACTED";
|
"REDACTED";
|
||||||
}
|
}
|
||||||
hiddenhost-prefix "SUPER";
|
cloak-prefix "SUPER";
|
||||||
plaintext-policy {
|
plaintext-policy {
|
||||||
user warn;
|
user warn;
|
||||||
oper deny;
|
oper deny;
|
||||||
|
@ -139,8 +134,8 @@ set {
|
||||||
user warn;
|
user warn;
|
||||||
oper deny;
|
oper deny;
|
||||||
server deny;
|
server deny;
|
||||||
user-message "4WARNING: You are using an outdated SSL/TLS protocol or cipher";
|
user-message "4WARNING: You are using an outdated TLS protocol or cipher";
|
||||||
oper-message "Network operators must be using an up-to-date SSL/TLS protocol & cipher";
|
oper-message "Network operators must be using an up-to-date TLS protocol & cipher";
|
||||||
}
|
}
|
||||||
anti-flood {
|
anti-flood {
|
||||||
everyone {
|
everyone {
|
||||||
|
@ -209,9 +204,10 @@ set {
|
||||||
ban-reason "8,4 E N T E R T H E V O I D ";
|
ban-reason "8,4 E N T E R T H E V O I D ";
|
||||||
}
|
}
|
||||||
connthrottle {
|
connthrottle {
|
||||||
known-users { minimum-reputation-score 25; sasl-bypass yes; }
|
known-users { minimum-reputation-score 100; sasl-bypass yes; }
|
||||||
new-users { local-throttle 20:60; global-throttle 30:60; }
|
new-users { local-throttle 20:60; global-throttle 30:60; }
|
||||||
disabled-when { reputation-gathering 1w; start-delay 3m; }
|
disabled-when { reputation-gathering 1w; start-delay 3m; }
|
||||||
|
reason "8,4 E N T E R T H E V O I D ";
|
||||||
}
|
}
|
||||||
history {
|
history {
|
||||||
channel {
|
channel {
|
||||||
|
@ -224,24 +220,24 @@ set {
|
||||||
}
|
}
|
||||||
hide-idle-time { policy always; }
|
hide-idle-time { policy always; }
|
||||||
whois-details {
|
whois-details {
|
||||||
basic { everyone full; }
|
|
||||||
modes { everyone none; self full; oper full; }
|
|
||||||
realhost { everyone none; self full; oper full; }
|
|
||||||
registered-nick { everyone full; }
|
|
||||||
channels { everyone limited; self full; oper full; }
|
|
||||||
server { everyone full; }
|
|
||||||
away { everyone full; }
|
|
||||||
oper { everyone limited; self full; oper full; }
|
|
||||||
secure { everyone limited; self full; oper full; }
|
|
||||||
bot { everyone full; }
|
|
||||||
services { everyone full; }
|
|
||||||
reputation { everyone none; self none; oper full; }
|
|
||||||
geo { everyone none; self none; oper full; }
|
|
||||||
certfp { everyone full; }
|
|
||||||
shunned { everyone none; self none; oper full; }
|
|
||||||
account { everyone full; }
|
account { everyone full; }
|
||||||
|
away { everyone full; }
|
||||||
|
basic { everyone full; }
|
||||||
|
bot { everyone full; }
|
||||||
|
certfp { everyone full; }
|
||||||
|
channels { everyone none; self full; oper full; }
|
||||||
|
geo { everyone none; }
|
||||||
|
idle { everyone none; }
|
||||||
|
modes { everyone none; self full; oper full; }
|
||||||
|
oper { everyone limited; self full; oper full; }
|
||||||
|
realhost { everyone none; self full; oper full; }
|
||||||
|
registered-nick { everyone full; }
|
||||||
|
reputation { everyone full; }
|
||||||
|
secure { everyone limited; self full; oper full; }
|
||||||
|
server { everyone full; }
|
||||||
|
services { everyone full; }
|
||||||
|
shunned { everyone none; self none; oper full; }
|
||||||
swhois { everyone full; }
|
swhois { everyone full; }
|
||||||
idle { everyone limited; self full; oper full; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,5 +250,5 @@ hideserver {
|
||||||
|
|
||||||
security-group known-users {
|
security-group known-users {
|
||||||
identified yes;
|
identified yes;
|
||||||
reputation-score 25;
|
reputation-score 100;
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
# in case it misbehaves
|
# in case it misbehaves
|
||||||
#
|
#
|
||||||
set +ex
|
set +ex
|
||||||
timeout --kill-after=5 600 extras/build-tests/nix/run-tests
|
timeout --kill-after=5 900 extras/build-tests/nix/run-tests
|
||||||
EX="$?"
|
EX="$?"
|
||||||
killall -9 valgrind valgrind.bin memcheck memcheck-amd64-linux memcheck-x86-linux ircd unrealircd val 1>/dev/null 2>&1
|
killall -9 valgrind valgrind.bin memcheck memcheck-amd64-linux memcheck-x86-linux ircd unrealircd val 1>/dev/null 2>&1
|
||||||
exit $EX
|
exit $EX
|
||||||
|
|
|
@ -36,11 +36,11 @@ rem Now the actual build
|
||||||
rem - First this, otherwise JOM will fail
|
rem - First this, otherwise JOM will fail
|
||||||
IF NOT EXIST src\version.c nmake -f Makefile.windows CONF
|
IF NOT EXIST src\version.c nmake -f Makefile.windows CONF
|
||||||
rem - Then build most of UnrealIRCd.exe etc
|
rem - Then build most of UnrealIRCd.exe etc
|
||||||
call extras\build-tests\windows\compilecmd\%SHORTNAME%.bat UNREALSVC.EXE UnrealIRCd.exe
|
call extras\build-tests\windows\compilecmd\%SHORTNAME%.bat UNREALSVC.EXE UnrealIRCd.exe unrealircdctl.exe
|
||||||
rem - It will fail due to missing symbolfile, which we create here..
|
rem - It will fail due to missing symbolfile, which we create here..
|
||||||
nmake -f makefile.windows SYMBOLFILE
|
nmake -f makefile.windows SYMBOLFILE
|
||||||
rem - Then we finalize building UnrealIRCd.exe: should be no error
|
rem - Then we finalize building UnrealIRCd.exe: should be no error
|
||||||
call extras\build-tests\windows\compilecmd\%SHORTNAME%.bat UNREALSVC.EXE UnrealIRCd.exe
|
call extras\build-tests\windows\compilecmd\%SHORTNAME%.bat UNREALSVC.EXE UnrealIRCd.exe unrealircdctl.exe
|
||||||
if %ERRORLEVEL% NEQ 0 EXIT /B 1
|
if %ERRORLEVEL% NEQ 0 EXIT /B 1
|
||||||
rem - Build all the modules (DLL files): should be no error
|
rem - Build all the modules (DLL files): should be no error
|
||||||
call extras\build-tests\windows\compilecmd\%SHORTNAME%.bat MODULES
|
call extras\build-tests\windows\compilecmd\%SHORTNAME%.bat MODULES
|
||||||
|
|
Binary file not shown.
|
@ -2,10 +2,8 @@
|
||||||
URL="https://www.unrealircd.org/files/curl-latest.tar.gz"
|
URL="https://www.unrealircd.org/files/curl-latest.tar.gz"
|
||||||
OUTF="curl-latest.tar.gz"
|
OUTF="curl-latest.tar.gz"
|
||||||
OUTD="curl-latest"
|
OUTD="curl-latest"
|
||||||
ARESPATH="`pwd`/extras/c-ares"
|
|
||||||
UNREALDIR="`pwd`"
|
UNREALDIR="`pwd`"
|
||||||
CARESVERSION="1.17.2"
|
PRIVATELIBDIR="$1"
|
||||||
LIBDIR="$1"
|
|
||||||
|
|
||||||
if [ "x$1" = "x" ]; then
|
if [ "x$1" = "x" ]; then
|
||||||
echo "You should (no longer) run this program directly."
|
echo "You should (no longer) run this program directly."
|
||||||
|
@ -73,26 +71,9 @@ else
|
||||||
n="-n"
|
n="-n"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -d "$ARESPATH/lib" ]; then
|
|
||||||
echo "c-ares has not been build yet, let's do that now..."
|
|
||||||
cd ../extras/
|
|
||||||
tar xzf c-ares.tar.gz || exit 1
|
|
||||||
cd c-ares-$CARESVERSION || exit 1
|
|
||||||
./configure --prefix=$ARESPATH || exit 1
|
|
||||||
(make && make install) || exit 1
|
|
||||||
cd ../../tmp/
|
|
||||||
echo "c-ares built."
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# We assume curl has been packaged in a way it will extract to "$OUTD"/
|
# We assume curl has been packaged in a way it will extract to "$OUTD"/
|
||||||
cd "$OUTD" || exit 1
|
cd "$OUTD" || exit 1
|
||||||
|
|
||||||
echo "Building and installing libcurl"
|
echo "Building and installing libcurl"
|
||||||
CPPFLAGS="-I$ARESPATH/include" ./configure --prefix=$UNREALDIR/extras/curl --libdir=$LIBDIR --enable-shared \
|
./configure --prefix=$UNREALDIR/extras/curl --libdir=$PRIVATELIBDIR --enable-shared --with-openssl
|
||||||
--enable-ares=$ARESPATH --with-openssl
|
|
||||||
cp -R $ARESPATH/lib ares
|
|
||||||
make && make install
|
make && make install
|
||||||
|
|
||||||
#cp $ARESPATH/lib/libcares.a $HOME/curl/lib
|
|
||||||
# that isn't needed anymore as the lib is already in unreal...
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ PROJECT_NAME = "UnrealIRCd"
|
||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 6.0.1.1
|
PROJECT_NUMBER = 6.0.3
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|
Binary file not shown.
|
@ -170,6 +170,7 @@ struct Configuration {
|
||||||
char *stats_server;
|
char *stats_server;
|
||||||
char *sasl_server;
|
char *sasl_server;
|
||||||
int server_notice_colors;
|
int server_notice_colors;
|
||||||
|
int server_notice_show_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MODVAR Configuration iConf;
|
extern MODVAR Configuration iConf;
|
||||||
|
|
51
include/h.h
51
include/h.h
|
@ -28,6 +28,34 @@
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include "fdlist.h"
|
#include "fdlist.h"
|
||||||
|
|
||||||
|
extern int dorehash, dorestart, doreloadcert;
|
||||||
|
#ifndef _WIN32
|
||||||
|
extern char **myargv;
|
||||||
|
#else
|
||||||
|
extern LPCSTR cmdLine;
|
||||||
|
#endif
|
||||||
|
/* Externals */
|
||||||
|
extern MODVAR char *buildid;
|
||||||
|
extern MODVAR char backupbuf[8192];
|
||||||
|
extern EVENT(unrealdns_removeoldrecords);
|
||||||
|
extern EVENT(unrealdb_expire_secret_cache);
|
||||||
|
extern void init_glines(void);
|
||||||
|
extern void tkl_init(void);
|
||||||
|
extern void process_clients(void);
|
||||||
|
extern void unrealdb_test(void);
|
||||||
|
extern void ignore_this_signal();
|
||||||
|
extern void s_rehash();
|
||||||
|
extern void s_reloadcert();
|
||||||
|
extern void s_restart();
|
||||||
|
extern void s_die();
|
||||||
|
#ifndef _WIN32
|
||||||
|
// nix specific
|
||||||
|
extern char unreallogo[];
|
||||||
|
#else
|
||||||
|
// windows specific
|
||||||
|
extern SERVICE_STATUS_HANDLE IRCDStatusHandle;
|
||||||
|
extern SERVICE_STATUS IRCDStatus;
|
||||||
|
#endif
|
||||||
extern MODVAR char *extraflags;
|
extern MODVAR char *extraflags;
|
||||||
extern MODVAR int tainted;
|
extern MODVAR int tainted;
|
||||||
extern MODVAR Member *freemember;
|
extern MODVAR Member *freemember;
|
||||||
|
@ -117,7 +145,7 @@ extern void ipport_seperate(const char *string, char **ip, char **port);
|
||||||
extern ConfigItem_class *find_class(const char *name);
|
extern ConfigItem_class *find_class(const char *name);
|
||||||
extern ConfigItem_oper *find_oper(const char *name);
|
extern ConfigItem_oper *find_oper(const char *name);
|
||||||
extern ConfigItem_operclass *find_operclass(const char *name);
|
extern ConfigItem_operclass *find_operclass(const char *name);
|
||||||
extern ConfigItem_listen *find_listen(const char *ipmask, int port, int ipv6);
|
extern ConfigItem_listen *find_listen(const char *ipmask, int port, SocketType socket_type);
|
||||||
extern ConfigItem_sni *find_sni(const char *name);
|
extern ConfigItem_sni *find_sni(const char *name);
|
||||||
extern ConfigItem_ulines *find_uline(const char *host);
|
extern ConfigItem_ulines *find_uline(const char *host);
|
||||||
extern ConfigItem_tld *find_tld(Client *cptr);
|
extern ConfigItem_tld *find_tld(Client *cptr);
|
||||||
|
@ -153,6 +181,7 @@ extern MODVAR struct list_head lclient_list;
|
||||||
extern MODVAR struct list_head server_list;
|
extern MODVAR struct list_head server_list;
|
||||||
extern MODVAR struct list_head oper_list;
|
extern MODVAR struct list_head oper_list;
|
||||||
extern MODVAR struct list_head unknown_list;
|
extern MODVAR struct list_head unknown_list;
|
||||||
|
extern MODVAR struct list_head control_list;
|
||||||
extern MODVAR struct list_head global_server_list;
|
extern MODVAR struct list_head global_server_list;
|
||||||
extern MODVAR struct list_head dead_list;
|
extern MODVAR struct list_head dead_list;
|
||||||
extern RealCommand *find_command(const char *cmd, int flags);
|
extern RealCommand *find_command(const char *cmd, int flags);
|
||||||
|
@ -489,6 +518,7 @@ extern int channel_canjoin(Client *client, const char *name);
|
||||||
extern char *collapse(char *pattern);
|
extern char *collapse(char *pattern);
|
||||||
extern void dcc_sync(Client *client);
|
extern void dcc_sync(Client *client);
|
||||||
extern void request_rehash(Client *client);
|
extern void request_rehash(Client *client);
|
||||||
|
extern int rehash_internal(Client *client);
|
||||||
extern void s_die();
|
extern void s_die();
|
||||||
extern int match_simple(const char *mask, const char *name);
|
extern int match_simple(const char *mask, const char *name);
|
||||||
extern int match_esc(const char *mask, const char *name);
|
extern int match_esc(const char *mask, const char *name);
|
||||||
|
@ -507,7 +537,7 @@ extern void rehash_motdrules();
|
||||||
extern void read_motd(const char *filename, MOTDFile *motd); /* s_serv.c */
|
extern void read_motd(const char *filename, MOTDFile *motd); /* s_serv.c */
|
||||||
extern void send_proto(Client *, ConfigItem_link *);
|
extern void send_proto(Client *, ConfigItem_link *);
|
||||||
extern void unload_all_modules(void);
|
extern void unload_all_modules(void);
|
||||||
extern void set_sock_opts(int fd, Client *cptr, int ipv6);
|
extern void set_sock_opts(int fd, Client *cptr, SocketType socket_type);
|
||||||
extern void stripcrlf(char *line);
|
extern void stripcrlf(char *line);
|
||||||
extern int strnatcmp(char const *a, char const *b);
|
extern int strnatcmp(char const *a, char const *b);
|
||||||
extern int strnatcasecmp(char const *a, char const *b);
|
extern int strnatcasecmp(char const *a, char const *b);
|
||||||
|
@ -663,7 +693,6 @@ extern int spamfilter_getconftargets(const char *s);
|
||||||
extern void remove_all_snomasks(Client *client);
|
extern void remove_all_snomasks(Client *client);
|
||||||
extern void remove_oper_modes(Client *client);
|
extern void remove_oper_modes(Client *client);
|
||||||
extern char *spamfilter_inttostring_long(int v);
|
extern char *spamfilter_inttostring_long(int v);
|
||||||
extern MODVAR char backupbuf[];
|
|
||||||
extern int is_invited(Client *client, Channel *channel);
|
extern int is_invited(Client *client, Channel *channel);
|
||||||
extern void channel_modes(Client *client, char *mbuf, char *pbuf, size_t mbuf_size, size_t pbuf_size, Channel *channel, int hide_local_modes);
|
extern void channel_modes(Client *client, char *mbuf, char *pbuf, size_t mbuf_size, size_t pbuf_size, Channel *channel, int hide_local_modes);
|
||||||
extern int op_can_override(const char *acl, Client *client,Channel *channel,void* extra);
|
extern int op_can_override(const char *acl, Client *client,Channel *channel,void* extra);
|
||||||
|
@ -859,6 +888,7 @@ extern const char *cmdname_by_spamftarget(int target);
|
||||||
extern void unrealdns_delreq_bycptr(Client *cptr);
|
extern void unrealdns_delreq_bycptr(Client *cptr);
|
||||||
extern void unrealdns_gethostbyname_link(const char *name, ConfigItem_link *conf, int ipv4_only);
|
extern void unrealdns_gethostbyname_link(const char *name, ConfigItem_link *conf, int ipv4_only);
|
||||||
extern void unrealdns_delasyncconnects(void);
|
extern void unrealdns_delasyncconnects(void);
|
||||||
|
extern EVENT(unrealdns_timeout);
|
||||||
extern int is_autojoin_chan(const char *chname);
|
extern int is_autojoin_chan(const char *chname);
|
||||||
extern void unreal_free_hostent(struct hostent *he);
|
extern void unreal_free_hostent(struct hostent *he);
|
||||||
extern struct hostent *unreal_create_hostent(const char *name, const char *ip);
|
extern struct hostent *unreal_create_hostent(const char *name, const char *ip);
|
||||||
|
@ -915,10 +945,14 @@ extern void report_crash(void);
|
||||||
extern void modulemanager(int argc, char *argv[]);
|
extern void modulemanager(int argc, char *argv[]);
|
||||||
extern int inet_pton4(const char *src, unsigned char *dst);
|
extern int inet_pton4(const char *src, unsigned char *dst);
|
||||||
extern int inet_pton6(const char *src, unsigned char *dst);
|
extern int inet_pton6(const char *src, unsigned char *dst);
|
||||||
extern int unreal_bind(int fd, const char *ip, int port, int ipv6);
|
extern int unreal_bind(int fd, const char *ip, int port, SocketType socket_type);
|
||||||
extern int unreal_connect(int fd, const char *ip, int port, int ipv6);
|
extern int unreal_connect(int fd, const char *ip, int port, int ipv6);
|
||||||
extern int is_valid_ip(const char *str);
|
extern int is_valid_ip(const char *str);
|
||||||
extern int ipv6_capable(void);
|
extern int ipv6_capable(void);
|
||||||
|
extern int unix_sockets_capable(void);
|
||||||
|
#ifdef _WIN32
|
||||||
|
extern void init_winsock(void);
|
||||||
|
#endif
|
||||||
extern MODVAR Client *remote_rehash_client;
|
extern MODVAR Client *remote_rehash_client;
|
||||||
extern MODVAR int debugfd;
|
extern MODVAR int debugfd;
|
||||||
extern void convert_to_absolute_path(char **path, const char *reldir);
|
extern void convert_to_absolute_path(char **path, const char *reldir);
|
||||||
|
@ -929,7 +963,7 @@ extern Cmode_t get_extmode_bitbychar(char m);
|
||||||
extern long find_user_mode(char mode);
|
extern long find_user_mode(char mode);
|
||||||
extern void start_listeners(void);
|
extern void start_listeners(void);
|
||||||
extern void buildvarstring(const char *inbuf, char *outbuf, size_t len, const char *name[], const char *value[]);
|
extern void buildvarstring(const char *inbuf, char *outbuf, size_t len, const char *name[], const char *value[]);
|
||||||
extern void reinit_tls(void);
|
extern int reinit_tls(void);
|
||||||
extern CMD_FUNC(cmd_error);
|
extern CMD_FUNC(cmd_error);
|
||||||
extern CMD_FUNC(cmd_dns);
|
extern CMD_FUNC(cmd_dns);
|
||||||
extern CMD_FUNC(cmd_info);
|
extern CMD_FUNC(cmd_info);
|
||||||
|
@ -1135,6 +1169,8 @@ extern void flood_limit_exceeded_log(Client *client, const char *floodname);
|
||||||
/* logging */
|
/* logging */
|
||||||
extern int config_test_log(ConfigFile *conf, ConfigEntry *ce);
|
extern int config_test_log(ConfigFile *conf, ConfigEntry *ce);
|
||||||
extern int config_run_log(ConfigFile *conf, ConfigEntry *ce);
|
extern int config_run_log(ConfigFile *conf, ConfigEntry *ce);
|
||||||
|
extern const char *log_level_terminal_color(LogLevel loglevel);
|
||||||
|
#define TERMINAL_COLOR_RESET "\033[0m"
|
||||||
extern LogType log_type_stringtoval(const char *str);
|
extern LogType log_type_stringtoval(const char *str);
|
||||||
extern const char *log_type_valtostring(LogType v);
|
extern const char *log_type_valtostring(LogType v);
|
||||||
#ifdef DEBUGMODE
|
#ifdef DEBUGMODE
|
||||||
|
@ -1208,3 +1244,8 @@ extern void make_umodestr(void);
|
||||||
extern void initwhowas(void);
|
extern void initwhowas(void);
|
||||||
extern void uid_init(void);
|
extern void uid_init(void);
|
||||||
extern const char *uid_get(void);
|
extern const char *uid_get(void);
|
||||||
|
/* proc i/o */
|
||||||
|
extern void add_proc_io_server(void);
|
||||||
|
extern void procio_post_rehash(int failure);
|
||||||
|
/* end of proc i/o */
|
||||||
|
extern int minimum_msec_since_last_run(struct timeval *tv_old, long minimum);
|
||||||
|
|
|
@ -394,7 +394,7 @@ typedef enum ExtbanType {
|
||||||
#define EXTBANTABLESZ 32
|
#define EXTBANTABLESZ 32
|
||||||
|
|
||||||
typedef enum ExtbanOptions {
|
typedef enum ExtbanOptions {
|
||||||
EXTBOPT_CHSVSMODE=0x1, /**< SVSMODE -b/-e/-I will clear this ban */
|
EXTBOPT_CHSVSMODE=0x1, /**< SVSMODE -b/-e/-I will clear this ban (UNUSED as of 6.0.1+) */
|
||||||
EXTBOPT_ACTMODIFIER=0x2, /**< Action modifier (not a matcher). These are extended bans like ~q/~n/~j. */
|
EXTBOPT_ACTMODIFIER=0x2, /**< Action modifier (not a matcher). These are extended bans like ~q/~n/~j. */
|
||||||
EXTBOPT_NOSTACKCHILD=0x4, /**< Disallow prefixing with another extban. Eg disallow ~n:~T:censor:xyz */
|
EXTBOPT_NOSTACKCHILD=0x4, /**< Disallow prefixing with another extban. Eg disallow ~n:~T:censor:xyz */
|
||||||
EXTBOPT_INVEX=0x8, /**< Available for use with +I too */
|
EXTBOPT_INVEX=0x8, /**< Available for use with +I too */
|
||||||
|
@ -1151,12 +1151,14 @@ extern void SavePersistentLongX(ModuleInfo *modinfo, const char *varshortname, l
|
||||||
#define HOOKTYPE_POST_LOCAL_NICKCHANGE 106
|
#define HOOKTYPE_POST_LOCAL_NICKCHANGE 106
|
||||||
/** See hooktype_post_remote_nickchange() */
|
/** See hooktype_post_remote_nickchange() */
|
||||||
#define HOOKTYPE_POST_REMOTE_NICKCHANGE 107
|
#define HOOKTYPE_POST_REMOTE_NICKCHANGE 107
|
||||||
/** See hooktype_userhost_changed() */
|
/** See hooktype_userhost_change() */
|
||||||
#define HOOKTYPE_USERHOST_CHANGED 108
|
#define HOOKTYPE_USERHOST_CHANGE 108
|
||||||
/** See hooktype_realname_changed() */
|
/** See hooktype_realname_change() */
|
||||||
#define HOOKTYPE_REALNAME_CHANGED 109
|
#define HOOKTYPE_REALNAME_CHANGE 109
|
||||||
/** See hooktype_can_set_topic() */
|
/** See hooktype_can_set_topic() */
|
||||||
#define HOOKTYPE_CAN_SET_TOPIC 110
|
#define HOOKTYPE_CAN_SET_TOPIC 110
|
||||||
|
/** See hooktype_ip_change() */
|
||||||
|
#define HOOKTYPE_IP_CHANGE 111
|
||||||
/* Adding a new hook here?
|
/* Adding a new hook here?
|
||||||
* 1) Add the #define HOOKTYPE_.... with a new number
|
* 1) Add the #define HOOKTYPE_.... with a new number
|
||||||
* 2) Add a hook prototype (see below)
|
* 2) Add a hook prototype (see below)
|
||||||
|
@ -2127,14 +2129,22 @@ int hooktype_post_remote_nickchange(Client *client, MessageTag *mtags, const cha
|
||||||
* @param oldhost Old hostname of the client
|
* @param oldhost Old hostname of the client
|
||||||
* @return The return value is ignored (use return 0)
|
* @return The return value is ignored (use return 0)
|
||||||
*/
|
*/
|
||||||
|
int hooktype_userhost_change(Client *client, const char *olduser, const char *oldhost);
|
||||||
int hooktype_realname_changed(Client *client, const char *oldinfo);
|
|
||||||
/** Called when user realname has changed.
|
/** Called when user realname has changed.
|
||||||
* @param client The client whose realname has changed
|
* @param client The client whose realname has changed
|
||||||
* @param oldinfo Old realname of the client
|
* @param oldinfo Old realname of the client
|
||||||
* @return The return value is ignored (use return 0)
|
* @return The return value is ignored (use return 0)
|
||||||
*/
|
*/
|
||||||
int hooktype_userhost_changed(Client *client, const char *olduser, const char *oldhost);
|
int hooktype_realname_change(Client *client, const char *oldinfo);
|
||||||
|
|
||||||
|
/** Called when changing IP (eg due to PROXY/WEBIRC/etc).
|
||||||
|
* @param client The client whose IP has changed
|
||||||
|
* @param oldip Old IP of the client
|
||||||
|
* @return The return value is ignored (use return 0)
|
||||||
|
*/
|
||||||
|
int hooktype_ip_change(Client *client, const char *oldip);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef GCC_TYPECHECKING
|
#ifdef GCC_TYPECHECKING
|
||||||
|
@ -2247,8 +2257,9 @@ _UNREAL_ERROR(_hook_error_incompatible, "Incompatible hook function. Check argum
|
||||||
((hooktype == HOOKTYPE_IS_INVITED) && !ValidateHook(hooktype_is_invited, func)) || \
|
((hooktype == HOOKTYPE_IS_INVITED) && !ValidateHook(hooktype_is_invited, func)) || \
|
||||||
((hooktype == HOOKTYPE_POST_LOCAL_NICKCHANGE) && !ValidateHook(hooktype_post_local_nickchange, func)) || \
|
((hooktype == HOOKTYPE_POST_LOCAL_NICKCHANGE) && !ValidateHook(hooktype_post_local_nickchange, func)) || \
|
||||||
((hooktype == HOOKTYPE_POST_REMOTE_NICKCHANGE) && !ValidateHook(hooktype_post_remote_nickchange, func)) || \
|
((hooktype == HOOKTYPE_POST_REMOTE_NICKCHANGE) && !ValidateHook(hooktype_post_remote_nickchange, func)) || \
|
||||||
((hooktype == HOOKTYPE_USERHOST_CHANGED) && !ValidateHook(hooktype_userhost_changed, func)) || \
|
((hooktype == HOOKTYPE_USERHOST_CHANGE) && !ValidateHook(hooktype_userhost_change, func)) || \
|
||||||
((hooktype == HOOKTYPE_REALNAME_CHANGED) && !ValidateHook(hooktype_realname_changed, func)) )\
|
((hooktype == HOOKTYPE_REALNAME_CHANGE) && !ValidateHook(hooktype_realname_change, func)) || \
|
||||||
|
((hooktype == HOOKTYPE_IP_CHANGE) && !ValidateHook(hooktype_ip_change, func)) ) \
|
||||||
_hook_error_incompatible();
|
_hook_error_incompatible();
|
||||||
#endif /* GCC_TYPECHECKING */
|
#endif /* GCC_TYPECHECKING */
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
|
|
||||||
#define RPL_REDIR 10
|
#define RPL_REDIR 10
|
||||||
|
|
||||||
|
#define RPL_MAPUSERS 18
|
||||||
|
|
||||||
#define RPL_REMOTEISUPPORT 105
|
#define RPL_REMOTEISUPPORT 105
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -349,10 +351,11 @@
|
||||||
#define STR_RPL_CREATED /* 003 */ ":This server was created %s"
|
#define STR_RPL_CREATED /* 003 */ ":This server was created %s"
|
||||||
#define STR_RPL_MYINFO /* 004 */ "%s %s %s %s"
|
#define STR_RPL_MYINFO /* 004 */ "%s %s %s %s"
|
||||||
#define STR_RPL_ISUPPORT /* 005 */ "%s :are supported by this server"
|
#define STR_RPL_ISUPPORT /* 005 */ "%s :are supported by this server"
|
||||||
#define STR_RPL_MAP /* 006 */ ":%s%-*s(%ld) %s"
|
#define STR_RPL_MAP /* 006 */ ":%s%s %s | Users: %*ld (%*.2f%%)%s"
|
||||||
#define STR_RPL_MAPEND /* 007 */ ":End of /MAP"
|
#define STR_RPL_MAPEND /* 007 */ ":End of /MAP"
|
||||||
#define STR_RPL_SNOMASK /* 008 */ "+%s :Server notice mask"
|
#define STR_RPL_SNOMASK /* 008 */ "+%s :Server notice mask"
|
||||||
#define STR_RPL_REDIR /* 010 */ "%s %d :Please use this Server/Port instead"
|
#define STR_RPL_REDIR /* 010 */ "%s %d :Please use this Server/Port instead"
|
||||||
|
#define STR_RPL_MAPUSERS /* 018 */ ":%d server%s and %d user%s, average %.2f users per server"
|
||||||
#define STR_RPL_REMOTEISUPPORT /* 105 */ "%s :are supported by this server"
|
#define STR_RPL_REMOTEISUPPORT /* 105 */ "%s :are supported by this server"
|
||||||
#define STR_RPL_TRACELINK /* 200 */ "Link %s%s %s %s"
|
#define STR_RPL_TRACELINK /* 200 */ "Link %s%s %s %s"
|
||||||
#define STR_RPL_TRACECONNECTING /* 201 */ "Attempt %s %s"
|
#define STR_RPL_TRACECONNECTING /* 201 */ "Attempt %s %s"
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
/* Define the location of the configuration files */
|
/* Define the location of the configuration files */
|
||||||
#undef CONFDIR
|
#undef CONFDIR
|
||||||
|
|
||||||
|
/* Define the path of the control socket */
|
||||||
|
#undef CONTROLFILE
|
||||||
|
|
||||||
/* Define the location of permanent data files */
|
/* Define the location of permanent data files */
|
||||||
#undef DATADIR
|
#undef DATADIR
|
||||||
|
|
||||||
|
|
|
@ -263,12 +263,18 @@ typedef struct Log Log;
|
||||||
struct Log {
|
struct Log {
|
||||||
Log *prev, *next;
|
Log *prev, *next;
|
||||||
LogSource *sources;
|
LogSource *sources;
|
||||||
|
int type;
|
||||||
char destination[CHANNELLEN+1];
|
char destination[CHANNELLEN+1];
|
||||||
|
int show_event;
|
||||||
|
/* for destination::file */
|
||||||
char *file;
|
char *file;
|
||||||
char *filefmt;
|
char *filefmt;
|
||||||
long maxsize;
|
long maxsize;
|
||||||
int type;
|
|
||||||
int logfd;
|
int logfd;
|
||||||
|
/* for destination::channel */
|
||||||
|
int color;
|
||||||
|
int json_message_tag;
|
||||||
|
int oper_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** This is used for deciding the <index> in logs[<index>] and temp_logs[<index>] */
|
/** This is used for deciding the <index> in logs[<index>] and temp_logs[<index>] */
|
||||||
|
@ -317,6 +323,7 @@ typedef enum LogDestination { LOG_DEST_SNOMASK=0, LOG_DEST_OPER=1, LOG_DEST_REMO
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
typedef enum ClientStatus {
|
typedef enum ClientStatus {
|
||||||
|
CLIENT_STATUS_CONTROL = -8, /**< Client is on the control channel */
|
||||||
CLIENT_STATUS_LOG = -7, /**< Client is a log file */
|
CLIENT_STATUS_LOG = -7, /**< Client is a log file */
|
||||||
CLIENT_STATUS_TLS_STARTTLS_HANDSHAKE = -8, /**< Client is doing a STARTTLS handshake */
|
CLIENT_STATUS_TLS_STARTTLS_HANDSHAKE = -8, /**< Client is doing a STARTTLS handshake */
|
||||||
CLIENT_STATUS_CONNECTING = -6, /**< Client is an outgoing connect */
|
CLIENT_STATUS_CONNECTING = -6, /**< Client is an outgoing connect */
|
||||||
|
@ -339,6 +346,7 @@ typedef enum ClientStatus {
|
||||||
/** Client is not fully registered yet. May become a user or a server, we don't know yet. */
|
/** Client is not fully registered yet. May become a user or a server, we don't know yet. */
|
||||||
#define IsUnknown(x) (((x)->status == CLIENT_STATUS_UNKNOWN) || ((x)->status == CLIENT_STATUS_TLS_STARTTLS_HANDSHAKE))
|
#define IsUnknown(x) (((x)->status == CLIENT_STATUS_UNKNOWN) || ((x)->status == CLIENT_STATUS_TLS_STARTTLS_HANDSHAKE))
|
||||||
#define IsServer(x) ((x)->status == CLIENT_STATUS_SERVER) /**< Is a server that has completed the connection handshake */
|
#define IsServer(x) ((x)->status == CLIENT_STATUS_SERVER) /**< Is a server that has completed the connection handshake */
|
||||||
|
#define IsControl(x) ((x)->status == CLIENT_STATUS_CONTROL) /**< Is on the control channel (not on IRC) */
|
||||||
#define IsLog(x) ((x)->status == CLIENT_STATUS_LOG) /**< Is a log file, not a user or server */
|
#define IsLog(x) ((x)->status == CLIENT_STATUS_LOG) /**< Is a log file, not a user or server */
|
||||||
#define IsStartTLSHandshake(x) ((x)->status == CLIENT_STATUS_TLS_STARTTLS_HANDSHAKE) /**< Currently doing a STARTTLS handshake */
|
#define IsStartTLSHandshake(x) ((x)->status == CLIENT_STATUS_TLS_STARTTLS_HANDSHAKE) /**< Currently doing a STARTTLS handshake */
|
||||||
#define IsTLSAcceptHandshake(x) ((x)->status == CLIENT_STATUS_TLS_ACCEPT_HANDSHAKE) /**< Currently doing a TLS handshake - incoming */
|
#define IsTLSAcceptHandshake(x) ((x)->status == CLIENT_STATUS_TLS_ACCEPT_HANDSHAKE) /**< Currently doing a TLS handshake - incoming */
|
||||||
|
@ -355,6 +363,8 @@ typedef enum ClientStatus {
|
||||||
#define SetServer(x) ((x)->status = CLIENT_STATUS_SERVER)
|
#define SetServer(x) ((x)->status = CLIENT_STATUS_SERVER)
|
||||||
#define SetUser(x) ((x)->status = CLIENT_STATUS_USER)
|
#define SetUser(x) ((x)->status = CLIENT_STATUS_USER)
|
||||||
#define SetLog(x) ((x)->status = CLIENT_STATUS_LOG)
|
#define SetLog(x) ((x)->status = CLIENT_STATUS_LOG)
|
||||||
|
#define SetControl(x) ((x)->status = CLIENT_STATUS_CONTROL)
|
||||||
|
#define SetUser(x) ((x)->status = CLIENT_STATUS_USER)
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
@ -366,7 +376,7 @@ typedef enum ClientStatus {
|
||||||
#define CLIENT_FLAG_DEAD 0x00000002 /**< Client is dead: already quit/exited and removed from all lists -- Remaining part will soon be freed in main loop */
|
#define CLIENT_FLAG_DEAD 0x00000002 /**< Client is dead: already quit/exited and removed from all lists -- Remaining part will soon be freed in main loop */
|
||||||
#define CLIENT_FLAG_DEADSOCKET 0x00000004 /**< Local socket is dead but otherwise the client still exists fully -- Will soon exit in main loop */
|
#define CLIENT_FLAG_DEADSOCKET 0x00000004 /**< Local socket is dead but otherwise the client still exists fully -- Will soon exit in main loop */
|
||||||
#define CLIENT_FLAG_KILLED 0x00000008 /**< Prevents "QUIT" from being sent for this */
|
#define CLIENT_FLAG_KILLED 0x00000008 /**< Prevents "QUIT" from being sent for this */
|
||||||
#define CLIENT_FLAG_IPV6 0x00000010 /**< Connection is using IPv6 */
|
#define CLIENT_FLAG_MONITOR_REHASH 0x00000010 /**< Client is monitoring rehash output */
|
||||||
#define CLIENT_FLAG_OUTGOING 0x00000020 /**< Outgoing connection (do not touch cptr->listener->clients) */
|
#define CLIENT_FLAG_OUTGOING 0x00000020 /**< Outgoing connection (do not touch cptr->listener->clients) */
|
||||||
#define CLIENT_FLAG_CLOSING 0x00000040 /**< Set when closing to suppress errors */
|
#define CLIENT_FLAG_CLOSING 0x00000040 /**< Set when closing to suppress errors */
|
||||||
#define CLIENT_FLAG_LISTEN 0x00000080 /**< Used to mark clients which we listen() on */
|
#define CLIENT_FLAG_LISTEN 0x00000080 /**< Used to mark clients which we listen() on */
|
||||||
|
@ -464,8 +474,8 @@ typedef enum ClientStatus {
|
||||||
#define IsDNSLookup(x) ((x)->flags & CLIENT_FLAG_DNSLOOKUP)
|
#define IsDNSLookup(x) ((x)->flags & CLIENT_FLAG_DNSLOOKUP)
|
||||||
#define IsEAuth(x) ((x)->flags & CLIENT_FLAG_EAUTH)
|
#define IsEAuth(x) ((x)->flags & CLIENT_FLAG_EAUTH)
|
||||||
#define IsIdentSuccess(x) ((x)->flags & CLIENT_FLAG_IDENTSUCCESS)
|
#define IsIdentSuccess(x) ((x)->flags & CLIENT_FLAG_IDENTSUCCESS)
|
||||||
#define IsIPV6(x) ((x)->flags & CLIENT_FLAG_IPV6)
|
|
||||||
#define IsKilled(x) ((x)->flags & CLIENT_FLAG_KILLED)
|
#define IsKilled(x) ((x)->flags & CLIENT_FLAG_KILLED)
|
||||||
|
#define IsMonitorRehash(x) ((x)->flags & CLIENT_FLAG_MONITOR_REHASH)
|
||||||
#define IsListening(x) ((x)->flags & CLIENT_FLAG_LISTEN)
|
#define IsListening(x) ((x)->flags & CLIENT_FLAG_LISTEN)
|
||||||
#define IsLocalhost(x) ((x)->flags & CLIENT_FLAG_LOCALHOST)
|
#define IsLocalhost(x) ((x)->flags & CLIENT_FLAG_LOCALHOST)
|
||||||
#define IsMap(x) ((x)->flags & CLIENT_FLAG_MAP)
|
#define IsMap(x) ((x)->flags & CLIENT_FLAG_MAP)
|
||||||
|
@ -496,8 +506,8 @@ typedef enum ClientStatus {
|
||||||
#define SetDNSLookup(x) do { (x)->flags |= CLIENT_FLAG_DNSLOOKUP; } while(0)
|
#define SetDNSLookup(x) do { (x)->flags |= CLIENT_FLAG_DNSLOOKUP; } while(0)
|
||||||
#define SetEAuth(x) do { (x)->flags |= CLIENT_FLAG_EAUTH; } while(0)
|
#define SetEAuth(x) do { (x)->flags |= CLIENT_FLAG_EAUTH; } while(0)
|
||||||
#define SetIdentSuccess(x) do { (x)->flags |= CLIENT_FLAG_IDENTSUCCESS; } while(0)
|
#define SetIdentSuccess(x) do { (x)->flags |= CLIENT_FLAG_IDENTSUCCESS; } while(0)
|
||||||
#define SetIPV6(x) do { (x)->flags |= CLIENT_FLAG_IPV6; } while(0)
|
|
||||||
#define SetKilled(x) do { (x)->flags |= CLIENT_FLAG_KILLED; } while(0)
|
#define SetKilled(x) do { (x)->flags |= CLIENT_FLAG_KILLED; } while(0)
|
||||||
|
#define SetMonitorRehash(x) do { (x)->flags |= CLIENT_FLAG_MONITOR_REHASH; } while(0)
|
||||||
#define SetListening(x) do { (x)->flags |= CLIENT_FLAG_LISTEN; } while(0)
|
#define SetListening(x) do { (x)->flags |= CLIENT_FLAG_LISTEN; } while(0)
|
||||||
#define SetLocalhost(x) do { (x)->flags |= CLIENT_FLAG_LOCALHOST; } while(0)
|
#define SetLocalhost(x) do { (x)->flags |= CLIENT_FLAG_LOCALHOST; } while(0)
|
||||||
#define SetMap(x) do { (x)->flags |= CLIENT_FLAG_MAP; } while(0)
|
#define SetMap(x) do { (x)->flags |= CLIENT_FLAG_MAP; } while(0)
|
||||||
|
@ -526,8 +536,8 @@ typedef enum ClientStatus {
|
||||||
#define ClearDNSLookup(x) do { (x)->flags &= ~CLIENT_FLAG_DNSLOOKUP; } while(0)
|
#define ClearDNSLookup(x) do { (x)->flags &= ~CLIENT_FLAG_DNSLOOKUP; } while(0)
|
||||||
#define ClearEAuth(x) do { (x)->flags &= ~CLIENT_FLAG_EAUTH; } while(0)
|
#define ClearEAuth(x) do { (x)->flags &= ~CLIENT_FLAG_EAUTH; } while(0)
|
||||||
#define ClearIdentSuccess(x) do { (x)->flags &= ~CLIENT_FLAG_IDENTSUCCESS; } while(0)
|
#define ClearIdentSuccess(x) do { (x)->flags &= ~CLIENT_FLAG_IDENTSUCCESS; } while(0)
|
||||||
#define ClearIPV6(x) do { (x)->flags &= ~CLIENT_FLAG_IPV6; } while(0)
|
|
||||||
#define ClearKilled(x) do { (x)->flags &= ~CLIENT_FLAG_KILLED; } while(0)
|
#define ClearKilled(x) do { (x)->flags &= ~CLIENT_FLAG_KILLED; } while(0)
|
||||||
|
#define ClearMonitorRehash(x) do { (x)->flags &= ~CLIENT_FLAG_MONITOR_REHASH; } while(0)
|
||||||
#define ClearListening(x) do { (x)->flags &= ~CLIENT_FLAG_LISTEN; } while(0)
|
#define ClearListening(x) do { (x)->flags &= ~CLIENT_FLAG_LISTEN; } while(0)
|
||||||
#define ClearLocalhost(x) do { (x)->flags &= ~CLIENT_FLAG_LOCALHOST; } while(0)
|
#define ClearLocalhost(x) do { (x)->flags &= ~CLIENT_FLAG_LOCALHOST; } while(0)
|
||||||
#define ClearMap(x) do { (x)->flags &= ~CLIENT_FLAG_MAP; } while(0)
|
#define ClearMap(x) do { (x)->flags &= ~CLIENT_FLAG_MAP; } while(0)
|
||||||
|
@ -546,6 +556,9 @@ typedef enum ClientStatus {
|
||||||
#define ClearULine(x) do { (x)->flags &= ~CLIENT_FLAG_ULINE; } while(0)
|
#define ClearULine(x) do { (x)->flags &= ~CLIENT_FLAG_ULINE; } while(0)
|
||||||
#define ClearVirus(x) do { (x)->flags &= ~CLIENT_FLAG_VIRUS; } while(0)
|
#define ClearVirus(x) do { (x)->flags &= ~CLIENT_FLAG_VIRUS; } while(0)
|
||||||
#define ClearIdentLookupSent(x) do { (x)->flags &= ~CLIENT_FLAG_IDENTLOOKUPSENT; } while(0)
|
#define ClearIdentLookupSent(x) do { (x)->flags &= ~CLIENT_FLAG_IDENTLOOKUPSENT; } while(0)
|
||||||
|
#define IsIPV6(x) ((x)->local->socket_type == SOCKET_TYPE_IPV6)
|
||||||
|
#define IsUnixSocket(x) ((x)->local->socket_type == SOCKET_TYPE_UNIX)
|
||||||
|
#define SetIPV6(x) do { (x)->local->socket_type = SOCKET_TYPE_IPV6; } while(0)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
|
@ -779,11 +792,11 @@ struct LoopStruct {
|
||||||
unsigned do_bancheck : 1; /* perform *line bancheck? */
|
unsigned do_bancheck : 1; /* perform *line bancheck? */
|
||||||
unsigned do_bancheck_spamf_user : 1; /* perform 'user' spamfilter bancheck */
|
unsigned do_bancheck_spamf_user : 1; /* perform 'user' spamfilter bancheck */
|
||||||
unsigned do_bancheck_spamf_away : 1; /* perform 'away' spamfilter bancheck */
|
unsigned do_bancheck_spamf_away : 1; /* perform 'away' spamfilter bancheck */
|
||||||
unsigned rehashing : 1;
|
|
||||||
unsigned terminating : 1;
|
unsigned terminating : 1;
|
||||||
unsigned config_load_failed : 1;
|
unsigned config_load_failed : 1;
|
||||||
unsigned rehash_download_busy : 1; /* don't return "all downloads complete", needed for race condition */
|
unsigned rehash_download_busy : 1; /* don't return "all downloads complete", needed for race condition */
|
||||||
unsigned tainted : 1;
|
unsigned tainted : 1;
|
||||||
|
int rehashing;
|
||||||
Client *rehash_save_client;
|
Client *rehash_save_client;
|
||||||
void (*boot_function)();
|
void (*boot_function)();
|
||||||
};
|
};
|
||||||
|
@ -851,6 +864,8 @@ struct SWhois {
|
||||||
#define CMD_VIRUS 0x0080
|
#define CMD_VIRUS 0x0080
|
||||||
/** Command requires IRCOp privileges */
|
/** Command requires IRCOp privileges */
|
||||||
#define CMD_OPER 0x0200
|
#define CMD_OPER 0x0200
|
||||||
|
/** Command is for control channel only (unrealircd.ctl socket) */
|
||||||
|
#define CMD_CONTROL 0x0400
|
||||||
|
|
||||||
/** Command function - used by all command handlers.
|
/** Command function - used by all command handlers.
|
||||||
* This is used in the code like <pre>CMD_FUNC(cmd_yourcmd)</pre> as a function definition.
|
* This is used in the code like <pre>CMD_FUNC(cmd_yourcmd)</pre> as a function definition.
|
||||||
|
@ -1212,6 +1227,7 @@ extern void unload_all_unused_moddata(void);
|
||||||
#define LISTENER_TLS 0x000010
|
#define LISTENER_TLS 0x000010
|
||||||
#define LISTENER_BOUND 0x000020
|
#define LISTENER_BOUND 0x000020
|
||||||
#define LISTENER_DEFER_ACCEPT 0x000040
|
#define LISTENER_DEFER_ACCEPT 0x000040
|
||||||
|
#define LISTENER_CONTROL 0x000080 /**< Control channel */
|
||||||
|
|
||||||
#define IsServersOnlyListener(x) ((x) && ((x)->options & LISTENER_SERVERSONLY))
|
#define IsServersOnlyListener(x) ((x) && ((x)->options & LISTENER_SERVERSONLY))
|
||||||
|
|
||||||
|
@ -1240,6 +1256,7 @@ typedef enum FloodOption {
|
||||||
FLD_KNOCK = 4, /**< knock-flood */
|
FLD_KNOCK = 4, /**< knock-flood */
|
||||||
FLD_CONVERSATIONS = 5, /**< max-concurrent-conversations */
|
FLD_CONVERSATIONS = 5, /**< max-concurrent-conversations */
|
||||||
FLD_LAG_PENALTY = 6, /**< lag-penalty / lag-penalty-bytes */
|
FLD_LAG_PENALTY = 6, /**< lag-penalty / lag-penalty-bytes */
|
||||||
|
FLD_VHOST = 7, /**< vhost-flood */
|
||||||
} FloodOption;
|
} FloodOption;
|
||||||
#define MAXFLOODOPTIONS 10
|
#define MAXFLOODOPTIONS 10
|
||||||
|
|
||||||
|
@ -1251,6 +1268,11 @@ struct TrafficStats {
|
||||||
long long bytes_received; /* Received bytes */
|
long long bytes_received; /* Received bytes */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Socket type (IPv4, IPv6, UNIX) */
|
||||||
|
typedef enum {
|
||||||
|
SOCKET_TYPE_IPV4=0, SOCKET_TYPE_IPV6=1, SOCKET_TYPE_UNIX=2
|
||||||
|
} SocketType;
|
||||||
|
|
||||||
/** This shows the Client struct (any client), the User struct (a user), Server (a server) that are commonly accessed both in the core and by 3rd party coders.
|
/** This shows the Client struct (any client), the User struct (a user), Server (a server) that are commonly accessed both in the core and by 3rd party coders.
|
||||||
* @defgroup CommonStructs Common structs
|
* @defgroup CommonStructs Common structs
|
||||||
* @{
|
* @{
|
||||||
|
@ -1288,6 +1310,7 @@ struct Client {
|
||||||
*/
|
*/
|
||||||
struct LocalClient {
|
struct LocalClient {
|
||||||
int fd; /**< File descriptor, can be <0 if socket has been closed already. */
|
int fd; /**< File descriptor, can be <0 if socket has been closed already. */
|
||||||
|
SocketType socket_type; /**< Type of socket: IPv4, IPV6, UNIX */
|
||||||
SSL *ssl; /**< OpenSSL/LibreSSL struct for TLS connection */
|
SSL *ssl; /**< OpenSSL/LibreSSL struct for TLS connection */
|
||||||
time_t fake_lag; /**< Time when user will next be allowed to send something (actually fake_lag<currenttime+10) */
|
time_t fake_lag; /**< Time when user will next be allowed to send something (actually fake_lag<currenttime+10) */
|
||||||
int fake_lag_msec; /**< Used for calculating 'fake_lag' penalty (modulo) */
|
int fake_lag_msec; /**< Used for calculating 'fake_lag' penalty (modulo) */
|
||||||
|
@ -1606,6 +1629,7 @@ struct ConfigItem_oper {
|
||||||
char *vhost;
|
char *vhost;
|
||||||
int maxlogins;
|
int maxlogins;
|
||||||
int server_notice_colors;
|
int server_notice_colors;
|
||||||
|
int server_notice_show_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The TLS options that are used in set::tls and otherblocks::tls-options.
|
/** The TLS options that are used in set::tls and otherblocks::tls-options.
|
||||||
|
@ -1666,11 +1690,12 @@ struct ConfigItem_tld {
|
||||||
struct ConfigItem_listen {
|
struct ConfigItem_listen {
|
||||||
ConfigItem_listen *prev, *next;
|
ConfigItem_listen *prev, *next;
|
||||||
ConfigFlag flag;
|
ConfigFlag flag;
|
||||||
|
SocketType socket_type;
|
||||||
|
char *file;
|
||||||
char *ip;
|
char *ip;
|
||||||
int port;
|
int port;
|
||||||
int options, clients;
|
int options, clients;
|
||||||
int fd;
|
int fd;
|
||||||
int ipv6;
|
|
||||||
SSL_CTX *ssl_ctx;
|
SSL_CTX *ssl_ctx;
|
||||||
TLSOptions *tls_options;
|
TLSOptions *tls_options;
|
||||||
int websocket_options; /* should be in module, but lazy */
|
int websocket_options; /* should be in module, but lazy */
|
||||||
|
|
|
@ -58,10 +58,12 @@
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#else
|
#else
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
#include <afunix.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
* Can be useful if the above 3 versionids are insufficient for you (eg: you want to support CVS).
|
* Can be useful if the above 3 versionids are insufficient for you (eg: you want to support CVS).
|
||||||
* This is updated automatically on the CVS server every Monday. so don't touch it.
|
* This is updated automatically on the CVS server every Monday. so don't touch it.
|
||||||
*/
|
*/
|
||||||
#define UNREAL_VERSION_TIME 202148
|
#define UNREAL_VERSION_TIME 202204
|
||||||
|
|
||||||
#define UNREAL_VERSION ((UNREAL_VERSION_GENERATION << 24) + (UNREAL_VERSION_MAJOR << 16) + (UNREAL_VERSION_MINOR << 8))
|
#define UNREAL_VERSION ((UNREAL_VERSION_GENERATION << 24) + (UNREAL_VERSION_MAJOR << 16) + (UNREAL_VERSION_MINOR << 8))
|
||||||
#define UnrealProtocol 6000
|
#define UnrealProtocol 6000
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#define CACHEDIR "cache"
|
#define CACHEDIR "cache"
|
||||||
#define TMPDIR "tmp"
|
#define TMPDIR "tmp"
|
||||||
#define PIDFILE PERMDATADIR"/unrealircd.pid"
|
#define PIDFILE PERMDATADIR"/unrealircd.pid"
|
||||||
|
#define CONTROLFILE PERMDATADIR"/unrealircd.ctl"
|
||||||
#define NO_U_TYPES
|
#define NO_U_TYPES
|
||||||
#define NEED_U_INT32_T
|
#define NEED_U_INT32_T
|
||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
|
@ -61,10 +62,10 @@
|
||||||
#define UNREAL_VERSION_MAJOR 0
|
#define UNREAL_VERSION_MAJOR 0
|
||||||
|
|
||||||
/* Minor version number (e.g.: 1 for Unreal3.2.1) */
|
/* Minor version number (e.g.: 1 for Unreal3.2.1) */
|
||||||
#define UNREAL_VERSION_MINOR 1
|
#define UNREAL_VERSION_MINOR 3
|
||||||
|
|
||||||
/* Version suffix such as a beta marker or release candidate marker. (e.g.:
|
/* Version suffix such as a beta marker or release candidate marker. (e.g.:
|
||||||
-rcX for unrealircd-3.2.9-rcX) */
|
-rcX for unrealircd-3.2.9-rcX) */
|
||||||
#define UNREAL_VERSION_SUFFIX ".1"
|
#define UNREAL_VERSION_SUFFIX ""
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
|
|
||||||
CC = "==== DO NOT RUN MAKE FROM THIS DIRECTORY ===="
|
CC = "==== DO NOT RUN MAKE FROM THIS DIRECTORY ===="
|
||||||
|
|
||||||
OBJS=dns.o auth.o channel.o crule.o dbuf.o \
|
OBJS=ircd_vars.o dns.o auth.o channel.o crule.o dbuf.o \
|
||||||
fdlist.o hash.o ircd.o ircsprintf.o list.o \
|
fdlist.o hash.o ircsprintf.o list.o \
|
||||||
match.o modules.o parse.o mempool.o operclass.o \
|
match.o modules.o parse.o mempool.o operclass.o \
|
||||||
conf_preprocessor.o conf.o debug.o dispatch.o \
|
conf_preprocessor.o conf.o proc_io_server.o debug.o dispatch.o \
|
||||||
misc.o serv.o aliases.o socket.o \
|
misc.o serv.o aliases.o socket.o \
|
||||||
tls.o user.o scache.o send.o support.o \
|
tls.o user.o scache.o send.o support.o \
|
||||||
version.o whowas.o random.o api-usermode.o api-channelmode.o \
|
version.o whowas.o random.o api-usermode.o api-channelmode.o \
|
||||||
|
@ -62,22 +62,22 @@ all: build
|
||||||
|
|
||||||
build:
|
build:
|
||||||
# Force build of 'ircd', before we start building any modules:
|
# Force build of 'ircd', before we start building any modules:
|
||||||
$(MAKE) ircd
|
$(MAKE) ircd unrealircdctl
|
||||||
$(MAKE) mods
|
$(MAKE) mods
|
||||||
|
|
||||||
custommodule:
|
custommodule:
|
||||||
+cd modules/third; $(MAKE) MODULEFILE=$(MODULEFILE) 'EXLIBS=$(EXLIBS)' custommodule
|
+cd modules/third; $(MAKE) MODULEFILE=$(MODULEFILE) 'EXLIBS=$(EXLIBS)' custommodule
|
||||||
|
|
||||||
ircd: $(OBJS)
|
ircd: $(OBJS) ircd.o
|
||||||
$(CC) $(CFLAGS) $(BINCFLAGS) $(CRYPTOLIB) -o ircd $(OBJS) $(LDFLAGS) $(BINLDFLAGS) $(IRCDLIBS) $(CRYPTOLIB)
|
$(CC) $(CFLAGS) $(BINCFLAGS) $(CRYPTOLIB) -o ircd ircd.o $(OBJS) $(LDFLAGS) $(BINLDFLAGS) $(IRCDLIBS) $(CRYPTOLIB)
|
||||||
|
|
||||||
|
unrealircdctl: $(OBJS) unrealircdctl.o proc_io_client.o
|
||||||
|
$(CC) $(CFLAGS) $(BINCFLAGS) $(CRYPTOLIB) -o unrealircdctl unrealircdctl.o proc_io_client.o $(OBJS) $(LDFLAGS) $(BINLDFLAGS) $(IRCDLIBS) $(CRYPTOLIB)
|
||||||
|
|
||||||
mods:
|
mods:
|
||||||
@if [ ! -r include ] ; then \
|
@if [ ! -r include ] ; then \
|
||||||
ln -s ../include include; \
|
ln -s ../include include; \
|
||||||
fi
|
fi
|
||||||
@if [ ! -r modules ] ; then \
|
|
||||||
echo "You havent done cvs update -P -d"; \
|
|
||||||
fi
|
|
||||||
+cd modules; $(MAKE) all
|
+cd modules; $(MAKE) all
|
||||||
|
|
||||||
version.c: version.c.SH
|
version.c: version.c.SH
|
||||||
|
|
|
@ -89,7 +89,7 @@ static Command *CommandAddInternal(Module *module, const char *cmd, CmdFunc func
|
||||||
Command *command = NULL;
|
Command *command = NULL;
|
||||||
RealCommand *c;
|
RealCommand *c;
|
||||||
|
|
||||||
if (find_command_simple(cmd))
|
if ((c = find_command(cmd, flags)) && (c->flags == flags))
|
||||||
{
|
{
|
||||||
if (module)
|
if (module)
|
||||||
module->errorcode = MODERR_EXISTS;
|
module->errorcode = MODERR_EXISTS;
|
||||||
|
@ -253,15 +253,26 @@ static RealCommand *add_Command_backend(const char *cmd)
|
||||||
RealCommand *find_command(const char *cmd, int flags)
|
RealCommand *find_command(const char *cmd, int flags)
|
||||||
{
|
{
|
||||||
RealCommand *p;
|
RealCommand *p;
|
||||||
for (p = CommandHash[toupper(*cmd)]; p; p = p->next) {
|
for (p = CommandHash[toupper(*cmd)]; p; p = p->next)
|
||||||
if ((flags & CMD_UNREGISTERED) && !(p->flags & CMD_UNREGISTERED))
|
{
|
||||||
continue;
|
if (flags & CMD_CONTROL)
|
||||||
if ((flags & CMD_SHUN) && !(p->flags & CMD_SHUN))
|
{
|
||||||
continue;
|
if (!(p->flags & CMD_CONTROL))
|
||||||
if ((flags & CMD_VIRUS) && !(p->flags & CMD_VIRUS))
|
continue;
|
||||||
continue;
|
} else
|
||||||
if ((flags & CMD_ALIAS) && !(p->flags & CMD_ALIAS))
|
{
|
||||||
continue;
|
if ((flags & CMD_UNREGISTERED) && !(p->flags & CMD_UNREGISTERED))
|
||||||
|
continue;
|
||||||
|
if ((flags & CMD_SHUN) && !(p->flags & CMD_SHUN))
|
||||||
|
continue;
|
||||||
|
if ((flags & CMD_VIRUS) && !(p->flags & CMD_VIRUS))
|
||||||
|
continue;
|
||||||
|
if ((flags & CMD_ALIAS) && !(p->flags & CMD_ALIAS))
|
||||||
|
continue;
|
||||||
|
if (p->flags & CMD_CONTROL)
|
||||||
|
continue; /* important to also filter it this way ;) */
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcasecmp(p->cmd, cmd))
|
if (!strcasecmp(p->cmd, cmd))
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,6 @@ ID_Copyright("(C) Carsten Munk 2001");
|
||||||
|
|
||||||
MODVAR Event *events = NULL;
|
MODVAR Event *events = NULL;
|
||||||
|
|
||||||
extern EVENT(unrealdns_removeoldrecords);
|
|
||||||
extern EVENT(unrealdb_expire_secret_cache);
|
|
||||||
|
|
||||||
/** Add an event, a function that will run at regular intervals.
|
/** Add an event, a function that will run at regular intervals.
|
||||||
* @param module Module that this event belongs to
|
* @param module Module that this event belongs to
|
||||||
* @param name Name of the event
|
* @param name Name of the event
|
||||||
|
@ -211,18 +208,3 @@ void DoEvents(void)
|
||||||
|
|
||||||
CleanupEvents();
|
CleanupEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupEvents(void)
|
|
||||||
{
|
|
||||||
/* Start events */
|
|
||||||
EventAdd(NULL, "tunefile", save_tunefile, NULL, 300*1000, 0);
|
|
||||||
EventAdd(NULL, "garbage", garbage_collect, NULL, GARBAGE_COLLECT_EVERY*1000, 0);
|
|
||||||
EventAdd(NULL, "loop", loop_event, NULL, 1000, 0);
|
|
||||||
EventAdd(NULL, "unrealdns_removeoldrecords", unrealdns_removeoldrecords, NULL, 15000, 0);
|
|
||||||
EventAdd(NULL, "check_pings", check_pings, NULL, 1000, 0);
|
|
||||||
EventAdd(NULL, "check_deadsockets", check_deadsockets, NULL, 1000, 0);
|
|
||||||
EventAdd(NULL, "handshake_timeout", handshake_timeout, NULL, 1000, 0);
|
|
||||||
EventAdd(NULL, "tls_check_expiry", tls_check_expiry, NULL, (86400/2)*1000, 0);
|
|
||||||
EventAdd(NULL, "unrealdb_expire_secret_cache", unrealdb_expire_secret_cache, NULL, 61000, 0);
|
|
||||||
EventAdd(NULL, "throttling_check_expire", throttling_check_expire, NULL, 1000, 0);
|
|
||||||
}
|
|
||||||
|
|
464
src/conf.c
464
src/conf.c
|
@ -199,8 +199,8 @@ void free_tls_options(TLSOptions *tlsoptions);
|
||||||
* Config parser (IRCd)
|
* Config parser (IRCd)
|
||||||
*/
|
*/
|
||||||
int config_read_file(const char *filename, const char *display_name);
|
int config_read_file(const char *filename, const char *display_name);
|
||||||
void config_rehash();
|
void config_rehash(void);
|
||||||
int config_run_blocks();
|
int config_run_blocks(void);
|
||||||
int config_test_blocks();
|
int config_test_blocks();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -464,10 +464,15 @@ int config_parse_flood_generic(const char *str, Configuration *conf, char *block
|
||||||
|
|
||||||
long config_checkval(const char *orig, unsigned short flags)
|
long config_checkval(const char *orig, unsigned short flags)
|
||||||
{
|
{
|
||||||
char *value = raw_strdup(orig);
|
char *value;
|
||||||
char *text;
|
char *text;
|
||||||
long ret = 0;
|
long ret = 0;
|
||||||
|
|
||||||
|
/* Handle empty strings early, since we use +1 later in the code etc. */
|
||||||
|
if (BadPtr(orig))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
value = raw_strdup(orig);
|
||||||
if (flags == CFG_YESNO) {
|
if (flags == CFG_YESNO) {
|
||||||
for (text = value; *text; text++) {
|
for (text = value; *text; text++) {
|
||||||
if (!isalnum(*text))
|
if (!isalnum(*text))
|
||||||
|
@ -1586,7 +1591,7 @@ ConfigCommand *config_binary_search(const char *cmd) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_iConf(Configuration *i)
|
void free_iConf(Configuration *i)
|
||||||
{
|
{
|
||||||
FloodSettings *f, *f_next;
|
FloodSettings *f, *f_next;
|
||||||
|
|
||||||
|
@ -1645,6 +1650,7 @@ void config_setdefaultsettings(Configuration *i)
|
||||||
|
|
||||||
safe_strdup(i->oper_snomask, OPER_SNOMASKS);
|
safe_strdup(i->oper_snomask, OPER_SNOMASKS);
|
||||||
i->server_notice_colors = 1;
|
i->server_notice_colors = 1;
|
||||||
|
i->server_notice_show_event = 1;
|
||||||
i->ident_read_timeout = 7;
|
i->ident_read_timeout = 7;
|
||||||
i->ident_connect_timeout = 3;
|
i->ident_connect_timeout = 3;
|
||||||
i->ban_version_tkl_time = 86400; /* 1d */
|
i->ban_version_tkl_time = 86400; /* 1d */
|
||||||
|
@ -1694,6 +1700,7 @@ void config_setdefaultsettings(Configuration *i)
|
||||||
/* - known-users */
|
/* - known-users */
|
||||||
config_parse_flood_generic("3:60", i, "known-users", FLD_NICK); /* NICK flood protection: max 3 per 60s */
|
config_parse_flood_generic("3:60", i, "known-users", FLD_NICK); /* NICK flood protection: max 3 per 60s */
|
||||||
config_parse_flood_generic("3:90", i, "known-users", FLD_JOIN); /* JOIN flood protection: max 3 per 90s */
|
config_parse_flood_generic("3:90", i, "known-users", FLD_JOIN); /* JOIN flood protection: max 3 per 90s */
|
||||||
|
config_parse_flood_generic("3:90", i, "known-users", FLD_VHOST); /* MODE -x flood protection: max 3 per 90s */
|
||||||
config_parse_flood_generic("4:120", i, "known-users", FLD_AWAY); /* AWAY flood protection: max 4 per 120s */
|
config_parse_flood_generic("4:120", i, "known-users", FLD_AWAY); /* AWAY flood protection: max 4 per 120s */
|
||||||
config_parse_flood_generic("4:60", i, "known-users", FLD_INVITE); /* INVITE flood protection: max 4 per 60s */
|
config_parse_flood_generic("4:60", i, "known-users", FLD_INVITE); /* INVITE flood protection: max 4 per 60s */
|
||||||
config_parse_flood_generic("4:120", i, "known-users", FLD_KNOCK); /* KNOCK protection: max 4 per 120s */
|
config_parse_flood_generic("4:120", i, "known-users", FLD_KNOCK); /* KNOCK protection: max 4 per 120s */
|
||||||
|
@ -1702,6 +1709,7 @@ void config_setdefaultsettings(Configuration *i)
|
||||||
/* - unknown-users */
|
/* - unknown-users */
|
||||||
config_parse_flood_generic("2:60", i, "unknown-users", FLD_NICK); /* NICK flood protection: max 2 per 60s */
|
config_parse_flood_generic("2:60", i, "unknown-users", FLD_NICK); /* NICK flood protection: max 2 per 60s */
|
||||||
config_parse_flood_generic("2:90", i, "unknown-users", FLD_JOIN); /* JOIN flood protection: max 2 per 90s */
|
config_parse_flood_generic("2:90", i, "unknown-users", FLD_JOIN); /* JOIN flood protection: max 2 per 90s */
|
||||||
|
config_parse_flood_generic("2:90", i, "unknown-users", FLD_VHOST); /* MODE -x flood protection: max 2 per 90s */
|
||||||
config_parse_flood_generic("4:120", i, "unknown-users", FLD_AWAY); /* AWAY flood protection: max 4 per 120s */
|
config_parse_flood_generic("4:120", i, "unknown-users", FLD_AWAY); /* AWAY flood protection: max 4 per 120s */
|
||||||
config_parse_flood_generic("2:60", i, "unknown-users", FLD_INVITE); /* INVITE flood protection: max 2 per 60s */
|
config_parse_flood_generic("2:60", i, "unknown-users", FLD_INVITE); /* INVITE flood protection: max 2 per 60s */
|
||||||
config_parse_flood_generic("2:120", i, "unknown-users", FLD_KNOCK); /* KNOCK protection: max 2 per 120s */
|
config_parse_flood_generic("2:120", i, "unknown-users", FLD_KNOCK); /* KNOCK protection: max 2 per 120s */
|
||||||
|
@ -2411,7 +2419,8 @@ void config_rehash()
|
||||||
}
|
}
|
||||||
for (listen_ptr = conf_listen; listen_ptr; listen_ptr = listen_ptr->next)
|
for (listen_ptr = conf_listen; listen_ptr; listen_ptr = listen_ptr->next)
|
||||||
{
|
{
|
||||||
listen_ptr->flag.temporary = 1;
|
if (!(listen_ptr->options & LISTENER_CONTROL))
|
||||||
|
listen_ptr->flag.temporary = 1;
|
||||||
}
|
}
|
||||||
for (tld_ptr = conf_tld; tld_ptr; tld_ptr = (ConfigItem_tld *) next)
|
for (tld_ptr = conf_tld; tld_ptr; tld_ptr = (ConfigItem_tld *) next)
|
||||||
{
|
{
|
||||||
|
@ -2642,152 +2651,87 @@ void config_switchover(void)
|
||||||
log_blocks_switchover();
|
log_blocks_switchover();
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_run_blocks()
|
/** Priority of config blocks during CONFIG_TEST stage */
|
||||||
|
static const char *config_test_priority_blocks[] =
|
||||||
|
{
|
||||||
|
"me",
|
||||||
|
"secret",
|
||||||
|
"log", /* "log" needs to be before "set" in CONFIG_TEST */
|
||||||
|
"set",
|
||||||
|
"class",
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Priority of config blocks during CONFIG_RUN stage */
|
||||||
|
static const char *config_run_priority_blocks[] =
|
||||||
|
{
|
||||||
|
"me",
|
||||||
|
"secret",
|
||||||
|
"set",
|
||||||
|
"log", /* "log" needs to be after "set" in CONFIG_RUN */
|
||||||
|
"class",
|
||||||
|
};
|
||||||
|
|
||||||
|
int config_test_blocks()
|
||||||
{
|
{
|
||||||
ConfigEntry *ce;
|
ConfigEntry *ce;
|
||||||
ConfigFile *cfptr;
|
ConfigFile *cfptr;
|
||||||
ConfigCommand *cc;
|
ConfigCommand *cc;
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
int i;
|
||||||
Hook *h;
|
Hook *h;
|
||||||
ConfigItem_allow *allow;
|
|
||||||
|
|
||||||
/* Stage 1: set block first */
|
invalid_snomasks_encountered = 0;
|
||||||
for (cfptr = conf; cfptr; cfptr = cfptr->next)
|
|
||||||
|
/* Stage 1: first the priority blocks, in the order as specified
|
||||||
|
* in config_test_priority_blocks[]
|
||||||
|
*/
|
||||||
|
for (i=0; i < ARRAY_SIZEOF(config_test_priority_blocks); i++)
|
||||||
{
|
{
|
||||||
if (config_verbose > 1)
|
const char *config_block = config_test_priority_blocks[i];
|
||||||
config_status("Running %s", cfptr->filename);
|
cc = config_binary_search(config_block);
|
||||||
for (ce = cfptr->items; ce; ce = ce->next)
|
if (!cc)
|
||||||
|
abort(); /* internal fuckup */
|
||||||
|
for (cfptr = conf; cfptr; cfptr = cfptr->next)
|
||||||
{
|
{
|
||||||
if (!strcmp(ce->name, "set"))
|
if (config_verbose > 1)
|
||||||
|
config_status("Running %s", cfptr->filename);
|
||||||
|
for (ce = cfptr->items; ce; ce = ce->next)
|
||||||
{
|
{
|
||||||
if (_conf_set(cfptr, ce) < 0)
|
if (!strcmp(ce->name, config_block))
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stage 2: now class blocks */
|
|
||||||
for (cfptr = conf; cfptr; cfptr = cfptr->next)
|
|
||||||
{
|
|
||||||
if (config_verbose > 1)
|
|
||||||
config_status("Running %s", cfptr->filename);
|
|
||||||
for (ce = cfptr->items; ce; ce = ce->next)
|
|
||||||
{
|
|
||||||
if (!strcmp(ce->name, "class"))
|
|
||||||
{
|
|
||||||
if (_conf_class(cfptr, ce) < 0)
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stage 3: now all the rest */
|
|
||||||
for (cfptr = conf; cfptr; cfptr = cfptr->next)
|
|
||||||
{
|
|
||||||
if (config_verbose > 1)
|
|
||||||
config_status("Running %s", cfptr->filename);
|
|
||||||
for (ce = cfptr->items; ce; ce = ce->next)
|
|
||||||
{
|
|
||||||
/* These are already processed above (set, class)
|
|
||||||
* or via config_test_blocks() (secret).
|
|
||||||
*/
|
|
||||||
if (!strcmp(ce->name, "set") ||
|
|
||||||
!strcmp(ce->name, "class") ||
|
|
||||||
!strcmp(ce->name, "secret"))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cc = config_binary_search(ce->name))) {
|
|
||||||
if ((cc->conffunc) && (cc->conffunc(cfptr, ce) < 0))
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int value;
|
|
||||||
for (h = Hooks[HOOKTYPE_CONFIGRUN]; h; h = h->next)
|
|
||||||
{
|
{
|
||||||
value = (*(h->func.intfunc))(cfptr,ce,CONFIG_MAIN);
|
int n = cc->testfunc(cfptr, ce);
|
||||||
if (value == 1)
|
errors += n;
|
||||||
break;
|
if (!strcmp(config_block, "secret") && (n == 0))
|
||||||
|
{
|
||||||
|
/* Yeah special case: secret { } blocks we run
|
||||||
|
* immediately here.
|
||||||
|
*/
|
||||||
|
_conf_secret(cfptr, ce);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close_unbound_listeners();
|
/* Stage 2: now all the other config blocks */
|
||||||
listen_cleanup();
|
|
||||||
close_unbound_listeners();
|
|
||||||
loop.do_bancheck = 1;
|
|
||||||
config_switchover();
|
|
||||||
update_throttling_timer_settings();
|
|
||||||
|
|
||||||
/* initialize conf_files with defaults if the block isn't set: */
|
|
||||||
if (!conf_files)
|
|
||||||
_conf_files(NULL, NULL);
|
|
||||||
|
|
||||||
if (errors > 0)
|
|
||||||
{
|
|
||||||
config_error("%i fatal errors encountered", errors);
|
|
||||||
}
|
|
||||||
return (errors > 0 ? -1 : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int config_test_blocks()
|
|
||||||
{
|
|
||||||
ConfigEntry *ce;
|
|
||||||
ConfigFile *cfptr;
|
|
||||||
ConfigCommand *cc;
|
|
||||||
int errors = 0;
|
|
||||||
Hook *h;
|
|
||||||
|
|
||||||
invalid_snomasks_encountered = 0;
|
|
||||||
|
|
||||||
/* First, all the log { } blocks everywhere */
|
|
||||||
for (cfptr = conf; cfptr; cfptr = cfptr->next)
|
for (cfptr = conf; cfptr; cfptr = cfptr->next)
|
||||||
{
|
{
|
||||||
if (config_verbose > 1)
|
if (config_verbose > 1)
|
||||||
config_status("Testing %s", cfptr->filename);
|
config_status("Running %s", cfptr->filename);
|
||||||
/* First test and run the log { } blocks */
|
|
||||||
for (ce = cfptr->items; ce; ce = ce->next)
|
for (ce = cfptr->items; ce; ce = ce->next)
|
||||||
{
|
{
|
||||||
if (!strcmp(ce->name, "log"))
|
char skip = 0;
|
||||||
errors += config_test_log(cfptr, ce);
|
for (i=0; i < ARRAY_SIZEOF(config_test_priority_blocks); i++)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cfptr = conf; cfptr; cfptr = cfptr->next)
|
|
||||||
{
|
|
||||||
if (config_verbose > 1)
|
|
||||||
config_status("Testing %s", cfptr->filename);
|
|
||||||
/* First test and run the secret { } blocks */
|
|
||||||
for (ce = cfptr->items; ce; ce = ce->next)
|
|
||||||
{
|
|
||||||
if (!strcmp(ce->name, "secret"))
|
|
||||||
{
|
{
|
||||||
int n = _test_secret(cfptr, ce);
|
if (!strcmp(ce->name, config_test_priority_blocks[i]))
|
||||||
errors += n;
|
{
|
||||||
if (n == 0)
|
skip = 1;
|
||||||
_conf_secret(cfptr, ce);
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (skip)
|
||||||
/* First test the set { } block */
|
|
||||||
for (ce = cfptr->items; ce; ce = ce->next)
|
|
||||||
{
|
|
||||||
if (!strcmp(ce->name, "set"))
|
|
||||||
errors += _test_set(cfptr, ce);
|
|
||||||
}
|
|
||||||
/* Now test all the rest */
|
|
||||||
for (ce = cfptr->items; ce; ce = ce->next)
|
|
||||||
{
|
|
||||||
/* These are already processed, so skip them here.. */
|
|
||||||
if (!strcmp(ce->name, "secret") ||
|
|
||||||
!strcmp(ce->name, "set") ||
|
|
||||||
!strcmp(ce->name, "log"))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if ((cc = config_binary_search(ce->name))) {
|
if ((cc = config_binary_search(ce->name))) {
|
||||||
if (cc->testfunc)
|
if (cc->testfunc)
|
||||||
errors += (cc->testfunc(cfptr, ce));
|
errors += (cc->testfunc(cfptr, ce));
|
||||||
|
@ -2841,7 +2785,9 @@ int config_test_blocks()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errors += config_post_test();
|
errors += config_post_test();
|
||||||
|
|
||||||
if (errors > 0)
|
if (errors > 0)
|
||||||
{
|
{
|
||||||
config_error("%i errors encountered", errors);
|
config_error("%i errors encountered", errors);
|
||||||
|
@ -2856,6 +2802,96 @@ int config_test_blocks()
|
||||||
return (errors > 0 ? -1 : 1);
|
return (errors > 0 ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_run_blocks(void)
|
||||||
|
{
|
||||||
|
ConfigEntry *ce;
|
||||||
|
ConfigFile *cfptr;
|
||||||
|
ConfigCommand *cc;
|
||||||
|
int errors = 0;
|
||||||
|
int i;
|
||||||
|
Hook *h;
|
||||||
|
ConfigItem_allow *allow;
|
||||||
|
|
||||||
|
/* Stage 1: first the priority blocks, in the order as specified
|
||||||
|
* in config_run_priority_blocks[]
|
||||||
|
*/
|
||||||
|
for (i=0; i < ARRAY_SIZEOF(config_run_priority_blocks); i++)
|
||||||
|
{
|
||||||
|
const char *config_block = config_run_priority_blocks[i];
|
||||||
|
cc = config_binary_search(config_block);
|
||||||
|
if (!cc)
|
||||||
|
abort(); /* internal fuckup */
|
||||||
|
if (!strcmp(config_block, "secret"))
|
||||||
|
continue; /* yeah special case, we already processed the run part in test for these */
|
||||||
|
for (cfptr = conf; cfptr; cfptr = cfptr->next)
|
||||||
|
{
|
||||||
|
if (config_verbose > 1)
|
||||||
|
config_status("Running %s", cfptr->filename);
|
||||||
|
for (ce = cfptr->items; ce; ce = ce->next)
|
||||||
|
{
|
||||||
|
if (!strcmp(ce->name, config_block))
|
||||||
|
{
|
||||||
|
if (cc->conffunc(cfptr, ce) < 0)
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stage 2: now all the other config blocks */
|
||||||
|
for (cfptr = conf; cfptr; cfptr = cfptr->next)
|
||||||
|
{
|
||||||
|
if (config_verbose > 1)
|
||||||
|
config_status("Running %s", cfptr->filename);
|
||||||
|
for (ce = cfptr->items; ce; ce = ce->next)
|
||||||
|
{
|
||||||
|
char skip = 0;
|
||||||
|
for (i=0; i < ARRAY_SIZEOF(config_run_priority_blocks); i++)
|
||||||
|
{
|
||||||
|
if (!strcmp(ce->name, config_run_priority_blocks[i]))
|
||||||
|
{
|
||||||
|
skip = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skip)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((cc = config_binary_search(ce->name))) {
|
||||||
|
if ((cc->conffunc) && (cc->conffunc(cfptr, ce) < 0))
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
for (h = Hooks[HOOKTYPE_CONFIGRUN]; h; h = h->next)
|
||||||
|
{
|
||||||
|
value = (*(h->func.intfunc))(cfptr,ce,CONFIG_MAIN);
|
||||||
|
if (value == 1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close_unbound_listeners();
|
||||||
|
listen_cleanup();
|
||||||
|
close_unbound_listeners();
|
||||||
|
loop.do_bancheck = 1;
|
||||||
|
config_switchover();
|
||||||
|
update_throttling_timer_settings();
|
||||||
|
|
||||||
|
/* initialize conf_files with defaults if the block isn't set: */
|
||||||
|
if (!conf_files)
|
||||||
|
_conf_files(NULL, NULL);
|
||||||
|
|
||||||
|
if (errors > 0)
|
||||||
|
{
|
||||||
|
config_error("%i fatal errors encountered", errors);
|
||||||
|
}
|
||||||
|
return (errors > 0 ? -1 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Service functions
|
* Service functions
|
||||||
*/
|
*/
|
||||||
|
@ -2935,7 +2971,7 @@ int count_oper_sessions(const char *name)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigItem_listen *find_listen(const char *ipmask, int port, int ipv6)
|
ConfigItem_listen *find_listen(const char *ipmask, int port, SocketType socket_type)
|
||||||
{
|
{
|
||||||
ConfigItem_listen *e;
|
ConfigItem_listen *e;
|
||||||
|
|
||||||
|
@ -2943,8 +2979,19 @@ ConfigItem_listen *find_listen(const char *ipmask, int port, int ipv6)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (e = conf_listen; e; e = e->next)
|
for (e = conf_listen; e; e = e->next)
|
||||||
if ((e->ipv6 == ipv6) && (e->port == port) && !strcmp(e->ip, ipmask))
|
{
|
||||||
return e;
|
if (e->socket_type != socket_type)
|
||||||
|
continue;
|
||||||
|
if (e->socket_type == SOCKET_TYPE_UNIX)
|
||||||
|
{
|
||||||
|
if (!strcmp(e->file, ipmask))
|
||||||
|
return e;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if ((e->socket_type == socket_type) && (e->port == port) && !strcmp(e->ip, ipmask))
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -3889,7 +3936,9 @@ int _conf_oper(ConfigFile *conf, ConfigEntry *ce)
|
||||||
oper = safe_alloc(sizeof(ConfigItem_oper));
|
oper = safe_alloc(sizeof(ConfigItem_oper));
|
||||||
safe_strdup(oper->name, ce->value);
|
safe_strdup(oper->name, ce->value);
|
||||||
|
|
||||||
oper->server_notice_colors = tempiConf.server_notice_colors; /* default */
|
/* Inherit some defaults: */
|
||||||
|
oper->server_notice_colors = tempiConf.server_notice_colors;
|
||||||
|
oper->server_notice_show_event = tempiConf.server_notice_show_event;
|
||||||
|
|
||||||
for (cep = ce->items; cep; cep = cep->next)
|
for (cep = ce->items; cep; cep = cep->next)
|
||||||
{
|
{
|
||||||
|
@ -3937,6 +3986,10 @@ int _conf_oper(ConfigFile *conf, ConfigEntry *ce)
|
||||||
{
|
{
|
||||||
oper->server_notice_colors = config_checkval(cep->value, CFG_YESNO);
|
oper->server_notice_colors = config_checkval(cep->value, CFG_YESNO);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(cep->name, "server-notice-show-event"))
|
||||||
|
{
|
||||||
|
oper->server_notice_show_event = config_checkval(cep->value, CFG_YESNO);
|
||||||
|
}
|
||||||
else if (!strcmp(cep->name, "modes"))
|
else if (!strcmp(cep->name, "modes"))
|
||||||
{
|
{
|
||||||
oper->modes = set_usermode(cep->value);
|
oper->modes = set_usermode(cep->value);
|
||||||
|
@ -4069,6 +4122,9 @@ int _test_oper(ConfigFile *conf, ConfigEntry *ce)
|
||||||
else if (!strcmp(cep->name, "server-notice-colors"))
|
else if (!strcmp(cep->name, "server-notice-colors"))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(cep->name, "server-notice-show-event"))
|
||||||
|
{
|
||||||
|
}
|
||||||
/* oper::modes */
|
/* oper::modes */
|
||||||
else if (!strcmp(cep->name, "modes"))
|
else if (!strcmp(cep->name, "modes"))
|
||||||
{
|
{
|
||||||
|
@ -4777,6 +4833,7 @@ int _conf_listen(ConfigFile *conf, ConfigEntry *ce)
|
||||||
ConfigEntry *cepp;
|
ConfigEntry *cepp;
|
||||||
ConfigEntry *tlsconfig = NULL;
|
ConfigEntry *tlsconfig = NULL;
|
||||||
ConfigItem_listen *listen = NULL;
|
ConfigItem_listen *listen = NULL;
|
||||||
|
char *file = NULL;
|
||||||
char *ip = NULL;
|
char *ip = NULL;
|
||||||
int start=0, end=0, port, isnew;
|
int start=0, end=0, port, isnew;
|
||||||
int tmpflags =0;
|
int tmpflags =0;
|
||||||
|
@ -4784,6 +4841,10 @@ int _conf_listen(ConfigFile *conf, ConfigEntry *ce)
|
||||||
|
|
||||||
for (cep = ce->items; cep; cep = cep->next)
|
for (cep = ce->items; cep; cep = cep->next)
|
||||||
{
|
{
|
||||||
|
if (!strcmp(cep->name, "file"))
|
||||||
|
{
|
||||||
|
file = cep->value;
|
||||||
|
} else
|
||||||
if (!strcmp(cep->name, "ip"))
|
if (!strcmp(cep->name, "ip"))
|
||||||
{
|
{
|
||||||
ip = cep->value;
|
ip = cep->value;
|
||||||
|
@ -4825,18 +4886,44 @@ int _conf_listen(ConfigFile *conf, ConfigEntry *ce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* UNIX domain socket code */
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
if (!(listen = find_listen(file, 0, SOCKET_TYPE_UNIX)))
|
||||||
|
{
|
||||||
|
listen = safe_alloc(sizeof(ConfigItem_listen));
|
||||||
|
safe_strdup(listen->file, file);
|
||||||
|
listen->socket_type = SOCKET_TYPE_UNIX;
|
||||||
|
listen->fd = -1;
|
||||||
|
isnew = 1;
|
||||||
|
} else {
|
||||||
|
isnew = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen->options & LISTENER_BOUND)
|
||||||
|
tmpflags |= LISTENER_BOUND;
|
||||||
|
|
||||||
|
listen->options = tmpflags;
|
||||||
|
if (isnew)
|
||||||
|
AddListItem(listen, conf_listen);
|
||||||
|
listen->flag.temporary = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (port = start; port <= end; port++)
|
for (port = start; port <= end; port++)
|
||||||
{
|
{
|
||||||
/* First deal with IPv4 */
|
/* First deal with IPv4 */
|
||||||
if (!strchr(ip, ':'))
|
if (!strchr(ip, ':'))
|
||||||
{
|
{
|
||||||
if (!(listen = find_listen(ip, port, 0)))
|
if (!(listen = find_listen(ip, port, SOCKET_TYPE_IPV4)))
|
||||||
{
|
{
|
||||||
listen = safe_alloc(sizeof(ConfigItem_listen));
|
listen = safe_alloc(sizeof(ConfigItem_listen));
|
||||||
safe_strdup(listen->ip, ip);
|
safe_strdup(listen->ip, ip);
|
||||||
listen->port = port;
|
listen->port = port;
|
||||||
listen->fd = -1;
|
listen->fd = -1;
|
||||||
listen->ipv6 = 0;
|
listen->socket_type = SOCKET_TYPE_IPV4;
|
||||||
isnew = 1;
|
isnew = 1;
|
||||||
} else
|
} else
|
||||||
isnew = 0;
|
isnew = 0;
|
||||||
|
@ -4915,13 +5002,13 @@ int _conf_listen(ConfigFile *conf, ConfigEntry *ce)
|
||||||
{
|
{
|
||||||
if (strchr(ip, ':') || (*ip == '*'))
|
if (strchr(ip, ':') || (*ip == '*'))
|
||||||
{
|
{
|
||||||
if (!(listen = find_listen(ip, port, 1)))
|
if (!(listen = find_listen(ip, port, SOCKET_TYPE_IPV6)))
|
||||||
{
|
{
|
||||||
listen = safe_alloc(sizeof(ConfigItem_listen));
|
listen = safe_alloc(sizeof(ConfigItem_listen));
|
||||||
safe_strdup(listen->ip, ip);
|
safe_strdup(listen->ip, ip);
|
||||||
listen->port = port;
|
listen->port = port;
|
||||||
listen->fd = -1;
|
listen->fd = -1;
|
||||||
listen->ipv6 = 1;
|
listen->socket_type = SOCKET_TYPE_IPV6;
|
||||||
isnew = 1;
|
isnew = 1;
|
||||||
} else
|
} else
|
||||||
isnew = 0;
|
isnew = 0;
|
||||||
|
@ -5002,7 +5089,8 @@ int _test_listen(ConfigFile *conf, ConfigEntry *ce)
|
||||||
ConfigEntry *cep;
|
ConfigEntry *cep;
|
||||||
ConfigEntry *cepp;
|
ConfigEntry *cepp;
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
char has_ip = 0, has_port = 0, has_options = 0, port_6667 = 0;
|
char has_file = 0, has_ip = 0, has_port = 0, has_options = 0, port_6667 = 0;
|
||||||
|
char *file = NULL;
|
||||||
char *ip = NULL;
|
char *ip = NULL;
|
||||||
Hook *h;
|
Hook *h;
|
||||||
|
|
||||||
|
@ -5117,6 +5205,11 @@ int _test_listen(ConfigFile *conf, ConfigEntry *ce)
|
||||||
}
|
}
|
||||||
continue; /* always */
|
continue; /* always */
|
||||||
} else
|
} else
|
||||||
|
if (!strcmp(cep->name, "file"))
|
||||||
|
{
|
||||||
|
has_file = 1;
|
||||||
|
file = cep->value;
|
||||||
|
} else
|
||||||
if (!strcmp(cep->name, "ip"))
|
if (!strcmp(cep->name, "ip"))
|
||||||
{
|
{
|
||||||
has_ip = 1;
|
has_ip = 1;
|
||||||
|
@ -5189,18 +5282,32 @@ int _test_listen(ConfigFile *conf, ConfigEntry *ce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_ip)
|
if (has_file)
|
||||||
{
|
{
|
||||||
config_error("%s:%d: listen block requires an listen::ip",
|
if (has_ip || has_port)
|
||||||
ce->file->filename, ce->line_number);
|
{
|
||||||
errors++;
|
config_error("%s:%d: listen block should either have a 'file' (for *NIX domain socket), "
|
||||||
}
|
"OR have an 'ip' and 'port' (for IPv4/IPv6). You cannot combine both in one listen block.",
|
||||||
|
ce->file->filename, ce->line_number);
|
||||||
|
errors++;
|
||||||
|
} else {
|
||||||
|
// TODO: check if file can be created fresh etc.
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if (!has_ip)
|
||||||
|
{
|
||||||
|
config_error("%s:%d: listen block requires an listen::ip",
|
||||||
|
ce->file->filename, ce->line_number);
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
|
||||||
if (!has_port)
|
if (!has_port)
|
||||||
{
|
{
|
||||||
config_error("%s:%d: listen block requires an listen::port",
|
config_error("%s:%d: listen block requires an listen::port",
|
||||||
ce->file->filename, ce->line_number);
|
ce->file->filename, ce->line_number);
|
||||||
errors++;
|
errors++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port_6667)
|
if (port_6667)
|
||||||
|
@ -7167,6 +7274,9 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
|
||||||
else if (!strcmp(cep->name, "server-notice-colors")) {
|
else if (!strcmp(cep->name, "server-notice-colors")) {
|
||||||
tempiConf.server_notice_colors = config_checkval(cep->value, CFG_YESNO);
|
tempiConf.server_notice_colors = config_checkval(cep->value, CFG_YESNO);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(cep->name, "server-notice-show-event")) {
|
||||||
|
tempiConf.server_notice_show_event = config_checkval(cep->value, CFG_YESNO);
|
||||||
|
}
|
||||||
else if (!strcmp(cep->name, "level-on-join")) {
|
else if (!strcmp(cep->name, "level-on-join")) {
|
||||||
const char *res = channellevel_to_string(cep->value); /* 'halfop', etc */
|
const char *res = channellevel_to_string(cep->value); /* 'halfop', etc */
|
||||||
if (!res)
|
if (!res)
|
||||||
|
@ -7380,6 +7490,10 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
|
||||||
{
|
{
|
||||||
config_parse_flood_generic(ceppp->value, &tempiConf, cepp->name, FLD_NICK);
|
config_parse_flood_generic(ceppp->value, &tempiConf, cepp->name, FLD_NICK);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(ceppp->name, "vhost-flood"))
|
||||||
|
{
|
||||||
|
config_parse_flood_generic(ceppp->value, &tempiConf, cepp->name, FLD_VHOST);
|
||||||
|
}
|
||||||
else if (!strcmp(ceppp->name, "join-flood"))
|
else if (!strcmp(ceppp->name, "join-flood"))
|
||||||
{
|
{
|
||||||
config_parse_flood_generic(ceppp->value, &tempiConf, cepp->name, FLD_JOIN);
|
config_parse_flood_generic(ceppp->value, &tempiConf, cepp->name, FLD_JOIN);
|
||||||
|
@ -7847,6 +7961,9 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
|
||||||
else if (!strcmp(cep->name, "server-notice-colors")) {
|
else if (!strcmp(cep->name, "server-notice-colors")) {
|
||||||
CheckNull(cep);
|
CheckNull(cep);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(cep->name, "server-notice-show-event")) {
|
||||||
|
CheckNull(cep);
|
||||||
|
}
|
||||||
else if (!strcmp(cep->name, "level-on-join")) {
|
else if (!strcmp(cep->name, "level-on-join")) {
|
||||||
CheckNull(cep);
|
CheckNull(cep);
|
||||||
CheckDuplicate(cep, level_on_join, "level-on-join");
|
CheckDuplicate(cep, level_on_join, "level-on-join");
|
||||||
|
@ -8340,6 +8457,19 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(ceppp->name, "vhost-flood"))
|
||||||
|
{
|
||||||
|
int cnt, period;
|
||||||
|
CheckNull(ceppp);
|
||||||
|
if (!config_parse_flood(ceppp->value, &cnt, &period) ||
|
||||||
|
(cnt < 1) || (cnt > 255) || (period < 5))
|
||||||
|
{
|
||||||
|
config_error("%s:%i: set::anti-flood::vhost-flood error. Syntax is '<count>:<period>' (eg 5:60), "
|
||||||
|
"count should be 1-255, period should be greater than 4",
|
||||||
|
ceppp->file->filename, ceppp->line_number);
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (!strcmp(ceppp->name, "join-flood"))
|
else if (!strcmp(ceppp->name, "join-flood"))
|
||||||
{
|
{
|
||||||
int cnt, period;
|
int cnt, period;
|
||||||
|
@ -9191,14 +9321,22 @@ void start_listeners(void)
|
||||||
log_data_string("listen_ip", listener->ip),
|
log_data_string("listen_ip", listener->ip),
|
||||||
log_data_integer("listen_port", listener->port));
|
log_data_integer("listen_port", listener->port));
|
||||||
} else {
|
} else {
|
||||||
if (listener->ipv6)
|
switch (listener->socket_type)
|
||||||
snprintf(boundmsg_ipv6+strlen(boundmsg_ipv6), sizeof(boundmsg_ipv6)-strlen(boundmsg_ipv6),
|
{
|
||||||
"%s:%d%s, ", listener->ip, listener->port,
|
case SOCKET_TYPE_IPV4:
|
||||||
listener->options & LISTENER_TLS ? "(TLS)" : "");
|
snprintf(boundmsg_ipv4+strlen(boundmsg_ipv4), sizeof(boundmsg_ipv4)-strlen(boundmsg_ipv4),
|
||||||
else
|
"%s:%d%s, ", listener->ip, listener->port,
|
||||||
snprintf(boundmsg_ipv4+strlen(boundmsg_ipv4), sizeof(boundmsg_ipv4)-strlen(boundmsg_ipv4),
|
listener->options & LISTENER_TLS ? "(TLS)" : "");
|
||||||
"%s:%d%s, ", listener->ip, listener->port,
|
break;
|
||||||
listener->options & LISTENER_TLS ? "(TLS)" : "");
|
case SOCKET_TYPE_IPV6:
|
||||||
|
snprintf(boundmsg_ipv6+strlen(boundmsg_ipv6), sizeof(boundmsg_ipv6)-strlen(boundmsg_ipv6),
|
||||||
|
"%s:%d%s, ", listener->ip, listener->port,
|
||||||
|
listener->options & LISTENER_TLS ? "(TLS)" : "");
|
||||||
|
break;
|
||||||
|
// TODO: show unix domain sockets ;)
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9268,6 +9406,7 @@ void config_run(void)
|
||||||
{
|
{
|
||||||
extcmodes_check_for_changes();
|
extcmodes_check_for_changes();
|
||||||
start_listeners();
|
start_listeners();
|
||||||
|
add_proc_io_server();
|
||||||
free_all_config_resources();
|
free_all_config_resources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10499,13 +10638,6 @@ void resource_download_complete(const char *url, const char *file, const char *e
|
||||||
safe_strdup(wce->ce->value, rs->file); // now information of url is lost, hm!!
|
safe_strdup(wce->ce->value, rs->file); // now information of url is lost, hm!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If rehashing, check if we are done.
|
|
||||||
* If booting (not rehashing), this is done from the
|
|
||||||
* startup loop where it also checks is_config_read_finished().
|
|
||||||
*/
|
|
||||||
if (loop.rehashing && is_config_read_finished())
|
|
||||||
rehash_internal(loop.rehash_save_client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Request to REHASH the configuration file.
|
/** Request to REHASH the configuration file.
|
||||||
|
@ -10540,13 +10672,16 @@ void request_rehash(Client *client)
|
||||||
|
|
||||||
int rehash_internal(Client *client)
|
int rehash_internal(Client *client)
|
||||||
{
|
{
|
||||||
|
int failure;
|
||||||
|
|
||||||
/* Log it here if it is by a signal */
|
/* Log it here if it is by a signal */
|
||||||
if (client == NULL)
|
if (client == NULL)
|
||||||
unreal_log(ULOG_INFO, "config", "CONFIG_RELOAD", client, "Rehashing server configuration file [./unrealircd rehash]");
|
unreal_log(ULOG_INFO, "config", "CONFIG_RELOAD", client, "Rehashing server configuration file [./unrealircd rehash]");
|
||||||
|
|
||||||
loop.rehashing = 1; /* double checking.. */
|
loop.rehashing = 2; /* now doing the actual rehash */
|
||||||
|
|
||||||
if (config_test() == 0)
|
failure = config_test();
|
||||||
|
if (failure == 0)
|
||||||
config_run();
|
config_run();
|
||||||
/* TODO: uh.. are we supposed to do all this for a failed rehash too? maybe some but not all? */
|
/* TODO: uh.. are we supposed to do all this for a failed rehash too? maybe some but not all? */
|
||||||
reread_motdsandrules();
|
reread_motdsandrules();
|
||||||
|
@ -10557,8 +10692,11 @@ int rehash_internal(Client *client)
|
||||||
// unload_all_unused_moddata(); -- this will crash
|
// unload_all_unused_moddata(); -- this will crash
|
||||||
umodes_check_for_changes();
|
umodes_check_for_changes();
|
||||||
charsys_check_for_changes();
|
charsys_check_for_changes();
|
||||||
|
|
||||||
|
/* Clear everything now that we are done */
|
||||||
loop.rehashing = 0;
|
loop.rehashing = 0;
|
||||||
remote_rehash_client = NULL;
|
remote_rehash_client = NULL;
|
||||||
|
procio_post_rehash(failure);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -649,6 +649,13 @@ int crashreport_send(char *fname)
|
||||||
if ((n < 0) || strncmp(buf, "HTTP/1.1 100", 12))
|
if ((n < 0) || strncmp(buf, "HTTP/1.1 100", 12))
|
||||||
{
|
{
|
||||||
printf("Error transmitting bug report (stage II, n=%d)\n", n);
|
printf("Error transmitting bug report (stage II, n=%d)\n", n);
|
||||||
|
if (!strncmp(buf, "HTTP/1.1 403", 12))
|
||||||
|
{
|
||||||
|
printf("Your crash report was rejected automatically.\n"
|
||||||
|
"This normally means your UnrealIRCd version is too old and unsupported.\n"
|
||||||
|
"Chances are that your crash issue is already fixed in a later release.\n"
|
||||||
|
"Check https://www.unrealircd.org/ for latest releases!\n");
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ static void dbuf_free(dbufbuf *ptr)
|
||||||
|
|
||||||
void dbuf_queue_init(dbuf *dyn)
|
void dbuf_queue_init(dbuf *dyn)
|
||||||
{
|
{
|
||||||
|
memset(dyn, 0, sizeof(dbuf));
|
||||||
INIT_LIST_HEAD(&dyn->dbuf_list);
|
INIT_LIST_HEAD(&dyn->dbuf_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ static int unrealdns_sock_create_cb(ares_socket_t fd, int type, void *data)
|
||||||
return ARES_SUCCESS;
|
return ARES_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EVENT(unrealdns_timeout)
|
EVENT(unrealdns_timeout)
|
||||||
{
|
{
|
||||||
ares_process_fd(resolver_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
|
ares_process_fd(resolver_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
|
||||||
}
|
}
|
||||||
|
|
344
src/ircd.c
344
src/ircd.c
|
@ -25,209 +25,10 @@
|
||||||
char *malloc_options = "h" MALLOC_FLAGS_EXTRA;
|
char *malloc_options = "h" MALLOC_FLAGS_EXTRA;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
/* Forward declarations */
|
||||||
extern char unreallogo[];
|
|
||||||
#endif
|
|
||||||
int SVSNOOP = 0;
|
|
||||||
extern MODVAR char *buildid;
|
|
||||||
time_t timeofday = 0;
|
|
||||||
struct timeval timeofday_tv;
|
|
||||||
int tainted = 0;
|
|
||||||
LoopStruct loop;
|
|
||||||
#ifndef _WIN32
|
|
||||||
uid_t irc_uid = 0;
|
|
||||||
gid_t irc_gid = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MODVAR IRCCounts irccounts;
|
|
||||||
MODVAR Client me; /* That's me */
|
|
||||||
MODVAR char *me_hash;
|
|
||||||
extern char backupbuf[8192];
|
|
||||||
#ifdef _WIN32
|
|
||||||
extern SERVICE_STATUS_HANDLE IRCDStatusHandle;
|
|
||||||
extern SERVICE_STATUS IRCDStatus;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MODVAR unsigned char conf_debuglevel = 0;
|
|
||||||
|
|
||||||
void server_reboot(const char *);
|
void server_reboot(const char *);
|
||||||
void restart(const char *);
|
void restart(const char *);
|
||||||
static void open_debugfile(), setup_signals();
|
static void open_debugfile(), setup_signals();
|
||||||
extern void init_glines(void);
|
|
||||||
extern void tkl_init(void);
|
|
||||||
extern void process_clients(void);
|
|
||||||
extern void unrealdb_test(void);
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
MODVAR char **myargv;
|
|
||||||
#else
|
|
||||||
LPCSTR cmdLine;
|
|
||||||
#endif
|
|
||||||
char *configfile = NULL; /* Server configuration file */
|
|
||||||
int debuglevel = 0; /* Server debug level */
|
|
||||||
int bootopt = 0; /* Server boot option flags */
|
|
||||||
char *debugmode = ""; /* -"- -"- -"- */
|
|
||||||
char *sbrk0; /* initial sbrk(0) */
|
|
||||||
static int dorehash = 0, dorestart = 0, doreloadcert = 0;
|
|
||||||
MODVAR int booted = FALSE;
|
|
||||||
|
|
||||||
void s_die()
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
Client *client;
|
|
||||||
if (!IsService)
|
|
||||||
{
|
|
||||||
loop.terminating = 1;
|
|
||||||
unload_all_modules();
|
|
||||||
|
|
||||||
list_for_each_entry(client, &lclient_list, lclient_node)
|
|
||||||
(void) send_queued(client);
|
|
||||||
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SERVICE_STATUS status;
|
|
||||||
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
|
||||||
SC_HANDLE hService = OpenService(hSCManager, "UnrealIRCd", SERVICE_STOP);
|
|
||||||
ControlService(hService, SERVICE_CONTROL_STOP, &status);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
loop.terminating = 1;
|
|
||||||
unload_all_modules();
|
|
||||||
unlink(conf_files ? conf_files->pid_file : IRCD_PIDFILE);
|
|
||||||
exit(0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
static void s_rehash()
|
|
||||||
{
|
|
||||||
struct sigaction act;
|
|
||||||
dorehash = 1;
|
|
||||||
act.sa_handler = s_rehash;
|
|
||||||
act.sa_flags = 0;
|
|
||||||
(void)sigemptyset(&act.sa_mask);
|
|
||||||
(void)sigaddset(&act.sa_mask, SIGHUP);
|
|
||||||
(void)sigaction(SIGHUP, &act, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void s_reloadcert()
|
|
||||||
{
|
|
||||||
struct sigaction act;
|
|
||||||
doreloadcert = 1;
|
|
||||||
act.sa_handler = s_reloadcert;
|
|
||||||
act.sa_flags = 0;
|
|
||||||
(void)sigemptyset(&act.sa_mask);
|
|
||||||
(void)sigaddset(&act.sa_mask, SIGUSR1);
|
|
||||||
(void)sigaction(SIGUSR1, &act, NULL);
|
|
||||||
}
|
|
||||||
#endif // #ifndef _WIN32
|
|
||||||
|
|
||||||
void restart(const char *mesg)
|
|
||||||
{
|
|
||||||
server_reboot(mesg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void s_restart()
|
|
||||||
{
|
|
||||||
dorestart = 1;
|
|
||||||
#if 0
|
|
||||||
static int restarting = 0;
|
|
||||||
|
|
||||||
if (restarting == 0) {
|
|
||||||
/*
|
|
||||||
* Send (or attempt to) a dying scream to oper if present
|
|
||||||
*/
|
|
||||||
|
|
||||||
restarting = 1;
|
|
||||||
server_reboot("SIGINT");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
/** Signal handler for signals which we ignore,
|
|
||||||
* like SIGPIPE ("Broken pipe") and SIGWINCH (terminal window changed) etc.
|
|
||||||
*/
|
|
||||||
void ignore_this_signal()
|
|
||||||
{
|
|
||||||
struct sigaction act;
|
|
||||||
|
|
||||||
act.sa_handler = ignore_this_signal;
|
|
||||||
act.sa_flags = 0;
|
|
||||||
(void)sigemptyset(&act.sa_mask);
|
|
||||||
(void)sigaddset(&act.sa_mask, SIGALRM);
|
|
||||||
(void)sigaddset(&act.sa_mask, SIGPIPE);
|
|
||||||
(void)sigaction(SIGALRM, &act, (struct sigaction *)NULL);
|
|
||||||
(void)sigaction(SIGPIPE, &act, (struct sigaction *)NULL);
|
|
||||||
#ifdef SIGWINCH
|
|
||||||
(void)sigaddset(&act.sa_mask, SIGWINCH);
|
|
||||||
(void)sigaction(SIGWINCH, &act, (struct sigaction *)NULL);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif /* #ifndef _WIN32 */
|
|
||||||
|
|
||||||
|
|
||||||
void server_reboot(const char *mesg)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
Client *client;
|
|
||||||
unreal_log(ULOG_INFO, "main", "UNREALIRCD_RESTARTING", NULL,
|
|
||||||
"Restarting server: $reason",
|
|
||||||
log_data_string("reason", mesg));
|
|
||||||
|
|
||||||
list_for_each_entry(client, &lclient_list, lclient_node)
|
|
||||||
(void) send_queued(client);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ** fd 0 must be 'preserved' if either the -d or -i options have
|
|
||||||
* ** been passed to us before restarting.
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_SYSLOG
|
|
||||||
(void)closelog();
|
|
||||||
#endif
|
|
||||||
#ifndef _WIN32
|
|
||||||
for (i = 3; i < MAXCONNECTIONS; i++)
|
|
||||||
(void)close(i);
|
|
||||||
if (!(bootopt & (BOOT_TTY | BOOT_DEBUG)))
|
|
||||||
(void)close(2);
|
|
||||||
(void)close(1);
|
|
||||||
(void)close(0);
|
|
||||||
(void)execv(MYNAME, myargv);
|
|
||||||
#else
|
|
||||||
close_connections();
|
|
||||||
if (!IsService)
|
|
||||||
{
|
|
||||||
CleanUp();
|
|
||||||
WinExec(cmdLine, SW_SHOWDEFAULT);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
unload_all_modules();
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (IsService)
|
|
||||||
{
|
|
||||||
SERVICE_STATUS status;
|
|
||||||
PROCESS_INFORMATION pi;
|
|
||||||
STARTUPINFO si;
|
|
||||||
char fname[MAX_PATH];
|
|
||||||
memset(&status, 0, sizeof(status));
|
|
||||||
memset(&si, 0, sizeof(si));
|
|
||||||
IRCDStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
|
||||||
SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
|
|
||||||
GetModuleFileName(GetModuleHandle(NULL), fname, MAX_PATH);
|
|
||||||
CreateProcess(fname, "restartsvc", NULL, NULL, FALSE,
|
|
||||||
0, NULL, NULL, &si, &pi);
|
|
||||||
IRCDStatus.dwCurrentState = SERVICE_STOPPED;
|
|
||||||
SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
|
|
||||||
ExitProcess(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODVAR char *areason;
|
|
||||||
|
|
||||||
EVENT(loop_event)
|
EVENT(loop_event)
|
||||||
{
|
{
|
||||||
|
@ -557,58 +358,6 @@ void fix_timers(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
/* Generate 3 cloak keys and print to console */
|
|
||||||
static void generate_cloakkeys()
|
|
||||||
{
|
|
||||||
#define GENERATE_CLOAKKEY_LEN 80 /* Length of cloak keys to generate. */
|
|
||||||
char keyBuf[GENERATE_CLOAKKEY_LEN + 1];
|
|
||||||
int keyNum;
|
|
||||||
int charIndex;
|
|
||||||
|
|
||||||
short has_upper;
|
|
||||||
short has_lower;
|
|
||||||
short has_num;
|
|
||||||
|
|
||||||
fprintf(stderr, "Here are 3 random cloak keys that you can copy-paste to your configuration file:\n\n");
|
|
||||||
|
|
||||||
fprintf(stderr, "set {\n\tcloak-keys {\n");
|
|
||||||
for (keyNum = 0; keyNum < 3; ++keyNum)
|
|
||||||
{
|
|
||||||
has_upper = 0;
|
|
||||||
has_lower = 0;
|
|
||||||
has_num = 0;
|
|
||||||
|
|
||||||
for (charIndex = 0; charIndex < sizeof(keyBuf)-1; ++charIndex)
|
|
||||||
{
|
|
||||||
switch (getrandom8() % 3)
|
|
||||||
{
|
|
||||||
case 0: /* Uppercase. */
|
|
||||||
keyBuf[charIndex] = (char)('A' + (getrandom8() % ('Z' - 'A')));
|
|
||||||
has_upper = 1;
|
|
||||||
break;
|
|
||||||
case 1: /* Lowercase. */
|
|
||||||
keyBuf[charIndex] = (char)('a' + (getrandom8() % ('z' - 'a')));
|
|
||||||
has_lower = 1;
|
|
||||||
break;
|
|
||||||
case 2: /* Digit. */
|
|
||||||
keyBuf[charIndex] = (char)('0' + (getrandom8() % ('9' - '0')));
|
|
||||||
has_num = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keyBuf[sizeof(keyBuf)-1] = '\0';
|
|
||||||
|
|
||||||
if (has_upper && has_lower && has_num)
|
|
||||||
fprintf(stderr, "\t\t\"%s\";\n", keyBuf);
|
|
||||||
else
|
|
||||||
/* Try again. For this reason, keyNum must be signed. */
|
|
||||||
keyNum--;
|
|
||||||
}
|
|
||||||
fprintf(stderr, "\t}\n}\n\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* MY tdiff... because 'double' sucks.
|
/* MY tdiff... because 'double' sucks.
|
||||||
* This should work until 2038, and very likely after that as well
|
* This should work until 2038, and very likely after that as well
|
||||||
* because 'long' should be 64 bit on all systems by then... -- Syzop
|
* because 'long' should be 64 bit on all systems by then... -- Syzop
|
||||||
|
@ -677,30 +426,19 @@ void detect_timeshift_and_warn(void)
|
||||||
oldtimeofday = timeofday;
|
oldtimeofday = timeofday;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check if at least 'minimum' seconds passed by since last run.
|
void SetupEvents(void)
|
||||||
* @param tv_old Pointer to a timeval struct to keep track of things.
|
|
||||||
* @param minimum The time specified in milliseconds (eg: 1000 for 1 second)
|
|
||||||
* @returns When 'minimum' msec passed 1 is returned and the time is reset, otherwise 0 is returned.
|
|
||||||
*/
|
|
||||||
int minimum_msec_since_last_run(struct timeval *tv_old, long minimum)
|
|
||||||
{
|
{
|
||||||
long v;
|
/* Start events */
|
||||||
|
EventAdd(NULL, "tunefile", save_tunefile, NULL, 300*1000, 0);
|
||||||
if (tv_old->tv_sec == 0)
|
EventAdd(NULL, "garbage", garbage_collect, NULL, GARBAGE_COLLECT_EVERY*1000, 0);
|
||||||
{
|
EventAdd(NULL, "loop", loop_event, NULL, 1000, 0);
|
||||||
/* First call ever */
|
EventAdd(NULL, "unrealdns_removeoldrecords", unrealdns_removeoldrecords, NULL, 15000, 0);
|
||||||
tv_old->tv_sec = timeofday_tv.tv_sec;
|
EventAdd(NULL, "check_pings", check_pings, NULL, 1000, 0);
|
||||||
tv_old->tv_usec = timeofday_tv.tv_usec;
|
EventAdd(NULL, "check_deadsockets", check_deadsockets, NULL, 1000, 0);
|
||||||
return 0;
|
EventAdd(NULL, "handshake_timeout", handshake_timeout, NULL, 1000, 0);
|
||||||
}
|
EventAdd(NULL, "tls_check_expiry", tls_check_expiry, NULL, (86400/2)*1000, 0);
|
||||||
v = ((timeofday_tv.tv_sec - tv_old->tv_sec) * 1000) + ((timeofday_tv.tv_usec - tv_old->tv_usec)/1000);
|
EventAdd(NULL, "unrealdb_expire_secret_cache", unrealdb_expire_secret_cache, NULL, 61000, 0);
|
||||||
if (v >= minimum)
|
EventAdd(NULL, "throttling_check_expire", throttling_check_expire, NULL, 1000, 0);
|
||||||
{
|
|
||||||
tv_old->tv_sec = timeofday_tv.tv_sec;
|
|
||||||
tv_old->tv_usec = timeofday_tv.tv_usec;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The main function. This will call SocketLoop() once the server is ready. */
|
/** The main function. This will call SocketLoop() once the server is ready. */
|
||||||
|
@ -710,10 +448,7 @@ int main(int argc, char *argv[])
|
||||||
int InitUnrealIRCd(int argc, char *argv[])
|
int InitUnrealIRCd(int argc, char *argv[])
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifndef _WIN32
|
||||||
WORD wVersionRequested = MAKEWORD(1, 1);
|
|
||||||
WSADATA wsaData;
|
|
||||||
#else
|
|
||||||
uid_t uid, euid;
|
uid_t uid, euid;
|
||||||
gid_t gid, egid;
|
gid_t gid, egid;
|
||||||
#endif
|
#endif
|
||||||
|
@ -755,7 +490,6 @@ int InitUnrealIRCd(int argc, char *argv[])
|
||||||
SetErrorMode(SEM_FAILCRITICALERRORS);
|
SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||||
#endif
|
#endif
|
||||||
#if !defined(_WIN32) && !defined(_AMIGA)
|
#if !defined(_WIN32) && !defined(_AMIGA)
|
||||||
sbrk0 = (char *)sbrk((size_t)0);
|
|
||||||
uid = getuid();
|
uid = getuid();
|
||||||
euid = geteuid();
|
euid = geteuid();
|
||||||
gid = getgid();
|
gid = getgid();
|
||||||
|
@ -784,7 +518,7 @@ int InitUnrealIRCd(int argc, char *argv[])
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
(void)umask(077); /* better safe than sorry --SRB */
|
(void)umask(077); /* better safe than sorry --SRB */
|
||||||
#else
|
#else
|
||||||
WSAStartup(wVersionRequested, &wsaData);
|
init_winsock();
|
||||||
#endif
|
#endif
|
||||||
setup_signals();
|
setup_signals();
|
||||||
|
|
||||||
|
@ -840,43 +574,6 @@ int InitUnrealIRCd(int argc, char *argv[])
|
||||||
safe_strdup(configfile, p);
|
safe_strdup(configfile, p);
|
||||||
convert_to_absolute_path(&configfile, CONFDIR);
|
convert_to_absolute_path(&configfile, CONFDIR);
|
||||||
break;
|
break;
|
||||||
#ifndef _WIN32
|
|
||||||
case 'P':{
|
|
||||||
short type;
|
|
||||||
const char *result;
|
|
||||||
srandom(TStime());
|
|
||||||
type = Auth_FindType(NULL, p);
|
|
||||||
if (type == -1)
|
|
||||||
{
|
|
||||||
type = AUTHTYPE_ARGON2;
|
|
||||||
} else {
|
|
||||||
p = *++argv;
|
|
||||||
argc--;
|
|
||||||
}
|
|
||||||
if (BadPtr(p))
|
|
||||||
{
|
|
||||||
#ifndef _WIN32
|
|
||||||
p = getpass("Enter password to hash: ");
|
|
||||||
#else
|
|
||||||
printf("ERROR: You should specify a password to hash");
|
|
||||||
exit(1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if ((type == AUTHTYPE_UNIXCRYPT) && (strlen(p) > 8))
|
|
||||||
{
|
|
||||||
/* Hmmm.. is this warning really still true (and always) ?? */
|
|
||||||
printf("WARNING: Password truncated to 8 characters due to 'crypt' algorithm. "
|
|
||||||
"You are suggested to use the 'argon2' algorithm instead.");
|
|
||||||
p[8] = '\0';
|
|
||||||
}
|
|
||||||
if (!(result = Auth_Hash(type, p))) {
|
|
||||||
printf("Failed to generate password. Deprecated method? Try 'argon2' instead.\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
printf("Encrypted password is: %s\n", result);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if 0
|
#if 0
|
||||||
case 'S':
|
case 'S':
|
||||||
charsys_dump_table(p ? p : "*");
|
charsys_dump_table(p ? p : "*");
|
||||||
|
@ -921,11 +618,6 @@ int InitUnrealIRCd(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
exit(0);
|
exit(0);
|
||||||
#endif
|
|
||||||
#ifndef _WIN32
|
|
||||||
case 'k':
|
|
||||||
generate_cloakkeys();
|
|
||||||
exit(0);
|
|
||||||
#endif
|
#endif
|
||||||
case 'K':
|
case 'K':
|
||||||
{
|
{
|
||||||
|
@ -1032,7 +724,6 @@ int InitUnrealIRCd(int argc, char *argv[])
|
||||||
initstats();
|
initstats();
|
||||||
if (!loop.config_test)
|
if (!loop.config_test)
|
||||||
DeleteTempModules();
|
DeleteTempModules();
|
||||||
booted = FALSE;
|
|
||||||
#if !defined(_WIN32) && !defined(_AMIGA) && !defined(OSXTIGER) && DEFAULT_PERMISSIONS != 0
|
#if !defined(_WIN32) && !defined(_AMIGA) && !defined(OSXTIGER) && DEFAULT_PERMISSIONS != 0
|
||||||
/* Hack to stop people from being able to read the config file */
|
/* Hack to stop people from being able to read the config file */
|
||||||
(void)chmod(CPATH, DEFAULT_PERMISSIONS);
|
(void)chmod(CPATH, DEFAULT_PERMISSIONS);
|
||||||
|
@ -1056,11 +747,11 @@ int InitUnrealIRCd(int argc, char *argv[])
|
||||||
gettimeofday(&timeofday_tv, NULL);
|
gettimeofday(&timeofday_tv, NULL);
|
||||||
timeofday = timeofday_tv.tv_sec;
|
timeofday = timeofday_tv.tv_sec;
|
||||||
url_socket_timeout(NULL);
|
url_socket_timeout(NULL);
|
||||||
|
unrealdns_timeout(NULL);
|
||||||
fd_select(500);
|
fd_select(500);
|
||||||
}
|
}
|
||||||
if (config_test() < 0)
|
if (config_test() < 0)
|
||||||
exit(-1);
|
exit(-1);
|
||||||
booted = TRUE;
|
|
||||||
load_tunefile();
|
load_tunefile();
|
||||||
make_umodestr();
|
make_umodestr();
|
||||||
SetListening(&me);
|
SetListening(&me);
|
||||||
|
@ -1223,6 +914,9 @@ void SocketLoop(void *dummy)
|
||||||
reinit_tls();
|
reinit_tls();
|
||||||
doreloadcert = 0;
|
doreloadcert = 0;
|
||||||
}
|
}
|
||||||
|
/* If rehashing, check if we are done. */
|
||||||
|
if (loop.rehashing && is_config_read_finished())
|
||||||
|
rehash_internal(loop.rehash_save_client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/************************************************************************
|
||||||
|
* UnrealIRCd - Unreal Internet Relay Chat Daemon - src/ircd_vars.c
|
||||||
|
* (c) 2021- Bram Matthys and The UnrealIRCd team
|
||||||
|
* License: GPLv2
|
||||||
|
*/
|
||||||
|
#include "unrealircd.h"
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief UnrealIRCd global variables of the IRCd
|
||||||
|
*/
|
||||||
|
|
||||||
|
int SVSNOOP = 0;
|
||||||
|
time_t timeofday = 0;
|
||||||
|
struct timeval timeofday_tv;
|
||||||
|
int tainted = 0;
|
||||||
|
LoopStruct loop;
|
||||||
|
MODVAR IRCCounts irccounts;
|
||||||
|
MODVAR Client me; /* That's me */
|
||||||
|
MODVAR char *me_hash;
|
||||||
|
char *configfile = NULL; /* Server configuration file */
|
||||||
|
int debuglevel = 0; /* Server debug level */
|
||||||
|
int bootopt = 0; /* Server boot option flags */
|
||||||
|
char *debugmode = ""; /* -"- -"- -"- */
|
||||||
|
int dorehash = 0; /**< Rehash server on next socket loop */
|
||||||
|
int dorestart = 0; /**< Restart server on next socket loop */
|
||||||
|
int doreloadcert = 0; /**< Reload TLS certificate on next socket loop */
|
||||||
|
#ifndef _WIN32
|
||||||
|
char **myargv;
|
||||||
|
#else
|
||||||
|
LPCSTR cmdLine;
|
||||||
|
#endif
|
|
@ -44,6 +44,7 @@ MODVAR int numclients = 0;
|
||||||
// TODO: Document whether servers are included or excluded in these lists...
|
// TODO: Document whether servers are included or excluded in these lists...
|
||||||
|
|
||||||
MODVAR struct list_head unknown_list; /**< Local clients in handshake (may become a user or server later) */
|
MODVAR struct list_head unknown_list; /**< Local clients in handshake (may become a user or server later) */
|
||||||
|
MODVAR struct list_head control_list; /**< Local "control channel" clients */
|
||||||
MODVAR struct list_head lclient_list; /**< Local clients (users only, right?) */
|
MODVAR struct list_head lclient_list; /**< Local clients (users only, right?) */
|
||||||
MODVAR struct list_head client_list; /**< All clients - local and remote (not in handshake) */
|
MODVAR struct list_head client_list; /**< All clients - local and remote (not in handshake) */
|
||||||
MODVAR struct list_head server_list; /**< Locally connected servers */
|
MODVAR struct list_head server_list; /**< Locally connected servers */
|
||||||
|
@ -71,6 +72,7 @@ void initlists(void)
|
||||||
INIT_LIST_HEAD(&server_list);
|
INIT_LIST_HEAD(&server_list);
|
||||||
INIT_LIST_HEAD(&oper_list);
|
INIT_LIST_HEAD(&oper_list);
|
||||||
INIT_LIST_HEAD(&unknown_list);
|
INIT_LIST_HEAD(&unknown_list);
|
||||||
|
INIT_LIST_HEAD(&control_list);
|
||||||
INIT_LIST_HEAD(&global_server_list);
|
INIT_LIST_HEAD(&global_server_list);
|
||||||
INIT_LIST_HEAD(&dead_list);
|
INIT_LIST_HEAD(&dead_list);
|
||||||
|
|
||||||
|
|
241
src/log.c
241
src/log.c
|
@ -28,7 +28,7 @@
|
||||||
#include "unrealircd.h"
|
#include "unrealircd.h"
|
||||||
|
|
||||||
// TODO: Make configurable at compile time (runtime won't do, as we haven't read the config file)
|
// TODO: Make configurable at compile time (runtime won't do, as we haven't read the config file)
|
||||||
#define show_event_id_console 0
|
#define show_event_console 0
|
||||||
|
|
||||||
/* Variables */
|
/* Variables */
|
||||||
Log *logs[NUM_LOG_DESTINATIONS] = { NULL, NULL, NULL, NULL, NULL };
|
Log *logs[NUM_LOG_DESTINATIONS] = { NULL, NULL, NULL, NULL, NULL };
|
||||||
|
@ -186,7 +186,7 @@ int config_test_log(ConfigFile *conf, ConfigEntry *block)
|
||||||
/* TODO: Validate the sources lightly for formatting issues */
|
/* TODO: Validate the sources lightly for formatting issues */
|
||||||
any_sources = 1;
|
any_sources = 1;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
if (!strcmp(ce->name, "destination"))
|
if (!strcmp(ce->name, "destination"))
|
||||||
{
|
{
|
||||||
for (cep = ce->items; cep; cep = cep->next)
|
for (cep = ce->items; cep; cep = cep->next)
|
||||||
|
@ -225,6 +225,22 @@ int config_test_log(ConfigFile *conf, ConfigEntry *block)
|
||||||
cep->file->filename, cep->line_number, cep->value);
|
cep->file->filename, cep->line_number, cep->value);
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
|
for (cepp = cep->items; cepp; cepp = cepp->next)
|
||||||
|
{
|
||||||
|
if (!strcmp(cepp->name, "color"))
|
||||||
|
;
|
||||||
|
else if (!strcmp(cepp->name, "show-event"))
|
||||||
|
;
|
||||||
|
else if (!strcmp(cepp->name, "json-message-tag"))
|
||||||
|
;
|
||||||
|
else if (!strcmp(cepp->name, "oper-only"))
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config_error_unknown(cepp->file->filename, cepp->line_number, "log::destination::channel", cepp->name);
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
if (!strcmp(cep->name, "file"))
|
if (!strcmp(cep->name, "file"))
|
||||||
{
|
{
|
||||||
|
@ -308,6 +324,10 @@ int config_test_log(ConfigFile *conf, ConfigEntry *block)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
config_error_unknown(ce->file->filename, ce->line_number, "log", ce->name);
|
||||||
|
errors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,6 +413,23 @@ int config_run_log(ConfigFile *conf, ConfigEntry *block)
|
||||||
strlcpy(log->destination, cep->value, sizeof(log->destination)); /* destination is the channel */
|
strlcpy(log->destination, cep->value, sizeof(log->destination)); /* destination is the channel */
|
||||||
log->sources = sources;
|
log->sources = sources;
|
||||||
AddListItem(log, temp_logs[LOG_DEST_CHANNEL]);
|
AddListItem(log, temp_logs[LOG_DEST_CHANNEL]);
|
||||||
|
/* set defaults */
|
||||||
|
log->color = tempiConf.server_notice_colors;
|
||||||
|
log->show_event = tempiConf.server_notice_show_event;
|
||||||
|
log->json_message_tag = 1;
|
||||||
|
log->oper_only = 1;
|
||||||
|
/* now parse options (if any) */
|
||||||
|
for (cepp = cep->items; cepp; cepp = cepp->next)
|
||||||
|
{
|
||||||
|
if (!strcmp(cepp->name, "color"))
|
||||||
|
log->color = config_checkval(cepp->value, CFG_YESNO);
|
||||||
|
else if (!strcmp(cepp->name, "show-event"))
|
||||||
|
log->show_event = config_checkval(cepp->value, CFG_YESNO);
|
||||||
|
else if (!strcmp(cepp->name, "json-message-tag"))
|
||||||
|
log->json_message_tag = config_checkval(cepp->value, CFG_YESNO);
|
||||||
|
else if (!strcmp(cepp->name, "oper-only"))
|
||||||
|
log->oper_only = config_checkval(cepp->value, CFG_YESNO);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
if (!strcmp(cep->name, "remote"))
|
if (!strcmp(cep->name, "remote"))
|
||||||
{
|
{
|
||||||
|
@ -499,6 +536,10 @@ void json_expand_client(json_t *j, const char *key, Client *client, int detail)
|
||||||
|
|
||||||
/* same for ip, is there for all (well, some services pseudo-users may not have one) */
|
/* same for ip, is there for all (well, some services pseudo-users may not have one) */
|
||||||
json_object_set_new(child, "ip", json_string_unreal(client->ip));
|
json_object_set_new(child, "ip", json_string_unreal(client->ip));
|
||||||
|
if (client->local && client->local->listener)
|
||||||
|
json_object_set_new(child, "server_port", json_integer(client->local->listener->port));
|
||||||
|
if (client->local && client->local->port)
|
||||||
|
json_object_set_new(child, "client_port", json_integer(client->local->port));
|
||||||
|
|
||||||
/* client.details is always available: it is nick!user@host, nick@host, server@host
|
/* client.details is always available: it is nick!user@host, nick@host, server@host
|
||||||
* server@ip, or just server.
|
* server@ip, or just server.
|
||||||
|
@ -963,7 +1004,6 @@ static NameValue log_colors_terminal[] = {
|
||||||
{ ULOG_ERROR, "\033[91m" },
|
{ ULOG_ERROR, "\033[91m" },
|
||||||
{ ULOG_FATAL, "\033[95m" },
|
{ ULOG_FATAL, "\033[95m" },
|
||||||
};
|
};
|
||||||
#define TERMINAL_COLOR_RESET "\033[0m"
|
|
||||||
|
|
||||||
const char *log_level_irc_color(LogLevel loglevel)
|
const char *log_level_irc_color(LogLevel loglevel)
|
||||||
{
|
{
|
||||||
|
@ -1151,7 +1191,7 @@ literal:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Do the actual writing to log files */
|
/** Do the actual writing to log files */
|
||||||
void do_unreal_log_disk(LogLevel loglevel, const char *subsystem, const char *event_id, MultiLine *msg, const char *json_serialized)
|
void do_unreal_log_disk(LogLevel loglevel, const char *subsystem, const char *event_id, MultiLine *msg, const char *json_serialized, Client *from_server)
|
||||||
{
|
{
|
||||||
static int last_log_file_warning = 0;
|
static int last_log_file_warning = 0;
|
||||||
Log *l;
|
Log *l;
|
||||||
|
@ -1171,14 +1211,14 @@ void do_unreal_log_disk(LogLevel loglevel, const char *subsystem, const char *ev
|
||||||
for (m = msg; m; m = m->next)
|
for (m = msg; m; m = m->next)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (show_event_id_console)
|
if (show_event_console)
|
||||||
win_log("* %s.%s%s [%s] %s\n", subsystem, event_id, m->next?"+":"", log_level_valtostring(loglevel), m->line);
|
win_log("* %s.%s%s [%s] %s\n", subsystem, event_id, m->next?"+":"", log_level_valtostring(loglevel), m->line);
|
||||||
else
|
else
|
||||||
win_log("* [%s] %s\n", log_level_valtostring(loglevel), m->line);
|
win_log("* [%s] %s\n", log_level_valtostring(loglevel), m->line);
|
||||||
#else
|
#else
|
||||||
if (terminal_supports_color())
|
if (terminal_supports_color())
|
||||||
{
|
{
|
||||||
if (show_event_id_console)
|
if (show_event_console)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s%s.%s%s %s[%s]%s %s\n",
|
fprintf(stderr, "%s%s.%s%s %s[%s]%s %s\n",
|
||||||
log_level_terminal_color(ULOG_INVALID), subsystem, event_id, TERMINAL_COLOR_RESET,
|
log_level_terminal_color(ULOG_INVALID), subsystem, event_id, TERMINAL_COLOR_RESET,
|
||||||
|
@ -1190,7 +1230,7 @@ void do_unreal_log_disk(LogLevel loglevel, const char *subsystem, const char *ev
|
||||||
m->line);
|
m->line);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (show_event_id_console)
|
if (show_event_console)
|
||||||
fprintf(stderr, "%s.%s%s [%s] %s\n", subsystem, event_id, m->next?"+":"", log_level_valtostring(loglevel), m->line);
|
fprintf(stderr, "%s.%s%s [%s] %s\n", subsystem, event_id, m->next?"+":"", log_level_valtostring(loglevel), m->line);
|
||||||
else
|
else
|
||||||
fprintf(stderr, "[%s] %s\n", log_level_valtostring(loglevel), m->line);
|
fprintf(stderr, "[%s] %s\n", log_level_valtostring(loglevel), m->line);
|
||||||
|
@ -1303,13 +1343,9 @@ void do_unreal_log_disk(LogLevel loglevel, const char *subsystem, const char *ev
|
||||||
for (m = msg; m; m = m->next)
|
for (m = msg; m; m = m->next)
|
||||||
{
|
{
|
||||||
char text_buf[8192];
|
char text_buf[8192];
|
||||||
snprintf(text_buf, sizeof(text_buf), "%s.%s%s %s: %s\n", subsystem, event_id, m->next?"+":"", log_level_valtostring(loglevel), m->line);
|
snprintf(text_buf, sizeof(text_buf), "%s%s %s.%s%s %s: %s\n",
|
||||||
// FIXME: don't write in 2 stages, waste of slow system calls
|
timebuf, from_server->name,
|
||||||
if (write(l->logfd, timebuf, strlen(timebuf)) < 0)
|
subsystem, event_id, m->next?"+":"", log_level_valtostring(loglevel), m->line);
|
||||||
{
|
|
||||||
/* Let's ignore any write errors for this one. Next write() will catch it... */
|
|
||||||
;
|
|
||||||
}
|
|
||||||
n = write(l->logfd, text_buf, strlen(text_buf));
|
n = write(l->logfd, text_buf, strlen(text_buf));
|
||||||
if (n < strlen(text_buf))
|
if (n < strlen(text_buf))
|
||||||
{
|
{
|
||||||
|
@ -1423,13 +1459,66 @@ const char *log_to_snomask(LogLevel loglevel, const char *subsystem, const char
|
||||||
|
|
||||||
#define COLOR_NONE "\xf"
|
#define COLOR_NONE "\xf"
|
||||||
#define COLOR_DARKGREY "\00314"
|
#define COLOR_DARKGREY "\00314"
|
||||||
/** Do the actual writing to log files */
|
|
||||||
|
/** Generic sendto function for logging to IRC. Used for notices to IRCOps and also for sending to individual users on channels */
|
||||||
|
void sendto_log(Client *client, const char *msgtype, const char *destination, int show_colors, int show_event,
|
||||||
|
LogLevel loglevel, const char *subsystem, const char *event_id, MultiLine *msg, const char *json_serialized, Client *from_server)
|
||||||
|
{
|
||||||
|
MultiLine *m;
|
||||||
|
|
||||||
|
for (m = msg; m; m = m->next)
|
||||||
|
{
|
||||||
|
MessageTag *mtags = NULL;
|
||||||
|
new_message(from_server, NULL, &mtags);
|
||||||
|
|
||||||
|
/* Add JSON data, but only if it is the first message (m == msg) */
|
||||||
|
if (json_serialized && (m == msg))
|
||||||
|
{
|
||||||
|
MessageTag *json_mtag = safe_alloc(sizeof(MessageTag));
|
||||||
|
safe_strdup(json_mtag->name, "unrealircd.org/json-log");
|
||||||
|
safe_strdup(json_mtag->value, json_serialized);
|
||||||
|
AddListItem(json_mtag, mtags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show_colors)
|
||||||
|
{
|
||||||
|
if (show_event)
|
||||||
|
{
|
||||||
|
sendto_one(client, mtags, ":%s %s %s :%s%s.%s%s%s %s[%s]%s %s",
|
||||||
|
from_server->name, msgtype, destination,
|
||||||
|
COLOR_DARKGREY, subsystem, event_id, m->next?"+":"", COLOR_NONE,
|
||||||
|
log_level_irc_color(loglevel), log_level_valtostring(loglevel), COLOR_NONE,
|
||||||
|
m->line);
|
||||||
|
} else {
|
||||||
|
sendto_one(client, mtags, ":%s %s %s :%s[%s]%s %s",
|
||||||
|
from_server->name, msgtype, destination,
|
||||||
|
log_level_irc_color(loglevel), log_level_valtostring(loglevel), COLOR_NONE,
|
||||||
|
m->line);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (show_event)
|
||||||
|
{
|
||||||
|
sendto_one(client, mtags, ":%s %s %s :%s.%s%s [%s] %s",
|
||||||
|
from_server->name, msgtype, destination,
|
||||||
|
subsystem, event_id, m->next?"+":"",
|
||||||
|
log_level_valtostring(loglevel),
|
||||||
|
m->line);
|
||||||
|
} else {
|
||||||
|
sendto_one(client, mtags, ":%s %s %s :[%s] %s",
|
||||||
|
from_server->name, msgtype, destination,
|
||||||
|
log_level_valtostring(loglevel),
|
||||||
|
m->line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
safe_free_message_tags(mtags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send server notices to IRCOps */
|
||||||
void do_unreal_log_opers(LogLevel loglevel, const char *subsystem, const char *event_id, MultiLine *msg, const char *json_serialized, Client *from_server)
|
void do_unreal_log_opers(LogLevel loglevel, const char *subsystem, const char *event_id, MultiLine *msg, const char *json_serialized, Client *from_server)
|
||||||
{
|
{
|
||||||
Client *client;
|
Client *client;
|
||||||
const char *snomask_destinations, *p;
|
const char *snomask_destinations, *p;
|
||||||
MessageTag *mtags = NULL, *mtags_loop;
|
|
||||||
MultiLine *m;
|
|
||||||
|
|
||||||
/* If not fully booted then we don't have a logging to snomask mapping so can't do much.. */
|
/* If not fully booted then we don't have a logging to snomask mapping so can't do much.. */
|
||||||
if (!loop.booted)
|
if (!loop.booted)
|
||||||
|
@ -1443,20 +1532,13 @@ void do_unreal_log_opers(LogLevel loglevel, const char *subsystem, const char *e
|
||||||
if (!snomask_destinations)
|
if (!snomask_destinations)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Prepare message tag for those who have CAP unrealircd.org/json-log */
|
|
||||||
if (json_serialized)
|
|
||||||
{
|
|
||||||
mtags = safe_alloc(sizeof(MessageTag));
|
|
||||||
safe_strdup(mtags->name, "unrealircd.org/json-log");
|
|
||||||
safe_strdup(mtags->value, json_serialized);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* To specific snomasks... */
|
/* To specific snomasks... */
|
||||||
list_for_each_entry(client, &oper_list, special_node)
|
list_for_each_entry(client, &oper_list, special_node)
|
||||||
{
|
{
|
||||||
const char *operlogin;
|
const char *operlogin;
|
||||||
ConfigItem_oper *oper;
|
ConfigItem_oper *oper;
|
||||||
int colors = iConf.server_notice_colors;
|
int show_colors = iConf.server_notice_colors;
|
||||||
|
int show_event = iConf.server_notice_show_event;
|
||||||
|
|
||||||
if (snomask_destinations)
|
if (snomask_destinations)
|
||||||
{
|
{
|
||||||
|
@ -1477,30 +1559,56 @@ void do_unreal_log_opers(LogLevel loglevel, const char *subsystem, const char *e
|
||||||
|
|
||||||
operlogin = get_operlogin(client);
|
operlogin = get_operlogin(client);
|
||||||
if (operlogin && (oper = find_oper(operlogin)))
|
if (operlogin && (oper = find_oper(operlogin)))
|
||||||
colors = oper->server_notice_colors;
|
|
||||||
|
|
||||||
mtags_loop = mtags;
|
|
||||||
for (m = msg; m; m = m->next)
|
|
||||||
{
|
{
|
||||||
if (colors)
|
show_colors = oper->server_notice_colors;
|
||||||
{
|
show_event = oper->server_notice_show_event;
|
||||||
sendto_one(client, mtags_loop, ":%s NOTICE %s :%s%s.%s%s%s %s[%s]%s %s",
|
}
|
||||||
from_server->name, client->name,
|
|
||||||
COLOR_DARKGREY, subsystem, event_id, m->next?"+":"", COLOR_NONE,
|
sendto_log(client, "NOTICE", client->name, show_colors, show_event, loglevel, subsystem, event_id, msg, json_serialized, from_server);
|
||||||
log_level_irc_color(loglevel), log_level_valtostring(loglevel), COLOR_NONE,
|
}
|
||||||
m->line);
|
}
|
||||||
} else {
|
|
||||||
sendto_one(client, mtags_loop, ":%s NOTICE %s :%s.%s%s [%s] %s",
|
/** Send server notices to channels */
|
||||||
from_server->name, client->name,
|
void do_unreal_log_channels(LogLevel loglevel, const char *subsystem, const char *event_id, MultiLine *msg, const char *json_serialized, Client *from_server)
|
||||||
subsystem, event_id, m->next?"+":"",
|
{
|
||||||
log_level_valtostring(loglevel),
|
Log *l;
|
||||||
m->line);
|
Member *m;
|
||||||
}
|
Client *client;
|
||||||
mtags_loop = NULL; /* this way we only send the JSON in the first msg */
|
|
||||||
|
/* If not fully booted then we don't have a logging to snomask mapping so can't do much.. */
|
||||||
|
if (!loop.booted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Never send these */
|
||||||
|
if (!strcmp(subsystem, "rawtraffic"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (l = logs[LOG_DEST_CHANNEL]; l; l = l->next)
|
||||||
|
{
|
||||||
|
const char *operlogin;
|
||||||
|
ConfigItem_oper *oper;
|
||||||
|
Channel *channel;
|
||||||
|
|
||||||
|
if (!log_sources_match(l->sources, loglevel, subsystem, event_id, 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
channel = find_channel(l->destination);
|
||||||
|
if (!channel)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (m = channel->members; m; m = m->next)
|
||||||
|
{
|
||||||
|
Client *client = m->client;
|
||||||
|
if (!MyUser(client))
|
||||||
|
continue;
|
||||||
|
if (l->oper_only && !IsOper(client))
|
||||||
|
continue;
|
||||||
|
sendto_log(client, "PRIVMSG", channel->name, l->color, l->show_event,
|
||||||
|
loglevel, subsystem, event_id, msg,
|
||||||
|
l->json_message_tag ? json_serialized : NULL,
|
||||||
|
from_server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_free_message_tags(mtags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_unreal_log_remote(LogLevel loglevel, const char *subsystem, const char *event_id, MultiLine *msg, const char *json_serialized)
|
void do_unreal_log_remote(LogLevel loglevel, const char *subsystem, const char *event_id, MultiLine *msg, const char *json_serialized)
|
||||||
|
@ -1522,6 +1630,25 @@ void do_unreal_log_remote(LogLevel loglevel, const char *subsystem, const char *
|
||||||
do_unreal_log_remote_deliver(loglevel, subsystem, event_id, msg, json_serialized);
|
do_unreal_log_remote_deliver(loglevel, subsystem, event_id, msg, json_serialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Send server notices to control channel */
|
||||||
|
void do_unreal_log_control(LogLevel loglevel, const char *subsystem, const char *event_id, MultiLine *msg, const char *json_serialized, Client *from_server)
|
||||||
|
{
|
||||||
|
Client *client;
|
||||||
|
MultiLine *m;
|
||||||
|
|
||||||
|
if (!loop.booted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Never send these */
|
||||||
|
if (!strcmp(subsystem, "rawtraffic"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
list_for_each_entry(client, &control_list, lclient_node)
|
||||||
|
if (IsMonitorRehash(client))
|
||||||
|
for (m = msg; m; m = m->next)
|
||||||
|
sendto_one(client, NULL, "REPLY [%s] %s", log_level_valtostring(loglevel), m->line);
|
||||||
|
}
|
||||||
|
|
||||||
void do_unreal_log_free_args(va_list vl)
|
void do_unreal_log_free_args(va_list vl)
|
||||||
{
|
{
|
||||||
LogData *d;
|
LogData *d;
|
||||||
|
@ -1693,17 +1820,24 @@ void do_unreal_log_internal(LogLevel loglevel, const char *subsystem, const char
|
||||||
/* Convert the message buffer to MultiLine */
|
/* Convert the message buffer to MultiLine */
|
||||||
mmsg = line2multiline(msgbuf);
|
mmsg = line2multiline(msgbuf);
|
||||||
|
|
||||||
/* Now call the disk loggers */
|
/* Parse the "from server" info, if any */
|
||||||
do_unreal_log_disk(loglevel, subsystem, event_id, mmsg, json_serialized);
|
|
||||||
|
|
||||||
/* And the ircops stuff */
|
|
||||||
t = json_object_get(j_details, "from_server_name");
|
t = json_object_get(j_details, "from_server_name");
|
||||||
if (t && (str = json_get_value(t)))
|
if (t && (str = json_get_value(t)))
|
||||||
from_server = find_server(str, NULL);
|
from_server = find_server(str, NULL);
|
||||||
if (from_server == NULL)
|
if (from_server == NULL)
|
||||||
from_server = &me;
|
from_server = &me;
|
||||||
|
|
||||||
|
/* Now call all the loggers: */
|
||||||
|
|
||||||
|
do_unreal_log_disk(loglevel, subsystem, event_id, mmsg, json_serialized, from_server);
|
||||||
|
|
||||||
|
if ((loop.rehashing == 2) || !strcmp(subsystem, "config"))
|
||||||
|
do_unreal_log_control(loglevel, subsystem, event_id, mmsg, json_serialized, from_server);
|
||||||
|
|
||||||
do_unreal_log_opers(loglevel, subsystem, event_id, mmsg, json_serialized, from_server);
|
do_unreal_log_opers(loglevel, subsystem, event_id, mmsg, json_serialized, from_server);
|
||||||
|
|
||||||
|
do_unreal_log_channels(loglevel, subsystem, event_id, mmsg, json_serialized, from_server);
|
||||||
|
|
||||||
do_unreal_log_remote(loglevel, subsystem, event_id, mmsg, json_serialized);
|
do_unreal_log_remote(loglevel, subsystem, event_id, mmsg, json_serialized);
|
||||||
|
|
||||||
// NOTE: code duplication further down!
|
// NOTE: code duplication further down!
|
||||||
|
@ -1723,10 +1857,11 @@ void do_unreal_log_internal_from_remote(LogLevel loglevel, const char *subsystem
|
||||||
unreal_log_recursion_trap = 1;
|
unreal_log_recursion_trap = 1;
|
||||||
|
|
||||||
/* Call the disk loggers */
|
/* Call the disk loggers */
|
||||||
do_unreal_log_disk(loglevel, subsystem, event_id, msg, json_serialized);
|
do_unreal_log_disk(loglevel, subsystem, event_id, msg, json_serialized, from_server);
|
||||||
|
|
||||||
/* And the ircops stuff */
|
/* And to IRC */
|
||||||
do_unreal_log_opers(loglevel, subsystem, event_id, msg, json_serialized, from_server);
|
do_unreal_log_opers(loglevel, subsystem, event_id, msg, json_serialized, from_server);
|
||||||
|
do_unreal_log_channels(loglevel, subsystem, event_id, msg, json_serialized, from_server);
|
||||||
|
|
||||||
unreal_log_recursion_trap = 0;
|
unreal_log_recursion_trap = 0;
|
||||||
}
|
}
|
||||||
|
|
174
src/misc.c
174
src/misc.c
|
@ -623,8 +623,8 @@ void exit_client_ex(Client *client, Client *origin, MessageTag *recv_mtags, cons
|
||||||
|
|
||||||
if (client->local->fd >= 0 && !IsConnecting(client))
|
if (client->local->fd >= 0 && !IsConnecting(client))
|
||||||
{
|
{
|
||||||
sendto_one(client, NULL, "ERROR :Closing Link: %s (%s)",
|
if (!IsControl(client))
|
||||||
get_client_name(client, FALSE), comment);
|
sendto_one(client, NULL, "ERROR :Closing Link: %s (%s)", get_client_name(client, FALSE), comment);
|
||||||
}
|
}
|
||||||
close_connection(client);
|
close_connection(client);
|
||||||
}
|
}
|
||||||
|
@ -2369,3 +2369,173 @@ void addlettertodynamicstringsorted(char **str, char letter)
|
||||||
safe_free_raw(*str);
|
safe_free_raw(*str);
|
||||||
*str = newbuf;
|
*str = newbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void s_die()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
Client *client;
|
||||||
|
if (!IsService)
|
||||||
|
{
|
||||||
|
loop.terminating = 1;
|
||||||
|
unload_all_modules();
|
||||||
|
|
||||||
|
list_for_each_entry(client, &lclient_list, lclient_node)
|
||||||
|
(void) send_queued(client);
|
||||||
|
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SERVICE_STATUS status;
|
||||||
|
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||||
|
SC_HANDLE hService = OpenService(hSCManager, "UnrealIRCd", SERVICE_STOP);
|
||||||
|
ControlService(hService, SERVICE_CONTROL_STOP, &status);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
loop.terminating = 1;
|
||||||
|
unload_all_modules();
|
||||||
|
unlink(conf_files ? conf_files->pid_file : IRCD_PIDFILE);
|
||||||
|
exit(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
void s_rehash()
|
||||||
|
{
|
||||||
|
struct sigaction act;
|
||||||
|
dorehash = 1;
|
||||||
|
act.sa_handler = s_rehash;
|
||||||
|
act.sa_flags = 0;
|
||||||
|
(void)sigemptyset(&act.sa_mask);
|
||||||
|
(void)sigaddset(&act.sa_mask, SIGHUP);
|
||||||
|
(void)sigaction(SIGHUP, &act, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void s_reloadcert()
|
||||||
|
{
|
||||||
|
struct sigaction act;
|
||||||
|
doreloadcert = 1;
|
||||||
|
act.sa_handler = s_reloadcert;
|
||||||
|
act.sa_flags = 0;
|
||||||
|
(void)sigemptyset(&act.sa_mask);
|
||||||
|
(void)sigaddset(&act.sa_mask, SIGUSR1);
|
||||||
|
(void)sigaction(SIGUSR1, &act, NULL);
|
||||||
|
}
|
||||||
|
#endif // #ifndef _WIN32
|
||||||
|
|
||||||
|
void restart(const char *mesg)
|
||||||
|
{
|
||||||
|
server_reboot(mesg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void s_restart()
|
||||||
|
{
|
||||||
|
dorestart = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
/** Signal handler for signals which we ignore,
|
||||||
|
* like SIGPIPE ("Broken pipe") and SIGWINCH (terminal window changed) etc.
|
||||||
|
*/
|
||||||
|
void ignore_this_signal()
|
||||||
|
{
|
||||||
|
struct sigaction act;
|
||||||
|
|
||||||
|
act.sa_handler = ignore_this_signal;
|
||||||
|
act.sa_flags = 0;
|
||||||
|
(void)sigemptyset(&act.sa_mask);
|
||||||
|
(void)sigaddset(&act.sa_mask, SIGALRM);
|
||||||
|
(void)sigaddset(&act.sa_mask, SIGPIPE);
|
||||||
|
(void)sigaction(SIGALRM, &act, (struct sigaction *)NULL);
|
||||||
|
(void)sigaction(SIGPIPE, &act, (struct sigaction *)NULL);
|
||||||
|
#ifdef SIGWINCH
|
||||||
|
(void)sigaddset(&act.sa_mask, SIGWINCH);
|
||||||
|
(void)sigaction(SIGWINCH, &act, (struct sigaction *)NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* #ifndef _WIN32 */
|
||||||
|
|
||||||
|
|
||||||
|
void server_reboot(const char *mesg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Client *client;
|
||||||
|
unreal_log(ULOG_INFO, "main", "UNREALIRCD_RESTARTING", NULL,
|
||||||
|
"Restarting server: $reason",
|
||||||
|
log_data_string("reason", mesg));
|
||||||
|
|
||||||
|
list_for_each_entry(client, &lclient_list, lclient_node)
|
||||||
|
(void) send_queued(client);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ** fd 0 must be 'preserved' if either the -d or -i options have
|
||||||
|
* ** been passed to us before restarting.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_SYSLOG
|
||||||
|
(void)closelog();
|
||||||
|
#endif
|
||||||
|
#ifndef _WIN32
|
||||||
|
for (i = 3; i < MAXCONNECTIONS; i++)
|
||||||
|
(void)close(i);
|
||||||
|
if (!(bootopt & (BOOT_TTY | BOOT_DEBUG)))
|
||||||
|
(void)close(2);
|
||||||
|
(void)close(1);
|
||||||
|
(void)close(0);
|
||||||
|
close_std_descriptors();
|
||||||
|
(void)execv(MYNAME, myargv);
|
||||||
|
#else
|
||||||
|
close_connections();
|
||||||
|
if (!IsService)
|
||||||
|
{
|
||||||
|
CleanUp();
|
||||||
|
WinExec(cmdLine, SW_SHOWDEFAULT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
unload_all_modules();
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (IsService)
|
||||||
|
{
|
||||||
|
SERVICE_STATUS status;
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
STARTUPINFO si;
|
||||||
|
char fname[MAX_PATH];
|
||||||
|
memset(&status, 0, sizeof(status));
|
||||||
|
memset(&si, 0, sizeof(si));
|
||||||
|
IRCDStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||||
|
SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
|
||||||
|
GetModuleFileName(GetModuleHandle(NULL), fname, MAX_PATH);
|
||||||
|
CreateProcess(fname, "restartsvc", NULL, NULL, FALSE,
|
||||||
|
0, NULL, NULL, &si, &pi);
|
||||||
|
IRCDStatus.dwCurrentState = SERVICE_STOPPED;
|
||||||
|
SetServiceStatus(IRCDStatusHandle, &IRCDStatus);
|
||||||
|
ExitProcess(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check if at least 'minimum' seconds passed by since last run.
|
||||||
|
* @param tv_old Pointer to a timeval struct to keep track of things.
|
||||||
|
* @param minimum The time specified in milliseconds (eg: 1000 for 1 second)
|
||||||
|
* @returns When 'minimum' msec passed 1 is returned and the time is reset, otherwise 0 is returned.
|
||||||
|
*/
|
||||||
|
int minimum_msec_since_last_run(struct timeval *tv_old, long minimum)
|
||||||
|
{
|
||||||
|
long v;
|
||||||
|
|
||||||
|
if (tv_old->tv_sec == 0)
|
||||||
|
{
|
||||||
|
/* First call ever */
|
||||||
|
tv_old->tv_sec = timeofday_tv.tv_sec;
|
||||||
|
tv_old->tv_usec = timeofday_tv.tv_usec;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
v = ((timeofday_tv.tv_sec - tv_old->tv_sec) * 1000) + ((timeofday_tv.tv_usec - tv_old->tv_usec)/1000);
|
||||||
|
if (v >= minimum)
|
||||||
|
{
|
||||||
|
tv_old->tv_sec = timeofday_tv.tv_sec;
|
||||||
|
tv_old->tv_usec = timeofday_tv.tv_usec;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -99,6 +99,7 @@ void blacklist_free_conf(void);
|
||||||
void delete_blacklist_block(Blacklist *e);
|
void delete_blacklist_block(Blacklist *e);
|
||||||
void blacklist_md_free(ModData *md);
|
void blacklist_md_free(ModData *md);
|
||||||
int blacklist_handshake(Client *client);
|
int blacklist_handshake(Client *client);
|
||||||
|
int blacklist_ip_change(Client *client, const char *oldip);
|
||||||
int blacklist_quit(Client *client, MessageTag *mtags, const char *comment);
|
int blacklist_quit(Client *client, MessageTag *mtags, const char *comment);
|
||||||
int blacklist_preconnect(Client *client);
|
int blacklist_preconnect(Client *client);
|
||||||
void blacklist_resolver_callback(void *arg, int status, int timeouts, struct hostent *he);
|
void blacklist_resolver_callback(void *arg, int status, int timeouts, struct hostent *he);
|
||||||
|
@ -146,6 +147,7 @@ MOD_INIT()
|
||||||
|
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, blacklist_config_run);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, blacklist_config_run);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_HANDSHAKE, 0, blacklist_handshake);
|
HookAdd(modinfo->handle, HOOKTYPE_HANDSHAKE, 0, blacklist_handshake);
|
||||||
|
HookAdd(modinfo->handle, HOOKTYPE_IP_CHANGE, 0, blacklist_ip_change);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_PRE_LOCAL_CONNECT, 0, blacklist_preconnect);
|
HookAdd(modinfo->handle, HOOKTYPE_PRE_LOCAL_CONNECT, 0, blacklist_preconnect);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_REHASH, 0, blacklist_rehash);
|
HookAdd(modinfo->handle, HOOKTYPE_REHASH, 0, blacklist_rehash);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_REHASH_COMPLETE, 0, blacklist_rehash_complete);
|
HookAdd(modinfo->handle, HOOKTYPE_REHASH_COMPLETE, 0, blacklist_rehash_complete);
|
||||||
|
@ -553,6 +555,12 @@ int blacklist_handshake(Client *client)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int blacklist_ip_change(Client *client, const char *oldip)
|
||||||
|
{
|
||||||
|
blacklist_start_check(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int blacklist_start_check(Client *client)
|
int blacklist_start_check(Client *client)
|
||||||
{
|
{
|
||||||
Blacklist *bl;
|
Blacklist *bl;
|
||||||
|
|
|
@ -73,9 +73,9 @@ int cmode_halfop_is_ok(Client *client, Channel *channel, char mode, const char *
|
||||||
/* User may always remove their own modes */
|
/* User may always remove their own modes */
|
||||||
return EX_ALLOW;
|
return EX_ALLOW;
|
||||||
}
|
}
|
||||||
if ((what == MODE_ADD) && check_channel_access(client, channel, "hoaq"))
|
if (check_channel_access(client, channel, "oaq"))
|
||||||
{
|
{
|
||||||
/* Permitted for +hoaq */
|
/* Permitted for +oaq */
|
||||||
return EX_ALLOW;
|
return EX_ALLOW;
|
||||||
}
|
}
|
||||||
if (type == EXCHK_ACCESS_ERR)
|
if (type == EXCHK_ACCESS_ERR)
|
||||||
|
|
|
@ -384,10 +384,24 @@ int read_listmode(UnrealDB *db, Ban **lst)
|
||||||
|
|
||||||
for (i = 0; i < total; i++)
|
for (i = 0; i < total; i++)
|
||||||
{
|
{
|
||||||
|
const char *str;
|
||||||
e = safe_alloc(sizeof(Ban));
|
e = safe_alloc(sizeof(Ban));
|
||||||
R_SAFE(unrealdb_read_str(db, &e->banstr));
|
R_SAFE(unrealdb_read_str(db, &e->banstr));
|
||||||
R_SAFE(unrealdb_read_str(db, &e->who));
|
R_SAFE(unrealdb_read_str(db, &e->who));
|
||||||
R_SAFE(unrealdb_read_int64(db, &when));
|
R_SAFE(unrealdb_read_int64(db, &when));
|
||||||
|
str = clean_ban_mask(e->banstr, MODE_ADD, &me, 0);
|
||||||
|
if (str == NULL)
|
||||||
|
{
|
||||||
|
/* Skip this item */
|
||||||
|
config_warn("[channeldb] listmode skipped (no longer valid?): %s", e->banstr);
|
||||||
|
safe_free(e->banstr);
|
||||||
|
safe_free(e->who);
|
||||||
|
safe_free(e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
safe_strdup(e->banstr, str);
|
||||||
|
|
||||||
|
/* Add to list */
|
||||||
e->when = when;
|
e->when = when;
|
||||||
e->next = *lst;
|
e->next = *lst;
|
||||||
*lst = e;
|
*lst = e;
|
||||||
|
|
|
@ -219,7 +219,7 @@ void _userhost_changed(Client *client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RunHook(HOOKTYPE_USERHOST_CHANGED, client, remember_user, remember_host);
|
RunHook(HOOKTYPE_USERHOST_CHANGE, client, remember_user, remember_host);
|
||||||
|
|
||||||
if (MyUser(client))
|
if (MyUser(client))
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
ModuleHeader MOD_HEADER
|
ModuleHeader MOD_HEADER
|
||||||
= {
|
= {
|
||||||
"dccdeny",
|
"dccdeny",
|
||||||
"5.0",
|
"6.0.2",
|
||||||
"command /dccdeny",
|
"command /dccdeny",
|
||||||
"UnrealIRCd Team",
|
"UnrealIRCd Team",
|
||||||
"unrealircd-6",
|
"unrealircd-6",
|
||||||
|
@ -525,11 +525,8 @@ int dccdeny_can_send_to_channel(Client *client, Channel *channel, Membership *lp
|
||||||
const char *filename = get_dcc_filename(*msg);
|
const char *filename = get_dcc_filename(*msg);
|
||||||
if (filename && !can_dcc(client, channel->name, NULL, filename, &err))
|
if (filename && !can_dcc(client, channel->name, NULL, filename, &err))
|
||||||
{
|
{
|
||||||
if (!IsDead(client) && (sendtype != SEND_TYPE_NOTICE))
|
strlcpy(errbuf, err, sizeof(errbuf));
|
||||||
{
|
*errmsg = errbuf;
|
||||||
strlcpy(errbuf, err, sizeof(errbuf));
|
|
||||||
*errmsg = errbuf;
|
|
||||||
}
|
|
||||||
return HOOK_DENY;
|
return HOOK_DENY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -649,7 +646,11 @@ static int can_dcc(Client *client, const char *target, Client *targetcli, const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match_spamfilter(client, filename, SPAMF_DCC, "PRIVMSG", target, 0, NULL))
|
if (match_spamfilter(client, filename, SPAMF_DCC, "PRIVMSG", target, 0, NULL))
|
||||||
|
{
|
||||||
|
/* Dirty hack, yeah spamfilter already sent the error message :( */
|
||||||
|
*errmsg = "";
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((fl = dcc_isforbidden(client, filename)))
|
if ((fl = dcc_isforbidden(client, filename)))
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,7 +43,7 @@ MOD_INIT()
|
||||||
req.conv_param = extban_realname_conv_param;
|
req.conv_param = extban_realname_conv_param;
|
||||||
req.is_banned = extban_realname_is_banned;
|
req.is_banned = extban_realname_is_banned;
|
||||||
req.is_banned_events = BANCHK_ALL|BANCHK_TKL;
|
req.is_banned_events = BANCHK_ALL|BANCHK_TKL;
|
||||||
req.options = EXTBOPT_CHSVSMODE|EXTBOPT_INVEX|EXTBOPT_TKL;
|
req.options = EXTBOPT_INVEX|EXTBOPT_TKL;
|
||||||
if (!ExtbanAdd(modinfo->handle, req))
|
if (!ExtbanAdd(modinfo->handle, req))
|
||||||
{
|
{
|
||||||
config_error("could not register extended ban type");
|
config_error("could not register extended ban type");
|
||||||
|
|
|
@ -78,7 +78,6 @@ MOD_INIT()
|
||||||
extban.letter = 't';
|
extban.letter = 't';
|
||||||
extban.name = "time";
|
extban.name = "time";
|
||||||
extban.options |= EXTBOPT_ACTMODIFIER; /* not really, but ours shouldn't be stacked from group 1 */
|
extban.options |= EXTBOPT_ACTMODIFIER; /* not really, but ours shouldn't be stacked from group 1 */
|
||||||
extban.options |= EXTBOPT_CHSVSMODE; /* so "SVSMODE -nick" will unset affected ~t extbans */
|
|
||||||
extban.options |= EXTBOPT_INVEX; /* also permit timed invite-only exceptions (+I) */
|
extban.options |= EXTBOPT_INVEX; /* also permit timed invite-only exceptions (+I) */
|
||||||
extban.conv_param = timedban_extban_conv_param;
|
extban.conv_param = timedban_extban_conv_param;
|
||||||
extban.is_ok = timedban_extban_is_ok;
|
extban.is_ok = timedban_extban_is_ok;
|
||||||
|
|
|
@ -26,8 +26,8 @@ long CAP_EXTENDED_MONITOR = 0L;
|
||||||
|
|
||||||
int extended_monitor_away(Client *client, MessageTag *mtags, const char *reason, int already_as_away);
|
int extended_monitor_away(Client *client, MessageTag *mtags, const char *reason, int already_as_away);
|
||||||
int extended_monitor_account_login(Client *client, MessageTag *mtags);
|
int extended_monitor_account_login(Client *client, MessageTag *mtags);
|
||||||
int extended_monitor_userhost_changed(Client *client, const char *olduser, const char *oldhost);
|
int extended_monitor_userhost_change(Client *client, const char *olduser, const char *oldhost);
|
||||||
int extended_monitor_realname_changed(Client *client, const char *oldinfo);
|
int extended_monitor_realname_change(Client *client, const char *oldinfo);
|
||||||
int extended_monitor_notification(Client *client, Watch *watch, Link *lp, int event);
|
int extended_monitor_notification(Client *client, Watch *watch, Link *lp, int event);
|
||||||
|
|
||||||
ModuleHeader MOD_HEADER
|
ModuleHeader MOD_HEADER
|
||||||
|
@ -59,8 +59,8 @@ MOD_INIT()
|
||||||
|
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_AWAY, 0, extended_monitor_away);
|
HookAdd(modinfo->handle, HOOKTYPE_AWAY, 0, extended_monitor_away);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_ACCOUNT_LOGIN, 0, extended_monitor_account_login);
|
HookAdd(modinfo->handle, HOOKTYPE_ACCOUNT_LOGIN, 0, extended_monitor_account_login);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_USERHOST_CHANGED, 0, extended_monitor_userhost_changed);
|
HookAdd(modinfo->handle, HOOKTYPE_USERHOST_CHANGE, 0, extended_monitor_userhost_change);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_REALNAME_CHANGED, 0, extended_monitor_realname_changed);
|
HookAdd(modinfo->handle, HOOKTYPE_REALNAME_CHANGE, 0, extended_monitor_realname_change);
|
||||||
|
|
||||||
return MOD_SUCCESS;
|
return MOD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -95,13 +95,13 @@ int extended_monitor_account_login(Client *client, MessageTag *mtags)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int extended_monitor_userhost_changed(Client *client, const char *olduser, const char *oldhost)
|
int extended_monitor_userhost_change(Client *client, const char *olduser, const char *oldhost)
|
||||||
{
|
{
|
||||||
watch_check(client, WATCH_EVENT_USERHOST, extended_monitor_notification);
|
watch_check(client, WATCH_EVENT_USERHOST, extended_monitor_notification);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int extended_monitor_realname_changed(Client *client, const char *oldinfo)
|
int extended_monitor_realname_change(Client *client, const char *oldinfo)
|
||||||
{
|
{
|
||||||
watch_check(client, WATCH_EVENT_REALNAME, extended_monitor_notification);
|
watch_check(client, WATCH_EVENT_REALNAME, extended_monitor_notification);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -25,6 +25,7 @@ void geoip_base_free(ModData *m);
|
||||||
const char *geoip_base_serialize(ModData *m);
|
const char *geoip_base_serialize(ModData *m);
|
||||||
void geoip_base_unserialize(const char *str, ModData *m);
|
void geoip_base_unserialize(const char *str, ModData *m);
|
||||||
int geoip_base_handshake(Client *client);
|
int geoip_base_handshake(Client *client);
|
||||||
|
int geoip_base_ip_change(Client *client, const char *oldip);
|
||||||
int geoip_base_whois(Client *client, Client *target, NameValuePrioList **list);
|
int geoip_base_whois(Client *client, Client *target, NameValuePrioList **list);
|
||||||
int geoip_connect_extinfo(Client *client, NameValuePrioList **list);
|
int geoip_connect_extinfo(Client *client, NameValuePrioList **list);
|
||||||
int geoip_base_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
|
int geoip_base_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
|
||||||
|
@ -119,10 +120,10 @@ MOD_INIT()
|
||||||
|
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, geoip_base_configrun);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, geoip_base_configrun);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_HANDSHAKE, 0, geoip_base_handshake);
|
HookAdd(modinfo->handle, HOOKTYPE_HANDSHAKE, 0, geoip_base_handshake);
|
||||||
|
HookAdd(modinfo->handle, HOOKTYPE_IP_CHANGE, 0, geoip_base_ip_change);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_SERVER_HANDSHAKE_OUT, 0, geoip_base_handshake);
|
HookAdd(modinfo->handle, HOOKTYPE_SERVER_HANDSHAKE_OUT, 0, geoip_base_handshake);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONNECT_EXTINFO, 1, geoip_connect_extinfo); /* (prio: near-first) */
|
HookAdd(modinfo->handle, HOOKTYPE_CONNECT_EXTINFO, 1, geoip_connect_extinfo); /* (prio: near-first) */
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_PRE_LOCAL_CONNECT, 0,geoip_base_handshake); /* in case the IP changed in registration phase (WEBIRC, HTTP Forwarded) */
|
HookAdd(modinfo->handle, HOOKTYPE_PRE_LOCAL_CONNECT, 0,geoip_base_handshake); /* in case the IP changed in registration phase (WEBIRC, HTTP Forwarded) */
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_REMOTE_CONNECT, 0, geoip_base_handshake); /* remote user */
|
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_WHOIS, 0, geoip_base_whois);
|
HookAdd(modinfo->handle, HOOKTYPE_WHOIS, 0, geoip_base_whois);
|
||||||
|
|
||||||
CommandAdd(modinfo->handle, "GEOIP", cmd_geoip, MAXPARA, CMD_USER);
|
CommandAdd(modinfo->handle, "GEOIP", cmd_geoip, MAXPARA, CMD_USER);
|
||||||
|
@ -167,6 +168,12 @@ int geoip_base_handshake(Client *client)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int geoip_base_ip_change(Client *client, const char *oldip)
|
||||||
|
{
|
||||||
|
geoip_base_handshake(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void geoip_base_free(ModData *m)
|
void geoip_base_free(ModData *m)
|
||||||
{
|
{
|
||||||
if (m->ptr)
|
if (m->ptr)
|
||||||
|
@ -229,12 +236,13 @@ void geoip_base_unserialize(const char *str, ModData *m)
|
||||||
m->ptr = res;
|
m->ptr = res;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVENT(geoip_base_set_existing_users_evt){
|
EVENT(geoip_base_set_existing_users_evt)
|
||||||
|
{
|
||||||
Client *client;
|
Client *client;
|
||||||
list_for_each_entry(client, &client_list, client_node){
|
list_for_each_entry(client, &client_list, client_node)
|
||||||
if (!IsUser(client))
|
{
|
||||||
continue;
|
if (MyUser(client))
|
||||||
geoip_base_handshake(client);
|
geoip_base_handshake(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,22 @@ static ModuleInfo *MyModInfo;
|
||||||
#define MyMod MyModInfo->handle
|
#define MyMod MyModInfo->handle
|
||||||
#define SAVE_MODINFO MyModInfo = modinfo;
|
#define SAVE_MODINFO MyModInfo = modinfo;
|
||||||
|
|
||||||
|
static int lmax = 0;
|
||||||
|
static int umax = 0;
|
||||||
|
|
||||||
|
static int dcount(int n)
|
||||||
|
{
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
while (n != 0)
|
||||||
|
{
|
||||||
|
n = n/10;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
ModuleHeader MOD_HEADER
|
ModuleHeader MOD_HEADER
|
||||||
= {
|
= {
|
||||||
"hideserver",
|
"hideserver",
|
||||||
|
@ -230,8 +246,24 @@ static void dump_map(Client *client, Client *server, char *mask, int prompt_leng
|
||||||
sendnumeric(client, RPL_MAPMORE, prompt, length, server->name);
|
sendnumeric(client, RPL_MAPMORE, prompt, length, server->name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sendnumeric(client, RPL_MAP, prompt,
|
char tbuf[256];
|
||||||
length, server->name, server->server->users, IsOper(client) ? server->id : "");
|
char sid[10];
|
||||||
|
int len = length - strlen(server->name) + 1;
|
||||||
|
|
||||||
|
if (len < 0)
|
||||||
|
len = 0;
|
||||||
|
if (len > 255)
|
||||||
|
len = 255;
|
||||||
|
|
||||||
|
tbuf[len--] = '\0';
|
||||||
|
while (len >= 0)
|
||||||
|
tbuf[len--] = '-';
|
||||||
|
if (IsOper(client))
|
||||||
|
snprintf(sid, sizeof(sid), " [%s]", server->id);
|
||||||
|
sendnumeric(client, RPL_MAP, prompt, server->name, tbuf, umax,
|
||||||
|
server->server->users, (double)(lmax < 10) ? 4 : (lmax == 100) ? 6 : 5,
|
||||||
|
(server->server->users * 100.0 / irccounts.clients),
|
||||||
|
IsOper(client) ? sid : "");
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,12 +311,25 @@ static void dump_map(Client *client, Client *server, char *mask, int prompt_leng
|
||||||
void dump_flat_map(Client *client, Client *server, int length)
|
void dump_flat_map(Client *client, Client *server, int length)
|
||||||
{
|
{
|
||||||
char buf[4];
|
char buf[4];
|
||||||
|
char tbuf[256];
|
||||||
Client *acptr;
|
Client *acptr;
|
||||||
int cnt = 0, hide_ulines;
|
int cnt = 0, len = 0, hide_ulines;
|
||||||
|
|
||||||
hide_ulines = (HIDE_ULINES && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL)) ? 1 : 0;
|
hide_ulines = (HIDE_ULINES && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL)) ? 1 : 0;
|
||||||
|
|
||||||
sendnumeric(client, RPL_MAP, "", length, server->name, server->server->users, "");
|
len = length - strlen(server->name) + 3;
|
||||||
|
if (len < 0)
|
||||||
|
len = 0;
|
||||||
|
if (len > 255)
|
||||||
|
len = 255;
|
||||||
|
|
||||||
|
tbuf[len--] = '\0';
|
||||||
|
while (len >= 0)
|
||||||
|
tbuf[len--] = '-';
|
||||||
|
|
||||||
|
sendnumeric(client, RPL_MAP, "", server->name, tbuf, umax, server->server->users,
|
||||||
|
(lmax < 10) ? 4 : (lmax == 100) ? 6 : 5,
|
||||||
|
(server->server->users * 100.0 / irccounts.clients), "");
|
||||||
|
|
||||||
list_for_each_entry(acptr, &global_server_list, client_node)
|
list_for_each_entry(acptr, &global_server_list, client_node)
|
||||||
{
|
{
|
||||||
|
@ -304,7 +349,20 @@ void dump_flat_map(Client *client, Client *server, int length)
|
||||||
break;
|
break;
|
||||||
if (--cnt == 0)
|
if (--cnt == 0)
|
||||||
*buf = '`';
|
*buf = '`';
|
||||||
sendnumeric(client, RPL_MAP, buf, length-2, acptr->name, acptr->server->users, "");
|
|
||||||
|
len = length - strlen(acptr->name) + 1;
|
||||||
|
if (len < 0)
|
||||||
|
len = 0;
|
||||||
|
if (len > 255)
|
||||||
|
len = 255;
|
||||||
|
|
||||||
|
tbuf[len--] = '\0';
|
||||||
|
while (len >= 0)
|
||||||
|
tbuf[len--] = '-';
|
||||||
|
|
||||||
|
sendnumeric(client, RPL_MAP, buf, acptr->name, tbuf, umax, acptr->server->users,
|
||||||
|
(lmax < 10) ? 4 : (lmax == 100) ? 6 : 5,
|
||||||
|
(acptr->server->users * 100.0 / irccounts.clients), "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,6 +376,10 @@ CMD_OVERRIDE_FUNC(override_map)
|
||||||
{
|
{
|
||||||
Client *acptr;
|
Client *acptr;
|
||||||
int longest = strlen(me.name);
|
int longest = strlen(me.name);
|
||||||
|
float avg_users = 0.0;
|
||||||
|
|
||||||
|
umax = 0;
|
||||||
|
lmax = 0;
|
||||||
|
|
||||||
if (parc < 2)
|
if (parc < 2)
|
||||||
parv[1] = "*";
|
parv[1] = "*";
|
||||||
|
@ -339,10 +401,16 @@ CMD_OVERRIDE_FUNC(override_map)
|
||||||
|
|
||||||
list_for_each_entry(acptr, &global_server_list, client_node)
|
list_for_each_entry(acptr, &global_server_list, client_node)
|
||||||
{
|
{
|
||||||
|
int perc = 0;
|
||||||
if (FindHiddenServer(acptr->name))
|
if (FindHiddenServer(acptr->name))
|
||||||
break;
|
break;
|
||||||
|
perc = (acptr->server->users * 100 / irccounts.clients);
|
||||||
if ((strlen(acptr->name) + acptr->hopcount * 2) > longest)
|
if ((strlen(acptr->name) + acptr->hopcount * 2) > longest)
|
||||||
longest = strlen(acptr->name) + acptr->hopcount * 2;
|
longest = strlen(acptr->name) + acptr->hopcount * 2;
|
||||||
|
if (lmax < perc)
|
||||||
|
lmax = perc;
|
||||||
|
if (umax < dcount(acptr->server->users))
|
||||||
|
umax = dcount(acptr->server->users);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (longest > 60)
|
if (longest > 60)
|
||||||
|
@ -354,6 +422,9 @@ CMD_OVERRIDE_FUNC(override_map)
|
||||||
else
|
else
|
||||||
dump_map(client, &me, "*", 0, longest);
|
dump_map(client, &me, "*", 0, longest);
|
||||||
|
|
||||||
|
avg_users = irccounts.clients * 1.0 / irccounts.servers;
|
||||||
|
sendnumeric(client, RPL_MAPUSERS, irccounts.servers, (irccounts.servers > 1 ? "s" : ""), irccounts.clients,
|
||||||
|
(irccounts.clients > 1 ? "s" : ""), avg_users);
|
||||||
sendnumeric(client, RPL_MAPEND);
|
sendnumeric(client, RPL_MAPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ int lr_post_command(Client *from, MessageTag *mtags, const char *buf)
|
||||||
*/
|
*/
|
||||||
int more_tags = currentcmd.firstbuf[0] == '@';
|
int more_tags = currentcmd.firstbuf[0] == '@';
|
||||||
currentcmd.client = NULL; /* prevent lr_packet from interfering */
|
currentcmd.client = NULL; /* prevent lr_packet from interfering */
|
||||||
snprintf(packet, sizeof(packet),
|
snprintf(packet, sizeof(packet)-3,
|
||||||
"@label=%s%s%s\r\n",
|
"@label=%s%s%s\r\n",
|
||||||
currentcmd.label,
|
currentcmd.label,
|
||||||
more_tags ? ";" : " ",
|
more_tags ? ";" : " ",
|
||||||
|
|
|
@ -31,7 +31,7 @@ ModuleHeader MOD_HEADER
|
||||||
= {
|
= {
|
||||||
"list",
|
"list",
|
||||||
"5.0",
|
"5.0",
|
||||||
"command /list",
|
"command /LIST",
|
||||||
"UnrealIRCd Team",
|
"UnrealIRCd Team",
|
||||||
"unrealircd-6",
|
"unrealircd-6",
|
||||||
};
|
};
|
||||||
|
@ -136,8 +136,8 @@ CMD_FUNC(cmd_list)
|
||||||
"use, and what channels LIST will return when you use them.",
|
"use, and what channels LIST will return when you use them.",
|
||||||
">number List channels with more than <number> people.",
|
">number List channels with more than <number> people.",
|
||||||
"<number List channels with less than <number> people.",
|
"<number List channels with less than <number> people.",
|
||||||
"C>number List channels created between now and <number> minutes ago.",
|
"C>number List channels created more than <number> minutes ago.",
|
||||||
"C<number List channels created earlier than <number> minutes ago.",
|
"C<number List channels created less than <number> minutes ago.",
|
||||||
"T>number List channels whose topics are older than <number> minutes",
|
"T>number List channels whose topics are older than <number> minutes",
|
||||||
" (Ie, they have not changed in the last <number> minutes.",
|
" (Ie, they have not changed in the last <number> minutes.",
|
||||||
"T<number List channels whose topics are not older than <number> minutes.",
|
"T<number List channels whose topics are not older than <number> minutes.",
|
||||||
|
@ -199,56 +199,52 @@ CMD_FUNC(cmd_list)
|
||||||
}
|
}
|
||||||
switch (*name)
|
switch (*name)
|
||||||
{
|
{
|
||||||
case '<':
|
case '<':
|
||||||
usermax = atoi(name + 1) - 1;
|
usermax = atoi(name + 1) - 1;
|
||||||
doall = 1;
|
doall = 1;
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
usermin = atoi(name + 1) + 1;
|
usermin = atoi(name + 1) + 1;
|
||||||
doall = 1;
|
doall = 1;
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
case 'c': /* Channel time -- creation time? */
|
case 'c': /* Channel time -- creation time? */
|
||||||
++name;
|
++name;
|
||||||
switch (*name++)
|
switch (*name++)
|
||||||
{
|
{
|
||||||
case '<':
|
case '<':
|
||||||
chantimemax = currenttime - 60 * atoi(name);
|
chantimemin = currenttime - 60 * atoi(name);
|
||||||
doall = 1;
|
doall = 1;
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
chantimemin = currenttime - 60 * atoi(name);
|
chantimemax = currenttime - 60 * atoi(name);
|
||||||
doall = 1;
|
doall = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sendnumeric(client, ERR_LISTSYNTAX);
|
sendnumeric(client, ERR_LISTSYNTAX);
|
||||||
error = 1;
|
error = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef LIST_USE_T
|
case 'T':
|
||||||
case 'T':
|
case 't':
|
||||||
case 't':
|
++name;
|
||||||
++name;
|
switch (*name++)
|
||||||
switch (*name++)
|
{
|
||||||
{
|
case '<':
|
||||||
case '<':
|
topictimemin = currenttime - 60 * atoi(name);
|
||||||
topictimemax =
|
doall = 1;
|
||||||
currenttime - 60 * atoi(name);
|
break;
|
||||||
doall = 1;
|
case '>':
|
||||||
break;
|
topictimemax = currenttime - 60 * atoi(name);
|
||||||
case '>':
|
doall = 1;
|
||||||
topictimemin =
|
break;
|
||||||
currenttime - 60 * atoi(name);
|
default:
|
||||||
doall = 1;
|
sendnumeric(client, ERR_LISTSYNTAX);
|
||||||
break;
|
error = 1;
|
||||||
default:
|
}
|
||||||
sendnumeric(client, ERR_LISTSYNTAX,
|
break;
|
||||||
"Bad list syntax, type /list ?");
|
default:
|
||||||
error = 1;
|
/* A channel, possibly with wildcards.
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default: /* A channel, possibly with wildcards.
|
|
||||||
* Thought for the future: Consider turning wildcard
|
* Thought for the future: Consider turning wildcard
|
||||||
* processing on the fly.
|
* processing on the fly.
|
||||||
* new syntax: !channelmask will tell ircd to ignore
|
* new syntax: !channelmask will tell ircd to ignore
|
||||||
|
@ -259,35 +255,38 @@ CMD_FUNC(cmd_list)
|
||||||
* channel even if any of the !channelmask masks
|
* channel even if any of the !channelmask masks
|
||||||
* matches it.
|
* matches it.
|
||||||
*/
|
*/
|
||||||
if (*name == '!')
|
if (*name == '!')
|
||||||
{
|
{
|
||||||
doall = 1;
|
/* Negative matching by name */
|
||||||
add_name_list(nolist, name + 1);
|
doall = 1;
|
||||||
}
|
add_name_list(nolist, name + 1);
|
||||||
else if (strchr(name, '*') || strchr(name, '?'))
|
}
|
||||||
{
|
else if (strchr(name, '*') || strchr(name, '?'))
|
||||||
doall = 1;
|
{
|
||||||
add_name_list(yeslist, name);
|
/* Channel with wildcards */
|
||||||
}
|
doall = 1;
|
||||||
else /* Just a normal channel */
|
add_name_list(yeslist, name);
|
||||||
{
|
}
|
||||||
channel = find_channel(name);
|
else
|
||||||
if (channel && (ShowChannel(client, channel) || ValidatePermissionsForPath("channel:see:list:secret",client,NULL,channel,NULL))) {
|
{
|
||||||
modebuf[0] = '[';
|
/* A specific channel name without wildcards */
|
||||||
channel_modes(client, modebuf+1, parabuf, sizeof(modebuf)-1, sizeof(parabuf), channel, 0);
|
channel = find_channel(name);
|
||||||
if (modebuf[2] == '\0')
|
if (channel && (ShowChannel(client, channel) || ValidatePermissionsForPath("channel:see:list:secret",client,NULL,channel,NULL)))
|
||||||
modebuf[0] = '\0';
|
{
|
||||||
else
|
modebuf[0] = '[';
|
||||||
strlcat(modebuf, "]", sizeof modebuf);
|
channel_modes(client, modebuf+1, parabuf, sizeof(modebuf)-1, sizeof(parabuf), channel, 0);
|
||||||
sendnumeric(client, RPL_LIST,
|
|
||||||
name, channel->users,
|
if (modebuf[2] == '\0')
|
||||||
modebuf,
|
modebuf[0] = '\0';
|
||||||
(channel->topic ? channel->topic :
|
else
|
||||||
""));
|
strlcat(modebuf, "]", sizeof modebuf);
|
||||||
}
|
|
||||||
}
|
sendnumeric(client, RPL_LIST, name, channel->users, modebuf,
|
||||||
} /* switch */
|
channel->topic ? channel->topic : "");
|
||||||
} /* while */
|
}
|
||||||
|
}
|
||||||
|
} /* switch */
|
||||||
|
} /* for */
|
||||||
|
|
||||||
if (doall)
|
if (doall)
|
||||||
{
|
{
|
||||||
|
@ -335,7 +334,7 @@ int send_list(Client *client)
|
||||||
* choice of numsend. -Rak
|
* choice of numsend. -Rak
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Begin of /list? then send official channels. */
|
/* Begin of /LIST? then send official channels first. */
|
||||||
if ((lopt->starthash == 0) && conf_offchans)
|
if ((lopt->starthash == 0) && conf_offchans)
|
||||||
{
|
{
|
||||||
ConfigItem_offchans *x;
|
ConfigItem_offchans *x;
|
||||||
|
@ -343,18 +342,15 @@ int send_list(Client *client)
|
||||||
{
|
{
|
||||||
if (find_channel(x->name))
|
if (find_channel(x->name))
|
||||||
continue; /* exists, >0 users.. will be sent later */
|
continue; /* exists, >0 users.. will be sent later */
|
||||||
sendnumeric(client, RPL_LIST, x->name,
|
sendnumeric(client, RPL_LIST, x->name, 0, "",
|
||||||
0,
|
x->topic ? x->topic : "");
|
||||||
"",
|
|
||||||
x->topic ? x->topic : "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (hashnum = lopt->starthash; hashnum < CHAN_HASH_TABLE_SIZE; hashnum++)
|
for (hashnum = lopt->starthash; hashnum < CHAN_HASH_TABLE_SIZE; hashnum++)
|
||||||
{
|
{
|
||||||
if (numsend > 0)
|
if (numsend > 0)
|
||||||
for (channel = hash_get_chan_bucket(hashnum);
|
for (channel = hash_get_chan_bucket(hashnum); channel; channel = channel->hnextch)
|
||||||
channel; channel = channel->hnextch)
|
|
||||||
{
|
{
|
||||||
if (SecretChannel(channel)
|
if (SecretChannel(channel)
|
||||||
&& !IsMember(client, channel)
|
&& !IsMember(client, channel)
|
||||||
|
@ -373,15 +369,13 @@ int send_list(Client *client)
|
||||||
if ((!lopt->showall))
|
if ((!lopt->showall))
|
||||||
{
|
{
|
||||||
/* User count must be in range */
|
/* User count must be in range */
|
||||||
if ((channel->users < lopt->usermin) ||
|
if ((channel->users < lopt->usermin) ||
|
||||||
((lopt->usermax >= 0) && (channel->users >
|
((lopt->usermax >= 0) && (channel->users > lopt->usermax)))
|
||||||
lopt->usermax)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Creation time must be in range */
|
/* Creation time must be in range */
|
||||||
if ((channel->creationtime && (channel->creationtime <
|
if ((channel->creationtime && (channel->creationtime < lopt->chantimemin)) ||
|
||||||
lopt->chantimemin)) || (channel->creationtime >
|
(channel->creationtime > lopt->chantimemax))
|
||||||
lopt->chantimemax))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Topic time must be in range */
|
/* Topic time must be in range */
|
||||||
|
@ -432,7 +426,7 @@ int send_list(Client *client)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We've exceeded the limit on the number of channels to send back
|
* We've exceeded the limit on the number of channels to send back
|
||||||
* at once.
|
* at once.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,6 +26,22 @@ CMD_FUNC(cmd_map);
|
||||||
|
|
||||||
#define MSG_MAP "MAP"
|
#define MSG_MAP "MAP"
|
||||||
|
|
||||||
|
static int lmax = 0;
|
||||||
|
static int umax = 0;
|
||||||
|
|
||||||
|
static int dcount(int n)
|
||||||
|
{
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
while (n != 0)
|
||||||
|
{
|
||||||
|
n = n/10;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
ModuleHeader MOD_HEADER
|
ModuleHeader MOD_HEADER
|
||||||
= {
|
= {
|
||||||
"map",
|
"map",
|
||||||
|
@ -70,8 +86,24 @@ static void dump_map(Client *client, Client *server, char *mask, int prompt_leng
|
||||||
sendnumeric(client, RPL_MAPMORE, prompt, length, server->name);
|
sendnumeric(client, RPL_MAPMORE, prompt, length, server->name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sendnumeric(client, RPL_MAP, prompt,
|
char tbuf[256];
|
||||||
length, server->name, server->server->users, IsOper(client) ? server->id : "");
|
char sid[10];
|
||||||
|
int len = length - strlen(server->name) + 1;
|
||||||
|
|
||||||
|
if (len < 0)
|
||||||
|
len = 0;
|
||||||
|
if (len > 255)
|
||||||
|
len = 255;
|
||||||
|
|
||||||
|
tbuf[len--] = '\0';
|
||||||
|
while (len >= 0)
|
||||||
|
tbuf[len--] = '-';
|
||||||
|
if (IsOper(client))
|
||||||
|
snprintf(sid, sizeof(sid), " [%s]", server->id);
|
||||||
|
sendnumeric(client, RPL_MAP, prompt, server->name, tbuf, umax,
|
||||||
|
server->server->users, (double)(lmax < 10) ? 4 : (lmax == 100) ? 6 : 5,
|
||||||
|
(server->server->users * 100.0 / irccounts.clients),
|
||||||
|
IsOper(client) ? sid : "");
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,12 +147,25 @@ static void dump_map(Client *client, Client *server, char *mask, int prompt_leng
|
||||||
void dump_flat_map(Client *client, Client *server, int length)
|
void dump_flat_map(Client *client, Client *server, int length)
|
||||||
{
|
{
|
||||||
char buf[4];
|
char buf[4];
|
||||||
|
char tbuf[256];
|
||||||
Client *acptr;
|
Client *acptr;
|
||||||
int cnt = 0, hide_ulines;
|
int cnt = 0, len = 0, hide_ulines;
|
||||||
|
|
||||||
hide_ulines = (HIDE_ULINES && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL)) ? 1 : 0;
|
hide_ulines = (HIDE_ULINES && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL)) ? 1 : 0;
|
||||||
|
|
||||||
sendnumeric(client, RPL_MAP, "", length, server->name, server->server->users, "");
|
len = length - strlen(server->name) + 3;
|
||||||
|
if (len < 0)
|
||||||
|
len = 0;
|
||||||
|
if (len > 255)
|
||||||
|
len = 255;
|
||||||
|
|
||||||
|
tbuf[len--] = '\0';
|
||||||
|
while (len >= 0)
|
||||||
|
tbuf[len--] = '-';
|
||||||
|
|
||||||
|
sendnumeric(client, RPL_MAP, "", server->name, tbuf, umax, server->server->users,
|
||||||
|
(lmax < 10) ? 4 : (lmax == 100) ? 6 : 5,
|
||||||
|
(server->server->users * 100.0 / irccounts.clients), "");
|
||||||
|
|
||||||
list_for_each_entry(acptr, &global_server_list, client_node)
|
list_for_each_entry(acptr, &global_server_list, client_node)
|
||||||
{
|
{
|
||||||
|
@ -136,7 +181,20 @@ void dump_flat_map(Client *client, Client *server, int length)
|
||||||
continue;
|
continue;
|
||||||
if (--cnt == 0)
|
if (--cnt == 0)
|
||||||
*buf = '`';
|
*buf = '`';
|
||||||
sendnumeric(client, RPL_MAP, buf, length-2, acptr->name, acptr->server->users, "");
|
|
||||||
|
len = length - strlen(acptr->name) + 1;
|
||||||
|
if (len < 0)
|
||||||
|
len = 0;
|
||||||
|
if (len > 255)
|
||||||
|
len = 255;
|
||||||
|
|
||||||
|
tbuf[len--] = '\0';
|
||||||
|
while (len >= 0)
|
||||||
|
tbuf[len--] = '-';
|
||||||
|
|
||||||
|
sendnumeric(client, RPL_MAP, buf, acptr->name, tbuf, umax, acptr->server->users,
|
||||||
|
(lmax < 10) ? 4 : (lmax == 100) ? 6 : 5,
|
||||||
|
(acptr->server->users * 100.0 / irccounts.clients), "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,14 +208,23 @@ CMD_FUNC(cmd_map)
|
||||||
{
|
{
|
||||||
Client *acptr;
|
Client *acptr;
|
||||||
int longest = strlen(me.name);
|
int longest = strlen(me.name);
|
||||||
|
float avg_users;
|
||||||
|
|
||||||
|
umax = 0;
|
||||||
|
lmax = 0;
|
||||||
|
|
||||||
if (parc < 2)
|
if (parc < 2)
|
||||||
parv[1] = "*";
|
parv[1] = "*";
|
||||||
|
|
||||||
list_for_each_entry(acptr, &global_server_list, client_node)
|
list_for_each_entry(acptr, &global_server_list, client_node)
|
||||||
{
|
{
|
||||||
|
int perc = (acptr->server->users * 100 / irccounts.clients);
|
||||||
if ((strlen(acptr->name) + acptr->hopcount * 2) > longest)
|
if ((strlen(acptr->name) + acptr->hopcount * 2) > longest)
|
||||||
longest = strlen(acptr->name) + acptr->hopcount * 2;
|
longest = strlen(acptr->name) + acptr->hopcount * 2;
|
||||||
|
if (lmax < perc)
|
||||||
|
lmax = perc;
|
||||||
|
if (umax < dcount(acptr->server->users))
|
||||||
|
umax = dcount(acptr->server->users);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (longest > 60)
|
if (longest > 60)
|
||||||
|
@ -169,5 +236,8 @@ CMD_FUNC(cmd_map)
|
||||||
else
|
else
|
||||||
dump_map(client, &me, "*", 0, longest);
|
dump_map(client, &me, "*", 0, longest);
|
||||||
|
|
||||||
|
avg_users = irccounts.clients * 1.0 / irccounts.servers;
|
||||||
|
sendnumeric(client, RPL_MAPUSERS, irccounts.servers, (irccounts.servers > 1 ? "s" : ""), irccounts.clients,
|
||||||
|
(irccounts.clients > 1 ? "s" : ""), avg_users);
|
||||||
sendnumeric(client, RPL_MAPEND);
|
sendnumeric(client, RPL_MAPEND);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ long CAP_MESSAGE_TAGS = 0; /**< Looked up at MOD_LOAD, may stay 0 if message-tag
|
||||||
ModuleHeader MOD_HEADER
|
ModuleHeader MOD_HEADER
|
||||||
= {
|
= {
|
||||||
"message", /* Name of module */
|
"message", /* Name of module */
|
||||||
"5.0", /* Version */
|
"6.0.2", /* Version */
|
||||||
"private message and notice", /* Short description of module */
|
"private message and notice", /* Short description of module */
|
||||||
"UnrealIRCd Team",
|
"UnrealIRCd Team",
|
||||||
"unrealircd-6",
|
"unrealircd-6",
|
||||||
|
@ -318,7 +318,7 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, const char *p
|
||||||
*/
|
*/
|
||||||
if (IsDead(client))
|
if (IsDead(client))
|
||||||
return;
|
return;
|
||||||
if (!IsDead(client) && (sendtype != SEND_TYPE_NOTICE) && errmsg)
|
if (!IsDead(client) && (sendtype != SEND_TYPE_NOTICE) && !BadPtr(errmsg))
|
||||||
sendnumeric(client, ERR_CANNOTSENDTOCHAN, channel->name, errmsg, p2);
|
sendnumeric(client, ERR_CANNOTSENDTOCHAN, channel->name, errmsg, p2);
|
||||||
continue; /* skip delivery to this target */
|
continue; /* skip delivery to this target */
|
||||||
}
|
}
|
||||||
|
@ -423,7 +423,7 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, const char *p
|
||||||
/* Message is discarded */
|
/* Message is discarded */
|
||||||
if (IsDead(client))
|
if (IsDead(client))
|
||||||
return;
|
return;
|
||||||
if ((sendtype != SEND_TYPE_NOTICE) && errmsg)
|
if ((sendtype != SEND_TYPE_NOTICE) && !BadPtr(errmsg))
|
||||||
sendnumeric(client, ERR_CANTSENDTOUSER, target->name, errmsg);
|
sendnumeric(client, ERR_CANTSENDTOUSER, target->name, errmsg);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
|
|
@ -370,28 +370,19 @@ void _do_mode(Channel *channel, Client *client, MessageTag *recv_mtags, int parc
|
||||||
":%s MODE %s %s %s",
|
":%s MODE %s %s %s",
|
||||||
client->name, channel->name, modebuf, parabuf);
|
client->name, channel->name, modebuf, parabuf);
|
||||||
|
|
||||||
if (IsServer(client) && sendts != -1)
|
if (IsServer(client) || IsMe(client))
|
||||||
{
|
{
|
||||||
sendto_server(client, 0, 0, mtags,
|
sendto_server(client, 0, 0, mtags,
|
||||||
":%s MODE %s %s %s %lld",
|
":%s MODE %s %s %s %lld",
|
||||||
client->id, channel->name,
|
client->id, channel->name,
|
||||||
modebuf, parabuf,
|
modebuf, parabuf,
|
||||||
(long long)sendts);
|
(sendts != -1) ? (long long)sendts : 0LL);
|
||||||
} else
|
|
||||||
if (samode && IsMe(client))
|
|
||||||
{
|
|
||||||
/* SAMODE is a special case: always send a TS of 0 (omitting TS==desync) */
|
|
||||||
sendto_server(client, 0, 0, mtags,
|
|
||||||
":%s MODE %s %s %s 0",
|
|
||||||
client->id, channel->name,
|
|
||||||
modebuf, parabuf);
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
sendto_server(client, 0, 0, mtags,
|
sendto_server(client, 0, 0, mtags,
|
||||||
":%s MODE %s %s %s",
|
":%s MODE %s %s %s",
|
||||||
client->id, channel->name,
|
client->id, channel->name,
|
||||||
modebuf, parabuf);
|
modebuf, parabuf);
|
||||||
/* tell them it's not a timestamp, in case the last param is a number. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MyConnect(client))
|
if (MyConnect(client))
|
||||||
|
@ -1159,6 +1150,22 @@ CMD_FUNC(_cmd_umode)
|
||||||
goto def;
|
goto def;
|
||||||
case 't':
|
case 't':
|
||||||
case 'x':
|
case 'x':
|
||||||
|
/* set::anti-flood::vhost-flood */
|
||||||
|
if (MyUser(client))
|
||||||
|
{
|
||||||
|
if ((what == MODE_DEL) && !ValidatePermissionsForPath("immune:vhost-flood",client,NULL,NULL,NULL) &&
|
||||||
|
flood_limit_exceeded(client, FLD_VHOST))
|
||||||
|
{
|
||||||
|
/* Throttle... */
|
||||||
|
if (!modex_err)
|
||||||
|
{
|
||||||
|
sendnotice(client, "*** Setting -%c too fast. Please try again later.", *m);
|
||||||
|
modex_err = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (UHOST_ALLOWED)
|
switch (UHOST_ALLOWED)
|
||||||
{
|
{
|
||||||
case UHALLOW_ALWAYS:
|
case UHALLOW_ALWAYS:
|
||||||
|
|
|
@ -141,6 +141,7 @@ CMD_FUNC(reputationunperm);
|
||||||
int reputation_whois(Client *client, Client *target, NameValuePrioList **list);
|
int reputation_whois(Client *client, Client *target, NameValuePrioList **list);
|
||||||
int reputation_set_on_connect(Client *client);
|
int reputation_set_on_connect(Client *client);
|
||||||
int reputation_pre_lconnect(Client *client);
|
int reputation_pre_lconnect(Client *client);
|
||||||
|
int reputation_ip_change(Client *client, const char *oldip);
|
||||||
int reputation_connect_extinfo(Client *client, NameValuePrioList **list);
|
int reputation_connect_extinfo(Client *client, NameValuePrioList **list);
|
||||||
int reputation_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
|
int reputation_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
|
||||||
int reputation_config_run(ConfigFile *cf, ConfigEntry *ce, int type);
|
int reputation_config_run(ConfigFile *cf, ConfigEntry *ce, int type);
|
||||||
|
@ -192,6 +193,7 @@ MOD_INIT()
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, reputation_config_run);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, reputation_config_run);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_WHOIS, 0, reputation_whois);
|
HookAdd(modinfo->handle, HOOKTYPE_WHOIS, 0, reputation_whois);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_HANDSHAKE, 0, reputation_set_on_connect);
|
HookAdd(modinfo->handle, HOOKTYPE_HANDSHAKE, 0, reputation_set_on_connect);
|
||||||
|
HookAdd(modinfo->handle, HOOKTYPE_IP_CHANGE, 0, reputation_ip_change);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_PRE_LOCAL_CONNECT, 2000000000, reputation_pre_lconnect); /* (prio: last) */
|
HookAdd(modinfo->handle, HOOKTYPE_PRE_LOCAL_CONNECT, 2000000000, reputation_pre_lconnect); /* (prio: last) */
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_REMOTE_CONNECT, -1000000000, reputation_set_on_connect); /* (prio: near-first) */
|
HookAdd(modinfo->handle, HOOKTYPE_REMOTE_CONNECT, -1000000000, reputation_set_on_connect); /* (prio: near-first) */
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONNECT_EXTINFO, 0, reputation_connect_extinfo); /* (prio: near-first) */
|
HookAdd(modinfo->handle, HOOKTYPE_CONNECT_EXTINFO, 0, reputation_connect_extinfo); /* (prio: near-first) */
|
||||||
|
@ -804,6 +806,12 @@ int reputation_set_on_connect(Client *client)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int reputation_ip_change(Client *client, const char *oldip)
|
||||||
|
{
|
||||||
|
reputation_lookup_score_and_set(client);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int reputation_pre_lconnect(Client *client)
|
int reputation_pre_lconnect(Client *client)
|
||||||
{
|
{
|
||||||
/* User will likely be accepted. Inform other servers about the score
|
/* User will likely be accepted. Inform other servers about the score
|
||||||
|
|
|
@ -170,9 +170,9 @@ CMD_FUNC(cmd_sapart)
|
||||||
if (comment)
|
if (comment)
|
||||||
{
|
{
|
||||||
snprintf(commentx, sizeof(commentx), "SAPart: %s", comment);
|
snprintf(commentx, sizeof(commentx), "SAPart: %s", comment);
|
||||||
//sendnotice(target, "*** You were forced to part %s (%s)", request, commentx);
|
sendnotice(target, "*** You were forced to part %s (%s)", request, commentx);
|
||||||
} else {
|
} else {
|
||||||
//sendnotice(target, "*** You were forced to part %s", request);
|
sendnotice(target, "*** You were forced to part %s", request);
|
||||||
}
|
}
|
||||||
|
|
||||||
parv[0] = target->name; // nick
|
parv[0] = target->name; // nick
|
||||||
|
|
|
@ -158,5 +158,5 @@ CMD_FUNC(cmd_setname)
|
||||||
}
|
}
|
||||||
free_message_tags(mtags);
|
free_message_tags(mtags);
|
||||||
|
|
||||||
RunHook(HOOKTYPE_REALNAME_CHANGED, client, oldinfo);
|
RunHook(HOOKTYPE_REALNAME_CHANGE, client, oldinfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,17 +520,17 @@ int stats_command(Client *client, const char *para)
|
||||||
|
|
||||||
int stats_oper(Client *client, const char *para)
|
int stats_oper(Client *client, const char *para)
|
||||||
{
|
{
|
||||||
ConfigItem_oper *oper_p;
|
ConfigItem_oper *o;
|
||||||
ConfigItem_mask *m;
|
ConfigItem_mask *m;
|
||||||
|
|
||||||
for (oper_p = conf_oper; oper_p; oper_p = oper_p->next)
|
for (o = conf_oper; o; o = o->next)
|
||||||
{
|
{
|
||||||
for (m = oper_p->mask; m; m = m->next)
|
for (m = o->mask; m; m = m->next)
|
||||||
{
|
{
|
||||||
sendnumeric(client, RPL_STATSOLINE,
|
sendnumeric(client, RPL_STATSOLINE,
|
||||||
'O', m->mask, oper_p->name,
|
'O', m->mask, o->name,
|
||||||
"-",
|
o->operclass ? o->operclass: "",
|
||||||
oper_p->class->name? oper_p->class->name : "");
|
o->class->name ? o->class->name : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -540,11 +540,20 @@ static char *stats_port_helper(ConfigItem_listen *listener)
|
||||||
{
|
{
|
||||||
static char buf[256];
|
static char buf[256];
|
||||||
|
|
||||||
ircsnprintf(buf, sizeof(buf), "%s%s%s%s",
|
ircsnprintf(buf, sizeof(buf), "%s%s%s",
|
||||||
(listener->options & LISTENER_CLIENTSONLY)? "clientsonly ": "",
|
(listener->options & LISTENER_CLIENTSONLY)? "clientsonly ": "",
|
||||||
(listener->options & LISTENER_SERVERSONLY)? "serversonly ": "",
|
(listener->options & LISTENER_SERVERSONLY)? "serversonly ": "",
|
||||||
(listener->options & LISTENER_TLS)? "tls ": "",
|
(listener->options & LISTENER_DEFER_ACCEPT)? "defer-accept ": "");
|
||||||
!(listener->options & LISTENER_TLS)? "plaintext ": "");
|
|
||||||
|
/* And one of these.. */
|
||||||
|
if (listener->options & LISTENER_CONTROL)
|
||||||
|
strlcat(buf, "control ", sizeof(buf));
|
||||||
|
else if (listener->socket_type == SOCKET_TYPE_UNIX)
|
||||||
|
;
|
||||||
|
else if (listener->options & LISTENER_TLS)
|
||||||
|
strlcat(buf, "tls ", sizeof(buf));
|
||||||
|
else
|
||||||
|
strlcat(buf, "plaintext ", sizeof(buf));
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,13 +567,22 @@ int stats_port(Client *client, const char *para)
|
||||||
continue;
|
continue;
|
||||||
if ((listener->options & LISTENER_SERVERSONLY) && !ValidatePermissionsForPath("server:info:stats",client,NULL,NULL,NULL))
|
if ((listener->options & LISTENER_SERVERSONLY) && !ValidatePermissionsForPath("server:info:stats",client,NULL,NULL,NULL))
|
||||||
continue;
|
continue;
|
||||||
sendnotice(client, "*** Listener on %s:%i (%s): has %i client(s), options: %s %s",
|
if (listener->socket_type == SOCKET_TYPE_UNIX)
|
||||||
listener->ip,
|
{
|
||||||
listener->port,
|
sendnotice(client, "*** Listener on %s (UNIX): has %i client(s), options: %s %s",
|
||||||
listener->ipv6 ? "IPv6" : "IPv4",
|
listener->file,
|
||||||
listener->clients,
|
listener->clients,
|
||||||
stats_port_helper(listener),
|
stats_port_helper(listener),
|
||||||
listener->flag.temporary ? "[TEMPORARY]" : "");
|
listener->flag.temporary ? "[TEMPORARY]" : "");
|
||||||
|
} else {
|
||||||
|
sendnotice(client, "*** Listener on %s:%i (%s): has %i client(s), options: %s %s",
|
||||||
|
listener->ip,
|
||||||
|
listener->port,
|
||||||
|
listener->socket_type == SOCKET_TYPE_IPV6 ? "IPv6" : "IPv4",
|
||||||
|
listener->clients,
|
||||||
|
stats_port_helper(listener),
|
||||||
|
listener->flag.temporary ? "[TEMPORARY]" : "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ void unban_user(Client *client, Channel *channel, Client *acptr, char chmode)
|
||||||
}
|
}
|
||||||
else if (chmode != 'I' && *ban->banstr == '~' && (extban = findmod_by_bantype(ban->banstr, &nextbanstr)))
|
else if (chmode != 'I' && *ban->banstr == '~' && (extban = findmod_by_bantype(ban->banstr, &nextbanstr)))
|
||||||
{
|
{
|
||||||
if ((extban->options & EXTBOPT_CHSVSMODE) && (extban->is_banned_events & b->ban_check_types))
|
if (extban->is_banned_events & b->ban_check_types)
|
||||||
{
|
{
|
||||||
b->banstr = nextbanstr;
|
b->banstr = nextbanstr;
|
||||||
if (extban->is_banned(b))
|
if (extban->is_banned(b))
|
||||||
|
@ -176,7 +176,7 @@ void clear_bans(Client *client, Channel *channel, char chmode)
|
||||||
bnext = ban->next;
|
bnext = ban->next;
|
||||||
if (chmode != 'I' && (*ban->banstr == '~') && (extban = findmod_by_bantype(ban->banstr, NULL)))
|
if (chmode != 'I' && (*ban->banstr == '~') && (extban = findmod_by_bantype(ban->banstr, NULL)))
|
||||||
{
|
{
|
||||||
if (!(extban->options & EXTBOPT_CHSVSMODE))
|
if (!(extban->is_banned_events & BANCHK_JOIN))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
add_send_mode_param(channel, client, '-', chmode, ban->banstr);
|
add_send_mode_param(channel, client, '-', chmode, ban->banstr);
|
||||||
|
@ -298,7 +298,7 @@ void channel_svsmode(Client *client, int parc, const char *parv[])
|
||||||
sendto_channel(channel, client, client, 0, 0, SEND_LOCAL, mtags,
|
sendto_channel(channel, client, client, 0, 0, SEND_LOCAL, mtags,
|
||||||
":%s MODE %s %s %s",
|
":%s MODE %s %s %s",
|
||||||
client->name, channel->name, modebuf, parabuf);
|
client->name, channel->name, modebuf, parabuf);
|
||||||
sendto_server(NULL, 0, 0, mtags, ":%s MODE %s %s %s", client->id, channel->name, modebuf, parabuf);
|
sendto_server(NULL, 0, 0, mtags, ":%s MODE %s %s %s%s", client->id, channel->name, modebuf, parabuf, IsServer(client)?" 0":"");
|
||||||
|
|
||||||
/* Activate this hook just like cmd_mode.c */
|
/* Activate this hook just like cmd_mode.c */
|
||||||
RunHook(HOOKTYPE_REMOTE_CHANMODE, client, channel, mtags, modebuf, parabuf, 0, 0, &destroy_channel);
|
RunHook(HOOKTYPE_REMOTE_CHANMODE, client, channel, mtags, modebuf, parabuf, 0, 0, &destroy_channel);
|
||||||
|
@ -615,7 +615,7 @@ void add_send_mode_param(Channel *channel, Client *from, char what, char mode, c
|
||||||
sendto_channel(channel, from, from, 0, 0, SEND_LOCAL, mtags,
|
sendto_channel(channel, from, from, 0, 0, SEND_LOCAL, mtags,
|
||||||
":%s MODE %s %s %s",
|
":%s MODE %s %s %s",
|
||||||
from->name, channel->name, modebuf, parabuf);
|
from->name, channel->name, modebuf, parabuf);
|
||||||
sendto_server(NULL, 0, 0, mtags, ":%s MODE %s %s %s", from->id, channel->name, modebuf, parabuf);
|
sendto_server(NULL, 0, 0, mtags, ":%s MODE %s %s %s%s", from->id, channel->name, modebuf, parabuf, IsServer(from)?" 0":"");
|
||||||
free_message_tags(mtags);
|
free_message_tags(mtags);
|
||||||
send = 0;
|
send = 0;
|
||||||
*parabuf = 0;
|
*parabuf = 0;
|
||||||
|
|
|
@ -41,6 +41,7 @@ int tkl_config_test_except(ConfigFile *, ConfigEntry *, int, int *);
|
||||||
int tkl_config_run_except(ConfigFile *, ConfigEntry *, int);
|
int tkl_config_run_except(ConfigFile *, ConfigEntry *, int);
|
||||||
int tkl_config_test_set(ConfigFile *, ConfigEntry *, int, int *);
|
int tkl_config_test_set(ConfigFile *, ConfigEntry *, int, int *);
|
||||||
int tkl_config_run_set(ConfigFile *, ConfigEntry *, int);
|
int tkl_config_run_set(ConfigFile *, ConfigEntry *, int);
|
||||||
|
int tkl_ip_change(Client *client, const char *oldip);
|
||||||
CMD_FUNC(cmd_gline);
|
CMD_FUNC(cmd_gline);
|
||||||
CMD_FUNC(cmd_shun);
|
CMD_FUNC(cmd_shun);
|
||||||
CMD_FUNC(cmd_tempshun);
|
CMD_FUNC(cmd_tempshun);
|
||||||
|
@ -213,6 +214,7 @@ MOD_INIT()
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_ban);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_ban);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_except);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_except);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_set);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_set);
|
||||||
|
HookAdd(modinfo->handle, HOOKTYPE_IP_CHANGE, 2000000000, tkl_ip_change);
|
||||||
CommandAdd(modinfo->handle, "GLINE", cmd_gline, 3, CMD_OPER);
|
CommandAdd(modinfo->handle, "GLINE", cmd_gline, 3, CMD_OPER);
|
||||||
CommandAdd(modinfo->handle, "SHUN", cmd_shun, 3, CMD_OPER);
|
CommandAdd(modinfo->handle, "SHUN", cmd_shun, 3, CMD_OPER);
|
||||||
CommandAdd(modinfo->handle, "TEMPSHUN", cmd_tempshun, 2, CMD_OPER);
|
CommandAdd(modinfo->handle, "TEMPSHUN", cmd_tempshun, 2, CMD_OPER);
|
||||||
|
@ -952,6 +954,12 @@ char *spamfilter_id(TKL *tk)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tkl_ip_change(Client *client, const char *oldip)
|
||||||
|
{
|
||||||
|
check_banned(client, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** GLINE - Global kline.
|
/** GLINE - Global kline.
|
||||||
** Syntax: /gline [+|-]u@h mask time :reason
|
** Syntax: /gline [+|-]u@h mask time :reason
|
||||||
**
|
**
|
||||||
|
@ -4772,23 +4780,15 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
/* We have a match! */
|
/* We have a match! But.. perhaps it's on the exceptions list? */
|
||||||
char destinationbuf[48];
|
|
||||||
|
|
||||||
if (destination) {
|
|
||||||
destinationbuf[0] = ' ';
|
|
||||||
strlcpy(destinationbuf+1, destination, sizeof(destinationbuf)-1); /* cut it off */
|
|
||||||
} else
|
|
||||||
destinationbuf[0] = '\0';
|
|
||||||
|
|
||||||
/* Hold on.. perhaps it's on the exceptions list... */
|
|
||||||
if (!winner_tkl && destination && target_is_spamexcept(destination))
|
if (!winner_tkl && destination && target_is_spamexcept(destination))
|
||||||
return 0; /* No problem! */
|
return 0; /* No problem! */
|
||||||
|
|
||||||
unreal_log(ULOG_INFO, "tkl", "SPAMFILTER_MATCH", client,
|
unreal_log(ULOG_INFO, "tkl", "SPAMFILTER_MATCH", client,
|
||||||
"[Spamfilter] $client.details matches filter '$tkl': [cmd: $command$destination: '$str'] [reason: $tkl.reason] [action: $tkl.ban_action]",
|
"[Spamfilter] $client.details matches filter '$tkl': [cmd: $command$_space$destination: '$str'] [reason: $tkl.reason] [action: $tkl.ban_action]",
|
||||||
log_data_tkl("tkl", tkl),
|
log_data_tkl("tkl", tkl),
|
||||||
log_data_string("command", cmd),
|
log_data_string("command", cmd),
|
||||||
|
log_data_string("_space", destination ? " " : ""),
|
||||||
log_data_string("destination", destination ? destination : ""),
|
log_data_string("destination", destination ? destination : ""),
|
||||||
log_data_string("str", str));
|
log_data_string("str", str));
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
|
|
||||||
ModDataInfo *watchCounterMD;
|
ModDataInfo *watchCounterMD;
|
||||||
ModDataInfo *watchListMD;
|
ModDataInfo *watchListMD;
|
||||||
static Watch *watchTable[WATCH_HASH_TABLE_SIZE];
|
|
||||||
static int watch_initialized = 0;
|
static Watch **watchTable = NULL;
|
||||||
static char siphashkey_watch[SIPHASH_KEY_LENGTH];
|
static char *siphashkey_watch = NULL;
|
||||||
|
|
||||||
void dummy_free(ModData *md);
|
void dummy_free(ModData *md);
|
||||||
void watch_free(ModData *md);
|
void watch_free(ModData *md);
|
||||||
|
@ -47,8 +47,8 @@ uint64_t hash_watch_nick_name(const char *name);
|
||||||
ModuleHeader MOD_HEADER
|
ModuleHeader MOD_HEADER
|
||||||
= {
|
= {
|
||||||
"watch-backend",
|
"watch-backend",
|
||||||
"5.0",
|
"6.0.3",
|
||||||
"backend for /watch",
|
"backend for /WATCH",
|
||||||
"UnrealIRCd Team",
|
"UnrealIRCd Team",
|
||||||
"unrealircd-6",
|
"unrealircd-6",
|
||||||
};
|
};
|
||||||
|
@ -65,20 +65,28 @@ MOD_TEST()
|
||||||
return MOD_SUCCESS;
|
return MOD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void watch_generic_free(ModData *m)
|
||||||
|
{
|
||||||
|
safe_free(m->ptr);
|
||||||
|
}
|
||||||
|
|
||||||
MOD_INIT()
|
MOD_INIT()
|
||||||
{
|
{
|
||||||
ModDataInfo mreq;
|
ModDataInfo mreq;
|
||||||
|
|
||||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||||
ModuleSetOptions(modinfo->handle, MOD_OPT_PERM_RELOADABLE, 1); /* or do a complex memory freeing algorithm instead */
|
ModuleSetOptions(modinfo->handle, MOD_OPT_PERM_RELOADABLE, 1); /* or do a complex memory freeing algorithm instead */
|
||||||
|
|
||||||
if (!watch_initialized)
|
LoadPersistentPointer(modinfo, siphashkey_watch, watch_generic_free);
|
||||||
|
if (siphashkey_watch == NULL)
|
||||||
{
|
{
|
||||||
memset(watchTable, 0, sizeof(watchTable));
|
siphashkey_watch = safe_alloc(SIPHASH_KEY_LENGTH);
|
||||||
siphash_generate_key(siphashkey_watch);
|
siphash_generate_key(siphashkey_watch);
|
||||||
watch_initialized = 1;
|
|
||||||
}
|
}
|
||||||
|
LoadPersistentPointer(modinfo, watchTable, watch_generic_free);
|
||||||
|
if (watchTable == NULL)
|
||||||
|
watchTable = safe_alloc(sizeof(Watch) * WATCH_HASH_TABLE_SIZE);
|
||||||
|
|
||||||
memset(&mreq, 0 , sizeof(mreq));
|
memset(&mreq, 0 , sizeof(mreq));
|
||||||
mreq.type = MODDATATYPE_LOCAL_CLIENT;
|
mreq.type = MODDATATYPE_LOCAL_CLIENT;
|
||||||
mreq.name = "watchCount",
|
mreq.name = "watchCount",
|
||||||
|
@ -113,6 +121,8 @@ MOD_LOAD()
|
||||||
|
|
||||||
MOD_UNLOAD()
|
MOD_UNLOAD()
|
||||||
{
|
{
|
||||||
|
SavePersistentPointer(modinfo, siphashkey_watch);
|
||||||
|
SavePersistentPointer(modinfo, watchTable);
|
||||||
return MOD_SUCCESS;
|
return MOD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,13 +161,13 @@ int _watch_add(char *nick, Client *client, int flags)
|
||||||
hashv = hash_watch_nick_name(nick);
|
hashv = hash_watch_nick_name(nick);
|
||||||
|
|
||||||
/* Find the right nick (header) in the bucket, or NULL... */
|
/* Find the right nick (header) in the bucket, or NULL... */
|
||||||
if ((watch = (Watch *)watchTable[hashv]))
|
if ((watch = watchTable[hashv]))
|
||||||
while (watch && mycmp(watch->nick, nick))
|
while (watch && mycmp(watch->nick, nick))
|
||||||
watch = watch->hnext;
|
watch = watch->hnext;
|
||||||
|
|
||||||
/* If found NULL (no header for this nick), make one... */
|
/* If found NULL (no header for this nick), make one... */
|
||||||
if (!watch) {
|
if (!watch) {
|
||||||
watch = (Watch *)safe_alloc(sizeof(Watch)+strlen(nick));
|
watch = safe_alloc(sizeof(Watch)+strlen(nick));
|
||||||
watch->lasttime = timeofday;
|
watch->lasttime = timeofday;
|
||||||
strcpy(watch->nick, nick);
|
strcpy(watch->nick, nick);
|
||||||
|
|
||||||
|
@ -203,7 +213,7 @@ int _watch_check(Client *client, int event, int (*watch_notify)(Client *client,
|
||||||
hashv = hash_watch_nick_name(client->name);
|
hashv = hash_watch_nick_name(client->name);
|
||||||
|
|
||||||
/* Find the right header in this bucket */
|
/* Find the right header in this bucket */
|
||||||
if ((watch = (Watch *)watchTable[hashv]))
|
if ((watch = watchTable[hashv]))
|
||||||
while (watch && mycmp(watch->nick, client->name))
|
while (watch && mycmp(watch->nick, client->name))
|
||||||
watch = watch->hnext;
|
watch = watch->hnext;
|
||||||
if (!watch)
|
if (!watch)
|
||||||
|
@ -231,7 +241,7 @@ Watch *_watch_get(char *nick)
|
||||||
|
|
||||||
hashv = hash_watch_nick_name(nick);
|
hashv = hash_watch_nick_name(nick);
|
||||||
|
|
||||||
if ((watch = (Watch *)watchTable[hashv]))
|
if ((watch = watchTable[hashv]))
|
||||||
while (watch && mycmp(watch->nick, nick))
|
while (watch && mycmp(watch->nick, nick))
|
||||||
watch = watch->hnext;
|
watch = watch->hnext;
|
||||||
|
|
||||||
|
|
|
@ -336,6 +336,7 @@ ConfigItem_webirc *find_webirc(Client *client, const char *password, WEBIRCType
|
||||||
/* Does the CGI:IRC host spoofing work */
|
/* Does the CGI:IRC host spoofing work */
|
||||||
void dowebirc(Client *client, const char *ip, const char *host, const char *options)
|
void dowebirc(Client *client, const char *ip, const char *host, const char *options)
|
||||||
{
|
{
|
||||||
|
char oldip[64];
|
||||||
char scratch[64];
|
char scratch[64];
|
||||||
|
|
||||||
if (IsWEBIRC(client))
|
if (IsWEBIRC(client))
|
||||||
|
@ -357,6 +358,7 @@ void dowebirc(Client *client, const char *ip, const char *host, const char *opti
|
||||||
}
|
}
|
||||||
|
|
||||||
/* STEP 2: Update GetIP() */
|
/* STEP 2: Update GetIP() */
|
||||||
|
strlcpy(oldip, client->ip, sizeof(oldip));
|
||||||
safe_strdup(client->ip, ip);
|
safe_strdup(client->ip, ip);
|
||||||
|
|
||||||
/* STEP 3: Update client->local->hostp */
|
/* STEP 3: Update client->local->hostp */
|
||||||
|
@ -397,15 +399,7 @@ void dowebirc(Client *client, const char *ip, const char *host, const char *opti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* blacklist_start_check() */
|
RunHook(HOOKTYPE_IP_CHANGE, client, oldip);
|
||||||
if (RCallbacks[CALLBACKTYPE_BLACKLIST_CHECK] != NULL)
|
|
||||||
RCallbacks[CALLBACKTYPE_BLACKLIST_CHECK]->func.intfunc(client);
|
|
||||||
|
|
||||||
/* Check (g)zlines right now; these are normally checked upon accept(),
|
|
||||||
* but since we know the IP only now after PASS/WEBIRC, we have to check
|
|
||||||
* here again...
|
|
||||||
*/
|
|
||||||
check_banned(client, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WEBIRC <pass> "cgiirc" <hostname> <ip> [:option1 [option2...]]*/
|
/* WEBIRC <pass> "cgiirc" <hostname> <ip> [:option1 [option2...]]*/
|
||||||
|
|
|
@ -686,6 +686,9 @@ int websocket_handshake_valid(Client *client)
|
||||||
}
|
}
|
||||||
if (WSU(client)->forwarded)
|
if (WSU(client)->forwarded)
|
||||||
{
|
{
|
||||||
|
struct HTTPForwardedHeader *forwarded;
|
||||||
|
char oldip[64];
|
||||||
|
|
||||||
/* check for source ip */
|
/* check for source ip */
|
||||||
if (BadPtr(client->local->listener->websocket_forward) || !websocket_ip_compare(client->local->listener->websocket_forward, client->ip))
|
if (BadPtr(client->local->listener->websocket_forward) || !websocket_ip_compare(client->local->listener->websocket_forward, client->ip))
|
||||||
{
|
{
|
||||||
|
@ -694,7 +697,6 @@ int websocket_handshake_valid(Client *client)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* parse the header */
|
/* parse the header */
|
||||||
struct HTTPForwardedHeader *forwarded;
|
|
||||||
forwarded = websocket_parse_forwarded_header(WSU(client)->forwarded);
|
forwarded = websocket_parse_forwarded_header(WSU(client)->forwarded);
|
||||||
/* check header values */
|
/* check header values */
|
||||||
if (!is_valid_ip(forwarded->ip))
|
if (!is_valid_ip(forwarded->ip))
|
||||||
|
@ -705,6 +707,7 @@ int websocket_handshake_valid(Client *client)
|
||||||
}
|
}
|
||||||
/* store data */
|
/* store data */
|
||||||
WSU(client)->secure = forwarded->secure;
|
WSU(client)->secure = forwarded->secure;
|
||||||
|
strlcpy(oldip, client->ip, sizeof(oldip));
|
||||||
safe_strdup(client->ip, forwarded->ip);
|
safe_strdup(client->ip, forwarded->ip);
|
||||||
/* Update client->local->hostp */
|
/* Update client->local->hostp */
|
||||||
strlcpy(client->local->sockhost, forwarded->ip, sizeof(client->local->sockhost)); /* in case dns lookup fails or is disabled */
|
strlcpy(client->local->sockhost, forwarded->ip, sizeof(client->local->sockhost)); /* in case dns lookup fails or is disabled */
|
||||||
|
@ -733,15 +736,7 @@ int websocket_handshake_valid(Client *client)
|
||||||
/* Race condition detected, DNS has been done, continue with auth */
|
/* Race condition detected, DNS has been done, continue with auth */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* blacklist_start_check() */
|
RunHook(HOOKTYPE_IP_CHANGE, client, oldip);
|
||||||
if (RCallbacks[CALLBACKTYPE_BLACKLIST_CHECK] != NULL)
|
|
||||||
RCallbacks[CALLBACKTYPE_BLACKLIST_CHECK]->func.intfunc(client);
|
|
||||||
|
|
||||||
/* Check (g)zlines right now; these are normally checked upon accept(),
|
|
||||||
* but since we know the IP only now after PASS/WEBIRC, we have to check
|
|
||||||
* here again...
|
|
||||||
*/
|
|
||||||
check_banned(client, 0);
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ ModuleHeader MOD_HEADER
|
||||||
#define WMATCH_ACCOUNT 0x0040
|
#define WMATCH_ACCOUNT 0x0040
|
||||||
#define WMATCH_IP 0x0080
|
#define WMATCH_IP 0x0080
|
||||||
#define WMATCH_MODES 0x0100
|
#define WMATCH_MODES 0x0100
|
||||||
|
#define WMATCH_CONTIME 0x0200
|
||||||
|
|
||||||
#define RPL_WHOSPCRPL 354
|
#define RPL_WHOSPCRPL 354
|
||||||
|
|
||||||
|
@ -69,6 +70,8 @@ struct who_format
|
||||||
const char *querytype;
|
const char *querytype;
|
||||||
int show_realhost;
|
int show_realhost;
|
||||||
int show_ip;
|
int show_ip;
|
||||||
|
time_t contimemin;
|
||||||
|
time_t contimemax;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
|
@ -229,6 +232,7 @@ CMD_FUNC(cmd_whox)
|
||||||
case 's': fmt.matchsel |= WMATCH_SERVER; continue;
|
case 's': fmt.matchsel |= WMATCH_SERVER; continue;
|
||||||
case 'a': fmt.matchsel |= WMATCH_ACCOUNT; continue;
|
case 'a': fmt.matchsel |= WMATCH_ACCOUNT; continue;
|
||||||
case 'm': fmt.matchsel |= WMATCH_MODES; continue;
|
case 'm': fmt.matchsel |= WMATCH_MODES; continue;
|
||||||
|
case 't': fmt.matchsel |= WMATCH_CONTIME; continue;
|
||||||
case 'R':
|
case 'R':
|
||||||
if (IsOper(client))
|
if (IsOper(client))
|
||||||
fmt.show_realhost = 1;
|
fmt.show_realhost = 1;
|
||||||
|
@ -336,6 +340,28 @@ CMD_FUNC(cmd_whox)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* match connect time */
|
||||||
|
if (fmt.matchsel & WMATCH_CONTIME)
|
||||||
|
{
|
||||||
|
char *s = mask;
|
||||||
|
time_t currenttime = TStime();
|
||||||
|
|
||||||
|
fmt.contimemin = 0;
|
||||||
|
fmt.contimemax = 0;
|
||||||
|
|
||||||
|
switch (*s)
|
||||||
|
{
|
||||||
|
case '<':
|
||||||
|
if (*s++)
|
||||||
|
fmt.contimemin = currenttime - config_checkval(s, CFG_TIME);
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
if (*s++)
|
||||||
|
fmt.contimemax = currenttime - config_checkval(s, CFG_TIME);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* '/who #some_channel' */
|
/* '/who #some_channel' */
|
||||||
if (IsChannelName(mask))
|
if (IsChannelName(mask))
|
||||||
{
|
{
|
||||||
|
@ -449,6 +475,16 @@ static int do_match(Client *client, Client *acptr, char *mask, struct who_format
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* match connect time */
|
||||||
|
if (IsMatch(fmt, WMATCH_CONTIME) && MyConnect(acptr) && (fmt->contimemin || fmt->contimemax))
|
||||||
|
{
|
||||||
|
if (fmt->contimemin && (acptr->local->creationtime > fmt->contimemin))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (fmt->contimemax && (acptr->local->creationtime < fmt->contimemax))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/parse.c
12
src/parse.c
|
@ -104,7 +104,9 @@ void parse_client_queued(Client *client)
|
||||||
return; /* we delay processing of data until identd has replied */
|
return; /* we delay processing of data until identd has replied */
|
||||||
|
|
||||||
if (!IsUser(client) && !IsServer(client) && (iConf.handshake_delay > 0) &&
|
if (!IsUser(client) && !IsServer(client) && (iConf.handshake_delay > 0) &&
|
||||||
!IsNoHandshakeDelay(client) && (TStime() - client->local->creationtime < iConf.handshake_delay))
|
!IsNoHandshakeDelay(client) &&
|
||||||
|
!IsControl(client) &&
|
||||||
|
(TStime() - client->local->creationtime < iConf.handshake_delay))
|
||||||
{
|
{
|
||||||
return; /* we delay processing of data until set::handshake-delay is reached */
|
return; /* we delay processing of data until set::handshake-delay is reached */
|
||||||
}
|
}
|
||||||
|
@ -368,6 +370,8 @@ static void parse2(Client *cptr, Client **fromptr, MessageTag *mtags, int mtags_
|
||||||
flags |= CMD_VIRUS;
|
flags |= CMD_VIRUS;
|
||||||
if (IsOper(from))
|
if (IsOper(from))
|
||||||
flags |= CMD_OPER;
|
flags |= CMD_OPER;
|
||||||
|
if (IsControl(from))
|
||||||
|
flags |= CMD_CONTROL;
|
||||||
cmptr = find_command(ch, flags);
|
cmptr = find_command(ch, flags);
|
||||||
if (!cmptr || !(cmptr->flags & CMD_NOLAG))
|
if (!cmptr || !(cmptr->flags & CMD_NOLAG))
|
||||||
{
|
{
|
||||||
|
@ -376,6 +380,12 @@ static void parse2(Client *cptr, Client **fromptr, MessageTag *mtags, int mtags_
|
||||||
}
|
}
|
||||||
if (!cmptr)
|
if (!cmptr)
|
||||||
{
|
{
|
||||||
|
if (IsControl(from))
|
||||||
|
{
|
||||||
|
sendto_one(from, NULL, "ERROR UNKNOWN_COMMAND: %s", ch);
|
||||||
|
sendto_one(from, NULL, "END 1");
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* Don't send error messages in response to NOTICEs
|
/* Don't send error messages in response to NOTICEs
|
||||||
* in pre-connection state.
|
* in pre-connection state.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
/************************************************************************
|
||||||
|
* UnrealIRCd - Unreal Internet Relay Chat Daemon - src/proc_io_client.c
|
||||||
|
* (c) 2022- Bram Matthys and The UnrealIRCd team
|
||||||
|
*
|
||||||
|
* See file AUTHORS in IRC package for additional names of
|
||||||
|
* the programmers.
|
||||||
|
*
|
||||||
|
* 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 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Inter-process I/O
|
||||||
|
*/
|
||||||
|
#include "unrealircd.h"
|
||||||
|
|
||||||
|
int procio_client_connect(const char *file)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
fprintf(stderr, "Your Windows version does not support UNIX sockets, "
|
||||||
|
"so cannot communicate to UnrealIRCd.\n"
|
||||||
|
"Windows 10 version 1803 (April 2018) or later is needed.\n");
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Cannot communicate to UnrealIRCd: %s\n"
|
||||||
|
"Perhaps your operating system does not support UNIX Sockets?\n",
|
||||||
|
strerror(ERRNO));
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strlcpy(addr.sun_path, file, sizeof(addr.sun_path));
|
||||||
|
|
||||||
|
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not connect to '%s': %s\n",
|
||||||
|
CONTROLFILE, strerror(errno));
|
||||||
|
fprintf(stderr, "The IRC server does not appear to be running.\n");
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int procio_send(int fd, const char *command)
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
int n;
|
||||||
|
snprintf(buf, sizeof(buf), "%s\r\n", command);
|
||||||
|
n = strlen(buf);
|
||||||
|
if (send(fd, buf, n, 0) != n)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *recolor_logs(const char *str)
|
||||||
|
{
|
||||||
|
static char retbuf[2048];
|
||||||
|
char buf[2048], *p;
|
||||||
|
const char *color = NULL;
|
||||||
|
|
||||||
|
strlcpy(buf, str, sizeof(buf));
|
||||||
|
p = strchr(buf, ' ');
|
||||||
|
if ((*str != '[') || !p)
|
||||||
|
return str;
|
||||||
|
*p++ = '\0';
|
||||||
|
|
||||||
|
if (!strcmp(buf, "[debug]"))
|
||||||
|
color = log_level_terminal_color(ULOG_DEBUG);
|
||||||
|
else if (!strcmp(buf, "[info]"))
|
||||||
|
color = log_level_terminal_color(ULOG_INFO);
|
||||||
|
else if (!strcmp(buf, "[warning]"))
|
||||||
|
color = log_level_terminal_color(ULOG_WARNING);
|
||||||
|
else if (!strcmp(buf, "[error]"))
|
||||||
|
color = log_level_terminal_color(ULOG_ERROR);
|
||||||
|
else if (!strcmp(buf, "[fatal]"))
|
||||||
|
color = log_level_terminal_color(ULOG_FATAL);
|
||||||
|
else
|
||||||
|
color = log_level_terminal_color(ULOG_INVALID);
|
||||||
|
|
||||||
|
snprintf(retbuf, sizeof(retbuf), "%s%s%s %s",
|
||||||
|
color, buf, TERMINAL_COLOR_RESET, p);
|
||||||
|
return retbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *recolor_split(const char *str)
|
||||||
|
{
|
||||||
|
static char retbuf[2048];
|
||||||
|
char buf[2048], *p;
|
||||||
|
const char *color = NULL;
|
||||||
|
|
||||||
|
strlcpy(buf, str, sizeof(buf));
|
||||||
|
p = strchr(buf, ' ');
|
||||||
|
if (!p)
|
||||||
|
return str;
|
||||||
|
*p++ = '\0';
|
||||||
|
|
||||||
|
snprintf(retbuf, sizeof(retbuf), "%s%s %s%s%s",
|
||||||
|
"\033[92m", buf,
|
||||||
|
"\033[93m", p,
|
||||||
|
TERMINAL_COLOR_RESET);
|
||||||
|
return retbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
int procio_client(const char *command, int auto_color_logs)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char buf[READBUFSIZE];
|
||||||
|
int n;
|
||||||
|
dbuf queue;
|
||||||
|
|
||||||
|
if (auto_color_logs && !terminal_supports_color())
|
||||||
|
auto_color_logs = 0;
|
||||||
|
|
||||||
|
fd = procio_client_connect(CONTROLFILE);
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Expect the welcome message */
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
n = recv(fd, buf, sizeof(buf), 0);
|
||||||
|
if ((n < 0) || strncmp(buf, "READY", 4))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error while communicating to IRCd via '%s': %s\n"
|
||||||
|
"Maybe the IRC server is not running?\n",
|
||||||
|
CONTROLFILE, strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!procio_send(fd, command))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error while sending command to IRCd via '%s'. Strange!\n",
|
||||||
|
CONTROLFILE);
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buf = '\0';
|
||||||
|
dbuf_queue_init(&queue);
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
n = recv(fd, buf, sizeof(buf)-1, 0);
|
||||||
|
if (n <= 0)
|
||||||
|
break;
|
||||||
|
buf[n] = '\0'; /* terminate the string */
|
||||||
|
dbuf_put(&queue, buf, n);
|
||||||
|
|
||||||
|
/* And try to read all complete lines: */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n = dbuf_getmsg(&queue, buf);
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
if (!strncmp(buf, "REPLY ", 6))
|
||||||
|
{
|
||||||
|
char *reply = buf+6;
|
||||||
|
if (auto_color_logs == 0)
|
||||||
|
printf("%s\n", reply);
|
||||||
|
else if (auto_color_logs == 1)
|
||||||
|
printf("%s\n", recolor_logs(reply));
|
||||||
|
else
|
||||||
|
printf("%s\n", recolor_split(reply));
|
||||||
|
} else
|
||||||
|
if (!strncmp(buf, "END ", 4))
|
||||||
|
{
|
||||||
|
int exitcode = atoi(buf+4);
|
||||||
|
close(fd);
|
||||||
|
return exitcode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(n > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IRCd hung up without saying goodbye, possibly problematic,
|
||||||
|
* or at least we cannot determine, so exit with status 66.
|
||||||
|
*/
|
||||||
|
close(fd);
|
||||||
|
return 66;
|
||||||
|
}
|
|
@ -0,0 +1,170 @@
|
||||||
|
/************************************************************************
|
||||||
|
* UnrealIRCd - Unreal Internet Relay Chat Daemon - src/proc_io_server.c
|
||||||
|
* (c) 2022- Bram Matthys and The UnrealIRCd team
|
||||||
|
*
|
||||||
|
* See file AUTHORS in IRC package for additional names of
|
||||||
|
* the programmers.
|
||||||
|
*
|
||||||
|
* 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 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Inter-process I/O
|
||||||
|
*/
|
||||||
|
#include "unrealircd.h"
|
||||||
|
#include <ares.h>
|
||||||
|
|
||||||
|
CMD_FUNC(procio_status);
|
||||||
|
CMD_FUNC(procio_modules);
|
||||||
|
CMD_FUNC(procio_rehash);
|
||||||
|
CMD_FUNC(procio_exit);
|
||||||
|
CMD_FUNC(procio_help);
|
||||||
|
|
||||||
|
/** Create the unrealircd.ctl socket (server-side) */
|
||||||
|
void add_proc_io_server(void)
|
||||||
|
{
|
||||||
|
ConfigItem_listen *listener;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* Ignore silently on Windows versions older than W10 build 17061 */
|
||||||
|
if (!unix_sockets_capable())
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
listener = safe_alloc(sizeof(ConfigItem_listen));
|
||||||
|
safe_strdup(listener->file, CONTROLFILE);
|
||||||
|
listener->socket_type = SOCKET_TYPE_UNIX;
|
||||||
|
listener->options = LISTENER_CONTROL;
|
||||||
|
listener->fd = -1;
|
||||||
|
AddListItem(listener, conf_listen);
|
||||||
|
if (add_listener(listener) == -1)
|
||||||
|
exit(-1);
|
||||||
|
CommandAdd(NULL, "STATUS", procio_status, MAXPARA, CMD_CONTROL);
|
||||||
|
CommandAdd(NULL, "MODULES", procio_modules, MAXPARA, CMD_CONTROL);
|
||||||
|
CommandAdd(NULL, "REHASH", procio_rehash, MAXPARA, CMD_CONTROL);
|
||||||
|
CommandAdd(NULL, "EXIT", procio_exit, MAXPARA, CMD_CONTROL);
|
||||||
|
CommandAdd(NULL, "HELP", procio_help, MAXPARA, CMD_CONTROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Start of "control channel" client handshake - this is minimal
|
||||||
|
* @param client The client
|
||||||
|
*/
|
||||||
|
void start_of_control_client_handshake(Client *client)
|
||||||
|
{
|
||||||
|
sendto_one(client, NULL, "READY %s %s", me.name, version);
|
||||||
|
fd_setselect(client->local->fd, FD_SELECT_READ, read_packet, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMD_FUNC(procio_status)
|
||||||
|
{
|
||||||
|
sendto_one(client, NULL, "REPLY servername %s", me.name);
|
||||||
|
sendto_one(client, NULL, "REPLY unrealircd_version %s", version);
|
||||||
|
sendto_one(client, NULL, "REPLY libssl_version %s", SSLeay_version(SSLEAY_VERSION));
|
||||||
|
sendto_one(client, NULL, "REPLY libsodium_version %s", sodium_version_string());
|
||||||
|
#ifdef USE_LIBCURL
|
||||||
|
sendto_one(client, NULL, "REPLY libcurl_version %s", curl_version());
|
||||||
|
#endif
|
||||||
|
sendto_one(client, NULL, "REPLY libcares_version %s", ares_version(NULL));
|
||||||
|
sendto_one(client, NULL, "REPLY libpcre2_version %s", pcre2_version());
|
||||||
|
sendto_one(client, NULL, "REPLY global_clients %ld", (long)irccounts.clients);
|
||||||
|
sendto_one(client, NULL, "REPLY local_clients %ld", (long)irccounts.me_clients);
|
||||||
|
sendto_one(client, NULL, "REPLY operators %ld", (long)irccounts.operators);
|
||||||
|
sendto_one(client, NULL, "REPLY servers %ld", (long)irccounts.servers);
|
||||||
|
sendto_one(client, NULL, "REPLY channels %ld", (long)irccounts.channels);
|
||||||
|
sendto_one(client, NULL, "END 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
extern MODVAR Module *Modules;
|
||||||
|
CMD_FUNC(procio_modules)
|
||||||
|
{
|
||||||
|
char tmp[1024];
|
||||||
|
Module *m;
|
||||||
|
|
||||||
|
for (m = Modules; m; m = m->next)
|
||||||
|
{
|
||||||
|
tmp[0] = '\0';
|
||||||
|
if (m->flags & MODFLAG_DELAYED)
|
||||||
|
strlcat(tmp, "[Unloading] ", sizeof(tmp));
|
||||||
|
if (m->options & MOD_OPT_PERM_RELOADABLE)
|
||||||
|
strlcat(tmp, "[PERM-BUT-RELOADABLE] ", sizeof(tmp));
|
||||||
|
if (m->options & MOD_OPT_PERM)
|
||||||
|
strlcat(tmp, "[PERM] ", sizeof(tmp));
|
||||||
|
if (!(m->options & MOD_OPT_OFFICIAL))
|
||||||
|
strlcat(tmp, "[3RD] ", sizeof(tmp));
|
||||||
|
sendto_one(client, NULL, "REPLY %s %s - %s - by %s %s",
|
||||||
|
m->header->name,
|
||||||
|
m->header->version,
|
||||||
|
m->header->description,
|
||||||
|
m->header->author,
|
||||||
|
tmp);
|
||||||
|
}
|
||||||
|
sendto_one(client, NULL, "END 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
CMD_FUNC(procio_rehash)
|
||||||
|
{
|
||||||
|
if (loop.rehashing)
|
||||||
|
{
|
||||||
|
sendto_one(client, NULL, "REPLY ERROR: A rehash is already in progress");
|
||||||
|
sendto_one(client, NULL, "END 1");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (parv[1] && !strcmp(parv[1], "-tls"))
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
SetMonitorRehash(client);
|
||||||
|
unreal_log(ULOG_INFO, "config", "CONFIG_RELOAD_TLS", NULL, "Reloading all TLS related data (./unrealircd reloadtls)");
|
||||||
|
ret = reinit_tls();
|
||||||
|
sendto_one(client, NULL, "END %d", ret == 0 ? -1 : 0);
|
||||||
|
ClearMonitorRehash(client);
|
||||||
|
} else {
|
||||||
|
SetMonitorRehash(client);
|
||||||
|
request_rehash(client);
|
||||||
|
/* completion will go via procio_post_rehash() */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CMD_FUNC(procio_exit)
|
||||||
|
{
|
||||||
|
sendto_one(client, NULL, "END 0");
|
||||||
|
exit_client(client, NULL, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
CMD_FUNC(procio_help)
|
||||||
|
{
|
||||||
|
sendto_one(client, NULL, "REPLY Commands available:");
|
||||||
|
sendto_one(client, NULL, "REPLY EXIT");
|
||||||
|
sendto_one(client, NULL, "REPLY HELP");
|
||||||
|
sendto_one(client, NULL, "REPLY REHASH");
|
||||||
|
sendto_one(client, NULL, "REPLY STATUS");
|
||||||
|
sendto_one(client, NULL, "REPLY MODULES");
|
||||||
|
sendto_one(client, NULL, "END 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called upon REHASH completion (with or without failure) */
|
||||||
|
void procio_post_rehash(int failure)
|
||||||
|
{
|
||||||
|
Client *client;
|
||||||
|
|
||||||
|
list_for_each_entry(client, &control_list, lclient_node)
|
||||||
|
{
|
||||||
|
if (IsMonitorRehash(client))
|
||||||
|
{
|
||||||
|
sendto_one(client, NULL, "END %d", failure);
|
||||||
|
ClearMonitorRehash(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
src/send.c
15
src/send.c
|
@ -218,7 +218,7 @@ void vsendto_one(Client *to, MessageTag *mtags, const char *pattern, va_list vl)
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||||
#endif
|
#endif
|
||||||
ircvsnprintf(sendbuf, sizeof(sendbuf), pattern, vl);
|
ircvsnprintf(sendbuf, sizeof(sendbuf)-3, pattern, vl);
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
@ -229,7 +229,7 @@ void vsendto_one(Client *to, MessageTag *mtags, const char *pattern, va_list vl)
|
||||||
sendbufto_one(to, sendbuf, 0);
|
sendbufto_one(to, sendbuf, 0);
|
||||||
} else {
|
} else {
|
||||||
/* Message tags need to be prepended */
|
/* Message tags need to be prepended */
|
||||||
snprintf(sendbuf2, sizeof(sendbuf2), "@%s %s", mtags_str, sendbuf);
|
snprintf(sendbuf2, sizeof(sendbuf2)-3, "@%s %s", mtags_str, sendbuf);
|
||||||
sendbufto_one(to, sendbuf2, 0);
|
sendbufto_one(to, sendbuf2, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,10 +339,10 @@ void sendbufto_one(Client *to, char *msg, unsigned int quick)
|
||||||
|
|
||||||
if (IsMe(to))
|
if (IsMe(to))
|
||||||
{
|
{
|
||||||
char tmp_msg[500], *p;
|
char tmp_msg[500];
|
||||||
|
|
||||||
p = strchr(msg, '\r');
|
strlcpy(tmp_msg, msg, sizeof(tmp_msg));
|
||||||
if (p) *p = '\0';
|
stripcrlf(tmp_msg);
|
||||||
unreal_log(ULOG_WARNING, "send", "SENDBUFTO_ONE_ME_MESSAGE", to,
|
unreal_log(ULOG_WARNING, "send", "SENDBUFTO_ONE_ME_MESSAGE", to,
|
||||||
"Trying to send data to myself: $buf",
|
"Trying to send data to myself: $buf",
|
||||||
log_data_string("buf", tmp_msg));
|
log_data_string("buf", tmp_msg));
|
||||||
|
@ -395,7 +395,10 @@ void sendbufto_one(Client *to, char *msg, unsigned int quick)
|
||||||
* a bad idea, CPU-wise. So now we just mark the client indicating
|
* a bad idea, CPU-wise. So now we just mark the client indicating
|
||||||
* that there is data to send.
|
* that there is data to send.
|
||||||
*/
|
*/
|
||||||
mark_data_to_send(to);
|
if (IsControl(to))
|
||||||
|
send_queued(to); /* send this one ASAP */
|
||||||
|
else
|
||||||
|
mark_data_to_send(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A single function to send data to a channel.
|
/** A single function to send data to a channel.
|
||||||
|
|
111
src/serv.c
111
src/serv.c
|
@ -716,62 +716,77 @@ CMD_FUNC(cmd_restart)
|
||||||
/** Send short message of the day to the client */
|
/** Send short message of the day to the client */
|
||||||
void short_motd(Client *client)
|
void short_motd(Client *client)
|
||||||
{
|
{
|
||||||
ConfigItem_tld *tld;
|
ConfigItem_tld *tld;
|
||||||
MOTDFile *themotd;
|
MOTDFile *themotd;
|
||||||
MOTDLine *motdline;
|
MOTDLine *motdline;
|
||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
char is_short;
|
char is_short;
|
||||||
|
|
||||||
tm = NULL;
|
tm = NULL;
|
||||||
is_short = 1;
|
is_short = 1;
|
||||||
|
|
||||||
tld = find_tld(client);
|
tld = find_tld(client);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try different sources of short MOTDs, falling back to the
|
* Try different sources of short MOTDs, falling back to the
|
||||||
* long MOTD.
|
* long MOTD.
|
||||||
*/
|
*/
|
||||||
themotd = &smotd;
|
themotd = &smotd;
|
||||||
if (tld && tld->smotd.lines)
|
if (tld && tld->smotd.lines)
|
||||||
themotd = &tld->smotd;
|
themotd = &tld->smotd;
|
||||||
|
|
||||||
/* try long MOTDs */
|
/* try long MOTDs */
|
||||||
if (!themotd->lines)
|
if (!themotd->lines)
|
||||||
{
|
{
|
||||||
is_short = 0;
|
is_short = 0;
|
||||||
if (tld && tld->motd.lines)
|
if (tld && tld->motd.lines)
|
||||||
themotd = &tld->motd;
|
themotd = &tld->motd;
|
||||||
else
|
else
|
||||||
themotd = &motd;
|
themotd = &motd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!themotd->lines)
|
if (!themotd->lines)
|
||||||
{
|
{
|
||||||
sendnumeric(client, ERR_NOMOTD);
|
sendnumeric(client, ERR_NOMOTD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (themotd->last_modified.tm_year)
|
if (themotd->last_modified.tm_year)
|
||||||
{
|
{
|
||||||
tm = &themotd->last_modified; /* for readability */
|
tm = &themotd->last_modified; /* for readability */
|
||||||
sendnumeric(client, RPL_MOTDSTART, me.name);
|
sendnumeric(client, RPL_MOTDSTART, me.name);
|
||||||
sendnumericfmt(client, RPL_MOTD, ":- %d/%d/%d %d:%02d", tm->tm_mday, tm->tm_mon + 1,
|
sendnumericfmt(client, RPL_MOTD, ":- %d/%d/%d %d:%02d", tm->tm_mday, tm->tm_mon + 1,
|
||||||
1900 + tm->tm_year, tm->tm_hour, tm->tm_min);
|
1900 + tm->tm_year, tm->tm_hour, tm->tm_min);
|
||||||
}
|
}
|
||||||
if (is_short)
|
if (is_short)
|
||||||
{
|
{
|
||||||
sendnumeric(client, RPL_MOTD, "This is the short MOTD. To view the complete MOTD type /motd");
|
sendnumeric(client, RPL_MOTD, "This is the short MOTD. To view the complete MOTD type /motd");
|
||||||
sendnumeric(client, RPL_MOTD, "");
|
sendnumeric(client, RPL_MOTD, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
motdline = NULL;
|
motdline = NULL;
|
||||||
if (themotd)
|
if (themotd)
|
||||||
motdline = themotd->lines;
|
motdline = themotd->lines;
|
||||||
while (motdline)
|
while (motdline)
|
||||||
{
|
{
|
||||||
sendnumeric(client, RPL_MOTD, motdline->line);
|
sendnumeric(client, RPL_MOTD, motdline->line);
|
||||||
motdline = motdline->next;
|
motdline = motdline->next;
|
||||||
}
|
}
|
||||||
sendnumeric(client, RPL_ENDOFMOTD);
|
|
||||||
|
if (!is_short)
|
||||||
|
{
|
||||||
|
/* If the admin does not use a short MOTD then we append the SVSMOTD here...
|
||||||
|
* If we did show a short motd then we don't append SVSMOTD,
|
||||||
|
* since they want to keep it short.
|
||||||
|
*/
|
||||||
|
motdline = svsmotd.lines;
|
||||||
|
while (motdline)
|
||||||
|
{
|
||||||
|
sendnumeric(client, RPL_MOTD, motdline->line);
|
||||||
|
motdline = motdline->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendnumeric(client, RPL_ENDOFMOTD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read motd-like file, used for rules/motd/botmotd/opermotd/etc.
|
/** Read motd-like file, used for rules/motd/botmotd/opermotd/etc.
|
||||||
|
|
378
src/socket.c
378
src/socket.c
|
@ -32,7 +32,7 @@ int OpenFiles = 0; /* GLOBAL - number of files currently open */
|
||||||
int readcalls = 0;
|
int readcalls = 0;
|
||||||
|
|
||||||
void completed_connection(int, int, void *);
|
void completed_connection(int, int, void *);
|
||||||
void set_sock_opts(int, Client *, int);
|
void set_sock_opts(int, Client *, SocketType);
|
||||||
void set_ipv6_opts(int);
|
void set_ipv6_opts(int);
|
||||||
void close_listener(ConfigItem_listen *listener);
|
void close_listener(ConfigItem_listen *listener);
|
||||||
static char readbuf[BUFSIZE];
|
static char readbuf[BUFSIZE];
|
||||||
|
@ -41,6 +41,7 @@ extern char *version;
|
||||||
MODVAR time_t last_allinuse = 0;
|
MODVAR time_t last_allinuse = 0;
|
||||||
|
|
||||||
void start_of_normal_client_handshake(Client *client);
|
void start_of_normal_client_handshake(Client *client);
|
||||||
|
extern void start_of_control_client_handshake(Client *client);
|
||||||
void proceed_normal_client_handshake(Client *client, struct hostent *he);
|
void proceed_normal_client_handshake(Client *client, struct hostent *he);
|
||||||
|
|
||||||
/** Close all connections - only used when we terminate the server (eg: /DIE or SIGTERM) */
|
/** Close all connections - only used when we terminate the server (eg: /DIE or SIGTERM) */
|
||||||
|
@ -72,6 +73,15 @@ void close_connections(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(client, &control_list, lclient_node)
|
||||||
|
{
|
||||||
|
if (client->local->fd >= 0)
|
||||||
|
{
|
||||||
|
fd_close(client->local->fd);
|
||||||
|
client->local->fd = -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
close_unbound_listeners();
|
close_unbound_listeners();
|
||||||
|
|
||||||
OpenFiles = 0;
|
OpenFiles = 0;
|
||||||
|
@ -101,10 +111,17 @@ static void listener_accept(int listener_fd, int revents, void *data)
|
||||||
* Of course the underlying cause of this issue should be investigated, as this
|
* Of course the underlying cause of this issue should be investigated, as this
|
||||||
* is very much a workaround.
|
* is very much a workaround.
|
||||||
*/
|
*/
|
||||||
unreal_log(ULOG_FATAL, "listen", "ACCEPT_ERROR", NULL, "Cannot accept incoming connection on IP \"$listen_ip\" port $listen_port: $socket_error",
|
if (listener->file)
|
||||||
log_data_socket_error(listener->fd),
|
{
|
||||||
log_data_string("listen_ip", listener->ip),
|
unreal_log(ULOG_FATAL, "listen", "ACCEPT_ERROR", NULL, "Cannot accept incoming connection on file $file: $socket_error",
|
||||||
log_data_integer("listen_port", listener->port));
|
log_data_socket_error(listener->fd),
|
||||||
|
log_data_string("file", listener->file));
|
||||||
|
} else {
|
||||||
|
unreal_log(ULOG_FATAL, "listen", "ACCEPT_ERROR", NULL, "Cannot accept incoming connection on IP \"$listen_ip\" port $listen_port: $socket_error",
|
||||||
|
log_data_socket_error(listener->fd),
|
||||||
|
log_data_string("listen_ip", listener->ip),
|
||||||
|
log_data_integer("listen_port", listener->port));
|
||||||
|
}
|
||||||
close_listener(listener);
|
close_listener(listener);
|
||||||
start_listeners();
|
start_listeners();
|
||||||
}
|
}
|
||||||
|
@ -113,45 +130,67 @@ static void listener_accept(int listener_fd, int revents, void *data)
|
||||||
|
|
||||||
ircstats.is_ac++;
|
ircstats.is_ac++;
|
||||||
|
|
||||||
set_sock_opts(cli_fd, NULL, listener->ipv6);
|
set_sock_opts(cli_fd, NULL, listener->socket_type);
|
||||||
|
|
||||||
if ((++OpenFiles >= maxclients) || (cli_fd >= maxclients))
|
/* Allow connections to the control socket, even if maxclients is reached */
|
||||||
|
if (listener->options & LISTENER_CONTROL)
|
||||||
{
|
{
|
||||||
ircstats.is_ref++;
|
/* ... but not unlimited ;) */
|
||||||
if (last_allinuse < TStime() - 15)
|
if ((++OpenFiles >= maxclients+(CLIENTS_RESERVE/2)) || (cli_fd >= maxclients+(CLIENTS_RESERVE/2)))
|
||||||
{
|
{
|
||||||
unreal_log(ULOG_FATAL, "listen", "ACCEPT_ERROR_MAXCLIENTS", NULL, "Cannot accept incoming connection on IP \"$listen_ip\" port $listen_port: All connections in use",
|
ircstats.is_ref++;
|
||||||
log_data_string("listen_ip", listener->ip),
|
if (last_allinuse < TStime() - 15)
|
||||||
log_data_integer("listen_port", listener->port));
|
{
|
||||||
last_allinuse = TStime();
|
unreal_log(ULOG_FATAL, "listen", "ACCEPT_ERROR_MAXCLIENTS", NULL, "Cannot accept incoming connection on file $file: All connections in use",
|
||||||
|
log_data_string("file", listener->file));
|
||||||
|
last_allinuse = TStime();
|
||||||
|
}
|
||||||
|
fd_close(cli_fd);
|
||||||
|
--OpenFiles;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
if ((++OpenFiles >= maxclients) || (cli_fd >= maxclients))
|
||||||
|
{
|
||||||
|
ircstats.is_ref++;
|
||||||
|
if (last_allinuse < TStime() - 15)
|
||||||
|
{
|
||||||
|
if (listener->file)
|
||||||
|
{
|
||||||
|
unreal_log(ULOG_FATAL, "listen", "ACCEPT_ERROR_MAXCLIENTS", NULL, "Cannot accept incoming connection on file $file: All connections in use",
|
||||||
|
log_data_string("file", listener->file));
|
||||||
|
} else {
|
||||||
|
unreal_log(ULOG_FATAL, "listen", "ACCEPT_ERROR_MAXCLIENTS", NULL, "Cannot accept incoming connection on IP \"$listen_ip\" port $listen_port: All connections in use",
|
||||||
|
log_data_string("listen_ip", listener->ip),
|
||||||
|
log_data_integer("listen_port", listener->port));
|
||||||
|
}
|
||||||
|
last_allinuse = TStime();
|
||||||
|
}
|
||||||
|
|
||||||
(void)send(cli_fd, "ERROR :All connections in use\r\n", 31, 0);
|
(void)send(cli_fd, "ERROR :All connections in use\r\n", 31, 0);
|
||||||
|
|
||||||
fd_close(cli_fd);
|
fd_close(cli_fd);
|
||||||
--OpenFiles;
|
--OpenFiles;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add_connection() may fail. we just don't care. */
|
/* add_connection() may fail. we just don't care. */
|
||||||
add_connection(listener, cli_fd);
|
add_connection(listener, cli_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a listener port.
|
int unreal_listen_inet(ConfigItem_listen *listener)
|
||||||
* @param listener The listen { } block configuration
|
|
||||||
* @param ip IP address to bind on
|
|
||||||
* @param port Port to bind on
|
|
||||||
* @param ipv6 IPv6 (1) or IPv4 (0)
|
|
||||||
* @returns 0 on success and <0 on error. Yeah, confusing.
|
|
||||||
*/
|
|
||||||
int unreal_listen(ConfigItem_listen *listener, char *ip, int port, int ipv6)
|
|
||||||
{
|
{
|
||||||
|
const char *ip = listener->ip;
|
||||||
|
int port = listener->port;
|
||||||
|
|
||||||
if (BadPtr(ip))
|
if (BadPtr(ip))
|
||||||
ip = "*";
|
ip = "*";
|
||||||
|
|
||||||
if (*ip == '*')
|
if (*ip == '*')
|
||||||
{
|
{
|
||||||
if (ipv6)
|
if (listener->socket_type == SOCKET_TYPE_IPV6)
|
||||||
ip = "::";
|
ip = "::";
|
||||||
else
|
else
|
||||||
ip = "0.0.0.0";
|
ip = "0.0.0.0";
|
||||||
|
@ -160,11 +199,11 @@ int unreal_listen(ConfigItem_listen *listener, char *ip, int port, int ipv6)
|
||||||
/* At first, open a new socket */
|
/* At first, open a new socket */
|
||||||
if (listener->fd >= 0)
|
if (listener->fd >= 0)
|
||||||
abort(); /* Socket already exists but we are asked to create and listen on one. Bad! */
|
abort(); /* Socket already exists but we are asked to create and listen on one. Bad! */
|
||||||
|
|
||||||
if (port == 0)
|
if (port == 0)
|
||||||
abort(); /* Impossible as well, right? */
|
abort(); /* Impossible as well, right? */
|
||||||
|
|
||||||
listener->fd = fd_socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0, "Listener socket");
|
listener->fd = fd_socket(listener->socket_type == SOCKET_TYPE_IPV6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0, "Listener socket");
|
||||||
if (listener->fd < 0)
|
if (listener->fd < 0)
|
||||||
{
|
{
|
||||||
unreal_log(ULOG_FATAL, "listen", "LISTEN_SOCKET_ERROR", NULL,
|
unreal_log(ULOG_FATAL, "listen", "LISTEN_SOCKET_ERROR", NULL,
|
||||||
|
@ -187,9 +226,9 @@ int unreal_listen(ConfigItem_listen *listener, char *ip, int port, int ipv6)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_sock_opts(listener->fd, NULL, ipv6);
|
set_sock_opts(listener->fd, NULL, listener->socket_type);
|
||||||
|
|
||||||
if (!unreal_bind(listener->fd, ip, port, ipv6))
|
if (!unreal_bind(listener->fd, ip, port, listener->socket_type))
|
||||||
{
|
{
|
||||||
unreal_log(ULOG_FATAL, "listen", "LISTEN_BIND_ERROR", NULL,
|
unreal_log(ULOG_FATAL, "listen", "LISTEN_BIND_ERROR", NULL,
|
||||||
"Could not listen on IP \"$listen_ip\" on port $listen_port: $socket_error",
|
"Could not listen on IP \"$listen_ip\" on port $listen_port: $socket_error",
|
||||||
|
@ -240,23 +279,95 @@ int unreal_listen(ConfigItem_listen *listener, char *ip, int port, int ipv6)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Activate a listen { } block */
|
int unreal_listen_unix(ConfigItem_listen *listener)
|
||||||
int add_listener(ConfigItem_listen *conf)
|
|
||||||
{
|
{
|
||||||
if (unreal_listen(conf, conf->ip, conf->port, conf->ipv6))
|
if (listener->socket_type != SOCKET_TYPE_UNIX)
|
||||||
|
abort(); /* "impossible" */
|
||||||
|
|
||||||
|
/* At first, open a new socket */
|
||||||
|
if (listener->fd >= 0)
|
||||||
|
abort(); /* Socket already exists but we are asked to create and listen on one. Bad! */
|
||||||
|
|
||||||
|
listener->fd = fd_socket(AF_UNIX, SOCK_STREAM, 0, "Listener socket (UNIX)");
|
||||||
|
if (listener->fd < 0)
|
||||||
{
|
{
|
||||||
/* Error is already handled upstream */
|
unreal_log(ULOG_FATAL, "listen", "LISTEN_SOCKET_ERROR", NULL,
|
||||||
conf->fd = -2;
|
"Could not create UNIX domain socket for $file: $socket_error",
|
||||||
|
log_data_socket_error(-1),
|
||||||
|
log_data_string("file", listener->file));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf->fd >= 0)
|
if (++OpenFiles >= maxclients)
|
||||||
{
|
{
|
||||||
conf->options |= LISTENER_BOUND;
|
unreal_log(ULOG_FATAL, "listen", "LISTEN_ERROR_MAXCLIENTS", NULL,
|
||||||
|
"Could not create UNIX domain socket for $file: all connections in use",
|
||||||
|
log_data_string("file", listener->file));
|
||||||
|
fd_close(listener->fd);
|
||||||
|
listener->fd = -1;
|
||||||
|
--OpenFiles;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_sock_opts(listener->fd, NULL, listener->socket_type);
|
||||||
|
|
||||||
|
if (!unreal_bind(listener->fd, listener->file, 0, SOCKET_TYPE_UNIX))
|
||||||
|
{
|
||||||
|
unreal_log(ULOG_FATAL, "listen", "LISTEN_BIND_ERROR", NULL,
|
||||||
|
"Could not listen on UNIX domain socket $file: $socket_error",
|
||||||
|
log_data_socket_error(listener->fd),
|
||||||
|
log_data_string("file", listener->file));
|
||||||
|
fd_close(listener->fd);
|
||||||
|
listener->fd = -1;
|
||||||
|
--OpenFiles;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(listener->fd, LISTEN_SIZE) < 0)
|
||||||
|
{
|
||||||
|
unreal_log(ULOG_FATAL, "listen", "LISTEN_LISTEN_ERROR", NULL,
|
||||||
|
"Could not listen on UNIX domain socket $file: $socket_error",
|
||||||
|
log_data_socket_error(listener->fd),
|
||||||
|
log_data_string("file", listener->file));
|
||||||
|
fd_close(listener->fd);
|
||||||
|
listener->fd = -1;
|
||||||
|
--OpenFiles;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_setselect(listener->fd, FD_SELECT_READ, listener_accept, listener);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a listener port.
|
||||||
|
* @param listener The listen { } block configuration
|
||||||
|
* @returns 0 on success and <0 on error. Yeah, confusing.
|
||||||
|
*/
|
||||||
|
int unreal_listen(ConfigItem_listen *listener)
|
||||||
|
{
|
||||||
|
if ((listener->socket_type == SOCKET_TYPE_IPV4) || (listener->socket_type == SOCKET_TYPE_IPV6))
|
||||||
|
return unreal_listen_inet(listener);
|
||||||
|
return unreal_listen_unix(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Activate a listen { } block */
|
||||||
|
int add_listener(ConfigItem_listen *listener)
|
||||||
|
{
|
||||||
|
if (unreal_listen(listener))
|
||||||
|
{
|
||||||
|
/* Error is already handled upstream */
|
||||||
|
listener->fd = -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listener->fd >= 0)
|
||||||
|
{
|
||||||
|
listener->options |= LISTENER_BOUND;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
conf->fd = -1;
|
listener->fd = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,7 +544,7 @@ void consider_ident_lookup(Client *client)
|
||||||
char buf[BUFSIZE];
|
char buf[BUFSIZE];
|
||||||
|
|
||||||
/* If ident checking is disabled or it's an outgoing connect, then no ident check */
|
/* If ident checking is disabled or it's an outgoing connect, then no ident check */
|
||||||
if ((IDENT_CHECK == 0) || (client->server && IsHandshake(client)))
|
if ((IDENT_CHECK == 0) || (client->server && IsHandshake(client)) || IsUnixSocket(client))
|
||||||
{
|
{
|
||||||
ClearIdentLookupSent(client);
|
ClearIdentLookupSent(client);
|
||||||
ClearIdentLookup(client);
|
ClearIdentLookup(client);
|
||||||
|
@ -560,37 +671,38 @@ void set_socket_buffers(int fd, int rcvbuf, int sndbuf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the appropriate socket options */
|
/** Set the appropriate socket options */
|
||||||
void set_sock_opts(int fd, Client *client, int ipv6)
|
void set_sock_opts(int fd, Client *client, SocketType socket_type)
|
||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
if (ipv6)
|
if (socket_type == SOCKET_TYPE_IPV6)
|
||||||
set_ipv6_opts(fd);
|
set_ipv6_opts(fd);
|
||||||
|
|
||||||
#ifdef SO_REUSEADDR
|
if ((socket_type == SOCKET_TYPE_IPV4) || (socket_type == SOCKET_TYPE_IPV6))
|
||||||
opt = 1;
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt)) < 0)
|
|
||||||
{
|
{
|
||||||
unreal_log(ULOG_WARNING, "socket", "SOCKET_ERROR_SETSOCKOPTS", client,
|
#ifdef SO_REUSEADDR
|
||||||
"Could not setsockopt(SO_REUSEADDR): $socket_error",
|
opt = 1;
|
||||||
log_data_socket_error(-1));
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt)) < 0)
|
||||||
}
|
{
|
||||||
|
unreal_log(ULOG_WARNING, "socket", "SOCKET_ERROR_SETSOCKOPTS", client,
|
||||||
|
"Could not setsockopt(SO_REUSEADDR): $socket_error",
|
||||||
|
log_data_socket_error(-1));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SO_USELOOPBACK) && !defined(_WIN32)
|
#if defined(SO_USELOOPBACK) && !defined(_WIN32)
|
||||||
opt = 1;
|
opt = 1;
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_USELOOPBACK, (void *)&opt, sizeof(opt)) < 0)
|
if (setsockopt(fd, SOL_SOCKET, SO_USELOOPBACK, (void *)&opt, sizeof(opt)) < 0)
|
||||||
{
|
{
|
||||||
unreal_log(ULOG_WARNING, "socket", "SOCKET_ERROR_SETSOCKOPTS", client,
|
unreal_log(ULOG_WARNING, "socket", "SOCKET_ERROR_SETSOCKOPTS", client,
|
||||||
"Could not setsockopt(SO_USELOOPBACK): $socket_error",
|
"Could not setsockopt(SO_USELOOPBACK): $socket_error",
|
||||||
log_data_socket_error(-1));
|
log_data_socket_error(-1));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Previously we also called set_socket_buffers() to set some
|
}
|
||||||
* specific buffer limits. This is no longer needed on modern OS's.
|
|
||||||
* Setting it explicitly actually slows things down.
|
/* The following code applies to all socket types: IPv4, IPv6, UNIX domain sockets */
|
||||||
*/
|
|
||||||
|
|
||||||
/* Set to non blocking: */
|
/* Set to non blocking: */
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
|
@ -641,7 +753,7 @@ int is_loopback_ip(char *ip)
|
||||||
|
|
||||||
for (e = conf_listen; e; e = e->next)
|
for (e = conf_listen; e; e = e->next)
|
||||||
{
|
{
|
||||||
if ((e->options & LISTENER_BOUND) && !strcmp(ip, e->ip))
|
if ((e->options & LISTENER_BOUND) && e->ip && !strcmp(ip, e->ip))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -718,15 +830,15 @@ Client *add_connection(ConfigItem_listen *listener, int fd)
|
||||||
Client *client;
|
Client *client;
|
||||||
const char *ip;
|
const char *ip;
|
||||||
int port = 0;
|
int port = 0;
|
||||||
|
|
||||||
client = make_client(NULL, &me);
|
client = make_client(NULL, &me);
|
||||||
|
client->local->socket_type = listener->socket_type;
|
||||||
|
|
||||||
/* If listener is IPv6 then mark client (client) as IPv6 */
|
if (listener->socket_type == SOCKET_TYPE_UNIX)
|
||||||
if (listener->ipv6)
|
ip = "127.0.0.1";
|
||||||
SetIPV6(client);
|
else
|
||||||
|
ip = getpeerip(client, fd, &port);
|
||||||
|
|
||||||
ip = getpeerip(client, fd, &port);
|
|
||||||
|
|
||||||
if (!ip)
|
if (!ip)
|
||||||
{
|
{
|
||||||
/* On Linux 2.4 and FreeBSD the socket may just have been disconnected
|
/* On Linux 2.4 and FreeBSD the socket may just have been disconnected
|
||||||
|
@ -762,29 +874,38 @@ refuse_client:
|
||||||
SetLocalhost(client);
|
SetLocalhost(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check set::max-unknown-connections-per-ip */
|
if (!(listener->options & LISTENER_CONTROL))
|
||||||
if (check_too_many_unknown_connections(client))
|
|
||||||
{
|
{
|
||||||
ircsnprintf(zlinebuf, sizeof(zlinebuf),
|
/* Check set::max-unknown-connections-per-ip */
|
||||||
"ERROR :Closing Link: [%s] (Too many unknown connections from your IP)\r\n",
|
if (check_too_many_unknown_connections(client))
|
||||||
client->ip);
|
{
|
||||||
(void)send(fd, zlinebuf, strlen(zlinebuf), 0);
|
ircsnprintf(zlinebuf, sizeof(zlinebuf),
|
||||||
goto refuse_client;
|
"ERROR :Closing Link: [%s] (Too many unknown connections from your IP)\r\n",
|
||||||
}
|
client->ip);
|
||||||
|
(void)send(fd, zlinebuf, strlen(zlinebuf), 0);
|
||||||
|
goto refuse_client;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check (G)Z-Lines and set::anti-flood::connect-flood */
|
/* Check (G)Z-Lines and set::anti-flood::connect-flood */
|
||||||
if (check_banned(client, NO_EXIT_CLIENT))
|
if (check_banned(client, NO_EXIT_CLIENT))
|
||||||
goto refuse_client;
|
goto refuse_client;
|
||||||
|
}
|
||||||
|
|
||||||
client->local->listener = listener;
|
client->local->listener = listener;
|
||||||
if (client->local->listener != NULL)
|
if (client->local->listener != NULL)
|
||||||
client->local->listener->clients++;
|
client->local->listener->clients++;
|
||||||
add_client_to_list(client);
|
add_client_to_list(client);
|
||||||
|
|
||||||
irccounts.unknown++;
|
if (!(listener->options & LISTENER_CONTROL))
|
||||||
client->status = CLIENT_STATUS_UNKNOWN;
|
{
|
||||||
|
/* IRC: unknown connection */
|
||||||
list_add(&client->lclient_node, &unknown_list);
|
irccounts.unknown++;
|
||||||
|
client->status = CLIENT_STATUS_UNKNOWN;
|
||||||
|
list_add(&client->lclient_node, &unknown_list);
|
||||||
|
} else {
|
||||||
|
client->status = CLIENT_STATUS_CONTROL;
|
||||||
|
list_add(&client->lclient_node, &control_list);
|
||||||
|
}
|
||||||
|
|
||||||
if ((listener->options & LISTENER_TLS) && ctx_server)
|
if ((listener->options & LISTENER_TLS) && ctx_server)
|
||||||
{
|
{
|
||||||
|
@ -809,7 +930,9 @@ refuse_client:
|
||||||
goto refuse_client;
|
goto refuse_client;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
if (listener->options & LISTENER_CONTROL)
|
||||||
|
start_of_control_client_handshake(client);
|
||||||
else
|
else
|
||||||
start_of_normal_client_handshake(client);
|
start_of_normal_client_handshake(client);
|
||||||
return client;
|
return client;
|
||||||
|
@ -828,7 +951,7 @@ void start_of_normal_client_handshake(Client *client)
|
||||||
|
|
||||||
RunHook(HOOKTYPE_HANDSHAKE, client);
|
RunHook(HOOKTYPE_HANDSHAKE, client);
|
||||||
|
|
||||||
if (!DONT_RESOLVE)
|
if (!DONT_RESOLVE && !IsUnixSocket(client))
|
||||||
{
|
{
|
||||||
if (should_show_connect_info(client))
|
if (should_show_connect_info(client))
|
||||||
sendto_one(client, NULL, ":%s %s", me.name, REPORT_DO_DNS);
|
sendto_one(client, NULL, ":%s %s", me.name, REPORT_DO_DNS);
|
||||||
|
@ -1027,6 +1150,20 @@ void process_clients(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while(&client->lclient_node != &unknown_list);
|
} while(&client->lclient_node != &unknown_list);
|
||||||
|
|
||||||
|
do {
|
||||||
|
list_for_each_entry(client, &control_list, lclient_node)
|
||||||
|
{
|
||||||
|
if ((client->local->fd >= 0) && DBufLength(&client->local->recvQ) && !IsDead(client))
|
||||||
|
{
|
||||||
|
parse_client_queued(client);
|
||||||
|
if (IsDead(client))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(&client->lclient_node != &control_list);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check if 'ip' is a valid IP address, and if so what type.
|
/** Check if 'ip' is a valid IP address, and if so what type.
|
||||||
|
@ -1038,16 +1175,16 @@ void process_clients(void)
|
||||||
int is_valid_ip(const char *ip)
|
int is_valid_ip(const char *ip)
|
||||||
{
|
{
|
||||||
char scratch[64];
|
char scratch[64];
|
||||||
|
|
||||||
if (BadPtr(ip))
|
if (BadPtr(ip))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (inet_pton(AF_INET, ip, scratch) == 1)
|
if (inet_pton(AF_INET, ip, scratch) == 1)
|
||||||
return 4; /* IPv4 */
|
return 4; /* IPv4 */
|
||||||
|
|
||||||
if (inet_pton(AF_INET6, ip, scratch) == 1)
|
if (inet_pton(AF_INET6, ip, scratch) == 1)
|
||||||
return 6; /* IPv6 */
|
return 6; /* IPv6 */
|
||||||
|
|
||||||
return 0; /* not an IP address */
|
return 0; /* not an IP address */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1060,11 +1197,21 @@ int ipv6_capable(void)
|
||||||
int s = socket(AF_INET6, SOCK_STREAM, 0);
|
int s = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
return 0; /* NO ipv6 */
|
return 0; /* NO ipv6 */
|
||||||
|
|
||||||
CLOSE_SOCK(s);
|
CLOSE_SOCK(s);
|
||||||
return 1; /* YES */
|
return 1; /* YES */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return 1 if UNIX sockets of type SOCK_STREAM are supported, and 0 otherwise */
|
||||||
|
int unix_sockets_capable(void)
|
||||||
|
{
|
||||||
|
int fd = fd_socket(AF_UNIX, SOCK_STREAM, 0, "Testing UNIX socket");
|
||||||
|
if (fd < 0)
|
||||||
|
return 0;
|
||||||
|
fd_close(fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/** Attempt to deliver data to a client.
|
/** Attempt to deliver data to a client.
|
||||||
* This function is only called from send_queued() and will deal
|
* This function is only called from send_queued() and will deal
|
||||||
* with sending to the TLS or plaintext connection.
|
* with sending to the TLS or plaintext connection.
|
||||||
|
@ -1156,7 +1303,7 @@ int deliver_it(Client *client, char *str, int len, int *want_read)
|
||||||
int unreal_connect(int fd, const char *ip, int port, int ipv6)
|
int unreal_connect(int fd, const char *ip, int port, int ipv6)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (ipv6)
|
if (ipv6)
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 server;
|
struct sockaddr_in6 server;
|
||||||
|
@ -1182,25 +1329,17 @@ int unreal_connect(int fd, const char *ip, int port, int ipv6)
|
||||||
{
|
{
|
||||||
return 0; /* FATAL ERROR */
|
return 0; /* FATAL ERROR */
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; /* SUCCESS (probably still in progress) */
|
return 1; /* SUCCESS (probably still in progress) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Bind to an IP/port (port may be 0 for auto).
|
/** Bind to an IP/port (port may be 0 for auto).
|
||||||
* @returns 0 on failure, other on success.
|
* @returns 0 on failure, other on success.
|
||||||
*/
|
*/
|
||||||
int unreal_bind(int fd, const char *ip, int port, int ipv6)
|
int unreal_bind(int fd, const char *ip, int port, SocketType socket_type)
|
||||||
{
|
{
|
||||||
if (ipv6)
|
if (socket_type == SOCKET_TYPE_IPV4)
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 server;
|
|
||||||
memset(&server, 0, sizeof(server));
|
|
||||||
server.sin6_family = AF_INET6;
|
|
||||||
server.sin6_port = htons(port);
|
|
||||||
if (inet_pton(AF_INET6, ip, &server.sin6_addr.s6_addr) != 1)
|
|
||||||
return 0;
|
|
||||||
return !bind(fd, (struct sockaddr *)&server, sizeof(server));
|
|
||||||
} else {
|
|
||||||
struct sockaddr_in server;
|
struct sockaddr_in server;
|
||||||
memset(&server, 0, sizeof(server));
|
memset(&server, 0, sizeof(server));
|
||||||
server.sin_family = AF_INET;
|
server.sin_family = AF_INET;
|
||||||
|
@ -1209,4 +1348,43 @@ int unreal_bind(int fd, const char *ip, int port, int ipv6)
|
||||||
return 0;
|
return 0;
|
||||||
return !bind(fd, (struct sockaddr *)&server, sizeof(server));
|
return !bind(fd, (struct sockaddr *)&server, sizeof(server));
|
||||||
}
|
}
|
||||||
|
else if (socket_type == SOCKET_TYPE_IPV6)
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 server;
|
||||||
|
memset(&server, 0, sizeof(server));
|
||||||
|
server.sin6_family = AF_INET6;
|
||||||
|
server.sin6_port = htons(port);
|
||||||
|
if (inet_pton(AF_INET6, ip, &server.sin6_addr.s6_addr) != 1)
|
||||||
|
return 0;
|
||||||
|
return !bind(fd, (struct sockaddr *)&server, sizeof(server));
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
struct sockaddr_un server;
|
||||||
|
mode_t saved_umask;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
unlink(ip); /* (ignore errors) */
|
||||||
|
|
||||||
|
memset(&server, 0, sizeof(server));
|
||||||
|
server.sun_family = AF_UNIX;
|
||||||
|
strlcpy(server.sun_path, ip, sizeof(server.sun_path));
|
||||||
|
saved_umask = umask(077); // TODO: make this configurable
|
||||||
|
ret = !bind(fd, (struct sockaddr *)&server, sizeof(server));
|
||||||
|
umask(saved_umask);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
void init_winsock(void)
|
||||||
|
{
|
||||||
|
WSADATA WSAData;
|
||||||
|
if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
|
||||||
|
{
|
||||||
|
MessageBox(NULL, "Unable to initialize WinSock", "UnrealIRCD Initalization Error", MB_OK);
|
||||||
|
fprintf(stderr, "Unable to initialize WinSock\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
14
src/tls.c
14
src/tls.c
|
@ -512,7 +512,7 @@ int init_tls(void)
|
||||||
|
|
||||||
/** Reinitialize TLS server and client contexts - after REHASH -tls
|
/** Reinitialize TLS server and client contexts - after REHASH -tls
|
||||||
*/
|
*/
|
||||||
void reinit_tls(void)
|
int reinit_tls(void)
|
||||||
{
|
{
|
||||||
SSL_CTX *tmp;
|
SSL_CTX *tmp;
|
||||||
ConfigItem_listen *listen;
|
ConfigItem_listen *listen;
|
||||||
|
@ -524,7 +524,7 @@ void reinit_tls(void)
|
||||||
{
|
{
|
||||||
unreal_log(ULOG_ERROR, "config", "TLS_RELOAD_FAILED", NULL,
|
unreal_log(ULOG_ERROR, "config", "TLS_RELOAD_FAILED", NULL,
|
||||||
"TLS Reload failed. See previous errors.");
|
"TLS Reload failed. See previous errors.");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ctx_server)
|
if (ctx_server)
|
||||||
SSL_CTX_free(ctx_server);
|
SSL_CTX_free(ctx_server);
|
||||||
|
@ -535,7 +535,7 @@ void reinit_tls(void)
|
||||||
{
|
{
|
||||||
unreal_log(ULOG_ERROR, "config", "TLS_RELOAD_FAILED", NULL,
|
unreal_log(ULOG_ERROR, "config", "TLS_RELOAD_FAILED", NULL,
|
||||||
"TLS Reload failed at client context. See previous errors.");
|
"TLS Reload failed at client context. See previous errors.");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ctx_client)
|
if (ctx_client)
|
||||||
SSL_CTX_free(ctx_client);
|
SSL_CTX_free(ctx_client);
|
||||||
|
@ -551,7 +551,7 @@ void reinit_tls(void)
|
||||||
{
|
{
|
||||||
unreal_log(ULOG_ERROR, "config", "TLS_RELOAD_FAILED", NULL,
|
unreal_log(ULOG_ERROR, "config", "TLS_RELOAD_FAILED", NULL,
|
||||||
"TLS Reload failed at listen::tls-options. See previous errors.");
|
"TLS Reload failed at listen::tls-options. See previous errors.");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (listen->ssl_ctx)
|
if (listen->ssl_ctx)
|
||||||
SSL_CTX_free(listen->ssl_ctx);
|
SSL_CTX_free(listen->ssl_ctx);
|
||||||
|
@ -569,7 +569,7 @@ void reinit_tls(void)
|
||||||
{
|
{
|
||||||
unreal_log(ULOG_ERROR, "config", "TLS_RELOAD_FAILED", NULL,
|
unreal_log(ULOG_ERROR, "config", "TLS_RELOAD_FAILED", NULL,
|
||||||
"TLS Reload failed at sni::tls-options. See previous errors.");
|
"TLS Reload failed at sni::tls-options. See previous errors.");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (sni->ssl_ctx)
|
if (sni->ssl_ctx)
|
||||||
SSL_CTX_free(sni->ssl_ctx);
|
SSL_CTX_free(sni->ssl_ctx);
|
||||||
|
@ -588,13 +588,15 @@ void reinit_tls(void)
|
||||||
unreal_log(ULOG_ERROR, "config", "TLS_RELOAD_FAILED", NULL,
|
unreal_log(ULOG_ERROR, "config", "TLS_RELOAD_FAILED", NULL,
|
||||||
"TLS Reload failed at link $servername due to outgoing::tls-options. See previous errors.",
|
"TLS Reload failed at link $servername due to outgoing::tls-options. See previous errors.",
|
||||||
log_data_string("servername", link->servername));
|
log_data_string("servername", link->servername));
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (link->ssl_ctx)
|
if (link->ssl_ctx)
|
||||||
SSL_CTX_free(link->ssl_ctx);
|
SSL_CTX_free(link->ssl_ctx);
|
||||||
link->ssl_ctx = tmp; /* activate */
|
link->ssl_ctx = tmp; /* activate */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set SSL connection as nonblocking */
|
/** Set SSL connection as nonblocking */
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
/************************************************************************
|
||||||
|
* UnrealIRCd - Unreal Internet Relay Chat Daemon - src/unrealircdctl
|
||||||
|
* (c) 2022- Bram Matthys and The UnrealIRCd team
|
||||||
|
*
|
||||||
|
* See file AUTHORS in IRC package for additional names of
|
||||||
|
* the programmers.
|
||||||
|
*
|
||||||
|
* 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 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief UnrealIRCd Control
|
||||||
|
*/
|
||||||
|
#include "unrealircd.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define UNREALCMD "unrealircdctl"
|
||||||
|
#else
|
||||||
|
#define UNREALCMD "./unrealircd"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern int procio_client(const char *command, int auto_color_logs);
|
||||||
|
|
||||||
|
void unrealircdctl_usage(const char *program_name)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <option>\n"
|
||||||
|
"Where <option> is one of:\n"
|
||||||
|
"rehash - Rehash the server (reread configuration files)\n"
|
||||||
|
"reloadtls - Reload the SSL/TLS certificates\n"
|
||||||
|
"status - Show current status of server\n"
|
||||||
|
"module-status - Show currently loaded modules\n"
|
||||||
|
"mkpasswd - Hash a password\n"
|
||||||
|
"gencloak - Display 3 random cloak keys\n"
|
||||||
|
"spkifp - Display SPKI Fingerprint\n"
|
||||||
|
"\n", program_name);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unrealircdctl_rehash(void)
|
||||||
|
{
|
||||||
|
if (procio_client("REHASH", 1) == 0)
|
||||||
|
{
|
||||||
|
printf("Rehashed succesfully.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
printf("Rehash failed.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unrealircdctl_reloadtls(void)
|
||||||
|
{
|
||||||
|
if (procio_client("REHASH -tls", 1) == 0)
|
||||||
|
{
|
||||||
|
printf("Reloading of TLS certificates successful.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
printf("Reloading TLS certificates failed.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unrealircdctl_status(void)
|
||||||
|
{
|
||||||
|
if (procio_client("STATUS", 2) == 0)
|
||||||
|
{
|
||||||
|
printf("UnrealIRCd is up and running.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
printf("UnrealIRCd status report failed.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unrealircdctl_module_status(void)
|
||||||
|
{
|
||||||
|
if (procio_client("MODULES", 2) == 0)
|
||||||
|
exit(0);
|
||||||
|
printf("Could not retrieve complete module list.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unrealircdctl_mkpasswd(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
AuthenticationType type;
|
||||||
|
const char *result;
|
||||||
|
char *p = argv[2];
|
||||||
|
|
||||||
|
type = Auth_FindType(NULL, p);
|
||||||
|
if (type == -1)
|
||||||
|
{
|
||||||
|
type = AUTHTYPE_ARGON2;
|
||||||
|
} else {
|
||||||
|
p = argv[3];
|
||||||
|
}
|
||||||
|
if (BadPtr(p))
|
||||||
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
|
p = getpass("Enter password to hash: ");
|
||||||
|
#else
|
||||||
|
printf("ERROR: You should specify a password to hash");
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if ((type == AUTHTYPE_UNIXCRYPT) && (strlen(p) > 8))
|
||||||
|
{
|
||||||
|
/* Hmmm.. is this warning really still true (and always) ?? */
|
||||||
|
printf("WARNING: Password truncated to 8 characters due to 'crypt' algorithm. "
|
||||||
|
"You are suggested to use the 'argon2' algorithm instead.");
|
||||||
|
p[8] = '\0';
|
||||||
|
}
|
||||||
|
if (!(result = Auth_Hash(type, p))) {
|
||||||
|
printf("Failed to generate password. Deprecated method? Try 'argon2' instead.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
printf("Encrypted password is: %s\n", result);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unrealircdctl_gencloak(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
#define GENERATE_CLOAKKEY_LEN 80 /* Length of cloak keys to generate. */
|
||||||
|
char keyBuf[GENERATE_CLOAKKEY_LEN + 1];
|
||||||
|
int keyNum;
|
||||||
|
int charIndex;
|
||||||
|
|
||||||
|
short has_upper;
|
||||||
|
short has_lower;
|
||||||
|
short has_num;
|
||||||
|
|
||||||
|
printf("Here are 3 random cloak keys that you can copy-paste to your configuration file:\n\n");
|
||||||
|
|
||||||
|
printf("set {\n\tcloak-keys {\n");
|
||||||
|
for (keyNum = 0; keyNum < 3; ++keyNum)
|
||||||
|
{
|
||||||
|
has_upper = 0;
|
||||||
|
has_lower = 0;
|
||||||
|
has_num = 0;
|
||||||
|
|
||||||
|
for (charIndex = 0; charIndex < sizeof(keyBuf)-1; ++charIndex)
|
||||||
|
{
|
||||||
|
switch (getrandom8() % 3)
|
||||||
|
{
|
||||||
|
case 0: /* Uppercase. */
|
||||||
|
keyBuf[charIndex] = (char)('A' + (getrandom8() % ('Z' - 'A')));
|
||||||
|
has_upper = 1;
|
||||||
|
break;
|
||||||
|
case 1: /* Lowercase. */
|
||||||
|
keyBuf[charIndex] = (char)('a' + (getrandom8() % ('z' - 'a')));
|
||||||
|
has_lower = 1;
|
||||||
|
break;
|
||||||
|
case 2: /* Digit. */
|
||||||
|
keyBuf[charIndex] = (char)('0' + (getrandom8() % ('9' - '0')));
|
||||||
|
has_num = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keyBuf[sizeof(keyBuf)-1] = '\0';
|
||||||
|
|
||||||
|
if (has_upper && has_lower && has_num)
|
||||||
|
printf("\t\t\"%s\";\n", keyBuf);
|
||||||
|
else
|
||||||
|
/* Try again. For this reason, keyNum must be signed. */
|
||||||
|
keyNum--;
|
||||||
|
}
|
||||||
|
printf("\t}\n}\n\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unrealircdctl_spkifp(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *file = argv[2];
|
||||||
|
SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
|
||||||
|
SSL *ssl;
|
||||||
|
X509 *cert;
|
||||||
|
const char *spkifp;
|
||||||
|
|
||||||
|
if (!ctx)
|
||||||
|
{
|
||||||
|
printf("Internal failure while initializing SSL/TLS library context\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
printf("NOTE: This script uses the default certificate location (any set::tls settings\n"
|
||||||
|
"are ignored). If this is not what you want then specify a certificate\n"
|
||||||
|
"explicitly like this: %s spkifp conf/tls/example.pem\n\n", UNREALCMD);
|
||||||
|
safe_strdup(file, "tls/server.cert.pem");
|
||||||
|
convert_to_absolute_path(&file, CONFDIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists(file))
|
||||||
|
{
|
||||||
|
printf("Could not open certificate: %s\n"
|
||||||
|
"You can specify a certificate like this: %s spkifp conf/tls/example.pem\n",
|
||||||
|
UNREALCMD, file);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SSL_CTX_use_certificate_chain_file(ctx, file) <= 0)
|
||||||
|
{
|
||||||
|
printf("Could not read certificate '%s'\n", file);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl = SSL_new(ctx);
|
||||||
|
if (!ssl)
|
||||||
|
{
|
||||||
|
printf("Something went wrong when generating the SPKI fingerprint.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cert = SSL_get_certificate(ssl);
|
||||||
|
spkifp = spki_fingerprint_ex(cert);
|
||||||
|
printf("The SPKI fingerprint for certificate '%s' is:\n"
|
||||||
|
"%s\n"
|
||||||
|
"\n"
|
||||||
|
"You normally add this password on the other side of the link as:\n"
|
||||||
|
"password \"%s\" { spkifp; };\n"
|
||||||
|
"\n",
|
||||||
|
file, spkifp, spkifp);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
chdir(".."); /* go up one level from "bin" */
|
||||||
|
init_winsock();
|
||||||
|
#endif
|
||||||
|
dbuf_init();
|
||||||
|
init_random();
|
||||||
|
early_init_tls();
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
unrealircdctl_usage(argv[0]);
|
||||||
|
|
||||||
|
if (!strcmp(argv[1], "rehash"))
|
||||||
|
unrealircdctl_rehash();
|
||||||
|
else if (!strcmp(argv[1], "reloadtls"))
|
||||||
|
unrealircdctl_reloadtls();
|
||||||
|
else if (!strcmp(argv[1], "status"))
|
||||||
|
unrealircdctl_status();
|
||||||
|
else if (!strcmp(argv[1], "module-status"))
|
||||||
|
unrealircdctl_module_status();
|
||||||
|
else if (!strcmp(argv[1], "mkpasswd"))
|
||||||
|
unrealircdctl_mkpasswd(argc, argv);
|
||||||
|
else if (!strcmp(argv[1], "gencloak"))
|
||||||
|
unrealircdctl_gencloak(argc, argv);
|
||||||
|
else if (!strcmp(argv[1], "spkifp") || !strcmp(argv[1], "spki"))
|
||||||
|
unrealircdctl_spkifp(argc, argv);
|
||||||
|
else
|
||||||
|
unrealircdctl_usage(argv[0]);
|
||||||
|
exit(0);
|
||||||
|
}
|
|
@ -1083,6 +1083,7 @@ MODVAR const char *floodoption_names[] = {
|
||||||
"knock-flood",
|
"knock-flood",
|
||||||
"max-concurrent-conversations",
|
"max-concurrent-conversations",
|
||||||
"lag-penalty",
|
"lag-penalty",
|
||||||
|
"vhost-flood",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ echo "Extracting src/version.c..."
|
||||||
if [ -d ../.git ]; then
|
if [ -d ../.git ]; then
|
||||||
SUFFIX="-$(git rev-parse --short HEAD)"
|
SUFFIX="-$(git rev-parse --short HEAD)"
|
||||||
fi
|
fi
|
||||||
id="6.0.1.1$SUFFIX"
|
id="6.0.3$SUFFIX"
|
||||||
echo "$id"
|
echo "$id"
|
||||||
|
|
||||||
if test -r version.c
|
if test -r version.c
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<assemblyIdentity
|
<assemblyIdentity
|
||||||
processorArchitecture="amd64"
|
processorArchitecture="amd64"
|
||||||
name="UnrealIRCd.UnrealIRCd.6"
|
name="UnrealIRCd.UnrealIRCd.6"
|
||||||
version="6.0.1.0"
|
version="6.0.3.0"
|
||||||
type="win32"
|
type="win32"
|
||||||
/>
|
/>
|
||||||
<description>Internet Relay Chat Daemon</description>
|
<description>Internet Relay Chat Daemon</description>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<assemblyIdentity
|
<assemblyIdentity
|
||||||
type="win32"
|
type="win32"
|
||||||
name="Microsoft.Windows.Common-Controls"
|
name="Microsoft.Windows.Common-Controls"
|
||||||
version="6.0.1.0"
|
version="6.0.0.0"
|
||||||
processorArchitecture="amd64"
|
processorArchitecture="amd64"
|
||||||
publicKeyToken="6595b64144ccf1df"
|
publicKeyToken="6595b64144ccf1df"
|
||||||
language="*"
|
language="*"
|
||||||
|
|
|
@ -188,7 +188,6 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
||||||
MSG msg;
|
MSG msg;
|
||||||
unsigned char *s;
|
unsigned char *s;
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
WSADATA WSAData;
|
|
||||||
HICON hIcon;
|
HICON hIcon;
|
||||||
SC_HANDLE hService, hSCManager;
|
SC_HANDLE hService, hSCManager;
|
||||||
SERVICE_TABLE_ENTRY DispatchTable[] =
|
SERVICE_TABLE_ENTRY DispatchTable[] =
|
||||||
|
@ -250,12 +249,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
||||||
if (!LoadLibrary("riched20.dll"))
|
if (!LoadLibrary("riched20.dll"))
|
||||||
LoadLibrary("riched32.dll");
|
LoadLibrary("riched32.dll");
|
||||||
InitDebug();
|
InitDebug();
|
||||||
|
init_winsock();
|
||||||
if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
|
|
||||||
{
|
|
||||||
MessageBox(NULL, "Unable to initialize WinSock", "UnrealIRCD Initalization Error", MB_OK);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
hInst = hInstance;
|
hInst = hInstance;
|
||||||
|
|
||||||
MainDlgBackground = CreateSolidBrush(RGB(75, 134, 238)); /* Background of main dialog */
|
MainDlgBackground = CreateSolidBrush(RGB(75, 134, 238)); /* Background of main dialog */
|
||||||
|
|
|
@ -90,7 +90,6 @@ VOID WINAPI IRCDCtrlHandler(DWORD opcode)
|
||||||
*/
|
*/
|
||||||
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
|
VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
|
||||||
{
|
{
|
||||||
WSADATA WSAData;
|
|
||||||
DWORD error = 0;
|
DWORD error = 0;
|
||||||
char path[MAX_PATH], *folder;
|
char path[MAX_PATH], *folder;
|
||||||
|
|
||||||
|
@ -121,13 +120,7 @@ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
|
||||||
GetOSName(OSName);
|
GetOSName(OSName);
|
||||||
|
|
||||||
InitDebug();
|
InitDebug();
|
||||||
|
init_winsock();
|
||||||
/* Initialize Winsocks */
|
|
||||||
if ((error = WSAStartup(MAKEWORD(1, 1), &WSAData)) != 0)
|
|
||||||
{
|
|
||||||
SetServiceStop(error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the IRCd */
|
/* Initialize the IRCd */
|
||||||
if ((error = InitUnrealIRCd(dwArgc, lpszArgv)) != 1)
|
if ((error = InitUnrealIRCd(dwArgc, lpszArgv)) != 1)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
AppName=UnrealIRCd 6
|
AppName=UnrealIRCd 6
|
||||||
AppVerName=UnrealIRCd 6.0.1.1
|
AppVerName=UnrealIRCd 6.0.3
|
||||||
AppPublisher=UnrealIRCd Team
|
AppPublisher=UnrealIRCd Team
|
||||||
AppPublisherURL=https://www.unrealircd.org
|
AppPublisherURL=https://www.unrealircd.org
|
||||||
AppSupportURL=https://www.unrealircd.org
|
AppSupportURL=https://www.unrealircd.org
|
||||||
|
@ -45,6 +45,7 @@ Name: "fixperm"; Description: "Make UnrealIRCd folder writable by current user";
|
||||||
; UnrealIRCd binaries
|
; UnrealIRCd binaries
|
||||||
Source: "UnrealIRCd.exe"; DestDir: "{app}\bin"; Flags: ignoreversion signonce
|
Source: "UnrealIRCd.exe"; DestDir: "{app}\bin"; Flags: ignoreversion signonce
|
||||||
Source: "UnrealIRCd.pdb"; DestDir: "{app}\bin"; Flags: ignoreversion
|
Source: "UnrealIRCd.pdb"; DestDir: "{app}\bin"; Flags: ignoreversion
|
||||||
|
Source: "unrealircdctl.exe"; DestDir: "{app}\bin"; Flags: ignoreversion signonce
|
||||||
Source: "unrealsvc.exe"; DestDir: "{app}\bin"; Flags: ignoreversion signonce
|
Source: "unrealsvc.exe"; DestDir: "{app}\bin"; Flags: ignoreversion signonce
|
||||||
|
|
||||||
; TLS certificate generation helpers
|
; TLS certificate generation helpers
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||||
|
<assemblyIdentity
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
name="UnrealIRCd.UnrealIRCd.6"
|
||||||
|
version="6.0.1.0"
|
||||||
|
type="win32"
|
||||||
|
/>
|
||||||
|
<description>UnrealIRCd - Control utility</description>
|
||||||
|
</assembly>
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
PID_FILE="@PIDFILE@"
|
PID_FILE="@PIDFILE@"
|
||||||
PID_BACKUP="@PIDFILE@.bak"
|
PID_BACKUP="@PIDFILE@.bak"
|
||||||
|
UNREALIRCDCTL="@BINDIR@/unrealircdctl"
|
||||||
|
|
||||||
# When built with --with-asan, ASan does not dump core by default because
|
# When built with --with-asan, ASan does not dump core by default because
|
||||||
# older gcc/clang might dump a 16TB core file. We explicitly enable it here.
|
# older gcc/clang might dump a 16TB core file. We explicitly enable it here.
|
||||||
|
@ -87,16 +88,13 @@ elif [ "$1" = "stop" ] ; then
|
||||||
kill -9 `cat $PID_FILE` 1>/dev/null 2>&1
|
kill -9 `cat $PID_FILE` 1>/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
elif [ "$1" = "rehash" ] ; then
|
elif [ "$1" = "rehash" ] ; then
|
||||||
echo "Rehashing UnrealIRCd"
|
$UNREALIRCDCTL $*
|
||||||
if [ ! -r $PID_FILE ] ; then
|
elif [ "$1" = "status" ] ; then
|
||||||
echo "ERROR: UnrealIRCd is not running"
|
$UNREALIRCDCTL $*
|
||||||
exit 1
|
elif [ "$1" = "module-status" ] ; then
|
||||||
fi
|
$UNREALIRCDCTL $*
|
||||||
kill -1 `cat $PID_FILE`
|
elif [ "$1" = "reloadtls" ] ; then
|
||||||
if [ "$?" != 0 ]; then
|
$UNREALIRCDCTL $*
|
||||||
echo "ERROR: UnrealIRCd is not running"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
elif [ "$1" = "restart" ] ; then
|
elif [ "$1" = "restart" ] ; then
|
||||||
echo "Restarting UnrealIRCd"
|
echo "Restarting UnrealIRCd"
|
||||||
$0 stop
|
$0 stop
|
||||||
|
@ -117,23 +115,12 @@ elif [ "$1" = "configtest" ] ; then
|
||||||
elif [ "$1" = "module" ] ; then
|
elif [ "$1" = "module" ] ; then
|
||||||
shift
|
shift
|
||||||
@BINDIR@/unrealircd -m $*
|
@BINDIR@/unrealircd -m $*
|
||||||
elif [ "$1" = "reloadtls" ] ; then
|
|
||||||
echo "Reloading SSL/TLS certificates"
|
|
||||||
if [ ! -r $PID_FILE ] ; then
|
|
||||||
echo "ERROR: UnrealIRCd is not running"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
kill -USR1 `cat $PID_FILE`
|
|
||||||
if [ "$?" != 0 ]; then
|
|
||||||
echo "ERROR: UnrealIRCd is not running"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
elif [ "$1" = "mkpasswd" ] ; then
|
elif [ "$1" = "mkpasswd" ] ; then
|
||||||
@BINDIR@/unrealircd -P $2 $3
|
$UNREALIRCDCTL $*
|
||||||
elif [ "$1" = "version" ] ; then
|
elif [ "$1" = "version" ] ; then
|
||||||
@BINDIR@/unrealircd -v
|
@BINDIR@/unrealircd -v
|
||||||
elif [ "$1" = "gencloak" ] ; then
|
elif [ "$1" = "gencloak" ] ; then
|
||||||
@BINDIR@/unrealircd -k
|
$UNREALIRCDCTL $*
|
||||||
elif [ "$1" = "backtrace" ] ; then
|
elif [ "$1" = "backtrace" ] ; then
|
||||||
cd @TMPDIR@
|
cd @TMPDIR@
|
||||||
|
|
||||||
|
@ -224,34 +211,7 @@ __EOF__
|
||||||
echo ""
|
echo ""
|
||||||
echo "Thanks!"
|
echo "Thanks!"
|
||||||
elif [ "$1" = "spki" -o "$1" = "spkifp" ] ; then
|
elif [ "$1" = "spki" -o "$1" = "spkifp" ] ; then
|
||||||
CERT="@CONFDIR@/tls/server.cert.pem"
|
$UNREALIRCDCTL $*
|
||||||
if [ "$2" != "" ]; then
|
|
||||||
CERT="$2"
|
|
||||||
else
|
|
||||||
echo "NOTE: This script uses the default certificate location (any set::tls settings"
|
|
||||||
echo "are ignored). If this is not what you want then specify a certificate"
|
|
||||||
echo "explicitly like this: ./unrealircd spkifp conf/tls/example.pem"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
if [ ! -f "$CERT" ]; then
|
|
||||||
echo "Could not open certificate: $CERT"
|
|
||||||
echo "You can specify a certificate like this: ./unrealircd spkifp conf/tls/example.pem"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
openssl x509 -noout -in "$CERT" -pubkey | openssl asn1parse -noout -inform pem -out @TMPDIR@/tmp.public.key
|
|
||||||
HASH="`openssl dgst -sha256 -binary @TMPDIR@/tmp.public.key | openssl enc -base64`"
|
|
||||||
rm -f @TMPDIR@/tmp.public.key
|
|
||||||
if [ "$HASH" = "" ]; then
|
|
||||||
echo "Sorry, something went wrong when generating the SPKI fingerprint."
|
|
||||||
echo "Is the 'openssl' tool properly installed?"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "The SPKI fingerprint for certificate $CERT is:"
|
|
||||||
echo "$HASH"
|
|
||||||
echo ""
|
|
||||||
echo "You normally add this password on the other side of the link as:"
|
|
||||||
echo "password \"$HASH\" { spkifp; };"
|
|
||||||
echo ""
|
|
||||||
elif [ "$1" = "hot-patch" -o "$1" = "cold-patch" ] ; then
|
elif [ "$1" = "hot-patch" -o "$1" = "cold-patch" ] ; then
|
||||||
if [ ! -d "@BUILDDIR@" ]; then
|
if [ ! -d "@BUILDDIR@" ]; then
|
||||||
echo "UnrealIRCd source not found. Sorry, it is not possible to patch."
|
echo "UnrealIRCd source not found. Sorry, it is not possible to patch."
|
||||||
|
@ -282,6 +242,11 @@ elif [ "$1" = "hot-patch" -o "$1" = "cold-patch" ] ; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! patch --dry-run -p1 -N <patch 1>/dev/null 2>&1; then
|
||||||
|
echo "Patch failed to apply (no files changed)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if ! patch -p1 <patch; then
|
if ! patch -p1 <patch; then
|
||||||
echo "Patch failed to apply"
|
echo "Patch failed to apply"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -291,11 +256,18 @@ elif [ "$1" = "hot-patch" -o "$1" = "cold-patch" ] ; then
|
||||||
make || gmake || exit 1
|
make || gmake || exit 1
|
||||||
make install || gmake install || exit 1
|
make install || gmake install || exit 1
|
||||||
|
|
||||||
cd -
|
cd @SCRIPTDIR@
|
||||||
if [ "$1" = "hot-patch" ]; then
|
if [ "$1" = "hot-patch" ]; then
|
||||||
echo "Patch applied successfully and installed. Rehashing your IRCd..."
|
echo "Patch applied successfully and installed. Rehashing your IRCd..."
|
||||||
./unrealircd rehash
|
if ./unrealircd rehash; then
|
||||||
echo "Done! All should be good now."
|
echo "Patch installed and server rehashed correctly. All should be good now!"
|
||||||
|
else
|
||||||
|
echo "Patching the source code and recompiling succeeded,"
|
||||||
|
echo "however rehashing the current UnrealIRCd process FAILED"
|
||||||
|
echo "so it is NOT running the patched code yet."
|
||||||
|
echo "IMPORTANT: Check error output above!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo "Patch applied successfully. You must now restart your IRC server."
|
echo "Patch applied successfully. You must now restart your IRC server."
|
||||||
fi
|
fi
|
||||||
|
@ -316,6 +288,8 @@ else
|
||||||
echo "unrealircd rehash Reload the configuration file"
|
echo "unrealircd rehash Reload the configuration file"
|
||||||
echo "unrealircd reloadtls Reload the SSL/TLS certificates"
|
echo "unrealircd reloadtls Reload the SSL/TLS certificates"
|
||||||
echo "unrealircd restart Restart the IRC Server (stop+start)"
|
echo "unrealircd restart Restart the IRC Server (stop+start)"
|
||||||
|
echo "unrealircd status Show current status of the IRC Server"
|
||||||
|
echo "unrealircd module-status Show all currently loaded modules"
|
||||||
echo "unrealircd upgrade Upgrade UnrealIRCd to the latest version"
|
echo "unrealircd upgrade Upgrade UnrealIRCd to the latest version"
|
||||||
echo "unrealircd upgrade-conf Upgrade the configuration file from UnrealIRCd"
|
echo "unrealircd upgrade-conf Upgrade the configuration file from UnrealIRCd"
|
||||||
echo " 3.2.x/4.x to 5.x format"
|
echo " 3.2.x/4.x to 5.x format"
|
||||||
|
|
Loading…
Reference in New Issue