summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2010-06-19 11:54:08 -0400
committerAdam <Adam@anope.org>2010-06-19 11:54:08 -0400
commit52058fe87b4b0475b1775198c725af14e540d355 (patch)
treec3597d6411a006ffbb670d2ce761101b9640e9b6 /src
parent43e951aed54f838ba55a4c1552214773aee2fb2f (diff)
parentdf9d291bcba9788e51d11424ebaf6f05c26cc80f (diff)
Merge remote branch 'origin/1.9.3' into 1.9
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt13
-rw-r--r--src/Makefile96
-rw-r--r--src/actions.cpp (renamed from src/actions.c)46
-rw-r--r--src/base64.cpp (renamed from src/base64.c)0
-rw-r--r--src/bots.cpp93
-rw-r--r--src/botserv.cpp (renamed from src/botserv.c)430
-rw-r--r--src/channels.cpp (renamed from src/channels.c)185
-rw-r--r--src/chanserv.cpp (renamed from src/chanserv.c)483
-rw-r--r--src/command.cpp33
-rw-r--r--src/commands.cpp (renamed from src/commands.c)137
-rw-r--r--src/compat.cpp (renamed from src/compat.c)0
-rw-r--r--src/config.cpp (renamed from src/config.c)50
-rw-r--r--src/core/CMakeLists.txt3
-rw-r--r--src/core/Makefile8
-rw-r--r--src/core/bs_act.cpp (renamed from src/core/bs_act.c)15
-rw-r--r--src/core/bs_assign.cpp (renamed from src/core/bs_assign.c)13
-rw-r--r--src/core/bs_badwords.cpp (renamed from src/core/bs_badwords.c)185
-rw-r--r--src/core/bs_bot.cpp (renamed from src/core/bs_bot.c)28
-rw-r--r--src/core/bs_botlist.cpp (renamed from src/core/bs_botlist.c)55
-rw-r--r--src/core/bs_help.cpp (renamed from src/core/bs_help.c)7
-rw-r--r--src/core/bs_info.cpp (renamed from src/core/bs_info.c)40
-rw-r--r--src/core/bs_kick.cpp (renamed from src/core/bs_kick.c)13
-rw-r--r--src/core/bs_say.cpp (renamed from src/core/bs_say.c)13
-rw-r--r--src/core/bs_set.cpp (renamed from src/core/bs_set.c)13
-rw-r--r--src/core/bs_unassign.cpp (renamed from src/core/bs_unassign.c)13
-rw-r--r--src/core/cs_access.c589
-rw-r--r--src/core/cs_access.cpp664
-rw-r--r--src/core/cs_akick.cpp (renamed from src/core/cs_akick.c)343
-rw-r--r--src/core/cs_ban.cpp (renamed from src/core/cs_ban.c)21
-rw-r--r--src/core/cs_clear.cpp (renamed from src/core/cs_clear.c)13
-rw-r--r--src/core/cs_drop.cpp (renamed from src/core/cs_drop.c)22
-rw-r--r--src/core/cs_forbid.cpp (renamed from src/core/cs_forbid.c)22
-rw-r--r--src/core/cs_getkey.cpp (renamed from src/core/cs_getkey.c)13
-rw-r--r--src/core/cs_help.cpp (renamed from src/core/cs_help.c)7
-rw-r--r--src/core/cs_info.cpp (renamed from src/core/cs_info.c)23
-rw-r--r--src/core/cs_invite.cpp (renamed from src/core/cs_invite.c)15
-rw-r--r--src/core/cs_kick.cpp (renamed from src/core/cs_kick.c)21
-rw-r--r--src/core/cs_list.cpp (renamed from src/core/cs_list.c)99
-rw-r--r--src/core/cs_modes.cpp (renamed from src/core/cs_modes.c)121
-rw-r--r--src/core/cs_register.cpp (renamed from src/core/cs_register.c)15
-rw-r--r--src/core/cs_saset.cpp131
-rw-r--r--src/core/cs_saset_noexpire.cpp85
-rw-r--r--src/core/cs_set.c839
-rw-r--r--src/core/cs_set.cpp136
-rw-r--r--src/core/cs_set_bantype.cpp113
-rw-r--r--src/core/cs_set_description.cpp107
-rw-r--r--src/core/cs_set_email.cpp106
-rw-r--r--src/core/cs_set_entrymsg.cpp114
-rw-r--r--src/core/cs_set_founder.cpp142
-rw-r--r--src/core/cs_set_keeptopic.cpp112
-rw-r--r--src/core/cs_set_mlock.cpp197
-rw-r--r--src/core/cs_set_opnotice.cpp112
-rw-r--r--src/core/cs_set_peace.cpp114
-rw-r--r--src/core/cs_set_persist.cpp163
-rw-r--r--src/core/cs_set_private.cpp112
-rw-r--r--src/core/cs_set_restricted.cpp116
-rw-r--r--src/core/cs_set_secure.cpp112
-rw-r--r--src/core/cs_set_securefounder.cpp118
-rw-r--r--src/core/cs_set_secureops.cpp112
-rw-r--r--src/core/cs_set_signkick.cpp112
-rw-r--r--src/core/cs_set_successor.cpp145
-rw-r--r--src/core/cs_set_topiclock.cpp112
-rw-r--r--src/core/cs_set_url.cpp114
-rw-r--r--src/core/cs_set_xop.cpp144
-rw-r--r--src/core/cs_status.cpp (renamed from src/core/cs_status.c)13
-rw-r--r--src/core/cs_suspend.cpp (renamed from src/core/cs_suspend.c)27
-rw-r--r--src/core/cs_topic.cpp (renamed from src/core/cs_topic.c)21
-rw-r--r--src/core/cs_unban.cpp (renamed from src/core/cs_unban.c)16
-rw-r--r--src/core/cs_xop.cpp (renamed from src/core/cs_xop.c)299
-rw-r--r--src/core/db_plain.cpp660
-rw-r--r--src/core/enc_md5.cpp (renamed from src/core/enc_md5.c)0
-rw-r--r--src/core/enc_none.cpp (renamed from src/core/enc_none.c)0
-rw-r--r--src/core/enc_old.cpp (renamed from src/core/enc_old.c)0
-rw-r--r--src/core/enc_sha1.cpp (renamed from src/core/enc_sha1.c)0
-rw-r--r--src/core/enc_sha256.cpp (renamed from src/core/enc_sha256.c)0
-rw-r--r--src/core/hs_del.cpp (renamed from src/core/hs_del.c)13
-rw-r--r--src/core/hs_delall.cpp (renamed from src/core/hs_delall.c)21
-rw-r--r--src/core/hs_group.cpp (renamed from src/core/hs_group.c)13
-rw-r--r--src/core/hs_help.cpp (renamed from src/core/hs_help.c)7
-rw-r--r--src/core/hs_list.cpp (renamed from src/core/hs_list.c)80
-rw-r--r--src/core/hs_off.cpp (renamed from src/core/hs_off.c)13
-rw-r--r--src/core/hs_on.cpp (renamed from src/core/hs_on.c)13
-rw-r--r--src/core/hs_set.cpp (renamed from src/core/hs_set.c)13
-rw-r--r--src/core/hs_setall.cpp (renamed from src/core/hs_setall.c)13
-rw-r--r--src/core/ms_cancel.cpp (renamed from src/core/ms_cancel.c)13
-rw-r--r--src/core/ms_check.cpp (renamed from src/core/ms_check.c)13
-rw-r--r--src/core/ms_del.cpp (renamed from src/core/ms_del.c)125
-rw-r--r--src/core/ms_help.cpp (renamed from src/core/ms_help.c)7
-rw-r--r--src/core/ms_info.cpp (renamed from src/core/ms_info.c)13
-rw-r--r--src/core/ms_list.cpp (renamed from src/core/ms_list.c)134
-rw-r--r--src/core/ms_read.cpp (renamed from src/core/ms_read.c)126
-rw-r--r--src/core/ms_rsend.cpp (renamed from src/core/ms_rsend.c)13
-rw-r--r--src/core/ms_send.cpp (renamed from src/core/ms_send.c)13
-rw-r--r--src/core/ms_sendall.cpp (renamed from src/core/ms_sendall.c)31
-rw-r--r--src/core/ms_set.cpp (renamed from src/core/ms_set.c)17
-rw-r--r--src/core/ms_staff.cpp (renamed from src/core/ms_staff.c)28
-rw-r--r--src/core/ns_access.cpp (renamed from src/core/ns_access.c)15
-rw-r--r--src/core/ns_alist.cpp (renamed from src/core/ns_alist.c)47
-rw-r--r--src/core/ns_drop.cpp (renamed from src/core/ns_drop.c)22
-rw-r--r--src/core/ns_forbid.cpp (renamed from src/core/ns_forbid.c)20
-rw-r--r--src/core/ns_getemail.cpp (renamed from src/core/ns_getemail.c)34
-rw-r--r--src/core/ns_getpass.cpp (renamed from src/core/ns_getpass.c)17
-rw-r--r--src/core/ns_ghost.cpp (renamed from src/core/ns_ghost.c)13
-rw-r--r--src/core/ns_group.cpp (renamed from src/core/ns_group.c)122
-rw-r--r--src/core/ns_help.cpp (renamed from src/core/ns_help.c)7
-rw-r--r--src/core/ns_identify.cpp (renamed from src/core/ns_identify.c)22
-rw-r--r--src/core/ns_info.cpp (renamed from src/core/ns_info.c)44
-rw-r--r--src/core/ns_list.cpp (renamed from src/core/ns_list.c)106
-rw-r--r--src/core/ns_logout.cpp (renamed from src/core/ns_logout.c)13
-rw-r--r--src/core/ns_recover.cpp (renamed from src/core/ns_recover.c)13
-rw-r--r--src/core/ns_register.cpp (renamed from src/core/ns_register.c)84
-rw-r--r--src/core/ns_release.cpp (renamed from src/core/ns_release.c)13
-rw-r--r--src/core/ns_resetpass.cpp (renamed from src/core/ns_resetpass.c)97
-rw-r--r--src/core/ns_saset.c599
-rw-r--r--src/core/ns_saset.cpp255
-rw-r--r--src/core/ns_saset_noexpire.cpp87
-rw-r--r--src/core/ns_sendpass.cpp (renamed from src/core/ns_sendpass.c)55
-rw-r--r--src/core/ns_set.c557
-rw-r--r--src/core/ns_set.cpp239
-rw-r--r--src/core/ns_set_autoop.cpp131
-rw-r--r--src/core/ns_set_email.cpp160
-rw-r--r--src/core/ns_set_greet.cpp129
-rw-r--r--src/core/ns_set_hide.cpp200
-rw-r--r--src/core/ns_set_icq.cpp136
-rw-r--r--src/core/ns_set_kill.cpp183
-rw-r--r--src/core/ns_set_language.cpp143
-rw-r--r--src/core/ns_set_message.cpp149
-rw-r--r--src/core/ns_set_private.cpp137
-rw-r--r--src/core/ns_set_secure.cpp137
-rw-r--r--src/core/ns_set_url.cpp128
-rw-r--r--src/core/ns_status.cpp (renamed from src/core/ns_status.c)13
-rw-r--r--src/core/ns_suspend.cpp (renamed from src/core/ns_suspend.c)33
-rw-r--r--src/core/ns_update.cpp (renamed from src/core/ns_update.c)12
-rw-r--r--src/core/os_akill.c409
-rw-r--r--src/core/os_akill.cpp402
-rw-r--r--src/core/os_chankill.cpp (renamed from src/core/os_chankill.c)25
-rw-r--r--src/core/os_chanlist.cpp (renamed from src/core/os_chanlist.c)42
-rw-r--r--src/core/os_clearmodes.cpp (renamed from src/core/os_clearmodes.c)15
-rw-r--r--src/core/os_defcon.cpp (renamed from src/core/os_defcon.c)68
-rw-r--r--src/core/os_global.cpp (renamed from src/core/os_global.c)15
-rw-r--r--src/core/os_help.cpp (renamed from src/core/os_help.c)7
-rw-r--r--src/core/os_ignore.cpp (renamed from src/core/os_ignore.c)18
-rw-r--r--src/core/os_jupe.cpp (renamed from src/core/os_jupe.c)27
-rw-r--r--src/core/os_kick.cpp (renamed from src/core/os_kick.c)17
-rw-r--r--src/core/os_mode.cpp (renamed from src/core/os_mode.c)17
-rw-r--r--src/core/os_modinfo.cpp (renamed from src/core/os_modinfo.c)60
-rw-r--r--src/core/os_modlist.cpp (renamed from src/core/os_modlist.c)120
-rw-r--r--src/core/os_modload.cpp (renamed from src/core/os_modload.c)23
-rw-r--r--src/core/os_modunload.cpp (renamed from src/core/os_modunload.c)23
-rw-r--r--src/core/os_news.cpp (renamed from src/core/os_news.c)36
-rw-r--r--src/core/os_noop.cpp (renamed from src/core/os_noop.c)25
-rw-r--r--src/core/os_oline.cpp (renamed from src/core/os_oline.c)19
-rw-r--r--src/core/os_quit.cpp (renamed from src/core/os_quit.c)13
-rw-r--r--src/core/os_reload.cpp (renamed from src/core/os_reload.c)13
-rw-r--r--src/core/os_restart.cpp (renamed from src/core/os_restart.c)13
-rw-r--r--src/core/os_session.cpp (renamed from src/core/os_session.c)303
-rw-r--r--src/core/os_set.cpp (renamed from src/core/os_set.c)21
-rw-r--r--src/core/os_sgline.c410
-rw-r--r--src/core/os_shutdown.cpp (renamed from src/core/os_shutdown.c)13
-rw-r--r--src/core/os_snline.cpp425
-rw-r--r--src/core/os_sqline.c395
-rw-r--r--src/core/os_sqline.cpp406
-rw-r--r--src/core/os_staff.cpp (renamed from src/core/os_staff.c)17
-rw-r--r--src/core/os_stats.cpp (renamed from src/core/os_stats.c)148
-rw-r--r--src/core/os_svsnick.cpp (renamed from src/core/os_svsnick.c)19
-rw-r--r--src/core/os_szline.c394
-rw-r--r--src/core/os_szline.cpp404
-rw-r--r--src/core/os_umode.cpp (renamed from src/core/os_umode.c)17
-rw-r--r--src/core/os_update.cpp (renamed from src/core/os_update.c)13
-rw-r--r--src/core/os_userlist.cpp (renamed from src/core/os_userlist.c)43
-rw-r--r--src/core/ss_main.cpp (renamed from src/core/ss_main.c)19
-rw-r--r--src/encrypt.cpp (renamed from src/encrypt.c)0
-rw-r--r--src/hashcomp.cpp43
-rw-r--r--src/hostserv.cpp (renamed from src/hostserv.c)71
-rw-r--r--src/init.cpp (renamed from src/init.c)98
-rw-r--r--src/ircd.cpp (renamed from src/ircd.c)0
-rw-r--r--src/language.cpp (renamed from src/language.c)0
-rw-r--r--src/log.cpp (renamed from src/log.c)3
-rw-r--r--src/mail.c283
-rw-r--r--src/mail.cpp151
-rw-r--r--src/main.cpp (renamed from src/main.c)63
-rw-r--r--src/memory.cpp (renamed from src/memory.c)0
-rw-r--r--src/memoserv.cpp (renamed from src/memoserv.c)65
-rw-r--r--src/messages.cpp (renamed from src/messages.c)114
-rw-r--r--src/misc.cpp (renamed from src/misc.c)179
-rw-r--r--src/modes.cpp45
-rw-r--r--src/module.cpp151
-rw-r--r--src/modulemanager.cpp43
-rw-r--r--src/modules.c784
-rw-r--r--src/modules.cpp413
-rw-r--r--src/modules/CMakeLists.txt4
-rw-r--r--src/modules/Makefile12
-rw-r--r--src/modules/cs_appendtopic.cpp (renamed from src/modules/cs_appendtopic.c)13
-rw-r--r--src/modules/cs_enforce.cpp (renamed from src/modules/cs_enforce.c)13
-rw-r--r--src/modules/cs_tban.cpp (renamed from src/modules/cs_tban.c)17
-rw-r--r--src/modules/hs_request.cpp (renamed from src/modules/hs_request.c)32
-rw-r--r--src/modules/mysql/db_mysql.h53
-rw-r--r--src/modules/mysql/db_mysql_execute.cpp45
-rw-r--r--src/modules/mysql/db_mysql_read.cpp118
-rw-r--r--src/modules/mysql/db_mysql_write.cpp385
-rw-r--r--src/modules/ns_maxemail.cpp (renamed from src/modules/ns_maxemail.c)13
-rw-r--r--src/modules/os_info.cpp (renamed from src/modules/os_info.c)94
-rw-r--r--src/modules/ssl/m_ssl.cpp148
-rw-r--r--src/nickalias.cpp34
-rw-r--r--src/nickcore.cpp16
-rw-r--r--src/nickserv.cpp (renamed from src/nickserv.c)374
-rw-r--r--src/operserv.c1065
-rw-r--r--src/operserv.cpp828
-rw-r--r--src/opertype.cpp27
-rw-r--r--src/process.cpp (renamed from src/process.c)29
-rw-r--r--src/protocol.cpp4
-rw-r--r--src/protocol/CMakeLists.txt3
-rw-r--r--src/protocol/Makefile8
-rw-r--r--src/protocol/bahamut.cpp (renamed from src/protocol/bahamut.c)183
-rw-r--r--src/protocol/inspircd11.cpp (renamed from src/protocol/inspircd11.c)204
-rw-r--r--src/protocol/inspircd12.cpp313
-rw-r--r--src/protocol/inspircd20.cpp314
-rw-r--r--src/protocol/ratbox.cpp (renamed from src/protocol/ratbox.c)166
-rw-r--r--src/protocol/unreal32.cpp (renamed from src/protocol/unreal32.c)330
-rw-r--r--src/regchannel.cpp249
-rw-r--r--src/send.cpp (renamed from src/send.c)18
-rw-r--r--src/servers.c702
-rw-r--r--src/servers.cpp585
-rw-r--r--src/sessions.cpp (renamed from src/sessions.c)87
-rw-r--r--src/slist.c395
-rw-r--r--src/threadengine.cpp37
-rw-r--r--src/threadengine_pthread.cpp113
-rw-r--r--src/threadengine_win32.cpp109
-rw-r--r--src/tools/db-convert.c4
-rw-r--r--src/users.cpp (renamed from src/users.c)300
230 files changed, 14796 insertions, 13163 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4bad367b4..b9c082c7b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,15 +1,24 @@
-# Find all the *.c and *.cpp files within the current source directory, and sort the list
-file(GLOB SRC_SRCS_C RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c")
+# Find all the *.cpp files within the current source directory, and sort the list
file(GLOB SRC_SRCS_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp")
set(SRC_SRCS ${SRC_SRCS_C} ${SRC_SRCS_CPP})
+
# Don't include win32_memory.cpp, it's only required by Visual Studio to override it's override of the new/delete operators
remove_item_from_list(SRC_SRCS win32_memory.cpp)
+
# If not using Windows, don't include windows.cpp, as it's Windows-specific
if(NOT WIN32)
remove_item_from_list(SRC_SRCS windows.cpp)
endif(NOT WIN32)
sort_list(SRC_SRCS)
+# If using Windows, remove the pthread threading engine from the list
+if(WIN32)
+ remove_item_from_list(SRC_SRCS threadengine_pthread.cpp)
+# If not using Windows, remove the Windows threading engine from the list
+else(WIN32)
+ remove_item_from_list(SRC_SRCS threadengine_win32.cpp)
+endif(WIN32)
+
# Set all the files to use C++ as well as set their compile flags (use the module-specific compile flags, though)
set_source_files_properties(${SRC_SRCS} PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${CXXFLAGS}")
diff --git a/src/Makefile b/src/Makefile
index 949e7e8ec..d4ce6625e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,14 +1,15 @@
OBJS = actions.o base64.o bots.o botserv.o channels.o chanserv.o command.o commands.o compat.o \
- config.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \
- memory.o memoserv.o messages.o misc.o modules.o nickserv.o operserv.o \
- process.o protocol.o send.o servers.o sessions.o slist.o sockets.o opertype.o users.o module.o modulemanager.o configreader.o \
- wildcard.o nickcore.o nickalias.o timers.o modes.o regchannel.o
-
-INCLUDES = ../include/commands.h ../include/defs.h ../include/language.h \
- ../include/pseudo.h ../include/sysconf.h ../include/config.h \
- ../include/messages.h ../include/services.h \
+ config.o configreader.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \
+ memory.o memoserv.o messages.o misc.o modes.o modules.o module.o modulemanager.o nickalias.o \
+ nickcore.o nickserv.o operserv.o process.o protocol.o regchannel.o send.o servers.o sessions.o \
+ sockets.o threadengine.o threadengine_pthread.o timers.o opertype.o users.o wildcard.o
+
+INCLUDES = ../include/commands.h ../include/language.h \
+ ../include/sysconf.h ../include/config.h \
+ ../include/services.h ../include/regchannel.h \
../include/timers.h ../include/extern.h \
- ../include/modules.h ../include/slist.h ../include/hashcomp.h
+ ../include/modules.h ../include/operserv.h ../include/hashcomp.h \
+ ../include/threadengine.h ../include/mail.h
MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \
'LDFLAGS=${LDFLAGS}' 'INSTDIR=${INSTDIR}' 'INSTALL=${INSTALL}' \
@@ -18,9 +19,6 @@ MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \
'SHARED=${SHARED}' 'MODULEFLAGS=${MODULEFLAGS}' \
'MAKEBIN=${MAKEBIN}' 'MYSQLDIR=${MYSQLDIR}'
-.c.o:
- $(MAKEBIN) $(CC) $(CFLAGS) -I../include/ -c $<
-
.cpp.o:
$(MAKEBIN) $(CC) $(CFLAGS) -I../include/ -c $<
@@ -33,48 +31,50 @@ services: $(OBJS)
$(MAKEBIN) $(CC) $(CFLAGS) $(OBJS) $(ANOPELIBS) $(MLIBS) -o $@ $(LDFLAGS)
$(OBJS): Makefile
-modes.o: modes.cpp $(INCLUDES)
-timers.o: timers.cpp $(INCLUDES)
-nickcore.o: nickcore.cpp $(INCLUDES)
-nickalias.o: nickalias.cpp $(INCLUDES)
-actions.o: actions.c $(INCLUDES)
-base64.o: base64.c $(INCLUDES)
+actions.o: actions.cpp $(INCLUDES)
+base64.o: base64.cpp $(INCLUDES)
bots.o: bots.cpp $(INCLUDES)
-botserv.o: botserv.c $(INCLUDES)
-channels.o: channels.c $(INCLUDES)
-chanserv.o: chanserv.c $(INCLUDES)
-command.o: command.cpp $(INCLUDES)
-commands.o: commands.c $(INCLUDES)
-compat.o: compat.c $(INCLUDES)
-config.o: config.c $(INCLUDES)
-encrypt.o: encrypt.c $(INCLUDES)
-init.o: init.c $(INCLUDES)
-ircd.o: ircd.c $(INCLUDES)
-hostserv.o: hostserv.c $(INCLUDES)
-language.o: language.c $(INCLUDES)
-log.o: log.c $(INCLUDES)
-mail.o: mail.c $(INCLUDES)
-main.o: main.c $(INCLUDES)
-memory.o: memory.c $(INCLUDES)
-memoserv.o: memoserv.c $(INCLUDES)
-messages.o: messages.c $(INCLUDES)
-modules.o: modules.c $(INCLUDES)
+botserv.o: botserv.cpp $(INCLUDES)
+channels.o: channels.cpp $(INCLUDES)
+chanserv.o: chanserv.cpp $(INCLUDES)
+command.o: command.cpp $(INCLUDES)
+commands.o: commands.cpp $(INCLUDES)
+compat.o: compat.cpp $(INCLUDES)
+config.o: config.cpp $(INCLUDES)
+configreader.o: configreader.cpp $(INCLUDES)
+encrypt.o: encrypt.cpp $(INCLUDES)
+init.o: init.cpp $(INCLUDES)
+ircd.o: ircd.cpp $(INCLUDES)
+hostserv.o: hostserv.cpp $(INCLUDES)
+language.o: language.cpp $(INCLUDES)
+log.o: log.cpp $(INCLUDES)
+mail.o: mail.cpp $(INCLUDES)
+main.o: main.cpp $(INCLUDES)
+memory.o: memory.cpp $(INCLUDES)
+memoserv.o: memoserv.cpp $(INCLUDES)
+messages.o: messages.cpp $(INCLUDES)
+modes.o: modes.cpp $(INCLUDES)
+modules.o: modules.cpp $(INCLUDES)
module.o: module.cpp $(INCLUDES)
modulemanager.o: modulemanager.cpp $(INCLUDES)
-misc.o: misc.c $(INCLUDES)
-nickserv.o: nickserv.c $(INCLUDES)
-operserv.o: operserv.c $(INCLUDES)
-process.o: process.c $(INCLUDES)
+misc.o: misc.cpp $(INCLUDES)
+nickalias.o: nickalias.cpp $(INCLUDES)
+nickcore.o: nickcore.cpp $(INCLUDES)
+nickserv.o: nickserv.cpp $(INCLUDES)
+operserv.o: operserv.cpp $(INCLUDES)
+opertype.o: opertype.cpp $(INCLUDES)
+process.o: process.cpp $(INCLUDES)
protocol.o: protocol.cpp $(INCLUDES)
regchannel.o: regchannel.cpp $(INCLUDES)
-send.o: send.c $(INCLUDES)
-servers.o: servers.c $(INCLUDES)
-sessions.o: sessions.c $(INCLUDES)
-slist.o: slist.c $(INCLUDES)
+send.o: send.cpp $(INCLUDES)
+servers.o: servers.cpp $(INCLUDES)
+sessions.o: sessions.cpp $(INCLUDES)
+slist.o: slist.cpp $(INCLUDES)
sockets.o: sockets.cpp $(INCLUDES)
-opertype.o: opertype.cpp $(INCLUDES)
-users.o: users.c $(INCLUDES)
-vsnprintf.o: vsnprintf.c $(INCLUDES)
+threadengine.o: threadengine.cpp $(INCLUDES)
+threadengine_pthread.o: threadengine_pthread.cpp $(INCLUDES)
+timers.o: timers.cpp $(INCLUDES)
+users.o: users.cpp $(INCLUDES)
wildcard.o: wildcard.cpp $(INCLUDES)
modules: DUMMY
diff --git a/src/actions.c b/src/actions.cpp
index 471e1273f..00ed01100 100644
--- a/src/actions.c
+++ b/src/actions.cpp
@@ -70,52 +70,6 @@ void kill_user(const std::string &source, const std::string &user, const std::st
/*************************************************************************/
/**
- * Check and enforce SQlines
- * @param mask of the sqline
- * @param reason for the sqline
- * @return void
- */
-void sqline(const std::string &mask, const std::string &reason)
-{
- int i;
- Channel *c, *next;
-
- if (ircd->chansqline)
- {
- if (mask[0] == '#')
- {
- ircdproto->SendSQLine(mask, reason);
-
- for (i = 0; i < 1024; ++i)
- {
- for (c = chanlist[i]; c; c = next)
- {
- next = c->next;
-
- if (!Anope::Match(c->name, mask, false))
- continue;
- for (CUserList::iterator it = c->users.begin(); it != c->users.end();)
- {
- UserContainer *uc = *it;
- ++it;
-
- if (is_oper(uc->user))
- continue;
- c->Kick(NULL, uc->user, "%s", reason.c_str());
- }
- }
- }
- }
- else
- ircdproto->SendSQLine(mask, reason);
- }
- else
- ircdproto->SendSQLine(mask, reason);
-}
-
-/*************************************************************************/
-
-/**
* Unban the nick from a channel
* @param ci channel info for the channel
* @param nick to remove the ban for
diff --git a/src/base64.c b/src/base64.cpp
index 3f576e96a..3f576e96a 100644
--- a/src/base64.c
+++ b/src/base64.cpp
diff --git a/src/bots.cpp b/src/bots.cpp
index 37cd553d1..e9021b188 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -10,6 +10,18 @@
#include "services.h"
#include "modules.h"
+#include "commands.h"
+
+botinfo_map BotListByNick;
+botinfo_uid_map BotListByUID;
+
+BotInfo *BotServ = NULL;
+BotInfo *ChanServ = NULL;
+BotInfo *Global = NULL;
+BotInfo *HostServ = NULL;
+BotInfo *MemoServ = NULL;
+BotInfo *NickServ = NULL;
+BotInfo *OperServ = NULL;
BotInfo::BotInfo(const std::string &nnick, const std::string &nuser, const std::string &nhost, const std::string &nreal)
{
@@ -19,100 +31,87 @@ BotInfo::BotInfo(const std::string &nnick, const std::string &nuser, const std::
this->real = nreal;
this->lastmsg = this->created = time(NULL);
this->uid = ts6_uid_retrieve();
- this->cmdTable = NULL;
- ++nbots;
this->chancount = 0;
ci::string ci_nick(nnick.c_str());
if (Config.s_ChanServ && ci_nick == Config.s_ChanServ)
{
- this->cmdTable = CHANSERV;
- this->SetFlag(BI_CHANSERV);
+ ChanServ = this;
}
else if (Config.s_BotServ && ci_nick == Config.s_BotServ)
{
- this->cmdTable = BOTSERV;
- this->SetFlag(BI_BOTSERV);
+ BotServ = this;
}
else if (Config.s_HostServ && ci_nick == Config.s_HostServ)
{
- this->cmdTable = HOSTSERV;
- this->SetFlag(BI_HOSTSERV);
+ HostServ = this;
}
else if (Config.s_OperServ && ci_nick == Config.s_OperServ)
{
- this->cmdTable = OPERSERV;
- this->SetFlag(BI_OPERSERV);
+ OperServ = this;
}
else if (Config.s_MemoServ && ci_nick == Config.s_MemoServ)
{
- this->cmdTable = MEMOSERV;
- this->SetFlag(BI_MEMOSERV);
+ MemoServ = this;
}
else if (Config.s_NickServ && ci_nick == Config.s_NickServ)
{
- this->cmdTable = NICKSERV;
- this->SetFlag(BI_NICKSERV);
+ NickServ = this;
}
else if (Config.s_GlobalNoticer && ci_nick == Config.s_GlobalNoticer)
{
- this->SetFlag(BI_GLOBAL);
+ Global = this;
}
- insert_bot(this); // XXX, this is ugly, but it needs to stay until hashing of bots is redone in STL.
+ BotListByNick[this->nick.c_str()] = this;
+ if (!this->uid.empty())
+ BotListByUID[this->uid] = this;
// If we're synchronised with the uplink already, call introduce_user() for this bot.
- if (serv_uplink && serv_uplink->sync == SSYNC_DONE)
+ if (Me && Me->GetUplink()->IsSynced())
{
ircdproto->SendClientIntroduction(this->nick, this->user, this->host, this->real, ircd->pseudoclient_mode, this->uid);
- ircdproto->SendSQLine(this->nick, "Reserved for services");
+ XLine x(this->nick.c_str(), "Reserved for services");
+ ircdproto->SendSQLine(&x);
}
}
BotInfo::~BotInfo()
{
- int i;
- ChannelInfo *ci;
-
- for (i = 0; i < 256; ++i)
- for (ci = chanlists[i]; ci; ci = ci->next)
- if (ci->bi == this)
- ci->bi = NULL;
-
- if (this->next)
- this->next->prev = this->prev;
- if (this->prev)
- this->prev->next = this->next;
- else
- botlists[tolower(this->nick[0])] = this->next;
-
- --nbots;
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
+ {
+ ChannelInfo *ci = it->second;
+
+ if (ci->bi == this)
+ {
+ ci->bi = NULL;
+ }
+ }
+
+ BotListByNick.erase(this->nick.c_str());
+ if (!this->uid.empty())
+ BotListByUID.erase(this->uid);
}
void BotInfo::ChangeNick(const char *newnick)
{
- if (this->next)
- this->next->prev = this->prev;
- if (this->prev)
- this->prev->next = this->next;
- else
- botlists[tolower(this->nick[0])] = this->next;
+ BotListByNick.erase(this->nick.c_str());
this->nick = newnick;
- insert_bot(this);
+ BotListByNick[this->nick.c_str()] = this;
}
void BotInfo::RejoinAll()
{
- int i;
- ChannelInfo *ci;
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
+ {
+ ChannelInfo *ci = it->second;
- for (i = 0; i < 256; ++i)
- for (ci = chanlists[i]; ci; ci = ci->next)
- if (ci->bi == this && ci->c && (ci->c->users.size() >= Config.BSMinUsers))
- bot_join(ci);
+ if (ci->bi == this && ci->c && ci->c->users.size() >= Config.BSMinUsers)
+ bot_join(ci);
+ }
}
void BotInfo::Assign(User *u, ChannelInfo *ci)
diff --git a/src/botserv.c b/src/botserv.cpp
index 54b968dec..2dd96706d 100644
--- a/src/botserv.c
+++ b/src/botserv.cpp
@@ -14,14 +14,8 @@
/*************************************************************************/
#include "services.h"
-#include "pseudo.h"
-
-/*************************************************************************/
-
-BotInfo *botlists[256]; /* Hash list of bots */
-int nbots = 0;
-
-/*************************************************************************/
+#include "modules.h"
+#include "language.h"
static UserData *get_user_data(Channel * c, User * u);
@@ -44,18 +38,17 @@ void moduleAddBotServCmds() {
void get_botserv_stats(long *nrec, long *memuse)
{
long count = 0, mem = 0;
- int i;
- BotInfo *bi;
-
- for (i = 0; i < 256; i++) {
- for (bi = botlists[i]; bi; bi = bi->next) {
- count++;
- mem += sizeof(*bi);
- mem += bi->nick.size() + 1;
- mem += bi->user.size() + 1;
- mem += bi->host.size() + 1;
- mem += bi->real.size() + 1;
- }
+
+ for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it)
+ {
+ BotInfo *bi = it->second;
+
+ count++;
+ mem += sizeof(*bi);
+ mem += bi->nick.size() + 1;
+ mem += bi->user.size() + 1;
+ mem += bi->host.size() + 1;
+ mem += bi->real.size() + 1;
}
*nrec = count;
@@ -78,46 +71,21 @@ void bs_init()
/* Main BotServ routine. */
-void botserv(User * u, char *buf)
+void botserv(User *u, BotInfo *bi, const std::string &buf)
{
- char *cmd, *s;
-
- cmd = strtok(buf, " ");
-
- if (!cmd) {
+ if (!u || !bi || buf.empty())
return;
- } else if (stricmp(cmd, "\1PING") == 0) {
- if (!(s = strtok(NULL, ""))) {
- *s = 0;
- }
- ircdproto->SendCTCP(findbot(Config.s_BotServ), u->nick.c_str(), "PING %s", s);
- } else {
- mod_run_cmd(Config.s_BotServ, u, BOTSERV, cmd);
- }
-
-}
-
-/*************************************************************************/
-
-/* Handles all messages sent to bots. (Currently only answers to pings ;) */
-
-void botmsgs(User * u, BotInfo * bi, char *buf)
-{
- char *cmd = strtok(buf, " ");
- char *s;
-
- if (!cmd || !u)
- return;
-
- if (!stricmp(cmd, "\1PING")) {
- if (!(s = strtok(NULL, ""))) {
- *s = 0;
- }
- ircdproto->SendCTCP(bi, u->nick.c_str(), "PING %s", s);
+
+ if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1')
+ {
+ std::string command = buf;
+ command.erase(command.begin());
+ command.erase(command.end());
+ ircdproto->SendCTCP(bi, u->nick.c_str(), "%s", command.c_str());
}
- else if (cmd && bi->cmdTable)
+ else
{
- mod_run_cmd(bi->nick, u, bi->cmdTable, cmd);
+ mod_run_cmd(bi, u, buf);
}
}
@@ -128,33 +96,36 @@ void botmsgs(User * u, BotInfo * bi, char *buf)
*
*/
-void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
+void botchanmsgs(User *u, ChannelInfo *ci, const std::string &buf)
{
- int c;
- char *cmd;
- UserData *ud;
- bool was_action = false;
- Command *command;
- std::string bbuf;
-
- if (!u || !buf || !ci || !ci->c)
+ if (!u || !ci || !ci->c || buf.empty())
return;
-
- /* Answer to ping if needed, without breaking the buffer. */
- if (!strnicmp(buf, "\1PING", 5)) {
- ircdproto->SendCTCP(ci->bi, u->nick.c_str(), "PING %s", buf);
+
+ /* Answer to ping if needed */
+ if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1')
+ {
+ std::string ctcp = buf;
+ ctcp.erase(ctcp.begin());
+ ctcp.erase(ctcp.end());
+ ircdproto->SendCTCP(ci->bi, u->nick.c_str(), "%s", ctcp.c_str());
}
- /* If it's a /me, cut the CTCP part at the beginning (not
- * at the end, because one character just doesn't matter,
- * but the ACTION may create strange behaviours with the
- * caps or badwords kickers */
- if (!strnicmp(buf, "\1ACTION ", 8))
+ bool was_action = false;
+ std::string realbuf = buf;
+
+ /* If it's a /me, cut the CTCP part because the ACTION will cause
+ * problems with the caps or badwords kicker
+ */
+ if (realbuf.find("\1ACTION ", 0, 8) && realbuf[buf.length() - 1] == '\1')
{
- buf += 8;
+ realbuf.erase(0, 8);
+ realbuf.erase(realbuf.end());
was_action = true;
}
+ if (realbuf.empty())
+ return;
+
/* Now we can make kicker stuff. We try to order the checks
* from the fastest one to the slowest one, since there's
* no need to process other kickers if an user is kicked before
@@ -172,56 +143,61 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && ci->c->HasUserStatus(u, CMODE_VOICE))
Allow = true;
- if (buf && !check_access(u, ci, CA_NOKICK) && Allow)
+ if (!check_access(u, ci, CA_NOKICK) && Allow)
{
/* Bolds kicker */
- if (ci->botflags.HasFlag(BS_KICK_BOLDS) && strchr(buf, 2)) {
+ if (ci->botflags.HasFlag(BS_KICK_BOLDS) && realbuf.find_first_of(2) != std::string::npos)
+ {
check_ban(ci, u, TTB_BOLDS);
bot_kick(ci, u, BOT_REASON_BOLD);
return;
}
/* Color kicker */
- if (ci->botflags.HasFlag(BS_KICK_COLORS) && strchr(buf, 3)) {
+ if (ci->botflags.HasFlag(BS_KICK_COLORS) && realbuf.find_first_of(3) != std::string::npos)
+ {
check_ban(ci, u, TTB_COLORS);
bot_kick(ci, u, BOT_REASON_COLOR);
return;
}
/* Reverses kicker */
- if (ci->botflags.HasFlag(BS_KICK_REVERSES) && strchr(buf, 22)) {
+ if (ci->botflags.HasFlag(BS_KICK_REVERSES) && realbuf.find_first_of(22) != std::string::npos)
+ {
check_ban(ci, u, TTB_REVERSES);
bot_kick(ci, u, BOT_REASON_REVERSE);
return;
}
/* Underlines kicker */
- if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && strchr(buf, 31)) {
+ if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && realbuf.find_first_of(31) != std::string::npos)
+ {
check_ban(ci, u, TTB_UNDERLINES);
bot_kick(ci, u, BOT_REASON_UNDERLINE);
return;
}
/* Caps kicker */
- if (ci->botflags.HasFlag(BS_KICK_CAPS)
- && ((c = strlen(buf)) >= ci->capsmin)) {
+ if (ci->botflags.HasFlag(BS_KICK_CAPS) && realbuf.length() >= ci->capsmin)
+ {
int i = 0;
int l = 0;
- char *s = buf;
-
- do {
- if (isupper(*s))
- i++;
- else if (islower(*s))
- l++;
- } while (*s++);
+ for (unsigned j = 0; j < realbuf.length(); ++j)
+ {
+ if (isupper(realbuf[j]))
+ ++i;
+ else if (islower(realbuf[j]))
+ ++l;
+ }
+
/* i counts uppercase chars, l counts lowercase chars. Only
* alphabetic chars (so islower || isupper) qualify for the
* percentage of caps to kick for; the rest is ignored. -GD
*/
- if (i && l && i >= ci->capsmin && i * 100 / (i + l) >= ci->capspercent) {
+ if (i && l && i >= ci->capsmin && i * 100 / (i + l) >= ci->capspercent)
+ {
check_ban(ci, u, TTB_CAPS);
bot_kick(ci, u, BOT_REASON_CAPS);
return;
@@ -229,49 +205,42 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
}
/* Bad words kicker */
- if (ci->botflags.HasFlag(BS_KICK_BADWORDS)) {
- int mustkick = 0;
- char *nbuf;
- BadWord *bw;
+ if (ci->botflags.HasFlag(BS_KICK_BADWORDS))
+ {
+ bool mustkick = false;
/* Normalize the buffer */
- nbuf = normalizeBuffer(buf);
+ const char *nbuf = normalizeBuffer(realbuf.c_str());
for (unsigned i = 0; i < ci->GetBadWordCount(); ++i)
{
- bw = ci->GetBadWord(i);
-
- if (bw->type == BW_ANY
- && ((Config.BSCaseSensitive && strstr(nbuf, bw->word.c_str()))
- || (!Config.BSCaseSensitive && stristr(nbuf, bw->word.c_str())))) {
- mustkick = 1;
- } else if (bw->type == BW_SINGLE) {
- int len = bw->word.length();
-
- if ((Config.BSCaseSensitive && nbuf == bw->word)
- || (!Config.BSCaseSensitive
- && (!stricmp(nbuf, bw->word.c_str())))) {
- mustkick = 1;
- /* two next if are quite odd isn't it? =) */
- } else if ((strchr(nbuf, ' ') == nbuf + len)
- &&
- ((Config.BSCaseSensitive && nbuf == bw->word)
- || (!Config.BSCaseSensitive
- && (stristr(nbuf, bw->word.c_str()) ==
- nbuf)))) {
- mustkick = 1;
- } else {
- if ((strrchr(nbuf, ' ') ==
- nbuf + strlen(nbuf) - len - 1)
- &&
- ((Config.BSCaseSensitive
- && (strstr(nbuf, bw->word.c_str()) ==
- nbuf + strlen(nbuf) - len))
- || (!Config.BSCaseSensitive
- && (stristr(nbuf, bw->word.c_str()) ==
- nbuf + strlen(nbuf) - len)))) {
- mustkick = 1;
- } else {
+ BadWord *bw = ci->GetBadWord(i);
+
+ if (bw->type == BW_ANY && ((Config.BSCaseSensitive && strstr(nbuf, bw->word.c_str())) || (!Config.BSCaseSensitive && stristr(nbuf, bw->word.c_str()))))
+ {
+ mustkick = true;
+ }
+ else if (bw->type == BW_SINGLE)
+ {
+ size_t len = bw->word.length();
+
+ if ((Config.BSCaseSensitive && nbuf == bw->word) || (!Config.BSCaseSensitive && (!stricmp(nbuf, bw->word.c_str()))))
+ {
+ mustkick = true;
+ }
+ else if ((strchr(nbuf, ' ') == nbuf + len) && ((Config.BSCaseSensitive && nbuf == bw->word)
+ || (!Config.BSCaseSensitive && (stristr(nbuf, bw->word.c_str()) == nbuf))))
+ {
+ mustkick = true;
+ }
+ else
+ {
+ if ((strrchr(nbuf, ' ') == nbuf + strlen(nbuf) - len - 1) && ((Config.BSCaseSensitive && (strstr(nbuf, bw->word.c_str()) == nbuf + strlen(nbuf) - len)) || (!Config.BSCaseSensitive && (stristr(nbuf, bw->word.c_str()) == nbuf + strlen(nbuf) - len))))
+ {
+ mustkick = true;
+ }
+ else
+ {
char *wordbuf = new char[len + 3];
wordbuf[0] = ' ';
@@ -279,69 +248,67 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
wordbuf[len + 2] = '\0';
memcpy(wordbuf + 1, bw->word.c_str(), len);
- if ((Config.BSCaseSensitive
- && (strstr(nbuf, wordbuf)))
- || (!Config.BSCaseSensitive
- && (stristr(nbuf, wordbuf)))) {
- mustkick = 1;
+ if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) || (!Config.BSCaseSensitive && (stristr(nbuf, wordbuf))))
+ {
+ mustkick = true;
}
- /* free previous (sc)allocated memory (#850) */
delete [] wordbuf;
}
}
- } else if (bw->type == BW_START) {
- int len = bw->word.length();
-
- if ((Config.BSCaseSensitive
- && (!strncmp(nbuf, bw->word.c_str(), len)))
- || (!Config.BSCaseSensitive
- && (!strnicmp(nbuf, bw->word.c_str(), len)))) {
- mustkick = 1;
- } else {
+ }
+ else if (bw->type == BW_START)
+ {
+ size_t len = bw->word.length();
+
+ if ((Config.BSCaseSensitive && (!strncmp(nbuf, bw->word.c_str(), len))) || (!Config.BSCaseSensitive && (!strnicmp(nbuf, bw->word.c_str(), len))))
+ {
+ mustkick = true;
+ }
+ else
+ {
char *wordbuf = new char[len + 2];
memcpy(wordbuf + 1, bw->word.c_str(), len);
wordbuf[0] = ' ';
wordbuf[len + 1] = '\0';
- if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf)))
- || (!Config.BSCaseSensitive
- && (stristr(nbuf, wordbuf))))
- mustkick = 1;
+ if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) || (!Config.BSCaseSensitive && (stristr(nbuf, wordbuf))))
+ {
+ mustkick = true;
+ }
delete [] wordbuf;
}
- } else if (bw->type == BW_END) {
- int len = bw->word.length();
-
- if ((Config.BSCaseSensitive
- &&
- (!strncmp
- (nbuf + strlen(nbuf) - len, bw->word.c_str(), len)))
- || (!Config.BSCaseSensitive
- &&
- (!strnicmp
- (nbuf + strlen(nbuf) - len, bw->word.c_str(),
- len)))) {
- mustkick = 1;
- } else {
+ }
+ else if (bw->type == BW_END)
+ {
+ size_t len = bw->word.length();
+
+ if ((Config.BSCaseSensitive && (!strncmp(nbuf + strlen(nbuf) - len, bw->word.c_str(), len)))
+ || (!Config.BSCaseSensitive && (!strnicmp(nbuf + strlen(nbuf) - len, bw->word.c_str(), len))))
+ {
+ mustkick = true;
+ }
+ else
+ {
char *wordbuf = new char[len + 2];
memcpy(wordbuf, bw->word.c_str(), len);
wordbuf[len] = ' ';
wordbuf[len + 1] = '\0';
- if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf)))
- || (!Config.BSCaseSensitive
- && (stristr(nbuf, wordbuf))))
- mustkick = 1;
+ if ((Config.BSCaseSensitive && (strstr(nbuf, wordbuf))) || (!Config.BSCaseSensitive && (stristr(nbuf, wordbuf))))
+ {
+ mustkick = true;
+ }
delete [] wordbuf;
}
}
- if (mustkick) {
+ if (mustkick)
+ {
check_ban(ci, u, TTB_BADWORDS);
if (Config.BSGentleBWReason)
bot_kick(ci, u, BOT_REASON_BADWORD_GENTLE);
@@ -360,21 +327,23 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
}
/* Flood kicker */
- if (ci->botflags.HasFlag(BS_KICK_FLOOD)) {
+ if (ci->botflags.HasFlag(BS_KICK_FLOOD))
+ {
time_t now = time(NULL);
- ud = get_user_data(ci->c, u);
- if (!ud) {
+ UserData *ud = get_user_data(ci->c, u);
+ if (!ud)
return;
- }
- if (now - ud->last_start > ci->floodsecs) {
+ if (now - ud->last_start > ci->floodsecs)
+ {
ud->last_start = time(NULL);
ud->lines = 0;
}
ud->lines++;
- if (ud->lines >= ci->floodlines) {
+ if (ud->lines >= ci->floodlines)
+ {
check_ban(ci, u, TTB_FLOOD);
bot_kick(ci, u, BOT_REASON_FLOOD);
return;
@@ -382,22 +351,27 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
}
/* Repeat kicker */
- if (ci->botflags.HasFlag(BS_KICK_REPEAT)) {
- ud = get_user_data(ci->c, u);
- if (!ud) {
+ if (ci->botflags.HasFlag(BS_KICK_REPEAT))
+ {
+ UserData *ud = get_user_data(ci->c, u);
+ if (!ud)
return;
- }
- if (ud->lastline && stricmp(ud->lastline, buf)) {
+
+ if (ud->lastline && stricmp(ud->lastline, buf.c_str()))
+ {
delete [] ud->lastline;
- ud->lastline = sstrdup(buf);
+ ud->lastline = sstrdup(buf.c_str());
ud->times = 0;
- } else {
+ }
+ else
+ {
if (!ud->lastline)
- ud->lastline = sstrdup(buf);
+ ud->lastline = sstrdup(buf.c_str());
ud->times++;
}
- if (ud->times >= ci->repeattimes) {
+ if (ud->times >= ci->repeattimes)
+ {
check_ban(ci, u, TTB_REPEAT);
bot_kick(ci, u, BOT_REASON_REPEAT);
return;
@@ -405,31 +379,31 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
}
}
-
/* return if the user is on the ignore list */
- if (get_ignore(u->nick.c_str()) != NULL) {
+ if (get_ignore(u->nick.c_str()) != NULL)
+ {
return;
}
/* Fantaisist commands */
+ if (ci->botflags.HasFlag(BS_FANTASY) && buf[0] == *Config.BSFantasyCharacter && !was_action)
+ {
+ spacesepstream sep(buf);
+ std::string token;
- if (buf && ci->botflags.HasFlag(BS_FANTASY) && *buf == *Config.BSFantasyCharacter && !was_action) {
- cmd = strtok(buf, " ");
-
- if (cmd && (cmd[0] == *Config.BSFantasyCharacter)) {
- char *params = strtok(NULL, "");
-
+ if (sep.GetToken(token) && (token[0] == *Config.BSFantasyCharacter))
+ {
/* Strip off the fantasy character */
- cmd++;
+ token.erase(token.begin());
if (check_access(u, ci, CA_FANTASIA))
{
- command = findCommand(CHANSERV, cmd);
+ Command *command = FindCommand(ChanServ, token.c_str());
/* Command exists and can not be called by fantasy */
if (command && !command->HasFlag(CFLAG_DISABLE_FANTASY))
{
- bbuf = std::string(cmd);
+ std::string bbuf = std::string(token);
/* Some commands don't need the channel name added.. eg !help */
if (!command->HasFlag(CFLAG_STRIP_CHANNEL))
@@ -438,20 +412,20 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
bbuf += ci->name;
}
- if (params)
+ if (!sep.StreamEnd())
{
bbuf += " ";
- bbuf += params;
+ bbuf += sep.GetRemaining();
}
- chanserv(u, const_cast<char *>(bbuf.c_str())); // XXX Unsafe cast, this needs reviewing -- CyberBotX
+ chanserv(u, bbuf);
}
- FOREACH_MOD(I_OnBotFantasy, OnBotFantasy(cmd, u, ci, params));
+ FOREACH_MOD(I_OnBotFantasy, OnBotFantasy(token, u, ci, sep.GetRemaining()));
}
else
{
- FOREACH_MOD(I_OnBotNoFantasyAccess, OnBotNoFantasyAccess(cmd, u, ci, params));
+ FOREACH_MOD(I_OnBotNoFantasyAccess, OnBotNoFantasyAccess(token, u, ci, sep.GetRemaining()));
}
}
}
@@ -459,53 +433,31 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf)
/*************************************************************************/
-/* Inserts a bot in the bot list. I can't be much explicit mh? */
-
-void insert_bot(BotInfo *bi)
+BotInfo *findbot(const char *nick)
{
- BotInfo *ptr, *prev;
-
- ci::string ci_bi_nick(bi->nick.c_str());
- for (prev = NULL, ptr = botlists[tolower(bi->nick[0])];
- ptr != NULL && ci_bi_nick > ptr->nick.c_str();
- prev = ptr, ptr = ptr->next);
- bi->prev = prev;
- bi->next = ptr;
- if (!prev)
- botlists[tolower(bi->nick[0])] = bi;
- else
- prev->next = bi;
- if (ptr)
- ptr->prev = bi;
+ return findbot(ci::string(nick));
}
-/*************************************************************************/
-/*************************************************************************/
-
BotInfo *findbot(const std::string &nick)
{
- BotInfo *bi;
-
- if (nick.empty())
- return NULL;
-
- ci::string ci_nick(nick.c_str());
+ return findbot(ci::string(nick.c_str()));
+}
- /*
- * XXX Less than efficient, but we need to do this for good TS6 support currently. This *will* improve. -- w00t
- */
- for (int i = 0; i < 256; i++)
+BotInfo *findbot(const ci::string &nick)
+{
+ if (isdigit(nick[0]) && ircd->ts6)
{
- for (bi = botlists[i]; bi; bi = bi->next)
- {
- if (ci_nick == bi->nick)
- return bi;
+ botinfo_uid_map::const_iterator it = BotListByUID.find(nick.c_str());
- if (ci_nick == bi->uid)
- return bi;
- }
+ if (it != BotListByUID.end())
+ return it->second;
+ return NULL;
}
+ botinfo_map::const_iterator it = BotListByNick.find(nick);
+
+ if (it != BotListByNick.end())
+ return it->second;
return NULL;
}
@@ -665,7 +617,7 @@ static void check_ban(ChannelInfo *ci, User *u, int ttbtype)
return;
/* Don't ban ulines */
- if (is_ulined(u->server->name))
+ if (u->server->IsULined())
return;
bd->ttb[ttbtype]++;
@@ -723,7 +675,7 @@ void bot_raw_ban(User * requester, ChannelInfo * ci, char *nick, const char *rea
if ((ModeManager::FindUserModeByName(UMODE_PROTECTED)))
{
- if (is_protected(u) && (requester != u)) {
+ if (u->IsProtected() && (requester != u)) {
ircdproto->SendPrivmsg(ci->bi, ci->name.c_str(), "%s", getstring(ACCESS_DENIED));
return;
}
@@ -764,7 +716,7 @@ void bot_raw_kick(User * requester, ChannelInfo * ci, char *nick, const char *re
if ((ModeManager::FindUserModeByName(UMODE_PROTECTED)))
{
- if (is_protected(u) && (requester != u)) {
+ if (u->IsProtected() && (requester != u)) {
ircdproto->SendPrivmsg(ci->bi, ci->name.c_str(), "%s", getstring(ACCESS_DENIED));
return;
}
@@ -797,7 +749,7 @@ void bot_raw_mode(User * requester, ChannelInfo * ci, const char *mode, char *ni
snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(time(NULL)));
if ((ModeManager::FindUserModeByName(UMODE_PROTECTED))) {
- if (is_protected(u) && *mode == '-' && (requester != u)) {
+ if (u->IsProtected() && *mode == '-' && (requester != u)) {
ircdproto->SendPrivmsg(ci->bi, ci->name.c_str(), "%s", getstring(ACCESS_DENIED));
return;
}
diff --git a/src/channels.c b/src/channels.cpp
index b98a2f579..b2c839083 100644
--- a/src/channels.c
+++ b/src/channels.cpp
@@ -15,11 +15,7 @@
#include "language.h"
#include "modules.h"
-Channel *chanlist[1024];
-
-#define HASH(chan) ((chan)[1] ? ((chan)[1]&31)<<5 | ((chan)[2]&31) : 0)
-
-/*************************************************************************/
+channel_map ChannelList;
/** Default constructor
* @param name The channel name
@@ -27,18 +23,12 @@ Channel *chanlist[1024];
*/
Channel::Channel(const std::string &name, time_t ts)
{
- Channel **list;
-
if (name.empty())
throw CoreException("A channel without a name ?");
this->name = name;
- list = &chanlist[HASH(this->name)];
- this->prev = NULL;
- this->next = *list;
- if (*list)
- (*list)->prev = this;
- *list = this;
+
+ ChannelList[this->name.c_str()] = this;
this->creation_time = ts;
this->topic = NULL;
@@ -102,12 +92,7 @@ Channel::~Channel()
}
}
- if (this->next)
- this->next->prev = this->prev;
- if (this->prev)
- this->prev->next = this->next;
- else
- chanlist[HASH(this->name)] = this->next;
+ ChannelList.erase(this->name.c_str());
}
void Channel::Sync()
@@ -118,7 +103,7 @@ void Channel::Sync()
stick_all(this->ci);
}
- if (serv_uplink && is_sync(serv_uplink) && !this->topic_sync)
+ if (Me && Me->IsSynced() && !this->topic_sync)
restore_topic(name.c_str());
}
@@ -146,7 +131,7 @@ void Channel::JoinUser(User *user)
}
/* Added channelname to entrymsg - 30.03.2004, Certus */
/* Also, don't send the entrymsg when bursting -GD */
- if (this->ci && this->ci->entry_message && is_sync(user->server))
+ if (this->ci && this->ci->entry_message && user->server->IsSynced())
user->SendMessage(whosends(this->ci)->nick, "[%s] %s", this->name.c_str(), this->ci->entry_message);
}
@@ -158,7 +143,7 @@ void Channel::JoinUser(User *user)
* But don't join the bot if the channel is persistant - Adam
* But join persistant channels when syncing with our uplink- DP
**/
- if (Config.s_BotServ && this->ci && this->ci->bi && ((serv_uplink->sync == SSYNC_IN_PROGRESS) || !this->ci->HasFlag(CI_PERSIST)))
+ if (Config.s_BotServ && this->ci && this->ci->bi && (!Me->IsSynced() || !this->ci->HasFlag(CI_PERSIST)))
{
if (this->users.size() == Config.BSMinUsers)
bot_join(this->ci);
@@ -172,7 +157,7 @@ void Channel::JoinUser(User *user)
* to has synced, or we'll get greet-floods when the net
* recovers from a netsplit. -GD
*/
- if (is_sync(user->server))
+ if (user->server->IsSynced())
{
ircdproto->SendPrivmsg(this->ci->bi, this->name.c_str(), "[%s] %s", user->Account()->display, user->Account()->greet);
this->ci->bi->lastmsg = time(NULL);
@@ -286,7 +271,7 @@ bool Channel::HasUserStatus(User *u, ChannelModeName Name)
*/
bool Channel::HasMode(ChannelModeName Name)
{
- return modes[Name];
+ return modes.HasFlag(Name);
}
/** Set a mode internally on a channel, this is not sent out to the IRCd
@@ -349,7 +334,7 @@ void Channel::SetModeInternal(ChannelMode *cm, const std::string &param, bool En
return;
}
- modes[cm->Name] = true;
+ modes.SetFlag(cm->Name);
if (!param.empty())
{
@@ -491,7 +476,7 @@ void Channel::RemoveModeInternal(ChannelMode *cm, const std::string &param, bool
return;
}
- modes[cm->Name] = false;
+ modes.UnsetFlag(cm->Name);
if (cm->Type == MODE_PARAM)
{
@@ -734,7 +719,7 @@ void Channel::ClearModes(BotInfo *bi)
}
}
- modes.reset();
+ modes.ClearFlags();
}
/** Clear all the bans from the channel
@@ -975,7 +960,11 @@ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...)
va_end(args);
/* May not kick ulines */
- if (is_ulined(u->server->name))
+ if (u->server->IsULined())
+ return false;
+
+ /* Do not kick protected clients */
+ if (u->IsProtected())
return false;
EventReturn MOD_RESULT;
@@ -1047,61 +1036,23 @@ char *chan_get_modes(Channel * chan, int complete, int plus)
/*************************************************************************/
-/* Return the Channel structure corresponding to the named channel, or NULL
- * if the channel was not found. chan is assumed to be non-NULL and valid
- * (i.e. pointing to a channel name of 2 or more characters). */
-
Channel *findchan(const char *chan)
{
- Channel *c;
-
- if (!chan || !*chan)
- {
- Alog(LOG_DEBUG) << "findchan() called with NULL values";
- return NULL;
- }
-
- c = chanlist[HASH(chan)];
- while (c)
- {
- if (stricmp(c->name.c_str(), chan) == 0)
- {
- Alog(LOG_DEBUG_3) << "findchan(" << chan << ") -> " << static_cast<void *>(c);
- return c;
- }
- c = c->next;
- }
- return NULL;
+ return findchan(ci::string(chan));
}
-/*************************************************************************/
-
-/* Iterate over all channels in the channel list. Return NULL at end of
- * list.
- */
-
-static Channel *current;
-static int next_index;
-
-Channel *firstchan()
+Channel *findchan(const std::string &chan)
{
- next_index = 0;
- while (next_index < 1024 && current == NULL)
- current = chanlist[next_index++];
- Alog(LOG_DEBUG_3) << "firstchan() returning " << (current ? current->name : "NULL (end of list)");
- return current;
+ return findchan(ci::string(chan.c_str()));
}
-Channel *nextchan()
+Channel *findchan(const ci::string &chan)
{
- if (current)
- current = current->next;
- if (!current && next_index < 1024) {
- while (next_index < 1024 && current == NULL)
- current = chanlist[next_index++];
- }
- Alog(LOG_DEBUG_3) << "nextchan() returning " << (current ? current->name : "NULL (end of list)");
- return current;
+ channel_map::const_iterator it = ChannelList.find(chan);
+
+ if (it != ChannelList.end())
+ return it->second;
+ return NULL;
}
/*************************************************************************/
@@ -1111,40 +1062,39 @@ Channel *nextchan()
void get_channel_stats(long *nrec, long *memuse)
{
long count = 0, mem = 0;
- Channel *chan;
BanData *bd;
- int i;
std::string buf;
- for (i = 0; i < 1024; i++) {
- for (chan = chanlist[i]; chan; chan = chan->next) {
- count++;
- mem += sizeof(*chan);
- if (chan->topic)
- mem += strlen(chan->topic) + 1;
- if (chan->GetParam(CMODE_KEY, buf))
- mem += buf.length() + 1;
- if (chan->GetParam(CMODE_FLOOD, buf))
- mem += buf.length() + 1;
- if (chan->GetParam(CMODE_REDIRECT, buf))
- mem += buf.length() + 1;
- mem += get_memuse(chan->bans);
- if (ModeManager::FindChannelModeByName(CMODE_EXCEPT))
- mem += get_memuse(chan->excepts);
- if (ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE))
- mem += get_memuse(chan->invites);
- for (CUserList::iterator it = chan->users.begin(); it != chan->users.end(); ++it)
- {
- mem += sizeof(*it);
- mem += sizeof((*it)->ud);
- if ((*it)->ud.lastline)
- mem += strlen((*it)->ud.lastline) + 1;
- }
- for (bd = chan->bd; bd; bd = bd->next) {
- if (bd->mask)
- mem += strlen(bd->mask) + 1;
- mem += sizeof(*bd);
- }
+ for (channel_map::const_iterator cit = ChannelList.begin(); cit != ChannelList.end(); ++cit)
+ {
+ Channel *chan = cit->second;
+
+ count++;
+ mem += sizeof(*chan);
+ if (chan->topic)
+ mem += strlen(chan->topic) + 1;
+ if (chan->GetParam(CMODE_KEY, buf))
+ mem += buf.length() + 1;
+ if (chan->GetParam(CMODE_FLOOD, buf))
+ mem += buf.length() + 1;
+ if (chan->GetParam(CMODE_REDIRECT, buf))
+ mem += buf.length() + 1;
+ mem += get_memuse(chan->bans);
+ if (ModeManager::FindChannelModeByName(CMODE_EXCEPT))
+ mem += get_memuse(chan->excepts);
+ if (ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE))
+ mem += get_memuse(chan->invites);
+ for (CUserList::iterator it = chan->users.begin(); it != chan->users.end(); ++it)
+ {
+ mem += sizeof(*it);
+ mem += sizeof((*it)->ud);
+ if ((*it)->ud.lastline)
+ mem += strlen((*it)->ud.lastline) + 1;
+ }
+ for (bd = chan->bd; bd; bd = bd->next) {
+ if (bd->mask)
+ mem += strlen(bd->mask) + 1;
+ mem += sizeof(*bd);
}
}
*nrec = count;
@@ -1205,13 +1155,13 @@ void do_join(const char *source, int ac, const char **av)
std::string channame = cc->chan->name;
FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, cc->chan));
cc->chan->DeleteUser(user);
- FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(channame.c_str()), channame, ""));
+ FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(channame), channame, ""));
}
user->chans.clear();
continue;
}
- chan = findchan(buf.c_str());
+ chan = findchan(buf);
/* Channel doesn't exist, create it */
if (!chan)
@@ -1306,7 +1256,7 @@ void do_part(const char *source, int ac, const char **av)
ci::string buf;
while (sep.GetToken(buf))
{
- Channel *c = findchan(buf.c_str());
+ Channel *c = findchan(buf);
if (!c)
{
@@ -1320,7 +1270,7 @@ void do_part(const char *source, int ac, const char **av)
FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, c));
std::string ChannelName = c->name;
c->DeleteUser(user);
- FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(ChannelName.c_str()), ChannelName, av[1] ? av[1] : ""));
+ FOREACH_MOD(I_OnPartChannel, OnPartChannel(user, findchan(ChannelName), ChannelName, av[1] ? av[1] : ""));
}
else
Alog(LOG_DEBUG) << "Recieved PART from " << user->nick << " for " << c->name << ", but " << user->nick << " isn't in " << c->name << "?";
@@ -1513,9 +1463,9 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes)
c->SetMode(NULL, CMODE_VOICE, user->nick);
}
/* If this channel has secureops or the user matches autodeop or the channel is syncing and this is the first user and they are not ulined, check to remove modes */
- if ((ci->HasFlag(CI_SECUREOPS) || check_access(user, ci, CA_AUTODEOP) || (c->HasFlag(CH_SYNCING) && c->users.size() == 1)) && !is_ulined(user->server->name))
+ if ((ci->HasFlag(CI_SECUREOPS) || check_access(user, ci, CA_AUTODEOP) || (c->HasFlag(CH_SYNCING) && c->users.size() == 1)) && !user->server->IsULined())
{
- if (owner && c->HasUserStatus(user, CMODE_OWNER) && !IsFounder(user, ci))
+ if (owner && c->HasUserStatus(user, CMODE_OWNER) && !check_access(user, ci, CA_FOUNDER))
c->RemoveMode(NULL, CMODE_OWNER, user->nick);
if (admin && c->HasUserStatus(user, CMODE_PROTECT) && !check_access(user, ci, CA_AUTOPROTECT) && !check_access(user, ci, CA_PROTECTME))
@@ -1538,10 +1488,10 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes)
*/
void MassChannelModes(BotInfo *bi, const std::string &modes)
{
- Channel *c;
-
- for (c = firstchan(); c; c = nextchan())
+ for (channel_map::const_iterator it = ChannelList.begin(); it != ChannelList.end(); ++it)
{
+ Channel *c = it->second;
+
if (c->bouncy_modes)
return;
c->SetModes(bi, false, modes.c_str());
@@ -1552,9 +1502,10 @@ void MassChannelModes(BotInfo *bi, const std::string &modes)
void restore_unsynced_topics()
{
- Channel *c;
+ for (channel_map::const_iterator it = ChannelList.begin(); it != ChannelList.end(); ++it)
+ {
+ Channel *c = it->second;
- for (c = firstchan(); c; c = nextchan()) {
if (!(c->topic_sync))
restore_topic(c->name.c_str());
}
diff --git a/src/chanserv.c b/src/chanserv.cpp
index 377a04323..10acd3731 100644
--- a/src/chanserv.c
+++ b/src/chanserv.cpp
@@ -14,12 +14,10 @@
/*************************************************************************/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
+#include "language.h"
-/*************************************************************************/
-/* *INDENT-OFF* */
-
-ChannelInfo *chanlists[256];
+registered_channel_map RegisteredChannelList;
static int def_levels[][2] = {
{ CA_AUTOOP, 5 },
@@ -61,6 +59,7 @@ static int def_levels[][2] = {
{ CA_AUTOOWNER, ACCESS_QOP },
{ CA_OWNER, ACCESS_FOUNDER },
{ CA_OWNERME, ACCESS_QOP },
+ { CA_FOUNDER, ACCESS_QOP },
{ -1 }
};
@@ -105,6 +104,7 @@ LevelInfo levelinfo[] = {
{ CA_AUTOOWNER, "AUTOOWNER", CHAN_LEVEL_AUTOOWNER },
{ CA_OWNER, "OWNER", CHAN_LEVEL_OWNER },
{ CA_OWNERME, "OWNERME", CHAN_LEVEL_OWNERME },
+ { CA_FOUNDER, "FOUNDER", CHAN_LEVEL_FOUNDER },
{ -1 }
};
int levelinfo_maxwidth = 0;
@@ -195,51 +195,51 @@ char *get_mlock_modes(ChannelInfo * ci, int complete)
void get_chanserv_stats(long *nrec, long *memuse)
{
long count = 0, mem = 0;
- unsigned i, j;
- ChannelInfo *ci;
std::string param;
- for (i = 0; i < 256; i++) {
- for (ci = chanlists[i]; ci; ci = ci->next) {
- count++;
- mem += sizeof(*ci);
- if (ci->desc)
- mem += strlen(ci->desc) + 1;
- if (ci->url)
- mem += strlen(ci->url) + 1;
- if (ci->email)
- mem += strlen(ci->email) + 1;
- mem += ci->GetAccessCount() * sizeof(ChanAccess);
- mem += ci->GetAkickCount() * sizeof(AutoKick);
-
- if (ci->GetParam(CMODE_KEY, param))
- mem += param.length() + 1;
-
- if (ci->GetParam(CMODE_FLOOD, param))
- mem += param.length() + 1;
-
- if (ci->GetParam(CMODE_REDIRECT, param))
- mem += param.length() + 1;
-
- if (ci->last_topic)
- mem += strlen(ci->last_topic) + 1;
- if (ci->entry_message)
- mem += strlen(ci->entry_message) + 1;
- if (ci->forbidby)
- mem += strlen(ci->forbidby) + 1;
- if (ci->forbidreason)
- mem += strlen(ci->forbidreason) + 1;
- if (ci->levels)
- mem += sizeof(*ci->levels) * CA_SIZE;
- mem += ci->memos.memos.size() * sizeof(Memo);
- for (j = 0; j < ci->memos.memos.size(); j++) {
- if (ci->memos.memos[j]->text)
- mem += strlen(ci->memos.memos[j]->text) + 1;
- }
- if (ci->ttb)
- mem += sizeof(*ci->ttb) * TTB_SIZE;
- mem += ci->GetBadWordCount() * sizeof(BadWord);
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
+ {
+ ChannelInfo *ci = it->second;
+
+ count++;
+ mem += sizeof(*ci);
+ if (ci->desc)
+ mem += strlen(ci->desc) + 1;
+ if (ci->url)
+ mem += strlen(ci->url) + 1;
+ if (ci->email)
+ mem += strlen(ci->email) + 1;
+ mem += ci->GetAccessCount() * sizeof(ChanAccess);
+ mem += ci->GetAkickCount() * sizeof(AutoKick);
+
+ if (ci->GetParam(CMODE_KEY, param))
+ mem += param.length() + 1;
+
+ if (ci->GetParam(CMODE_FLOOD, param))
+ mem += param.length() + 1;
+
+ if (ci->GetParam(CMODE_REDIRECT, param))
+ mem += param.length() + 1;
+
+ if (ci->last_topic)
+ mem += strlen(ci->last_topic) + 1;
+ if (ci->entry_message)
+ mem += strlen(ci->entry_message) + 1;
+ if (ci->forbidby)
+ mem += strlen(ci->forbidby) + 1;
+ if (ci->forbidreason)
+ mem += strlen(ci->forbidreason) + 1;
+ if (ci->levels)
+ mem += sizeof(*ci->levels) * CA_SIZE;
+ mem += ci->memos.memos.size() * sizeof(Memo);
+ for (unsigned j = 0; j < ci->memos.memos.size(); j++)
+ {
+ if (ci->memos.memos[j]->text)
+ mem += strlen(ci->memos.memos[j]->text) + 1;
}
+ if (ci->ttb)
+ mem += sizeof(*ci->ttb) * TTB_SIZE;
+ mem += ci->GetBadWordCount() * sizeof(BadWord);
}
*nrec = count;
*memuse = mem;
@@ -259,21 +259,21 @@ void cs_init()
/* Main ChanServ routine. */
-void chanserv(User * u, char *buf)
+void chanserv(User *u, const std::string &buf)
{
- char *cmd, *s;
-
- cmd = strtok(buf, " ");
-
- if (!cmd) {
+ if (!u || buf.empty())
return;
- } else if (stricmp(cmd, "\1PING") == 0) {
- if (!(s = strtok(NULL, ""))) {
- *s = 0;
- }
- ircdproto->SendCTCP(findbot(Config.s_ChanServ), u->nick.c_str(), "PING %s", s);
- } else {
- mod_run_cmd(Config.s_ChanServ, u, CHANSERV, cmd);
+
+ if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1')
+ {
+ std::string command = buf;
+ command.erase(command.begin());
+ command.erase(command.end());
+ ircdproto->SendCTCP(ChanServ, u->nick.c_str(), "%s", command.c_str());
+ }
+ else
+ {
+ mod_run_cmd(ChanServ, u, buf);
}
}
@@ -468,111 +468,6 @@ int check_valid_op(User * user, Channel * chan, int servermode)
/*************************************************************************/
-/* Check whether a user should be opped on a channel, and if so, do it.
- * Return 1 if the user was opped, 0 otherwise. (Updates the channel's
- * last used time if the user was opped.) */
-
-int check_should_op(User * user, char *chan)
-{
- ChannelInfo *ci = cs_findchan(chan);
-
- if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+')
- return 0;
-
- if ((ci->HasFlag(CI_SECURE)) && !user->IsIdentified())
- return 0;
-
- if (check_access(user, ci, CA_AUTOOP))
- {
- ci->c->SetMode(NULL, CMODE_OP, user->nick);
- return 1;
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
-/* Check whether a user should be voiced on a channel, and if so, do it.
- * Return 1 if the user was voiced, 0 otherwise. */
-
-int check_should_voice(User * user, char *chan)
-{
- ChannelInfo *ci = cs_findchan(chan);
-
- if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+')
- return 0;
-
- if ((ci->HasFlag(CI_SECURE)) && !user->IsIdentified())
- return 0;
-
- if (check_access(user, ci, CA_AUTOVOICE))
- {
- ci->c->SetMode(NULL, CMODE_VOICE, user->nick);
- return 1;
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
-int check_should_halfop(User * user, char *chan)
-{
- ChannelInfo *ci = cs_findchan(chan);
-
- if (!ci || (ci->HasFlag(CI_FORBIDDEN)) || *chan == '+')
- return 0;
-
- if (check_access(user, ci, CA_AUTOHALFOP))
- {
- ci->c->SetMode(NULL, CMODE_HALFOP, user->nick);
- return 1;
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
-int check_should_owner(User * user, char *chan)
-{
- ChannelInfo *ci = cs_findchan(chan);
-
- if (!ci || !ci->c || ci->HasFlag(CI_FORBIDDEN) || *chan == '+')
- return 0;
-
- if ((ci->HasFlag(CI_SECUREFOUNDER) && IsRealFounder(user, ci))
- || (!ci->HasFlag(CI_SECUREFOUNDER) && IsFounder(user, ci))) {
- ci->c->SetMode(NULL, CMODE_OP, user->nick);
- ci->c->SetMode(NULL, CMODE_OWNER, user->nick);
- return 1;
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
-int check_should_protect(User * user, char *chan)
-{
- ChannelInfo *ci = cs_findchan(chan);
-
- if (!ci || !ci->c || ci->HasFlag(CI_FORBIDDEN) || *chan == '+')
- return 0;
-
- if (check_access(user, ci, CA_AUTOPROTECT))
- {
- ci->c->SetMode(NULL, CMODE_OWNER, user->nick);
- ci->c->SetMode(NULL, CMODE_PROTECT, user->nick);
- return 1;
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
/* Record the current channel topic in the ChannelInfo structure. */
void record_topic(const char *chan)
@@ -632,15 +527,15 @@ void restore_topic(const char *chan)
c->topic_setter = whosends(ci)->nick;
}
if (ircd->join2set) {
- if (whosends(ci) == findbot(Config.s_ChanServ)) {
- ircdproto->SendJoin(findbot(Config.s_ChanServ), chan, c->creation_time);
+ if (whosends(ci) == ChanServ) {
+ ircdproto->SendJoin(ChanServ, chan, c->creation_time);
c->SetMode(NULL, CMODE_OP, Config.s_ChanServ);
}
}
ircdproto->SendTopic(whosends(ci), c, c->topic_setter.c_str(), c->topic ? c->topic : "");
if (ircd->join2set) {
- if (whosends(ci) == findbot(Config.s_ChanServ)) {
- ircdproto->SendPart(findbot(Config.s_ChanServ), c, NULL);
+ if (whosends(ci) == ChanServ) {
+ ircdproto->SendPart(ChanServ, c, NULL);
}
}
}
@@ -692,8 +587,8 @@ int check_topiclock(Channel * c, time_t topic_time)
}
if (ircd->join2set) {
- if (whosends(ci) == findbot(Config.s_ChanServ)) {
- ircdproto->SendJoin(findbot(Config.s_ChanServ), c->name.c_str(), c->creation_time);
+ if (whosends(ci) == ChanServ) {
+ ircdproto->SendJoin(ChanServ, c->name.c_str(), c->creation_time);
c->SetMode(NULL, CMODE_OP, Config.s_ChanServ);
}
}
@@ -701,8 +596,8 @@ int check_topiclock(Channel * c, time_t topic_time)
ircdproto->SendTopic(whosends(ci), c, c->topic_setter.c_str(), c->topic ? c->topic : "");
if (ircd->join2set) {
- if (whosends(ci) == findbot(Config.s_ChanServ)) {
- ircdproto->SendPart(findbot(Config.s_ChanServ), c, NULL);
+ if (whosends(ci) == ChanServ) {
+ ircdproto->SendPart(ChanServ, c, NULL);
}
}
return 1;
@@ -714,118 +609,113 @@ int check_topiclock(Channel * c, time_t topic_time)
void expire_chans()
{
- ChannelInfo *ci, *next;
- int i;
- time_t now = time(NULL);
-
if (!Config.CSExpire)
return;
+
+ time_t now = time(NULL);
- for (i = 0; i < 256; i++) {
- for (ci = chanlists[i]; ci; ci = next) {
- next = ci->next;
- if (!ci->c && now - ci->last_used >= Config.CSExpire && !ci->HasFlag(CI_FORBIDDEN) && !ci->HasFlag(CI_NO_EXPIRE) && !ci->HasFlag(CI_SUSPENDED))
- {
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci));
- if (MOD_RESULT == EVENT_STOP)
- continue;
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end();)
+ {
+ ChannelInfo *ci = it->second;
+ ++it;
- char *chname = sstrdup(ci->name.c_str());
- Alog() << "Expiring channel " << ci->name << " (founder: " << (ci->founder ? ci->founder->display : "(none)") << " )";
- delete ci;
- FOREACH_MOD(I_OnChanExpire, OnChanExpire(chname));
- delete [] chname;
- }
+ if (!ci->c && now - ci->last_used >= Config.CSExpire && !ci->HasFlag(CI_FORBIDDEN) && !ci->HasFlag(CI_NO_EXPIRE) && !ci->HasFlag(CI_SUSPENDED))
+ {
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci));
+ if (MOD_RESULT == EVENT_STOP)
+ continue;
+
+ char *chname = sstrdup(ci->name.c_str());
+ Alog() << "Expiring channel " << ci->name << " (founder: " << (ci->founder ? ci->founder->display : "(none)") << " )";
+ delete ci;
+ FOREACH_MOD(I_OnChanExpire, OnChanExpire(chname));
+ delete [] chname;
}
}
}
/*************************************************************************/
-/* Remove a (deleted or expired) nickname from all channel lists. */
-
+// XXX this is slightly inefficient
void cs_remove_nick(const NickCore * nc)
{
- int i, j;
- ChannelInfo *ci, *next;
+ int j;
ChanAccess *ca;
AutoKick *akick;
- for (i = 0; i < 256; i++) {
- for (ci = chanlists[i]; ci; ci = next) {
- next = ci->next;
- if (ci->founder == nc) {
- if (ci->successor) {
- NickCore *nc2 = ci->successor;
- if (!nc2->IsServicesOper() && Config.CSMaxReg && nc2->channelcount >= Config.CSMaxReg) {
- Alog() << Config.s_ChanServ << ": Successor (" << nc2->display << " ) of " << ci->name << " owns too many channels, deleting channel",
- delete ci;
- continue;
- } else {
- Alog() << Config.s_ChanServ << ": Transferring foundership of " << ci->name << " from deleted nick " << nc->display << " to successor " << nc2->display;
- ci->founder = nc2;
- ci->successor = NULL;
- nc2->channelcount++;
- }
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
+ {
+ ChannelInfo *ci = it->second;
+
+ if (ci->founder == nc) {
+ if (ci->successor) {
+ NickCore *nc2 = ci->successor;
+ if (!nc2->IsServicesOper() && Config.CSMaxReg && nc2->channelcount >= Config.CSMaxReg) {
+ Alog() << Config.s_ChanServ << ": Successor (" << nc2->display << " ) of " << ci->name << " owns too many channels, deleting channel",
+ delete ci;
+ continue;
} else {
- Alog() << Config.s_ChanServ << ": Deleting channel " << ci->name << "owned by deleted nick " << nc->display;
+ Alog() << Config.s_ChanServ << ": Transferring foundership of " << ci->name << " from deleted nick " << nc->display << " to successor " << nc2->display;
+ ci->founder = nc2;
+ ci->successor = NULL;
+ nc2->channelcount++;
+ }
+ } else {
+ Alog() << Config.s_ChanServ << ": Deleting channel " << ci->name << "owned by deleted nick " << nc->display;
- if ((ModeManager::FindChannelModeByName(CMODE_REGISTERED)))
+ if ((ModeManager::FindChannelModeByName(CMODE_REGISTERED)))
+ {
+ /* Maybe move this to delchan() ? */
+ if (ci->c && ci->c->HasMode(CMODE_REGISTERED))
{
- /* Maybe move this to delchan() ? */
- if (ci->c && ci->c->HasMode(CMODE_REGISTERED))
- {
- ci->c->RemoveMode(NULL, CMODE_REGISTERED);
- }
+ ci->c->RemoveMode(NULL, CMODE_REGISTERED);
}
-
- delete ci;
- continue;
}
+
+ delete ci;
+ continue;
}
+ }
- if (ci->successor == nc)
- ci->successor = NULL;
+ if (ci->successor == nc)
+ ci->successor = NULL;
- for (j = ci->GetAccessCount(); j > 0; --j)
- {
- ca = ci->GetAccess(j - 1);
+ for (j = ci->GetAccessCount(); j > 0; --j)
+ {
+ ca = ci->GetAccess(j - 1);
- if (ca->in_use && ca->nc == nc)
- ci->EraseAccess(j - 1);
- }
+ if (ca->nc == nc)
+ ci->EraseAccess(j - 1);
+ }
- for (j = ci->GetAkickCount(); j > 0; --j)
- {
- akick = ci->GetAkick(j - 1);
- if (akick->InUse && akick->HasFlag(AK_ISNICK) && akick->nc == nc)
- ci->EraseAkick(akick);
- }
+ for (j = ci->GetAkickCount(); j > 0; --j)
+ {
+ akick = ci->GetAkick(j - 1);
+ if (akick->HasFlag(AK_ISNICK) && akick->nc == nc)
+ ci->EraseAkick(j - 1);
}
}
}
/*************************************************************************/
-/* Return the ChannelInfo structure for the given channel, or NULL if the
- * channel isn't registered. */
+ChannelInfo *cs_findchan(const char *chan)
+{
+ return cs_findchan(ci::string(chan));
+}
ChannelInfo *cs_findchan(const std::string &chan)
{
- ChannelInfo *ci;
+ return cs_findchan(ci::string(chan.c_str()));
+}
- if (chan.empty())
- {
- Alog(LOG_DEBUG) << "cs_findchan() called with NULL values";
- return NULL;
- }
+ChannelInfo *cs_findchan(const ci::string &chan)
+{
+ registered_channel_map::const_iterator it = RegisteredChannelList.find(chan);
- for (ci = chanlists[static_cast<unsigned char>(tolower(chan[1]))]; ci;
- ci = ci->next) {
- if (ci::string(ci->name.c_str()) == chan)
- return ci;
- }
+ if (it != RegisteredChannelList.end())
+ return it->second;
return NULL;
}
@@ -853,15 +743,20 @@ int check_access(User * user, ChannelInfo * ci, int what)
if (level > 0)
ci->last_used = time(NULL);
+ /* Superadmin always wins. Always. */
+ if (user->isSuperAdmin)
+ return (what == CA_AUTODEOP || what == CA_NOJOIN ? 0 : 1);
+ /* If the access of the level we are checking is disabled, they *always* get denied */
if (limit == ACCESS_INVALID)
return 0;
- if (limit > ACCESS_FOUNDER)
- return 1;
- if (limit == ACCESS_FOUNDER)
- return (what == CA_AUTODEOP || what == CA_NOJOIN ? !IsRealFounder(user, ci) : IsRealFounder(user, ci));
+ /* If the level of the user is >= the level for "founder" of this channel and "founder" isn't disabled, they can do anything */
+ if (ci->levels[CA_FOUNDER] != ACCESS_INVALID && level >= ci->levels[CA_FOUNDER])
+ return (what == CA_AUTODEOP || what == CA_NOJOIN ? 0 : 1);
+
/* Hacks to make flags work */
if (what == CA_AUTODEOP && (ci->HasFlag(CI_SECUREOPS)) && level == 0)
return 1;
+
if (what == CA_AUTODEOP || what == CA_NOJOIN)
return level <= ci->levels[what];
else
@@ -872,33 +767,6 @@ int check_access(User * user, ChannelInfo * ci, int what)
/*********************** ChanServ private routines ***********************/
/*************************************************************************/
-/* Insert a channel alphabetically into the database. */
-
-void alpha_insert_chan(ChannelInfo * ci)
-{
- ChannelInfo *ptr, *prev;
-
- if (!ci)
- {
- Alog(LOG_DEBUG) << "alpha_insert_chan() called with NULL values";
- return;
- }
-
- const char *chan = ci->name.c_str();
-
- for (prev = NULL, ptr = chanlists[static_cast<unsigned char>(tolower(chan[1]))];
- ptr != NULL && stricmp(ptr->name.c_str(), chan) < 0;
- prev = ptr, ptr = ptr->next);
- ci->prev = prev;
- ci->next = ptr;
- if (!prev)
- chanlists[static_cast<unsigned char>(tolower(chan[1]))] = ci;
- else
- prev->next = ci;
- if (ptr)
- ptr->prev = ci;
-}
-
/* Reset channel access level values to their default state. */
void reset_levels(ChannelInfo * ci)
@@ -920,43 +788,12 @@ void reset_levels(ChannelInfo * ci)
/*************************************************************************/
-/** Is the user a channel founder? (owner)
- * @param user The user
- * @param ci The channel
- * @return true or false
- */
-bool IsFounder(User *user, ChannelInfo *ci)
-{
- ChanAccess *access = NULL;
-
- if (!user || !ci)
- return false;
-
- if (IsRealFounder(user, ci))
- return true;
-
- if (user->Account())
- access = ci->GetAccess(user->Account());
- else
- {
- NickAlias *na = findnick(user->nick);
- if (na)
- access = ci->GetAccess(na->nc);
- }
-
- /* If they're QOP+ and theyre identified or theyre recognized and the channel isn't secure */
- if (access && access->level >= ACCESS_QOP && (user->Account() || (user->IsRecognized() && !(ci->HasFlag(CI_SECURE)))))
- return true;
-
- return false;
-}
-
/** Is the user the real founder?
* @param user The user
* @param ci The channel
* @return true or false
*/
-bool IsRealFounder(User *user, ChannelInfo *ci)
+bool IsFounder(User *user, ChannelInfo *ci)
{
if (!user || !ci)
return false;
@@ -1088,6 +925,22 @@ int get_access_level(ChannelInfo * ci, NickAlias * na)
return access->level;
}
+int get_access_level(ChannelInfo *ci, NickCore *nc)
+{
+ if (!ci || !nc)
+ return 0;
+
+ if (nc == ci->founder)
+ return ACCESS_FOUNDER;
+
+ ChanAccess *access = ci->GetAccess(nc);
+
+ if (!access)
+ return 0;
+ else
+ return access->level;
+}
+
const char *get_xop_level(int level)
{
ChannelMode *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP);
@@ -1125,7 +978,7 @@ AutoKick *is_stuck(ChannelInfo * ci, const char *mask)
{
AutoKick *akick = ci->GetAkick(i);
- if (!akick->InUse || akick->HasFlag(AK_ISNICK) || !akick->HasFlag(AK_STUCK))
+ if (akick->HasFlag(AK_ISNICK) || !akick->HasFlag(AK_STUCK))
continue;
if (Anope::Match(akick->mask, mask, false))
@@ -1180,7 +1033,7 @@ void stick_all(ChannelInfo * ci)
{
AutoKick *akick = ci->GetAkick(i);
- if (!akick->InUse || (akick->HasFlag(AK_ISNICK) || !akick->HasFlag(AK_STUCK)))
+ if (akick->HasFlag(AK_ISNICK) || !akick->HasFlag(AK_STUCK))
continue;
ci->c->SetMode(NULL, CMODE_BAN, akick->mask.c_str());
@@ -1204,7 +1057,7 @@ void ChanServTimer::Tick(time_t)
if (!c->users.empty())
return;
- ircdproto->SendPart(findbot(Config.s_ChanServ), c, NULL);
+ ircdproto->SendPart(ChanServ, c, NULL);
/* Now delete the channel as it is empty */
if (!c->HasFlag(CH_PERSIST) && !c->ci->HasFlag(CI_PERSIST))
diff --git a/src/command.cpp b/src/command.cpp
index ea66a7261..922f298c3 100644
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -10,32 +10,41 @@
#include "services.h"
#include "modules.h"
-Command::Command(const std::string &sname, size_t min_params, size_t max_params, const std::string &spermission) : MaxParams(max_params), MinParams(min_params), name(sname), permission(spermission)
+Command::Command(const ci::string &sname, size_t min_params, size_t max_params, const std::string &spermission) : MaxParams(max_params), MinParams(min_params), name(sname), permission(spermission)
{
- this->core = 0;
- this->mod_name = NULL;
+ this->module = NULL;
this->service = NULL;
- this->next = NULL;
}
Command::~Command()
{
- if (this->mod_name) {
- delete [] this->mod_name;
- }
- if (this->service) {
- delete [] this->service;
- }
}
-CommandReturn Command::Execute(User *u, const std::vector<ci::string> &) { return MOD_CONT; }
+CommandReturn Command::Execute(User *u, const std::vector<ci::string> &)
+{
+ return MOD_CONT;
+}
+
+void Command::OnServHelp(User *u) { }
bool Command::OnHelp(User *u, const ci::string &subcommand) { return false; }
-void Command::OnSyntaxError(User *u, const ci::string &subcommand) { }
+void Command::OnSyntaxError(User *u, const ci::string &subcommand)
+{
+}
void Command::SetPermission(const std::string &reststr)
{
this->permission = reststr;
}
+bool Command::AddSubcommand(Command *c)
+{
+ return false;
+}
+
+bool Command::DelSubcommand(const ci::string &cname)
+{
+ return false;
+}
+
diff --git a/src/commands.c b/src/commands.cpp
index 19d668137..f066b2885 100644
--- a/src/commands.c
+++ b/src/commands.cpp
@@ -12,55 +12,49 @@
*/
#include "services.h"
-#include "commands.h"
+#include "modules.h"
#include "language.h"
#include "hashcomp.h"
-/*************************************************************************/
+Command *FindCommand(BotInfo *bi, const ci::string &name)
+{
+ if (!bi || bi->Commands.empty() || name.empty())
+ return NULL;
+
+ std::map<ci::string, Command *>::iterator it = bi->Commands.find(name);
-/**
- * Return the Command corresponding to the given name, or NULL if no such
- * command exists.
- * @param list Command struct
- * @param cmd Command to look up
- * @return Command Struct for the given cmd
- */
-Command *lookup_cmd(Command * list, char *cmd)
+ if (it != bi->Commands.end())
+ return it->second;
+
+ return NULL;
+}
+
+void mod_run_cmd(BotInfo *bi, User *u, const std::string &message)
{
- Command *c;
+ spacesepstream sep(ci::string(message.c_str()));
+ ci::string cmd;
- for (c = list; ; c++) {
- if (stricmp(c->name.c_str(), cmd) == 0) {
- return c;
- }
+ if (sep.GetToken(cmd))
+ {
+ mod_run_cmd(bi, u, FindCommand(bi, cmd), cmd, sep.GetRemaining().c_str());
}
}
-/*************************************************************************/
-
-/**
- * Run the routine for the given command, if it exists and the user has
- * privilege to do so; if not, print an appropriate error message.
- * @param services Services Client
- * @param u User Struct
- * @param Command Hash Table
- * @param cmd Command
- * @return void
- */
-void mod_run_cmd(const std::string &service, User * u, CommandHash * cmdTable[], const char *cmd)
+void mod_run_cmd(BotInfo *bi, User *u, Command *c, const ci::string &command, const ci::string &message)
{
- Command *c = findCommand(cmdTable, cmd);
- int retVal = MOD_CONT;
- ChannelInfo *ci;
- EventReturn MOD_RESULT;
+ if (!bi || !u)
+ return;
+
+ CommandReturn ret = MOD_CONT;
- FOREACH_RESULT(I_OnPreCommandRun, OnPreCommandRun(service, u, cmd, c));
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnPreCommandRun, OnPreCommandRun(u, bi, command, message, c));
if (MOD_RESULT == EVENT_STOP)
return;
if (!c)
{
- notice_lang(service, u, UNKNOWN_COMMAND_HELP, cmd, service.c_str());
+ notice_lang(bi->nick, u, UNKNOWN_COMMAND_HELP, command.c_str(), bi->nick.c_str());
return;
}
@@ -69,36 +63,36 @@ void mod_run_cmd(const std::string &service, User * u, CommandHash * cmdTable[],
// Command requires registered users only
if (!u->IsIdentified())
{
- notice_lang(service, u, NICK_IDENTIFY_REQUIRED, Config.s_NickServ);
- Alog() << "Access denied for unregistered user " << u->nick << " with service " << service << " and command " << cmd;
+ notice_lang(bi->nick, u, NICK_IDENTIFY_REQUIRED, Config.s_NickServ);
+ Alog() << "Access denied for unregistered user " << u->nick << " with service " << bi->nick << " and command " << command;
return;
}
}
std::vector<ci::string> params;
- std::string curparam;
- char *s = NULL;
- while ((s = strtok(NULL, " ")))
+ ci::string curparam, endparam;
+ spacesepstream sep(message);
+ while (sep.GetToken(curparam))
{
// - 1 because params[0] corresponds with a maxparam of 1.
if (params.size() >= (c->MaxParams - 1))
{
- curparam += s;
- curparam += " ";
+ endparam += curparam;
+ endparam += " ";
}
else
{
- params.push_back(s);
+ params.push_back(curparam);
}
}
- if (!curparam.empty())
+ if (!endparam.empty())
{
// Remove trailing space
- curparam.erase(curparam.size() - 1, curparam.size());
+ endparam.erase(endparam.size() - 1, endparam.size());
// Add it
- params.push_back(curparam.c_str());
+ params.push_back(endparam);
}
if (params.size() < c->MinParams)
@@ -107,41 +101,42 @@ void mod_run_cmd(const std::string &service, User * u, CommandHash * cmdTable[],
return;
}
- FOREACH_RESULT(I_OnPreCommand, OnPreCommand(u, c->service, c->name.c_str(), params));
+ FOREACH_RESULT(I_OnPreCommand, OnPreCommand(u, c->service, c->name, params));
if (MOD_RESULT == EVENT_STOP)
return;
- if (params.size() > 0 && !c->HasFlag(CFLAG_STRIP_CHANNEL) && (cmdTable == CHANSERV || cmdTable == BOTSERV))
+ if (params.size() > 0 && !c->HasFlag(CFLAG_STRIP_CHANNEL) && (bi == ChanServ || bi == BotServ))
{
if (ircdproto->IsChannelValid(params[0].c_str()))
{
- if ((ci = cs_findchan(params[0].c_str())))
+ ChannelInfo *ci = cs_findchan(params[0]);
+ if (ci)
{
if ((ci->HasFlag(CI_FORBIDDEN)) && (!c->HasFlag(CFLAG_ALLOW_FORBIDDEN)))
{
- notice_lang(service, u, CHAN_X_FORBIDDEN, ci->name.c_str());
- Alog() << "Access denied for user " << u->nick << " with service " << service
- << " and command " << cmd << " because of FORBIDDEN channel " << ci->name;
+ notice_lang(bi->nick, u, CHAN_X_FORBIDDEN, ci->name.c_str());
+ Alog() << "Access denied for user " << u->nick << " with service " << bi->nick
+ << " and command " << command << " because of FORBIDDEN channel " << ci->name;
return;
}
else if ((ci->HasFlag(CI_SUSPENDED)) && (!c->HasFlag(CFLAG_ALLOW_SUSPENDED)))
{
- notice_lang(service, u, CHAN_X_FORBIDDEN, ci->name.c_str());
- Alog() << "Access denied for user " << u->nick << " with service " << service
- <<" and command " << cmd << " because of SUSPENDED channel " << ci->name;
+ notice_lang(bi->nick, u, CHAN_X_FORBIDDEN, ci->name.c_str());
+ Alog() << "Access denied for user " << u->nick << " with service " << bi->nick
+ <<" and command " << command << " because of SUSPENDED channel " << ci->name;
return;
}
}
else if (!c->HasFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL))
{
- notice_lang(service, u, CHAN_X_NOT_REGISTERED, params[0].c_str());
+ notice_lang(bi->nick, u, CHAN_X_NOT_REGISTERED, params[0].c_str());
return;
}
}
/* A user not giving a channel name for a param that should be a channel */
else
{
- notice_lang(service, u, CHAN_X_INVALID, params[0].c_str());
+ notice_lang(bi->nick, u, CHAN_X_INVALID, params[0].c_str());
return;
}
}
@@ -151,23 +146,21 @@ void mod_run_cmd(const std::string &service, User * u, CommandHash * cmdTable[],
{
if (!u->Account()->HasCommand(c->permission))
{
- notice_lang(service, u, ACCESS_DENIED);
- Alog() << "Access denied for user " << u->nick << " with service " << service << " and command " << cmd;
+ notice_lang(bi->nick, u, ACCESS_DENIED);
+ Alog() << "Access denied for user " << u->nick << " with service " << bi->nick << " and command " << command;
return;
}
}
- retVal = c->Execute(u, params);
+ ret = c->Execute(u, params);
- if (retVal == MOD_CONT)
+ if (ret == MOD_CONT)
{
FOREACH_MOD(I_OnPostCommand, OnPostCommand(u, c->service, c->name.c_str(), params));
}
}
-/*************************************************************************/
-
/**
* Prints the help message for a given command.
* @param services Services Client
@@ -176,36 +169,38 @@ void mod_run_cmd(const std::string &service, User * u, CommandHash * cmdTable[],
* @param cmd Command
* @return void
*/
-void mod_help_cmd(char *service, User * u, CommandHash * cmdTable[], const char *cmd)
+void mod_help_cmd(BotInfo *bi, User *u, const ci::string &cmd)
{
+ if (!bi || !u || cmd.empty())
+ return;
+
spacesepstream tokens(cmd);
- std::string token;
+ ci::string token;
tokens.GetToken(token);
- Command *c = findCommand(cmdTable, token.c_str());
+ Command *c = FindCommand(bi, token);
ci::string subcommand = tokens.StreamEnd() ? "" : tokens.GetRemaining().c_str();
if (!c || !c->OnHelp(u, subcommand))
- notice_lang(service, u, NO_HELP_AVAILABLE, cmd);
+ notice_lang(bi->nick, u, NO_HELP_AVAILABLE, cmd.c_str());
else
{
- u->SendMessage(service, " ");
+ u->SendMessage(bi->nick, " ");
/* Inform the user what permission is required to use the command */
if (!c->permission.empty())
- notice_lang(service, u, COMMAND_REQUIRES_PERM, c->permission.c_str());
+ notice_lang(bi->nick, u, COMMAND_REQUIRES_PERM, c->permission.c_str());
/* User isn't identified and needs to be to use this command */
if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified())
- notice_lang(service, u, COMMAND_IDENTIFY_REQUIRED);
+ notice_lang(bi->nick, u, COMMAND_IDENTIFY_REQUIRED);
/* User doesn't have the proper permission to use this command */
else if (!c->permission.empty() && (!u->Account() || (!u->Account()->HasCommand(c->permission))))
- notice_lang(service, u, COMMAND_CANNOT_USE);
+ notice_lang(bi->nick, u, COMMAND_CANNOT_USE);
/* User can use this command */
else
- notice_lang(service, u, COMMAND_CAN_USE);
+ notice_lang(bi->nick, u, COMMAND_CAN_USE);
}
}
-/*************************************************************************/
diff --git a/src/compat.c b/src/compat.cpp
index eb3088fe9..eb3088fe9 100644
--- a/src/compat.c
+++ b/src/compat.cpp
diff --git a/src/config.c b/src/config.cpp
index 9c486b7e3..a1264abce 100644
--- a/src/config.c
+++ b/src/config.cpp
@@ -12,7 +12,7 @@
*/
#include "services.h"
-#include "configreader.h"
+#include "config.h"
#include "hashcomp.h" // If this gets added to services.h or someplace else later, remove it from here -- CyberBotX
/*************************************************************************/
@@ -425,8 +425,9 @@ static bool InitOperTypes(ServerConfig *, const char *, bool)
static bool DoOperType(ServerConfig *conf, const char *, const char **, ValueList &values, int *, bool)
{
const char *name = values[0].GetString();
- const char *commands = values[1].GetString();
- const char *privs = values[2].GetString();
+ const char *inherits = values[1].GetString();
+ const char *commands = values[2].GetString();
+ const char *privs = values[3].GetString();
ValueItem vi(name);
if (!ValidateNotEmpty(conf, "opertype", "name", vi))
@@ -442,6 +443,23 @@ static bool DoOperType(ServerConfig *conf, const char *, const char **, ValueLis
spacesepstream privstr(privs);
while (privstr.GetToken(tok))
ot->AddPriv(tok);
+
+ commasepstream inheritstr(inherits);
+ while (inheritstr.GetToken(tok))
+ {
+ /* Strip leading ' ' after , */
+ if (tok.size() > 1 && tok[0] == ' ')
+ tok.erase(tok.begin());
+ for (std::list<OperType *>::iterator it = Config.MyOperTypes.begin(); it != Config.MyOperTypes.end(); ++it)
+ {
+ if ((*it)->GetName() == tok)
+ {
+ Alog() << "Inheriting commands and privs from " << (*it)->GetName() << " to " << ot->GetName();
+ ot->Inherits(*it);
+ break;
+ }
+ }
+ }
Config.MyOperTypes.push_back(ot);
return true;
@@ -456,13 +474,9 @@ static bool DoneOperTypes(ServerConfig *, const char *, bool)
static bool InitOpers(ServerConfig *, const char *, bool)
{
- int i;
- NickCore *nc;
+ for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it)
+ it->second->ot = NULL;
- for (i = 0; i < 1024; ++i)
- for (nc = nclists[i]; nc; nc = nc->next)
- nc->ot = NULL;
-
Config.Opers.clear();
return true;
@@ -724,11 +738,11 @@ int ServerConfig::Read(bool bail)
{"operserv", "logmaxusers", "no", new ValueContainerBool(&Config.LogMaxUsers), DT_BOOLEAN, NoValidation},
{"operserv", "autokillexpiry", "0", new ValueContainerTime(&Config.AutokillExpiry), DT_TIME, ValidateNotZero},
{"operserv", "chankillexpiry", "0", new ValueContainerTime(&Config.ChankillExpiry), DT_TIME, ValidateNotZero},
- {"operserv", "sglineexpiry", "0", new ValueContainerTime(&Config.SGLineExpiry), DT_TIME, ValidateNotZero},
+ {"operserv", "snlineexpiry", "0", new ValueContainerTime(&Config.SNLineExpiry), DT_TIME, ValidateNotZero},
{"operserv", "sqlineexpiry", "0", new ValueContainerTime(&Config.SQLineExpiry), DT_TIME, ValidateNotZero},
{"operserv", "szlineexpiry", "0", new ValueContainerTime(&Config.SZLineExpiry), DT_TIME, ValidateNotZero},
{"operserv", "akillonadd", "no", new ValueContainerBool(&Config.AkillOnAdd), DT_BOOLEAN, NoValidation},
- {"operserv", "killonsgline", "no", new ValueContainerBool(&Config.KillonSGline), DT_BOOLEAN, NoValidation},
+ {"operserv", "killonsnline", "no", new ValueContainerBool(&Config.KillonSNline), DT_BOOLEAN, NoValidation},
{"operserv", "killonsqline", "no", new ValueContainerBool(&Config.KillonSQline), DT_BOOLEAN, NoValidation},
{"operserv", "notifications", "", new ValueContainerString(&OSNotifications), DT_STRING, NoValidation},
{"operserv", "limitsessions", "no", new ValueContainerBool(&Config.LimitSessions), DT_BOOLEAN, NoValidation},
@@ -772,9 +786,9 @@ int ServerConfig::Read(bool bail)
{DT_CHARPTR},
InitModules, DoModule, DoneModules},
{"opertype",
- {"name", "commands", "privs", NULL},
- {"", "", "", NULL},
- {DT_CHARPTR, DT_CHARPTR, DT_CHARPTR},
+ {"name", "inherits", "commands", "privs", NULL},
+ {"", "", "", "", NULL},
+ {DT_CHARPTR, DT_CHARPTR, DT_CHARPTR, DT_CHARPTR},
InitOperTypes, DoOperType, DoneOperTypes},
{"oper",
{"name", "type", NULL},
@@ -1619,8 +1633,8 @@ int read_config(int reload)
}
}
- Config.WallOper = Config.WallBadOS = Config.WallOSGlobal = Config.WallOSMode = Config.WallOSClearmodes = Config.WallOSKick = Config.WallOSAkill = Config.WallOSSGLine = Config.WallOSSQLine =
- Config.WallOSSZLine = Config.WallOSNoOp = Config.WallOSJupe = Config.WallAkillExpire = Config.WallSGLineExpire = Config.WallSQLineExpire = Config.WallSZLineExpire = Config.WallExceptionExpire = Config.WallGetpass = Config.WallSetpass = Config.WallForbid =
+ Config.WallOper = Config.WallBadOS = Config.WallOSGlobal = Config.WallOSMode = Config.WallOSClearmodes = Config.WallOSKick = Config.WallOSAkill = Config.WallOSSNLine = Config.WallOSSQLine =
+ Config.WallOSSZLine = Config.WallOSNoOp = Config.WallOSJupe = Config.WallAkillExpire = Config.WallSNLineExpire = Config.WallSQLineExpire = Config.WallSZLineExpire = Config.WallExceptionExpire = Config.WallGetpass = Config.WallSetpass = Config.WallForbid =
Config.WallDrop = false;
if (!OSNotifications.empty()) {
spacesepstream notifications(OSNotifications);
@@ -1633,13 +1647,13 @@ int read_config(int reload)
else if (notice == "osclearmodes") Config.WallOSClearmodes = true;
else if (notice == "oskick") Config.WallOSKick = true;
else if (notice == "osakill") Config.WallOSAkill = true;
- else if (notice == "ossgline") Config.WallOSSGLine = true;
+ else if (notice == "ossnline") Config.WallOSSNLine = true;
else if (notice == "ossqline") Config.WallOSSQLine = true;
else if (notice == "osszline") Config.WallOSSZLine = true;
else if (notice == "osnoop") Config.WallOSNoOp = true;
else if (notice == "osjupe") Config.WallOSJupe = true;
else if (notice == "akillexpire") Config.WallAkillExpire = true;
- else if (notice == "sglineexpire") Config.WallSGLineExpire = true;
+ else if (notice == "snlineexpire") Config.WallSNLineExpire = true;
else if (notice == "sqlineexpire") Config.WallSQLineExpire = true;
else if (notice == "szlineexpire") Config.WallSZLineExpire = true;
else if (notice == "exceptionexpire") Config.WallExceptionExpire = true;
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index f8547872b..2af2b3ea9 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,5 +1,4 @@
-# Find all the *.c and *.cpp files within the current source directory, and sort the list
-file(GLOB CORE_SRCS_C RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c")
+# Find all the *.cpp files within the current source directory, and sort the list
file(GLOB CORE_SRCS_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp")
set(CORE_SRCS ${CORE_SRCS_C} ${CORE_SRCS_CPP})
sort_list(CORE_SRCS)
diff --git a/src/core/Makefile b/src/core/Makefile
index 122522d69..e1dec257c 100644
--- a/src/core/Makefile
+++ b/src/core/Makefile
@@ -8,8 +8,7 @@ MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \
'PROFILE=${PROFILE}' 'SHARED=${SHARED}' \
'MODULEFLAGS=${MODULEFLAGS}' 'MAKEBIN=${MAKEBIN}'
-OBJECTS= $(SRCS:.c=.so)
-OBJECTS+= $(SRCS:.cpp=.so)
+OBJECTS= $(SRCS:.cpp=.so)
CDEFS= -rdynamic -Wall
all: modules subs
@@ -21,10 +20,7 @@ install:
distclean: spotless
-.SUFFIXES: .c .cpp .so
-
-.c.so:
- $(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} -I../${INCLUDEDIR} -o $@ $<
+.SUFFIXES: .cpp .so
.cpp.so:
$(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} -I../${INCLUDEDIR} -o $@ $<
diff --git a/src/core/bs_act.c b/src/core/bs_act.cpp
index d0b9c8b08..d313fd587 100644
--- a/src/core/bs_act.c
+++ b/src/core/bs_act.cpp
@@ -23,7 +23,7 @@ class CommandBSAct : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- ChannelInfo *ci = cs_findchan(params[0].c_str());
+ ChannelInfo *ci = cs_findchan(params[0]);
ci::string message = params[1];
if (!check_access(u, ci, CA_SAY))
@@ -65,6 +65,11 @@ class CommandBSAct : public Command
notice_help(Config.s_BotServ, u, BOT_HELP_ACT);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_ACT);
+ }
};
class BSAct : public Module
@@ -75,13 +80,7 @@ class BSAct : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSAct());
-
- ModuleManager::Attach(I_OnBotServHelp, this);
- }
- void OnBotServHelp(User *u)
- {
- notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_ACT);
+ this->AddCommand(BotServ, new CommandBSAct());
}
};
diff --git a/src/core/bs_assign.c b/src/core/bs_assign.cpp
index f37db9aca..d5fa0bdef 100644
--- a/src/core/bs_assign.c
+++ b/src/core/bs_assign.cpp
@@ -75,6 +75,11 @@ class CommandBSAssign : public Command
{
syntax_error(Config.s_BotServ, u, "ASSIGN", BOT_ASSIGN_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_ASSIGN);
+ }
};
class BSAssign : public Module
@@ -85,13 +90,7 @@ class BSAssign : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSAssign);
-
- ModuleManager::Attach(I_OnBotServHelp, this);
- }
- void OnBotServHelp(User *u)
- {
- notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_ASSIGN);
+ this->AddCommand(BotServ, new CommandBSAssign);
}
};
diff --git a/src/core/bs_badwords.c b/src/core/bs_badwords.cpp
index af616c41a..7a9c6ebdf 100644
--- a/src/core/bs_badwords.c
+++ b/src/core/bs_badwords.cpp
@@ -14,40 +14,106 @@
#include "module.h"
-int badwords_del_callback(User * u, int num, va_list args);
-int badwords_list(User * u, int index, ChannelInfo * ci, int *sent_header);
-int badwords_list_callback(User * u, int num, va_list args);
+class BadwordsListCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ bool SentHeader;
+ public:
+ BadwordsListCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list, false), u(_u), ci(_ci), SentHeader(false)
+ {
+ }
+
+ ~BadwordsListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetBadWordCount())
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str());
+ }
+
+ DoList(u, ci, Number - 1, ci->GetBadWord(Number - 1));
+ }
+
+ static void DoList(User *u, ChannelInfo *ci, unsigned Number, BadWord *bw)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_FORMAT, Number + 1, bw->word.c_str(), ((bw->type == BW_SINGLE) ? "(SINGLE)" : ((bw->type == BW_START) ? "(START)" : ((bw->type == BW_END) ? "(END)" : ""))));
+ }
+};
+
+class BadwordsDelCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ unsigned Deleted;
+ public:
+ BadwordsDelCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list, true), u(_u), ci(_ci), Deleted(0)
+ {
+ }
+
+ ~BadwordsDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
+ else if (Deleted == 1)
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_ONE, ci->name.c_str());
+ else
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_SEVERAL, Deleted, ci->name.c_str());
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetBadWordCount())
+ return;
+
+ ++Deleted;
+ ci->EraseBadWord(Number - 1);
+ }
+};
class CommandBSBadwords : public Command
{
private:
CommandReturn DoList(User *u, ChannelInfo *ci, const ci::string &word)
{
- int sent_header = 0;
-
if (!ci->GetBadWordCount())
{
notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_EMPTY, ci->name.c_str());
- return MOD_CONT;
- }
- if (!word.empty() && strspn(word.c_str(), "1234567890,-") == word.length())
- {
- process_numlist(word.c_str(), NULL, badwords_list_callback, u, ci, &sent_header);
}
+ else if (!word.empty() && strspn(word.c_str(), "1234567890,-") == word.length())
+ (new BadwordsListCallback(u, ci, word.c_str()))->Process();
else
{
+ bool SentHeader = false;
+
for (unsigned i = 0; i < ci->GetBadWordCount(); i++)
{
- BadWord *badword = ci->GetBadWord(i);
+ BadWord *bw = ci->GetBadWord(i);
- if (!word.empty() && !Anope::Match(badword->word, word.c_str(), false))
+ if (!word.empty() && !Anope::Match(bw->word, word.c_str(), false))
continue;
- badwords_list(u, i, ci, &sent_header);
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str());
+ }
+
+ BadwordsListCallback::DoList(u, ci, i, bw);
}
+
+ if (!SentHeader)
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
}
- if (!sent_header)
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
return MOD_CONT;
}
@@ -83,7 +149,7 @@ class CommandBSBadwords : public Command
{
BadWord *bw = ci->GetBadWord(i);
- if (!bw->word.empty() && (Config.BSCaseSensitive && !stricmp(bw->word.c_str(), realword.c_str())
+ if (!bw->word.empty() && ((Config.BSCaseSensitive && !stricmp(bw->word.c_str(), realword.c_str()))
|| (!Config.BSCaseSensitive && bw->word == realword.c_str())))
{
notice_lang(Config.s_BotServ, u, BOT_BADWORDS_ALREADY_EXISTS, bw->word.c_str(), ci->name.c_str());
@@ -102,33 +168,7 @@ class CommandBSBadwords : public Command
{
/* Special case: is it a number/list? Only do search if it isn't. */
if (!word.empty() && isdigit(word[0]) && strspn(word.c_str(), "1234567890,-") == word.length())
- {
- int count, deleted, last = -1;
- deleted = process_numlist(word.c_str(), &count, badwords_del_callback, u, ci, &last);
-
- if (!deleted)
- {
- if (count == 1)
- {
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_SUCH_ENTRY, last, ci->name.c_str());
- }
- else
- {
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
- }
- }
- else if (deleted == 1)
- {
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_ONE, ci->name.c_str());
- }
- else
- {
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_SEVERAL, deleted, ci->name.c_str());
- }
-
- if (deleted)
- ci->CleanBadWords();
- }
+ (new BadwordsDelCallback(u, ci, word.c_str()))->Process();
else
{
unsigned i;
@@ -148,7 +188,7 @@ class CommandBSBadwords : public Command
return MOD_CONT;
}
- ci->EraseBadWord(badword);
+ ci->EraseBadWord(i);
notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED, badword->word.c_str(), ci->name.c_str());
}
@@ -219,6 +259,11 @@ class CommandBSBadwords : public Command
{
syntax_error(Config.s_BotServ, u, "BADWORDS", BOT_BADWORDS_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BADWORDS);
+ }
};
class BSBadwords : public Module
@@ -229,58 +274,8 @@ class BSBadwords : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSBadwords);
-
- ModuleManager::Attach(I_OnBotServHelp, this);
- }
- void OnBotServHelp(User *u)
- {
- notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BADWORDS);
+ this->AddCommand(BotServ, new CommandBSBadwords);
}
};
-int badwords_del_callback(User * u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *last = va_arg(args, int *);
-
- *last = num;
-
- if (num < 1 || num > ci->GetBadWordCount())
- return 0;
-
- ci->GetBadWord(num - 1)->InUse = false;
-
- return 1;
-}
-
-int badwords_list(User * u, int index, ChannelInfo * ci, int *sent_header)
-{
- BadWord *bw = ci->GetBadWord(index);
-
- if (!*sent_header)
- {
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str());
- *sent_header = 1;
- }
-
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_FORMAT, index + 1, bw->word.c_str(),
- ((bw->type == BW_SINGLE) ? "(SINGLE)" : ((bw->type == BW_START) ? "(START)"
- : ((bw->type == BW_END) ? "(END)" : "")))
- );
-
- return 1;
-}
-
-int badwords_list_callback(User * u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *sent_header = va_arg(args, int *);
-
- if (num < 1 || num > ci->GetBadWordCount())
- return 0;
-
- return badwords_list(u, num - 1, ci, sent_header);
-}
-
MODULE_INIT(BSBadwords)
diff --git a/src/core/bs_bot.c b/src/core/bs_bot.cpp
index 8abfecde8..1d3103e29 100644
--- a/src/core/bs_bot.c
+++ b/src/core/bs_bot.cpp
@@ -242,7 +242,8 @@ class CommandBSBot : public Command
the old nick. */
if (ircd->sqline)
{
- ircdproto->SendSQLineDel(bi->nick);
+ XLine x(bi->nick.c_str());
+ ircdproto->SendSQLineDel(&x);
}
/* We check whether user with this nick is online, and kill it if so */
@@ -251,9 +252,11 @@ class CommandBSBot : public Command
if (user)
ircdproto->SendQuit(bi, "Quit: Be right back");
- else {
+ else
+ {
ircdproto->SendChangeBotNick(bi, nick);
- ircdproto->SendSQLine(bi->nick, "Reserved for services");
+ XLine x(bi->nick.c_str(), "Reserved for services");
+ ircdproto->SendSQLine(&x);
}
if (bi->nick != nick)
@@ -273,7 +276,8 @@ class CommandBSBot : public Command
bi->uid = ts6_uid_retrieve();
}
ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, ircd->pseudoclient_mode, bi->uid);
- ircdproto->SendSQLine(bi->nick, "Reserved for services");
+ XLine x(bi->nick.c_str(), "Reserved for services");
+ ircdproto->SendSQLine(&x);
bi->RejoinAll();
}
@@ -309,7 +313,8 @@ class CommandBSBot : public Command
FOREACH_MOD(I_OnBotDelete, OnBotDelete(bi));
ircdproto->SendQuit(bi, "Quit: Help! I'm being deleted by %s!", u->nick.c_str());
- ircdproto->SendSQLineDel(bi->nick);
+ XLine x(bi->nick.c_str());
+ ircdproto->SendSQLineDel(&x);
delete bi;
notice_lang(Config.s_BotServ, u, BOT_BOT_DELETED, nick);
@@ -404,6 +409,11 @@ class CommandBSBot : public Command
{
syntax_error(Config.s_BotServ, u, "BOT", BOT_BOT_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BOT);
+ }
};
class BSBot : public Module
@@ -414,13 +424,7 @@ class BSBot : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSBot());
-
- ModuleManager::Attach(I_OnBotServHelp, this);
- }
- void OnBotServHelp(User *u)
- {
- notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BOT);
+ this->AddCommand(BotServ, new CommandBSBot());
}
};
diff --git a/src/core/bs_botlist.c b/src/core/bs_botlist.cpp
index 540cac30d..ebebf7a71 100644
--- a/src/core/bs_botlist.c
+++ b/src/core/bs_botlist.cpp
@@ -23,34 +23,39 @@ class CommandBSBotList : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- int i, count = 0;
- BotInfo *bi;
+ unsigned count = 0;
- if (!nbots) {
+ if (BotListByNick.empty())
+ {
notice_lang(Config.s_BotServ, u, BOT_BOTLIST_EMPTY);
return MOD_CONT;
}
- for (i = 0; i < 256; i++) {
- for (bi = botlists[i]; bi; bi = bi->next) {
- if (!(bi->HasFlag(BI_PRIVATE))) {
- if (!count)
- notice_lang(Config.s_BotServ, u, BOT_BOTLIST_HEADER);
- count++;
- u->SendMessage(Config.s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->user.c_str(), bi->host.c_str());
- }
+ for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it)
+ {
+ BotInfo *bi = it->second;
+
+ if (!bi->HasFlag(BI_PRIVATE))
+ {
+ if (!count)
+ notice_lang(Config.s_BotServ, u, BOT_BOTLIST_HEADER);
+ count++;
+ u->SendMessage(Config.s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->user.c_str(), bi->host.c_str());
}
}
- if (u->Account()->HasCommand("botserv/botlist") && count < nbots) {
+ if (u->Account()->HasCommand("botserv/botlist") && count < BotListByNick.size())
+ {
notice_lang(Config.s_BotServ, u, BOT_BOTLIST_PRIVATE_HEADER);
- for (i = 0; i < 256; i++) {
- for (bi = botlists[i]; bi; bi = bi->next) {
- if (bi->HasFlag(BI_PRIVATE)) {
- u->SendMessage(Config.s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->user.c_str(), bi->host.c_str());
- count++;
- }
+ for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it)
+ {
+ BotInfo *bi = it->second;
+
+ if (bi->HasFlag(BI_PRIVATE))
+ {
+ u->SendMessage(Config.s_BotServ, " %-15s (%s@%s)", bi->nick.c_str(), bi->user.c_str(), bi->host.c_str());
+ count++;
}
}
}
@@ -59,6 +64,7 @@ class CommandBSBotList : public Command
notice_lang(Config.s_BotServ, u, BOT_BOTLIST_EMPTY);
else
notice_lang(Config.s_BotServ, u, BOT_BOTLIST_FOOTER, count);
+
return MOD_CONT;
}
@@ -67,6 +73,11 @@ class CommandBSBotList : public Command
notice_help(Config.s_BotServ, u, BOT_HELP_BOTLIST);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BOTLIST);
+ }
};
class BSBotList : public Module
@@ -77,13 +88,7 @@ class BSBotList : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSBotList());
-
- ModuleManager::Attach(I_OnBotServHelp, this);
- }
- void OnBotServHelp(User *u)
- {
- notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_BOTLIST);
+ this->AddCommand(BotServ, new CommandBSBotList());
}
};
diff --git a/src/core/bs_help.c b/src/core/bs_help.cpp
index d28595986..80070c138 100644
--- a/src/core/bs_help.c
+++ b/src/core/bs_help.cpp
@@ -25,7 +25,7 @@ class CommandBSHelp : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- mod_help_cmd(Config.s_BotServ, u, BOTSERV, params[0].c_str());
+ mod_help_cmd(findbot(Config.s_BotServ), u, params[0].c_str());
return MOD_CONT;
}
@@ -33,7 +33,8 @@ class CommandBSHelp : public Command
{
// Abuse syntax error to display general list help.
notice_help(Config.s_BotServ, u, BOT_HELP);
- FOREACH_MOD(I_OnBotServHelp, OnBotServHelp(u));
+ for (CommandMap::const_iterator it = BotServ->Commands.begin(); it != BotServ->Commands.end(); ++it)
+ it->second->OnServHelp(u);
notice_help(Config.s_BotServ, u, BOT_HELP_FOOTER, Config.BSMinUsers);
}
};
@@ -46,7 +47,7 @@ class BSHelp : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSHelp());
+ this->AddCommand(BotServ, new CommandBSHelp());
}
};
diff --git a/src/core/bs_info.c b/src/core/bs_info.cpp
index 3ac3e9540..4e8cf042f 100644
--- a/src/core/bs_info.c
+++ b/src/core/bs_info.cpp
@@ -19,25 +19,24 @@ class CommandBSInfo : public Command
private:
void send_bot_channels(User * u, BotInfo * bi)
{
- int i;
- ChannelInfo *ci;
char buf[307], *end;
*buf = 0;
end = buf;
- for (i = 0; i < 256; i++) {
- for (ci = chanlists[i]; ci; ci = ci->next) {
- if (ci->bi == bi) {
- if (strlen(buf) + strlen(ci->name.c_str()) > 300) {
- u->SendMessage(Config.s_BotServ, "%s", buf);
- *buf = 0;
- end = buf;
- }
- end +=
- snprintf(end, sizeof(buf) - (end - buf), " %s ",
- ci->name.c_str());
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
+ {
+ ChannelInfo *ci = it->second;
+
+ if (ci->bi == bi)
+ {
+ if (strlen(buf) + strlen(ci->name.c_str()) > 300)
+ {
+ u->SendMessage(Config.s_BotServ, "%s", buf);
+ *buf = 0;
+ end = buf;
}
+ end += snprintf(end, sizeof(buf) - (end - buf), " %s ", ci->name.c_str());
}
}
@@ -79,7 +78,7 @@ class CommandBSInfo : public Command
}
else if ((ci = cs_findchan(query)))
{
- if (!IsFounder(u, ci) && !u->Account()->HasPriv("botserv/administration"))
+ if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("botserv/administration"))
{
notice_lang(Config.s_BotServ, u, ACCESS_DENIED);
return MOD_CONT;
@@ -241,6 +240,11 @@ class CommandBSInfo : public Command
{
syntax_error(Config.s_BotServ, u, "INFO", BOT_INFO_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_INFO);
+ }
};
class BSInfo : public Module
@@ -251,13 +255,7 @@ class BSInfo : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSInfo());
-
- ModuleManager::Attach(I_OnBotServHelp, this);
- }
- void OnBotServHelp(User *u)
- {
- notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_INFO);
+ this->AddCommand(BotServ, new CommandBSInfo());
}
};
diff --git a/src/core/bs_kick.c b/src/core/bs_kick.cpp
index 766239c73..6c8e020e4 100644
--- a/src/core/bs_kick.c
+++ b/src/core/bs_kick.cpp
@@ -325,6 +325,11 @@ class CommandBSKick : public Command
{
syntax_error(Config.s_BotServ, u, "KICK", BOT_KICK_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_KICK);
+ }
};
class BSKick : public Module
@@ -335,13 +340,7 @@ class BSKick : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSKick());
-
- ModuleManager::Attach(I_OnBotServHelp, this);
- }
- void OnBotServHelp(User *u)
- {
- notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_KICK);
+ this->AddCommand(BotServ, new CommandBSKick());
}
};
diff --git a/src/core/bs_say.c b/src/core/bs_say.cpp
index 9cd630eb8..a388a1ec9 100644
--- a/src/core/bs_say.c
+++ b/src/core/bs_say.cpp
@@ -71,6 +71,11 @@ class CommandBSSay : public Command
{
syntax_error(Config.s_BotServ, u, "SAY", BOT_SAY_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_SAY);
+ }
};
class BSSay : public Module
@@ -81,13 +86,7 @@ class BSSay : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSSay());
-
- ModuleManager::Attach(I_OnBotServHelp, this);
- }
- void OnBotServHelp(User *u)
- {
- notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_SAY);
+ this->AddCommand(BotServ, new CommandBSSay());
}
};
diff --git a/src/core/bs_set.c b/src/core/bs_set.cpp
index 0614651cc..a5fee9d4f 100644
--- a/src/core/bs_set.c
+++ b/src/core/bs_set.cpp
@@ -176,6 +176,11 @@ class CommandBSSet : public Command
{
syntax_error(Config.s_BotServ, u, "SET", BOT_SET_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_SET);
+ }
};
class BSSet : public Module
{
@@ -185,13 +190,7 @@ class BSSet : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSSet());
-
- ModuleManager::Attach(I_OnBotServHelp, this);
- }
- void OnBotServHelp(User *u)
- {
- notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_SET);
+ this->AddCommand(BotServ, new CommandBSSet());
}
};
diff --git a/src/core/bs_unassign.c b/src/core/bs_unassign.cpp
index e053f75d7..72e62a310 100644
--- a/src/core/bs_unassign.c
+++ b/src/core/bs_unassign.cpp
@@ -53,6 +53,11 @@ class CommandBSUnassign : public Command
{
syntax_error(Config.s_BotServ, u, "UNASSIGN", BOT_UNASSIGN_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_UNASSIGN);
+ }
};
class BSUnassign : public Module
@@ -63,13 +68,7 @@ class BSUnassign : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(BOTSERV, new CommandBSUnassign);
-
- ModuleManager::Attach(I_OnBotServHelp, this);
- }
- void OnBotServHelp(User *u)
- {
- notice_lang(Config.s_BotServ, u, BOT_HELP_CMD_UNASSIGN);
+ this->AddCommand(BotServ, new CommandBSUnassign);
}
};
diff --git a/src/core/cs_access.c b/src/core/cs_access.c
deleted file mode 100644
index e4e1d0e4b..000000000
--- a/src/core/cs_access.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-/*************************************************************************/
-
-#include "module.h"
-
-static int access_del(User * u, ChannelInfo *ci, ChanAccess * access, int *perm, int uacc)
-{
- if (!access->in_use)
- return 0;
- if (uacc <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
- {
- (*perm)++;
- return 0;
- }
- NickCore *nc = access->nc;
- access->nc = NULL;
- access->in_use = 0;
-
- FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, nc));
-
- return 1;
-}
-
-static int access_del_callback(User * u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *last = va_arg(args, int *);
- int *perm = va_arg(args, int *);
- int uacc = va_arg(args, int);
- if (num < 1 || num > ci->GetAccessCount())
- return 0;
- *last = num;
- return access_del(u, ci, ci->GetAccess(num - 1), perm, uacc);
-}
-
-
-static int access_list(User * u, int index, ChannelInfo * ci, int *sent_header)
-{
- ChanAccess *access = ci->GetAccess(index);
- const char *xop;
-
- if (!access->in_use)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
- *sent_header = 1;
- }
-
- if (ci->HasFlag(CI_XOP))
- {
- xop = get_xop_level(access->level);
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_XOP_FORMAT, index + 1, xop, access->nc->display);
- }
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_AXS_FORMAT, index + 1, access->level, access->nc->display);
- return 1;
-}
-
-static int access_list_callback(User * u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *sent_header = va_arg(args, int *);
- if (num < 1 || num > ci->GetAccessCount())
- return 0;
- return access_list(u, num - 1, ci, sent_header);
-}
-
-static int access_view(User *u, int index, ChannelInfo *ci, int *sent_header)
-{
- ChanAccess *access = ci->GetAccess(index);
- const char *xop;
- char timebuf[64];
- tm tm;
-
- if (!access || !access->in_use)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
- *sent_header = 1;
- }
-
- memset(&timebuf, 0, sizeof(timebuf));
- if (ci->c && u->Account() && nc_on_chan(ci->c, u->Account()))
- sprintf(timebuf, "Now");
- else if (access->last_seen == 0)
- sprintf(timebuf, "Never");
- else
- {
- tm = *localtime(&access->last_seen);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm);
- }
-
- if (ci->HasFlag(CI_XOP))
- {
- xop = get_xop_level(access->level);
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_XOP_FORMAT, index + 1, xop, access->nc->display, access->creator.c_str(), timebuf);
- }
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_AXS_FORMAT, index + 1, access->level, access->nc->display, access->creator.c_str(), timebuf);
-
- return 1;
-}
-
-static int access_view_callback(User *u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *sent_header = va_arg(args, int *);
- if (num < 1 || num > ci->GetAccessCount())
- return 0;
- return access_view(u, num - 1, ci, sent_header);
-}
-
-class CommandCSAccess : public Command
-{
- public:
- CommandCSAccess() : Command("ACCESS", 2, 4)
- {
- }
-
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
- {
- const char *chan = params[0].c_str();
- ci::string cmd = params[1];
- const char *nick = params.size() > 2 ? params[2].c_str() : NULL;
- const char *s = params.size() > 3 ? params[3].c_str() : NULL;
-
- ChannelInfo *ci = cs_findchan(chan);
- NickAlias *na = NULL;
- NickCore *nc;
- ChanAccess *access;
-
- unsigned i;
- int level = 0, ulev;
- bool is_list = cmd == "LIST" || cmd == "VIEW";
-
- /* If LIST, we don't *require* any parameters, but we can take any.
- * If DEL, we require a nick and no level.
- * Else (ADD), we require a level (which implies a nick). */
- if (is_list || cmd == "CLEAR" ? 0 : (cmd == "DEL" ? (!nick || s) : !s))
- this->OnSyntaxError(u, cmd);
- /* We still allow LIST in xOP mode, but not others */
- else if ((ci->HasFlag(CI_XOP)) && !is_list)
- {
- if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_XOP_HOP, Config.s_ChanServ);
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_XOP, Config.s_ChanServ);
- }
- else if ((
- (is_list && !check_access(u, ci, CA_ACCESS_LIST) && !u->Account()->HasCommand("chanserv/access/list"))
- ||
- (!is_list && !check_access(u, ci, CA_ACCESS_CHANGE) && !u->Account()->HasPriv("chanserv/access/modify"))
- ))
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else if (cmd == "ADD")
- {
- if (readonly)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DISABLED);
- return MOD_CONT;
- }
-
- level = atoi(s);
- ulev = get_access(u, ci);
-
- if (level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
- {
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- return MOD_CONT;
- }
-
- if (!level)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_NONZERO);
- return MOD_CONT;
- }
- else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
- return MOD_CONT;
- }
-
- na = findnick(nick);
- if (!na)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NICKS_ONLY);
- return MOD_CONT;
- }
- else if (na->HasFlag(NS_FORBIDDEN))
- {
- notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, nick);
- return MOD_CONT;
- }
-
- nc = na->nc;
- access = ci->GetAccess(nc);
- if (access)
- {
- /* Don't allow lowering from a level >= ulev */
- if (access->level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
- {
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- return MOD_CONT;
- }
- if (access->level == level)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_UNCHANGED, access->nc->display, chan, level);
- return MOD_CONT;
- }
- access->level = level;
-
- FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na, level));
-
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level "
- << access->level << " to " << na->nick << " (group " << nc->display << ") on channel " << ci->name;
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_CHANGED, nc->display, chan, level);
- return MOD_CONT;
- }
-
- if (ci->GetAccessCount() >= Config.CSAccessMax)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_REACHED_LIMIT, Config.CSAccessMax);
- return MOD_CONT;
- }
-
- std::string usernick = u->nick;
- ci->AddAccess(nc, level, usernick);
-
- FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, na, level));
-
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level "
- << level << " to " << na->nick << " (group " << nc->display << ") on channel " << ci->name;
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_ADDED, nc->display, ci->name.c_str(), level);
- }
- else if (cmd == "DEL")
- {
- int deleted;
- if (readonly)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DISABLED);
- return MOD_CONT;
- }
-
- if (!ci->GetAccessCount())
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan);
- return MOD_CONT;
- }
-
- /* Special case: is it a number/list? Only do search if it isn't. */
- if (isdigit(*nick) && strspn(nick, "1234567890,-") == strlen(nick))
- {
- int count, last = -1, perm = 0;
- deleted = process_numlist(nick, &count, access_del_callback, u, ci, &last, &perm, get_access(u, ci));
- if (!deleted)
- {
- if (perm)
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else if (count == 1)
- {
- last = atoi(nick);
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_SUCH_ENTRY, last, ci->name.c_str());
- }
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
- }
- else
- {
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci)
- << ") deleted access of user" << (deleted == 1 ? " " : "s ") << nick << " on " << chan;
- if (deleted == 1)
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_ONE, ci->name.c_str());
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_SEVERAL, deleted, ci->name.c_str());
- }
- }
- else
- {
- na = findnick(nick);
- if (!na)
- {
- notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, nick);
- return MOD_CONT;
- }
- nc = na->nc;
- access = ci->GetAccess(nc);
- if (!access)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NOT_FOUND, nick, chan);
- return MOD_CONT;
- }
- if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
- {
- deleted = 0;
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- }
- else
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED, access->nc->display, ci->name.c_str());
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci)
- << ") deleted access of " << na->nick << " (group " << access->nc->display << ") on " << chan;
- access->nc = NULL;
- access->in_use = 0;
- deleted = 1;
- }
- }
-
- if (deleted)
- {
- /* We'll free the access entries no longer in use... */
- ci->CleanAccess();
-
- /* Only call this event if na exists (if they deleted by user, not numlist).
- * The callback for deleting by numlist will call this event otherwise - Adam */
- if (na)
- {
- FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc));
- }
- }
- }
- else if (cmd == "LIST")
- {
- int sent_header = 0;
-
- if (!ci->GetAccessCount())
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan);
- return MOD_CONT;
- }
- if (nick && strspn(nick, "1234567890,-") == strlen(nick))
- process_numlist(nick, NULL, access_list_callback, u, ci, &sent_header);
- else
- {
- for (i = 0; i < ci->GetAccessCount(); i++)
- {
- access = ci->GetAccess(i);
- if (nick && access->nc && !Anope::Match(access->nc->display, nick, false))
- continue;
- access_list(u, i, ci, &sent_header);
- }
- }
- if (!sent_header)
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, chan);
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
- }
- else if (cmd == "VIEW")
- {
- int sent_header = 0;
-
- if (!ci->GetAccessCount())
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan);
- return MOD_CONT;
- }
- if (nick && strspn(nick, "1234567890,-") == strlen(nick))
- process_numlist(nick, NULL, access_view_callback, u, ci, &sent_header);
- else
- {
- for (i = 0; i < ci->GetAccessCount(); ++i)
- {
- access = ci->GetAccess(i);
- if (nick && access->nc && !Anope::Match(access->nc->display, nick, false))
- continue;
- access_view(u, i, ci, &sent_header);
- }
- }
- if (!sent_header)
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, chan);
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
- }
- else if (cmd == "CLEAR")
- {
- if (readonly)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DISABLED);
- return MOD_CONT;
- }
-
- if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify"))
- {
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- return MOD_CONT;
- }
-
- ci->ClearAccess();
-
- FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u));
-
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_CLEAR, ci->name.c_str());
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << " cleared access list on " << chan;
- }
- else
- this->OnSyntaxError(u, "");
- return MOD_CONT;
- }
-
- bool OnHelp(User *u, const ci::string &subcommand)
- {
- notice_help(Config.s_ChanServ, u, CHAN_HELP_ACCESS);
- notice_help(Config.s_ChanServ, u, CHAN_HELP_ACCESS_LEVELS);
- return true;
- }
-
- void OnSyntaxError(User *u, const ci::string &subcommand)
- {
- syntax_error(Config.s_ChanServ, u, "ACCESS", CHAN_ACCESS_SYNTAX);
- }
-};
-
-
-class CommandCSLevels : public Command
-{
- public:
- CommandCSLevels() : Command("LEVELS", 2, 4)
- {
- }
-
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
- {
- const char *chan = params[0].c_str();
- ci::string cmd = params[1];
- const char *what = params.size() > 2 ? params[2].c_str() : NULL;
- const char *s = params.size() > 3 ? params[3].c_str() : NULL;
- char *error;
-
- ChannelInfo *ci = cs_findchan(chan);
- int level;
- int i;
-
- /* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only
- * one; else, we want none.
- */
- if (cmd == "SET" ? !s : (cmd.substr(0, 3) == "DIS" ? (!what || s) : !!what))
- this->OnSyntaxError(u, cmd);
- else if (ci->HasFlag(CI_XOP))
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_XOP);
- else if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify"))
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else if (cmd == "SET") {
- level = strtol(s, &error, 10);
-
- if (!stricmp(s, "FOUNDER"))
- {
- level = ACCESS_FOUNDER;
- *error = '\0';
- }
-
- if (*error != '\0') {
- this->OnSyntaxError(u, "SET");
- return MOD_CONT;
- }
-
- if (level <= ACCESS_INVALID || level > ACCESS_FOUNDER) {
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_RANGE,
- ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
- return MOD_CONT;
- }
-
- for (i = 0; levelinfo[i].what >= 0; i++) {
- if (stricmp(levelinfo[i].name, what) == 0) {
- ci->levels[levelinfo[i].what] = level;
- FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, level));
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " set level " << levelinfo[i].name
- << " on channel " << ci->name << " to " << level;
- if (level == ACCESS_FOUNDER)
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_CHANGED_FOUNDER, levelinfo[i].name, ci->name.c_str());
- else
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_CHANGED,
- levelinfo[i].name, ci->name.c_str(), level);
- return MOD_CONT;
- }
- }
-
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what, Config.s_ChanServ);
-
- } else if (cmd == "DIS" || cmd == "DISABLE") {
- for (i = 0; levelinfo[i].what >= 0; i++) {
- if (stricmp(levelinfo[i].name, what) == 0) {
- ci->levels[levelinfo[i].what] = ACCESS_INVALID;
- FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, levelinfo[i].what));
-
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled level " << levelinfo[i].name
- << " on channel " << ci->name;
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_DISABLED,
- levelinfo[i].name, chan);
- return MOD_CONT;
- }
- }
-
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what, Config.s_ChanServ);
- } else if (cmd == "LIST") {
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_HEADER, chan);
-
- if (!levelinfo_maxwidth) {
- for (i = 0; levelinfo[i].what >= 0; i++) {
- int len = strlen(levelinfo[i].name);
- if (len > levelinfo_maxwidth)
- levelinfo_maxwidth = len;
- }
- }
-
- for (i = 0; levelinfo[i].what >= 0; i++) {
- int j = ci->levels[levelinfo[i].what];
-
- if (j == ACCESS_INVALID) {
- j = levelinfo[i].what;
-
- if (j == CA_AUTOOP || j == CA_AUTODEOP || j == CA_AUTOVOICE
- || j == CA_NOJOIN) {
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_DISABLED,
- levelinfo_maxwidth, levelinfo[i].name);
- } else {
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_DISABLED,
- levelinfo_maxwidth, levelinfo[i].name);
- }
- } else if (j == ACCESS_FOUNDER) {
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_FOUNDER,
- levelinfo_maxwidth, levelinfo[i].name);
- } else {
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_NORMAL,
- levelinfo_maxwidth, levelinfo[i].name, j);
- }
- }
-
- } else if (cmd == "RESET") {
- reset_levels(ci);
- FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0));
-
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " reset levels definitions on channel " << ci->name;
- notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_RESET, chan);
- } else {
- this->OnSyntaxError(u, "");
- }
- return MOD_CONT;
- }
-
- bool OnHelp(User *u, const ci::string &subcommand)
- {
- notice_help(Config.s_ChanServ, u, CHAN_HELP_LEVELS);
- return true;
- }
-
- void OnSyntaxError(User *u, const ci::string &subcommand)
- {
- syntax_error(Config.s_ChanServ, u, "LEVELS", CHAN_LEVELS_SYNTAX);
- }
-};
-
-
-class CSAccess : public Module
-{
- public:
- CSAccess(const std::string &modname, const std::string &creator) : Module(modname, creator)
- {
- this->SetAuthor("Anope");
- this->SetVersion(VERSION_STRING);
- this->SetType(CORE);
-
- this->AddCommand(CHANSERV, new CommandCSAccess());
- this->AddCommand(CHANSERV, new CommandCSLevels());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_ACCESS);
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_LEVELS);
- }
-};
-
-
-MODULE_INIT(CSAccess)
diff --git a/src/core/cs_access.cpp b/src/core/cs_access.cpp
new file mode 100644
index 000000000..49d253d12
--- /dev/null
+++ b/src/core/cs_access.cpp
@@ -0,0 +1,664 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class AccessListCallback : public NumberList
+{
+ protected:
+ User *u;
+ ChannelInfo *ci;
+ bool SentHeader;
+ public:
+ AccessListCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : NumberList(numlist, false), u(_u), ci(_ci), SentHeader(false)
+ {
+ }
+
+ ~AccessListCallback()
+ {
+ if (SentHeader)
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
+ }
+
+ virtual void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAccessCount())
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
+ }
+
+ DoList(u, ci, Number - 1, ci->GetAccess(Number - 1));
+ }
+
+ static void DoList(User *u, ChannelInfo *ci, unsigned Number, ChanAccess *access)
+ {
+ if (ci->HasFlag(CI_XOP))
+ {
+ const char *xop = get_xop_level(access->level);
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_XOP_FORMAT, Number + 1, xop, access->nc->display);
+ }
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_AXS_FORMAT, Number + 1, access->level, access->nc->display);
+ }
+};
+
+class AccessViewCallback : public AccessListCallback
+{
+ public:
+ AccessViewCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : AccessListCallback(_u, _ci, numlist)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAccessCount())
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
+ }
+
+ DoList(u, ci, Number - 1, ci->GetAccess(Number - 1));
+ }
+
+ static void DoList(User *u, ChannelInfo *ci, unsigned Number, ChanAccess *access)
+ {
+ char timebuf[64];
+ struct tm tm;
+
+ memset(&timebuf, 0, sizeof(timebuf));
+ if (ci->c && u->Account() && nc_on_chan(ci->c, u->Account()))
+ snprintf(timebuf, sizeof(timebuf), "Now");
+ else if (access->last_seen == 0)
+ snprintf(timebuf, sizeof(timebuf), "Never");
+ else
+ {
+ tm = *localtime(&access->last_seen);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm);
+ }
+
+ if (ci->HasFlag(CI_XOP))
+ {
+ const char *xop = get_xop_level(access->level);
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_XOP_FORMAT, Number + 1, xop, access->nc->display, access->creator.c_str(), timebuf);
+ }
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, access->level, access->nc->display, access->creator.c_str(), timebuf);
+ }
+};
+
+class AccessDelCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ unsigned Deleted;
+ std::string Nicks;
+ bool Denied;
+ public:
+ AccessDelCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : NumberList(numlist, true), u(_u), ci(_ci), Deleted(0), Denied(false)
+ {
+ }
+
+ ~AccessDelCallback()
+ {
+ if (Denied && !Deleted)
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ else if (!Deleted)
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
+ else
+ {
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of user" << (Deleted == 1 ? " " : "s ") << Nicks << " on " << ci->name;
+
+ if (Deleted == 1)
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_ONE, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_SEVERAL, Deleted, ci->name.c_str());
+ }
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAccessCount())
+ return;
+
+ ChanAccess *access = ci->GetAccess(Number - 1);
+
+ if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
+ {
+ Denied = true;
+ return;
+ }
+
+ ++Deleted;
+ if (!Nicks.empty())
+ Nicks += ", " + std::string(access->nc->display);
+ else
+ Nicks = access->nc->display;
+
+ FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access->nc));
+
+ ci->EraseAccess(Number - 1);
+ }
+};
+
+class CommandCSAccess : public Command
+{
+ CommandReturn DoAdd(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
+ {
+ const ci::string nick = params[2];
+ int level = atoi(params[3].c_str());
+ int ulev = get_access(u, ci);
+
+ if (level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+
+ if (!level)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_NONZERO);
+ return MOD_CONT;
+ }
+ else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
+ return MOD_CONT;
+ }
+
+ NickAlias *na = findnick(nick.c_str());
+ if (!na)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NICKS_ONLY);
+ return MOD_CONT;
+ }
+ else if (na->HasFlag(NS_FORBIDDEN))
+ {
+ notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, nick.c_str());
+ return MOD_CONT;
+ }
+
+ NickCore *nc = na->nc;
+ ChanAccess *access = ci->GetAccess(nc);
+ if (access)
+ {
+ /* Don't allow lowering from a level >= ulev */
+ if (access->level >= ulev && !u->Account()->HasPriv("chanserv/access/modify"))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+ if (access->level == level)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_UNCHANGED, access->nc->display, ci->name.c_str(), level);
+ return MOD_CONT;
+ }
+ access->level = level;
+
+ FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level));
+
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level " << access->level << " to " << na->nick << " (group " << nc->display << ") on channel " << ci->name;
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LEVEL_CHANGED, nc->display, ci->name.c_str(), level);
+ return MOD_CONT;
+ }
+
+ if (ci->GetAccessCount() >= Config.CSAccessMax)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_REACHED_LIMIT, Config.CSAccessMax);
+ return MOD_CONT;
+ }
+
+ ci->AddAccess(nc, level, u->nick);
+
+ FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level));
+
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level " << level << " to " << na->nick << " (group " << nc->display << ") on channel " <<
+ci->name;
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_ADDED, nc->display, ci->name.c_str(), level);
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoDel(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
+ {
+ const ci::string nick = params[2];
+
+ if (!ci->GetAccessCount())
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str());
+ else if (isdigit(*nick.c_str()) && strspn(nick.c_str(), "1234567890,-") == nick.length())
+ (new AccessDelCallback(u, ci, nick.c_str()))->Process();
+ else
+ {
+ NickAlias *na = findnick(nick);
+ if (!na)
+ {
+ notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, nick.c_str());
+ return MOD_CONT;
+ }
+
+ NickCore *nc = na->nc;
+
+ unsigned i;
+ ChanAccess *access = NULL;
+ for (i = 0; i < ci->GetAccessCount(); ++i)
+ {
+ access = ci->GetAccess(i);
+
+ if (access->nc == nc)
+ break;
+ }
+
+ if (i == ci->GetAccessCount())
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NOT_FOUND, nick.c_str(), ci->name.c_str());
+ }
+ else if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ }
+ else
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED, access->nc->display, ci->name.c_str());
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of " << na->nick << " (group " << access->nc->display << ") on " << ci->name;
+ FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc));
+
+ ci->EraseAccess(i);
+ }
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoList(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
+ {
+ const ci::string nick = params.size() > 2 ? params[2] : "";
+
+ if (!ci->GetAccessCount())
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str());
+ else if (!nick.empty() && strspn(nick.c_str(), "1234567890,-") == nick.length())
+ (new AccessListCallback(u, ci, nick.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < ci->GetAccessCount(); i++)
+ {
+ ChanAccess *access = ci->GetAccess(i);
+
+ if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick))
+ continue;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
+ }
+
+ AccessListCallback::DoList(u, ci, i, access);
+ }
+
+ if (SentHeader)
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoView(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
+ {
+ const ci::string nick = params.size() > 2 ? params[2] : "";
+
+ if (!ci->GetAccessCount())
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, ci->name.c_str());
+ else if (!nick.empty() && strspn(nick.c_str(), "1234567890,-") == nick.length())
+ (new AccessViewCallback(u, ci, nick.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
+ {
+ ChanAccess *access = ci->GetAccess(i);
+
+ if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick))
+ continue;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
+ }
+
+ AccessViewCallback::DoList(u, ci, i, access);
+ }
+
+ if (SentHeader)
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoClear(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
+ {
+ if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify"))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ }
+ else
+ {
+ ci->ClearAccess();
+
+ FOREACH_MOD(I_OnAccessClear, OnAccessClear(ci, u));
+
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_CLEAR, ci->name.c_str());
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << " cleared access list on " << ci->name;
+ }
+
+ return MOD_CONT;
+ }
+
+ public:
+ CommandCSAccess() : Command("ACCESS", 2, 4)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ const char *chan = params[0].c_str();
+ ci::string cmd = params[1];
+ const char *nick = params.size() > 2 ? params[2].c_str() : NULL;
+ const char *s = params.size() > 3 ? params[3].c_str() : NULL;
+
+ ChannelInfo *ci = cs_findchan(chan);
+
+ bool is_list = cmd == "LIST" || cmd == "VIEW";
+
+ /* If LIST, we don't *require* any parameters, but we can take any.
+ * If DEL, we require a nick and no level.
+ * Else (ADD), we require a level (which implies a nick). */
+ if (is_list || cmd == "CLEAR" ? 0 : (cmd == "DEL" ? (!nick || s) : !s))
+ this->OnSyntaxError(u, cmd);
+ /* We still allow LIST in xOP mode, but not others */
+ else if ((ci->HasFlag(CI_XOP)) && !is_list)
+ {
+ if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_XOP_HOP, Config.s_ChanServ);
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_XOP, Config.s_ChanServ);
+ }
+ else if ((
+ (is_list && !check_access(u, ci, CA_ACCESS_LIST) && !u->Account()->HasCommand("chanserv/access/list"))
+ ||
+ (!is_list && !check_access(u, ci, CA_ACCESS_CHANGE) && !u->Account()->HasPriv("chanserv/access/modify"))
+ ))
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ else if (readonly && (cmd == "ADD" || cmd == "DEL" || cmd == "CLEAR"))
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DISABLED);
+ }
+ else if (cmd == "ADD")
+ {
+ this->DoAdd(u, ci, params);
+ }
+ else if (cmd == "DEL")
+ {
+ this->DoDel(u, ci, params);
+ }
+ else if (cmd == "LIST")
+ {
+ this->DoList(u, ci, params);
+ }
+ else if (cmd == "VIEW")
+ {
+ this->DoView(u, ci, params);
+ }
+ else if (cmd == "CLEAR")
+ {
+ this->DoClear(u, ci, params);
+ }
+ else
+ {
+ this->OnSyntaxError(u, "");
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_ACCESS);
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_ACCESS_LEVELS);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_ChanServ, u, "ACCESS", CHAN_ACCESS_SYNTAX);
+ }
+};
+
+
+class CommandCSLevels : public Command
+{
+ CommandReturn DoSet(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
+ {
+ const ci::string what = params[2];
+ const ci::string lev = params[3];
+
+ char *error;
+ int level = strtol(lev.c_str(), &error, 10);
+
+ if (lev == "FONDER")
+ {
+ level = ACCESS_FOUNDER;
+ *error = '\0';
+ }
+
+ if (*error != '\0')
+ {
+ this->OnSyntaxError(u, "SET");
+ }
+ else if (level <= ACCESS_INVALID || level > ACCESS_FOUNDER)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
+ }
+ else
+ {
+ for (int i = 0; levelinfo[i].what >= 0; i++)
+ {
+ if (levelinfo[i].name == what)
+ {
+ ci->levels[levelinfo[i].what] = level;
+ FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, level));
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " set level " << levelinfo[i].name << " on channel " << ci->name << " to " << level;
+ if (level == ACCESS_FOUNDER)
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_CHANGED_FOUNDER, levelinfo[i].name, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_CHANGED, levelinfo[i].name, ci->name.c_str(), level);
+ return MOD_CONT;
+ }
+ }
+ }
+
+
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what.c_str(), Config.s_ChanServ);
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoDisable(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
+ {
+ const ci::string what = params[2];
+
+ /* Don't allow disabling of the founder level. It would be hard to change it back if you dont have access to use this command */
+ if (what != "FOUNDER")
+ {
+ for (int i = 0; levelinfo[i].what >= 0; i++)
+ {
+ if (levelinfo[i].name == what)
+ {
+ ci->levels[levelinfo[i].what] = ACCESS_INVALID;
+ FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, i, levelinfo[i].what));
+
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled level " << levelinfo[i].name << " on channel " << ci->name;
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_DISABLED, levelinfo[i].name, ci->name.c_str());
+ return MOD_CONT;
+ }
+ }
+ }
+
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what.c_str(), Config.s_ChanServ);
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoList(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_HEADER, ci->name.c_str());
+
+ if (!levelinfo_maxwidth)
+ {
+ for (int i = 0; levelinfo[i].what >= 0; i++) {
+ int len = strlen(levelinfo[i].name);
+ if (len > levelinfo_maxwidth)
+ levelinfo_maxwidth = len;
+ }
+ }
+
+ for (int i = 0; levelinfo[i].what >= 0; i++) {
+ int j = ci->levels[levelinfo[i].what];
+
+ if (j == ACCESS_INVALID) {
+ j = levelinfo[i].what;
+
+ if (j == CA_AUTOOP || j == CA_AUTODEOP || j == CA_AUTOVOICE
+ || j == CA_NOJOIN) {
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_DISABLED, levelinfo_maxwidth, levelinfo[i].name);
+ } else {
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_DISABLED, levelinfo_maxwidth, levelinfo[i].name);
+ }
+ } else if (j == ACCESS_FOUNDER) {
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_FOUNDER, levelinfo_maxwidth, levelinfo[i].name);
+ } else {
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_LIST_NORMAL, levelinfo_maxwidth, levelinfo[i].name, j);
+ }
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoReset(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
+ {
+ reset_levels(ci);
+ FOREACH_MOD(I_OnLevelChange, OnLevelChange(u, ci, -1, 0));
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " reset levels definitions on channel " << ci->name;
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_RESET, ci->name.c_str());
+ return MOD_CONT;
+ }
+
+ public:
+ CommandCSLevels() : Command("LEVELS", 2, 4)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ const char *chan = params[0].c_str();
+ ci::string cmd = params[1];
+ const char *what = params.size() > 2 ? params[2].c_str() : NULL;
+ const char *s = params.size() > 3 ? params[3].c_str() : NULL;
+
+ ChannelInfo *ci = cs_findchan(chan);
+
+ /* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only
+ * one; else, we want none.
+ */
+ if (cmd == "SET" ? !s : (cmd.substr(0, 3) == "DIS" ? (!what || s) : !!what))
+ this->OnSyntaxError(u, cmd);
+ else if (ci->HasFlag(CI_XOP))
+ notice_lang(Config.s_ChanServ, u, CHAN_LEVELS_XOP);
+ else if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify"))
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ else if (cmd == "SET")
+ {
+ this->DoSet(u, ci, params);
+ }
+ else if (cmd == "DIS" || cmd == "DISABLE")
+ {
+ this->DoDisable(u, ci, params);
+ }
+ else if (cmd == "LIST")
+ {
+ this->DoList(u, ci, params);
+ }
+ else if (cmd == "RESET")
+ {
+ this->DoReset(u, ci, params);
+ }
+ else
+ {
+ this->OnSyntaxError(u, "");
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_LEVELS);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_ChanServ, u, "LEVELS", CHAN_LEVELS_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_ACCESS);
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_LEVELS);
+ }
+};
+
+
+class CSAccess : public Module
+{
+ public:
+ CSAccess(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion(VERSION_STRING);
+ this->SetType(CORE);
+
+ this->AddCommand(ChanServ, new CommandCSAccess());
+ this->AddCommand(ChanServ, new CommandCSLevels());
+ }
+};
+
+
+MODULE_INIT(CSAccess)
diff --git a/src/core/cs_akick.c b/src/core/cs_akick.cpp
index ac17ef504..e2ad9de99 100644
--- a/src/core/cs_akick.c
+++ b/src/core/cs_akick.cpp
@@ -45,103 +45,125 @@ static void split_usermask(const char *mask, const char **nick, const char **use
delete [] mask2;
}
-int akick_del_callback(User * u, int num, va_list args)
+class AkickListCallback : public NumberList
{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *last = va_arg(args, int *);
+ protected:
+ User *u;
+ ChannelInfo *ci;
+ bool SentHeader;
+ public:
+ AkickListCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : NumberList(numlist, false), u(_u), ci(_ci), SentHeader(false)
+ {
+ }
- *last = num;
+ ~AkickListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str());
+ }
- if (num < 1 || num > ci->GetAkickCount())
- return 0;
+ virtual void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAkickCount())
+ return;
- ci->GetAkick(num - 1)->InUse = false;
- return 1;
-}
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
+ }
+ DoList(u, ci, Number - 1, ci->GetAkick(Number - 1));
+ }
-int akick_list(User * u, int index, ChannelInfo * ci, int *sent_header)
-{
- AutoKick *akick = ci->GetAkick(index);
+ static void DoList(User *u, ChannelInfo *ci, unsigned index, AutoKick *akick)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_FORMAT, index + 1,
+ ((akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str()),
+ (!akick->reason.empty() ? akick->reason.c_str() : getstring(u, NO_REASON)));
+ }
+};
- if (!akick->InUse)
- return 0;
- if (!*sent_header) {
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
- *sent_header = 1;
+class AkickViewCallback : public AkickListCallback
+{
+ public:
+ AkickViewCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : AkickListCallback(u, ci, numlist)
+ {
}
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_FORMAT, index + 1,
- ((akick->HasFlag(AK_ISNICK)) ? akick->nc->
- display : akick->mask.c_str()),
- (!akick->reason.empty() ? akick->
- reason.c_str() : getstring(u, NO_REASON)));
- return 1;
-}
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAkickCount())
+ return;
-int akick_list_callback(User * u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *sent_header = va_arg(args, int *);
- if (num < 1 || num > ci->GetAkickCount())
- return 0;
- return akick_list(u, num - 1, ci, sent_header);
-}
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
+ }
-int akick_view(User * u, int index, ChannelInfo * ci, int *sent_header)
-{
- AutoKick *akick = ci->GetAkick(index);
- char timebuf[64];
- struct tm tm;
-
- if (!akick->InUse)
- return 0;
- if (!*sent_header) {
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
- *sent_header = 1;
+ DoList(u, ci, Number - 1, ci->GetAkick(Number - 1));
}
- if (akick->addtime) {
- tm = *localtime(&akick->addtime);
- strftime_lang(timebuf, sizeof(timebuf), u,
- STRFTIME_SHORT_DATE_FORMAT, &tm);
- } else {
- snprintf(timebuf, sizeof(timebuf), "%s", getstring(u, UNKNOWN));
+ static void DoList(User *u, ChannelInfo *ci, unsigned index, AutoKick *akick)
+ {
+ char timebuf[64];
+ struct tm tm;
+
+ memset(&timebuf, 0, sizeof(timebuf));
+
+ if (akick->addtime)
+ {
+ tm = *localtime(&akick->addtime);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ }
+ else
+ snprintf(timebuf, sizeof(timebuf), "%s", getstring(u, UNKNOWN));
+
+ notice_lang(Config.s_ChanServ, u, (akick->HasFlag(AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK : CHAN_AKICK_VIEW_FORMAT), index + 1,
+ ((akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str()),
+ !akick->creator.empty() ? akick->creator.c_str() : getstring(u, UNKNOWN), timebuf,
+ (!akick->reason.empty() ? akick->reason.c_str() : getstring(u, NO_REASON)));
+
+ if (akick->last_used)
+ {
+ char last_used[64];
+ tm = *localtime(&akick->last_used);
+ strftime_lang(last_used, sizeof(last_used), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LAST_USED, last_used);
+ }
}
+};
- notice_lang(Config.s_ChanServ, u, (akick->HasFlag(AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK : CHAN_AKICK_VIEW_FORMAT), index + 1,
- ((akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str()),
- !akick->creator.empty() ? akick->creator.c_str() : getstring(u, UNKNOWN), timebuf,
- (!akick->reason.empty() ? akick->reason.c_str() : getstring(u, NO_REASON)));
- if (akick->last_used)
+class AkickDelCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ unsigned Deleted;
+ public:
+ AkickDelCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list, true), u(_u), ci(_ci), Deleted(0)
{
- char last_used[64];
- tm = *localtime(&akick->last_used);
- strftime_lang(last_used, sizeof(last_used), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LAST_USED, last_used);
}
- return 1;
-}
-int akick_view_callback(User * u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *sent_header = va_arg(args, int *);
- if (num < 1 || num > ci->GetAkickCount())
- return 0;
- return akick_view(u, num - 1, ci, sent_header);
-}
+ ~AkickDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str());
+ else if (Deleted == 1)
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_ONE, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_SEVERAL, Deleted, ci->name.c_str());
+ }
-int get_access_nc(NickCore *nc, ChannelInfo *ci)
-{
- ChanAccess *access;
- if (!ci || !nc)
- return 0;
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAkickCount())
+ return;
- if ((access = ci->GetAccess(nc)))
- return access->level;
- return 0;
-}
+ ++Deleted;
+ ci->EraseAkick(Number - 1);
+ }
+};
class CommandCSAKick : public Command
{
@@ -149,10 +171,9 @@ class CommandCSAKick : public Command
{
ci::string mask = params[2];
ci::string reason = params.size() > 3 ? params[3] : "";
- NickAlias *na = findnick(mask.c_str());
+ NickAlias *na = findnick(mask);
NickCore *nc = NULL;
AutoKick *akick;
- int i;
if (!na)
{
@@ -189,7 +210,7 @@ class CommandCSAKick : public Command
* or whether the mask matches a user with higher/equal access - Viper */
if ((ci->HasFlag(CI_PEACE)) && nc)
{
- if ((nc == ci->founder) || (get_access_nc(nc, ci) >= get_access(u, ci)))
+ if ((nc == ci->founder) || (get_access_level(ci, nc) >= get_access(u, ci)))
{
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
return;
@@ -197,42 +218,40 @@ class CommandCSAKick : public Command
}
else if ((ci->HasFlag(CI_PEACE)))
{
- char buf[BUFSIZE];
/* Match against all currently online users with equal or
* higher access. - Viper */
- for (i = 0; i < 1024; i++)
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
{
- for (User *u2 = userlist[i]; u2; u2 = u2->next)
+ User *u2 = it->second;
+
+ if (check_access(u2, ci, CA_FOUNDER) || (get_access(u2, ci) >= get_access(u, ci)))
{
- if (IsFounder(u2, ci) || (get_access(u2, ci) >= get_access(u, ci)))
+ if (match_usermask(mask.c_str(), u2))
{
- if (match_usermask(mask.c_str(), u2))
- {
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- return;
- }
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return;
}
}
- }
-
+ }
- /* Match against the lastusermask of all nickalias's with equal
- * or higher access. - Viper */
- for (i = 0; i < 1024; i++)
+ /* Match against the lastusermask of all nickalias's with equal
+ * or higher access. - Viper */
+ for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it)
{
- for (NickAlias *na2 = nalists[i]; na2; na2 = na2->next)
+ NickAlias *na2 = it->second;
+
+ if (na2->HasFlag(NS_FORBIDDEN))
+ continue;
+
+ if (na2->nc && ((na2->nc == ci->founder) || (get_access_level(ci, na2->nc) >= get_access(u, ci))))
{
- if (na2->HasFlag(NS_FORBIDDEN))
- continue;
+ char buf[BUFSIZE];
- if (na2->nc && ((na2->nc == ci->founder) || (get_access_nc(na2->nc, ci) >= get_access(u, ci))))
+ snprintf(buf, BUFSIZE, "%s!%s", na2->nick, na2->last_usermask);
+ if (Anope::Match(buf, mask.c_str(), false))
{
- snprintf(buf, BUFSIZE, "%s!%s", na2->nick, na2->last_usermask);
- if (Anope::Match(buf, mask.c_str(), false))
- {
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- return;
- }
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return;
}
}
}
@@ -241,8 +260,6 @@ class CommandCSAKick : public Command
for (unsigned j = 0; j < ci->GetAkickCount(); ++j)
{
akick = ci->GetAkick(j);
- if (!akick->InUse)
- continue;
if ((akick->HasFlag(AK_ISNICK)) ? akick->nc == nc : akick->mask == mask)
{
notice_lang(Config.s_ChanServ, u, CHAN_AKICK_ALREADY_EXISTS, (akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str(), ci->name.c_str());
@@ -262,6 +279,8 @@ class CommandCSAKick : public Command
else
akick = ci->AddAkick(u->nick, mask.c_str(), !reason.empty() ? reason.c_str() : "");
+ FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(u, ci, akick));
+
notice_lang(Config.s_ChanServ, u, CHAN_AKICK_ADDED, mask.c_str(), ci->name.c_str());
this->DoEnforce(u, ci, params);
@@ -281,14 +300,14 @@ class CommandCSAKick : public Command
return;
}
- na = findnick(mask.c_str());
+ na = findnick(mask);
nc = (na ? na->nc : NULL);
for (i = 0; i < ci->GetAkickCount(); ++i)
{
akick = ci->GetAkick(i);
- if (!akick->InUse || akick->HasFlag(AK_ISNICK))
+ if (akick->HasFlag(AK_ISNICK))
continue;
if (akick->mask == mask)
break;
@@ -321,14 +340,14 @@ class CommandCSAKick : public Command
return;
}
- na = findnick(mask.c_str());
+ na = findnick(mask);
nc = (na ? na->nc : NULL);
for (i = 0; i < ci->GetAkickCount(); ++i)
{
akick = ci->GetAkick(i);
- if (!akick->InUse || akick->HasFlag(AK_ISNICK))
+ if (akick->HasFlag(AK_ISNICK))
continue;
if (akick->mask == mask)
break;
@@ -357,37 +376,17 @@ class CommandCSAKick : public Command
}
/* Special case: is it a number/list? Only do search if it isn't. */
- if (isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == strlen(mask.c_str()))
- {
- int last = -1, deleted, count;
-
- deleted = process_numlist(mask.c_str(), &count, akick_del_callback, u, ci, &last);
-
- if (!deleted)
- {
- if (count == 1)
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_SUCH_ENTRY, last, ci->name.c_str());
- else
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str());
- }
- else if (deleted == 1)
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_ONE, ci->name.c_str());
- else
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_SEVERAL, deleted, ci->name.c_str());
- if (deleted)
- ci->CleanAkick();
- }
+ if (isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new AkickDelCallback(u, ci, mask.c_str()))->Process();
else
{
- NickAlias *na = findnick(mask.c_str());
+ NickAlias *na = findnick(mask);
NickCore *nc = (na ? na->nc : NULL);
for (i = 0; i < ci->GetAkickCount(); ++i)
{
akick = ci->GetAkick(i);
- if (!akick->InUse)
- continue;
if (((akick->HasFlag(AK_ISNICK)) && akick->nc == nc)
|| (!(akick->HasFlag(AK_ISNICK))
&& akick->mask == mask))
@@ -400,7 +399,7 @@ class CommandCSAKick : public Command
return;
}
- ci->EraseAkick(akick);
+ ci->EraseAkick(i);
notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED, mask.c_str(), ci->name.c_str());
}
@@ -408,10 +407,7 @@ class CommandCSAKick : public Command
void DoList(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
{
- int sent_header = 0;
ci::string mask = params.size() > 2 ? params[2] : "";
- unsigned i;
- AutoKick *akick;
if (!ci->GetAkickCount())
{
@@ -419,16 +415,16 @@ class CommandCSAKick : public Command
return;
}
- if (!mask.empty() && isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == strlen(mask.c_str()))
- process_numlist(mask.c_str(), NULL, akick_list_callback, u, ci, &sent_header);
+ if (!mask.empty() && isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new AkickListCallback(u, ci, mask.c_str()))->Process();
else
{
- for (i = 0; i < ci->GetAkickCount(); ++i)
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
{
- akick = ci->GetAkick(i);
+ AutoKick *akick = ci->GetAkick(i);
- if (!akick->InUse)
- continue;
if (!mask.empty())
{
if (!(akick->HasFlag(AK_ISNICK)) && !Anope::Match(akick->mask.c_str(), mask.c_str(), false))
@@ -436,21 +432,24 @@ class CommandCSAKick : public Command
if ((akick->HasFlag(AK_ISNICK)) && !Anope::Match(akick->nc->display, mask.c_str(), false))
continue;
}
- akick_list(u, i, ci, &sent_header);
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
+ }
+
+ AkickListCallback::DoList(u, ci, i, akick);
}
+
+ if (!SentHeader)
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str());
}
-
- if (!sent_header)
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str());
-
}
void DoView(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
{
- int sent_header = 0;
ci::string mask = params.size() > 2 ? params[2] : "";
- AutoKick *akick;
- unsigned i;
if (!ci->GetAkickCount())
{
@@ -458,16 +457,16 @@ class CommandCSAKick : public Command
return;
}
- if (!mask.empty() && isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == strlen(mask.c_str()))
- process_numlist(mask.c_str(), NULL, akick_view_callback, u, ci, &sent_header);
+ if (!mask.empty() && isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new AkickViewCallback(u, ci, mask.c_str()))->Process();
else
{
- for (i = 0; i < ci->GetAkickCount(); ++i)
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
{
- akick = ci->GetAkick(i);
+ AutoKick *akick = ci->GetAkick(i);
- if (!akick->InUse)
- continue;
if (!mask.empty())
{
if (!(akick->HasFlag(AK_ISNICK)) && !Anope::Match(akick->mask.c_str(), mask.c_str(), false))
@@ -475,12 +474,19 @@ class CommandCSAKick : public Command
if ((akick->HasFlag(AK_ISNICK)) && !Anope::Match(akick->nc->display, mask.c_str(), false))
continue;
}
- akick_view(u, i, ci, &sent_header);
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
+ }
+
+ AkickViewCallback::DoList(u, ci, i, akick);
}
- }
- if (!sent_header)
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str());
+ if (!SentHeader)
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str());
+ }
}
void DoEnforce(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
@@ -524,7 +530,7 @@ class CommandCSAKick : public Command
ci::string cmd = params[1];
ci::string mask = params.size() > 2 ? params[2] : "";
- ChannelInfo *ci = cs_findchan(chan.c_str());
+ ChannelInfo *ci = cs_findchan(chan);
if (mask.empty() && (cmd == "ADD" || cmd == "STICK" || cmd == "UNSTICK" || cmd == "DEL"))
this->OnSyntaxError(u, cmd);
@@ -564,6 +570,11 @@ class CommandCSAKick : public Command
{
syntax_error(Config.s_ChanServ, u, "AKICK", CHAN_AKICK_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_AKICK);
+ }
};
@@ -577,13 +588,7 @@ class CSAKick : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSAKick());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_AKICK);
+ this->AddCommand(ChanServ, new CommandCSAKick());
}
};
diff --git a/src/core/cs_ban.c b/src/core/cs_ban.cpp
index d0bbbfbb4..9aee9d1dc 100644
--- a/src/core/cs_ban.c
+++ b/src/core/cs_ban.cpp
@@ -17,7 +17,7 @@
class CommandCSBan : public Command
{
public:
- CommandCSBan(const std::string &cname) : Command(cname, 2, 3)
+ CommandCSBan(const ci::string &cname) : Command(cname, 2, 3)
{
}
@@ -62,9 +62,9 @@ class CommandCSBan : public Command
*/
} else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, u2)) {
notice_lang(Config.s_ChanServ, u, CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
- } else if (is_protected(u2)) {
+ } else if (u2->IsProtected())
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- } else {
+ else {
char mask[BUFSIZE];
get_idealban(ci, u2, mask, sizeof(mask));
@@ -93,6 +93,11 @@ class CommandCSBan : public Command
{
syntax_error(Config.s_ChanServ, u, "BAN", CHAN_BAN_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_BAN);
+ }
};
@@ -104,14 +109,8 @@ class CSBan : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSBan("BAN"));
- this->AddCommand(CHANSERV, new CommandCSBan("KB"));
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_BAN);
+ this->AddCommand(ChanServ, new CommandCSBan("BAN"));
+ this->AddCommand(ChanServ, new CommandCSBan("KB"));
}
};
diff --git a/src/core/cs_clear.c b/src/core/cs_clear.cpp
index bb86e3b74..f331f7a24 100644
--- a/src/core/cs_clear.c
+++ b/src/core/cs_clear.cpp
@@ -161,6 +161,11 @@ class CommandCSClear : public Command
{
syntax_error(Config.s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_CLEAR);
+ }
};
class CSClear : public Module
@@ -171,13 +176,7 @@ class CSClear : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSClear());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_CLEAR);
+ this->AddCommand(ChanServ, new CommandCSClear());
}
};
diff --git a/src/core/cs_drop.c b/src/core/cs_drop.cpp
index b91fdc846..04b2f595f 100644
--- a/src/core/cs_drop.c
+++ b/src/core/cs_drop.cpp
@@ -48,7 +48,7 @@ class CommandCSDrop : public Command
return MOD_CONT;
}
- if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci)) && !u->Account()->HasCommand("chanserv/drop"))
+ if ((ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)) && !u->Account()->HasCommand("chanserv/drop"))
{
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
return MOD_CONT;
@@ -66,7 +66,8 @@ class CommandCSDrop : public Command
if (ircd->chansqline && (ci->HasFlag(CI_FORBIDDEN)))
{
- ircdproto->SendSQLineDel(ci->name.c_str());
+ XLine x(ci->name.c_str());
+ ircdproto->SendSQLineDel(&x);
}
Alog() << Config.s_ChanServ << ": Channel " << ci->name << " dropped by " << u->GetMask() << " (founder: "
@@ -78,8 +79,8 @@ class CommandCSDrop : public Command
* drop the channel before issuing the wallops.
*/
if (Config.WallDrop) {
- if ((level < ACCESS_FOUNDER) || (!IsRealFounder(u, ci) && ci->HasFlag(CI_SECUREFOUNDER)))
- ircdproto->SendGlobops(findbot(Config.s_ChanServ), "\2%s\2 used DROP on channel \2%s\2", u->nick.c_str(), chan);
+ if ((level < ACCESS_FOUNDER) || (!IsFounder(u, ci) && ci->HasFlag(CI_SECUREFOUNDER)))
+ ircdproto->SendGlobops(ChanServ, "\2%s\2 used DROP on channel \2%s\2", u->nick.c_str(), chan);
}
notice_lang(Config.s_ChanServ, u, CHAN_DROPPED, chan);
@@ -103,6 +104,11 @@ class CommandCSDrop : public Command
{
syntax_error(Config.s_ChanServ, u, "DROP", CHAN_DROP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DROP);
+ }
};
class CSDrop : public Module
@@ -113,13 +119,7 @@ class CSDrop : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSDrop());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DROP);
+ this->AddCommand(ChanServ, new CommandCSDrop());
}
};
diff --git a/src/core/cs_forbid.c b/src/core/cs_forbid.cpp
index b47982a7e..d59be57b2 100644
--- a/src/core/cs_forbid.c
+++ b/src/core/cs_forbid.cpp
@@ -64,7 +64,7 @@ class CommandCSForbid : public Command
if (reason)
ci->forbidreason = sstrdup(reason);
- if ((c = findchan(ci->name.c_str())))
+ if ((c = findchan(ci->name)))
{
/* Before banning everyone, it might be prudent to clear +e and +I lists..
* to prevent ppl from rejoining.. ~ Viper */
@@ -78,16 +78,17 @@ class CommandCSForbid : public Command
if (is_oper(uc->user))
continue;
- c->Kick(findbot(Config.s_ChanServ), uc->user, "%s", reason ? reason : getstring(uc->user->Account(), CHAN_FORBID_REASON));
+ c->Kick(ChanServ, uc->user, "%s", reason ? reason : getstring(uc->user->Account(), CHAN_FORBID_REASON));
}
}
if (Config.WallForbid)
- ircdproto->SendGlobops(findbot(Config.s_ChanServ), "\2%s\2 used FORBID on channel \2%s\2", u->nick.c_str(), ci->name.c_str());
+ ircdproto->SendGlobops(ChanServ, "\2%s\2 used FORBID on channel \2%s\2", u->nick.c_str(), ci->name.c_str());
if (ircd->chansqline)
{
- ircdproto->SendSQLine(ci->name, reason ? reason : "Forbidden");
+ XLine x(chan, "Forbidden");
+ ircdproto->SendSQLine(&x);
}
Alog() << Config.s_ChanServ << ": " << u->nick << " set FORBID for channel " << ci->name;
@@ -108,6 +109,11 @@ class CommandCSForbid : public Command
{
syntax_error(Config.s_ChanServ, u, "FORBID", CHAN_FORBID_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_FORBID);
+ }
};
class CSForbid : public Module
@@ -118,13 +124,7 @@ class CSForbid : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSForbid());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_FORBID);
+ this->AddCommand(ChanServ, new CommandCSForbid());
}
};
diff --git a/src/core/cs_getkey.c b/src/core/cs_getkey.cpp
index a0937911b..dc89bbbd0 100644
--- a/src/core/cs_getkey.c
+++ b/src/core/cs_getkey.cpp
@@ -55,6 +55,11 @@ class CommandCSGetKey : public Command
{
syntax_error(Config.s_ChanServ, u, "GETKEY", CHAN_GETKEY_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_GETKEY);
+ }
};
@@ -66,13 +71,7 @@ class CSGetKey : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSGetKey());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_GETKEY);
+ this->AddCommand(ChanServ, new CommandCSGetKey());
}
};
diff --git a/src/core/cs_help.c b/src/core/cs_help.cpp
index d975647b2..3fe704349 100644
--- a/src/core/cs_help.c
+++ b/src/core/cs_help.cpp
@@ -46,7 +46,7 @@ class CommandCSHelp : public Command
}
}
else
- mod_help_cmd(Config.s_ChanServ, u, CHANSERV, cmd.c_str());
+ mod_help_cmd(ChanServ, u, cmd.c_str());
return MOD_CONT;
}
@@ -54,7 +54,8 @@ class CommandCSHelp : public Command
void OnSyntaxError(User *u, const ci::string &subcommand)
{
notice_help(Config.s_ChanServ, u, CHAN_HELP);
- FOREACH_MOD(I_OnChanServHelp, OnChanServHelp(u));
+ for (CommandMap::const_iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.end(); ++it)
+ it->second->OnServHelp(u);
if (Config.CSExpire >= 86400)
notice_help(Config.s_ChanServ, u, CHAN_HELP_EXPIRES, Config.CSExpire / 86400);
if (u->Account() && u->Account()->IsServicesOper())
@@ -71,7 +72,7 @@ class CSHelp : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSHelp());
+ this->AddCommand(ChanServ, new CommandCSHelp());
}
};
diff --git a/src/core/cs_info.c b/src/core/cs_info.cpp
index 60e8ebf50..4e5bf9159 100644
--- a/src/core/cs_info.c
+++ b/src/core/cs_info.cpp
@@ -43,8 +43,8 @@ class CommandCSInfo : public Command
ChannelInfo *ci;
char buf[BUFSIZE];
struct tm *tm;
- bool has_auspex = u->Account() && u->Account()->HasPriv("chanserv/auspex");
- int show_all = 0;
+ bool has_auspex = u->IsIdentified() && u->Account()->HasPriv("chanserv/auspex");
+ bool show_all = false;
time_t expt;
ci = cs_findchan(chan);
@@ -64,7 +64,7 @@ class CommandCSInfo : public Command
/* Should we show all fields? Only for sadmins and identified users */
if (!param.empty() && param == "ALL" && (check_access(u, ci, CA_INFO) || has_auspex))
- show_all = 1;
+ show_all = true;
notice_lang(Config.s_ChanServ, u, CHAN_INFO_HEADER, chan);
notice_lang(Config.s_ChanServ, u, CHAN_INFO_NO_FOUNDER, ci->founder->display);
@@ -138,6 +138,8 @@ class CommandCSInfo : public Command
notice_lang(Config.s_ChanServ, u, CHAN_X_SUSPENDED, ci->forbidby, (ci->forbidreason ? ci->forbidreason : getstring(u, NO_REASON)));
}
+ FOREACH_MOD(I_OnChanInfo, OnChanInfo(u, ci, show_all));
+
if (!show_all && (check_access(u, ci, CA_INFO) || has_auspex))
notice_lang(Config.s_ChanServ, u, NICK_INFO_FOR_MORE, Config.s_ChanServ, ci->name.c_str());
return MOD_CONT;
@@ -146,7 +148,7 @@ class CommandCSInfo : public Command
bool OnHelp(User *u, const ci::string &subcommand)
{
notice_lang(Config.s_ChanServ, u, CHAN_HELP_INFO);
- if (u->Account() && u->Account()->HasPriv("chanserv/auspex"))
+ if (u->IsIdentified() && u->Account()->HasPriv("chanserv/auspex"))
notice_lang(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_INFO);
return true;
@@ -156,6 +158,11 @@ class CommandCSInfo : public Command
{
syntax_error(Config.s_ChanServ, u, "INFO", CHAN_INFO_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_INFO);
+ }
};
class CSInfo : public Module
@@ -166,13 +173,7 @@ class CSInfo : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSInfo());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_INFO);
+ this->AddCommand(ChanServ, new CommandCSInfo());
}
};
diff --git a/src/core/cs_invite.c b/src/core/cs_invite.cpp
index b71e487cc..40999af83 100644
--- a/src/core/cs_invite.c
+++ b/src/core/cs_invite.cpp
@@ -46,7 +46,7 @@ class CommandCSInvite : public Command
u2 = u;
else
{
- if (!(u2 = finduser(params[1].c_str())))
+ if (!(u2 = finduser(params[1])))
{
notice_lang(Config.s_ChanServ, u, NICK_X_NOT_IN_USE, params[1].c_str());
return MOD_CONT;
@@ -74,6 +74,11 @@ class CommandCSInvite : public Command
{
syntax_error(Config.s_ChanServ, u, "INVITE", CHAN_INVITE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_INVITE);
+ }
};
class CSInvite : public Module
@@ -84,13 +89,7 @@ class CSInvite : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSInvite());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_INVITE);
+ this->AddCommand(ChanServ, new CommandCSInvite());
}
};
diff --git a/src/core/cs_kick.c b/src/core/cs_kick.cpp
index bce32d401..e28b1f176 100644
--- a/src/core/cs_kick.c
+++ b/src/core/cs_kick.cpp
@@ -17,7 +17,7 @@
class CommandCSKick : public Command
{
public:
- CommandCSKick(const std::string& cname) : Command(cname, 2, 3)
+ CommandCSKick(const ci::string &cname) : Command(cname, 2, 3)
{
}
@@ -56,9 +56,9 @@ class CommandCSKick : public Command
} else if (!is_same && (ci->HasFlag(CI_PEACE))
&& (get_access(u2, ci) >= get_access(u, ci))) {
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- } else if (is_protected(u2)) {
+ } else if (u2->IsProtected())
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- } else if (!c->FindUser(u2)) {
+ else if (!c->FindUser(u2)) {
notice_lang(Config.s_ChanServ, u, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
} else {
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK)))
@@ -79,6 +79,11 @@ class CommandCSKick : public Command
{
syntax_error(Config.s_ChanServ, u, "KICK", CHAN_KICK_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_KICK);
+ }
};
class CSKick : public Module
@@ -89,14 +94,8 @@ class CSKick : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSKick("KICK"));
- this->AddCommand(CHANSERV, new CommandCSKick("K"));
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_KICK);
+ this->AddCommand(ChanServ, new CommandCSKick("KICK"));
+ this->AddCommand(ChanServ, new CommandCSKick("K"));
}
};
diff --git a/src/core/cs_list.c b/src/core/cs_list.cpp
index cb86bb300..9e8ed1779 100644
--- a/src/core/cs_list.c
+++ b/src/core/cs_list.cpp
@@ -28,8 +28,7 @@ public:
const char *pattern = params[0].c_str();
int spattern_size;
char *spattern;
- ChannelInfo *ci;
- unsigned nchans, i;
+ unsigned nchans;
char buf[BUFSIZE];
bool is_servadmin = u->Account()->HasCommand("chanserv/list");
int count = 0, from = 0, to = 0, tofree = 0;
@@ -111,55 +110,56 @@ public:
snprintf(spattern, spattern_size, "#%s", pattern);
notice_lang(Config.s_ChanServ, u, CHAN_LIST_HEADER, pattern);
- for (i = 0; i < 256; i++)
+
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
{
- for (ci = chanlists[i]; ci; ci = ci->next)
+ ChannelInfo *ci = it->second;
+
+ if (!is_servadmin && ((ci->HasFlag(CI_PRIVATE))
+ || (ci->HasFlag(CI_FORBIDDEN)) || (ci->HasFlag(CI_SUSPENDED))))
+ continue;
+ if (forbidden && !ci->HasFlag(CI_FORBIDDEN))
+ continue;
+ else if (suspended && !ci->HasFlag(CI_SUSPENDED))
+ continue;
+ else if (channoexpire && !ci->HasFlag(CI_NO_EXPIRE))
+ continue;
+
+ if ((stricmp(pattern, ci->name.c_str()) == 0)
+ || (stricmp(spattern, ci->name.c_str()) == 0)
+ || Anope::Match(ci->name, pattern, false)
+ || Anope::Match(ci->name, spattern, false))
{
- if (!is_servadmin && ((ci->HasFlag(CI_PRIVATE))
- || (ci->HasFlag(CI_FORBIDDEN)) || (ci->HasFlag(CI_SUSPENDED))))
- continue;
- if (forbidden && !ci->HasFlag(CI_FORBIDDEN))
- continue;
- else if (suspended && !ci->HasFlag(CI_SUSPENDED))
- continue;
- else if (channoexpire && !ci->HasFlag(CI_NO_EXPIRE))
- continue;
-
- if ((stricmp(pattern, ci->name.c_str()) == 0)
- || (stricmp(spattern, ci->name.c_str()) == 0)
- || Anope::Match(ci->name, pattern, false)
- || Anope::Match(ci->name, spattern, false))
+ if ((((count + 1 >= from) && (count + 1 <= to))
+ || ((from == 0) && (to == 0)))
+ && (++nchans <= Config.CSListMax))
{
- if ((((count + 1 >= from) && (count + 1 <= to))
- || ((from == 0) && (to == 0)))
- && (++nchans <= Config.CSListMax))
+ char noexpire_char = ' ';
+ if (is_servadmin && (ci->HasFlag(CI_NO_EXPIRE)))
+ noexpire_char = '!';
+
+ if (ci->HasFlag(CI_FORBIDDEN))
+ {
+ snprintf(buf, sizeof(buf),
+ "%-20s [Forbidden]", ci->name.c_str());
+ }
+ else if (ci->HasFlag(CI_SUSPENDED))
{
- char noexpire_char = ' ';
- if (is_servadmin && (ci->HasFlag(CI_NO_EXPIRE)))
- noexpire_char = '!';
-
- if (ci->HasFlag(CI_FORBIDDEN))
- {
- snprintf(buf, sizeof(buf),
- "%-20s [Forbidden]", ci->name.c_str());
- }
- else if (ci->HasFlag(CI_SUSPENDED))
- {
- snprintf(buf, sizeof(buf),
- "%-20s [Suspended]", ci->name.c_str());
- }
- else
- {
- snprintf(buf, sizeof(buf), "%-20s %s",
- ci->name.c_str(), ci->desc ? ci->desc : "");
- }
-
- u->SendMessage(Config.s_ChanServ, " %c%s", noexpire_char, buf);
+ snprintf(buf, sizeof(buf),
+ "%-20s [Suspended]", ci->name.c_str());
}
- count++;
+ else
+ {
+ snprintf(buf, sizeof(buf), "%-20s %s",
+ ci->name.c_str(), ci->desc ? ci->desc : "");
+ }
+
+ u->SendMessage(Config.s_ChanServ, " %c%s", noexpire_char, buf);
}
+ count++;
}
}
+
notice_lang(Config.s_ChanServ, u, CHAN_LIST_END,
nchans > Config.CSListMax ? Config.CSListMax : nchans, nchans);
delete [] spattern;
@@ -178,6 +178,11 @@ public:
{
syntax_error(Config.s_ChanServ, u, "LIST", CHAN_LIST_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_LIST);
+ }
};
class CSList : public Module
@@ -188,13 +193,7 @@ public:
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSList());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_LIST);
+ this->AddCommand(ChanServ, new CommandCSList());
}
};
diff --git a/src/core/cs_modes.c b/src/core/cs_modes.cpp
index 3df93d912..67d38ba49 100644
--- a/src/core/cs_modes.c
+++ b/src/core/cs_modes.cpp
@@ -49,7 +49,7 @@ static CommandReturn do_util(User *u, ChannelMode *cm, const char *chan, const c
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
else if (!set && !is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci)))
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else if (!set && is_protected(u2) && !is_same)
+ else if (!set && u2->IsProtected() && !is_same)
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
else if (!c->FindUser(u2))
notice_lang(Config.s_ChanServ, u, NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
@@ -92,6 +92,11 @@ class CommandCSOp : public Command
{
syntax_error(Config.s_ChanServ, u, "OP", CHAN_OP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_OP);
+ }
};
@@ -119,6 +124,11 @@ class CommandCSDeOp : public Command
{
syntax_error(Config.s_ChanServ, u, "DEOP", CHAN_DEOP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEOP);
+ }
};
@@ -146,6 +156,11 @@ class CommandCSVoice : public Command
{
syntax_error(Config.s_ChanServ, u, "VOICE", CHAN_VOICE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_VOICE);
+ }
};
@@ -173,6 +188,11 @@ class CommandCSDeVoice : public Command
{
syntax_error(Config.s_ChanServ, u, "DEVOICE", CHAN_DEVOICE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEVOICE);
+ }
};
@@ -205,6 +225,11 @@ class CommandCSHalfOp : public Command
{
syntax_error(Config.s_ChanServ, u, "HALFOP", CHAN_HALFOP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_HALFOP);
+ }
};
@@ -238,6 +263,11 @@ class CommandCSDeHalfOp : public Command
{
syntax_error(Config.s_ChanServ, u, "DEHALFOP", CHAN_DEHALFOP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEHALFOP);
+ }
};
@@ -270,6 +300,11 @@ class CommandCSProtect : public Command
{
syntax_error(Config.s_ChanServ, u, "PROTECT", CHAN_PROTECT_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_PROTECT);
+ }
};
class CommandCSDeProtect : public Command
@@ -301,6 +336,11 @@ class CommandCSDeProtect : public Command
{
syntax_error(Config.s_ChanServ, u, "DEPROTECT", CHAN_DEPROTECT_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEPROTECT);
+ }
};
class CommandCSOwner : public Command
@@ -332,6 +372,11 @@ class CommandCSOwner : public Command
{
syntax_error(Config.s_ChanServ, u, "OWNER", CHAN_OWNER_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_OWNER);
+ }
};
class CommandCSDeOwner : public Command
@@ -363,6 +408,11 @@ class CommandCSDeOwner : public Command
{
syntax_error(Config.s_ChanServ, u, "DEOWNER", CHAN_DEOWNER_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEOWNER);
+ }
};
@@ -375,76 +425,49 @@ class CSModes : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSOp());
- this->AddCommand(CHANSERV, new CommandCSDeOp());
- this->AddCommand(CHANSERV, new CommandCSVoice());
- this->AddCommand(CHANSERV, new CommandCSDeVoice());
+ this->AddCommand(ChanServ, new CommandCSOp());
+ this->AddCommand(ChanServ, new CommandCSDeOp());
+ this->AddCommand(ChanServ, new CommandCSVoice());
+ this->AddCommand(ChanServ, new CommandCSDeVoice());
- if (serv_uplink && is_sync(serv_uplink))
- OnUplinkSync();
+ if (Me && Me->IsSynced())
+ OnUplinkSync(NULL);
Implementation i[] = {
- I_OnUplinkSync, I_OnServerDisconnect, I_OnChanServHelp
+ I_OnUplinkSync, I_OnServerDisconnect
};
- ModuleManager::Attach(i, this, 3);
+ ModuleManager::Attach(i, this, 2);
}
- void OnUplinkSync()
+ void OnUplinkSync(Server *)
{
if (ModeManager::FindChannelModeByName(CMODE_OWNER))
{
- this->AddCommand(CHANSERV, new CommandCSOwner());
- this->AddCommand(CHANSERV, new CommandCSDeOwner());
+ this->AddCommand(ChanServ, new CommandCSOwner());
+ this->AddCommand(ChanServ, new CommandCSDeOwner());
}
if (ModeManager::FindChannelModeByName(CMODE_PROTECT))
{
- this->AddCommand(CHANSERV, new CommandCSProtect());
- this->AddCommand(CHANSERV, new CommandCSDeProtect());
+ this->AddCommand(ChanServ, new CommandCSProtect());
+ this->AddCommand(ChanServ, new CommandCSDeProtect());
}
if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
{
- this->AddCommand(CHANSERV, new CommandCSHalfOp());
- this->AddCommand(CHANSERV, new CommandCSDeHalfOp());
+ this->AddCommand(ChanServ, new CommandCSHalfOp());
+ this->AddCommand(ChanServ, new CommandCSDeHalfOp());
}
}
void OnServerDisconnect()
{
- this->DelCommand(CHANSERV, "OWNER");
- this->DelCommand(CHANSERV, "DEOWNER");
- this->DelCommand(CHANSERV, "PROTECT");
- this->DelCommand(CHANSERV, "DEPROTECT");
- this->DelCommand(CHANSERV, "HALFOP");
- this->DelCommand(CHANSERV, "DEHALFOP");
- }
-
- void OnChanServHelp(User *u)
- {
- if (ModeManager::FindChannelModeByName(CMODE_OWNER))
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_OWNER);
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEOWNER);
- }
-
- if (ModeManager::FindChannelModeByName(CMODE_PROTECT))
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_PROTECT);
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEPROTECT);
- }
-
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_OP);
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEOP);
-
- if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_HALFOP);
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEHALFOP);
- }
-
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_VOICE);
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_DEVOICE);
+ this->DelCommand(ChanServ, FindCommand(ChanServ, "OWNER"));
+ this->DelCommand(ChanServ, FindCommand(ChanServ, "DEOWNER"));
+ this->DelCommand(ChanServ, FindCommand(ChanServ, "PROTECT"));
+ this->DelCommand(ChanServ, FindCommand(ChanServ, "DEPROTECT"));
+ this->DelCommand(ChanServ, FindCommand(ChanServ, "HALFOP"));
+ this->DelCommand(ChanServ, FindCommand(ChanServ, "DEHALFOP"));
}
};
diff --git a/src/core/cs_register.c b/src/core/cs_register.cpp
index 2c6531226..1706ac16e 100644
--- a/src/core/cs_register.c
+++ b/src/core/cs_register.cpp
@@ -44,8 +44,6 @@ class CommandCSRegister : public Command
notice_lang(Config.s_ChanServ, u, CHAN_X_INVALID, chan);
else if ((ci = cs_findchan(chan)))
notice_lang(Config.s_ChanServ, u, CHAN_ALREADY_REGISTERED, chan);
- else if (!stricmp(chan, "#"))
- notice_lang(Config.s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan);
else if (c && !c->HasUserStatus(u, CMODE_OP))
notice_lang(Config.s_ChanServ, u, CHAN_MUST_BE_CHANOP);
else if (Config.CSMaxReg && u->Account()->channelcount >= Config.CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit"))
@@ -114,6 +112,11 @@ class CommandCSRegister : public Command
{
syntax_error(Config.s_ChanServ, u, "REGISTER", CHAN_REGISTER_SYNTAX);
}
+
+ void OnSyntaxError(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_REGISTER);
+ }
};
class CSRegister : public Module
@@ -125,13 +128,7 @@ class CSRegister : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSRegister());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_REGISTER);
+ this->AddCommand(ChanServ, new CommandCSRegister());
}
};
diff --git a/src/core/cs_saset.cpp b/src/core/cs_saset.cpp
new file mode 100644
index 000000000..29f7f7264
--- /dev/null
+++ b/src/core/cs_saset.cpp
@@ -0,0 +1,131 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSASet : public Command
+{
+ std::map<ci::string, Command *> subcommands;
+
+ public:
+ CommandCSSASet(const ci::string &cname) : Command(cname, 2, 3)
+ {
+ }
+
+ ~CommandCSSASet()
+ {
+ for (std::map<ci::string, Command *>::const_iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ {
+ delete it->second;
+ }
+ this->subcommands.clear();
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (readonly)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_DISABLED);
+ return MOD_CONT;
+ }
+
+ Command *c = this->FindCommand(params[1]);
+
+ if (c)
+ {
+ ci::string cmdparams = cs_findchan(params[0])->name.c_str();
+ for (std::vector<ci::string>::const_iterator it = params.begin() + 2; it != params.end(); ++it)
+ cmdparams += " " + *it;
+ mod_run_cmd(ChanServ, u, c, params[1], cmdparams);
+ }
+ else
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, params[1].c_str());
+ notice_lang(Config.s_ChanServ, u, MORE_INFO, Config.s_ChanServ, "SET");
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ if (subcommand.empty())
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SASET_HEAD);
+ for (std::map<ci::string, Command *>::iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ it->second->OnServHelp(u);
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TAIL);
+ return true;
+ }
+ else
+ {
+ Command *c = this->FindCommand(subcommand);
+
+ if (c)
+ {
+ return c->OnHelp(u, subcommand);
+ }
+ }
+
+ return false;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SASET);
+ }
+
+ bool AddSubcommand(Command *c)
+ {
+ return this->subcommands.insert(std::make_pair(c->name, c)).second;
+ }
+
+ bool DelSubcommand(const ci::string &command)
+ {
+ return this->subcommands.erase(command);
+ }
+
+ Command *FindCommand(const ci::string &subcommand)
+ {
+ std::map<ci::string, Command *>::const_iterator it = this->subcommands.find(subcommand);
+
+ if (it != this->subcommands.end())
+ {
+ return it->second;
+ }
+
+ return NULL;
+ }
+};
+
+class CSSASet : public Module
+{
+ public:
+ CSSASet(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ this->AddCommand(ChanServ, new CommandCSSASet("SASET"));
+ }
+};
+
+MODULE_INIT(CSSASet)
diff --git a/src/core/cs_saset_noexpire.cpp b/src/core/cs_saset_noexpire.cpp
new file mode 100644
index 000000000..8d9ce2e18
--- /dev/null
+++ b/src/core/cs_saset_noexpire.cpp
@@ -0,0 +1,85 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSASetNoexpire : public Command
+{
+ public:
+ CommandCSSASetNoexpire(const ci::string &cname) : Command(cname, 2, 2, "chanserv/saset/noexpire")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[0] == "ON")
+ {
+ ci->SetFlag(CI_NO_EXPIRE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_ON, ci->name.c_str());
+ }
+ else if (params[0] == "OFF")
+ {
+ ci->UnsetFlag(CI_NO_EXPIRE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "NOEXPIRE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_SET_NOEXPIRE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET NOEXPIRE", CHAN_SET_NOEXPIRE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_NOEXPIRE);
+ }
+};
+
+class CSSetNoexpire : public Module
+{
+ public:
+ CSSetNoexpire(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetNoexpire("NOEXPIRE"));
+ }
+
+ ~CSSetNoexpire()
+ {
+ Command *c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("NOEXPIRE");
+ }
+};
+
+MODULE_INIT(CSSetNoexpire)
diff --git a/src/core/cs_set.c b/src/core/cs_set.c
deleted file mode 100644
index c964d26fc..000000000
--- a/src/core/cs_set.c
+++ /dev/null
@@ -1,839 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-/*************************************************************************/
-
-#include "module.h"
-#include "hashcomp.h"
-
-class CommandCSSet : public Command
-{
- private:
- CommandReturn DoSetFounder(User * u, ChannelInfo * ci, const ci::string &param)
- {
- NickAlias *na = findnick(param.c_str());
- NickCore *nc, *nc0 = ci->founder;
-
- if (!na)
- {
- notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, param.c_str());
- return MOD_CONT;
- }
- else if (na->HasFlag(NS_FORBIDDEN))
- {
- notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, param.c_str());
- return MOD_CONT;
- }
-
- nc = na->nc;
- if (Config.CSMaxReg && nc->channelcount >= Config.CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit"))
- {
- notice_lang(Config.s_ChanServ, u, CHAN_SET_FOUNDER_TOO_MANY_CHANS, param.c_str());
- return MOD_CONT;
- }
-
- Alog() << Config.s_ChanServ << ": Changing founder of " << ci->name << " from " << ci->founder->display
- << " to " << nc->display << " by " << u->GetMask();
-
- /* Founder and successor must not be the same group */
- if (nc == ci->successor)
- ci->successor = NULL;
-
- nc0->channelcount--;
- ci->founder = nc;
- nc->channelcount++;
-
- notice_lang(Config.s_ChanServ, u, CHAN_FOUNDER_CHANGED, ci->name.c_str(), param.c_str());
- return MOD_CONT;
- }
-
- CommandReturn DoSetSuccessor(User * u, ChannelInfo * ci, const ci::string &param)
- {
- NickAlias *na;
- NickCore *nc;
-
- if (!param.empty())
- {
- na = findnick(param.c_str());
-
- if (!na)
- {
- notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, param.c_str());
- return MOD_CONT;
- }
- if (na->HasFlag(NS_FORBIDDEN))
- {
- notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, param.c_str());
- return MOD_CONT;
- }
- if (na->nc == ci->founder)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_IS_FOUNDER, param.c_str(), ci->name.c_str());
- return MOD_CONT;
- }
- nc = na->nc;
-
- }
- else
- nc = NULL;
-
- Alog() << Config.s_ChanServ << ": Changing successor of " << ci->name << " from "
- << (ci->successor ? ci->successor->display : "none")
- << " to " << (nc ? nc->display : "none") << " by " << u->GetMask();
-
- ci->successor = nc;
-
- if (nc)
- notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_CHANGED, ci->name.c_str(), param.c_str());
- else
- notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_UNSET, ci->name.c_str());
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetDesc(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (ci->desc)
- delete [] ci->desc;
- ci->desc = sstrdup(param.c_str());
- notice_lang(Config.s_ChanServ, u, CHAN_DESC_CHANGED, ci->name.c_str(), param.c_str());
- return MOD_CONT;
- }
-
- CommandReturn DoSetURL(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (ci->url)
- delete [] ci->url;
- if (!param.empty())
- {
- ci->url = sstrdup(param.c_str());
- notice_lang(Config.s_ChanServ, u, CHAN_URL_CHANGED, ci->name.c_str(), param.c_str());
- }
- else
- {
- ci->url = NULL;
- notice_lang(Config.s_ChanServ, u, CHAN_URL_UNSET, ci->name.c_str());
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetEMail(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (ci->email)
- delete [] ci->email;
- if (!param.empty())
- {
- ci->email = sstrdup(param.c_str());
- notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_CHANGED, ci->name.c_str(), param.c_str());
- }
- else
- {
- ci->email = NULL;
- notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_UNSET, ci->name.c_str());
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetEntryMsg(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (ci->entry_message)
- delete [] ci->entry_message;
- if (!param.empty())
- {
- ci->entry_message = sstrdup(param.c_str());
- notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_CHANGED, ci->name.c_str(), param.c_str());
- }
- else
- {
- ci->entry_message = NULL;
- notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_UNSET, ci->name.c_str());
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetMLock(User * u, ChannelInfo * ci, const char *modes)
- {
- int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
- unsigned char mode;
- ChannelMode *cm;
- ChannelModeParam *cmp;
-
- ci->ClearMLock();
-
- if (ModeManager::FindChannelModeByName(CMODE_REGISTERED))
- ci->SetMLock(CMODE_REGISTERED, true);
-
- ci->ClearParams();
-
- std::string params(modes ? modes : ""), param;
- unsigned space = params.find(' ');
- if (space != std::string::npos)
- {
- param = params.substr(space + 1);
- params = params.substr(0, space);
- modes = params.c_str();
- }
- spacesepstream modeparams(param);
-
- while (modes && (mode = *modes++)) {
- switch (mode) {
- case '+':
- add = 1;
- continue;
- case '-':
- add = 0;
- continue;
- default:
- if (add < 0)
- continue;
- }
-
- if ((cm = ModeManager::FindChannelModeByChar(mode)))
- {
- if (cm->Type == MODE_STATUS || cm->Type == MODE_LIST || !cm->CanSet(u))
- {
- notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_IMPOSSIBLE_CHAR, mode);
- }
- else if (add)
- {
- ci->RemoveMLock(cm->Name);
-
- if (cm->Type == MODE_PARAM)
- {
- cmp = dynamic_cast<ChannelModeParam *>(cm);
-
- if (!modeparams.GetToken(param))
- continue;
-
- if (!cmp->IsValid(param))
- continue;
-
- ci->SetMLock(cmp->Name, true, param);
- }
- else
- {
- ci->SetMLock(cm->Name, true);
- }
- }
- else
- {
- ci->SetMLock(cm->Name, false);
- }
- }
- else
- notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_UNKNOWN_CHAR, mode);
- } /* while (*modes) */
-
- if (ModeManager::FindChannelModeByName(CMODE_REDIRECT)) {
- /* We can't mlock +L if +l is not mlocked as well. */
- if (ci->HasMLock(CMODE_REDIRECT, true) && !ci->HasMLock(CMODE_LIMIT, true))
- {
- ci->RemoveMLock(CMODE_REDIRECT);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_L_REQUIRED);
- }
- }
-
- /* Some ircd we can't set NOKNOCK without INVITE */
- /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */
- if (ModeManager::FindChannelModeByName(CMODE_NOKNOCK) && ircd->knock_needs_i) {
- if (ci->HasMLock(CMODE_NOKNOCK, true) && !ci->HasMLock(CMODE_INVITE, true))
- {
- ci->RemoveMLock(CMODE_NOKNOCK);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_K_REQUIRED);
- }
- }
-
- /* Since we always enforce mode r there is no way to have no
- * mode lock at all.
- */
- if (get_mlock_modes(ci, 0)) {
- notice_lang(Config.s_ChanServ, u, CHAN_MLOCK_CHANGED, ci->name.c_str(),
- get_mlock_modes(ci, 0));
- }
-
- /* Implement the new lock. */
- if (ci->c)
- check_modes(ci->c);
- return MOD_CONT;
- }
-
- CommandReturn DoSetBanType(User * u, ChannelInfo * ci, const char *param)
- {
- char *endptr;
-
- int16 bantype = strtol(param, &endptr, 10);
-
- if (*endptr != 0 || bantype < 0 || bantype > 3) {
- notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_INVALID, param);
- } else {
- ci->bantype = bantype;
- notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_CHANGED, ci->name.c_str(),
- ci->bantype);
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetKeepTopic(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_KEEPTOPIC);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_KEEPTOPIC);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "KEEPTOPIC");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetTopicLock(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_TOPICLOCK);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_TOPICLOCK);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "TOPICLOCK");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetPrivate(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_PRIVATE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_PRIVATE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "PRIVATE");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetSecureOps(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_SECUREOPS);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_SECUREOPS);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "SECUREOPS");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetSecureFounder(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_SECUREFOUNDER);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_SECUREFOUNDER);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "SECUREFOUNDER");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetRestricted(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_RESTRICTED);
- if (ci->levels[CA_NOJOIN] < 0)
- ci->levels[CA_NOJOIN] = 0;
- notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_RESTRICTED);
- if (ci->levels[CA_NOJOIN] >= 0)
- ci->levels[CA_NOJOIN] = -2;
- notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "RESTRICTED");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetSecure(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_SECURE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_SECURE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "SECURE");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetSignKick(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_SIGNKICK);
- ci->UnsetFlag(CI_SIGNKICK_LEVEL);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_ON, ci->name.c_str());
- }
- else if (param == "LEVEL")
- {
- ci->SetFlag(CI_SIGNKICK_LEVEL);
- ci->UnsetFlag(CI_SIGNKICK);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_LEVEL, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_SIGNKICK);
- ci->UnsetFlag(CI_SIGNKICK_LEVEL);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "SIGNKICK");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetOpNotice(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_OPNOTICE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_OPNOTICE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "OPNOTICE");
-
- return MOD_CONT;
- }
-
-#define CHECKLEV(lev) ((ci->levels[(lev)] != ACCESS_INVALID) && (access->level >= ci->levels[(lev)]))
-
- CommandReturn DoSetXOP(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- if (!(ci->HasFlag(CI_XOP)))
- {
- ChanAccess *access;
-
- for (unsigned i = 0; i < ci->GetAccessCount(); i++)
- {
- access = ci->GetAccess(i);
- if (!access->in_use)
- continue;
- /* This will probably cause wrong levels to be set, but hey,
- * it's better than losing it altogether.
- */
- if (access->level == ACCESS_QOP)
- access->level = ACCESS_QOP;
- else if (CHECKLEV(CA_AKICK) || CHECKLEV(CA_SET))
- access->level = ACCESS_SOP;
- else if (CHECKLEV(CA_AUTOOP) || CHECKLEV(CA_OPDEOP) || CHECKLEV(CA_OPDEOPME))
- access->level = ACCESS_AOP;
- else if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && (CHECKLEV(CA_AUTOHALFOP) || CHECKLEV(CA_HALFOP) || CHECKLEV(CA_HALFOPME)))
- access->level = ACCESS_HOP;
- else if (CHECKLEV(CA_AUTOVOICE) || CHECKLEV(CA_VOICE) || CHECKLEV(CA_VOICEME))
- access->level = ACCESS_VOP;
- else
- {
- ci->EraseAccess(i);
- }
- }
-
- /* The above may have set an access entry to not be in use, this will clean that up. */
- ci->CleanAccess();
-
- reset_levels(ci);
- ci->SetFlag(CI_XOP);
- }
-
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " enabled XOP for " << ci->name;
- notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_XOP);
-
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled XOP for " << ci->name;
- notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "XOP");
-
- return MOD_CONT;
- }
-
-#undef CHECKLEV
-
- CommandReturn DoSetPeace(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_PEACE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_PEACE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "PEACE");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetPersist(User *u, ChannelInfo *ci, const ci::string &param)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM);
-
- if (param == "ON")
- {
- if (!ci->HasFlag(CI_PERSIST))
- {
- ci->SetFlag(CI_PERSIST);
-
- /* Channel doesn't exist, create it internally */
- if (!ci->c)
- {
- new Channel(ci->name);
- if (ci->bi)
- bot_join(ci);
- }
-
- /* No botserv bot, no channel mode */
- if (!ci->bi && !cm)
- {
- /* Give them ChanServ
- * Yes, this works fine with no Config.s_BotServ
- */
- findbot(Config.s_ChanServ)->Assign(NULL, ci);
- }
-
- /* Set the perm mode */
- if (cm && ci->c && !ci->c->HasMode(CMODE_PERM))
- {
- ci->c->SetMode(NULL, cm);
- }
- }
-
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- if (ci->HasFlag(CI_PERSIST))
- {
- ci->UnsetFlag(CI_PERSIST);
-
- /* Unset perm mode */
- if (cm && ci->c && ci->c->HasMode(CMODE_PERM))
- ci->c->RemoveMode(NULL, cm);
- if (Config.s_BotServ && ci->bi && ci->c->users.size() == Config.BSMinUsers - 1)
- ircdproto->SendPart(ci->bi, ci->c, NULL);
-
- /* No channel mode, no BotServ, but using ChanServ as the botserv bot
- * which was assigned when persist was set on
- */
- if (!cm && !Config.s_BotServ && ci->bi)
- {
- /* Unassign bot */
- findbot(Config.s_ChanServ)->UnAssign(NULL, ci);
- }
-
- if (ci->c && ci->c->users.empty())
- delete ci->c;
- }
-
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "PERSIST");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetNoExpire(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (!u->Account()->HasCommand("chanserv/set/noexpire"))
- {
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- return MOD_CONT;
- }
- if (param == "ON")
- {
- ci->SetFlag(CI_NO_EXPIRE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_NO_EXPIRE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "NOEXPIRE");
-
- return MOD_CONT;
- }
-
- public:
- CommandCSSet() : Command("SET", 2, 3)
- {
- }
-
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
- {
- const char *chan = params[0].c_str();
- ci::string cmd = params[1];
- ci::string param = params.size() > 2 ? params[2] : "";
- ChannelInfo *ci = cs_findchan(chan);
- bool is_servadmin = u->Account()->HasPriv("chanserv/set");
-
- if (readonly) {
- notice_lang(Config.s_ChanServ, u, CHAN_SET_DISABLED);
- return MOD_CONT;
- }
-
- if (param.empty() && cmd != "SUCCESSOR" && cmd != "URL" && cmd != "EMAIL" && cmd != "ENTRYMSG" && cmd != "MLOCK")
- this->OnSyntaxError(u, cmd);
- else if (!is_servadmin && !check_access(u, ci, CA_SET))
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else if (cmd == "FOUNDER")
- {
- if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci)))
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else
- DoSetFounder(u, ci, param);
- }
- else if (cmd == "SUCCESSOR")
- {
- if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci)))
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else
- DoSetSuccessor(u, ci, param);
- }
- else if (cmd == "DESC")
- DoSetDesc(u, ci, param);
- else if (cmd == "URL")
- DoSetURL(u, ci, param);
- else if (cmd == "EMAIL")
- DoSetEMail(u, ci, param);
- else if (cmd == "ENTRYMSG")
- DoSetEntryMsg(u, ci, param);
- else if (cmd == "TOPIC")
- notice_lang(Config.s_ChanServ, u, OBSOLETE_COMMAND, "TOPIC");
- else if (cmd == "BANTYPE")
- DoSetBanType(u, ci, param.c_str());
- else if (cmd == "MLOCK")
- DoSetMLock(u, ci, param.c_str());
- else if (cmd == "KEEPTOPIC")
- DoSetKeepTopic(u, ci, param);
- else if (cmd == "TOPICLOCK")
- DoSetTopicLock(u, ci, param);
- else if (cmd == "PRIVATE")
- DoSetPrivate(u, ci, param);
- else if (cmd == "SECUREOPS")
- DoSetSecureOps(u, ci, param);
- else if (cmd == "SECUREFOUNDER")
- {
- if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsRealFounder(u, ci) : !IsFounder(u, ci)))
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else
- DoSetSecureFounder(u, ci, param);
- }
- else if (cmd == "RESTRICTED")
- DoSetRestricted(u, ci, param);
- else if (cmd == "SECURE")
- DoSetSecure(u, ci, param);
- else if (cmd == "SIGNKICK")
- DoSetSignKick(u, ci, param);
- else if (cmd == "OPNOTICE")
- DoSetOpNotice(u, ci, param);
- else if (cmd == "XOP")
- {
- if (!findModule("cs_xop"))
- notice_lang(Config.s_ChanServ, u, CHAN_XOP_NOT_AVAILABLE, cmd.c_str());
- else
- DoSetXOP(u, ci, param);
- }
- else if (cmd == "PEACE")
- DoSetPeace(u, ci, param);
- else if (cmd == "PERSIST")
- DoSetPersist(u, ci, param);
- else if (cmd == "NOEXPIRE")
- DoSetNoExpire(u, ci, param);
- else
- {
- notice_lang(Config.s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, cmd.c_str());
- notice_lang(Config.s_ChanServ, u, MORE_INFO, Config.s_ChanServ, "SET");
- }
-
- return MOD_CONT;
- }
-
- bool OnHelp(User *u, const ci::string &subcommand)
- {
- if (subcommand.empty())
- {
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET);
- if (u->Account() && u->Account()->IsServicesOper())
- notice_help(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_SET);
- }
- else if (subcommand == "FOUNDER")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_FOUNDER);
- else if (subcommand == "SUCCESSOR")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SUCCESSOR);
- else if (subcommand == "DESC")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_DESC);
- else if (subcommand == "URL")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_URL);
- else if (subcommand == "EMAIL")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_EMAIL);
- else if (subcommand == "ENTRYMSG")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_ENTRYMSG);
- else if (subcommand == "BANTYPE")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_BANTYPE);
- else if (subcommand == "PRIVATE")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PRIVATE);
- else if (subcommand == "KEEPTOPIC")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_KEEPTOPIC);
- else if (subcommand == "TOPICLOCK")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TOPICLOCK);
- else if (subcommand == "MLOCK")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_MLOCK);
- else if (subcommand == "RESTRICTED")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_RESTRICTED);
- else if (subcommand == "SECURE")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECURE, Config.s_NickServ);
- else if (subcommand == "SECUREOPS")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREOPS);
- else if (subcommand == "SECUREFOUNDER")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREFOUNDER);
- else if (subcommand == "SIGNKICK")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SIGNKICK);
- else if (subcommand == "OPNOTICE")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_OPNOTICE);
- else if (subcommand == "XOP")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_XOP);
- else if (subcommand == "PEACE")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PEACE);
- else if (subcommand == "PERSIST")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PERSIST);
- else if (subcommand == "NOEXPIRE")
- notice_help(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_SET_NOEXPIRE);
- else
- return false;
-
- return true;
- }
-
- void OnSyntaxError(User *u, const ci::string &subcommand)
- {
- int reply = CHAN_SET_SYNTAX;
- ci::string command = "SET";
-
- if (!subcommand.empty())
- {
- if (subcommand == "KEEPTOPIC")
- reply = CHAN_SET_KEEPTOPIC_SYNTAX;
- else if (subcommand == "TOPICLOCK")
- reply = CHAN_SET_TOPICLOCK_SYNTAX;
- else if (subcommand == "PRIVATE")
- reply = CHAN_SET_PRIVATE_SYNTAX;
- else if (subcommand == "SECUREOPS")
- reply = CHAN_SET_SECUREOPS_SYNTAX;
- else if (subcommand == "SECUREFOUNDER")
- reply = CHAN_SET_SECUREFOUNDER_SYNTAX;
- else if (subcommand == "RESTRICTED")
- reply = CHAN_SET_RESTRICTED_SYNTAX;
- else if (subcommand == "SECURE")
- reply = CHAN_SET_SECURE_SYNTAX;
- else if (subcommand == "SIGNKICK")
- reply = CHAN_SET_SIGNKICK_SYNTAX;
- else if (subcommand == "OPNOTICE")
- reply = CHAN_SET_OPNOTICE_SYNTAX;
- else if (subcommand == "XOP")
- reply = CHAN_SET_XOP_SYNTAX;
- else if (subcommand == "PEACE")
- reply = CHAN_SET_PEACE_SYNTAX;
- else if (subcommand == "PERSIST")
- reply = CHAN_SET_PERSIST_SYNTAX;
- else if (subcommand == "NOEXPIRE")
- reply = CHAN_SET_NOEXPIRE_SYNTAX;
-
- if (reply != CHAN_SET_SYNTAX)
- command += " " + subcommand;
- }
-
- syntax_error(Config.s_ChanServ, u, command.c_str(), reply);
- }
-};
-
-class CSSet : public Module
-{
- public:
- CSSet(const std::string &modname, const std::string &creator) : Module(modname, creator)
- {
- this->SetAuthor("Anope");
- this->SetVersion(VERSION_STRING);
- this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSSet());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET);
- }
-};
-
-MODULE_INIT(CSSet)
diff --git a/src/core/cs_set.cpp b/src/core/cs_set.cpp
new file mode 100644
index 000000000..c11a1c102
--- /dev/null
+++ b/src/core/cs_set.cpp
@@ -0,0 +1,136 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSet : public Command
+{
+ std::map<ci::string, Command *> subcommands;
+
+ public:
+ CommandCSSet(const ci::string &cname) : Command(cname, 2, 3)
+ {
+ }
+
+ ~CommandCSSet()
+ {
+ for (std::map<ci::string, Command *>::const_iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ {
+ delete it->second;
+ }
+ this->subcommands.clear();
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (readonly)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_DISABLED);
+ return MOD_CONT;
+ }
+ if (!check_access(u, cs_findchan(params[0]), CA_SET))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+
+
+ Command *c = this->FindCommand(params[1]);
+
+ if (c)
+ {
+ ci::string cmdparams = cs_findchan(params[0])->name.c_str();
+ for (std::vector<ci::string>::const_iterator it = params.begin() + 2; it != params.end(); ++it)
+ cmdparams += " " + *it;
+ mod_run_cmd(ChanServ, u, c, params[1], cmdparams);
+ }
+ else
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, params[1].c_str());
+ notice_lang(Config.s_ChanServ, u, MORE_INFO, Config.s_ChanServ, "SET");
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ if (subcommand.empty())
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_HEAD);
+ for (std::map<ci::string, Command *>::iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ it->second->OnServHelp(u);
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TAIL);
+ return true;
+ }
+ else
+ {
+ Command *c = this->FindCommand(subcommand);
+
+ if (c)
+ {
+ return c->OnHelp(u, subcommand);
+ }
+ }
+
+ return false;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET);
+ }
+
+ bool AddSubcommand(Command *c)
+ {
+ return this->subcommands.insert(std::make_pair(c->name, c)).second;
+ }
+
+ bool DelSubcommand(const ci::string &command)
+ {
+ return this->subcommands.erase(command);
+ }
+
+ Command *FindCommand(const ci::string &subcommand)
+ {
+ std::map<ci::string, Command *>::const_iterator it = this->subcommands.find(subcommand);
+
+ if (it != this->subcommands.end())
+ {
+ return it->second;
+ }
+
+ return NULL;
+ }
+};
+
+class CSSet : public Module
+{
+ public:
+ CSSet(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion(VERSION_STRING);
+ this->SetType(CORE);
+
+ this->AddCommand(ChanServ, new CommandCSSet("SET"));
+ }
+};
+
+MODULE_INIT(CSSet)
diff --git a/src/core/cs_set_bantype.cpp b/src/core/cs_set_bantype.cpp
new file mode 100644
index 000000000..985c6f1e6
--- /dev/null
+++ b/src/core/cs_set_bantype.cpp
@@ -0,0 +1,113 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetBanType : public Command
+{
+ public:
+ CommandCSSetBanType(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ char *endptr;
+
+ int16 bantype = strtol(params[1].c_str(), &endptr, 10);
+
+ if (*endptr != 0 || bantype < 0 || bantype > 3)
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_INVALID, params[1].c_str());
+ else
+ {
+ ci->bantype = bantype;
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_CHANGED, ci->name.c_str(), ci->bantype);
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_BANTYPE, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_BANTYPE);
+ }
+};
+
+class CommandCSSASetBanType : public CommandCSSetBanType
+{
+ public:
+ CommandCSSASetBanType(const ci::string &cname) : CommandCSSetBanType(cname, "chanserv/saset/bantype")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_BANTYPE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetBanType : public Module
+{
+ public:
+ CSSetBanType(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetBanType("BANTYPE"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetBanType("BANTYPE"));
+ }
+
+ ~CSSetBanType()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("BANTYPE");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("BANTYPE");
+ }
+};
+
+MODULE_INIT(CSSetBanType)
diff --git a/src/core/cs_set_description.cpp b/src/core/cs_set_description.cpp
new file mode 100644
index 000000000..44e6090bf
--- /dev/null
+++ b/src/core/cs_set_description.cpp
@@ -0,0 +1,107 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetDescription : public Command
+{
+ public:
+ CommandCSSetDescription(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (ci->desc)
+ delete [] ci->desc;
+ ci->desc = sstrdup(params[1].c_str());
+
+ notice_lang(Config.s_ChanServ, u, CHAN_DESC_CHANGED, ci->name.c_str(), ci->desc);
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_DESC, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_DESC);
+ }
+};
+
+class CommandCSSASetDescription : public CommandCSSetDescription
+{
+ public:
+ CommandCSSASetDescription(const ci::string &cname) : CommandCSSetDescription(cname, "chanserv/saset/description")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_DESC, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetDescription : public Module
+{
+ public:
+ CSSetDescription(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetDescription("DESC"));
+
+ c = FindCommand(ChanServ, "SASEt");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetDescription("DESC"));
+ }
+
+ ~CSSetDescription()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("DESC");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("DESC");
+ }
+};
+
+MODULE_INIT(CSSetDescription)
diff --git a/src/core/cs_set_email.cpp b/src/core/cs_set_email.cpp
new file mode 100644
index 000000000..d226a3b06
--- /dev/null
+++ b/src/core/cs_set_email.cpp
@@ -0,0 +1,106 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetEMail : public Command
+{
+ public:
+ CommandCSSetEMail(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (ci->email)
+ delete [] ci->email;
+ if (params.size() > 1)
+ {
+ ci->email = sstrdup(params[1].c_str());
+ notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_CHANGED, ci->name.c_str(), ci->email);
+ }
+ else
+ {
+ ci->email = NULL;
+ notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_UNSET, ci->name.c_str());
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_EMAIL, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_EMAIL);
+ }
+};
+
+class CommandCSSASetEMail : public CommandCSSetEMail
+{
+ public:
+ CommandCSSASetEMail(const ci::string &cname) : CommandCSSetEMail(cname, "chanserv/saset/email")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_EMAIL, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ /// XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetEMail : public Module
+{
+ public:
+ CSSetEMail(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetEMail("EMAIL"));
+ }
+
+ ~CSSetEMail()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("EMAIL");
+ }
+};
+
+MODULE_INIT(CSSetEMail)
diff --git a/src/core/cs_set_entrymsg.cpp b/src/core/cs_set_entrymsg.cpp
new file mode 100644
index 000000000..b7c223546
--- /dev/null
+++ b/src/core/cs_set_entrymsg.cpp
@@ -0,0 +1,114 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetEntryMsg : public Command
+{
+ public:
+ CommandCSSetEntryMsg(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (ci->entry_message)
+ delete [] ci->entry_message;
+ if (params.size() > 1)
+ {
+ ci->entry_message = sstrdup(params[1].c_str());
+ notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_CHANGED, ci->name.c_str(), ci->entry_message);
+ }
+ else
+ {
+ ci->entry_message = NULL;
+ notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_UNSET, ci->name.c_str());
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_ENTRYMSG, "SEt");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_ENTRYMSG);
+ }
+};
+
+class CommandCSSASetEntryMsg : public CommandCSSetEntryMsg
+{
+ public:
+ CommandCSSASetEntryMsg(const ci::string &cname) : CommandCSSetEntryMsg(cname, "/chanserv/saset/entrymsg")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_ENTRYMSG, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetEntryMsg : public Module
+{
+ public:
+ CSSetEntryMsg(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetEntryMsg("ENTRYMSG"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetEntryMsg("ENTRYMSG"));
+ }
+
+ ~CSSetEntryMsg()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("ENTRYMSG");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("ENTRYMSG");
+ }
+};
+
+MODULE_INIT(CSSetEntryMsg)
diff --git a/src/core/cs_set_founder.cpp b/src/core/cs_set_founder.cpp
new file mode 100644
index 000000000..6a456a0f6
--- /dev/null
+++ b/src/core/cs_set_founder.cpp
@@ -0,0 +1,142 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetFounder : public Command
+{
+ public:
+ CommandCSSetFounder(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (this->permission.empty() && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+
+ NickAlias *na = findnick(params[1]);
+ NickCore *nc, *nc0 = ci->founder;
+
+
+ if (!na)
+ {
+ notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, params[1].c_str());
+ return MOD_CONT;
+ }
+ else if (na->HasFlag(NS_FORBIDDEN))
+ {
+ notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, na->nick);
+ return MOD_CONT;
+ }
+
+ nc = na->nc;
+ if (Config.CSMaxReg && nc->channelcount >= Config.CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit"))
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_FOUNDER_TOO_MANY_CHANS, na->nick);
+ return MOD_CONT;
+ }
+
+ Alog() << Config.s_ChanServ << ": Changing founder of " << ci->name << " from " << ci->founder->display
+ << " to " << nc->display << " by " << u->GetMask();
+
+ /* Founder and successor must not be the same group */
+ if (nc == ci->successor)
+ ci->successor = NULL;
+
+ nc0->channelcount--;
+ ci->founder = nc;
+ nc->channelcount++;
+
+ notice_lang(Config.s_ChanServ, u, CHAN_FOUNDER_CHANGED, ci->name.c_str(), na->nick);
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_FOUNDER, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_FOUNDER);
+ }
+};
+
+class CommandCSSASetFounder : public CommandCSSetFounder
+{
+ public:
+ CommandCSSASetFounder(const ci::string &cname) : CommandCSSetFounder(cname, "chanserv/saset/founder")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_FOUNDER, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetFounder : public Module
+{
+ public:
+ CSSetFounder(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetFounder("FOUNDER"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetFounder("FOUNDER"));
+ }
+
+ ~CSSetFounder()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("FOUNDER");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("FOUNDER");
+ }
+};
+
+MODULE_INIT(CSSetFounder)
diff --git a/src/core/cs_set_keeptopic.cpp b/src/core/cs_set_keeptopic.cpp
new file mode 100644
index 000000000..87a4660cf
--- /dev/null
+++ b/src/core/cs_set_keeptopic.cpp
@@ -0,0 +1,112 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetKeepTopic : public Command
+{
+ public:
+ CommandCSSetKeepTopic(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_KEEPTOPIC);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_KEEPTOPIC);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "KEEPTOPIC");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_KEEPTOPIC, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET KEEPTOPIC", CHAN_SET_KEEPTOPIC_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_KEEPTOPIC);
+ }
+};
+
+class CommandCSSASetKeepTopic : public CommandCSSetKeepTopic
+{
+ public:
+ CommandCSSASetKeepTopic(const ci::string &cname) : CommandCSSetKeepTopic(cname, "chanserv/saset/keeptopic")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_KEEPTOPIC, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET KEEPTOPIC", CHAN_SASET_KEEPTOPIC_SYNTAX);
+ }
+};
+
+class CSSetKeepTopic : public Module
+{
+ public:
+ CSSetKeepTopic(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetKeepTopic("KEEPTOPIC"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetKeepTopic("KEEPTOPIC"));
+ }
+
+ ~CSSetKeepTopic()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("KEEPTOPIC");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("KEEPTOPIC");
+ }
+};
+
+MODULE_INIT(CSSetKeepTopic)
diff --git a/src/core/cs_set_mlock.cpp b/src/core/cs_set_mlock.cpp
new file mode 100644
index 000000000..d75363ac4
--- /dev/null
+++ b/src/core/cs_set_mlock.cpp
@@ -0,0 +1,197 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetMLock : public Command
+{
+ public:
+ CommandCSSetMLock(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 0, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
+ unsigned char mode;
+ ChannelMode *cm;
+ unsigned paramcount = 2;
+
+ ci->ClearMLock();
+ ci->ClearParams();
+
+ if (ModeManager::FindChannelModeByName(CMODE_REGISTERED))
+ ci->SetMLock(CMODE_REGISTERED, true);
+
+ const char *modes = params[1].c_str();
+ while (modes && (mode = *modes++))
+ {
+ switch (mode) {
+ case '+':
+ add = 1;
+ continue;
+ case '-':
+ add = 0;
+ continue;
+ default:
+ if (add < 0)
+ continue;
+ }
+
+ if ((cm = ModeManager::FindChannelModeByChar(mode)))
+ {
+ if (cm->Type == MODE_STATUS || cm->Type == MODE_LIST || !cm->CanSet(u))
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_IMPOSSIBLE_CHAR, mode);
+ }
+ else if (add)
+ {
+ ci->RemoveMLock(cm->Name);
+
+ if (cm->Type == MODE_PARAM)
+ {
+ if (paramcount >= params.size())
+ continue;
+
+ std::string param = params[paramcount].c_str();
+
+ ChannelModeParam *cmp = dynamic_cast<ChannelModeParam *>(cm);
+
+ if (!cmp || !cmp->IsValid(param))
+ continue;
+
+ ci->SetMLock(cmp->Name, true, param);
+ }
+ else
+ {
+ ci->SetMLock(cm->Name, true);
+ }
+ }
+ else
+ {
+ ci->SetMLock(cm->Name, false);
+ }
+ }
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_UNKNOWN_CHAR, mode);
+ } /* while (*modes) */
+
+ if (ModeManager::FindChannelModeByName(CMODE_REDIRECT))
+ {
+ /* We can't mlock +L if +l is not mlocked as well. */
+ if (ci->HasMLock(CMODE_REDIRECT, true) && !ci->HasMLock(CMODE_LIMIT, true))
+ {
+ ci->RemoveMLock(CMODE_REDIRECT);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_L_REQUIRED);
+ }
+ }
+
+ /* Some ircd we can't set NOKNOCK without INVITE */
+ /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */
+ if (ModeManager::FindChannelModeByName(CMODE_NOKNOCK) && ircd->knock_needs_i)
+ {
+ if (ci->HasMLock(CMODE_NOKNOCK, true) && !ci->HasMLock(CMODE_INVITE, true))
+ {
+ ci->RemoveMLock(CMODE_NOKNOCK);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_K_REQUIRED);
+ }
+ }
+
+ /* Since we always enforce mode r there is no way to have no
+ * mode lock at all.
+ */
+ if (get_mlock_modes(ci, 0)) {
+ notice_lang(Config.s_ChanServ, u, CHAN_MLOCK_CHANGED, ci->name.c_str(), get_mlock_modes(ci, 0));
+ }
+
+ /* Implement the new lock. */
+ if (ci->c)
+ check_modes(ci->c);
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_MLOCK, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_MLOCK);
+ }
+};
+
+class CommandCSSASetMLock : public CommandCSSetMLock
+{
+ public:
+ CommandCSSASetMLock(const ci::string &cname) : CommandCSSetMLock(cname, "chanserv/saset/mlock")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_MLOCK, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetMLock : public Module
+{
+ public:
+ CSSetMLock(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetMLock("MLOCK"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetMLock("MLOCK"));
+ }
+
+ ~CSSetMLock()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("MLOCK");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("MLOCK");
+ }
+};
+
+MODULE_INIT(CSSetMLock)
diff --git a/src/core/cs_set_opnotice.cpp b/src/core/cs_set_opnotice.cpp
new file mode 100644
index 000000000..b889869bd
--- /dev/null
+++ b/src/core/cs_set_opnotice.cpp
@@ -0,0 +1,112 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetOpNotice : public Command
+{
+ public:
+ CommandCSSetOpNotice(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_OPNOTICE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_OPNOTICE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "OPNOTICE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_OPNOTICE, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET OPNOTICE", CHAN_SET_OPNOTICE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_OPNOTICE);
+ }
+};
+
+class CommandCSSASetOpNotice : public CommandCSSetOpNotice
+{
+ public:
+ CommandCSSASetOpNotice(const ci::string &cname) : CommandCSSetOpNotice(cname, "chanserv/saset/opnotice")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_OPNOTICE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET OPNOTICE", CHAN_SASET_OPNOTICE_SYNTAX);
+ }
+};
+
+class CSSetOpNotice : public Module
+{
+ public:
+ CSSetOpNotice(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetOpNotice("OPNOTICE"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetOpNotice("OPNOTICE"));
+ }
+
+ ~CSSetOpNotice()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("OPNOTICE");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("OPNOTICE");
+ }
+};
+
+MODULE_INIT(CSSetOpNotice)
diff --git a/src/core/cs_set_peace.cpp b/src/core/cs_set_peace.cpp
new file mode 100644
index 000000000..05cf5f863
--- /dev/null
+++ b/src/core/cs_set_peace.cpp
@@ -0,0 +1,114 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetPeace : public Command
+{
+ public:
+ CommandCSSetPeace(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_PEACE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_PEACE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_OFF, ci->name.c_str());
+ }
+ else
+ {
+ this->OnSyntaxError(u, "PEACE");
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PEACE, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET PEACE", CHAN_SET_PEACE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_PEACE, "SET");
+ }
+};
+
+class CommandCSSASetPeace : public CommandCSSetPeace
+{
+ public:
+ CommandCSSASetPeace(const ci::string &cname) : CommandCSSetPeace(cname, "chanserv/saset/peace")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PEACE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET PEACE", CHAN_SASET_PEACE_SYNTAX);
+ }
+};
+
+class CSSetPeace : public Module
+{
+ public:
+ CSSetPeace(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetPeace("PEACE"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetPeace("PEACE"));
+ }
+
+ ~CSSetPeace()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("PEACE");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("PEACE");
+ }
+};
+
+MODULE_INIT(CSSetPeace)
diff --git a/src/core/cs_set_persist.cpp b/src/core/cs_set_persist.cpp
new file mode 100644
index 000000000..0e713c715
--- /dev/null
+++ b/src/core/cs_set_persist.cpp
@@ -0,0 +1,163 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetPersist : public Command
+{
+ public:
+ CommandCSSetPersist(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM);
+
+ if (params[0] == "ON")
+ {
+ if (!ci->HasFlag(CI_PERSIST))
+ {
+ ci->SetFlag(CI_PERSIST);
+
+ /* Channel doesn't exist, create it internally */
+ if (!ci->c)
+ {
+ new Channel(ci->name);
+ if (ci->bi)
+ bot_join(ci);
+ }
+
+ /* No botserv bot, no channel mode */
+ if (!ci->bi && !cm)
+ {
+ /* Give them ChanServ
+ * Yes, this works fine with no Config.s_BotServ
+ */
+ ChanServ->Assign(NULL, ci);
+ }
+
+ /* Set the perm mode */
+ if (cm && ci->c && !ci->c->HasMode(CMODE_PERM))
+ {
+ ci->c->SetMode(NULL, cm);
+ }
+ }
+
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_ON, ci->name.c_str());
+ }
+ else if (params[0] == "OFF")
+ {
+ if (ci->HasFlag(CI_PERSIST))
+ {
+ ci->UnsetFlag(CI_PERSIST);
+
+ /* Unset perm mode */
+ if (cm && ci->c && ci->c->HasMode(CMODE_PERM))
+ ci->c->RemoveMode(NULL, cm);
+ if (Config.s_BotServ && ci->bi && ci->c->users.size() == Config.BSMinUsers - 1)
+ ircdproto->SendPart(ci->bi, ci->c, NULL);
+
+ /* No channel mode, no BotServ, but using ChanServ as the botserv bot
+ * which was assigned when persist was set on
+ */
+ if (!cm && !Config.s_BotServ && ci->bi)
+ {
+ /* Unassign bot */
+ ChanServ->UnAssign(NULL, ci);
+ }
+
+ if (ci->c && ci->c->users.empty())
+ delete ci->c;
+ }
+
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "PERSIST");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PERSIST, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET PERSIST", CHAN_SET_PERSIST_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_PERSIST);
+ }
+};
+
+class CommandCSSASetPersist : public CommandCSSetPersist
+{
+ public:
+ CommandCSSASetPersist(const ci::string &cname) : CommandCSSetPersist(cname, "chanserv/saset/persist")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PERSIST, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET PERSIST", CHAN_SASET_PERSIST_SYNTAX);
+ }
+};
+
+class CSSetPersist : public Module
+{
+ public:
+ CSSetPersist(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetPersist("PERSIST"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetPersist("PERSIST"));
+ }
+
+ ~CSSetPersist()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("PERSIST");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("PERSIST");
+ }
+};
+
+MODULE_INIT(CSSetPersist)
diff --git a/src/core/cs_set_private.cpp b/src/core/cs_set_private.cpp
new file mode 100644
index 000000000..9f96828df
--- /dev/null
+++ b/src/core/cs_set_private.cpp
@@ -0,0 +1,112 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetPrivate : public Command
+{
+ public:
+ CommandCSSetPrivate(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_PRIVATE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_PRIVATE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "PRIVATE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PRIVATE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET PRIVATE", CHAN_SET_PRIVATE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_PRIVATE);
+ }
+};
+
+class CommandCSSASetPrivate : public CommandCSSetPrivate
+{
+ public:
+ CommandCSSASetPrivate(const ci::string &cname) : CommandCSSetPrivate(cname, "chanserv/saset/private")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PRIVATE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET PRIVATE", CHAN_SASET_PRIVATE_SYNTAX);
+ }
+};
+
+class CSSetPrivate : public Module
+{
+ public:
+ CSSetPrivate(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetPrivate("PRIVATE"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetPrivate("PRIVATE"));
+ }
+
+ ~CSSetPrivate()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("PRIVATE");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("PRIVATE");
+ }
+};
+
+MODULE_INIT(CSSetPrivate)
diff --git a/src/core/cs_set_restricted.cpp b/src/core/cs_set_restricted.cpp
new file mode 100644
index 000000000..7e0cc42b3
--- /dev/null
+++ b/src/core/cs_set_restricted.cpp
@@ -0,0 +1,116 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetRestricted : public Command
+{
+ public:
+ CommandCSSetRestricted(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_RESTRICTED);
+ if (ci->levels[CA_NOJOIN] < 0)
+ ci->levels[CA_NOJOIN] = 0;
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_RESTRICTED);
+ if (ci->levels[CA_NOJOIN] >= 0)
+ ci->levels[CA_NOJOIN] = -2;
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "RESTRICTED");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_RESTRICTED, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET RESTRICTED", CHAN_SET_RESTRICTED_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_RESTRICTED);
+ }
+};
+
+class CommandCSSASetRestricted : public CommandCSSetRestricted
+{
+ public:
+ CommandCSSASetRestricted(const ci::string &cname) : CommandCSSetRestricted(cname, "chanserv/saset/restricted")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_RESTRICTED, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET RESTRICTED", CHAN_SASET_RESTRICTED_SYNTAX);
+ }
+};
+
+class CSSetRestricted : public Module
+{
+ public:
+ CSSetRestricted(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetRestricted("RESTRICTED"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetRestricted("RESTRICTED"));
+ }
+
+ ~CSSetRestricted()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("RESTRICTED");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("RESTRICTED");
+ }
+};
+
+MODULE_INIT(CSSetRestricted)
diff --git a/src/core/cs_set_secure.cpp b/src/core/cs_set_secure.cpp
new file mode 100644
index 000000000..bdcffdb21
--- /dev/null
+++ b/src/core/cs_set_secure.cpp
@@ -0,0 +1,112 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetSecure : public Command
+{
+ public:
+ CommandCSSetSecure(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_SECURE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_SECURE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "SECURE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECURE, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET SECURE", CHAN_SET_SECURE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SECURE);
+ }
+};
+
+class CommandCSSASetSecure : public CommandCSSetSecure
+{
+ public:
+ CommandCSSASetSecure(const ci::string &cname) : CommandCSSetSecure(cname, "chanserv/saset/secure")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECURE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET SECURE", CHAN_SASET_SECURE_SYNTAX);
+ }
+};
+
+class CSSetSecure : public Module
+{
+ public:
+ CSSetSecure(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSecure("SECURE"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetSecure("SECURE"));
+ }
+
+ ~CSSetSecure()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("SECURE");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("SECURE");
+ }
+};
+
+MODULE_INIT(CSSetSecure)
diff --git a/src/core/cs_set_securefounder.cpp b/src/core/cs_set_securefounder.cpp
new file mode 100644
index 000000000..9d4a99d20
--- /dev/null
+++ b/src/core/cs_set_securefounder.cpp
@@ -0,0 +1,118 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetSecureFounder : public Command
+{
+ public:
+ CommandCSSetSecureFounder(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (this->permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_SECUREFOUNDER);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_SECUREFOUNDER);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "SECUREFOUNDER");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREFOUNDER, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET SECUREFOUNDER", CHAN_SET_SECUREFOUNDER_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SECUREFOUNDER);
+ }
+};
+
+class CommandCSSASetSecureFounder : public CommandCSSetSecureFounder
+{
+ public:
+ CommandCSSASetSecureFounder(const ci::string &cname) : CommandCSSetSecureFounder(cname, "chanserv/saset/securefounder")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREFOUNDER, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET SECUREFOUNDER", CHAN_SASET_SECUREFOUNDER_SYNTAX);
+ }
+};
+
+class CSSetSecureFounder : public Module
+{
+ public:
+ CSSetSecureFounder(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSecureFounder("SECUREFOUNDER"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetSecureFounder("SECUREFOUNDER"));
+ }
+
+ ~CSSetSecureFounder()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("SECUREFOUNDER");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("SECUREFOUNDER");
+ }
+};
+
+MODULE_INIT(CSSetSecureFounder)
diff --git a/src/core/cs_set_secureops.cpp b/src/core/cs_set_secureops.cpp
new file mode 100644
index 000000000..dc510f71a
--- /dev/null
+++ b/src/core/cs_set_secureops.cpp
@@ -0,0 +1,112 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetSecureOps : public Command
+{
+ public:
+ CommandCSSetSecureOps(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_SECUREOPS);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_SECUREOPS);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "SECUREOPS");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREOPS, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET SECUREOPS", CHAN_SET_SECUREOPS_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SECUREOPS);
+ }
+};
+
+class CommandCSSASetSecureOps : public CommandCSSetSecureOps
+{
+ public:
+ CommandCSSASetSecureOps(const ci::string &cname) : CommandCSSetSecureOps(cname, "chanserv/saset/secureops")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREOPS, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET SECUREOPS", CHAN_SASET_SECUREOPS_SYNTAX);
+ }
+};
+
+class CSSetSecureOps : public Module
+{
+ public:
+ CSSetSecureOps(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSecureOps("SECUREOPS"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetSecureOps("SECUREOPS"));
+ }
+
+ ~CSSetSecureOps()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("SECUREOPS");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("SECUREOPS");
+ }
+};
+
+MODULE_INIT(CSSetSecureOps)
diff --git a/src/core/cs_set_signkick.cpp b/src/core/cs_set_signkick.cpp
new file mode 100644
index 000000000..2e24f8d38
--- /dev/null
+++ b/src/core/cs_set_signkick.cpp
@@ -0,0 +1,112 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetSignKick : public Command
+{
+ public:
+ CommandCSSetSignKick(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_SIGNKICK);
+ ci->UnsetFlag(CI_SIGNKICK_LEVEL);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_ON, ci->name.c_str());
+ }
+ else if (params[1] == "LEVEL")
+ {
+ ci->SetFlag(CI_SIGNKICK_LEVEL);
+ ci->UnsetFlag(CI_SIGNKICK);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_LEVEL, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_SIGNKICK);
+ ci->UnsetFlag(CI_SIGNKICK_LEVEL);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "SIGNKICK");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SIGNKICK, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET SIGNKICK", CHAN_SET_SIGNKICK_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SIGNKICK);
+ }
+};
+
+class CommandCSSASetSignKick : public CommandCSSetSignKick
+{
+ public:
+ CommandCSSASetSignKick(const ci::string &cname) : CommandCSSetSignKick(cname, "chanserv/saset/signkick")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SIGNKICK, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET SIGNKICK", CHAN_SASET_SIGNKICK_SYNTAX);
+ }
+};
+
+class CSSetSignKick : public Module
+{
+ public:
+ CSSetSignKick(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSignKick("SIGNKICK"));
+ }
+
+ ~CSSetSignKick()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("SIGNKICK");
+ }
+};
+
+MODULE_INIT(CSSetSignKick)
diff --git a/src/core/cs_set_successor.cpp b/src/core/cs_set_successor.cpp
new file mode 100644
index 000000000..3de30631a
--- /dev/null
+++ b/src/core/cs_set_successor.cpp
@@ -0,0 +1,145 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetSuccessor : public Command
+{
+ public:
+ CommandCSSetSuccessor(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (this->permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+
+ NickCore *nc;
+
+ if (params.size() > 1)
+ {
+ NickAlias *na = findnick(params[1]);
+
+ if (!na)
+ {
+ notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, params[1].c_str());
+ return MOD_CONT;
+ }
+ if (na->HasFlag(NS_FORBIDDEN))
+ {
+ notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, na->nick);
+ return MOD_CONT;
+ }
+ if (na->nc == ci->founder)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_IS_FOUNDER, na->nick, ci->name.c_str());
+ return MOD_CONT;
+ }
+ nc = na->nc;
+
+ }
+ else
+ nc = NULL;
+
+ Alog() << Config.s_ChanServ << ": Changing successor of " << ci->name << " from "
+ << (ci->successor ? ci->successor->display : "none")
+ << " to " << (nc ? nc->display : "none") << " by " << u->GetMask();
+
+ ci->successor = nc;
+
+ if (nc)
+ notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_CHANGED, ci->name.c_str(), nc->display);
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_UNSET, ci->name.c_str());
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SUCCESSOR, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SUCCESSOR);
+ }
+};
+
+class CommandCSSASetSuccessor : public CommandCSSetSuccessor
+{
+ public:
+ CommandCSSASetSuccessor(const ci::string &cname) : CommandCSSetSuccessor(cname, "chanserv/saset/successor")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SUCCESSOR, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASEt", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetSuccessor : public Module
+{
+ public:
+ CSSetSuccessor(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSuccessor("SUCCESSOR"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSuccessor("SUCCESSOR"));
+ }
+
+ ~CSSetSuccessor()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("SUCCESSOR");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("SUCCESSOR");
+ }
+};
+
+MODULE_INIT(CSSetSuccessor)
diff --git a/src/core/cs_set_topiclock.cpp b/src/core/cs_set_topiclock.cpp
new file mode 100644
index 000000000..14934f551
--- /dev/null
+++ b/src/core/cs_set_topiclock.cpp
@@ -0,0 +1,112 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetTopicLock : public Command
+{
+ public:
+ CommandCSSetTopicLock(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_TOPICLOCK);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_TOPICLOCK);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "TOPICLOCK");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TOPICLOCK, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_TOPICLOCK_SYNTAX);;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_TOPICLOCK);
+ }
+};
+
+class CommandCSSASetTopicLock : public CommandCSSetTopicLock
+{
+ public:
+ CommandCSSASetTopicLock(const ci::string &cname) : CommandCSSetTopicLock(cname, "chanserv/saset/topiclock")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TOPICLOCK, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_TOPICLOCK_SYNTAX);
+ }
+};
+
+class CSSetTopicLock : public Module
+{
+ public:
+ CSSetTopicLock(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetTopicLock("TOPICLOCK"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetTopicLock("TOPICLOCK"));
+ }
+
+ ~CSSetTopicLock()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("TOPICLOCK");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("TOPICLOCK");
+ }
+};
+
+MODULE_INIT(CSSetTopicLock)
diff --git a/src/core/cs_set_url.cpp b/src/core/cs_set_url.cpp
new file mode 100644
index 000000000..06c49da4f
--- /dev/null
+++ b/src/core/cs_set_url.cpp
@@ -0,0 +1,114 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetURL : public Command
+{
+ public:
+ CommandCSSetURL(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (ci->url)
+ delete [] ci->url;
+ if (params.size() > 1)
+ {
+ ci->url = sstrdup(params[1].c_str());
+ notice_lang(Config.s_ChanServ, u, CHAN_URL_CHANGED, ci->name.c_str(), ci->url);
+ }
+ else
+ {
+ ci->url = NULL;
+ notice_lang(Config.s_ChanServ, u, CHAN_URL_UNSET, ci->name.c_str());
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_URL, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_URL);
+ }
+};
+
+class CommandCSSASetURL : public CommandCSSetURL
+{
+ public:
+ CommandCSSASetURL(const ci::string &cname) : CommandCSSetURL(cname, "chanserv/saset/url")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_URL, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET URL", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetURL : public Module
+{
+ public:
+ CSSetURL(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetURL("URL"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetURL("URL"));
+ }
+
+ ~CSSetURL()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("URL");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("URL");
+ }
+};
+
+MODULE_INIT(CSSetURL)
diff --git a/src/core/cs_set_xop.cpp b/src/core/cs_set_xop.cpp
new file mode 100644
index 000000000..398cf4c1b
--- /dev/null
+++ b/src/core/cs_set_xop.cpp
@@ -0,0 +1,144 @@
+/* ChanServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+#define CHECKLEV(lev) ((ci->levels[(lev)] != ACCESS_INVALID) && (access->level >= ci->levels[(lev)]))
+
+class CommandCSSetXOP : public Command
+{
+ public:
+ CommandCSSetXOP(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (!FindModule("cs_xop"))
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_XOP_NOT_AVAILABLE, "XOP");
+ return MOD_CONT;
+ }
+
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ if (!ci->HasFlag(CI_XOP))
+ {
+ ChanAccess *access;
+
+ for (unsigned i = ci->GetAccessCount() - 1; 0 <= i; --i)
+ {
+ access = ci->GetAccess(i);
+
+ /* This will probably cause wrong levels to be set, but hey,
+ * it's better than losing it altogether.
+ */
+ if (access->level == ACCESS_QOP)
+ access->level = ACCESS_QOP;
+ else if (CHECKLEV(CA_AKICK) || CHECKLEV(CA_SET))
+ access->level = ACCESS_SOP;
+ else if (CHECKLEV(CA_AUTOOP) || CHECKLEV(CA_OPDEOP) || CHECKLEV(CA_OPDEOPME))
+ access->level = ACCESS_AOP;
+ else if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && (CHECKLEV(CA_AUTOHALFOP) || CHECKLEV(CA_HALFOP)
+|| CHECKLEV(CA_HALFOPME)))
+ access->level = ACCESS_HOP;
+ else if (CHECKLEV(CA_AUTOVOICE) || CHECKLEV(CA_VOICE) || CHECKLEV(CA_VOICEME))
+ access->level = ACCESS_VOP;
+ else
+ ci->EraseAccess(i);
+ }
+
+ reset_levels(ci);
+ ci->SetFlag(CI_XOP);
+ }
+
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " enabled XOP for " << ci->name;
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_XOP);
+
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled XOP for " << ci->name;
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "XOP");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_XOP, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET XOP", CHAN_SET_XOP_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_XOP);
+ }
+};
+
+class CommandCSSASetXOP : public CommandCSSetXOP
+{
+ public:
+ CommandCSSASetXOP(const ci::string &cname) : CommandCSSetXOP(cname, "chanserv/saset/xop")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_XOP, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET XOP", CHAN_SASET_XOP_SYNTAX);
+ }
+};
+
+class CSSetXOP : public Module
+{
+ public:
+ CSSetXOP(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetXOP("XOP"));
+ }
+
+ ~CSSetXOP()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("XOP");
+ }
+};
+
+MODULE_INIT(CSSetXOP)
diff --git a/src/core/cs_status.c b/src/core/cs_status.cpp
index 18d175f34..174d1a2d8 100644
--- a/src/core/cs_status.c
+++ b/src/core/cs_status.cpp
@@ -55,6 +55,11 @@ class CommandCSStatus : public Command
{
syntax_error(Config.s_ChanServ, u, "STATUS", CHAN_STATUS_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_STATUS);
+ }
};
class CSStatus : public Module
@@ -65,14 +70,6 @@ class CSStatus : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
-
- this->AddCommand(CHANSERV, new CommandCSStatus());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_STATUS);
}
};
diff --git a/src/core/cs_suspend.c b/src/core/cs_suspend.cpp
index 39b1f9fd5..6931fb62b 100644
--- a/src/core/cs_suspend.c
+++ b/src/core/cs_suspend.cpp
@@ -59,7 +59,7 @@ class CommandCSSuspend : public Command
if (reason)
ci->forbidreason = sstrdup(reason);
- if ((c = findchan(ci->name.c_str())))
+ if ((c = findchan(ci->name)))
{
for (CUserList::iterator it = c->users.begin(); it != c->users.end();)
{
@@ -73,7 +73,7 @@ class CommandCSSuspend : public Command
}
if (Config.WallForbid)
- ircdproto->SendGlobops(findbot(Config.s_ChanServ), "\2%s\2 used SUSPEND on channel \2%s\2", u->nick.c_str(), ci->name.c_str());
+ ircdproto->SendGlobops(ChanServ, "\2%s\2 used SUSPEND on channel \2%s\2", u->nick.c_str(), ci->name.c_str());
Alog() << Config.s_ChanServ << ": " << u->GetMask() << " set SUSPEND for channel " << ci->name;
notice_lang(Config.s_ChanServ, u, CHAN_SUSPEND_SUCCEEDED, chan);
@@ -98,6 +98,11 @@ class CommandCSSuspend : public Command
{
syntax_error(Config.s_ChanServ, u, "SUSPEND", Config.ForceForbidReason ? CHAN_SUSPEND_SYNTAX_REASON : CHAN_SUSPEND_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SUSPEND);
+ }
};
class CommandCSUnSuspend : public Command
@@ -143,7 +148,7 @@ class CommandCSUnSuspend : public Command
}
if (Config.WallForbid)
- ircdproto->SendGlobops(findbot(Config.s_ChanServ), "\2%s\2 used UNSUSPEND on channel \2%s\2", u->nick.c_str(), ci->name.c_str());
+ ircdproto->SendGlobops(ChanServ, "\2%s\2 used UNSUSPEND on channel \2%s\2", u->nick.c_str(), ci->name.c_str());
Alog() << Config.s_ChanServ << ": " << u->GetMask() << " set UNSUSPEND for channel " << ci->name;
notice_lang(Config.s_ChanServ, u, CHAN_UNSUSPEND_SUCCEEDED, chan);
@@ -168,6 +173,11 @@ class CommandCSUnSuspend : public Command
{
syntax_error(Config.s_ChanServ, u, "UNSUSPEND", CHAN_UNSUSPEND_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_UNSUSPEND);
+ }
};
class CSSuspend : public Module
@@ -179,15 +189,8 @@ class CSSuspend : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSSuspend());
- this->AddCommand(CHANSERV, new CommandCSUnSuspend());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SUSPEND);
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_UNSUSPEND);
+ this->AddCommand(ChanServ, new CommandCSSuspend());
+ this->AddCommand(ChanServ, new CommandCSUnSuspend());
}
};
diff --git a/src/core/cs_topic.c b/src/core/cs_topic.cpp
index da41e0ac3..9e62fe681 100644
--- a/src/core/cs_topic.c
+++ b/src/core/cs_topic.cpp
@@ -55,14 +55,14 @@ class CommandCSTopic : public Command
if (!check_access(u, ci, CA_TOPIC))
Alog() << Config.s_NickServ << ": " << u->GetMask() << " changed topic of " << c->name << " as services admin.";
- if (ircd->join2set && whosends(ci) == findbot(Config.s_ChanServ))
+ if (ircd->join2set && whosends(ci) == ChanServ)
{
- ircdproto->SendJoin(findbot(Config.s_ChanServ), c->name.c_str(), c->creation_time);
+ ircdproto->SendJoin(ChanServ, c->name.c_str(), c->creation_time);
ircdproto->SendMode(NULL, c, "+o %s", Config.s_ChanServ);
}
ircdproto->SendTopic(whosends(ci), c, u->nick.c_str(), topic ? topic : "");
- if (ircd->join2set && whosends(ci) == findbot(Config.s_ChanServ))
- ircdproto->SendPart(findbot(Config.s_ChanServ), c, NULL);
+ if (ircd->join2set && whosends(ci) == ChanServ)
+ ircdproto->SendPart(ChanServ, c, NULL);
}
return MOD_CONT;
}
@@ -77,6 +77,11 @@ class CommandCSTopic : public Command
{
syntax_error(Config.s_ChanServ, u, "TOPIC", CHAN_TOPIC_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_TOPIC);
+ }
};
class CSTopic : public Module
@@ -88,13 +93,7 @@ class CSTopic : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSTopic());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_TOPIC);
+ this->AddCommand(ChanServ, new CommandCSTopic());
}
};
diff --git a/src/core/cs_unban.c b/src/core/cs_unban.cpp
index aa6184fbb..c361032bf 100644
--- a/src/core/cs_unban.c
+++ b/src/core/cs_unban.cpp
@@ -41,7 +41,7 @@ class CommandCSUnban : public Command
u2 = u;
if (params.size() > 1)
- u2 = finduser(params[1].c_str());
+ u2 = finduser(params[1]);
if (!u2)
{
@@ -67,6 +67,11 @@ class CommandCSUnban : public Command
{
syntax_error(Config.s_ChanServ, u, "UNBAN", CHAN_UNBAN_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_UNBAN);
+ }
};
class CSUnban : public Module
@@ -78,14 +83,7 @@ class CSUnban : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSUnban());
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
-
- void OnChanServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_UNBAN);
+ this->AddCommand(ChanServ, new CommandCSUnban());
}
};
diff --git a/src/core/cs_xop.c b/src/core/cs_xop.cpp
index 702919d8e..4eb8d15f2 100644
--- a/src/core/cs_xop.c
+++ b/src/core/cs_xop.cpp
@@ -14,10 +14,6 @@
#include "module.h"
-int xop_del_callback(User *u, int num, va_list args);
-int xop_list_callback(User *u, int num, va_list args);
-int xop_list(User *u, int index, ChannelInfo *ci, int *sent_header, int xlev, int xmsg);
-
enum
{
XOP_AOP,
@@ -114,6 +110,89 @@ int xop_msgs[XOP_TYPES][XOP_MESSAGES] = {
CHAN_QOP_CLEAR}
};
+class XOPListCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ int level;
+ int *messages;
+ bool SentHeader;
+ public:
+ XOPListCallback(User *_u, ChannelInfo *_ci, const std::string &numlist, int _level, int *_messages) : NumberList(numlist, false), u(_u), ci(_ci), level(_level), messages(_messages), SentHeader(false)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAccessCount())
+ return;
+
+ ChanAccess *access = ci->GetAccess(Number - 1);
+
+ if (level != access->level)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, messages[XOP_LIST_HEADER], ci->name.c_str());
+ }
+
+ DoList(u, ci, access, Number - 1, level, messages);
+ }
+
+ static void DoList(User *u, ChannelInfo *ci, ChanAccess *access, unsigned index, int level, int *messages)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_XOP_LIST_FORMAT, index, access->nc->display);
+ }
+};
+
+class XOPDelCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ int *messages;
+ unsigned Deleted;
+ std::string Nicks;
+ public:
+ XOPDelCallback(User *_u, ChannelInfo *_ci, int *_messages, const std::string &numlist) : NumberList(numlist, true), u(_u), ci(_ci), messages(_messages), Deleted(0)
+ {
+ }
+
+ ~XOPDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_ChanServ, u, messages[XOP_NO_MATCH], ci->name.c_str());
+ else
+ {
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of users " << Nicks << " on " << ci->name;
+
+ if (Deleted == 1)
+ notice_lang(Config.s_ChanServ, u, messages[XOP_DELETED_ONE], ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, messages[XOP_DELETED_SEVERAL], Deleted, ci->name.c_str());
+ }
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAccessCount())
+ return;
+
+ ChanAccess *access = ci->GetAccess(Number - 1);
+
+ ++Deleted;
+ if (!Nicks.empty())
+ Nicks += ", " + std::string(access->nc->display);
+ else
+ Nicks = access->nc->display;
+
+ FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access->nc));
+
+ ci->EraseAccess(Number - 1);
+ }
+};
+
class XOPBase : public Command
{
private:
@@ -178,8 +257,7 @@ class XOPBase : public Command
if (!change)
{
- std::string usernick = u->nick;
- ci->AddAccess(nc, level, usernick);
+ ci->AddAccess(nc, level, u->nick);
}
else
{
@@ -194,12 +272,12 @@ class XOPBase : public Command
if (!change)
{
- FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, na, level));
+ FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level));
notice_lang(Config.s_ChanServ, u, messages[XOP_ADDED], nc->display, ci->name.c_str());
}
else
{
- FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na, level));
+ FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level));
notice_lang(Config.s_ChanServ, u, messages[XOP_MOVED], nc->display, ci->name.c_str());
}
@@ -211,8 +289,6 @@ class XOPBase : public Command
const char *nick = params.size() > 2 ? params[2].c_str() : NULL;
ChanAccess *access;
- int deleted;
-
if (!nick)
{
this->OnSyntaxError(u, "DEL");
@@ -241,26 +317,7 @@ class XOPBase : public Command
/* Special case: is it a number/list? Only do search if it isn't. */
if (isdigit(*nick) && strspn(nick, "1234567890,-") == strlen(nick))
- {
- int count, last = -1, perm = 0;
- deleted = process_numlist(nick, &count, xop_del_callback, u, ci, &last, &perm, ulev, level);
- if (!deleted)
- {
- if (perm)
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else if (count == 1)
- {
- last = atoi(nick);
- notice_lang(Config.s_ChanServ, u, messages[XOP_NO_SUCH_ENTRY], last, ci->name.c_str());
- }
- else
- notice_lang(Config.s_ChanServ, u, messages[XOP_NO_MATCH], ci->name.c_str());
- }
- else if (deleted == 1)
- notice_lang(Config.s_ChanServ, u, messages[XOP_DELETED_ONE], ci->name.c_str());
- else
- notice_lang(Config.s_ChanServ, u, messages[XOP_DELETED_SEVERAL], deleted, ci->name.c_str());
- }
+ (new XOPDelCallback(u, ci, messages, nick))->Process();
else
{
NickAlias *na = findnick(nick);
@@ -270,9 +327,17 @@ class XOPBase : public Command
return MOD_CONT;
}
NickCore *nc = na->nc;
- access = ci->GetAccess(nc, level);
- if (!access)
+ unsigned i;
+ for (i = 0; i < ci->GetAccessCount(); ++i)
+ {
+ access = ci->GetAccess(nc, level);
+
+ if (access->nc == nc)
+ break;
+ }
+
+ if (i == ci->GetAccessCount())
{
notice_lang(Config.s_ChanServ, u, messages[XOP_NOT_FOUND], nick, ci->name.c_str());
return MOD_CONT;
@@ -280,34 +345,25 @@ class XOPBase : public Command
if (ulev <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
{
- deleted = 0;
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
}
else
{
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of user " << access->nc->display << " on " << ci->name;
+
notice_lang(Config.s_ChanServ, u, messages[XOP_DELETED], access->nc->display, ci->name.c_str());
- access->nc = NULL;
- access->in_use = 0;
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc));
- deleted = 1;
+ ci->EraseAccess(i);
}
}
- if (deleted)
- {
- /* If the patch provided in bug #706 is applied, this should be placed
- * before sending the events! */
- /* We'll free the access entries no longer in use... */
- ci->CleanAccess();
- }
return MOD_CONT;
}
CommandReturn DoList(User *u, const std::vector<ci::string> &params, ChannelInfo *ci, int level, int *messages)
{
- int sent_header = 0;
const char *nick = params.size() > 2 ? params[2].c_str() : NULL;
if (!get_access(u, ci) && !u->Account()->HasCommand("chanserv/access/list"))
@@ -323,19 +379,30 @@ class XOPBase : public Command
}
if (nick && strspn(nick, "1234567890,-") == strlen(nick))
- process_numlist(nick, NULL, xop_list_callback, u, ci, &sent_header, level, messages[XOP_LIST_HEADER]);
+ (new XOPListCallback(u, ci, nick, level, messages))->Process();
else
{
+ bool SentHeader = false;
+
for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
{
ChanAccess *access = ci->GetAccess(i);
+
if (nick && access->nc && !Anope::Match(access->nc->display, nick, false))
continue;
- xop_list(u, i, ci, &sent_header, level, messages[XOP_LIST_HEADER]);
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, messages[XOP_LIST_HEADER], ci->name.c_str());
+ }
+
+ XOPListCallback::DoList(u, ci, access, i, level, messages);
}
+
+ if (!SentHeader)
+ notice_lang(Config.s_ChanServ, u, messages[XOP_NO_MATCH], ci->name.c_str());
}
- if (!sent_header)
- notice_lang(Config.s_ChanServ, u, messages[XOP_NO_MATCH], ci->name.c_str());
return MOD_CONT;
}
@@ -354,7 +421,7 @@ class XOPBase : public Command
return MOD_CONT;
}
- if (!IsFounder(u, ci) && !u->Account()->HasPriv("chanserv/access/modify"))
+ if (!check_access(u, ci, CA_FOUNDER) && !u->Account()->HasPriv("chanserv/access/modify"))
{
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
return MOD_CONT;
@@ -363,7 +430,7 @@ class XOPBase : public Command
for (unsigned i = ci->GetAccessCount(); i > 0; --i)
{
ChanAccess *access = ci->GetAccess(i - 1);
- if (access->in_use && access->level == level)
+ if (access->level == level)
ci->EraseAccess(i - 1);
}
@@ -396,7 +463,7 @@ class XOPBase : public Command
return MOD_CONT;
}
public:
- XOPBase(const std::string &command) : Command(command, 2, 3)
+ XOPBase(const ci::string &command) : Command(command, 2, 3)
{
}
@@ -409,6 +476,8 @@ class XOPBase : public Command
virtual bool OnHelp(User *u, const ci::string &subcommand) = 0;
virtual void OnSyntaxError(User *u, const ci::string &subcommand) = 0;
+
+ virtual void OnServHelp(User *u) = 0;
};
class CommandCSQOP : public XOPBase
@@ -433,6 +502,11 @@ class CommandCSQOP : public XOPBase
{
syntax_error(Config.s_ChanServ, u, "QOP", CHAN_QOP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_QOP);
+ }
};
class CommandCSAOP : public XOPBase
@@ -457,6 +531,11 @@ class CommandCSAOP : public XOPBase
{
syntax_error(Config.s_ChanServ, u, "AOP", CHAN_AOP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_AOP);
+ }
};
class CommandCSHOP : public XOPBase
@@ -481,6 +560,11 @@ class CommandCSHOP : public XOPBase
{
syntax_error(Config.s_ChanServ, u, "HOP", CHAN_HOP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_HOP);
+ }
};
class CommandCSSOP : public XOPBase
@@ -505,6 +589,11 @@ class CommandCSSOP : public XOPBase
{
syntax_error(Config.s_ChanServ, u, "SOP", CHAN_SOP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SOP);
+ }
};
class CommandCSVOP : public XOPBase
@@ -529,6 +618,11 @@ class CommandCSVOP : public XOPBase
{
syntax_error(Config.s_ChanServ, u, "VOP", CHAN_VOP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_VOP);
+ }
};
class CSXOP : public Module
@@ -540,111 +634,32 @@ class CSXOP : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(CHANSERV, new CommandCSSOP());
- this->AddCommand(CHANSERV, new CommandCSAOP());
- this->AddCommand(CHANSERV, new CommandCSVOP());
+ this->AddCommand(ChanServ, new CommandCSSOP());
+ this->AddCommand(ChanServ, new CommandCSAOP());
+ this->AddCommand(ChanServ, new CommandCSVOP());
- if (serv_uplink && is_sync(serv_uplink))
- OnUplinkSync();
+ if (Me && Me->IsSynced())
+ OnUplinkSync(NULL);
Implementation i[] = {
- I_OnUplinkSync, I_OnServerDisconnect, I_OnChanServHelp
+ I_OnUplinkSync, I_OnServerDisconnect
};
- ModuleManager::Attach(i, this, 3);
+ ModuleManager::Attach(i, this, 2);
}
- void OnUplinkSync()
+ void OnUplinkSync(Server *)
{
if (ModeManager::FindChannelModeByName(CMODE_OWNER))
- this->AddCommand(CHANSERV, new CommandCSQOP());
+ this->AddCommand(ChanServ, new CommandCSQOP());
if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
- this->AddCommand(CHANSERV, new CommandCSHOP());
+ this->AddCommand(ChanServ, new CommandCSHOP());
}
void OnServerDisconnect()
{
- this->DelCommand(CHANSERV, "QOP");
- this->DelCommand(CHANSERV, "HOP");
- }
-
- void OnChanServHelp(User *u)
- {
- if (ModeManager::FindChannelModeByName(CMODE_OWNER))
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_QOP);
- if (ModeManager::FindChannelModeByName(CMODE_PROTECT))
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SOP);
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_AOP);
- if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_HOP);
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_VOP);
+ this->DelCommand(ChanServ, FindCommand(ChanServ, "QOP"));
+ this->DelCommand(ChanServ, FindCommand(ChanServ, "HOP"));
}
};
-/* `last' is set to the last index this routine was called with
- * `perm' is incremented whenever a permission-denied error occurs
- */
-int xop_del(User *u, ChannelInfo *ci, ChanAccess *access, int *perm, int uacc, int xlev)
-{
- if (!access->in_use || access->level != xlev)
- return 0;
- if (uacc <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
- {
- ++(*perm);
- return 0;
- }
- NickCore *nc = access->nc;
- access->nc = NULL;
- access->in_use = 0;
-
- FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, nc));
-
- return 1;
-}
-
-int xop_del_callback(User *u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *last = va_arg(args, int *);
- int *perm = va_arg(args, int *);
- int uacc = va_arg(args, int);
- int xlev = va_arg(args, int);
-
- if (num < 1 || num > ci->GetAccessCount())
- return 0;
- *last = num;
-
- return xop_del(u, ci, ci->GetAccess(num - 1), perm, uacc, xlev);
-}
-
-
-int xop_list(User *u, int index, ChannelInfo *ci, int *sent_header, int xlev, int xmsg)
-{
- ChanAccess *access = ci->GetAccess(index);
-
- if (!access->in_use || access->level != xlev)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_ChanServ, u, xmsg, ci->name.c_str());
- *sent_header = 1;
- }
-
- notice_lang(Config.s_ChanServ, u, CHAN_XOP_LIST_FORMAT, index + 1, access->nc->display);
- return 1;
-}
-
-int xop_list_callback(User *u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *sent_header = va_arg(args, int *);
- int xlev = va_arg(args, int);
- int xmsg = va_arg(args, int);
-
- if (num < 1 || num > ci->GetAccessCount())
- return 0;
-
- return xop_list(u, num - 1, ci, sent_header, xlev, xmsg);
-}
-
MODULE_INIT(CSXOP)
diff --git a/src/core/db_plain.cpp b/src/core/db_plain.cpp
index 65f936650..98e055ee8 100644
--- a/src/core/db_plain.cpp
+++ b/src/core/db_plain.cpp
@@ -24,6 +24,7 @@ enum MDType
MD_NONE,
MD_NC,
MD_NA,
+ MD_NR,
MD_BI,
MD_CH
};
@@ -39,7 +40,6 @@ static const char endl = '\n';
*/
static void ReadDatabase(Module *m = NULL)
{
- std::string buf;
EventReturn MOD_RESULT;
MDType Type = MD_NONE;
@@ -53,9 +53,11 @@ static void ReadDatabase(Module *m = NULL)
NickCore *nc = NULL;
NickAlias *na = NULL;
+ NickRequest *nr = NULL;
BotInfo *bi = NULL;
ChannelInfo *ci = NULL;
+ std::string buf;
while (std::getline(db, buf))
{
if (buf.empty())
@@ -87,19 +89,23 @@ static void ReadDatabase(Module *m = NULL)
if (MOD_RESULT == EVENT_STOP)
continue;
- std::string mdbuf;
if (!params.empty())
{
if (params[0] == "NC")
{
- nc = findcore(params[1].c_str());
+ nc = findcore(params[1]);
Type = MD_NC;
}
else if (params[0] == "NA")
{
- na = findnick(params[2].c_str());
+ na = findnick(params[2]);
Type = MD_NA;
}
+ else if (params[0] == "NR")
+ {
+ nr = findrequestnick(params[1]);
+ Type = MD_NR;
+ }
else if (params[0] == "BI")
{
bi = findbot(params[1]);
@@ -148,6 +154,22 @@ static void ReadDatabase(Module *m = NULL)
Alog() << "[db_plain]: " << ex.GetReason();
}
}
+ else if (Type == MD_NR && nr)
+ {
+ try
+ {
+ if (m)
+ m->OnDatabaseReadMetadata(nr, key, params);
+ else
+ {
+ FOREACH_RESULT(I_OnDatabaseReadMetadata, OnDatabaseReadMetadata(nr, key, params));
+ }
+ }
+ catch (DatabaseException& ex)
+ {
+ Alog() << "[db_plain]: " << ex.GetReason();
+ }
+ }
else if (Type == MD_BI && bi)
{
try
@@ -198,12 +220,6 @@ struct LangInfo
int LanguageId;
};
-struct ChannelModeInfo
-{
- std::string Name;
- ChannelModeName Value;
-};
-
struct ChannelFlagInfo
{
std::string Name;
@@ -245,42 +261,6 @@ LangInfo LangInfos[] = {
{"", -1}
};
-ChannelModeInfo ChannelModes[] = {
- {"CMODE_BLOCKCOLOR", CMODE_BLOCKCOLOR},
- {"CMODE_FLOOD", CMODE_FLOOD},
- {"CMODE_INVITE", CMODE_INVITE},
- {"CMODE_KEY", CMODE_KEY},
- {"CMODE_LIMIT", CMODE_LIMIT},
- {"CMODE_MODERATED", CMODE_MODERATED},
- {"CMODE_NOEXTERNAL", CMODE_NOEXTERNAL},
- {"CMODE_PRIVATE", CMODE_PRIVATE},
- {"CMODE_REGISTERED", CMODE_REGISTERED},
- {"CMODE_SECRET", CMODE_SECRET},
- {"CMODE_TOPIC", CMODE_TOPIC},
- {"CMODE_AUDITORIUM", CMODE_AUDITORIUM},
- {"CMODE_SSL", CMODE_SSL},
- {"CMODE_ADMINONLY", CMODE_ADMINONLY},
- {"CMODE_NOCTCP", CMODE_NOCTCP},
- {"CMODE_FILTER", CMODE_FILTER},
- {"CMODE_NOKNOCK", CMODE_NOKNOCK},
- {"CMODE_REDIRECT", CMODE_REDIRECT},
- {"CMODE_REGMODERATED", CMODE_REGMODERATED},
- {"CMODE_NONICK", CMODE_NONICK},
- {"CMODE_OPERONLY", CMODE_OPERONLY},
- {"CMODE_NONICK", CMODE_NONICK},
- {"CMODE_REGISTEREDONLY", CMODE_REGISTEREDONLY},
- {"CMODE_STRIPCOLOR", CMODE_STRIPCOLOR},
- {"CMODE_NONOTICE", CMODE_NONOTICE},
- {"CMODE_NOINVITE", CMODE_NOINVITE},
- {"CMODE_ALLINVITE", CMODE_ALLINVITE},
- {"CMODE_BLOCKCAPS", CMODE_BLOCKCAPS},
- {"CMODE_PERM", CMODE_PERM},
- {"CMODE_NICKFLOOD", CMODE_NICKFLOOD},
- {"CMODE_JOINFLOOD", CMODE_JOINFLOOD},
- {"CMODE_NOREJOIN", CMODE_NOREJOIN},
- {"", static_cast<ChannelModeName>(-1)}
-};
-
ChannelFlagInfo ChannelInfoFlags[] = {
{"KEEPTOPIC", CI_KEEPTOPIC},
{"SECUREOPS", CI_SECUREOPS},
@@ -410,7 +390,7 @@ static void LoadNickCore(const std::vector<std::string> &params)
static void LoadNickAlias(const std::vector<std::string> &params)
{
- NickCore *nc = findcore(params[0].c_str());
+ NickCore *nc = findcore(params[0]);
if (!nc)
{
Alog() << "[db_plain]: Unable to find core " << params[0];
@@ -442,11 +422,11 @@ static void LoadBotInfo(const std::vector<std::string> &params)
BotInfo *bi = findbot(params[0]);
if (!bi)
bi = new BotInfo(params[0]);
- bi->user = sstrdup(params[1].c_str());
- bi->host = sstrdup(params[2].c_str());
+ bi->user = params[1];
+ bi->host = params[2];
bi->created = atol(params[3].c_str());
bi->chancount = atol(params[4].c_str());
- bi->real = sstrdup(params[5].c_str());
+ bi->real = params[5];
Alog(LOG_DEBUG_2) << "[db_plain]: Loaded botinfo for " << bi->nick;
}
@@ -478,31 +458,42 @@ static void LoadOperInfo(const std::vector<std::string> &params)
maxusercnt = atol(params[1].c_str());
maxusertime = strtol(params[2].c_str(), NULL, 10);
}
- else if (params[0] == "SGLINE" || params[0] == "SQLINE" || params[0] == "SZLINE")
+ else if (params[0] == "SNLINE" || params[0] == "SQLINE" || params[0] == "SZLINE")
{
- SXLine *sx = new SXLine;
- sx->mask = sstrdup(params[1].c_str());
- sx->by = sstrdup(params[2].c_str());
- sx->seton = atol(params[3].c_str());
- sx->expires = atol(params[4].c_str());
- sx->reason = sstrdup(params[5].c_str());
- if (params[0] == "SGLINE")
- slist_add(&sglines, sx);
- else if (params[0] == "SQLINE")
- slist_add(&sqlines, sx);
- else if (params[0] == "SZLINE")
- slist_add(&szlines, sx);
+ ci::string mask = params[1].c_str();
+ ci::string by = params[2].c_str();
+ time_t seton = atol(params[3].c_str());
+ time_t expires = atol(params[4].c_str());
+ std::string reason = params[5];
+
+ XLine *x = NULL;
+ if (params[0] == "SNLINE" && SNLine)
+ x = SNLine->Add(NULL, NULL, mask, expires, reason);
+ else if (params[0] == "SQLINE" && SQLine)
+ x = SQLine->Add(NULL, NULL, mask, expires, reason);
+ else if (params[0] == "SZLINE" && SZLine)
+ x = SZLine->Add(NULL, NULL, mask, expires, reason);
+ if (x)
+ {
+ x->By = by;
+ x->Created = seton;
+ }
}
- else if (params[0] == "AKILL")
+ else if (params[0] == "AKILL" && SGLine)
{
- Akill *ak = new Akill;
- ak->user = sstrdup(params[1].c_str());
- ak->host = sstrdup(params[2].c_str());
- ak->by = sstrdup(params[3].c_str());
- ak->seton = atol(params[4].c_str());
- ak->expires = atol(params[5].c_str());
- ak->reason = sstrdup(params[6].c_str());
- slist_add(&akills, ak);
+ ci::string user = params[1].c_str();
+ ci::string host = params[2].c_str();
+ ci::string by = params[3].c_str();
+ time_t seton = atol(params[4].c_str());
+ time_t expires = atol(params[5].c_str());
+ std::string reason = params[6];
+
+ XLine *x = SGLine->Add(NULL, NULL, user + "@" + host, expires, reason);
+ if (x)
+ {
+ x->By = by;
+ x->Created = seton;
+ }
}
else if (params[0] == "EXCEPTION")
{
@@ -556,8 +547,7 @@ class DBPlain : public Module
void BackupDatabase()
{
/* Do not backup a database that doesn't exist */
- struct stat DBInfo;
- if (stat(DatabaseFile.c_str(), &DBInfo))
+ if (!IsFile(DatabaseFile))
{
return;
}
@@ -572,7 +562,7 @@ class DBPlain : public Module
snprintf(newname, DatabaseFile.length() + 30, "backups/%s.%d%d%d", DatabaseFile.c_str(), tm->tm_year, tm->tm_mon, tm->tm_mday);
/* Backup already exists */
- if (!stat(newname, &DBInfo))
+ if (IsFile(newname))
{
delete [] newname;
return;
@@ -581,7 +571,7 @@ class DBPlain : public Module
Alog(LOG_DEBUG) << "db_plain: Attemping to rename " << DatabaseFile << " to " << newname;
if (rename(DatabaseFile.c_str(), newname) != 0)
{
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "Unable to backup database!");
+ ircdproto->SendGlobops(OperServ, "Unable to backup database!");
Alog() << "Unable to back up database!";
if (!Config.NoBackupOkay)
@@ -719,20 +709,6 @@ class DBPlain : public Module
{
if (params[j] == "PRIVATE")
bi->SetFlag(BI_PRIVATE);
- else if (params[j] == "CHANSERV")
- bi->SetFlag(BI_CHANSERV);
- else if (params[j] == "BOTSERV")
- bi->SetFlag(BI_BOTSERV);
- else if (params[j] == "HOSTSERV")
- bi->SetFlag(BI_HOSTSERV);
- else if (params[j] == "OPERSERV")
- bi->SetFlag(BI_OPERSERV);
- else if (params[j] == "MEMOSERV")
- bi->SetFlag(BI_MEMOSERV);
- else if (params[j] == "NICKSERV")
- bi->SetFlag(BI_NICKSERV);
- else if (params[j] == "GLOBAL")
- bi->SetFlag(BI_GLOBAL);
}
}
@@ -741,11 +717,9 @@ class DBPlain : public Module
EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const std::string &key, const std::vector<std::string> &params)
{
- int i;
-
if (key == "FOUNDER")
{
- ci->founder = findcore(params[0].c_str());
+ ci->founder = findcore(params[0]);
if (!ci->founder)
{
std::stringstream reason;
@@ -754,18 +728,18 @@ class DBPlain : public Module
}
}
else if (key == "SUCCESSOR")
- ci->successor = findcore(params[0].c_str());
+ ci->successor = findcore(params[0]);
else if (key == "LEVELS")
{
for (unsigned j = 0; j < params.size(); ++j, ++j)
- for (i = 0; ChannelLevels[i].Level != -1; ++i)
+ for (int i = 0; ChannelLevels[i].Level != -1; ++i)
if (ChannelLevels[i].Name == params[j])
ci->levels[ChannelLevels[i].Level] = atoi(params[j + 1].c_str());
}
else if (key == "FLAGS")
{
for (unsigned j = 0; j < params.size(); ++j)
- for (i = 0; ChannelInfoFlags[i].Flag != -1; ++i)
+ for (int i = 0; ChannelInfoFlags[i].Flag != -1; ++i)
if (ChannelInfoFlags[i].Name == params[j])
ci->SetFlag(ChannelInfoFlags[i].Flag);
}
@@ -788,7 +762,7 @@ class DBPlain : public Module
}
else if (key == "ACCESS")
{
- NickCore *nc = findcore(params[0].c_str());
+ NickCore *nc = findcore(params[0]);
if (!nc)
{
std::stringstream reason;
@@ -807,7 +781,7 @@ class DBPlain : public Module
NickCore *nc = NULL;
if (Nick)
{
- nc = findcore(params[2].c_str());
+ nc = findcore(params[2]);
if (!nc)
{
std::stringstream reason;
@@ -830,17 +804,20 @@ class DBPlain : public Module
{
bool Set = key == "MLOCK_ON" ? true : false;
- for (unsigned j = 0; j < params.size(); ++j)
- for (i = 0; ChannelModes[i].Value != -1; ++i)
- if (ChannelModes[i].Name == params[j])
- ci->SetMLock(ChannelModes[i].Value, Set);
+ /* For now store mlock in extensible, Anope hasn't yet connected to the IRCd and doesn't know what modes exist */
+ ci->Extend(Set ? "db_mlock_modes_on" : "db_mlock_modes_off", new ExtensibleItemRegular<std::vector<std::string> >(params));
}
else if (key == "MLP")
{
+ std::vector<std::pair<std::string, std::string> > mlp;
+
for (unsigned j = 0; j < params.size(); ++j, ++j)
- for (i = 0; ChannelModes[i].Value != -1; ++i)
- if (ChannelModes[i].Name == params[j])
- ci->SetMLock(ChannelModes[i].Value, true, params[j + 1]);
+ {
+ mlp.push_back(std::make_pair(params[j], params[j + 1]));
+ }
+
+ /* For now store mlocked modes in extensible, Anope hasn't yet connected to the IRCd and doesn't know what modes exist */
+ ci->Extend("db_mlp", new ExtensibleItemRegular<std::vector<std::pair<std::string, std::string> > >(mlp));
}
else if (key == "MI")
{
@@ -869,7 +846,7 @@ class DBPlain : public Module
else if (params[0] == "FLAGS")
{
for (unsigned j = 1; j < params.size(); ++j)
- for (i = 0; BotFlags[i].Flag != -1; ++i)
+ for (int i = 0; BotFlags[i].Flag != -1; ++i)
if (BotFlags[i].Name == params[j])
ci->botflags.SetFlag(BotFlags[i].Flag);
}
@@ -937,282 +914,295 @@ class DBPlain : public Module
db << "VER 1" << endl;
- int i, j;
- unsigned k;
-
- for (i = 0; i < 1024; ++i)
+ for (nickrequest_map::const_iterator it = NickRequestList.begin(); it != NickRequestList.end(); ++it)
{
- for (NickRequest *nr = nrlists[i]; nr; nr = nr->next)
- {
- db << "NR " << nr->nick << " " << nr->passcode << " " << nr->password << " " << nr->email << " " << nr->requested << endl;
- }
+ NickRequest *nr = it->second;
+
+ db << "NR " << nr->nick << " " << nr->passcode << " " << nr->password << " " << nr->email << " " << nr->requested << endl;
+
+ FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nr));
}
- NickCore *nc;
- for (i = 0; i < 1024; ++i)
+ for (nickcore_map::const_iterator nit = NickCoreList.begin(); nit != NickCoreList.end(); ++nit)
{
- for (nc = nclists[i]; nc; nc = nc->next)
+ NickCore *nc = nit->second;
+
+ if (nc->HasFlag(NI_FORBIDDEN))
{
- if (nc->HasFlag(NI_FORBIDDEN))
- {
- db << "NC " << nc->display << endl;
- db << "MD FLAGS FORBIDDEN" << endl;
- FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nc));
- continue;
- }
- else
- {
- db << "NC " << nc->display << " " << nc->pass << " ";
- }
- for (j = 0; LangInfos[j].LanguageId != -1; ++j)
- if (nc->language == LangInfos[j].LanguageId)
- db << LangInfos[j].Name;
- db << " " << nc->memos.memomax << " " << nc->channelcount << endl;
-
- if (nc->email)
- db << "MD EMAIL " << nc->email << endl;
- if (nc->greet)
- db << "MD GREET :" << nc->greet << endl;
- if (nc->icq)
- db << "MD ICQ :" << nc->icq << endl;
- if (nc->url)
- db << "MD URL :" << nc->url << endl;
- if (!nc->access.empty())
- {
- for (std::vector<std::string>::iterator it = nc->access.begin(); it != nc->access.end(); ++it)
- db << "MD ACCESS " << *it << endl;
- }
- if (nc->FlagCount())
- {
- db << "MD FLAGS";
- for (j = 0; NickCoreFlags[j].Flag != -1; ++j)
- if (nc->HasFlag(NickCoreFlags[j].Flag))
- db << " " << NickCoreFlags[j].Name;
- db << endl;
- }
- if (!nc->memos.memos.empty())
+ db << "NC " << nc->display << endl;
+ db << "MD FLAGS FORBIDDEN" << endl;
+ FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nc));
+ continue;
+ }
+ else
+ {
+ db << "NC " << nc->display << " " << nc->pass << " ";
+ }
+ for (int j = 0; LangInfos[j].LanguageId != -1; ++j)
+ if (nc->language == LangInfos[j].LanguageId)
+ db << LangInfos[j].Name;
+ db << " " << nc->memos.memomax << " " << nc->channelcount << endl;
+
+ if (nc->email)
+ db << "MD EMAIL " << nc->email << endl;
+ if (nc->greet)
+ db << "MD GREET :" << nc->greet << endl;
+ if (nc->icq)
+ db << "MD ICQ :" << nc->icq << endl;
+ if (nc->url)
+ db << "MD URL :" << nc->url << endl;
+ if (!nc->access.empty())
+ {
+ for (std::vector<std::string>::iterator it = nc->access.begin(); it != nc->access.end(); ++it)
+ db << "MD ACCESS " << *it << endl;
+ }
+ if (nc->FlagCount())
+ {
+ db << "MD FLAGS";
+ for (int j = 0; NickCoreFlags[j].Flag != -1; ++j)
+ if (nc->HasFlag(NickCoreFlags[j].Flag))
+ db << " " << NickCoreFlags[j].Name;
+ db << endl;
+ }
+ if (!nc->memos.memos.empty())
+ {
+ MemoInfo *mi = &nc->memos;
+ for (unsigned k = 0; k < mi->memos.size(); ++k)
{
- MemoInfo *mi = &nc->memos;
- for (k = 0; k < mi->memos.size(); ++k)
- {
- db << "MD MI " << mi->memos[k]->number << " " << mi->memos[k]->time << " " << mi->memos[k]->sender;
- if (mi->memos[k]->HasFlag(MF_UNREAD))
- db << " UNREAD";
- if (mi->memos[k]->HasFlag(MF_RECEIPT))
- db << " RECEIPT";
- if (mi->memos[k]->HasFlag(MF_NOTIFYS))
- db << " NOTIFYS";
- db << " :" << mi->memos[k]->text << endl;
- }
+ db << "MD MI " << mi->memos[k]->number << " " << mi->memos[k]->time << " " << mi->memos[k]->sender;
+ if (mi->memos[k]->HasFlag(MF_UNREAD))
+ db << " UNREAD";
+ if (mi->memos[k]->HasFlag(MF_RECEIPT))
+ db << " RECEIPT";
+ if (mi->memos[k]->HasFlag(MF_NOTIFYS))
+ db << " NOTIFYS";
+ db << " :" << mi->memos[k]->text << endl;
}
-
- FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nc));
-
}
+ FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nc));
+
}
- NickAlias *na;
- for (i = 0; i < 1024; ++i)
+ for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it)
{
- for (na = nalists[i]; na; na = na->next)
+ NickAlias *na = it->second;
+
+ db << "NA " << na->nc->display << " " << na->nick << " " << na->time_registered << " " << na->last_seen << endl;
+ if (na->last_usermask)
+ db << "MD LAST_USERMASK " << na->last_usermask << endl;
+ if (na->last_realname)
+ db << "MD LAST_REALNAME :" << na->last_realname << endl;
+ if (na->last_quit)
+ db << "MD LAST_QUIT :" << na->last_quit << endl;
+ if (na->HasFlag(NS_FORBIDDEN) || na->HasFlag(NS_NO_EXPIRE))
{
- db << "NA " << na->nc->display << " " << na->nick << " " << na->time_registered << " " << na->last_seen << endl;
- if (na->last_usermask)
- db << "MD LAST_USERMASK " << na->last_usermask << endl;
- if (na->last_realname)
- db << "MD LAST_REALNAME :" << na->last_realname << endl;
- if (na->last_quit)
- db << "MD LAST_QUIT :" << na->last_quit << endl;
- if (na->HasFlag(NS_FORBIDDEN) || na->HasFlag(NS_NO_EXPIRE))
- {
- db << "MD FLAGS" << (na->HasFlag(NS_FORBIDDEN) ? " FORBIDDEN" : "") << (na->HasFlag(NS_NO_EXPIRE) ? " NOEXPIRE " : "") << endl;
- }
- if (na->hostinfo.HasVhost())
- {
- db << "MD VHOST " << na->hostinfo.GetCreator() << " " << na->hostinfo.GetTime() << " " << na->hostinfo.GetHost() << " :" << na->hostinfo.GetIdent() << endl;
- }
-
- FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, na));
+ db << "MD FLAGS" << (na->HasFlag(NS_FORBIDDEN) ? " FORBIDDEN" : "") << (na->HasFlag(NS_NO_EXPIRE) ? " NOEXPIRE " : "") << endl;
+ }
+ if (na->hostinfo.HasVhost())
+ {
+ db << "MD VHOST " << na->hostinfo.GetCreator() << " " << na->hostinfo.GetTime() << " " << na->hostinfo.GetHost() << " :" << na->hostinfo.GetIdent() << endl;
}
+
+ FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, na));
}
- BotInfo *bi;
- for (i = 0; i < 256; ++i)
+ for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it)
{
- for (bi = botlists[i]; bi; bi = bi->next)
+ BotInfo *bi = it->second;
+
+ db << "BI " << bi->nick << " " << bi->user << " " << bi->host << " " << bi->created << " " << bi->chancount << " :" << bi->real << endl;
+ if (bi->FlagCount())
{
- db << "BI " << bi->nick << " " << bi->user << " " << bi->host << " " << bi->created << " " << bi->chancount << " :" << bi->real << endl;
- if (bi->FlagCount())
- {
- db << "MD FLAGS";
- if (bi->HasFlag(BI_PRIVATE))
- db << " PRIVATE";
- if (bi->HasFlag(BI_CHANSERV))
- db << " CHANSERV";
- else if (bi->HasFlag(BI_BOTSERV))
- db << " BOTSERV";
- else if (bi->HasFlag(BI_HOSTSERV))
- db << " HOSTSERV";
- else if (bi->HasFlag(BI_OPERSERV))
- db << " OPERSERV";
- else if (bi->HasFlag(BI_MEMOSERV))
- db << " MEMOSERV";
- else if (bi->HasFlag(BI_NICKSERV))
- db << " NICKSERV";
- else if (bi->HasFlag(BI_GLOBAL))
- db << " GLOBAL";
- db << endl;
- }
-
- FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, bi));
+ db << "MD FLAGS";
+ if (bi->HasFlag(BI_PRIVATE))
+ db << " PRIVATE";
+ db << endl;
}
}
- ChannelInfo *ci;
- for (i = 0; i < 256; ++i)
+ for (registered_channel_map::const_iterator cit = RegisteredChannelList.begin(); cit != RegisteredChannelList.end(); ++cit)
{
- for (ci = chanlists[i]; ci; ci = ci->next)
+ ChannelInfo *ci = cit->second;
+
+ db << "CH " << ci->name << " " << ci->time_registered << " " << ci->last_used;
+ db << " " << ci->bantype << " " << ci->memos.memomax << endl;
+ if (ci->founder)
+ db << "MD FOUNDER " << ci->founder->display << endl;
+ if (ci->successor)
+ db << "MD SUCCESSOR " << ci->successor->display << endl;
+ if (ci->desc)
+ db << "MD DESC :" << ci->desc << endl;
+ if (ci->url)
+ db << "MD URL :" << ci->url << endl;
+ if (ci->email)
+ db << "MD EMAIL :" << ci->email << endl;
+ if (ci->last_topic)
+ db << "MD TOPIC " << ci->last_topic_setter << " " << ci->last_topic_time << " :" << ci->last_topic << endl;
+ db << "MD LEVELS";
+ for (int j = 0; ChannelLevels[j].Level != -1; ++j)
+ db << " " << ChannelLevels[j].Name << " " << ci->levels[ChannelLevels[j].Level];
+ db << endl;
+ if (ci->FlagCount())
{
- db << "CH " << ci->name << " " << ci->time_registered << " " << ci->last_used;
- db << " " << ci->bantype << " " << ci->memos.memomax << endl;
- if (ci->founder)
- db << "MD FOUNDER " << ci->founder->display << endl;
- if (ci->successor)
- db << "MD SUCCESSOR " << ci->successor->display << endl;
- if (ci->desc)
- db << "MD DESC :" << ci->desc << endl;
- if (ci->url)
- db << "MD URL :" << ci->url << endl;
- if (ci->email)
- db << "MD EMAIL :" << ci->email << endl;
- if (ci->last_topic)
- db << "MD TOPIC " << ci->last_topic_setter << " " << ci->last_topic_time << " :" << ci->last_topic << endl;
- db << "MD LEVELS";
- for (j = 0; ChannelLevels[j].Level != -1; ++j)
- db << " " << ChannelLevels[j].Name << " " << ci->levels[ChannelLevels[j].Level];
+ db << "MD FLAGS";
+ for (int j = 0; ChannelInfoFlags[j].Flag != -1; ++j)
+ if (ci->HasFlag(ChannelInfoFlags[j].Flag))
+ db << " " << ChannelInfoFlags[j].Name;
db << endl;
- if (ci->FlagCount())
- {
- db << "MD FLAGS";
- for (j = 0; ChannelInfoFlags[j].Flag != -1; ++j)
- if (ci->HasFlag(ChannelInfoFlags[j].Flag))
- db << " " << ChannelInfoFlags[j].Name;
- db << endl;
- if (ci->HasFlag(CI_FORBIDDEN))
- db << "MD FORBID " << ci->forbidby << " :" << ci->forbidreason << endl;
- }
- for (k = 0; k < ci->GetAccessCount(); ++k)
- if (ci->GetAccess(k)->in_use)
- db << "MD ACCESS " << ci->GetAccess(k)->nc->display << " " << ci->GetAccess(k)->level << " "
- << ci->GetAccess(k)->last_seen << " " << ci->GetAccess(k)->creator << endl;
- for (k = 0; k < ci->GetAkickCount(); ++k)
- {
- db << "MD AKICK "
- << (ci->GetAkick(k)->HasFlag(AK_STUCK) ? "STUCK " : "UNSTUCK ")
- << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? "NICK " : "MASK ")
- << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? ci->GetAkick(k)->nc->display : ci->GetAkick(k)->mask)
- << " " << ci->GetAkick(k)->creator << " " << ci->GetAkick(k)->addtime
- << " " << ci->last_used << " :";
- if (!ci->GetAkick(k)->reason.empty())
- db << ci->GetAkick(k)->reason;
- db << endl;
- }
- if (ci->GetMLockCount(true))
+ if (ci->HasFlag(CI_FORBIDDEN))
+ db << "MD FORBID " << ci->forbidby << " :" << ci->forbidreason << endl;
+ }
+ for (unsigned k = 0; k < ci->GetAccessCount(); ++k)
+ db << "MD ACCESS " << ci->GetAccess(k)->nc->display << " " << ci->GetAccess(k)->level << " "
+ << ci->GetAccess(k)->last_seen << " " << ci->GetAccess(k)->creator << endl;
+ for (unsigned k = 0; k < ci->GetAkickCount(); ++k)
+ {
+ db << "MD AKICK "
+ << (ci->GetAkick(k)->HasFlag(AK_STUCK) ? "STUCK " : "UNSTUCK ")
+ << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? "NICK " : "MASK ")
+ << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? ci->GetAkick(k)->nc->display : ci->GetAkick(k)->mask)
+ << " " << ci->GetAkick(k)->creator << " " << ci->GetAkick(k)->addtime
+ << " " << ci->last_used << " :";
+ if (!ci->GetAkick(k)->reason.empty())
+ db << ci->GetAkick(k)->reason;
+ db << endl;
+ }
+ if (ci->GetMLockCount(true))
+ {
+ db << "MD MLOCK_ON";
+ for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(); it != ModeManager::Modes.end(); ++it)
{
- db << "MD MLOCK_ON";
- for (j = 0; ChannelModes[j].Value != -1; ++j)
- if (ci->HasMLock(ChannelModes[j].Value, true))
- db << " " << ChannelModes[j].Name;
- db << endl;
+ if ((*it)->Class == MC_CHANNEL)
+ {
+ ChannelMode *cm = dynamic_cast<ChannelMode *>(*it);
+
+ if (ci->HasMLock(cm->Name, true))
+ {
+ db << " " << cm->NameAsString;
+ }
+ }
}
- if (ci->GetMLockCount(false))
+ db << endl;
+ }
+ if (ci->GetMLockCount(false))
+ {
+ db << "MD MLOCK_OFF";
+ for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(); it != ModeManager::Modes.end(); ++it)
{
- db << "MD MLOCK_OFF";
- for (j = 0; ChannelModes[j].Value != -1; ++j)
- if (ci->HasMLock(ChannelModes[j].Value, false))
- db << " " << ChannelModes[j].Name;
- db << endl;
+ if ((*it)->Class == MC_CHANNEL)
+ {
+ ChannelMode *cm = dynamic_cast<ChannelMode *>(*it);
+
+ if (ci->HasMLock(cm->Name, false))
+ {
+ db << " " << cm->NameAsString;
+ }
+ }
}
- std::string Param;
- for (j = 0; ChannelModes[j].Value != -1; ++j)
- if (ci->GetParam(ChannelModes[j].Value, Param))
- db << "MD MLP " << ChannelModes[j].Name << " " << Param << endl;
- if (!ci->memos.memos.empty())
+ db << endl;
+ }
+ std::string Param;
+ for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(); it != ModeManager::Modes.end(); ++it)
+ {
+ if ((*it)->Class == MC_CHANNEL)
{
- MemoInfo *memos = &ci->memos;
+ ChannelMode *cm = dynamic_cast<ChannelMode *>(*it);
- for (k = 0; k < memos->memos.size(); ++k)
+ if (ci->GetParam(cm->Name, Param))
{
- db << "MD MI " << memos->memos[k]->number << " " << memos->memos[k]->time << " " << memos->memos[k]->sender;
- if (memos->memos[k]->HasFlag(MF_UNREAD))
- db << " UNREAD";
- if (memos->memos[k]->HasFlag(MF_RECEIPT))
- db << " RECEIPT";
- if (memos->memos[k]->HasFlag(MF_NOTIFYS))
- db << " NOTIFYS";
- db << " :" << memos->memos[k]->text << endl;
+ db << "MD MLP " << cm->NameAsString << " " << Param << endl;
}
}
- if (ci->entry_message)
- db << "MD ENTRYMSG :" << ci->entry_message << endl;
- if (ci->bi)
- db << "MD BI NAME " << ci->bi->nick << endl;
- if (ci->botflags.FlagCount())
+ }
+ if (!ci->memos.memos.empty())
+ {
+ MemoInfo *memos = &ci->memos;
+
+ for (unsigned k = 0; k < memos->memos.size(); ++k)
{
- db << "MD BI FLAGS";
- for (j = 0; BotFlags[j].Flag != -1; ++j)
- if (ci->botflags.HasFlag(BotFlags[j].Flag))
- db << " " << BotFlags[j].Name;
- db << endl;
+ db << "MD MI " << memos->memos[k]->number << " " << memos->memos[k]->time << " " << memos->memos[k]->sender;
+ if (memos->memos[k]->HasFlag(MF_UNREAD))
+ db << " UNREAD";
+ if (memos->memos[k]->HasFlag(MF_RECEIPT))
+ db << " RECEIPT";
+ if (memos->memos[k]->HasFlag(MF_NOTIFYS))
+ db << " NOTIFYS";
+ db << " :" << memos->memos[k]->text << endl;
}
- db << "MD BI TTB BOLDS " << ci->ttb[0] << " COLORS " << ci->ttb[1] << " REVERSES " << ci->ttb[2] << " UNDERLINES " << ci->ttb[3] << " BADWORDS " << ci->ttb[4] << " CAPS " << ci->ttb[5] << " FLOOD " << ci->ttb[6] << " REPEAT " << ci->ttb[7] << endl;
- if (ci->capsmin)
- db << "MD BI CAPSMIN " << ci->capsmin << endl;
- if (ci->capspercent)
- db << "MD BI CAPSPERCENT " << ci->capspercent << endl;
- if (ci->floodlines)
- db << "MD BI FLOODLINES " << ci->floodlines << endl;
- if (ci->floodsecs)
- db << "MD BI FLOODSECS " << ci->floodsecs << endl;
- if (ci->repeattimes)
- db << "MD BI REPEATTIMES " << ci->repeattimes << endl;
- for (k = 0; k < ci->GetBadWordCount(); ++k)
- db << "MD BI BADWORD "
- << (ci->GetBadWord(k)->type == BW_ANY ? "ANY " : "")
- << (ci->GetBadWord(k)->type == BW_SINGLE ? "SINGLE " : "")
- << (ci->GetBadWord(k)->type == BW_START ? "START " : "")
- << (ci->GetBadWord(k)->type == BW_END ? "END " : "")
- << ":" << ci->GetBadWord(k)->word << endl;
-
- FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, ci));
}
+ if (ci->entry_message)
+ db << "MD ENTRYMSG :" << ci->entry_message << endl;
+ if (ci->bi)
+ db << "MD BI NAME " << ci->bi->nick << endl;
+ if (ci->botflags.FlagCount())
+ {
+ db << "MD BI FLAGS";
+ for (int j = 0; BotFlags[j].Flag != -1; ++j)
+ if (ci->botflags.HasFlag(BotFlags[j].Flag))
+ db << " " << BotFlags[j].Name;
+ db << endl;
+ }
+ db << "MD BI TTB BOLDS " << ci->ttb[0] << " COLORS " << ci->ttb[1] << " REVERSES " << ci->ttb[2] << " UNDERLINES " << ci->ttb[3] << " BADWORDS " << ci->ttb[4] << " CAPS " << ci->ttb[5] << " FLOOD " << ci->ttb[6] << " REPEAT " << ci->ttb[7] << endl;
+ if (ci->capsmin)
+ db << "MD BI CAPSMIN " << ci->capsmin << endl;
+ if (ci->capspercent)
+ db << "MD BI CAPSPERCENT " << ci->capspercent << endl;
+ if (ci->floodlines)
+ db << "MD BI FLOODLINES " << ci->floodlines << endl;
+ if (ci->floodsecs)
+ db << "MD BI FLOODSECS " << ci->floodsecs << endl;
+ if (ci->repeattimes)
+ db << "MD BI REPEATTIMES " << ci->repeattimes << endl;
+ for (unsigned k = 0; k < ci->GetBadWordCount(); ++k)
+ db << "MD BI BADWORD "
+ << (ci->GetBadWord(k)->type == BW_ANY ? "ANY " : "")
+ << (ci->GetBadWord(k)->type == BW_SINGLE ? "SINGLE " : "")
+ << (ci->GetBadWord(k)->type == BW_START ? "START " : "")
+ << (ci->GetBadWord(k)->type == BW_END ? "END " : "")
+ << ":" << ci->GetBadWord(k)->word << endl;
+
+ FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, ci));
}
- for (i = 0; i < akills.count; ++i)
+ db << "OS STATS " << maxusercnt << " " << maxusertime << endl;
+
+ if (SGLine)
{
- Akill *ak = static_cast<Akill *>(akills.list[i]);
- db << "OS AKILL " << ak->user << " " << ak->host << " " << ak->by << " " << ak->seton << " " << ak->expires << " :" << ak->reason << endl;
+ for (unsigned i = 0; i < SGLine->GetCount(); ++i)
+ {
+ XLine *x = SGLine->GetEntry(i);
+ db << "OS AKILL " << x->GetUser() << " " << x->GetHost() << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
+ }
}
- db << "OS STATS " << maxusercnt << " " << maxusertime << endl;
- SXLine *sx;
- for (i = 0; i < sglines.count; ++i)
+ if (SNLine)
{
- sx = static_cast<SXLine *>(sglines.list[i]);
- db << "OS SGLINE " << sx->mask << " " << sx->by << " " << sx->seton << " " << sx->expires << " :" << sx->reason << endl;
+ for (unsigned i = 0; i < SNLine->GetCount(); ++i)
+ {
+ XLine *x = SNLine->GetEntry(i);
+ db << "OS SNLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
+ }
}
- for (i = 0; i < sqlines.count; ++i)
+
+ if (SQLine)
{
- sx = static_cast<SXLine *>(sqlines.list[i]);
- db << "OS SQLINE " << sx->mask << " " << sx->by << " " << sx->seton << " " << sx->expires << " :" << sx->reason << endl;
+ for (unsigned i = 0; i < SQLine->GetCount(); ++i)
+ {
+ XLine *x = SQLine->GetEntry(i);
+ db << "OS SQLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
+ }
}
- for (i = 0; i < szlines.count; ++i)
+
+ if (SZLine)
{
- sx = static_cast<SXLine *>(szlines.list[i]);
- db << "OS SZLINE " << sx->mask << " " << sx->by << " " << sx->seton << " " << sx->expires << " :" << sx->reason << endl;
+ for (unsigned i = 0; i < SZLine->GetCount(); ++i)
+ {
+ XLine *x = SZLine->GetEntry(i);
+ db << "OS SZLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
+ }
}
- for (i = 0; i < nexceptions; i++)
+ for (int i = 0; i < nexceptions; i++)
{
db << "OS EXCEPTION " << exceptions[i].mask << " " << exceptions[i].limit << " " << exceptions[i].who << " " << exceptions[i].time << " " << exceptions[i].expires << " " << exceptions[i].reason << endl;
}
diff --git a/src/core/enc_md5.c b/src/core/enc_md5.cpp
index 1c46ca72b..1c46ca72b 100644
--- a/src/core/enc_md5.c
+++ b/src/core/enc_md5.cpp
diff --git a/src/core/enc_none.c b/src/core/enc_none.cpp
index 280c86bd2..280c86bd2 100644
--- a/src/core/enc_none.c
+++ b/src/core/enc_none.cpp
diff --git a/src/core/enc_old.c b/src/core/enc_old.cpp
index 68eece13c..68eece13c 100644
--- a/src/core/enc_old.c
+++ b/src/core/enc_old.cpp
diff --git a/src/core/enc_sha1.c b/src/core/enc_sha1.cpp
index b4ac2a4e2..b4ac2a4e2 100644
--- a/src/core/enc_sha1.c
+++ b/src/core/enc_sha1.cpp
diff --git a/src/core/enc_sha256.c b/src/core/enc_sha256.cpp
index ef1ed7a00..ef1ed7a00 100644
--- a/src/core/enc_sha256.c
+++ b/src/core/enc_sha256.cpp
diff --git a/src/core/hs_del.c b/src/core/hs_del.cpp
index 286366735..e86db7e81 100644
--- a/src/core/hs_del.c
+++ b/src/core/hs_del.cpp
@@ -52,6 +52,11 @@ class CommandHSDel : public Command
{
syntax_error(Config.s_HostServ, u, "DEL", HOST_DEL_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_DEL);
+ }
};
class HSDel : public Module
@@ -63,13 +68,7 @@ class HSDel : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(HOSTSERV, new CommandHSDel());
-
- ModuleManager::Attach(I_OnHostServHelp, this);
- }
- void OnHostServHelp(User *u)
- {
- notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_DEL);
+ this->AddCommand(HostServ, new CommandHSDel());
}
};
diff --git a/src/core/hs_delall.c b/src/core/hs_delall.cpp
index b40565e3d..97a09a073 100644
--- a/src/core/hs_delall.c
+++ b/src/core/hs_delall.cpp
@@ -23,10 +23,8 @@ class CommandHSDelAll : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- int i;
const char *nick = params[0].c_str();
NickAlias *na;
- NickCore *nc;
if ((na = findnick(nick)))
{
if (na->HasFlag(NS_FORBIDDEN))
@@ -35,10 +33,10 @@ class CommandHSDelAll : public Command
return MOD_CONT;
}
FOREACH_MOD(I_OnDeleteVhost, OnDeleteVhost(na));
- nc = na->nc;
- for (i = 0; i < nc->aliases.count; ++i)
+ NickCore *nc = na->nc;
+ for (std::list<NickAlias *>::iterator it = nc->aliases.begin(); it != nc->aliases.end(); ++it)
{
- na = static_cast<NickAlias *>(nc->aliases.list[i]);
+ na = *it;
na->hostinfo.RemoveVhost();
}
Alog() << "vHosts for all nicks in group \002" << nc->display << "\002 deleted by oper \002" << u->nick << "\002";
@@ -59,6 +57,11 @@ class CommandHSDelAll : public Command
{
syntax_error(Config.s_HostServ, u, "DELALL", HOST_DELALL_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_DELALL);
+ }
};
class HSDelAll : public Module
@@ -70,13 +73,7 @@ class HSDelAll : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(HOSTSERV, new CommandHSDelAll());
-
- ModuleManager::Attach(I_OnHostServHelp, this);
- }
- void OnHostServHelp(User *u)
- {
- notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_DELALL);
+ this->AddCommand(HostServ, new CommandHSDelAll());
}
};
diff --git a/src/core/hs_group.c b/src/core/hs_group.cpp
index e4117ba9c..d71c4088d 100644
--- a/src/core/hs_group.c
+++ b/src/core/hs_group.cpp
@@ -45,6 +45,11 @@ class CommandHSGroup : public Command
notice_help(Config.s_HostServ, u, HOST_HELP_GROUP);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_GROUP);
+ }
};
class HSGroup : public Module
@@ -56,13 +61,7 @@ class HSGroup : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(HOSTSERV, new CommandHSGroup());
-
- ModuleManager::Attach(I_OnHostServHelp, this);
- }
- void OnHostServHelp(User *u)
- {
- notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_GROUP);
+ this->AddCommand(HostServ, new CommandHSGroup());
}
};
diff --git a/src/core/hs_help.c b/src/core/hs_help.cpp
index 0522c09d4..5cc7e5129 100644
--- a/src/core/hs_help.c
+++ b/src/core/hs_help.cpp
@@ -24,14 +24,15 @@ class CommandHSHelp : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- mod_help_cmd(Config.s_HostServ, u, HOSTSERV, params[0].c_str());
+ mod_help_cmd(HostServ, u, params[0].c_str());
return MOD_CONT;
}
void OnSyntaxError(User *u, const ci::string &subcommand)
{
notice_help(Config.s_HostServ, u, HOST_HELP, Config.s_HostServ);
- FOREACH_MOD(I_OnHostServHelp, OnHostServHelp(u));
+ for (CommandMap::const_iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.end(); ++it)
+ it->second->OnServHelp(u);
}
};
@@ -44,7 +45,7 @@ class HSHelp : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(HOSTSERV, new CommandHSHelp());
+ this->AddCommand(HostServ, new CommandHSHelp());
}
};
diff --git a/src/core/hs_list.c b/src/core/hs_list.cpp
index e86f2d0dc..d92822b63 100644
--- a/src/core/hs_list.c
+++ b/src/core/hs_list.cpp
@@ -53,47 +53,46 @@ class CommandHSList : public Command
}
}
- for (int j = 0; j < 1024; ++j)
+ for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it)
{
- for (NickAlias *na = nalists[j]; na; na = na->next)
- {
- if (!na->hostinfo.HasVhost())
- continue;
+ NickAlias *na = it->second;
+
+ if (!na->hostinfo.HasVhost())
+ continue;
- if (!key.empty() && key[0] != '#')
+ if (!key.empty() && key[0] != '#')
+ {
+ if ((Anope::Match(na->nick, key) || Anope::Match(na->hostinfo.GetHost(), key.c_str())) && display_counter < Config.NSListMax)
{
- if ((Anope::Match(na->nick, key) || Anope::Match(na->hostinfo.GetHost(), key.c_str())) && display_counter < Config.NSListMax)
- {
- ++display_counter;
- time_t time = na->hostinfo.GetTime();
- tm = localtime(&time);
- strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm);
- if (!na->hostinfo.GetIdent().empty())
- notice_lang(Config.s_HostServ, u, HOST_IDENT_ENTRY, counter, na->nick, na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf);
- else
- notice_lang(Config.s_HostServ, u, HOST_ENTRY, counter, na->nick, na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf);
- }
+ ++display_counter;
+ time_t time = na->hostinfo.GetTime();
+ tm = localtime(&time);
+ strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm);
+ if (!na->hostinfo.GetIdent().empty())
+ notice_lang(Config.s_HostServ, u, HOST_IDENT_ENTRY, counter, na->nick, na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf);
+ else
+ notice_lang(Config.s_HostServ, u, HOST_ENTRY, counter, na->nick, na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf);
}
- else
+ }
+ else
+ {
+ /**
+ * List the host if its in the display range, and not more
+ * than NSListMax records have been displayed...
+ **/
+ if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config.NSListMax)
{
- /**
- * List the host if its in the display range, and not more
- * than NSListMax records have been displayed...
- **/
- if (((counter >= from && counter <= to) || (!from && !to)) && display_counter < Config.NSListMax)
- {
- ++display_counter;
- time_t time = na->hostinfo.GetTime();
- tm = localtime(&time);
- strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm);
- if (!na->hostinfo.GetIdent().empty())
- notice_lang(Config.s_HostServ, u, HOST_IDENT_ENTRY, counter, na->nick, na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf);
- else
- notice_lang(Config.s_HostServ, u, HOST_ENTRY, counter, na->nick, na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf);
- }
+ ++display_counter;
+ time_t time = na->hostinfo.GetTime();
+ tm = localtime(&time);
+ strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm);
+ if (!na->hostinfo.GetIdent().empty())
+ notice_lang(Config.s_HostServ, u, HOST_IDENT_ENTRY, counter, na->nick, na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf);
+ else
+ notice_lang(Config.s_HostServ, u, HOST_ENTRY, counter, na->nick, na->hostinfo.GetHost().c_str(), na->hostinfo.GetCreator().c_str(), buf);
}
- ++counter;
}
+ ++counter;
}
if (!key.empty())
notice_lang(Config.s_HostServ, u, HOST_LIST_KEY_FOOTER, key.c_str(), display_counter);
@@ -112,6 +111,11 @@ class CommandHSList : public Command
notice_help(Config.s_HostServ, u, HOST_HELP_LIST);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_LIST);
+ }
};
class HSList : public Module
@@ -123,13 +127,7 @@ class HSList : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(HOSTSERV, new CommandHSList());
-
- ModuleManager::Attach(I_OnHostServHelp, this);
- }
- void OnHostServHelp(User *u)
- {
- notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_LIST);
+ this->AddCommand(HostServ, new CommandHSList());
}
};
diff --git a/src/core/hs_off.c b/src/core/hs_off.cpp
index 5943e8850..0a483e2a4 100644
--- a/src/core/hs_off.c
+++ b/src/core/hs_off.cpp
@@ -41,6 +41,11 @@ class CommandHSOff : public Command
notice_help(Config.s_HostServ, u, HOST_HELP_OFF);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_OFF);
+ }
};
class HSOff : public Module
@@ -52,13 +57,7 @@ class HSOff : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(HOSTSERV, new CommandHSOff());
-
- ModuleManager::Attach(I_OnHostServHelp, this);
- }
- void OnHostServHelp(User *u)
- {
- notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_OFF);
+ this->AddCommand(HostServ, new CommandHSOff());
}
};
diff --git a/src/core/hs_on.c b/src/core/hs_on.cpp
index 2194e2d2b..4fd415ead 100644
--- a/src/core/hs_on.c
+++ b/src/core/hs_on.cpp
@@ -55,6 +55,11 @@ class CommandHSOn : public Command
notice_help(Config.s_HostServ, u, HOST_HELP_ON);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_ON);
+ }
};
class HSOn : public Module
@@ -66,13 +71,7 @@ class HSOn : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(HOSTSERV, new CommandHSOn());
-
- ModuleManager::Attach(I_OnHostServHelp, this);
- }
- void OnHostServHelp(User *u)
- {
- notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_ON);
+ this->AddCommand(HostServ, new CommandHSOn());
}
};
diff --git a/src/core/hs_set.c b/src/core/hs_set.cpp
index b382cb0ea..3aeb5c6be 100644
--- a/src/core/hs_set.c
+++ b/src/core/hs_set.cpp
@@ -149,6 +149,11 @@ class CommandHSSet : public Command
{
syntax_error(Config.s_HostServ, u, "SET", HOST_SET_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_SET);
+ }
};
class HSSet : public Module
@@ -160,13 +165,7 @@ class HSSet : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(HOSTSERV, new CommandHSSet());
-
- ModuleManager::Attach(I_OnHostServHelp, this);
- }
- void OnHostServHelp(User *u)
- {
- notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_SET);
+ this->AddCommand(HostServ, new CommandHSSet());
}
};
diff --git a/src/core/hs_setall.c b/src/core/hs_setall.cpp
index 9afb26206..88a47dc9a 100644
--- a/src/core/hs_setall.c
+++ b/src/core/hs_setall.cpp
@@ -147,6 +147,11 @@ class CommandHSSetAll : public Command
{
syntax_error(Config.s_HostServ, u, "SETALL", HOST_SETALL_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_SETALL);
+ }
};
class HSSetAll : public Module
@@ -158,13 +163,7 @@ class HSSetAll : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(HOSTSERV, new CommandHSSetAll());
-
- ModuleManager::Attach(I_OnHostServHelp, this);
- }
- void OnHostServHelp(User *u)
- {
- notice_lang(Config.s_HostServ, u, HOST_HELP_CMD_SETALL);
+ this->AddCommand(HostServ, new CommandHSSetAll());
}
};
diff --git a/src/core/ms_cancel.c b/src/core/ms_cancel.cpp
index c2eeee4c5..4528134fa 100644
--- a/src/core/ms_cancel.c
+++ b/src/core/ms_cancel.cpp
@@ -69,6 +69,11 @@ class CommandMSCancel : public Command
{
syntax_error(Config.s_MemoServ, u, "CANCEL", MEMO_CANCEL_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_CANCEL);
+ }
};
class MSCancel : public Module
@@ -79,13 +84,7 @@ class MSCancel : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSCancel());
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_CANCEL);
+ this->AddCommand(MemoServ, new CommandMSCancel());
}
};
diff --git a/src/core/ms_check.c b/src/core/ms_check.cpp
index 47270a4ab..87d4a4417 100644
--- a/src/core/ms_check.c
+++ b/src/core/ms_check.cpp
@@ -85,6 +85,11 @@ class CommandMSCheck : public Command
{
syntax_error(Config.s_MemoServ, u, "CHECK", MEMO_CHECK_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_CHECK);
+ }
};
class MSCheck : public Module
@@ -95,13 +100,7 @@ class MSCheck : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSCheck());
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_CHECK);
+ this->AddCommand(MemoServ, new CommandMSCheck());
}
};
diff --git a/src/core/ms_del.c b/src/core/ms_del.cpp
index f5c27cc4e..e10b7f3fb 100644
--- a/src/core/ms_del.c
+++ b/src/core/ms_del.cpp
@@ -14,7 +14,33 @@
#include "module.h"
-int del_memo_callback(User *u, int num, va_list args);
+class MemoDelCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ MemoInfo *mi;
+ public:
+ MemoDelCallback(User *_u, ChannelInfo *_ci, MemoInfo *_mi, const std::string &list) : NumberList(list, true), u(_u), ci(_ci), mi(_mi)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > mi->memos.size())
+ return;
+
+ if (ci)
+ {
+ FOREACH_MOD(I_OnMemoDel, OnMemoDel(ci, mi, Number - 1));
+ }
+ else
+ {
+ FOREACH_MOD(I_OnMemoDel, OnMemoDel(u->Account(), mi, Number - 1));
+ }
+
+ delmemo(mi, Number - 1);
+ }
+};
class CommandMSDel : public Command
{
@@ -28,17 +54,15 @@ class CommandMSDel : public Command
MemoInfo *mi;
ChannelInfo *ci = NULL;
ci::string numstr = params.size() ? params[0] : "", chan;
- int last, last0;
unsigned i;
- char buf[BUFSIZE], *end;
- int delcount, count, left;
+ int last;
if (!numstr.empty() && numstr[0] == '#')
{
chan = numstr;
numstr = params.size() > 1 ? params[1] : "";
- if (!(ci = cs_findchan(chan.c_str())))
+ if (!(ci = cs_findchan(chan)))
{
notice_lang(Config.s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan.c_str());
return MOD_CONT;
@@ -71,37 +95,7 @@ class CommandMSDel : public Command
else
{
if (isdigit(numstr[0]))
- {
- /* Delete a specific memo or memos. */
- last = -1; /* Last memo deleted */
- last0 = -1; /* Beginning of range of last memos deleted */
- end = buf;
- left = sizeof(buf);
- delcount = process_numlist(numstr.c_str(), &count, del_memo_callback, u, mi, &last, &last0, &end, &left, ci);
- if (last != -1)
- {
- /* Some memos got deleted; tell them which ones. */
- if (delcount > 1)
- {
- if (last0 != last)
- end += snprintf(end, sizeof(buf) - (end - buf), ",%d-%d", last0, last);
- else
- end += snprintf(end, sizeof(buf) - (end - buf), ",%d", last);
- /* "buf+1" here because *buf == ',' */
- notice_lang(Config.s_MemoServ, u, MEMO_DELETED_SEVERAL, buf + 1);
- }
- else
- notice_lang(Config.s_MemoServ, u, MEMO_DELETED_ONE, last);
- }
- else
- {
- /* No memos were deleted. Tell them so. */
- if (count == 1)
- notice_lang(Config.s_MemoServ, u, MEMO_DOES_NOT_EXIST, atoi(numstr.c_str()));
- else
- notice_lang(Config.s_MemoServ, u, MEMO_DELETED_NONE);
- }
- }
+ (new MemoDelCallback(u, ci, mi, numstr.c_str()))->Process();
else if (numstr == "LAST")
{
/* Delete last memo. */
@@ -158,6 +152,11 @@ class CommandMSDel : public Command
{
syntax_error(Config.s_MemoServ, u, "DEL", MEMO_DEL_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_DEL);
+ }
};
class MSDel : public Module
@@ -168,61 +167,7 @@ class MSDel : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSDel());
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_DEL);
}
};
-/**
- * Delete a single memo from a MemoInfo. callback function
- * @param u User Struct
- * @param int Number
- * @param va_list Variable Arguemtns
- * @return 1 if successful, 0 if it fails
- */
-int del_memo_callback(User *u, int num, va_list args)
-{
- MemoInfo *mi = va_arg(args, MemoInfo *);
- int *last = va_arg(args, int *);
- int *last0 = va_arg(args, int *);
- char **end = va_arg(args, char **);
- int *left = va_arg(args, int *);
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
-
- if (ci)
- {
- FOREACH_MOD(I_OnMemoDel, OnMemoDel(ci, mi, num));
- }
- else
- {
- FOREACH_MOD(I_OnMemoDel, OnMemoDel(u->Account(), mi, num));
- }
- if (delmemo(mi, num))
- {
- if (num != (*last) + 1)
- {
- if (*last != -1)
- {
- int len;
- if (*last0 != *last)
- len = snprintf(*end, *left, ",%d-%d", *last0, *last);
- else
- len = snprintf(*end, *left, ",%d", *last);
- *end += len;
- *left -= len;
- }
- *last0 = num;
- }
- *last = num;
- return 1;
- }
- else
- return 0;
-}
-
MODULE_INIT(MSDel)
diff --git a/src/core/ms_help.c b/src/core/ms_help.cpp
index baa74aa93..2aa837d64 100644
--- a/src/core/ms_help.c
+++ b/src/core/ms_help.cpp
@@ -24,14 +24,15 @@ class CommandMSHelp : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- mod_help_cmd(Config.s_MemoServ, u, MEMOSERV, params[0].c_str());
+ mod_help_cmd(MemoServ, u, params[0].c_str());
return MOD_CONT;
}
void OnSyntaxError(User *u, const ci::string &subcommand)
{
notice_help(Config.s_MemoServ, u, MEMO_HELP_HEADER);
- FOREACH_MOD(I_OnMemoServHelp, OnMemoServHelp(u));
+ for (CommandMap::const_iterator it = NickServ->Commands.begin(); it != NickServ->Commands.end(); ++it)
+ it->second->OnServHelp(u);
notice_help(Config.s_MemoServ, u, MEMO_HELP_FOOTER, Config.s_ChanServ);
}
};
@@ -44,7 +45,7 @@ class MSHelp : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSHelp());
+ this->AddCommand(MemoServ, new CommandMSHelp());
}
};
diff --git a/src/core/ms_info.c b/src/core/ms_info.cpp
index a1066f466..81650d584 100644
--- a/src/core/ms_info.c
+++ b/src/core/ms_info.cpp
@@ -198,6 +198,11 @@ class CommandMSInfo : public Command
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_INFO);
+ }
};
class MSInfo : public Module
@@ -208,13 +213,7 @@ class MSInfo : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSInfo());
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_INFO);
+ this->AddCommand(MemoServ, new CommandMSInfo());
}
};
diff --git a/src/core/ms_list.c b/src/core/ms_list.cpp
index 5e97615ab..088fcdb12 100644
--- a/src/core/ms_list.c
+++ b/src/core/ms_list.cpp
@@ -14,8 +14,46 @@
#include "module.h"
-int list_memo_callback(User *u, int num, va_list args);
-int list_memo(User *u, int index, MemoInfo *mi, int *sent_header, int newi, const char *chan);
+class MemoListCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ MemoInfo *mi;
+ bool SentHeader;
+ public:
+ MemoListCallback(User *_u, ChannelInfo *_ci, MemoInfo *_mi, const std::string &list) : NumberList(list, false), u(_u), ci(_ci), mi(_mi), SentHeader(false)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > mi->memos.size())
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ if (ci)
+ notice_lang(Config.s_MemoServ, u, MEMO_LIST_CHAN_MEMOS, ci->name.c_str(), Config.s_MemoServ, ci->name.c_str());
+ else
+ notice_lang(Config.s_MemoServ, u, MEMO_LIST_MEMOS, u->nick.c_str(), Config.s_MemoServ);
+
+ notice_lang(Config.s_MemoServ, u, MEMO_LIST_HEADER);
+ }
+
+ DoList(u, ci, mi, Number - 1);
+ }
+
+ static void DoList(User *u, ChannelInfo *ci, MemoInfo *mi, unsigned index)
+ {
+ Memo *m = mi->memos[index];
+ struct tm tm = *localtime(&m->time);
+ char timebuf[64];
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm);
+ timebuf[sizeof(timebuf) - 1] = 0; /* just in case */
+ notice_lang(Config.s_MemoServ, u, MEMO_LIST_FORMAT, (m->HasFlag(MF_UNREAD)) ? '*' : ' ', m->number, m->sender.c_str(), timebuf);
+ }
+};
class CommandMSList : public Command
{
@@ -36,7 +74,7 @@ class CommandMSList : public Command
chan = param;
param = params.size() > 1 ? params[1] : "";
- if (!(ci = cs_findchan(chan.c_str())))
+ if (!(ci = cs_findchan(chan)))
{
notice_lang(Config.s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan.c_str());
return MOD_CONT;
@@ -63,9 +101,8 @@ class CommandMSList : public Command
}
else
{
- int sent_header = 0;
if (!param.empty() && isdigit(param[0]))
- process_numlist(param.c_str(), NULL, list_memo_callback, u, mi, &sent_header, chan.empty() ? NULL : chan.c_str());
+ (new MemoListCallback(u, ci, mi, param.c_str()))->Process();
else
{
if (!param.empty())
@@ -84,11 +121,25 @@ class CommandMSList : public Command
return MOD_CONT;
}
}
+
+ bool SentHeader = false;
+
for (i = 0; i < mi->memos.size(); ++i)
{
if (!param.empty() && !(mi->memos[i]->HasFlag(MF_UNREAD)))
continue;
- list_memo(u, i, mi, &sent_header, !param.empty(), chan.empty() ? NULL : chan.c_str());
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ if (ci)
+ notice_lang(Config.s_MemoServ, u, !param.empty() ? MEMO_LIST_CHAN_NEW_MEMOS : MEMO_LIST_CHAN_MEMOS, ci->name.c_str(), Config.s_MemoServ, ci->name.c_str());
+ else
+ notice_lang(Config.s_MemoServ, u, !param.empty() ? MEMO_LIST_NEW_MEMOS : MEMO_LIST_MEMOS, u->nick.c_str(), Config.s_MemoServ);
+ notice_lang(Config.s_MemoServ, u, MEMO_LIST_HEADER);
+ }
+
+ MemoListCallback::DoList(u, ci, mi, i);
}
}
}
@@ -105,6 +156,11 @@ class CommandMSList : public Command
{
syntax_error(Config.s_MemoServ, u, "LIST", MEMO_LIST_SYNTAX);
}
+
+ void OnServCommand(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_LIST);
+ }
};
class MSList : public Module
@@ -115,72 +171,8 @@ class MSList : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSList());
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_LIST);
+ this->AddCommand(MemoServ, new CommandMSList());
}
};
-/**
- * list memno callback function
- * @param u User Struct
- * @param int Memo number
- * @param va_list List of arguements
- * @return result form list_memo()
- */
-int list_memo_callback(User *u, int num, va_list args)
-{
- MemoInfo *mi = va_arg(args, MemoInfo *);
- int *sent_header = va_arg(args, int *);
- const char *chan = va_arg(args, const char *);
- int i;
-
- for (i = 0; i < mi->memos.size(); ++i)
- {
- if (mi->memos[i]->number == num)
- break;
- }
- /* Range checking done by list_memo() */
- return list_memo(u, i, mi, sent_header, 0, chan);
-}
-
-/**
- * Display a single memo entry, possibly printing the header first.
- * @param u User Struct
- * @param int Memo index
- * @param mi MemoInfo Struct
- * @param send_header If we are to send the headers
- * @param newi If we are listing new memos
- * @param chan Channel name
- * @return MOD_CONT
- */
-int list_memo(User *u, int index, MemoInfo *mi, int *sent_header, int newi, const char *chan)
-{
- Memo *m;
- char timebuf[64];
- struct tm tm;
-
- if (index < 0 || index >= mi->memos.size())
- return 0;
- if (!*sent_header)
- {
- if (chan)
- notice_lang(Config.s_MemoServ, u, newi ? MEMO_LIST_CHAN_NEW_MEMOS : MEMO_LIST_CHAN_MEMOS, chan, Config.s_MemoServ, chan);
- else
- notice_lang(Config.s_MemoServ, u, newi ? MEMO_LIST_NEW_MEMOS : MEMO_LIST_MEMOS, u->nick.c_str(), Config.s_MemoServ);
- notice_lang(Config.s_MemoServ, u, MEMO_LIST_HEADER);
- *sent_header = 1;
- }
- m = mi->memos[index];
- tm = *localtime(&m->time);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm);
- timebuf[sizeof(timebuf) - 1] = 0; /* just in case */
- notice_lang(Config.s_MemoServ, u, MEMO_LIST_FORMAT, (m->HasFlag(MF_UNREAD)) ? '*' : ' ', m->number, m->sender.c_str(), timebuf);
- return 1;
-}
-
MODULE_INIT(MSList)
diff --git a/src/core/ms_read.c b/src/core/ms_read.cpp
index d5e10b213..9553127af 100644
--- a/src/core/ms_read.c
+++ b/src/core/ms_read.cpp
@@ -14,9 +14,42 @@
#include "module.h"
-int read_memo_callback(User *u, int num, va_list args);
-int read_memo(User *u, int index, MemoInfo *mi, const char *chan);
-extern void rsend_notify(User *u, Memo *m, const char *chan);
+class MemoListCallback : public NumberList
+{
+ User *u;
+ MemoInfo *mi;
+ public:
+ MemoListCallback(User *_u, MemoInfo *_mi, const std::string &numlist) : NumberList(numlist, false), u(_u), mi(_mi)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > mi->memos.size())
+ return;
+
+ MemoListCallback::DoRead(u, mi, NULL, Number - 1);
+ }
+
+ static void DoRead(User *u, MemoInfo *mi, ChannelInfo *ci, unsigned index)
+ {
+ Memo *m = mi->memos[index];
+ struct tm tm = *localtime(&m->time);
+ char timebuf[64];
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm);
+ timebuf[sizeof(timebuf) - 1] = 0;
+ if (ci)
+ notice_lang(Config.s_MemoServ, u, MEMO_CHAN_HEADER, m->number, m->sender.c_str(), timebuf, Config.s_MemoServ, ci->name.c_str(), m->number);
+ else
+ notice_lang(Config.s_MemoServ, u, MEMO_HEADER, m->number, m->sender.c_str(), timebuf, Config.s_MemoServ, m->number);
+ notice_lang(Config.s_MemoServ, u, MEMO_TEXT, m->text);
+ m->UnsetFlag(MF_UNREAD);
+
+ /* Check if a receipt notification was requested */
+ if (m->HasFlag(MF_RECEIPT))
+ rsend_notify(u, m, ci ? ci->name.c_str() : NULL);
+ }
+};
class CommandMSRead : public Command
{
@@ -28,16 +61,16 @@ class CommandMSRead : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
MemoInfo *mi;
- ChannelInfo *ci;
+ ChannelInfo *ci = NULL;
ci::string numstr = params.size() ? params[0] : "", chan;
- int num, count;
+ int num;
if (!numstr.empty() && numstr[0] == '#')
{
chan = numstr;
numstr = params.size() > 1 ? params[1] : "";
- if (!(ci = cs_findchan(chan.c_str())))
+ if (!(ci = cs_findchan(chan)))
{
notice_lang(Config.s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan.c_str());
return MOD_CONT;
@@ -73,7 +106,7 @@ class CommandMSRead : public Command
{
if (mi->memos[i]->HasFlag(MF_UNREAD))
{
- read_memo(u, i, mi, !chan.empty() ? chan.c_str() : NULL);
+ MemoListCallback::DoRead(u, mi, ci, i);
++readcount;
}
}
@@ -88,17 +121,11 @@ class CommandMSRead : public Command
else if (numstr == "LAST")
{
for (i = 0; i < mi->memos.size() - 1; ++i);
- read_memo(u, i, mi, !chan.empty() ? chan.c_str() : NULL);
+ MemoListCallback::DoRead(u, mi, ci, i);
}
else /* number[s] */
{
- if (!process_numlist(numstr.c_str(), &count, read_memo_callback, u, mi, !chan.empty() ? chan.c_str() : NULL))
- {
- if (count == 1)
- notice_lang(Config.s_MemoServ, u, MEMO_DOES_NOT_EXIST, num);
- else
- notice_lang(Config.s_MemoServ, u, MEMO_LIST_NOT_FOUND, numstr.c_str());
- }
+ (new MemoListCallback(u, mi, numstr.c_str()))->Process();
}
}
return MOD_CONT;
@@ -114,6 +141,11 @@ class CommandMSRead : public Command
{
syntax_error(Config.s_MemoServ, u, "READ", MEMO_READ_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_READ);
+ }
};
class MSRead : public Module
@@ -124,70 +156,8 @@ class MSRead : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSRead());
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_READ);
+ this->AddCommand(MemoServ, new CommandMSRead());
}
};
-/**
- * Read a memo callback function
- * @param u User Struct
- * @param int Index number
- * @param va_list variable arguements
- * @return result of read_memo()
- */
-int read_memo_callback(User *u, int num, va_list args)
-{
- MemoInfo *mi = va_arg(args, MemoInfo *);
- const char *chan = va_arg(args, const char *);
- int i;
-
- for (i = 0; i < mi->memos.size(); ++i)
- {
- if (mi->memos[i]->number == num)
- break;
- }
- /* Range check done in read_memo */
- return read_memo(u, i, mi, chan);
-}
-
-/**
- * Read a memo
- * @param u User Struct
- * @param int Index number
- * @param mi MemoInfo struct
- * @param chan Channel Name
- * @return 1 on success, 0 if failed
- */
-int read_memo(User *u, int index, MemoInfo *mi, const char *chan)
-{
- Memo *m;
- char timebuf[64];
- struct tm tm;
-
- if (index < 0 || index >= mi->memos.size())
- return 0;
- m = mi->memos[index];
- tm = *localtime(&m->time);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm);
- timebuf[sizeof(timebuf) - 1] = 0;
- if (chan)
- notice_lang(Config.s_MemoServ, u, MEMO_CHAN_HEADER, m->number, m->sender.c_str(), timebuf, Config.s_MemoServ, chan, m->number);
- else
- notice_lang(Config.s_MemoServ, u, MEMO_HEADER, m->number, m->sender.c_str(), timebuf, Config.s_MemoServ, m->number);
- notice_lang(Config.s_MemoServ, u, MEMO_TEXT, m->text);
- m->UnsetFlag(MF_UNREAD);
-
- /* Check if a receipt notification was requested */
- if (m->HasFlag(MF_RECEIPT))
- rsend_notify(u, m, chan);
-
- return 1;
-}
-
MODULE_INIT(MSRead)
diff --git a/src/core/ms_rsend.c b/src/core/ms_rsend.cpp
index d8ebc1245..5ad43ac49 100644
--- a/src/core/ms_rsend.c
+++ b/src/core/ms_rsend.cpp
@@ -69,6 +69,11 @@ class CommandMSRSend : public Command
{
syntax_error(Config.s_MemoServ, u, "RSEND", MEMO_RSEND_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_RSEND);
+ }
};
class MSRSend : public Module
@@ -79,16 +84,10 @@ class MSRSend : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSRSend());
+ this->AddCommand(MemoServ, new CommandMSRSend());
if (!Config.MSMemoReceipt)
throw ModuleException("Don't like memo reciepts, or something.");
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_RSEND);
}
};
diff --git a/src/core/ms_send.c b/src/core/ms_send.cpp
index 12123fda8..71479924c 100644
--- a/src/core/ms_send.c
+++ b/src/core/ms_send.cpp
@@ -40,6 +40,11 @@ class CommandMSSend : public Command
{
syntax_error(Config.s_MemoServ, u, "SEND", MEMO_SEND_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SEND);
+ }
};
class MSSend : public Module
@@ -50,13 +55,7 @@ class MSSend : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSSend());
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SEND);
+ this->AddCommand(MemoServ, new CommandMSSend());
}
};
diff --git a/src/core/ms_sendall.c b/src/core/ms_sendall.cpp
index 4a09457e2..9150152df 100644
--- a/src/core/ms_sendall.c
+++ b/src/core/ms_sendall.cpp
@@ -23,8 +23,7 @@ class CommandMSSendAll : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- int i, z = 1;
- NickCore *nc;
+ int z = 1;
const char *text = params[0].c_str();
if (readonly)
@@ -33,14 +32,15 @@ class CommandMSSendAll : public Command
return MOD_CONT;
}
- for (i = 0; i < 1024; ++i)
+ NickAlias *na = findnick(u->nick);
+
+ for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it)
{
- for (nc = nclists[i]; nc; nc = nc->next)
- {
- if (stricmp(u->nick.c_str(), nc->display))
- memo_send(u, nc->display, text, z);
- } /* /nc */
- } /* /i */
+ NickCore *nc = it->second;
+
+ if ((na && na->nc == nc) || stricmp(u->nick.c_str(), nc->display))
+ memo_send(u, nc->display, text, z);
+ }
notice_lang(Config.s_MemoServ, u, MEMO_MASS_SENT);
return MOD_CONT;
@@ -56,6 +56,11 @@ class CommandMSSendAll : public Command
{
syntax_error(Config.s_MemoServ, u, "SENDALL", MEMO_SEND_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SENDALL);
+ }
};
class MSSendAll : public Module
@@ -66,13 +71,7 @@ class MSSendAll : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSSendAll());
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SENDALL);
+ this->AddCommand(MemoServ, new CommandMSSendAll());
}
};
diff --git a/src/core/ms_set.c b/src/core/ms_set.cpp
index 150224f1e..d915d7856 100644
--- a/src/core/ms_set.c
+++ b/src/core/ms_set.cpp
@@ -83,7 +83,7 @@ class CommandMSSet : public Command
p1 = p2;
p2 = p3;
p3 = params.size() > 4 ? params[4] : "";
- if (!(ci = cs_findchan(chan.c_str())))
+ if (!(ci = cs_findchan(chan)))
{
notice_lang(Config.s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan.c_str());
return MOD_CONT;
@@ -100,7 +100,7 @@ class CommandMSSet : public Command
if (!p2.empty() && p2 != "HARD" && chan.empty())
{
NickAlias *na;
- if (!(na = findnick(p1.c_str())))
+ if (!(na = findnick(p1)))
{
notice_lang(Config.s_MemoServ, u, NICK_X_NOT_REGISTERED, p1.c_str());
return MOD_CONT;
@@ -251,6 +251,11 @@ class CommandMSSet : public Command
{
syntax_error(Config.s_MemoServ, u, "SET", MEMO_SET_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SET);
+ }
};
class MSSet : public Module
@@ -262,13 +267,7 @@ class MSSet : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSSet());
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_SET);
+ this->AddCommand(MemoServ, new CommandMSSet());
}
};
diff --git a/src/core/ms_staff.c b/src/core/ms_staff.cpp
index 939322269..3d2877e44 100644
--- a/src/core/ms_staff.c
+++ b/src/core/ms_staff.cpp
@@ -23,8 +23,7 @@ class CommandMSStaff : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- NickCore *nc;
- int i, z = 0;
+ int z = 0;
const char *text = params[0].c_str();
if (readonly)
@@ -33,14 +32,14 @@ class CommandMSStaff : public Command
return MOD_CONT;
}
- for (i = 0; i < 1024; ++i)
+ for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it)
{
- for (nc = nclists[i]; nc; nc = nc->next)
- {
- if (nc->IsServicesOper())
- memo_send(u, nc->display, text, z);
- }
+ NickCore *nc = it->second;
+
+ if (nc->IsServicesOper())
+ memo_send(u, nc->display, text, z);
}
+
return MOD_CONT;
}
@@ -54,6 +53,11 @@ class CommandMSStaff : public Command
{
syntax_error(Config.s_MemoServ, u, "STAFF", MEMO_STAFF_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_STAFF);
+ }
};
class MSStaff : public Module
@@ -64,13 +68,7 @@ class MSStaff : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(MEMOSERV, new CommandMSStaff());
-
- ModuleManager::Attach(I_OnMemoServHelp, this);
- }
- void OnMemoServHelp(User *u)
- {
- notice_lang(Config.s_MemoServ, u, MEMO_HELP_CMD_STAFF);
+ this->AddCommand(MemoServ, new CommandMSStaff());
}
};
diff --git a/src/core/ns_access.c b/src/core/ns_access.cpp
index bebf1491f..c578e6095 100644
--- a/src/core/ns_access.c
+++ b/src/core/ns_access.cpp
@@ -124,7 +124,7 @@ class CommandNSAccess : public Command
const char *mask = params.size() > 1 ? params[1].c_str() : NULL;
NickAlias *na;
- if (cmd == "LIST" && u->Account()->IsServicesOper() && mask && (na = findnick(params[1].c_str())))
+ if (cmd == "LIST" && u->Account()->IsServicesOper() && mask && (na = findnick(params[1])))
return this->DoServAdminList(u, params, na->nc);
if (mask && !strchr(mask, '@'))
@@ -160,6 +160,11 @@ class CommandNSAccess : public Command
{
syntax_error(Config.s_NickServ, u, "ACCESS", NICK_ACCESS_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_ACCESS);
+ }
};
class NSAccess : public Module
@@ -171,13 +176,7 @@ class NSAccess : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSAccess());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_ACCESS);
+ this->AddCommand(NickServ, new CommandNSAccess());
}
};
diff --git a/src/core/ns_alist.c b/src/core/ns_alist.cpp
index 57b09ab10..a904fe9b0 100644
--- a/src/core/ns_alist.c
+++ b/src/core/ns_alist.cpp
@@ -88,37 +88,35 @@ class CommandNSAList : public Command
notice_lang(Config.s_NickServ, u, CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
else
{
- int i, level;
+ int level;
int chan_count = 0;
int match_count = 0;
- ChannelInfo *ci;
notice_lang(Config.s_NickServ, u, is_servadmin ? NICK_ALIST_HEADER_X : NICK_ALIST_HEADER, na->nick);
- for (i = 0; i < 256; ++i)
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
{
- for (ci = chanlists[i]; ci; ci = ci->next)
+ ChannelInfo *ci = it->second;
+
+ if ((level = get_access_level(ci, na)))
{
- if ((level = get_access_level(ci, na)))
- {
- ++chan_count;
+ ++chan_count;
- if (min_level > level)
- continue;
+ if (min_level > level)
+ continue;
- ++match_count;
+ ++match_count;
- if ((ci->HasFlag(CI_XOP)) || level == ACCESS_FOUNDER)
- {
- const char *xop;
+ if ((ci->HasFlag(CI_XOP)) || level == ACCESS_FOUNDER)
+ {
+ const char *xop;
- xop = get_xop_level(level);
+ xop = get_xop_level(level);
- notice_lang(Config.s_NickServ, u, NICK_ALIST_XOP_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), xop, ci->desc ? ci->desc : "");
- }
- else
- notice_lang(Config.s_NickServ, u, NICK_ALIST_ACCESS_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), level, ci->desc ? ci->desc : "");
+ notice_lang(Config.s_NickServ, u, NICK_ALIST_XOP_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), xop, ci->desc ? ci->desc : "");
}
+ else
+ notice_lang(Config.s_NickServ, u, NICK_ALIST_ACCESS_FORMAT, match_count, ci->HasFlag(CI_NO_EXPIRE) ? '!' : ' ', ci->name.c_str(), level, ci->desc ? ci->desc : "");
}
}
@@ -136,6 +134,11 @@ class CommandNSAList : public Command
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_ALIST);
+ }
};
class NSAList : public Module
@@ -147,13 +150,7 @@ class NSAList : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSAList());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_ALIST);
+ this->AddCommand(NickServ, new CommandNSAList());
}
};
diff --git a/src/core/ns_drop.c b/src/core/ns_drop.cpp
index ce87626c1..7383706d9 100644
--- a/src/core/ns_drop.c
+++ b/src/core/ns_drop.cpp
@@ -42,7 +42,7 @@ class CommandNSDrop : public Command
if ((nr = findrequestnick(nick)) && u->Account()->IsServicesOper())
{
if (Config.WallDrop)
- ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used DROP on \2%s\2", u->nick.c_str(), nick);
+ ircdproto->SendGlobops(NickServ, "\2%s\2 used DROP on \2%s\2", u->nick.c_str(), nick);
Alog() << Config.s_NickServ << ": " << u->GetMask() << " dropped nickname " << nr->nick << " (e-mail: " << nr->email << ")";
delete nr;
notice_lang(Config.s_NickServ, u, NICK_X_DROPPED, nick);
@@ -69,7 +69,10 @@ class CommandNSDrop : public Command
notice_lang(Config.s_NickServ, u, READ_ONLY_MODE);
if (ircd->sqline && (na->HasFlag(NS_FORBIDDEN)))
- ircdproto->SendSQLineDel(na->nick);
+ {
+ XLine x(na->nick);
+ ircdproto->SendSQLineDel(&x);
+ }
Alog() << Config.s_NickServ << ": " << u->GetMask() << " dropped nickname " << na->nick << " (group " << na->nc->display << ") (e-mail: " << (na->nc->email ? na->nc->email : "none") << ")";
delete na;
@@ -79,7 +82,7 @@ class CommandNSDrop : public Command
if (!is_mine)
{
if (Config.WallDrop)
- ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used DROP on \2%s\2", u->nick.c_str(), nick);
+ ircdproto->SendGlobops(NickServ, "\2%s\2 used DROP on \2%s\2", u->nick.c_str(), nick);
notice_lang(Config.s_NickServ, u, NICK_X_DROPPED, nick);
}
else
@@ -104,6 +107,11 @@ class CommandNSDrop : public Command
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_DROP);
+ }
};
class NSDrop : public Module
@@ -115,13 +123,7 @@ class NSDrop : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSDrop());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_DROP);
+ this->AddCommand(NickServ, new CommandNSDrop());
}
};
diff --git a/src/core/ns_forbid.c b/src/core/ns_forbid.cpp
index 14101a335..61a28e552 100644
--- a/src/core/ns_forbid.c
+++ b/src/core/ns_forbid.cpp
@@ -69,10 +69,13 @@ class CommandNSForbid : public Command
if (ircd->sqline)
- ircdproto->SendSQLine(na->nick, reason ? reason : "Forbidden");
+ {
+ XLine x(na->nick, reason ? reason : "Forbidden");
+ ircdproto->SendSQLine(&x);
+ }
if (Config.WallForbid)
- ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used FORBID on \2%s\2", u->nick.c_str(), nick);
+ ircdproto->SendGlobops(NickServ, "\2%s\2 used FORBID on \2%s\2", u->nick.c_str(), nick);
Alog() << Config.s_NickServ << ": " << u->nick << " set FORBID for nick " << nick;
notice_lang(Config.s_NickServ, u, NICK_FORBID_SUCCEEDED, nick);
@@ -97,6 +100,11 @@ class CommandNSForbid : public Command
{
syntax_error(Config.s_NickServ, u, "FORBID", Config.ForceForbidReason ? NICK_FORBID_SYNTAX_REASON : NICK_FORBID_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_FORBID);
+ }
};
class NSForbid : public Module
@@ -108,13 +116,7 @@ class NSForbid : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSForbid());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_FORBID);
+ this->AddCommand(NickServ, new CommandNSForbid());
}
};
diff --git a/src/core/ns_getemail.c b/src/core/ns_getemail.cpp
index 9c72ea023..c0a2980c5 100644
--- a/src/core/ns_getemail.c
+++ b/src/core/ns_getemail.cpp
@@ -29,29 +29,30 @@ class CommandNSGetEMail : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
ci::string email = params[0];
- int i, j = 0;
- NickCore *nc;
+ int j = 0;
Alog() << Config.s_NickServ << ": " << u->GetMask() << " used GETEMAIL on " << email;
- for (i = 0; i < 1024; ++i)
+
+ for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it)
{
- for (nc = nclists[i]; nc; nc = nc->next)
+ NickCore *nc = it->second;
+
+ if (nc->email)
{
- if (nc->email)
+ if (nc->email == email)
{
- if (nc->email == email)
- {
- ++j;
- notice_lang(Config.s_NickServ, u, NICK_GETEMAIL_EMAILS_ARE, nc->display, email.c_str());
- }
+ ++j;
+ notice_lang(Config.s_NickServ, u, NICK_GETEMAIL_EMAILS_ARE, nc->display, email.c_str());
}
}
}
+
if (j <= 0)
{
notice_lang(Config.s_NickServ, u, NICK_GETEMAIL_NOT_USED, email.c_str());
return MOD_CONT;
}
+
return MOD_CONT;
}
@@ -65,6 +66,11 @@ class CommandNSGetEMail : public Command
{
syntax_error(Config.s_NickServ, u, "GETMAIL", NICK_GETEMAIL_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GETEMAIL);
+ }
};
class NSGetEMail : public Module
@@ -76,13 +82,7 @@ class NSGetEMail : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSGetEMail());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GETEMAIL);
+ this->AddCommand(NickServ, new CommandNSGetEMail());
}
};
diff --git a/src/core/ns_getpass.c b/src/core/ns_getpass.cpp
index 01ce31c90..cda008967 100644
--- a/src/core/ns_getpass.c
+++ b/src/core/ns_getpass.cpp
@@ -34,7 +34,7 @@ class CommandNSGetPass : public Command
{
Alog() << Config.s_NickServ << ": " << u->GetMask() << " used GETPASS on " << nick;
if (Config.WallGetpass)
- ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used GETPASS on \2%s\2", u->nick.c_str(), nick);
+ ircdproto->SendGlobops(NickServ, "\2%s\2 used GETPASS on \2%s\2", u->nick.c_str(), nick);
notice_lang(Config.s_NickServ, u, NICK_GETPASS_PASSCODE_IS, nick, nr->passcode.c_str());
}
else
@@ -50,7 +50,7 @@ class CommandNSGetPass : public Command
{
Alog() << Config.s_NickServ << ": " << u->GetMask() << " used GETPASS on " << nick;
if (Config.WallGetpass)
- ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used GETPASS on \2%s\2", u->nick.c_str(), nick);
+ ircdproto->SendGlobops(NickServ, "\2%s\2 used GETPASS on \2%s\2", u->nick.c_str(), nick);
notice_lang(Config.s_NickServ, u, NICK_GETPASS_PASSWORD_IS, nick, tmp_pass.c_str());
}
else
@@ -69,6 +69,11 @@ class CommandNSGetPass : public Command
{
syntax_error(Config.s_NickServ, u, "GETPASS", NICK_GETPASS_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GETPASS);
+ }
};
class NSGetPass : public Module
@@ -80,17 +85,11 @@ class NSGetPass : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSGetPass());
+ this->AddCommand(NickServ, new CommandNSGetPass());
std::string tmp_pass = "plain:tmp";
if (enc_decrypt(tmp_pass, tmp_pass) == -1)
throw ModuleException("Incompatible with the encryption module being used");
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GETPASS);
}
};
diff --git a/src/core/ns_ghost.c b/src/core/ns_ghost.cpp
index 41c0a68a4..1ae0a1946 100644
--- a/src/core/ns_ghost.c
+++ b/src/core/ns_ghost.cpp
@@ -82,6 +82,11 @@ class CommandNSGhost : public Command
{
syntax_error(Config.s_NickServ, u, "GHOST", NICK_GHOST_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GHOST);
+ }
};
class NSGhost : public Module
@@ -93,13 +98,7 @@ class NSGhost : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSGhost());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GHOST);
+ this->AddCommand(NickServ, new CommandNSGhost());
}
};
diff --git a/src/core/ns_group.c b/src/core/ns_group.cpp
index 2aa47ac1f..ffb94296b 100644
--- a/src/core/ns_group.c
+++ b/src/core/ns_group.cpp
@@ -29,7 +29,7 @@ class CommandNSGroup : public Command
std::string pass = params[1].c_str();
std::list<std::pair<std::string, std::string> >::iterator it;
- if (Config.NSEmailReg && findrequestnick(u->nick.c_str()))
+ if (Config.NSEmailReg && findrequestnick(u->nick))
{
notice_lang(Config.s_NickServ, u, NICK_REQUESTED);
return MOD_CONT;
@@ -51,9 +51,7 @@ class CommandNSGroup : public Command
{
for (it = Config.Opers.begin(); it != Config.Opers.end(); ++it)
{
- std::string nick = it->first;
-
- if (stristr(u->nick.c_str(), nick.c_str()) && !is_oper(u))
+ if (!is_oper(u) && u->nick.find(it->first) != std::string::npos)
{
notice_lang(Config.s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick.c_str());
return MOD_CONT;
@@ -82,7 +80,7 @@ class CommandNSGroup : public Command
notice_lang(Config.s_NickServ, u, NICK_GROUP_SAME, target->nick);
else if (na && na->nc != u->Account())
notice_lang(Config.s_NickServ, u, NICK_IDENTIFY_REQUIRED, Config.s_NickServ);
- else if (Config.NSMaxAliases && (target->nc->aliases.count >= Config.NSMaxAliases) && !target->nc->IsServicesOper())
+ else if (Config.NSMaxAliases && (target->nc->aliases.size() >= Config.NSMaxAliases) && !target->nc->IsServicesOper())
notice_lang(Config.s_NickServ, u, NICK_GROUP_TOO_MANY, target->nick, Config.s_NickServ, Config.s_NickServ);
else if (enc_check_password(pass, target->nc->pass) != 1)
{
@@ -151,6 +149,82 @@ class CommandNSGroup : public Command
{
syntax_error(Config.s_NickServ, u, "GROUP", NICK_GROUP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GROUP);
+ }
+};
+
+class CommandNSUngroup : public Command
+{
+ public:
+ CommandNSUngroup() : Command("UNGROUP", 0, 1)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ const char *nick = params.size() ? params[0].c_str() : NULL;
+ NickAlias *na = nick ? findnick(nick) : findnick(u->nick);
+
+ if (u->Account()->aliases.size() == 1)
+ notice_lang(Config.s_NickServ, u, NICK_UNGROUP_ONE_NICK);
+ else if (!na)
+ notice_lang(Config.s_NickServ, u, NICK_X_NOT_REGISTERED, nick ? nick : u->nick.c_str());
+ else if (na->nc != u->Account())
+ notice_lang(Config.s_NickServ, u, NICK_UNGROUP_NOT_IN_GROUP, na->nick);
+ else
+ {
+ NickCore *oldcore = na->nc;
+
+ std::list<NickAlias *>::iterator it = std::find(oldcore->aliases.begin(), oldcore->aliases.end(), na);
+ if (it != oldcore->aliases.end())
+ {
+ oldcore->aliases.erase(it);
+ }
+
+ if (!stricmp(oldcore->display, na->nick))
+ {
+ change_core_display(oldcore);
+ }
+
+ na->nc = new NickCore(na->nick);
+ na->nc->aliases.push_back(na);
+
+ na->nc->pass = oldcore->pass;
+ if (oldcore->email)
+ na->nc->email = sstrdup(oldcore->email);
+ if (oldcore->greet)
+ na->nc->greet = sstrdup(oldcore->greet);
+ na->nc->icq = oldcore->icq;
+ if (oldcore->url)
+ na->nc->url = sstrdup(oldcore->url);
+ na->nc->language = oldcore->language;
+
+ notice_lang(Config.s_NickServ, u, NICK_UNGROUP_SUCCESSFUL, na->nick, oldcore->display);
+
+ User *user = finduser(na->nick);
+ if (user)
+ {
+ /* The user on the nick who was ungrouped may be identified to the old group, set -r */
+ user->RemoveMode(NickServ, UMODE_REGISTERED);
+ }
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_UNGROUP);
+ return true;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_UNGROUP);
+ }
};
class CommandNSGList : public Command
@@ -165,7 +239,6 @@ class CommandNSGList : public Command
const char *nick = params.size() ? params[0].c_str() : NULL;
NickCore *nc = u->Account();
- int i;
if (nick && (stricmp(nick, u->nick.c_str()) && !u->Account()->IsServicesOper()))
notice_lang(Config.s_NickServ, u, ACCESS_DENIED, Config.s_NickServ);
@@ -179,21 +252,19 @@ class CommandNSGList : public Command
int wont_expire;
notice_lang(Config.s_NickServ, u, nick ? NICK_GLIST_HEADER_X : NICK_GLIST_HEADER, nc->display);
- for (i = 0; i < nc->aliases.count; ++i)
+ for (std::list<NickAlias *>::iterator it = nc->aliases.begin(); it != nc->aliases.end(); ++it)
{
- NickAlias *na2 = static_cast<NickAlias *>(nc->aliases.list[i]);
- if (na2->nc == nc)
+ NickAlias *na2 = *it;
+
+ if (!(wont_expire = na2->HasFlag(NS_NO_EXPIRE)))
{
- if (!(wont_expire = na2->HasFlag(NS_NO_EXPIRE)))
- {
- expt = na2->last_seen + Config.NSExpire;
- tm = localtime(&expt);
- strftime_lang(buf, sizeof(buf), finduser(na2->nick), STRFTIME_DATE_TIME_FORMAT, tm);
- }
- notice_lang(Config.s_NickServ, u, u->Account()->IsServicesOper() && !wont_expire ? NICK_GLIST_REPLY_ADMIN : NICK_GLIST_REPLY, wont_expire ? '!' : ' ', na2->nick, buf);
+ expt = na2->last_seen + Config.NSExpire;
+ tm = localtime(&expt);
+ strftime_lang(buf, sizeof(buf), finduser(na2->nick), STRFTIME_DATE_TIME_FORMAT, tm);
}
+ notice_lang(Config.s_NickServ, u, wont_expire ? NICK_GLIST_REPLY_NOEXPIRE : NICK_GLIST_REPLY, na2->nick, buf);
}
- notice_lang(Config.s_NickServ, u, NICK_GLIST_FOOTER, nc->aliases.count);
+ notice_lang(Config.s_NickServ, u, NICK_GLIST_FOOTER, nc->aliases.size());
}
return MOD_CONT;
}
@@ -208,6 +279,11 @@ class CommandNSGList : public Command
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GLIST);
+ }
};
class NSGroup : public Module
@@ -219,15 +295,9 @@ class NSGroup : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSGroup());
- this->AddCommand(NICKSERV, new CommandNSGList());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GROUP);
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_GLIST);
+ this->AddCommand(NickServ, new CommandNSGroup());
+ this->AddCommand(NickServ, new CommandNSUngroup());
+ this->AddCommand(NickServ, new CommandNSGList());
}
};
diff --git a/src/core/ns_help.c b/src/core/ns_help.cpp
index a2485c6dc..a9b40592f 100644
--- a/src/core/ns_help.c
+++ b/src/core/ns_help.cpp
@@ -34,7 +34,7 @@ class CommandNSHelp : public Command
u->SendMessage(Config.s_NickServ, " %2d) %s", i + 1, langnames[langlist[i]]);
}
else
- mod_help_cmd(Config.s_NickServ, u, NICKSERV, cmd.c_str());
+ mod_help_cmd(NickServ, u, cmd.c_str());
return MOD_CONT;
}
@@ -42,7 +42,8 @@ class CommandNSHelp : public Command
void OnSyntaxError(User *u, const ci::string &subcommand)
{
notice_help(Config.s_NickServ, u, NICK_HELP);
- FOREACH_MOD(I_OnNickServHelp, OnNickServHelp(u));
+ for (CommandMap::const_iterator it = NickServ->Commands.begin(); it != NickServ->Commands.end(); ++it)
+ it->second->OnServHelp(u);
if (u->Account() && u->Account()->IsServicesOper())
notice_help(Config.s_NickServ, u, NICK_SERVADMIN_HELP);
if (Config.NSExpire >= 86400)
@@ -60,7 +61,7 @@ class NSHelp : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSHelp());
+ this->AddCommand(NickServ, new CommandNSHelp());
}
};
diff --git a/src/core/ns_identify.c b/src/core/ns_identify.cpp
index 866497fc0..2f02cac81 100644
--- a/src/core/ns_identify.c
+++ b/src/core/ns_identify.cpp
@@ -17,7 +17,7 @@
class CommandNSIdentify : public Command
{
public:
- CommandNSIdentify(const std::string &cname) : Command(cname, 1, 1)
+ CommandNSIdentify(const ci::string &cname) : Command(cname, 1, 1)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
}
@@ -29,9 +29,9 @@ class CommandNSIdentify : public Command
NickRequest *nr;
int res;
- if (!(na = findnick(u->nick.c_str())))
+ if (!(na = findnick(u->nick)))
{
- if ((nr = findrequestnick(u->nick.c_str())))
+ if ((nr = findrequestnick(u->nick)))
notice_lang(Config.s_NickServ, u, NICK_IS_PREREG);
else
notice_lang(Config.s_NickServ, u, NICK_NOT_REGISTERED);
@@ -104,6 +104,12 @@ class CommandNSIdentify : public Command
{
syntax_error(Config.s_NickServ, u, "IDENTIFY", NICK_IDENTIFY_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ if (this->name == "IDENTIFY")
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_IDENTIFY);
+ }
};
class NSIdentify : public Module
@@ -115,14 +121,8 @@ class NSIdentify : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSIdentify("IDENTIFY"));
- this->AddCommand(NICKSERV, new CommandNSIdentify("ID"));
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_IDENTIFY);
+ this->AddCommand(NickServ, new CommandNSIdentify("IDENTIFY"));
+ this->AddCommand(NickServ, new CommandNSIdentify("ID"));
}
};
diff --git a/src/core/ns_info.c b/src/core/ns_info.cpp
index 0635e52df..e5a4d5e9e 100644
--- a/src/core/ns_info.c
+++ b/src/core/ns_info.cpp
@@ -79,19 +79,19 @@ class CommandNSInfo : public Command
{
struct tm *tm;
char buf[BUFSIZE];
- int nick_online = 0;
- int show_hidden = 0;
+ bool nick_online = false, show_hidden = false;
time_t expt;
+ bool has_auspex = u->IsIdentified() && u->Account()->HasPriv("nickserv/auspex");
/* Is the real owner of the nick we're looking up online? -TheShadow */
User *u2 = finduser(na->nick);
if (u2 && u2->Account() == na->nc)
- nick_online = 1;
+ nick_online = true;
/* Only show hidden fields to owner and sadmins and only when the ALL
* parameter is used. -TheShadow */
- if (!param.empty() && param == "ALL" && u->Account() && (na->nc == u->Account() || u->Account()->IsServicesOper()))
- show_hidden = 1;
+ if (!param.empty() && param == "ALL" && u->Account() && (na->nc == u->Account() || has_auspex))
+ show_hidden = true;
notice_lang(Config.s_NickServ, u, NICK_INFO_REALNAME, na->nick, na->last_realname);
@@ -100,7 +100,6 @@ class CommandNSInfo : public Command
if (show_hidden || (!(na->nc->HasFlag(NI_HIDE_STATUS))))
{
notice_lang(Config.s_NickServ, u, NICK_INFO_SERVICES_OPERTYPE, na->nick, na->nc->ot->GetName().c_str());
-
}
}
@@ -111,7 +110,8 @@ class CommandNSInfo : public Command
else
notice_lang(Config.s_NickServ, u, NICK_INFO_ADDRESS_ONLINE_NOHOST, na->nick);
}
- else {
+ else
+ {
if (show_hidden || !(na->nc->HasFlag(NI_HIDE_MASK)))
notice_lang(Config.s_NickServ, u, NICK_INFO_ADDRESS, na->last_usermask);
}
@@ -171,17 +171,16 @@ class CommandNSInfo : public Command
notice_lang(Config.s_NickServ, u, NICK_INFO_NO_EXPIRE);
else
{
- if (u->Account()->IsServicesOper())
- {
- expt = na->last_seen + Config.NSExpire;
- tm = localtime(&expt);
- strftime_lang(buf, sizeof(buf), finduser(na->nick), STRFTIME_DATE_TIME_FORMAT, tm);
- notice_lang(Config.s_NickServ, u, NICK_INFO_EXPIRE, buf);
- }
+ expt = na->last_seen + Config.NSExpire;
+ tm = localtime(&expt);
+ strftime_lang(buf, sizeof(buf), finduser(na->nick), STRFTIME_DATE_TIME_FORMAT, tm);
+ notice_lang(Config.s_NickServ, u, NICK_INFO_EXPIRE, buf);
}
}
- if (!show_hidden && u->Account() && (na->nc == u->Account() || u->Account()->IsServicesOper()))
+ FOREACH_MOD(I_OnNickInfo, OnNickInfo(u, na, show_hidden));
+
+ if (!show_hidden && u->Account() && (na->nc == u->Account() || has_auspex))
notice_lang(Config.s_NickServ, u, NICK_INFO_FOR_MORE, Config.s_NickServ, na->nick);
}
return MOD_CONT;
@@ -190,7 +189,7 @@ class CommandNSInfo : public Command
bool OnHelp(User *u, const ci::string &subcommand)
{
notice_help(Config.s_NickServ, u, NICK_HELP_INFO);
- if (u->Account() && u->Account()->IsServicesOper())
+ if (u->IsIdentified() && u->Account()->HasPriv("nickserv/auspex"))
notice_help(Config.s_NickServ, u, NICK_SERVADMIN_HELP_INFO);
return true;
@@ -200,6 +199,11 @@ class CommandNSInfo : public Command
{
syntax_error(Config.s_NickServ, u, "INFO", NICK_INFO_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_INFO);
+ }
};
class NSInfo : public Module
@@ -211,13 +215,7 @@ class NSInfo : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSInfo());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_INFO);
+ this->AddCommand(NickServ, new CommandNSInfo());
}
};
diff --git a/src/core/ns_list.c b/src/core/ns_list.cpp
index 195763037..7b9419a14 100644
--- a/src/core/ns_list.c
+++ b/src/core/ns_list.cpp
@@ -38,12 +38,10 @@ class CommandNSList : public Command
* UPDATE: SUSPENDED keyword is now accepted as well.
*/
const char *pattern = params[0].c_str();
- NickAlias *na;
NickCore *mync;
- unsigned nnicks, i;
+ unsigned nnicks;
char buf[BUFSIZE];
bool is_servadmin = u->Account()->IsServicesOper();
- NickRequest *nr = NULL;
char noexpire_char = ' ';
int count = 0, from = 0, to = 0, tofree = 0;
char *tmp = NULL;
@@ -123,46 +121,45 @@ class CommandNSList : public Command
notice_lang(Config.s_NickServ, u, NICK_LIST_HEADER, pattern);
if (!unconfirmed)
{
- for (i = 0; i < 1024; ++i)
+ for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it)
{
- for (na = nalists[i]; na; na = na->next)
+ NickAlias *na = it->second;
+
+ /* Don't show private and forbidden nicks to non-services admins. */
+ if ((na->HasFlag(NS_FORBIDDEN)) && !is_servadmin)
+ continue;
+ if ((na->nc->HasFlag(NI_PRIVATE)) && !is_servadmin && na->nc != mync)
+ continue;
+ if (forbidden && !na->HasFlag(NS_FORBIDDEN))
+ continue;
+ else if (nsnoexpire && !na->HasFlag(NS_NO_EXPIRE))
+ continue;
+ else if (suspended && !na->nc->HasFlag(NI_SUSPENDED))
+ continue;
+
+ /* We no longer compare the pattern against the output buffer.
+ * Instead we build a nice nick!user@host buffer to compare.
+ * The output is then generated separately. -TheShadow */
+ snprintf(buf, sizeof(buf), "%s!%s", na->nick, na->last_usermask && !(na->HasFlag(NS_FORBIDDEN)) ? na->last_usermask : "*@*");
+ if (!stricmp(pattern, na->nick) || Anope::Match(buf, pattern, false))
{
- /* Don't show private and forbidden nicks to non-services admins. */
- if ((na->HasFlag(NS_FORBIDDEN)) && !is_servadmin)
- continue;
- if ((na->nc->HasFlag(NI_PRIVATE)) && !is_servadmin && na->nc != mync)
- continue;
- if (forbidden && !na->HasFlag(NS_FORBIDDEN))
- continue;
- else if (nsnoexpire && !na->HasFlag(NS_NO_EXPIRE))
- continue;
- else if (suspended && !na->nc->HasFlag(NI_SUSPENDED))
- continue;
-
- /* We no longer compare the pattern against the output buffer.
- * Instead we build a nice nick!user@host buffer to compare.
- * The output is then generated separately. -TheShadow */
- snprintf(buf, sizeof(buf), "%s!%s", na->nick, na->last_usermask && !(na->HasFlag(NS_FORBIDDEN)) ? na->last_usermask : "*@*");
- if (!stricmp(pattern, na->nick) || Anope::Match(buf, pattern, false))
+ if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= Config.NSListMax)
{
- if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= Config.NSListMax)
- {
- if (is_servadmin && (na->HasFlag(NS_NO_EXPIRE)))
- noexpire_char = '!';
- else
- noexpire_char = ' ';
- if ((na->nc->HasFlag(NI_HIDE_MASK)) && !is_servadmin && na->nc != mync)
- snprintf(buf, sizeof(buf), "%-20s [Hostname Hidden]", na->nick);
- else if (na->HasFlag(NS_FORBIDDEN))
- snprintf(buf, sizeof(buf), "%-20s [Forbidden]", na->nick);
- else if (na->nc->HasFlag(NI_SUSPENDED))
- snprintf(buf, sizeof(buf), "%-20s [Suspended]", na->nick);
- else
- snprintf(buf, sizeof(buf), "%-20s %s", na->nick, na->last_usermask);
- u->SendMessage(Config.s_NickServ, " %c%s", noexpire_char, buf);
- }
- ++count;
+ if (is_servadmin && (na->HasFlag(NS_NO_EXPIRE)))
+ noexpire_char = '!';
+ else
+ noexpire_char = ' ';
+ if ((na->nc->HasFlag(NI_HIDE_MASK)) && !is_servadmin && na->nc != mync)
+ snprintf(buf, sizeof(buf), "%-20s [Hostname Hidden]", na->nick);
+ else if (na->HasFlag(NS_FORBIDDEN))
+ snprintf(buf, sizeof(buf), "%-20s [Forbidden]", na->nick);
+ else if (na->nc->HasFlag(NI_SUSPENDED))
+ snprintf(buf, sizeof(buf), "%-20s [Suspended]", na->nick);
+ else
+ snprintf(buf, sizeof(buf), "%-20s %s", na->nick, na->last_usermask);
+ u->SendMessage(Config.s_NickServ, " %c%s", noexpire_char, buf);
}
+ ++count;
}
}
}
@@ -170,18 +167,18 @@ class CommandNSList : public Command
if (unconfirmed || is_servadmin)
{
noexpire_char = ' ';
- for (i = 0; i < 1024; ++i)
+
+ for (nickrequest_map::const_iterator it = NickRequestList.begin(); it != NickRequestList.end(); ++it)
{
- for (nr = nrlists[i]; nr; nr = nr->next)
+ NickRequest *nr = it->second;
+
+ snprintf(buf, sizeof(buf), "%s!*@*", nr->nick);
+ if (!stricmp(pattern, nr->nick) || Anope::Match(buf, pattern, false))
{
- snprintf(buf, sizeof(buf), "%s!*@*", nr->nick);
- if (!stricmp(pattern, nr->nick) || Anope::Match(buf, pattern, false))
+ if (++nnicks <= Config.NSListMax)
{
- if (++nnicks <= Config.NSListMax)
- {
- snprintf(buf, sizeof(buf), "%-20s [UNCONFIRMED]", nr->nick);
- u->SendMessage(Config.s_NickServ, " %c%s", noexpire_char, buf);
- }
+ snprintf(buf, sizeof(buf), "%-20s [UNCONFIRMED]", nr->nick);
+ u->SendMessage(Config.s_NickServ, " %c%s", noexpire_char, buf);
}
}
}
@@ -209,6 +206,11 @@ class CommandNSList : public Command
else
syntax_error(Config.s_NickServ, u, "LIST", NICK_LIST_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_LIST);
+ }
};
class NSList : public Module
@@ -220,13 +222,7 @@ class NSList : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSList());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_LIST);
+ this->AddCommand(NickServ, new CommandNSList());
}
};
diff --git a/src/core/ns_logout.c b/src/core/ns_logout.cpp
index 373dbabbd..c3d5696f2 100644
--- a/src/core/ns_logout.c
+++ b/src/core/ns_logout.cpp
@@ -77,6 +77,11 @@ class CommandNSLogout : public Command
{
syntax_error(Config.s_NickServ, u, "LOGOUT", NICK_LOGOUT_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_LOGOUT);
+ }
};
class NSLogout : public Module
@@ -88,13 +93,7 @@ class NSLogout : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSLogout());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_LOGOUT);
+ this->AddCommand(NickServ, new CommandNSLogout());
}
};
diff --git a/src/core/ns_recover.c b/src/core/ns_recover.cpp
index 7484da87c..501c06642 100644
--- a/src/core/ns_recover.c
+++ b/src/core/ns_recover.cpp
@@ -103,6 +103,11 @@ class CommandNSRecover : public Command
{
syntax_error(Config.s_NickServ, u, "RECOVER", NICK_RECOVER_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RECOVER);
+ }
};
class NSRecover : public Module
@@ -114,13 +119,7 @@ class NSRecover : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSRecover());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RECOVER);
+ this->AddCommand(NickServ, new CommandNSRecover());
}
};
diff --git a/src/core/ns_register.c b/src/core/ns_register.cpp
index 4a9bfb6fe..f8bf1691f 100644
--- a/src/core/ns_register.c
+++ b/src/core/ns_register.cpp
@@ -14,7 +14,7 @@
#include "module.h"
-int do_sendregmail(User *u, NickRequest *nr);
+static bool SendRegmail(User *u, NickRequest *nr);
class CommandNSConfirm : public Command
{
@@ -94,10 +94,9 @@ class CommandNSConfirm : public Command
CommandReturn DoConfirm(User *u, const std::vector<ci::string> &params)
{
- NickRequest *nr = NULL;
std::string passcode = !params.empty() ? params[0].c_str() : "";
- nr = findrequestnick(u->nick.c_str());
+ NickRequest *nr = findrequestnick(u->nick);
if (Config.NSEmailReg)
{
@@ -113,7 +112,7 @@ class CommandNSConfirm : public Command
{
/* If an admin, their nick is obviously already regged, so look at the passcode to get the nick
of the user they are trying to validate, and push that user through regardless of passcode */
- nr = findrequestnick(passcode.c_str());
+ nr = findrequestnick(passcode);
if (nr)
{
ActuallyConfirmNick(u, nr, true);
@@ -143,7 +142,7 @@ class CommandNSConfirm : public Command
}
public:
- CommandNSConfirm(const std::string &cmdn, int min, int max) : Command(cmdn, min, max)
+ CommandNSConfirm(const ci::string &cmdn, int min, int max) : Command(cmdn, min, max)
{
this->SetFlag(CFLAG_ALLOW_UNREGISTERED);
}
@@ -165,6 +164,11 @@ class CommandNSConfirm : public Command
{
notice_lang(Config.s_NickServ, u, NICK_CONFIRM_INVALID);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_CONFIRM);
+ }
};
class CommandNSRegister : public CommandNSConfirm
@@ -206,7 +210,7 @@ class CommandNSRegister : public CommandNSConfirm
return MOD_CONT;
}
- if ((anr = findrequestnick(u->nick.c_str())))
+ if ((anr = findrequestnick(u->nick)))
{
notice_lang(Config.s_NickServ, u, NICK_REQUESTED);
return MOD_CONT;
@@ -247,7 +251,7 @@ class CommandNSRegister : public CommandNSConfirm
this->OnSyntaxError(u, "");
else if (time(NULL) < u->lastnickreg + Config.NSRegDelay)
notice_lang(Config.s_NickServ, u, NICK_REG_PLEASE_WAIT, (u->lastnickreg + Config.NSRegDelay) - time(NULL));
- else if ((na = findnick(u->nick.c_str())))
+ else if ((na = findnick(u->nick)))
{
/* i.e. there's already such a nick regged */
if (na->HasFlag(NS_FORBIDDEN))
@@ -279,7 +283,7 @@ class CommandNSRegister : public CommandNSConfirm
FOREACH_MOD(I_OnMakeNickRequest, OnMakeNickRequest(nr));
if (Config.NSEmailReg)
{
- if (!do_sendregmail(u, nr))
+ if (SendRegmail(u, nr))
{
notice_lang(Config.s_NickServ, u, NICK_ENTER_REG_CODE, email, Config.s_NickServ);
Alog() << Config.s_NickServ << ": sent registration verification code to " << nr->email;
@@ -315,6 +319,11 @@ class CommandNSRegister : public CommandNSConfirm
else
syntax_error(Config.s_NickServ, u, "REGISTER", NICK_REGISTER_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_REGISTER);
+ }
};
class CommandNSResend : public Command
@@ -330,14 +339,14 @@ class CommandNSResend : public Command
NickRequest *nr = NULL;
if (Config.NSEmailReg)
{
- if ((nr = findrequestnick(u->nick.c_str())))
+ if ((nr = findrequestnick(u->nick)))
{
if (time(NULL) < nr->lastmail + Config.NSResendDelay)
{
notice_lang(Config.s_NickServ, u, MAIL_LATER);
return MOD_CONT;
}
- if (!do_sendregmail(u, nr))
+ if (!SendRegmail(u, nr))
{
nr->lastmail = time(NULL);
notice_lang(Config.s_NickServ, u, NICK_REG_RESENT, nr->email);
@@ -358,6 +367,11 @@ class CommandNSResend : public Command
notice_help(Config.s_NickServ, u, NICK_HELP_RESEND);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RESEND);
+ }
};
class NSRegister : public Module
@@ -369,50 +383,20 @@ class NSRegister : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSRegister());
- this->AddCommand(NICKSERV, new CommandNSConfirm("CONFIRM", 1, 1));
- this->AddCommand(NICKSERV, new CommandNSResend());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_REGISTER);
- if (Config.NSEmailReg)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_CONFIRM);
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RESEND);
- }
+ this->AddCommand(NickServ, new CommandNSRegister());
+ this->AddCommand(NickServ, new CommandNSConfirm("CONFIRM", 1, 1));
+ this->AddCommand(NickServ, new CommandNSResend());
}
};
-/*************************************************************************/
-
-int do_sendregmail(User *u, NickRequest *nr)
+static bool SendRegmail(User *u, NickRequest *nr)
{
- MailInfo *mail = NULL;
- char buf[BUFSIZE];
-
- if (!nr && !u)
- return -1;
- snprintf(buf, sizeof(buf), getstring(NICK_REG_MAIL_SUBJECT), nr->nick);
- mail = MailRegBegin(u, nr, buf, Config.s_NickServ);
- if (!mail)
- return -1;
- fprintf(mail->pipe, "%s", getstring(NICK_REG_MAIL_HEAD));
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring(NICK_REG_MAIL_LINE_1), nr->nick);
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring(NICK_REG_MAIL_LINE_2), Config.s_NickServ, nr->passcode.c_str());
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, "%s", getstring(NICK_REG_MAIL_LINE_3));
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, "%s", getstring(NICK_REG_MAIL_LINE_4));
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring(NICK_REG_MAIL_LINE_5), Config.NetworkName);
- fprintf(mail->pipe, "\n.\n");
- MailEnd(mail);
- return 0;
+ char subject[BUFSIZE], message[BUFSIZE];
+
+ snprintf(subject, sizeof(subject), getstring(NICK_REG_MAIL_SUBJECT), nr->nick);
+ snprintf(message, sizeof(message), getstring(NICK_REG_MAIL), nr->nick, Config.NetworkName, Config.s_NickServ, nr->passcode.c_str(), Config.NetworkName);
+
+ return Mail(u, nr, Config.s_NickServ, subject, message);
}
MODULE_INIT(NSRegister)
diff --git a/src/core/ns_release.c b/src/core/ns_release.cpp
index 0855bc46d..7efcdae88 100644
--- a/src/core/ns_release.c
+++ b/src/core/ns_release.cpp
@@ -85,6 +85,11 @@ class CommandNSRelease : public Command
{
syntax_error(Config.s_NickServ, u, "RELEASE", NICK_RELEASE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RELEASE);
+ }
};
class NSRelease : public Module
@@ -96,13 +101,7 @@ class NSRelease : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSRelease());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RELEASE);
+ this->AddCommand(NickServ, new CommandNSRelease());
}
};
diff --git a/src/core/ns_resetpass.c b/src/core/ns_resetpass.cpp
index c47fa0308..be14caa08 100644
--- a/src/core/ns_resetpass.c
+++ b/src/core/ns_resetpass.cpp
@@ -14,6 +14,8 @@
#include "module.h"
+static bool SendResetEmail(User *u, NickAlias *na);
+
class CommandNSResetPass : public Command
{
public:
@@ -27,47 +29,17 @@ class CommandNSResetPass : public Command
if (Config.RestrictMail && !u->Account()->HasCommand("nickserv/resetpass"))
notice_lang(Config.s_NickServ, u, ACCESS_DENIED);
- if (!(na = findnick(params[0].c_str())))
+ if (!(na = findnick(params[0])))
notice_lang(Config.s_NickServ, u, NICK_X_NOT_REGISTERED, params[0].c_str());
else if (na->HasFlag(NS_FORBIDDEN))
notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick);
else
{
- char buf[BUFSIZE], message[BUFSIZE];
- snprintf(buf, sizeof(buf), getstring(na, NICK_RESETPASS_SUBJECT), na->nick);
-
- MailInfo *mail = MailBegin(u, na->nc, buf, Config.s_NickServ);
- if (!mail)
- return MOD_CONT;
-
- char passcode[20];
- int min = 1, max = 62;
- int chars[] = {
- ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
- 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
- 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
- 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
- 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
- };
-
- int idx;
- for (idx = 0; idx < 20; ++idx)
- passcode[idx] = chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min];
- passcode[idx] = '\0';
-
- snprintf(message, sizeof(message), getstring(na, NICK_RESETPASS_MESSAGE), na->nick, Config.s_NickServ, passcode, Config.NetworkName);
- fprintf(mail->pipe, "%s", message);
- fprintf(mail->pipe, "\n.\n");
- MailEnd(mail);
-
- na->nc->Shrink("ns_resetpass_code");
- na->nc->Shrink("ns_resetpass_time");
-
- na->nc->Extend("ns_resetpass_code", new ExtensibleItemPointerArray<char>(sstrdup(passcode)));
- na->nc->Extend("ns_resetpass_time", new ExtensibleItemRegular<time_t>(time(NULL)));
-
- Alog() << Config.s_NickServ << ": " << u->GetMask() << " used RESETPASS on " << na->nick << " (" << na->nc->display << ")";
- notice_lang(Config.s_NickServ, u, NICK_RESETPASS_COMPLETE, na->nick);
+ if (SendResetEmail(u, na))
+ {
+ Alog() << Config.s_NickServ << ": " << u->GetMask() << " used RESETPASS on " << na->nick << " (" << na->nc->display << ")";
+ notice_lang(Config.s_NickServ, u, NICK_RESETPASS_COMPLETE, na->nick);
+ }
}
return MOD_CONT;
@@ -83,6 +55,11 @@ class CommandNSResetPass : public Command
{
syntax_error(Config.s_NickServ, u, "RESETPASS", NICK_RESETPASS_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RESETPASS);
+ }
};
class NSResetPass : public Module
@@ -97,27 +74,20 @@ class NSResetPass : public Module
if (!Config.UseMail)
throw ModuleException("Not using mail.");
- this->AddCommand(NICKSERV, new CommandNSResetPass());
-
- Implementation i[] = { I_OnNickServHelp, I_OnPreCommand };
- ModuleManager::Attach(i, this, 2);
- }
+ this->AddCommand(NickServ, new CommandNSResetPass());
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_RESETPASS);
+ ModuleManager::Attach(I_OnPreCommand, this);
}
EventReturn OnPreCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> &params)
{
- time_t t;
- char *c;
-
if (service == Config.s_NickServ && command == "CONFIRM" && !params.empty())
{
NickAlias *na = findnick(u->nick);
- if (na && na->nc->GetExtArray("ns_resetpass_code", c) && na->nc->GetExtRegular<time_t>("ns_resetpass_time", t))
+ time_t t;
+ std::string c;
+ if (na && na->nc->GetExtRegular("ns_resetpass_code", c) && na->nc->GetExtRegular("ns_resetpass_time", t))
{
if (t < time(NULL) - 3600)
{
@@ -167,4 +137,35 @@ class NSResetPass : public Module
}
};
+static bool SendResetEmail(User *u, NickAlias *na)
+{
+ char subject[BUFSIZE], message[BUFSIZE], passcode[20];
+
+ snprintf(subject, sizeof(subject), getstring(na, NICK_RESETPASS_SUBJECT), na->nick);
+
+ int min = 1, max = 62;
+ int chars[] = {
+ ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
+ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
+ 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
+ };
+
+ int idx;
+ for (idx = 0; idx < 20; ++idx)
+ passcode[idx] = chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min];
+ passcode[idx] = '\0';
+
+ snprintf(message, sizeof(message), getstring(na, NICK_RESETPASS_MESSAGE), na->nick, Config.s_NickServ, passcode, Config.NetworkName);
+
+ na->nc->Shrink("ns_resetpass_code");
+ na->nc->Shrink("ns_resetpass_time");
+
+ na->nc->Extend("ns_resetpass_code", new ExtensibleItemRegular<std::string>(passcode));
+ na->nc->Extend("ns_resetpass_time", new ExtensibleItemRegular<time_t>(time(NULL)));
+
+ return Mail(u, na->nc, Config.s_NickServ, subject, message);
+}
+
MODULE_INIT(NSResetPass)
diff --git a/src/core/ns_saset.c b/src/core/ns_saset.c
deleted file mode 100644
index 6978ba356..000000000
--- a/src/core/ns_saset.c
+++ /dev/null
@@ -1,599 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-/*************************************************************************/
-
-#include "module.h"
-
-class CommandNSSASet : public Command
-{
-private:
- CommandReturn DoSetDisplay(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 2 ? params[2] : "";
- int i;
- NickAlias *na;
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "DISPLAY");
- return MOD_CONT;
- }
-
- /* First check whether param is a valid nick of the group */
- for (i = 0; i < nc->aliases.count; ++i)
- {
- na = static_cast<NickAlias *>(nc->aliases.list[i]);
- if (na->nick == param)
- {
- param = na->nick; /* Because case may differ */
- break;
- }
- }
-
- if (i == nc->aliases.count)
- {
- notice_lang(Config.s_NickServ, u, NICK_SASET_DISPLAY_INVALID, nc->display);
- return MOD_CONT;
- }
-
- change_core_display(nc, param.c_str());
- notice_lang(Config.s_NickServ, u, NICK_SASET_DISPLAY_CHANGED, nc->display);
- return MOD_CONT;
- }
-
- CommandReturn DoSetPassword(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 2 ? params[2] : "";
- std::string buf, tmp_pass;
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "PASSWORD");
- return MOD_CONT;
- }
-
- int len = param.size();
-
- if (Config.NSSecureAdmins && u->Account() != nc && nc->IsServicesOper())
- {
- notice_lang(Config.s_NickServ, u, ACCESS_DENIED);
- return MOD_CONT;
- }
- else if (nc->display == param || (Config.StrictPasswords && len < 5))
- {
- notice_lang(Config.s_NickServ, u, MORE_OBSCURE_PASSWORD);
- return MOD_CONT;
- }
- else if (len > Config.PassLen)
- {
- notice_lang(Config.s_NickServ, u, PASSWORD_TOO_LONG);
- return MOD_CONT;
- }
- buf = param.c_str(); /* conversion from ci::string to std::string */
- if (enc_encrypt(buf, nc->pass))
- {
- Alog() << Config.s_NickServ << ": Failed to encrypt password for " << nc->display << " (set)";
- notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_FAILED, nc->display);
- return MOD_CONT;
- }
-
- if (enc_decrypt(nc->pass, tmp_pass) == 1)
- notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_CHANGED_TO, nc->display, tmp_pass.c_str());
- else
- notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_CHANGED, nc->display);
-
- Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SASET PASSWORD on " << nc->display << " (e-mail: "<< (nc->email ? nc->email : "none") << ")";
- if (Config.WallSetpass)
- ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used SASET PASSWORD on \2%s\2", u->nick.c_str(), nc->display);
- return MOD_CONT;
- }
-
- CommandReturn DoSetUrl(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- const char *param = params.size() > 2 ? params[2].c_str() : NULL;
-
- if (nc->url)
- delete [] nc->url;
-
- if (param)
- {
- nc->url = sstrdup(param);
- notice_lang(Config.s_NickServ, u, NICK_SASET_URL_CHANGED, nc->display, param);
- }
- else
- {
- nc->url = NULL;
- notice_lang(Config.s_NickServ, u, NICK_SASET_URL_UNSET, nc->display);
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetEmail(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- const char *param = params.size() > 2 ? params[2].c_str() : NULL;
-
- if (!param && Config.NSForceEmail)
- {
- notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_UNSET_IMPOSSIBLE);
- return MOD_CONT;
- }
- else if (Config.NSSecureAdmins && u->Account() != nc && nc->IsServicesOper())
- {
- notice_lang(Config.s_NickServ, u, ACCESS_DENIED);
- return MOD_CONT;
- }
- else if (param && !MailValidate(param))
- {
- notice_lang(Config.s_NickServ, u, MAIL_X_INVALID, param);
- return MOD_CONT;
- }
-
- Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SASET EMAIL on " << nc->display << " (e-mail: " << (nc->email ? nc->email : "none") << ")";
-
- if (nc->email)
- delete [] nc->email;
-
- if (param)
- {
- nc->email = sstrdup(param);
- notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_CHANGED, nc->display, param);
- }
- else
- {
- nc->email = NULL;
- notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_UNSET, nc->display);
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetICQ(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- const char *param = params.size() > 2 ? params[2].c_str() : NULL;
-
- if (param)
- {
- int32 tmp = atol(param);
- if (!tmp)
- notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_INVALID, param);
- else
- {
- nc->icq = tmp;
- notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_CHANGED, nc->display, param);
- }
- }
- else
- {
- nc->icq = 0;
- notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_UNSET, nc->display);
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetGreet(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- const char *param = params.size() > 2 ? params[2].c_str() : NULL;
-
- if (nc->greet)
- delete [] nc->greet;
-
- if (param)
- {
- char buf[BUFSIZE];
- const char *rest = params.size() > 3 ? params[3].c_str() : NULL;
-
- snprintf(buf, sizeof(buf), "%s%s%s", param, rest ? " " : "", rest ? rest : "");
-
- nc->greet = sstrdup(buf);
- notice_lang(Config.s_NickServ, u, NICK_SASET_GREET_CHANGED, nc->display, buf);
- }
- else
- {
- nc->greet = NULL;
- notice_lang(Config.s_NickServ, u, NICK_SASET_GREET_UNSET, nc->display);
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetKill(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 2 ? params[2] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "KILL");
- return MOD_CONT;
- }
-
- if (param == "ON")
- {
- nc->SetFlag(NI_KILLPROTECT);
- nc->UnsetFlag(NI_KILL_QUICK);
- nc->UnsetFlag(NI_KILL_IMMED);
- notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_ON, nc->display);
- }
- else if (param == "QUICK")
- {
- nc->SetFlag(NI_KILLPROTECT);
- nc->SetFlag(NI_KILL_QUICK);
- nc->UnsetFlag(NI_KILL_IMMED);
- notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_QUICK, nc->display);
- }
- else if (param == "IMMED")
- {
- if (Config.NSAllowKillImmed)
- {
- nc->SetFlag(NI_KILLPROTECT);
- nc->SetFlag(NI_KILL_IMMED);
- nc->UnsetFlag(NI_KILL_QUICK);
- notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_IMMED, nc->display);
- }
- else
- notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_IMMED_DISABLED);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(NI_KILLPROTECT);
- nc->UnsetFlag(NI_KILL_QUICK);
- nc->UnsetFlag(NI_KILL_IMMED);
- notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_OFF, nc->display);
- }
- else
- syntax_error(Config.s_NickServ, u, "SASET KILL", Config.NSAllowKillImmed ? NICK_SASET_KILL_IMMED_SYNTAX : NICK_SASET_KILL_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetSecure(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 2 ? params[2] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "SECURE");
- return MOD_CONT;
- }
-
- if (param == "ON")
- {
- nc->SetFlag(NI_SECURE);
- notice_lang(Config.s_NickServ, u, NICK_SASET_SECURE_ON, nc->display);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(NI_SECURE);
- notice_lang(Config.s_NickServ, u, NICK_SASET_SECURE_OFF, nc->display);
- }
- else
- syntax_error(Config.s_NickServ, u, "SASET SECURE", NICK_SASET_SECURE_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetPrivate(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 2 ? params[2] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "PRIVATE");
- return MOD_CONT;
- }
-
- if (param == "ON")
- {
- nc->SetFlag(NI_PRIVATE);
- notice_lang(Config.s_NickServ, u, NICK_SASET_PRIVATE_ON, nc->display);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(NI_PRIVATE);
- notice_lang(Config.s_NickServ, u, NICK_SASET_PRIVATE_OFF, nc->display);
- }
- else
- syntax_error(Config.s_NickServ, u, "SASET PRIVATE", NICK_SASET_PRIVATE_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetMsg(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 2 ? params[2] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "MSG");
- return MOD_CONT;
- }
-
- if (!Config.UsePrivmsg)
- {
- notice_lang(Config.s_NickServ, u, NICK_SASET_OPTION_DISABLED, "MSG");
- return MOD_CONT;
- }
-
- if (param == "ON")
- {
- nc->SetFlag(NI_MSG);
- notice_lang(Config.s_NickServ, u, NICK_SASET_MSG_ON, nc->display);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(NI_MSG);
- notice_lang(Config.s_NickServ, u, NICK_SASET_MSG_OFF, nc->display);
- }
- else
- syntax_error(Config.s_NickServ, u, "SASET MSG", NICK_SASET_MSG_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetHide(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 2 ? params[2] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "HIDE");
- return MOD_CONT;
- }
-
- int onmsg, offmsg;
- NickCoreFlag flag;
-
- if (param == "EMAIL")
- {
- flag = NI_HIDE_EMAIL;
- onmsg = NICK_SASET_HIDE_EMAIL_ON;
- offmsg = NICK_SASET_HIDE_EMAIL_OFF;
- }
- else if (param == "USERMASK")
- {
- flag = NI_HIDE_MASK;
- onmsg = NICK_SASET_HIDE_MASK_ON;
- offmsg = NICK_SASET_HIDE_MASK_OFF;
- }
- else if (param == "STATUS")
- {
- flag = NI_HIDE_STATUS;
- onmsg = NICK_SASET_HIDE_STATUS_ON;
- offmsg = NICK_SASET_HIDE_STATUS_OFF;
- }
- else if (param == "QUIT")
- {
- flag = NI_HIDE_QUIT;
- onmsg = NICK_SASET_HIDE_QUIT_ON;
- offmsg = NICK_SASET_HIDE_QUIT_OFF;
- }
- else
- {
- syntax_error(Config.s_NickServ, u, "SASET HIDE", NICK_SASET_HIDE_SYNTAX);
- return MOD_CONT;
- }
-
- param = params.size() > 3 ? params[3] : "";
- if (param.empty())
- syntax_error(Config.s_NickServ, u, "SASET HIDE", NICK_SASET_HIDE_SYNTAX);
- else if (param == "ON")
- {
- nc->SetFlag(flag);
- notice_lang(Config.s_NickServ, u, onmsg, nc->display, Config.s_NickServ);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(flag);
- notice_lang(Config.s_NickServ, u, offmsg, nc->display, Config.s_NickServ);
- }
- else
- syntax_error(Config.s_NickServ, u, "SASET HIDE", NICK_SASET_HIDE_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetNoExpire(User *u, const std::vector<ci::string> &params, NickAlias *na)
- {
- ci::string param = params.size() > 2 ? params[2] : "";
-
- if (param.empty())
- {
- syntax_error(Config.s_NickServ, u, "SASET NOEXPIRE", NICK_SASET_NOEXPIRE_SYNTAX);
- return MOD_CONT;
- }
-
- if (param == "ON")
- {
- na->SetFlag(NS_NO_EXPIRE);
- notice_lang(Config.s_NickServ, u, NICK_SASET_NOEXPIRE_ON, na->nick);
- }
- else if (param == "OFF")
- {
- na->UnsetFlag(NS_NO_EXPIRE);
- notice_lang(Config.s_NickServ, u, NICK_SASET_NOEXPIRE_OFF, na->nick);
- }
- else
- syntax_error(Config.s_NickServ, u, "SASET NOEXPIRE", NICK_SASET_NOEXPIRE_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetAutoOP(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 2 ? params[2] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "AUTOOP");
- return MOD_CONT;
- }
-
- if (param == "ON")
- {
- nc->SetFlag(NI_AUTOOP);
- notice_lang(Config.s_NickServ, u, NICK_SASET_AUTOOP_ON, nc->display);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(NI_AUTOOP);
- notice_lang(Config.s_NickServ, u, NICK_SASET_AUTOOP_OFF, nc->display);
- }
- else
- syntax_error(Config.s_NickServ, u, "SET AUTOOP", NICK_SASET_AUTOOP_SYNTAX);
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetLanguage(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- const char *param = params.size() > 2 ? params[2].c_str() : NULL;
-
- if (!param)
- {
- this->OnSyntaxError(u, "LANGUAGE");
- return MOD_CONT;
- }
-
- int langnum;
-
- if (param[strspn(param, "0123456789")]) /* i.e. not a number */
- {
- syntax_error(Config.s_NickServ, u, "SASET LANGUAGE", NICK_SASET_LANGUAGE_SYNTAX);
- return MOD_CONT;
- }
- langnum = atoi(param) - 1;
- if (langnum < 0 || langnum >= NUM_LANGS || langlist[langnum] < 0)
- {
- notice_lang(Config.s_NickServ, u, NICK_SASET_LANGUAGE_UNKNOWN, langnum + 1, Config.s_NickServ);
- return MOD_CONT;
- }
- nc->language = langlist[langnum];
- notice_lang(Config.s_NickServ, u, NICK_SASET_LANGUAGE_CHANGED);
-
- return MOD_CONT;
- }
-public:
- CommandNSSASet() : Command("SASET", 2, 4, "nickserv/saset")
- {
- }
-
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
- {
- const char *nick = params[0].c_str();
- ci::string cmd = params[1];
-
- NickAlias *na;
-
- if (readonly)
- {
- notice_lang(Config.s_NickServ, u, NICK_SASET_DISABLED);
- return MOD_CONT;
- }
- if (!(na = findnick(nick)))
- {
- notice_lang(Config.s_NickServ, u, NICK_SASET_BAD_NICK, nick);
- return MOD_CONT;
- }
-
- if (na->HasFlag(NS_FORBIDDEN))
- notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick);
- else if (na->nc->HasFlag(NI_SUSPENDED))
- notice_lang(Config.s_NickServ, u, NICK_X_SUSPENDED, na->nick);
- else if (cmd == "DISPLAY")
- return this->DoSetDisplay(u, params, na->nc);
- else if (cmd == "PASSWORD")
- return this->DoSetPassword(u, params, na->nc);
- else if (cmd == "URL")
- return this->DoSetUrl(u, params, na->nc);
- else if (cmd == "EMAIL")
- return this->DoSetEmail(u, params, na->nc);
- else if (cmd == "ICQ")
- return this->DoSetICQ(u, params, na->nc);
- else if (cmd == "GREET")
- return this->DoSetGreet(u, params, na->nc);
- else if (cmd == "KILL")
- return this->DoSetKill(u, params, na->nc);
- else if (cmd == "SECURE")
- return this->DoSetSecure(u, params, na->nc);
- else if (cmd == "PRIVATE")
- return this->DoSetPrivate(u, params, na->nc);
- else if (cmd == "MSG")
- return this->DoSetMsg(u, params, na->nc);
- else if (cmd == "HIDE")
- return this->DoSetHide(u, params, na->nc);
- else if (cmd == "NOEXPIRE")
- return this->DoSetNoExpire(u, params, na);
- else if (cmd == "AUTOOP")
- return this->DoSetAutoOP(u, params, na->nc);
- else if (cmd == "LANGUAGE")
- return this->DoSetLanguage(u, params, na->nc);
- else
- notice_lang(Config.s_NickServ, u, NICK_SASET_UNKNOWN_OPTION, cmd.c_str());
- return MOD_CONT;
- }
-
- bool OnHelp(User *u, const ci::string &subcommand)
- {
- if (subcommand.empty())
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET);
- else if (subcommand == "DISPLAY")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_DISPLAY);
- else if (subcommand == "PASSWORD")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_PASSWORD);
- else if (subcommand == "URL")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_URL);
- else if (subcommand == "EMAIL")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_EMAIL);
- else if (subcommand == "ICQ")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_ICQ);
- else if (subcommand == "GREET")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_GREET);
- else if (subcommand == "KILL")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_KILL);
- else if (subcommand == "SECURE")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_SECURE);
- else if (subcommand == "PRIVATE")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_PRIVATE);
- else if (subcommand == "MSG")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_MSG);
- else if (subcommand == "HIDE")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_HIDE);
- else if (subcommand == "NOEXPIRE")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_NOEXPIRE);
- else if (subcommand == "AUTOOP")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_AUTOOP);
- else if (subcommand == "LANGUAGE")
- notice_help(Config.s_NickServ, u, NICK_HELP_SASET_LANGUAGE);
- else
- return false;
-
- return true;
- }
-
- void OnSyntaxError(User *u, const ci::string &subcommand)
- {
- syntax_error(Config.s_NickServ, u, "SASET", NICK_SASET_SYNTAX);
- }
-};
-
-class NSSASet : public Module
-{
-public:
- NSSASet(const std::string &modname, const std::string &creator) : Module(modname, creator)
- {
- this->SetAuthor("Anope");
- this->SetVersion(VERSION_STRING);
- this->SetType(CORE);
-
- this->AddCommand(NICKSERV, new CommandNSSASet());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET);
- }
-};
-
-MODULE_INIT(NSSASet)
diff --git a/src/core/ns_saset.cpp b/src/core/ns_saset.cpp
new file mode 100644
index 000000000..ccc6be928
--- /dev/null
+++ b/src/core/ns_saset.cpp
@@ -0,0 +1,255 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSASet : public Command
+{
+ std::map<ci::string, Command *> subcommands;
+ public:
+ CommandNSSASet(const ci::string &cname) : Command(cname, 2, 4)
+ {
+ }
+
+ ~CommandNSSASet()
+ {
+ for (std::map<ci::string, Command *>::const_iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ {
+ delete it->second;
+ }
+ this->subcommands.clear();
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ const char *nick = params[0].c_str();
+ ci::string cmd = params[1];
+
+ if (readonly)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SASET_DISABLED);
+ return MOD_CONT;
+ }
+
+ NickAlias *na = findnick(nick);
+ if (!na)
+ notice_lang(Config.s_NickServ, u, NICK_SASET_BAD_NICK, nick);
+ else if (na->HasFlag(NS_FORBIDDEN))
+ notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick);
+ else if (na->nc->HasFlag(NI_SUSPENDED))
+ notice_lang(Config.s_NickServ, u, NICK_X_SUSPENDED, na->nick);
+ else
+ {
+ Command *c = this->FindCommand(params[1]);
+
+ if (c)
+ {
+ ci::string cmdparams = na->nc->display;
+ for (std::vector<ci::string>::const_iterator it = params.begin() + 1; it != params.end(); ++it)
+ cmdparams += " " + *it;
+ mod_run_cmd(NickServ, u, c, params[1], cmdparams);
+ }
+ else
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SASET_UNKNOWN_OPTION, cmd.c_str());
+ }
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ if (subcommand.empty())
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_HEAD);
+ for (std::map<ci::string, Command *>::iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ it->second->OnServHelp(u);
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_TAIL);
+ return true;
+ }
+ else
+ {
+ Command *c = this->FindCommand(subcommand);
+
+ if (c)
+ {
+ return c->OnHelp(u, subcommand);
+ }
+ }
+
+ return false;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_NickServ, u, "SASET", NICK_SASET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET);
+ }
+
+ bool AddSubcommand(Command *c)
+ {
+ return this->subcommands.insert(std::make_pair(c->name, c)).second;
+ }
+
+ bool DelSubcommand(const ci::string &command)
+ {
+ return this->subcommands.erase(command);
+ }
+
+ Command *FindCommand(const ci::string &subcommand)
+ {
+ std::map<ci::string, Command *>::const_iterator it = this->subcommands.find(subcommand);
+
+ if (it != this->subcommands.end())
+ {
+ return it->second;
+ }
+
+ return NULL;
+ }
+};
+
+class CommandNSSASetDisplay : public Command
+{
+ public:
+ CommandNSSASetDisplay(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/display")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ NickAlias *na = findnick(params[1]);
+ if (!na || na->nc != nc)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SASET_DISPLAY_INVALID, nc->display);
+ return MOD_CONT;
+ }
+
+ change_core_display(nc, params[1].c_str());
+ notice_lang(Config.s_NickServ, u, NICK_SASET_DISPLAY_CHANGED, nc->display);
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_DISPLAY);
+ return true;
+ }
+
+ void OnSyntaxError(User *u)
+ {
+ // XXX
+ syntax_error(Config.s_NickServ, u, "SASET", NICK_SASET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_DISPLAY);
+ }
+};
+
+class CommandNSSASetPassword : public Command
+{
+ public:
+ CommandNSSASetPassword(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/password")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ size_t len = params[1].size();
+
+ if (Config.NSSecureAdmins && u->Account() != nc && nc->IsServicesOper())
+ {
+ notice_lang(Config.s_NickServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+ else if (nc->display == params[1] || (Config.StrictPasswords && len < 5))
+ {
+ notice_lang(Config.s_NickServ, u, MORE_OBSCURE_PASSWORD);
+ return MOD_CONT;
+ }
+ else if (len > Config.PassLen)
+ {
+ notice_lang(Config.s_NickServ, u, PASSWORD_TOO_LONG);
+ return MOD_CONT;
+ }
+
+ std::string buf = params[1].c_str();
+ if (enc_encrypt(buf, nc->pass))
+ {
+ Alog() << Config.s_NickServ << ": Failed to encrypt password for " << nc->display << " (saset)";
+ notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_FAILED, nc->display);
+ return MOD_CONT;
+ }
+
+ std::string tmp_pass;
+ if (enc_decrypt(nc->pass, tmp_pass) == 1)
+ notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_CHANGED_TO, nc->display, tmp_pass.c_str());
+ else
+ notice_lang(Config.s_NickServ, u, NICK_SASET_PASSWORD_CHANGED, nc->display);
+
+ Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SASET PASSWORD on " << nc->display << " (e-mail: "<< (nc->email ? nc->email : "none") << ")";
+
+ if (Config.WallSetpass)
+ ircdproto->SendGlobops(NickServ, "\2%s\2 used SASET PASSWORD on \2%s\2", u->nick.c_str(), nc->display);
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_PASSWORD);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SASET", NICK_SASET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_PASSWORD);
+ }
+};
+
+class NSSASet : public Module
+{
+public:
+ NSSASet(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion(VERSION_STRING);
+ this->SetType(CORE);
+
+ Command *c = new CommandNSSASet("SASET");
+ this->AddCommand(NickServ, c);
+ c->AddSubcommand(new CommandNSSASetDisplay("DISPLAY"));
+ c->AddSubcommand(new CommandNSSASetPassword("PASSWORD"));
+ }
+};
+
+MODULE_INIT(NSSASet)
diff --git a/src/core/ns_saset_noexpire.cpp b/src/core/ns_saset_noexpire.cpp
new file mode 100644
index 000000000..a5df0bb19
--- /dev/null
+++ b/src/core/ns_saset_noexpire.cpp
@@ -0,0 +1,87 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSASetNoexpire : public Command
+{
+ public:
+ CommandNSSASetNoexpire(const ci::string &cname) : Command(cname, 1, 2, "nickserv/saset/noexpire")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickAlias *na = findnick(params[0]);
+ assert(na);
+
+ ci::string param = params.size() > 1 ? params[1] : "";
+
+ if (param == "ON")
+ {
+ na->SetFlag(NS_NO_EXPIRE);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_NOEXPIRE_ON, na->nick);
+ }
+ else if (param == "OFF")
+ {
+ na->UnsetFlag(NS_NO_EXPIRE);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_NOEXPIRE_OFF, na->nick);
+ }
+ else
+ this->OnSyntaxError(u, "NOEXPIRE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_NOEXPIRE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SASET NOEXPIRE", NICK_SASET_NOEXPIRE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_NOEXPIRE);
+ }
+};
+
+class NSSASetNoexpire : public Module
+{
+ public:
+ NSSASetNoexpire(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandNSSASetNoexpire("NOEXPIRE"));
+ }
+
+ ~NSSASetNoexpire()
+ {
+ Command *c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->DelSubcommand("NOEXPRE");
+ }
+};
+
+MODULE_INIT(NSSASetNoexpire)
diff --git a/src/core/ns_sendpass.c b/src/core/ns_sendpass.cpp
index 0ce8f6c5c..6d4358f06 100644
--- a/src/core/ns_sendpass.c
+++ b/src/core/ns_sendpass.cpp
@@ -14,6 +14,8 @@
#include "module.h"
+static bool SendPassMail(User *u, NickAlias *na, const std::string &pass);
+
class CommandNSSendPass : public Command
{
public:
@@ -34,34 +36,14 @@ class CommandNSSendPass : public Command
notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick);
else
{
- char buf[BUFSIZE];
std::string tmp_pass;
if (enc_decrypt(na->nc->pass,tmp_pass) == 1)
{
- MailInfo *mail;
-
- snprintf(buf, sizeof(buf), getstring(na, NICK_SENDPASS_SUBJECT), na->nick);
- mail = MailBegin(u, na->nc, buf, Config.s_NickServ);
- if (!mail)
- return MOD_CONT;
-
- fprintf(mail->pipe, "%s", getstring(na, NICK_SENDPASS_HEAD));
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring(na, NICK_SENDPASS_LINE_1), na->nick);
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring(na, NICK_SENDPASS_LINE_2), tmp_pass.c_str());
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, "%s", getstring(na, NICK_SENDPASS_LINE_3));
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, "%s", getstring(na, NICK_SENDPASS_LINE_4));
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring(na, NICK_SENDPASS_LINE_5), Config.NetworkName);
- fprintf(mail->pipe, "\n.\n");
-
- MailEnd(mail);
-
- Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SENDPASS on " << nick;
- notice_lang(Config.s_NickServ, u, NICK_SENDPASS_OK, nick);
+ if (SendPassMail(u, na, tmp_pass))
+ {
+ Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SENDPASS on " << nick;
+ notice_lang(Config.s_NickServ, u, NICK_SENDPASS_OK, nick);
+ }
}
else
notice_lang(Config.s_NickServ, u, NICK_SENDPASS_UNAVAILABLE);
@@ -80,6 +62,11 @@ class CommandNSSendPass : public Command
{
syntax_error(Config.s_NickServ, u, "SENDPASS", NICK_SENDPASS_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SENDPASS);
+ }
};
class NSSendPass : public Module
@@ -91,7 +78,7 @@ class NSSendPass : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSSendPass());
+ this->AddCommand(NickServ, new CommandNSSendPass());
if (!Config.UseMail)
throw ModuleException("Not using mail, whut.");
@@ -99,13 +86,17 @@ class NSSendPass : public Module
std::string tmp_pass = "plain:tmp";
if (enc_decrypt(tmp_pass, tmp_pass) == -1)
throw ModuleException("Incompatible with the encryption module being used");
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SENDPASS);
}
};
+static bool SendPassMail(User *u, NickAlias *na, const std::string &pass)
+{
+ char subject[BUFSIZE], message[BUFSIZE];
+
+ snprintf(subject, sizeof(subject), getstring(na, NICK_SENDPASS_SUBJECT), na->nick);
+ snprintf(message, sizeof(message), getstring(na, NICK_SENDPASS), na->nick, pass.c_str(), Config.NetworkName);
+
+ return Mail(u, na->nc, Config.s_NickServ, subject, message);
+}
+
MODULE_INIT(NSSendPass)
diff --git a/src/core/ns_set.c b/src/core/ns_set.c
deleted file mode 100644
index 1cd797881..000000000
--- a/src/core/ns_set.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/* NickServ core functions
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-/*************************************************************************/
-
-#include "module.h"
-
-class CommandNSSet : public Command
-{
- private:
- CommandReturn DoSetDisplay(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 1 ? params[1] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "DISPLAY");
- return MOD_CONT;
- }
-
- int i;
- NickAlias *na;
-
- /* First check whether param is a valid nick of the group */
- for (i = 0; i < nc->aliases.count; ++i)
- {
- na = static_cast<NickAlias *>(nc->aliases.list[i]);
- if (na->nick == param)
- {
- param = na->nick; /* Because case may differ */
- break;
- }
- }
-
- if (i == nc->aliases.count)
- {
- notice_lang(Config.s_NickServ, u, NICK_SET_DISPLAY_INVALID);
- return MOD_CONT;
- }
-
- change_core_display(nc, param.c_str());
- notice_lang(Config.s_NickServ, u, NICK_SET_DISPLAY_CHANGED, nc->display);
- return MOD_CONT;
- }
-
- CommandReturn DoSetPassword(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 1 ? params[1] : "";
- std::string buf, tmp_pass;
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "PASSWORD");
- return MOD_CONT;
- }
-
- int len = param.size();
-
- if (nc->display == param || (Config.StrictPasswords && len < 5))
- {
- notice_lang(Config.s_NickServ, u, MORE_OBSCURE_PASSWORD);
- return MOD_CONT;
- }
- else if (len > Config.PassLen)
- {
- notice_lang(Config.s_NickServ, u, PASSWORD_TOO_LONG);
- return MOD_CONT;
- }
-
- buf = param.c_str(); /* conversion from ci::string to std::string */
- if (enc_encrypt(buf, nc->pass) < 0)
- {
- Alog() << Config.s_NickServ << ": Failed to encrypt password for " << nc->display << " (set)";
- notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_FAILED);
- return MOD_CONT;
- }
-
- if (enc_decrypt(nc->pass, tmp_pass) == 1)
- notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_CHANGED_TO, tmp_pass.c_str());
- else
- notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_CHANGED);
-
- Alog() << Config.s_NickServ << ": " << u->GetMask() << " (e-mail: " << (nc->email ? nc->email : "none") << ") changed its password.";
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetLanguage(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- const char *param = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!param)
- {
- this->OnSyntaxError(u, "LANGUAGE");
- return MOD_CONT;
- }
-
- int langnum;
-
- if (param[strspn(param, "0123456789")]) /* i.e. not a number */
- {
- syntax_error(Config.s_NickServ, u, "SET LANGUAGE", NICK_SET_LANGUAGE_SYNTAX);
- return MOD_CONT;
- }
- langnum = atoi(param) - 1;
- if (langnum < 0 || langnum >= NUM_LANGS || langlist[langnum] < 0)
- {
- notice_lang(Config.s_NickServ, u, NICK_SET_LANGUAGE_UNKNOWN, langnum + 1, Config.s_NickServ);
- return MOD_CONT;
- }
- nc->language = langlist[langnum];
- notice_lang(Config.s_NickServ, u, NICK_SET_LANGUAGE_CHANGED);
- return MOD_CONT;
- }
-
- CommandReturn DoSetUrl(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- const char *param = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (nc->url)
- delete [] nc->url;
-
- if (param)
- {
- nc->url = sstrdup(param);
- notice_lang(Config.s_NickServ, u, NICK_SET_URL_CHANGED, param);
- }
- else
- {
- nc->url = NULL;
- notice_lang(Config.s_NickServ, u, NICK_SET_URL_UNSET);
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetEmail(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- const char *param = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!param && Config.NSForceEmail)
- {
- notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_UNSET_IMPOSSIBLE);
- return MOD_CONT;
- }
- else if (param && !MailValidate(param))
- {
- notice_lang(Config.s_NickServ, u, MAIL_X_INVALID, param);
- return MOD_CONT;
- }
-
- Alog() << Config.s_NickServ << ": " << u->GetMask() << " (e-mail: " << (nc->email ? nc->email : "none") << ") changed its e-mail to " << (param ? param : "none");
-
- if (nc->email)
- delete [] nc->email;
-
- if (param)
- {
- nc->email = sstrdup(param);
- notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_CHANGED, param);
- }
- else
- {
- nc->email = NULL;
- notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_UNSET);
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetICQ(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- const char *param = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (param)
- {
- int32 tmp = atol(param);
- if (!tmp)
- notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_INVALID, param);
- else
- {
- nc->icq = tmp;
- notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_CHANGED, param);
- }
- }
- else
- {
- nc->icq = 0;
- notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_UNSET);
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetGreet(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- const char *param = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (nc->greet)
- delete [] nc->greet;
-
- if (param)
- {
- char buf[BUFSIZE];
- const char *rest = params.size() > 2 ? params[2].c_str() : NULL;
-
- snprintf(buf, sizeof(buf), "%s%s%s", param, rest ? " " : "", rest ? rest : "");
-
- nc->greet = sstrdup(buf);
- notice_lang(Config.s_NickServ, u, NICK_SET_GREET_CHANGED, buf);
- }
- else
- {
- nc->greet = NULL;
- notice_lang(Config.s_NickServ, u, NICK_SET_GREET_UNSET);
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetKill(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 1 ? params[1] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "KILL");
- return MOD_CONT;
- }
-
- if (param == "ON")
- {
- nc->SetFlag(NI_KILLPROTECT);
- nc->UnsetFlag(NI_KILL_QUICK);
- nc->UnsetFlag(NI_KILL_IMMED);
- notice_lang(Config.s_NickServ, u, NICK_SET_KILL_ON);
- }
- else if (param == "QUICK")
- {
- nc->SetFlag(NI_KILLPROTECT);
- nc->SetFlag(NI_KILL_QUICK);
- nc->UnsetFlag(NI_KILL_IMMED);
- notice_lang(Config.s_NickServ, u, NICK_SET_KILL_QUICK);
- }
- else if (param == "IMMED")
- {
- if (Config.NSAllowKillImmed)
- {
- nc->SetFlag(NI_KILLPROTECT);
- nc->SetFlag(NI_KILL_IMMED);
- nc->UnsetFlag(NI_KILL_QUICK);
- notice_lang(Config.s_NickServ, u, NICK_SET_KILL_IMMED);
- }
- else
- notice_lang(Config.s_NickServ, u, NICK_SET_KILL_IMMED_DISABLED);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(NI_KILLPROTECT);
- nc->UnsetFlag(NI_KILL_QUICK);
- nc->UnsetFlag(NI_KILL_IMMED);
- notice_lang(Config.s_NickServ, u, NICK_SET_KILL_OFF);
- }
- else
- syntax_error(Config.s_NickServ, u, "SET KILL", Config.NSAllowKillImmed ? NICK_SET_KILL_IMMED_SYNTAX : NICK_SET_KILL_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetSecure(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 1 ? params[1] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "SECURE");
- return MOD_CONT;
- }
-
- if (param == "ON")
- {
- nc->SetFlag(NI_SECURE);
- notice_lang(Config.s_NickServ, u, NICK_SET_SECURE_ON);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(NI_SECURE);
- notice_lang(Config.s_NickServ, u, NICK_SET_SECURE_OFF);
- }
- else
- syntax_error(Config.s_NickServ, u, "SET SECURE", NICK_SET_SECURE_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetPrivate(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 1 ? params[1] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "PRIVATE");
- return MOD_CONT;
- }
-
- if (param == "ON")
- {
- nc->SetFlag(NI_PRIVATE);
- notice_lang(Config.s_NickServ, u, NICK_SET_PRIVATE_ON);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(NI_PRIVATE);
- notice_lang(Config.s_NickServ, u, NICK_SET_PRIVATE_OFF);
- }
- else
- syntax_error(Config.s_NickServ, u, "SET PRIVATE", NICK_SET_PRIVATE_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetMsg(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 1 ? params[1] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "MSG");
- return MOD_CONT;
- }
-
- if (!Config.UsePrivmsg)
- {
- notice_lang(Config.s_NickServ, u, NICK_SET_OPTION_DISABLED, "MSG");
- return MOD_CONT;
- }
-
- if (param == "ON")
- {
- nc->SetFlag(NI_MSG);
- notice_lang(Config.s_NickServ, u, NICK_SET_MSG_ON);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(NI_MSG);
- notice_lang(Config.s_NickServ, u, NICK_SET_MSG_OFF);
- }
- else
- syntax_error(Config.s_NickServ, u, "SET MSG", NICK_SET_MSG_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetHide(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 1 ? params[1] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "HIDE");
- return MOD_CONT;
- }
-
- int onmsg, offmsg;
- NickCoreFlag flag;
-
- if (param == "EMAIL")
- {
- flag = NI_HIDE_EMAIL;
- onmsg = NICK_SET_HIDE_EMAIL_ON;
- offmsg = NICK_SET_HIDE_EMAIL_OFF;
- }
- else if (param == "USERMASK")
- {
- flag = NI_HIDE_MASK;
- onmsg = NICK_SET_HIDE_MASK_ON;
- offmsg = NICK_SET_HIDE_MASK_OFF;
- }
- else if (param == "STATUS")
- {
- flag = NI_HIDE_STATUS;
- onmsg = NICK_SET_HIDE_STATUS_ON;
- offmsg = NICK_SET_HIDE_STATUS_OFF;
- }
- else if (param == "QUIT")
- {
- flag = NI_HIDE_QUIT;
- onmsg = NICK_SET_HIDE_QUIT_ON;
- offmsg = NICK_SET_HIDE_QUIT_OFF;
- }
- else
- {
- syntax_error(Config.s_NickServ, u, "SET HIDE", NICK_SET_HIDE_SYNTAX);
- return MOD_CONT;
- }
-
- param = params.size() > 2 ? params[2] : "";
- if (param.empty())
- syntax_error(Config.s_NickServ, u, "SET HIDE", NICK_SET_HIDE_SYNTAX);
- else if (param == "ON")
- {
- nc->SetFlag(flag);
- notice_lang(Config.s_NickServ, u, onmsg, Config.s_NickServ);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(flag);
- notice_lang(Config.s_NickServ, u, offmsg, Config.s_NickServ);
- }
- else
- syntax_error(Config.s_NickServ, u, "SET HIDE", NICK_SET_HIDE_SYNTAX);
- return MOD_CONT;
- }
-
- CommandReturn DoSetAutoOP(User *u, const std::vector<ci::string> &params, NickCore *nc)
- {
- ci::string param = params.size() > 1 ? params[1] : "";
-
- if (param.empty())
- {
- this->OnSyntaxError(u, "AUTOOP");
- return MOD_CONT;
- }
-
- /**
- * This works the other way around, the absence of this flag denotes ON
- * This is so when people upgrade, and dont have the flag
- * the default is on
- **/
- if (param == "ON")
- {
- nc->SetFlag(NI_AUTOOP);
- notice_lang(Config.s_NickServ, u, NICK_SET_AUTOOP_ON);
- }
- else if (param == "OFF")
- {
- nc->UnsetFlag(NI_AUTOOP);
- notice_lang(Config.s_NickServ, u, NICK_SET_AUTOOP_OFF);
- }
- else
- syntax_error(Config.s_NickServ, u, "SET AUTOOP", NICK_SET_AUTOOP_SYNTAX);
-
- return MOD_CONT;
- }
- public:
- CommandNSSet() : Command("SET", 1, 3)
- {
- }
-
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
- {
- ci::string cmd = params[0];
-
- if (readonly)
- {
- notice_lang(Config.s_NickServ, u, NICK_SET_DISABLED);
- return MOD_CONT;
- }
-
-/*
- if (na->HasFlag(NS_FORBIDDEN))
- notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick);
-*/
- if (u->Account()->HasFlag(NI_SUSPENDED))
- notice_lang(Config.s_NickServ, u, NICK_X_SUSPENDED, u->Account()->display);
- else if (cmd == "DISPLAY")
- return this->DoSetDisplay(u, params, u->Account());
- else if (cmd == "PASSWORD")
- return this->DoSetPassword(u, params, u->Account());
- else if (cmd == "LANGUAGE")
- return this->DoSetLanguage(u, params, u->Account());
- else if (cmd == "URL")
- return this->DoSetUrl(u, params, u->Account());
- else if (cmd == "EMAIL")
- return this->DoSetEmail(u, params, u->Account());
- else if (cmd == "ICQ")
- return this->DoSetICQ(u, params, u->Account());
- else if (cmd == "GREET")
- return this->DoSetGreet(u, params, u->Account());
- else if (cmd == "KILL")
- return this->DoSetKill(u, params, u->Account());
- else if (cmd == "SECURE")
- return this->DoSetSecure(u, params, u->Account());
- else if (cmd == "PRIVATE")
- return this->DoSetPrivate(u, params, u->Account());
- else if (cmd == "MSG")
- return this->DoSetMsg(u, params, u->Account());
- else if (cmd == "HIDE")
- return this->DoSetHide(u, params, u->Account());
- else if (cmd == "AUTOOP")
- return this->DoSetAutoOP(u, params, u->Account());
- else
- notice_lang(Config.s_NickServ, u, NICK_SET_UNKNOWN_OPTION, cmd.c_str());
- return MOD_CONT;
- }
-
- bool OnHelp(User *u, const ci::string &subcommand)
- {
- if (subcommand.empty())
- notice_help(Config.s_NickServ, u, NICK_HELP_SET);
- else if (subcommand == "DISPLAY")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_DISPLAY);
- else if (subcommand == "PASSWORD")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_PASSWORD);
- else if (subcommand == "URL")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_URL);
- else if (subcommand == "EMAIL")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_EMAIL);
- else if (subcommand == "ICQ")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_ICQ);
- else if (subcommand == "GREET")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_GREET);
- else if (subcommand == "KILL")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_KILL);
- else if (subcommand == "SECURE")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_SECURE);
- else if (subcommand == "PRIVATE")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_PRIVATE);
- else if (subcommand == "MSG")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_MSG);
- else if (subcommand == "HIDE")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_HIDE);
- else if (subcommand == "AUTOOP")
- notice_help(Config.s_NickServ, u, NICK_HELP_SET_AUTOOP);
- else
- return false;
-
- return true;
- }
-
- void OnSyntaxError(User *u, const ci::string &subcommand)
- {
- syntax_error(Config.s_NickServ, u, "SET", NICK_SET_SYNTAX);
- }
-};
-
-class NSSet : public Module
-{
- public:
- NSSet(const std::string &modname, const std::string &creator) : Module(modname, creator)
- {
- this->SetAuthor("Anope");
- this->SetVersion(VERSION_STRING);
- this->SetType(CORE);
-
- this->AddCommand(NICKSERV, new CommandNSSet());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET);
- }
-};
-
-MODULE_INIT(NSSet)
diff --git a/src/core/ns_set.cpp b/src/core/ns_set.cpp
new file mode 100644
index 000000000..ecb1355c3
--- /dev/null
+++ b/src/core/ns_set.cpp
@@ -0,0 +1,239 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSet : public Command
+{
+ std::map<ci::string, Command *> subcommands;
+ public:
+ CommandNSSet(const ci::string &cname) : Command(cname, 1, 3)
+ {
+ }
+
+ ~CommandNSSet()
+ {
+ for (std::map<ci::string, Command *>::const_iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ {
+ delete it->second;
+ }
+ this->subcommands.clear();
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (readonly)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SET_DISABLED);
+ return MOD_CONT;
+ }
+
+ if (u->Account()->HasFlag(NI_SUSPENDED))
+ {
+ notice_lang(Config.s_NickServ, u, NICK_X_SUSPENDED, u->Account()->display);
+ return MOD_CONT;
+ }
+
+ Command *c = this->FindCommand(params[0]);
+
+ if (c)
+ {
+ ci::string cmdparams;
+ for (std::vector<ci::string>::const_iterator it = params.begin() + 1; it != params.end(); ++it)
+ cmdparams += " " + *it;
+ if (!cmdparams.empty())
+ cmdparams.erase(cmdparams.begin());
+ mod_run_cmd(NickServ, u, c, params[0], cmdparams);
+ }
+ else
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SET_UNKNOWN_OPTION, params[0].c_str());
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ if (subcommand.empty())
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_HEAD);
+ for (std::map<ci::string, Command *>::iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ it->second->OnServHelp(u);
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_TAIL);
+ return true;
+ }
+ else
+ {
+ Command *c = this->FindCommand(subcommand);
+
+ if (c)
+ {
+ return c->OnHelp(u, subcommand);
+ }
+ }
+
+ return false;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_NickServ, u, "SET", NICK_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET);
+ }
+
+ bool AddSubcommand(Command *c)
+ {
+ return this->subcommands.insert(std::make_pair(c->name, c)).second;
+ }
+
+ bool DelSubcommand(const ci::string &command)
+ {
+ return this->subcommands.erase(command);
+ }
+
+ Command *FindCommand(const ci::string &subcommand)
+ {
+ std::map<ci::string, Command *>::const_iterator it = this->subcommands.find(subcommand);
+
+ if (it != this->subcommands.end())
+ {
+ return it->second;
+ }
+
+ return NULL;
+ }
+};
+
+class CommandNSSetDisplay : public Command
+{
+ public:
+ CommandNSSetDisplay(const ci::string &cname) : Command(cname, 1)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickAlias *na = findnick(params[0]);
+
+ if (!na || na->nc != u->Account())
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SET_DISPLAY_INVALID);
+ return MOD_CONT;
+ }
+
+ change_core_display(u->Account(), params[0].c_str());
+ notice_lang(Config.s_NickServ, u, NICK_SET_DISPLAY_CHANGED, u->Account()->display);
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_DISPLAY);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_NickServ, u, "SET", NICK_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_DISPLAY);
+ }
+};
+
+class CommandNSSetPassword : public Command
+{
+ public:
+ CommandNSSetPassword(const ci::string &cname) : Command(cname, 1)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ci::string param = params[0];
+
+ int len = param.size();
+
+ if (u->Account()->display == param || (Config.StrictPasswords && len < 5))
+ {
+ notice_lang(Config.s_NickServ, u, MORE_OBSCURE_PASSWORD);
+ return MOD_CONT;
+ }
+ else if (len > Config.PassLen)
+ {
+ notice_lang(Config.s_NickServ, u, PASSWORD_TOO_LONG);
+ return MOD_CONT;
+ }
+
+ std::string buf = param.c_str(); /* conversion from ci::string to std::string */
+ if (enc_encrypt(buf, u->Account()->pass) < 0)
+ {
+ Alog() << Config.s_NickServ << ": Failed to encrypt password for " << u->Account()->display << " (set)";
+ notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_FAILED);
+ return MOD_CONT;
+ }
+
+ std::string tmp_pass;
+ if (enc_decrypt(u->Account()->pass, tmp_pass) == 1)
+ notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_CHANGED_TO, tmp_pass.c_str());
+ else
+ notice_lang(Config.s_NickServ, u, NICK_SET_PASSWORD_CHANGED);
+
+ Alog() << Config.s_NickServ << ": " << u->GetMask() << " (e-mail: " << (u->Account()->email ? u->Account()->email : "none") << ") changed its password.";
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_PASSWORD);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_NickServ, u, "SET", NICK_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_PASSWORD);
+ }
+};
+
+class NSSet : public Module
+{
+ public:
+ NSSet(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion(VERSION_STRING);
+ this->SetType(CORE);
+
+ Command *set = new CommandNSSet("SET");
+ this->AddCommand(NickServ, set);
+ set->AddSubcommand(new CommandNSSetDisplay("DISPLAY"));
+ set->AddSubcommand(new CommandNSSetPassword("PASSWORD"));
+ }
+};
+
+MODULE_INIT(NSSet)
diff --git a/src/core/ns_set_autoop.cpp b/src/core/ns_set_autoop.cpp
new file mode 100644
index 000000000..d1c0d0d81
--- /dev/null
+++ b/src/core/ns_set_autoop.cpp
@@ -0,0 +1,131 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetAutoOp : public Command
+{
+ public:
+ CommandNSSetAutoOp(const ci::string &cname) : Command(cname, 2)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (params[0] == "ON")
+ {
+ u->Account()->SetFlag(NI_AUTOOP);
+ notice_lang(Config.s_NickServ, u, NICK_SET_AUTOOP_ON);
+ }
+ else if (params[0] == "OFF")
+ {
+ u->Account()->UnsetFlag(NI_AUTOOP);
+ notice_lang(Config.s_NickServ, u, NICK_SET_AUTOOP_OFF);
+ }
+ else
+ this->OnSyntaxError(u, "AUTOOP");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_AUTOOP);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SET AUTOOP", NICK_SET_AUTOOP_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_AUTOOP);
+ }
+};
+
+class CommandNSSASetAutoOp : public Command
+{
+ public:
+ CommandNSSASetAutoOp(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/autoop")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ ci::string param = params[1];
+
+ if (param == "ON")
+ {
+ nc->SetFlag(NI_AUTOOP);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_AUTOOP_ON, nc->display);
+ }
+ else if (param == "OFF")
+ {
+ nc->UnsetFlag(NI_AUTOOP);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_AUTOOP_OFF, nc->display);
+ }
+ else
+ this->OnSyntaxError(u, "AUTOOP");
+
+ return MOD_CONT;
+ }
+
+ bool Help(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_AUTOOP);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SET AUTOOP", NICK_SASET_AUTOOP_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_AUTOOP);
+ }
+};
+
+class NSSetAutoOp : public Module
+{
+ public:
+ NSSetAutoOp(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *set = FindCommand(NickServ, "SET");
+
+ if (set)
+ set->AddSubcommand(new CommandNSSetAutoOp("AUTOOP"));
+ }
+
+ ~NSSetAutoOp()
+ {
+ Command *set = FindCommand(NickServ, "SET");
+
+ if (set)
+ set->DelSubcommand("AUTOOP");
+ }
+};
+
+MODULE_INIT(NSSetAutoOp)
diff --git a/src/core/ns_set_email.cpp b/src/core/ns_set_email.cpp
new file mode 100644
index 000000000..ec1b78c83
--- /dev/null
+++ b/src/core/ns_set_email.cpp
@@ -0,0 +1,160 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetEmail : public Command
+{
+ public:
+ CommandNSSetEmail(const ci::string &cname) : Command(cname, 0)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (params.empty() && Config.NSForceEmail)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_UNSET_IMPOSSIBLE);
+ return MOD_CONT;
+ }
+ else if (!params.empty() && !MailValidate(params[0].c_str()))
+ {
+ notice_lang(Config.s_NickServ, u, MAIL_X_INVALID, params[0].c_str());
+ return MOD_CONT;
+ }
+
+ Alog() << Config.s_NickServ << ": " << u->GetMask() << " (e-mail: " << (u->Account()->email ? u->Account()->email : "none") << ") changed its e-mail to " << (!params.empty() ? params[0] : "none");
+
+ if (u->Account()->email)
+ delete [] u->Account()->email;
+
+ if (!params.empty())
+ {
+ u->Account()->email = sstrdup(params[0].c_str());
+ notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_CHANGED, params[0].c_str());
+ }
+ else
+ {
+ u->Account()->email = NULL;
+ notice_lang(Config.s_NickServ, u, NICK_SET_EMAIL_UNSET);
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_EMAIL);
+ return true;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_EMAIL);
+ }
+};
+
+class CommandNSSASetEmail : public Command
+{
+ public:
+ CommandNSSASetEmail(const ci::string &cname) : Command(cname, 1, 2, "nickserv/saset/email")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ const char *param = params.size() > 1 ? params[1].c_str() : NULL;
+
+ if (!param && Config.NSForceEmail)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_UNSET_IMPOSSIBLE);
+ return MOD_CONT;
+ }
+ else if (Config.NSSecureAdmins && u->Account() != nc && nc->IsServicesOper())
+ {
+ notice_lang(Config.s_NickServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+ else if (param && !MailValidate(param))
+ {
+ notice_lang(Config.s_NickServ, u, MAIL_X_INVALID, param);
+ return MOD_CONT;
+ }
+
+ Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SASET EMAIL on " << nc->display << " (e-mail: " << (nc->email ? nc->email : "none") << ")";
+
+ if (nc->email)
+ delete [] nc->email;
+
+ if (param)
+ {
+ nc->email = sstrdup(param);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_CHANGED, nc->display, param);
+ }
+ else
+ {
+ nc->email = NULL;
+ notice_lang(Config.s_NickServ, u, NICK_SASET_EMAIL_UNSET, nc->display);
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_EMAIL);
+ return true;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_EMAIL);
+ }
+};
+
+class NSSetEmail : public Module
+{
+ public:
+ NSSetEmail(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandNSSetEmail("EMAIL"));
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandNSSASetEmail("EMAIL"));
+ }
+
+ ~NSSetEmail()
+ {
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->DelSubcommand("EMAIL");
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->DelSubcommand("EMAIL");
+ }
+};
+
+MODULE_INIT(NSSetEmail)
diff --git a/src/core/ns_set_greet.cpp b/src/core/ns_set_greet.cpp
new file mode 100644
index 000000000..0a1e94547
--- /dev/null
+++ b/src/core/ns_set_greet.cpp
@@ -0,0 +1,129 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetGreet : public Command
+{
+ public:
+ CommandNSSetGreet(const ci::string &cname) : Command(cname, 0)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (u->Account()->greet)
+ delete [] u->Account()->greet;
+
+ if (!params.empty())
+ {
+ u->Account()->greet = sstrdup(params[0].c_str());
+ notice_lang(Config.s_NickServ, u, NICK_SET_GREET_CHANGED, u->Account()->greet);
+ }
+ else
+ {
+ u->Account()->greet = NULL;
+ notice_lang(Config.s_NickServ, u, NICK_SET_GREET_UNSET);
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_GREET);
+ return true;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_GREET);
+ }
+};
+
+class CommandNSSASetGreet : public Command
+{
+ public:
+ CommandNSSASetGreet(const ci::string &cname) : Command(cname, 1, 2, "nickserv/saset/greet")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ const char *param = params.size() > 1 ? params[1].c_str() : NULL;
+
+ if (nc->greet)
+ delete [] nc->greet;
+
+ if (param)
+ {
+ nc->greet = sstrdup(param);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_GREET_CHANGED, nc->display, nc->greet);
+ }
+ else
+ {
+ nc->greet = NULL;
+ notice_lang(Config.s_NickServ, u, NICK_SASET_GREET_UNSET, nc->display);
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_GREET);
+ return true;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_GREET);
+ }
+};
+
+class NSSetGreet : public Module
+{
+ public:
+ NSSetGreet(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandNSSetGreet("GREET"));
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandNSSASetGreet("GREET"));
+ }
+
+ ~NSSetGreet()
+ {
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->DelSubcommand("GREET");
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->DelSubcommand("GREET");
+ }
+};
+
+MODULE_INIT(NSSetGreet)
diff --git a/src/core/ns_set_hide.cpp b/src/core/ns_set_hide.cpp
new file mode 100644
index 000000000..e17fac21f
--- /dev/null
+++ b/src/core/ns_set_hide.cpp
@@ -0,0 +1,200 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetHide : public Command
+{
+ public:
+ CommandNSSetHide(const ci::string &cname) : Command(cname, 2)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ int onmsg, offmsg;
+ NickCoreFlag flag;
+
+ if (params[0] == "EMAIL")
+ {
+ flag = NI_HIDE_EMAIL;
+ onmsg = NICK_SET_HIDE_EMAIL_ON;
+ offmsg = NICK_SET_HIDE_EMAIL_OFF;
+ }
+ else if (params[0] == "USERMASK")
+ {
+ flag = NI_HIDE_MASK;
+ onmsg = NICK_SET_HIDE_MASK_ON;
+ offmsg = NICK_SET_HIDE_MASK_OFF;
+ }
+ else if (params[0] == "STATUS")
+ {
+ flag = NI_HIDE_STATUS;
+ onmsg = NICK_SET_HIDE_STATUS_ON;
+ offmsg = NICK_SET_HIDE_STATUS_OFF;
+ }
+ else if (params[0] == "QUIT")
+ {
+ flag = NI_HIDE_QUIT;
+ onmsg = NICK_SET_HIDE_QUIT_ON;
+ offmsg = NICK_SET_HIDE_QUIT_OFF;
+ }
+ else
+ {
+ this->OnSyntaxError(u, "HIDE");
+ return MOD_CONT;
+ }
+
+ if (params[1] == "ON")
+ {
+ u->Account()->SetFlag(flag);
+ notice_lang(Config.s_NickServ, u, onmsg, Config.s_NickServ);
+ }
+ else if (params[1] == "OFF")
+ {
+ u->Account()->UnsetFlag(flag);
+ notice_lang(Config.s_NickServ, u, offmsg, Config.s_NickServ);
+ }
+ else
+ this->OnSyntaxError(u, "HIDE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_HIDE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SET HIDE", NICK_SET_HIDE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_HIDE);
+ }
+};
+
+class CommandNSSASetHide : public Command
+{
+ public:
+ CommandNSSASetHide(const ci::string &cname) : Command(cname, 3, 3, "nickserv/saset/command")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ ci::string param = params[1];
+
+ int onmsg, offmsg;
+ NickCoreFlag flag;
+
+ if (param == "EMAIL")
+ {
+ flag = NI_HIDE_EMAIL;
+ onmsg = NICK_SASET_HIDE_EMAIL_ON;
+ offmsg = NICK_SASET_HIDE_EMAIL_OFF;
+ }
+ else if (param == "USERMASK")
+ {
+ flag = NI_HIDE_MASK;
+ onmsg = NICK_SASET_HIDE_MASK_ON;
+ offmsg = NICK_SASET_HIDE_MASK_OFF;
+ }
+ else if (param == "STATUS")
+ {
+ flag = NI_HIDE_STATUS;
+ onmsg = NICK_SASET_HIDE_STATUS_ON;
+ offmsg = NICK_SASET_HIDE_STATUS_OFF;
+ }
+ else if (param == "QUIT")
+ {
+ flag = NI_HIDE_QUIT;
+ onmsg = NICK_SASET_HIDE_QUIT_ON;
+ offmsg = NICK_SASET_HIDE_QUIT_OFF;
+ }
+ else
+ {
+ this->OnSyntaxError(u, "HIDE");
+ return MOD_CONT;
+ }
+
+ param = params[2];
+ if (param.empty())
+ this->OnSyntaxError(u, "HIDE");
+ else if (param == "ON")
+ {
+ nc->SetFlag(flag);
+ notice_lang(Config.s_NickServ, u, onmsg, nc->display, Config.s_NickServ);
+ }
+ else if (param == "OFF")
+ {
+ nc->UnsetFlag(flag);
+ notice_lang(Config.s_NickServ, u, offmsg, nc->display, Config.s_NickServ);
+ }
+ else
+ this->OnSyntaxError(u, "HIDE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_HIDE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SASET HIDE", NICK_SASET_HIDE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_HIDE);
+ }
+};
+
+class NSSetHide : public Module
+{
+ public:
+ NSSetHide(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *set = FindCommand(NickServ, "SET");
+
+ if (set)
+ set->AddSubcommand(new CommandNSSetHide("HIDE"));
+ }
+
+ ~NSSetHide()
+ {
+ Command *set = FindCommand(NickServ, "SET");
+
+ if (set)
+ set->DelSubcommand("HIDE");
+ }
+};
+
+MODULE_INIT(NSSetHide)
diff --git a/src/core/ns_set_icq.cpp b/src/core/ns_set_icq.cpp
new file mode 100644
index 000000000..a00810bac
--- /dev/null
+++ b/src/core/ns_set_icq.cpp
@@ -0,0 +1,136 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetICQ : public Command
+{
+ public:
+ CommandNSSetICQ(const ci::string &cname) : Command(cname, 0)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (!params.empty())
+ {
+ int32 tmp = atol(params[0].c_str());
+ if (!tmp)
+ notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_INVALID, params[0].c_str());
+ else
+ {
+ u->Account()->icq = tmp;
+ notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_CHANGED, params[0].c_str());
+ }
+ }
+ else
+ {
+ u->Account()->icq = 0;
+ notice_lang(Config.s_NickServ, u, NICK_SET_ICQ_UNSET);
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_ICQ);
+ return true;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_ICQ);
+ }
+};
+
+class CommandNSSASetICQ : public Command
+{
+ public:
+ CommandNSSASetICQ(const ci::string &cname) : Command(cname, 1, 2, "nickserv/saset/icq")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ const char *param = params.size() > 1 ? params[1].c_str() : NULL;
+
+ if (param)
+ {
+ int32 tmp = atol(param);
+
+ if (tmp)
+ notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_INVALID, param);
+ else
+ {
+ nc->icq = tmp;
+ notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_CHANGED, nc->display, param);
+ }
+ }
+ else
+ {
+ nc->icq = 0;
+ notice_lang(Config.s_NickServ, u, NICK_SASET_ICQ_UNSET, nc->display);
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_ICQ);
+ return true;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_ICQ);
+ }
+};
+
+class NSSetICQ : public Module
+{
+ public:
+ NSSetICQ(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandNSSetICQ("ICQ"));
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandNSSASetICQ("ICQ"));
+ }
+
+ ~NSSetICQ()
+ {
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->DelSubcommand("ICQ");
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->DelSubcommand("ICQ");
+ }
+};
+
+MODULE_INIT(NSSetICQ)
diff --git a/src/core/ns_set_kill.cpp b/src/core/ns_set_kill.cpp
new file mode 100644
index 000000000..d9d6caa7c
--- /dev/null
+++ b/src/core/ns_set_kill.cpp
@@ -0,0 +1,183 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetKill : public Command
+{
+ public:
+ CommandNSSetKill(const ci::string &cname) : Command(cname, 1)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (params[0] == "ON")
+ {
+ u->Account()->SetFlag(NI_KILLPROTECT);
+ u->Account()->UnsetFlag(NI_KILL_QUICK);
+ u->Account()->UnsetFlag(NI_KILL_IMMED);
+ notice_lang(Config.s_NickServ, u, NICK_SET_KILL_ON);
+ }
+ else if (params[0] == "QUICK")
+ {
+ u->Account()->SetFlag(NI_KILLPROTECT);
+ u->Account()->SetFlag(NI_KILL_QUICK);
+ u->Account()->UnsetFlag(NI_KILL_IMMED);
+ notice_lang(Config.s_NickServ, u, NICK_SET_KILL_QUICK);
+ }
+ else if (params[0] == "IMMED")
+ {
+ if (Config.NSAllowKillImmed)
+ {
+ u->Account()->SetFlag(NI_KILLPROTECT);
+ u->Account()->SetFlag(NI_KILL_IMMED);
+ u->Account()->UnsetFlag(NI_KILL_QUICK);
+ notice_lang(Config.s_NickServ, u, NICK_SET_KILL_IMMED);
+ }
+ else
+ notice_lang(Config.s_NickServ, u, NICK_SET_KILL_IMMED_DISABLED);
+ }
+ else if (params[0] == "OFF")
+ {
+ u->Account()->UnsetFlag(NI_KILLPROTECT);
+ u->Account()->UnsetFlag(NI_KILL_QUICK);
+ u->Account()->UnsetFlag(NI_KILL_IMMED);
+ notice_lang(Config.s_NickServ, u, NICK_SET_KILL_OFF);
+ }
+ else
+ this->OnSyntaxError(u, "KILL");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_KILL);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SET KILL", Config.NSAllowKillImmed ? NICK_SET_KILL_IMMED_SYNTAX : NICK_SET_KILL_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_KILL);
+ }
+};
+
+class CommandNSSASetKill : public Command
+{
+ public:
+ CommandNSSASetKill(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/kill")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ ci::string param = params[1];
+
+ if (param == "ON")
+ {
+ nc->SetFlag(NI_KILLPROTECT);
+ nc->UnsetFlag(NI_KILL_QUICK);
+ nc->UnsetFlag(NI_KILL_IMMED);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_ON, nc->display);
+ }
+ else if (param == "QUICK")
+ {
+ nc->SetFlag(NI_KILLPROTECT);
+ nc->SetFlag(NI_KILL_QUICK);
+ nc->UnsetFlag(NI_KILL_IMMED);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_QUICK, nc->display);
+ }
+ else if (param == "IMMED")
+ {
+ if (Config.NSAllowKillImmed)
+ {
+ nc->SetFlag(NI_KILLPROTECT);
+ nc->SetFlag(NI_KILL_IMMED);
+ nc->UnsetFlag(NI_KILL_QUICK);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_IMMED, nc->display);
+ }
+ else
+ notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_IMMED_DISABLED);
+ }
+ else if (param == "OFF")
+ {
+ nc->UnsetFlag(NI_KILLPROTECT);
+ nc->UnsetFlag(NI_KILL_QUICK);
+ nc->UnsetFlag(NI_KILL_IMMED);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_KILL_OFF, nc->display);
+ }
+ else
+ this->OnSyntaxError(u, "KILL");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_KILL);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SASET KILL", Config.NSAllowKillImmed ? NICK_SASET_KILL_IMMED_SYNTAX : NICK_SASET_KILL_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_KILL);
+ }
+};
+
+class NSSetKill : public Module
+{
+ public:
+ NSSetKill(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandNSSetKill("KILL"));
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandNSSASetKill("KILL"));
+ }
+
+ ~NSSetKill()
+ {
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->DelSubcommand("KILL");
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->DelSubcommand("KILL");
+ }
+};
+
+MODULE_INIT(NSSetKill)
diff --git a/src/core/ns_set_language.cpp b/src/core/ns_set_language.cpp
new file mode 100644
index 000000000..a175f91a7
--- /dev/null
+++ b/src/core/ns_set_language.cpp
@@ -0,0 +1,143 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetLanguage : public Command
+{
+ public:
+ CommandNSSetLanguage(const ci::string &cname) : Command(cname, 1)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ const char *param = params[0].c_str();
+
+ if (param[strspn(param, "0123456789")]) /* i.e. not a number */
+ {
+ this->OnSyntaxError(u, "");
+ return MOD_CONT;
+ }
+
+ int langnum = atoi(param) - 1;
+ if (langnum < 0 || langnum >= NUM_LANGS || langlist[langnum] < 0)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SET_LANGUAGE_UNKNOWN, langnum + 1, Config.s_NickServ);
+ return MOD_CONT;
+ }
+
+ u->Account()->language = langlist[langnum];
+ notice_lang(Config.s_NickServ, u, NICK_SET_LANGUAGE_CHANGED);
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_LANGUAGE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SET LANGUAGE", NICK_SET_LANGUAGE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_LANGUAGE);
+ }
+};
+
+class CommandNSSASetLanguage : public Command
+{
+ public:
+ CommandNSSASetLanguage(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/language")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ const char *param = params[1].c_str();
+
+ if (param[strspn(param, "0123456789")]) /* i.e. not a number */
+ {
+ this->OnSyntaxError(u, "LANGUAGE");
+ return MOD_CONT;
+ }
+ int langnum = atoi(param) - 1;
+ if (langnum < 0 || langnum >= NUM_LANGS || langlist[langnum] < 0)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SASET_LANGUAGE_UNKNOWN, langnum + 1, Config.s_NickServ);
+ return MOD_CONT;
+ }
+ nc->language = langlist[langnum];
+ notice_lang(Config.s_NickServ, u, NICK_SASET_LANGUAGE_CHANGED);
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_LANGUAGE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SASET LANGUAGE", NICK_SASET_LANGUAGE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_LANGUAGE);
+ }
+};
+
+class NSSetLanguage : public Module
+{
+ public:
+ NSSetLanguage(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandNSSetLanguage("LANGUAGE"));
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandNSSASetLanguage("LANGUAGE"));
+ }
+
+ ~NSSetLanguage()
+ {
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->DelSubcommand("LANGUAGE");
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->DelSubcommand("LANGUAGE");
+ }
+};
+
+MODULE_INIT(NSSetLanguage)
diff --git a/src/core/ns_set_message.cpp b/src/core/ns_set_message.cpp
new file mode 100644
index 000000000..89f3cca0a
--- /dev/null
+++ b/src/core/ns_set_message.cpp
@@ -0,0 +1,149 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetMessage : public Command
+{
+ public:
+ CommandNSSetMessage(const ci::string &cname) : Command(cname, 1)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (!Config.UsePrivmsg)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SET_OPTION_DISABLED, "MSG");
+ return MOD_CONT;
+ }
+
+ if (params[0] == "ON")
+ {
+ u->Account()->SetFlag(NI_MSG);
+ notice_lang(Config.s_NickServ, u, NICK_SET_MSG_ON);
+ }
+ else if (params[0] == "OFF")
+ {
+ u->Account()->UnsetFlag(NI_MSG);
+ notice_lang(Config.s_NickServ, u, NICK_SET_MSG_OFF);
+ }
+ else
+ this->OnSyntaxError(u, "MSG");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_MSG);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SET MSG", NICK_SET_MSG_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_MSG);
+ }
+};
+
+class CommandNSSASetMessage : public Command
+{
+ public:
+ CommandNSSASetMessage(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/message")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ ci::string param = params[1];
+
+ if (!Config.UsePrivmsg)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_SASET_OPTION_DISABLED, "MSG");
+ return MOD_CONT;
+ }
+
+ if (param == "ON")
+ {
+ nc->SetFlag(NI_MSG);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_MSG_ON, nc->display);
+ }
+ else if (param == "OFF")
+ {
+ nc->UnsetFlag(NI_MSG);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_MSG_OFF, nc->display);
+ }
+ else
+ this->OnSyntaxError(u, "MSG");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_MSG);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SASET MSG", NICK_SASET_MSG_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_MSG);
+ }
+};
+
+class NSSetMessage : public Module
+{
+ public:
+ NSSetMessage(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandNSSetMessage("MSG"));
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandNSSASetMessage("MSG"));
+ }
+
+ ~NSSetMessage()
+ {
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->DelSubcommand("MSG");
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->DelSubcommand("MSG");
+ }
+};
+
+MODULE_INIT(NSSetMessage)
diff --git a/src/core/ns_set_private.cpp b/src/core/ns_set_private.cpp
new file mode 100644
index 000000000..661287929
--- /dev/null
+++ b/src/core/ns_set_private.cpp
@@ -0,0 +1,137 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetPrivate : public Command
+{
+ public:
+ CommandNSSetPrivate(const ci::string &cname) : Command(cname, 1)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (params[0] == "ON")
+ {
+ u->Account()->SetFlag(NI_PRIVATE);
+ notice_lang(Config.s_NickServ, u, NICK_SET_PRIVATE_ON);
+ }
+ else if (params[0] == "OFF")
+ {
+ u->Account()->UnsetFlag(NI_PRIVATE);
+ notice_lang(Config.s_NickServ, u, NICK_SET_PRIVATE_OFF);
+ }
+ else
+ this->OnSyntaxError(u, "PRIVATE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_PRIVATE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SET PRIVATE", NICK_SET_PRIVATE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_CMD_SET_PRIVATE);
+ }
+};
+
+class CommandNSSASetPrivate : public Command
+{
+ public:
+ CommandNSSASetPrivate(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/private")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ ci::string param = params[1];
+
+ if (param == "ON")
+ {
+ nc->SetFlag(NI_PRIVATE);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_PRIVATE_ON, nc->display);
+ }
+ else if (param == "OFF")
+ {
+ nc->UnsetFlag(NI_PRIVATE);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_PRIVATE_OFF, nc->display);
+ }
+ else
+ this->OnSyntaxError(u, "PRIVATE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_PRIVATE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SASET PRIVATE", NICK_SASET_PRIVATE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_CMD_SASET_PRIVATE);
+ }
+};
+
+class NSSetPrivate : public Module
+{
+ public:
+ NSSetPrivate(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandNSSetPrivate("PRIVATE"));
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandNSSASetPrivate("PRIVATE"));
+ }
+
+ ~NSSetPrivate()
+ {
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->DelSubcommand("PRIVATE");
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->DelSubcommand("PRIVATE");
+ }
+};
+
+MODULE_INIT(NSSetPrivate)
diff --git a/src/core/ns_set_secure.cpp b/src/core/ns_set_secure.cpp
new file mode 100644
index 000000000..a452a31f3
--- /dev/null
+++ b/src/core/ns_set_secure.cpp
@@ -0,0 +1,137 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetSecure : public Command
+{
+ public:
+ CommandNSSetSecure(const ci::string &cname) : Command(cname, 1)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (params[0] == "ON")
+ {
+ u->Account()->SetFlag(NI_SECURE);
+ notice_lang(Config.s_NickServ, u, NICK_SET_SECURE_ON);
+ }
+ else if (params[0] == "OFF")
+ {
+ u->Account()->UnsetFlag(NI_SECURE);
+ notice_lang(Config.s_NickServ, u, NICK_SET_SECURE_OFF);
+ }
+ else
+ this->OnSyntaxError(u, "SECURE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_SECURE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SET SECURE", NICK_SET_SECURE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_SECURE);
+ }
+};
+
+class CommandNSSASetSecure : public Command
+{
+ public:
+ CommandNSSASetSecure(const ci::string &cname) : Command(cname, 2, 2, "nickserv/saset/secure")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ ci::string param = params[1];
+
+ if (param == "ON")
+ {
+ nc->SetFlag(NI_SECURE);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_SECURE_ON, nc->display);
+ }
+ else if (param == "OFF")
+ {
+ nc->UnsetFlag(NI_SECURE);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_SECURE_OFF, nc->display);
+ }
+ else
+ this->OnSyntaxError(u, "SECURE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_SECURE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_NickServ, u, "SASET SECURE", NICK_SASET_SECURE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_SECURE);
+ }
+};
+
+class NSSetSecure : public Module
+{
+ public:
+ NSSetSecure(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandNSSetSecure("SECURE"));
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandNSSASetSecure("SECURE"));
+ }
+
+ ~NSSetSecure()
+ {
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->DelSubcommand("SECURE");
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->DelSubcommand("SECURE");
+ }
+};
+
+MODULE_INIT(NSSetSecure)
diff --git a/src/core/ns_set_url.cpp b/src/core/ns_set_url.cpp
new file mode 100644
index 000000000..5ef83d32e
--- /dev/null
+++ b/src/core/ns_set_url.cpp
@@ -0,0 +1,128 @@
+/* NickServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandNSSetURL : public Command
+{
+ public:
+ CommandNSSetURL(const ci::string &cname) : Command(cname, 0)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (u->Account()->url)
+ delete [] u->Account()->url;
+
+ if (!params.empty())
+ {
+ u->Account()->url = sstrdup(params[0].c_str());
+ notice_lang(Config.s_NickServ, u, NICK_SET_URL_CHANGED, params[0].c_str());
+ }
+ else
+ {
+ u->Account()->url = NULL;
+ notice_lang(Config.s_NickServ, u, NICK_SET_URL_UNSET);
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SET_URL);
+ return true;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SET_URL);
+ }
+};
+
+class CommandNSSASetURL : public Command
+{
+ public:
+ CommandNSSASetURL(const ci::string &cname) : Command(cname, 1, 2, "nickserv/saset/url")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ NickCore *nc = findcore(params[0]);
+ assert(nc);
+
+ const char *param = params.size() > 1 ? params[1].c_str() : NULL;
+
+ if (nc->url)
+ delete [] nc->url;
+
+ if (param)
+ {
+ nc->url = sstrdup(param);
+ notice_lang(Config.s_NickServ, u, NICK_SASET_URL_CHANGED, nc->display, param);
+ }
+ else
+ {
+ nc->url = NULL;
+ notice_lang(Config.s_NickServ, u, NICK_SASET_URL_UNSET, nc->display);
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_NickServ, u, NICK_HELP_SASET_URL);
+ return true;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SASET_URL);
+ }
+};
+
+class NSSetURL : public Module
+{
+ public:
+ NSSetURL(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandNSSetURL("URL"));
+
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandNSSASetURL("URL"));
+ }
+
+ ~NSSetURL()
+ {
+ Command *c = FindCommand(NickServ, "SET");
+ if (c)
+ c->DelSubcommand("URL");
+ c = FindCommand(NickServ, "SASET");
+ if (c)
+ c->DelSubcommand("URL");
+ }
+};
+
+MODULE_INIT(NSSetURL)
diff --git a/src/core/ns_status.c b/src/core/ns_status.cpp
index 978b1f69f..9695dd4fd 100644
--- a/src/core/ns_status.c
+++ b/src/core/ns_status.cpp
@@ -56,6 +56,11 @@ class CommandNSStatus : public Command
notice_help(Config.s_NickServ, u, NICK_HELP_STATUS);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_STATUS);
+ }
};
class NSStatus : public Module
@@ -67,13 +72,7 @@ class NSStatus : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSStatus());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_STATUS);
+ this->AddCommand(NickServ, new CommandNSStatus());
}
};
diff --git a/src/core/ns_suspend.c b/src/core/ns_suspend.cpp
index 8a909f151..ef147551a 100644
--- a/src/core/ns_suspend.c
+++ b/src/core/ns_suspend.cpp
@@ -23,11 +23,10 @@ class CommandNSSuspend : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- NickAlias *na, *na2;
+ NickAlias *na;
User *u2;
const char *nick = params[0].c_str();
const char *reason = params[1].c_str();
- int i;
if (readonly)
{
@@ -61,9 +60,10 @@ class CommandNSSuspend : public Command
na->nc->UnsetFlag(NI_KILL_QUICK);
na->nc->UnsetFlag(NI_KILL_IMMED);
- for (i = 0; i < na->nc->aliases.count; ++i)
+ for (std::list<NickAlias *>::iterator it = na->nc->aliases.begin(); it != na->nc->aliases.end(); ++it)
{
- na2 = static_cast<NickAlias *>(na->nc->aliases.list[i]);
+ NickAlias *na2 = *it;
+
if (na2->nc == na->nc)
{
if (na2->last_quit)
@@ -79,7 +79,7 @@ class CommandNSSuspend : public Command
}
if (Config.WallForbid)
- ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used SUSPEND on \2%s\2", u->nick.c_str(), nick);
+ ircdproto->SendGlobops(NickServ, "\2%s\2 used SUSPEND on \2%s\2", u->nick.c_str(), nick);
Alog() << Config.s_NickServ << ": " << u->nick << " set SUSPEND for nick " << nick;
notice_lang(Config.s_NickServ, u, NICK_SUSPEND_SUCCEEDED, nick);
@@ -104,6 +104,11 @@ class CommandNSSuspend : public Command
{
syntax_error(Config.s_NickServ, u, "SUSPEND", NICK_SUSPEND_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SUSPEND);
+ }
};
class CommandNSUnSuspend : public Command
@@ -147,7 +152,7 @@ class CommandNSUnSuspend : public Command
na->nc->UnsetFlag(NI_SUSPENDED);
if (Config.WallForbid)
- ircdproto->SendGlobops(findbot(Config.s_NickServ), "\2%s\2 used UNSUSPEND on \2%s\2", u->nick.c_str(), nick);
+ ircdproto->SendGlobops(NickServ, "\2%s\2 used UNSUSPEND on \2%s\2", u->nick.c_str(), nick);
Alog() << Config.s_NickServ << ": " << u->nick << " set UNSUSPEND for nick " << nick;
notice_lang(Config.s_NickServ, u, NICK_UNSUSPEND_SUCCEEDED, nick);
@@ -172,6 +177,11 @@ class CommandNSUnSuspend : public Command
{
syntax_error(Config.s_NickServ, u, "UNSUSPEND", NICK_UNSUSPEND_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_UNSUSPEND);
+ }
};
class NSSuspend : public Module
@@ -183,15 +193,8 @@ class NSSuspend : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSSuspend());
- this->AddCommand(NICKSERV, new CommandNSUnSuspend());
-
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SUSPEND);
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_UNSUSPEND);
+ this->AddCommand(NickServ, new CommandNSSuspend());
+ this->AddCommand(NickServ, new CommandNSUnSuspend());
}
};
diff --git a/src/core/ns_update.c b/src/core/ns_update.cpp
index 739f1dc7e..4ed3b5b77 100644
--- a/src/core/ns_update.c
+++ b/src/core/ns_update.cpp
@@ -46,6 +46,11 @@ class CommandNSUpdate : public Command
notice_help(Config.s_NickServ, u, NICK_HELP_UPDATE);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_UPDATE);
+ }
};
class NSUpdate : public Module
@@ -56,12 +61,7 @@ class NSUpdate : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(NICKSERV, new CommandNSUpdate());
- ModuleManager::Attach(I_OnNickServHelp, this);
- }
- void OnNickServHelp(User *u)
- {
- notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_UPDATE);
+ this->AddCommand(NickServ, new CommandNSUpdate());
}
};
diff --git a/src/core/os_akill.c b/src/core/os_akill.c
deleted file mode 100644
index a83b0aa98..000000000
--- a/src/core/os_akill.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-/*************************************************************************/
-
-#include "module.h"
-
-int akill_view_callback(SList *slist, int number, void *item, va_list args);
-int akill_list_callback(SList *slist, int number, void *item, va_list args);
-int akill_view(int number, Akill *ak, User *u, int *sent_header);
-int akill_list(int number, Akill *ak, User *u, int *sent_header);
-
-static int akill_del_callback(SList *slist, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, static_cast<Akill *>(item)));
- return 1;
-}
-
-class CommandOSAKill : public Command
-{
- private:
- CommandReturn DoAdd(User *u, const std::vector<ci::string> &params)
- {
- int deleted = 0;
- unsigned last_param = 2;
- const char *expiry, *mask;
- char reason[BUFSIZE];
- time_t expires;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
- if (mask && *mask == '+')
- {
- expiry = mask;
- mask = params.size() > 2 ? params[2].c_str() : NULL;
- last_param = 3;
- }
- else
- expiry = NULL;
-
- expires = expiry ? dotime(expiry) : Config.AutokillExpiry;
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (expiry && isdigit(expiry[strlen(expiry) - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires != 0 && expires < 60)
- {
- notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
- return MOD_CONT;
- }
- else if (expires > 0)
- expires += time(NULL);
-
- if (params.size() <= last_param)
- {
- this->OnSyntaxError(u, "ADD");
- return MOD_CONT;
- }
- snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : "");
- if (mask && *reason) {
- /* We first do some sanity check on the proposed mask. */
- if (strchr(mask, '!'))
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_NICK);
- return MOD_CONT;
- }
-
- if (!strchr(mask, '@'))
- {
- notice_lang(Config.s_OperServ, u, BAD_USERHOST_MASK);
- return MOD_CONT;
- }
-
- if (mask && strspn(mask, "~@.*?") == strlen(mask))
- {
- notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
- return MOD_CONT;
- }
-
- std::string realreason;
- if (Config.AddAkiller)
- realreason = "[" + u->nick + "] " + std::string(reason);
- else
- realreason = reason;
-
- deleted = add_akill(u, mask, u->nick.c_str(), expires, realreason.c_str());
- if (deleted < 0)
- return MOD_CONT;
- else if (deleted)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_SEVERAL, deleted);
- notice_lang(Config.s_OperServ, u, OPER_AKILL_ADDED, mask);
-
- if (Config.WallOSAkill)
- {
- char buf[128];
-
- if (!expires)
- strcpy(buf, "does not expire");
- else
- {
- int wall_expiry = expires - time(NULL);
- const char *s = NULL;
-
- if (wall_expiry >= 86400)
- {
- wall_expiry /= 86400;
- s = "day";
- }
- else if (wall_expiry >= 3600)
- {
- wall_expiry /= 3600;
- s = "hour";
- }
- else if (wall_expiry >= 60)
- {
- wall_expiry /= 60;
- s = "minute";
- }
-
- snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
- }
-
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an AKILL for %s (%s) (%s)", u->nick.c_str(), mask, realreason.c_str(), buf);
- }
-
- if (readonly)
- notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
- }
- else
- this->OnSyntaxError(u, "ADD");
-
- return MOD_CONT;
- }
-
- CommandReturn DoDel(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res = 0;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask)
- {
- this->OnSyntaxError(u, "DEL");
- return MOD_CONT;
- }
-
- if (!akills.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY);
- return MOD_CONT;
- }
-
- if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))
- {
- /* Deleting a range */
- res = slist_delete_range(&akills, mask, akill_del_callback, u);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
- return MOD_CONT;
- }
- else if (res == 1)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_ONE);
- else
- notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_SEVERAL, res);
- }
- else
- {
- if ((res = slist_indexof(&akills, const_cast<void *>(static_cast<const void *>(mask)))) == -1) // XXX: possibly unsafe cast
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NOT_FOUND, mask);
- return MOD_CONT;
- }
-
- FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, static_cast<Akill *>(akills.list[res])));
-
- slist_delete(&akills, res);
- notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED, mask);
- }
-
- if (readonly)
- notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
-
- return MOD_CONT;
- }
-
- CommandReturn DoList(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res, sent_header = 0;
-
- if (!akills.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY);
- return MOD_CONT;
- }
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&akills, mask, &akill_list_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
- return MOD_CONT;
- }
- else
- notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill");
- }
- else
- {
- int i;
- char amask[BUFSIZE];
-
- for (i = 0; i < akills.count; ++i)
- {
- snprintf(amask, sizeof(amask), "%s@%s", (static_cast<Akill *>(akills.list[i]))->user, (static_cast<Akill *>(akills.list[i]))->host);
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- akill_list(i + 1, static_cast<Akill *>(akills.list[i]), u, &sent_header);
- }
-
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
- else
- notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill");
- }
-
- return MOD_CONT;
- }
-
- CommandReturn DoView(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res, sent_header = 0;
-
- if (!akills.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY);
- return MOD_CONT;
- }
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&akills, mask, &akill_view_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
- return MOD_CONT;
- }
- }
- else
- {
- int i;
- char amask[BUFSIZE];
-
- for (i = 0; i < akills.count; ++i)
- {
- snprintf(amask, sizeof(amask), "%s@%s", (static_cast<Akill *>(akills.list[i]))->user, (static_cast<Akill *>(akills.list[i]))->host);
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- akill_view(i + 1, static_cast<Akill *>(akills.list[i]), u, &sent_header);
- }
-
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
- }
-
- return MOD_CONT;
- }
-
- CommandReturn DoClear(User *u)
- {
- FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, NULL));
- slist_clear(&akills, 1);
- notice_lang(Config.s_OperServ, u, OPER_AKILL_CLEAR);
-
- return MOD_CONT;
- }
- public:
- CommandOSAKill() : Command("AKILL", 1, 4, "operserv/akill")
- {
- }
-
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
- {
- ci::string cmd = params[0];
-
- if (cmd == "ADD")
- return this->DoAdd(u, params);
- else if (cmd == "DEL")
- return this->DoDel(u, params);
- else if (cmd == "LIST")
- return this->DoList(u, params);
- else if (cmd == "VIEW")
- return this->DoView(u, params);
- else if (cmd == "CLEAR")
- return this->DoClear(u);
- else
- this->OnSyntaxError(u, "");
- return MOD_CONT;
- }
-
- bool OnHelp(User *u, const ci::string &subcommand)
- {
- notice_help(Config.s_OperServ, u, OPER_HELP_AKILL);
- return true;
- }
-
- void OnSyntaxError(User *u, const ci::string &subcommand)
- {
- syntax_error(Config.s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
- }
-};
-
-class OSAKill : public Module
-{
- public:
- OSAKill(const std::string &modname, const std::string &creator) : Module(modname, creator)
- {
- this->SetAuthor("Anope");
- this->SetVersion(VERSION_STRING);
- this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSAKill());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_AKILL);
- }
-};
-
-int akill_view(int number, Akill *ak, User *u, int *sent_header)
-{
- char mask[BUFSIZE];
- char timebuf[32], expirebuf[256];
- struct tm tm;
-
- if (!ak)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_HEADER);
- *sent_header = 1;
- }
-
- snprintf(mask, sizeof(mask), "%s@%s", ak->user, ak->host);
- tm = *localtime(&ak->seton);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
- expire_left(u->Account(), expirebuf, sizeof(expirebuf), ak->expires);
- notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_FORMAT, number, mask, ak->by, timebuf, expirebuf, ak->reason);
-
- return 1;
-}
-
-/* Lists an AKILL entry, prefixing it with the header if needed */
-int akill_list_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return akill_list(number, static_cast<Akill *>(item), u, sent_header);
-}
-
-/* Callback for enumeration purposes */
-int akill_view_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return akill_view(number, static_cast<Akill *>(item), u, sent_header);
-}
-
-/* Lists an AKILL entry, prefixing it with the header if needed */
-int akill_list(int number, Akill *ak, User *u, int *sent_header)
-{
- char mask[BUFSIZE];
-
- if (!ak)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_HEADER);
- *sent_header = 1;
- }
-
- snprintf(mask, sizeof(mask), "%s@%s", ak->user, ak->host);
- notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_FORMAT, number, mask, ak->reason);
-
- return 1;
-}
-
-MODULE_INIT(OSAKill)
diff --git a/src/core/os_akill.cpp b/src/core/os_akill.cpp
new file mode 100644
index 000000000..fd840cd5c
--- /dev/null
+++ b/src/core/os_akill.cpp
@@ -0,0 +1,402 @@
+/* OperServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class AkillDelCallback : public NumberList
+{
+ User *u;
+ unsigned Deleted;
+ public:
+ AkillDelCallback(User *_u, const std::string &numlist) : NumberList(numlist, true), u(_u), Deleted(0)
+ {
+ }
+
+ ~AkillDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
+ else if (Deleted == 1)
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_ONE);
+ else
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED_SEVERAL, Deleted);
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SGLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ ++Deleted;
+ DoDel(u, x);
+ }
+
+ static void DoDel(User *u, XLine *x)
+ {
+ SGLine->DelXLine(x);
+ }
+};
+
+class AkillListCallback : public NumberList
+{
+ protected:
+ User *u;
+ bool SentHeader;
+ public:
+ AkillListCallback(User *_u, const std::string &numlist) : NumberList(numlist, false), u(_u), SentHeader(false)
+ {
+ }
+
+ ~AkillListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
+ else
+ notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill");
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SGLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str());
+ }
+};
+
+class AkillViewCallback : public AkillListCallback
+{
+ public:
+ AkillViewCallback(User *_u, const std::string &numlist) : AkillListCallback(_u, numlist)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SGLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ char timebuf[32], expirebuf[256];
+ struct tm tm;
+
+ tm = *localtime(&x->Created);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires);
+
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf, expirebuf, x->Reason.c_str());
+ }
+};
+
+class CommandOSAKill : public Command
+{
+ private:
+ CommandReturn DoAdd(User *u, const std::vector<ci::string> &params)
+ {
+ unsigned last_param = 2;
+ const char *expiry, *mask;
+ char reason[BUFSIZE];
+ time_t expires;
+
+ mask = params.size() > 1 ? params[1].c_str() : NULL;
+ if (mask && *mask == '+')
+ {
+ expiry = mask;
+ mask = params.size() > 2 ? params[2].c_str() : NULL;
+ last_param = 3;
+ }
+ else
+ expiry = NULL;
+
+ expires = expiry ? dotime(expiry) : Config.AutokillExpiry;
+ /* If the expiry given does not contain a final letter, it's in days,
+ * said the doc. Ah well.
+ */
+ if (expiry && isdigit(expiry[strlen(expiry) - 1]))
+ expires *= 86400;
+ /* Do not allow less than a minute expiry time */
+ if (expires != 0 && expires < 60)
+ {
+ notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
+ return MOD_CONT;
+ }
+ else if (expires > 0)
+ expires += time(NULL);
+
+ if (params.size() <= last_param)
+ {
+ this->OnSyntaxError(u, "ADD");
+ return MOD_CONT;
+ }
+ snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : "");
+ if (mask && *reason)
+ {
+ XLine *x = SGLine->Add(OperServ, u, mask, expires, reason);
+
+ if (!x)
+ return MOD_CONT;
+
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_ADDED, mask);
+
+ if (Config.WallOSAkill)
+ {
+ char buf[128];
+
+ if (!expires)
+ strcpy(buf, "does not expire");
+ else
+ {
+ int wall_expiry = expires - time(NULL);
+ const char *s = NULL;
+
+ if (wall_expiry >= 86400)
+ {
+ wall_expiry /= 86400;
+ s = "day";
+ }
+ else if (wall_expiry >= 3600)
+ {
+ wall_expiry /= 3600;
+ s = "hour";
+ }
+ else if (wall_expiry >= 60)
+ {
+ wall_expiry /= 60;
+ s = "minute";
+ }
+
+ snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
+ }
+
+ ircdproto->SendGlobops(OperServ, "%s added an AKILL for %s (%s) (%s)", u->nick.c_str(), mask, reason, buf);
+ }
+
+ if (readonly)
+ notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
+ }
+ else
+ this->OnSyntaxError(u, "ADD");
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoDel(User *u, const std::vector<ci::string> &params)
+ {
+ const ci::string mask = params.size() > 1 ? params[0] : "";
+
+ if (mask.empty())
+ {
+ this->OnSyntaxError(u, "DEL");
+ return MOD_CONT;
+ }
+
+ if (SGLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ if (isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new AkillDelCallback(u, mask.c_str()))->Process();
+ else
+ {
+ XLine *x = SGLine->HasEntry(mask);
+
+ if (!x)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_NOT_FOUND, mask.c_str());
+ return MOD_CONT;
+ }
+
+ FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, x));
+
+ AkillDelCallback::DoDel(u, x);
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_DELETED, mask.c_str());
+ }
+
+ if (readonly)
+ notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoList(User *u, const std::vector<ci::string> &params)
+ {
+ if (SGLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new AkillListCallback(u, mask.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < SGLine->GetCount(); ++i)
+ {
+ XLine *x = SGLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_HEADER);
+ }
+
+ AkillListCallback::DoList(u, x, i);
+ }
+ }
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
+ else
+ notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "Akill");
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoView(User *u, const std::vector<ci::string> &params)
+ {
+ if (SGLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new AkillViewCallback(u, mask.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < SGLine->GetCount(); ++i)
+ {
+ XLine *x = SGLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_VIEW_HEADER);
+ }
+
+ AkillViewCallback::DoList(u, x, i);
+ }
+ }
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_NO_MATCH);
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoClear(User *u)
+ {
+ FOREACH_MOD(I_OnDelAkill, OnDelAkill(u, NULL));
+ SGLine->Clear();
+ notice_lang(Config.s_OperServ, u, OPER_AKILL_CLEAR);
+
+ return MOD_CONT;
+ }
+ public:
+ CommandOSAKill() : Command("AKILL", 1, 4, "operserv/akill")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ci::string cmd = params[0];
+
+ if (cmd == "ADD")
+ return this->DoAdd(u, params);
+ else if (cmd == "DEL")
+ return this->DoDel(u, params);
+ else if (cmd == "LIST")
+ return this->DoList(u, params);
+ else if (cmd == "VIEW")
+ return this->DoView(u, params);
+ else if (cmd == "CLEAR")
+ return this->DoClear(u);
+ else
+ this->OnSyntaxError(u, "");
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ notice_help(Config.s_OperServ, u, OPER_HELP_AKILL);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_OperServ, u, "AKILL", OPER_AKILL_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_AKILL);
+ }
+};
+
+class OSAKill : public Module
+{
+ public:
+ OSAKill(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion(VERSION_STRING);
+ this->SetType(CORE);
+ this->AddCommand(OperServ, new CommandOSAKill());
+ }
+};
+
+MODULE_INIT(OSAKill)
diff --git a/src/core/os_chankill.c b/src/core/os_chankill.cpp
index e945728f7..033bf380d 100644
--- a/src/core/os_chankill.c
+++ b/src/core/os_chankill.cpp
@@ -26,7 +26,6 @@ class CommandOSChanKill : public Command
const char *expiry, *channel;
char reason[BUFSIZE];
time_t expires;
- char *mask = new char[Config.UserLen + Config.HostLen + 2];
unsigned last_param = 1;
Channel *c;
@@ -46,7 +45,6 @@ class CommandOSChanKill : public Command
if (expires != 0 && expires < 60)
{
notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
- delete [] mask;
return MOD_CONT;
}
else if (expires > 0)
@@ -55,7 +53,6 @@ class CommandOSChanKill : public Command
if (params.size() <= last_param)
{
this->OnSyntaxError(u, "");
- delete [] mask;
return MOD_CONT;
}
snprintf(reason, sizeof(reason), "%s%s", params[last_param].c_str(), (params.size() > last_param + 1 ? params[last_param + 1].c_str() : ""));
@@ -77,18 +74,15 @@ class CommandOSChanKill : public Command
if (is_oper(uc->user))
continue;
- strlcpy(mask, "*@", Config.UserLen + Config.HostLen + 2); /* Use *@" for the akill's, */
- strlcat(mask, uc->user->host, Config.UserLen + Config.HostLen + 2);
- add_akill(NULL, mask, Config.s_OperServ, expires, realreason.c_str());
- check_akill(uc->user->nick.c_str(), uc->user->GetIdent().c_str(), uc->user->host, NULL, NULL);
+ SGLine->Add(OperServ, u, ci::string("*@") + uc->user->host, expires, realreason);
+ SGLine->Check(uc->user);
}
if (Config.WallOSAkill)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s used CHANKILL on %s (%s)", u->nick.c_str(), channel, realreason.c_str());
+ ircdproto->SendGlobops(OperServ, "%s used CHANKILL on %s (%s)", u->nick.c_str(), channel, realreason.c_str());
}
else
notice_lang(Config.s_OperServ, u, CHAN_X_NOT_IN_USE, channel);
}
- delete [] mask;
return MOD_CONT;
}
@@ -102,6 +96,11 @@ class CommandOSChanKill : public Command
{
syntax_error(Config.s_OperServ, u, "CHANKILL", OPER_CHANKILL_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CHANKILL);
+ }
};
class OSChanKill : public Module
@@ -113,13 +112,7 @@ class OSChanKill : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSChanKill());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CHANKILL);
+ this->AddCommand(OperServ, new CommandOSChanKill());
}
};
diff --git a/src/core/os_chanlist.c b/src/core/os_chanlist.cpp
index 48846255a..eb8c32e6a 100644
--- a/src/core/os_chanlist.c
+++ b/src/core/os_chanlist.cpp
@@ -38,9 +38,9 @@ class CommandOSChanList : public Command
{
notice_lang(Config.s_OperServ, u, OPER_CHANLIST_HEADER_USER, u2->nick.c_str());
- for (UChannelList::iterator it = u2->chans.begin(); it != u2->chans.end(); ++it)
+ for (UChannelList::iterator uit = u2->chans.begin(); uit != u2->chans.end(); ++uit)
{
- ChannelContainer *cc = *it;
+ ChannelContainer *cc = *uit;
if (!Modes.empty())
{
@@ -56,27 +56,24 @@ class CommandOSChanList : public Command
}
else
{
- int i;
- Channel *c;
-
notice_lang(Config.s_OperServ, u, OPER_CHANLIST_HEADER);
- for (i = 0; i < 1024; ++i)
+ for (channel_map::const_iterator cit = ChannelList.begin(); cit != ChannelList.end(); ++cit)
{
- for (c = chanlist[i]; c; c = c->next)
+ Channel *c = cit->second;
+
+ if (pattern && !Anope::Match(c->name, pattern, false))
+ continue;
+ if (!Modes.empty())
{
- if (pattern && !Anope::Match(c->name, pattern, false))
- continue;
- if (!Modes.empty())
+ for (std::list<ChannelModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it)
{
- for (std::list<ChannelModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it)
- {
- if (!c->HasMode(*it))
- continue;
- }
+ if (!c->HasMode(*it))
+ continue;
}
- notice_lang(Config.s_OperServ, u, OPER_CHANLIST_RECORD, c->name.c_str(), c->users.size(), chan_get_modes(c, 1, 1), c->topic ? c->topic : "");
}
+
+ notice_lang(Config.s_OperServ, u, OPER_CHANLIST_RECORD, c->name.c_str(), c->users.size(), chan_get_modes(c, 1, 1), c->topic ? c->topic : "");
}
}
@@ -89,6 +86,11 @@ class CommandOSChanList : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_CHANLIST);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CHANLIST);
+ }
};
class OSChanList : public Module
@@ -100,13 +102,7 @@ class OSChanList : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSChanList());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CHANLIST);
+ this->AddCommand(OperServ, new CommandOSChanList());
}
};
diff --git a/src/core/os_clearmodes.c b/src/core/os_clearmodes.cpp
index 8d50b92e5..b5ebba938 100644
--- a/src/core/os_clearmodes.c
+++ b/src/core/os_clearmodes.cpp
@@ -52,7 +52,7 @@ class CommandOSClearModes : public Command
}
if (Config.WallOSClearmodes)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s used CLEARMODES%s on %s", u->nick.c_str(), all ? " ALL" : "", chan);
+ ircdproto->SendGlobops(OperServ, "%s used CLEARMODES%s on %s", u->nick.c_str(), all ? " ALL" : "", chan);
if (all)
{
/* Clear mode +o */
@@ -166,6 +166,11 @@ class CommandOSClearModes : public Command
{
syntax_error(Config.s_OperServ, u, "CLEARMODES", OPER_CLEARMODES_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CLEARMODES);
+ }
};
class OSClearModes : public Module
@@ -177,13 +182,7 @@ class OSClearModes : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSClearModes());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_CLEARMODES);
+ this->AddCommand(OperServ, new CommandOSClearModes());
}
};
diff --git a/src/core/os_defcon.c b/src/core/os_defcon.cpp
index 403ac1281..caf2836fe 100644
--- a/src/core/os_defcon.c
+++ b/src/core/os_defcon.cpp
@@ -36,7 +36,7 @@ class DefConTimeout : public Timer
Config.DefConLevel = level;
FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(level));
Alog() << "Defcon level timeout, returning to lvl " << level;
- ircdproto->SendGlobops(findbot(Config.s_OperServ), getstring(OPER_DEFCON_WALL), Config.s_OperServ, level);
+ ircdproto->SendGlobops(OperServ, getstring(OPER_DEFCON_WALL), Config.s_OperServ, level);
if (Config.GlobalOnDefcon)
{
@@ -95,7 +95,7 @@ class CommandOSDEFCON : public Command
notice_lang(Config.s_OperServ, u, OPER_DEFCON_CHANGED, Config.DefConLevel);
defcon_sendlvls(u);
Alog() << "Defcon level changed to " << newLevel << " by Oper " << u->nick;
- ircdproto->SendGlobops(findbot(Config.s_OperServ), getstring(OPER_DEFCON_WALL), u->nick.c_str(), newLevel);
+ ircdproto->SendGlobops(OperServ, getstring(OPER_DEFCON_WALL), u->nick.c_str(), newLevel);
/* Global notice the user what is happening. Also any Message that
the Admin would like to add. Set in config file. */
if (Config.GlobalOnDefcon)
@@ -125,6 +125,11 @@ class CommandOSDEFCON : public Command
{
syntax_error(Config.s_OperServ, u, "DEFCON", OPER_DEFCON_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_DEFCON);
+ }
};
class OSDEFCON : public Module
@@ -141,33 +146,24 @@ class OSDEFCON : public Module
throw ModuleException("Invalid configuration settings");
}
- Implementation i[] = { I_OnOperServHelp, I_OnPreUserConnect, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommandRun, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate };
- ModuleManager::Attach(i, this, 9);
+ Implementation i[] = { I_OnPreUserConnect, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommandRun, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate };
+ ModuleManager::Attach(i, this, 8);
- this->AddCommand(OPERSERV, new CommandOSDEFCON());
+ this->AddCommand(OperServ, new CommandOSDEFCON());
defconParseModeString(Config.DefConChanModes);
}
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_DEFCON);
- }
-
EventReturn OnPreUserConnect(User *u)
{
- std::string mask;
-
- if (u && is_sync(u->server) && CheckDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(u->server->name))
+ if (u->server->IsSynced() && CheckDefCon(DEFCON_AKILL_NEW_CLIENTS) && !u->server->IsULined())
{
if (CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
{
- mask = "*@" + std::string(u->host);
- Alog() << "DEFCON: adding akill for " << mask;
- add_akill(NULL, mask.c_str(), Config.s_OperServ,
- time(NULL) + Config.DefConAKILL,
- Config.DefConAkillReason ? Config.DefConAkillReason :
- "DEFCON AKILL");
+ Alog() << "DEFCON: adding akill for *@" << u->host;
+ XLine *x = SGLine->Add(NULL, NULL, ci::string("*@") + u->host, time(NULL) + Config.DefConAKILL, Config.DefConAkillReason ? Config.DefConAkillReason : "DEFCON AKILL");
+ if (x)
+ x->By = Config.s_OperServ;
}
if (CheckDefCon(DEFCON_NO_NEW_CLIENTS) || CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
@@ -185,7 +181,7 @@ class OSDEFCON : public Module
if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && cm && DefConModesOff.HasFlag(Name))
{
- c->RemoveMode(findbot(Config.s_OperServ), Name, param);
+ c->RemoveMode(OperServ, Name, param);
return EVENT_STOP;
}
@@ -201,12 +197,12 @@ class OSDEFCON : public Module
{
std::string param;
- if (GetDefConParam(Name, &param))
+ if (GetDefConParam(Name, param))
{
- c->SetMode(findbot(Config.s_OperServ), Name, param);
+ c->SetMode(OperServ, Name, param);
}
else
- c->SetMode(findbot(Config.s_OperServ), Name);
+ c->SetMode(OperServ, Name);
return EVENT_STOP;
@@ -215,7 +211,7 @@ class OSDEFCON : public Module
return EVENT_CONTINUE;
}
- EventReturn OnPreCommandRun(const std::string &service, User *u, const char *cmd, Command *c)
+ EventReturn OnPreCommandRun(User *u, BotInfo *bi, const ci::string &command, const ci::string &message, Command *c)
{
if (!c)
{
@@ -226,7 +222,7 @@ class OSDEFCON : public Module
{
if (!CheckDefCon(DEFCON_SILENT_OPER_ONLY))
{
- notice_lang(service, u, OPER_DEFCON_DENIED);
+ notice_lang(bi->nick.c_str(), u, OPER_DEFCON_DENIED);
}
return EVENT_STOP;
@@ -295,18 +291,16 @@ class OSDEFCON : public Module
if (session && session->count > Config.DefConSessionLimit)
{
if (Config.SessionLimitExceeded)
- ircdproto->SendMessage(findbot(Config.s_OperServ), u->nick.c_str(), Config.SessionLimitExceeded, u->host);
+ ircdproto->SendMessage(OperServ, u->nick.c_str(), Config.SessionLimitExceeded, u->host);
if (Config.SessionLimitDetailsLoc)
- ircdproto->SendMessage(findbot(Config.s_OperServ), u->nick.c_str(), "%s", Config.SessionLimitDetailsLoc);
+ ircdproto->SendMessage(OperServ, u->nick.c_str(), "%s", Config.SessionLimitDetailsLoc);
kill_user(Config.s_OperServ, u->nick, "Session limit exceeded");
session->hits++;
if (Config.MaxSessionKill && session->hits >= Config.MaxSessionKill)
{
- char akillmask[BUFSIZE];
- snprintf(akillmask, sizeof(akillmask), "*@%s", u->host);
- add_akill(NULL, akillmask, Config.s_OperServ, time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded");
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask);
+ SGLine->Add(NULL, NULL, ci::string("*@") + u->host, time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded");
+ ircdproto->SendGlobops(OperServ, "Added a temporary AKILL for \2*@%s\2 due to excessive connections", u->host);
}
}
}
@@ -332,7 +326,7 @@ class OSDEFCON : public Module
{
if (CheckDefCon(DEFCON_FORCE_CHAN_MODES))
{
- c->SetModes(findbot(Config.s_OperServ), false, Config.DefConChanModes);
+ c->SetModes(OperServ, false, Config.DefConChanModes);
}
}
};
@@ -375,22 +369,22 @@ void runDefCon()
if (Config.DefConChanModes[0] == '+' || Config.DefConChanModes[0] == '-')
{
Alog() << "DEFCON: setting " << Config.DefConChanModes << " on all channels";
- DefConModesSet = 1;
- MassChannelModes(findbot(Config.s_OperServ), Config.DefConChanModes);
+ DefConModesSet = true;
+ MassChannelModes(OperServ, Config.DefConChanModes);
}
}
}
else
{
- if (Config.DefConChanModes && (DefConModesSet != 0))
+ if (Config.DefConChanModes && DefConModesSet)
{
if (Config.DefConChanModes[0] == '+' || Config.DefConChanModes[0] == '-')
{
- DefConModesSet = 0;
+ DefConModesSet = false;
if ((newmodes = defconReverseModes(Config.DefConChanModes)))
{
Alog() << "DEFCON: setting " << newmodes << " on all channels";
- MassChannelModes(findbot(Config.s_OperServ), newmodes);
+ MassChannelModes(OperServ, newmodes);
delete [] newmodes;
}
}
diff --git a/src/core/os_global.c b/src/core/os_global.cpp
index 4c2c81e22..df62f753f 100644
--- a/src/core/os_global.c
+++ b/src/core/os_global.cpp
@@ -26,7 +26,7 @@ class CommandOSGlobal : public Command
const char *msg = params[0].c_str();
if (Config.WallOSGlobal)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 just used GLOBAL command.", u->nick.c_str());
+ ircdproto->SendGlobops(OperServ, "\2%s\2 just used GLOBAL command.", u->nick.c_str());
oper_global(const_cast<char *>(u->nick.c_str()), "%s", msg);
return MOD_CONT;
}
@@ -41,6 +41,11 @@ class CommandOSGlobal : public Command
{
syntax_error(Config.s_OperServ, u, "GLOBAL", OPER_GLOBAL_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_GLOBAL);
+ }
};
class OSGlobal : public Module
@@ -52,13 +57,7 @@ class OSGlobal : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSGlobal());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_GLOBAL);
+ this->AddCommand(OperServ, new CommandOSGlobal());
}
};
diff --git a/src/core/os_help.c b/src/core/os_help.cpp
index baeb5a45f..d6f9001b4 100644
--- a/src/core/os_help.c
+++ b/src/core/os_help.cpp
@@ -23,14 +23,15 @@ class CommandOSHelp : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- mod_help_cmd(Config.s_OperServ, u, OPERSERV, params[0].c_str());
+ mod_help_cmd(OperServ, u, params[0].c_str());
return MOD_CONT;
}
void OnSyntaxError(User *u, const ci::string &subcommand)
{
notice_help(Config.s_OperServ, u, OPER_HELP);
- FOREACH_MOD(I_OnOperServHelp, OnOperServHelp(u));
+ for (CommandMap::const_iterator it = NickServ->Commands.begin(); it != NickServ->Commands.end(); ++it)
+ it->second->OnServHelp(u);
notice_help(Config.s_OperServ, u, OPER_HELP_LOGGED);
}
};
@@ -43,7 +44,7 @@ class OSHelp : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSHelp());
+ this->AddCommand(OperServ, new CommandOSHelp());
}
};
diff --git a/src/core/os_ignore.c b/src/core/os_ignore.cpp
index 335fa8d63..f852a36b8 100644
--- a/src/core/os_ignore.c
+++ b/src/core/os_ignore.cpp
@@ -127,6 +127,11 @@ class CommandOSIgnore : public Command
{
syntax_error(Config.s_OperServ, u, "IGNORE", OPER_IGNORE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_IGNORE);
+ }
};
class OSIgnore : public Module
@@ -137,17 +142,12 @@ class OSIgnore : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSIgnore());
+ this->AddCommand(OperServ, new CommandOSIgnore());
- Implementation i[] = { I_OnOperServHelp, I_OnDatabaseRead, I_OnDatabaseWrite };
- ModuleManager::Attach(i, this, 3);
+ Implementation i[] = { I_OnDatabaseRead, I_OnDatabaseWrite };
+ ModuleManager::Attach(i, this, 2);
}
-
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_IGNORE);
- }
-
+
EventReturn OnDatabaseRead(const std::vector<std::string> &params)
{
std::string buf;
diff --git a/src/core/os_jupe.c b/src/core/os_jupe.cpp
index 9af3d3176..7fedb968c 100644
--- a/src/core/os_jupe.c
+++ b/src/core/os_jupe.cpp
@@ -25,22 +25,24 @@ class CommandOSJupe : public Command
{
const char *jserver = params[0].c_str();
const char *reason = params.size() > 1 ? params[1].c_str() : NULL;
- Server *server = findserver(servlist, jserver);
+ Server *server = Server::Find(jserver);
if (!isValidHost(jserver, 3))
notice_lang(Config.s_OperServ, u, OPER_JUPE_HOST_ERROR);
- else if (server && (server->HasFlag(SERVER_ISME) || server->HasFlag(SERVER_ISUPLINK)))
+ else if (server && (server == Me || server == Me->GetUplink()))
notice_lang(Config.s_OperServ, u, OPER_JUPE_INVALID_SERVER);
- else {
+ else
+ {
char rbuf[256];
snprintf(rbuf, sizeof(rbuf), "Juped by %s%s%s", u->nick.c_str(), reason ? ": " : "", reason ? reason : "");
- if (findserver(servlist, jserver))
+ if (server)
ircdproto->SendSquit(jserver, rbuf);
- Server *juped_server = new_server(me_server, jserver, rbuf, SERVER_JUPED, ircd->ts6 ? ts6_sid_retrieve() : "");
+ Server *juped_server = new Server(Me, jserver, 0, rbuf, ircd->ts6 ? ts6_sid_retrieve() : "");
+ juped_server->SetFlag(SERVER_JUPED);
ircdproto->SendServer(juped_server);
if (Config.WallOSJupe)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 used JUPE on \2%s\2", u->nick.c_str(), jserver);
+ ircdproto->SendGlobops(OperServ, "\2%s\2 used JUPE on \2%s\2", u->nick.c_str(), jserver);
}
return MOD_CONT;
}
@@ -55,6 +57,11 @@ class CommandOSJupe : public Command
{
syntax_error(Config.s_OperServ, u, "JUPE", OPER_JUPE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_JUPE);
+ }
};
class OSJupe : public Module
@@ -66,13 +73,7 @@ class OSJupe : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSJupe());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_JUPE);
+ this->AddCommand(OperServ, new CommandOSJupe());
}
};
diff --git a/src/core/os_kick.c b/src/core/os_kick.cpp
index 803a2c970..f4fb4f7e5 100644
--- a/src/core/os_kick.c
+++ b/src/core/os_kick.cpp
@@ -43,9 +43,9 @@ class CommandOSKick : public Command
return MOD_CONT;
}
- c->Kick(findbot(Config.s_OperServ), u2, "%s (%s)", u->nick.c_str(), s);
+ c->Kick(OperServ, u2, "%s (%s)", u->nick.c_str(), s);
if (Config.WallOSKick)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s used KICK on %s/%s", u->nick.c_str(), u2->nick.c_str(), chan);
+ ircdproto->SendGlobops(OperServ, "%s used KICK on %s/%s", u->nick.c_str(), u2->nick.c_str(), chan);
return MOD_CONT;
}
@@ -59,6 +59,11 @@ class CommandOSKick : public Command
{
syntax_error(Config.s_OperServ, u, "KICK", OPER_KICK_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_KICK);
+ }
};
class OSKick : public Module
@@ -70,13 +75,7 @@ class OSKick : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSKick());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_KICK);
+ this->AddCommand(OperServ, new CommandOSKick());
}
};
diff --git a/src/core/os_mode.c b/src/core/os_mode.cpp
index 0eddcd82b..1f9396169 100644
--- a/src/core/os_mode.c
+++ b/src/core/os_mode.cpp
@@ -32,10 +32,10 @@ class CommandOSMode : public Command
notice_lang(Config.s_OperServ, u, OPER_BOUNCY_MODES_U_LINE);
else
{
- c->SetModes(findbot(Config.s_OperServ), false, modes);
+ c->SetModes(OperServ, false, modes);
if (Config.WallOSMode)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s used MODE %s on %s", u->nick.c_str(), modes, chan);
+ ircdproto->SendGlobops(OperServ, "%s used MODE %s on %s", u->nick.c_str(), modes, chan);
}
return MOD_CONT;
}
@@ -50,6 +50,11 @@ class CommandOSMode : public Command
{
syntax_error(Config.s_OperServ, u, "MODE", OPER_MODE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODE);
+ }
};
class OSMode : public Module
@@ -61,13 +66,7 @@ class OSMode : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSMode());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODE);
+ this->AddCommand(OperServ, new CommandOSMode());
}
};
diff --git a/src/core/os_modinfo.c b/src/core/os_modinfo.cpp
index 2a1d8a8f8..055d2a136 100644
--- a/src/core/os_modinfo.c
+++ b/src/core/os_modinfo.cpp
@@ -14,7 +14,7 @@
#include "module.h"
-int showModuleCmdLoaded(CommandHash *cmdList, const char *mod_name, User *u);
+static int showModuleCmdLoaded(BotInfo *bi, const ci::string &mod_name, User *u);
class CommandOSModInfo : public Command
{
@@ -25,30 +25,27 @@ class CommandOSModInfo : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- const char *file = params[0].c_str();
+ const std::string file = params[0].c_str();
struct tm tm;
char timebuf[64];
- Module *m;
- int idx = 0;
- m = findModule(file);
+ Module *m = FindModule(file.c_str());
if (m)
{
tm = *localtime(&m->created);
strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm);
notice_lang(Config.s_OperServ, u, OPER_MODULE_INFO_LIST, m->name.c_str(), !m->version.empty() ? m->version.c_str() : "?", !m->author.empty() ? m->author.c_str() : "?", timebuf);
- for (idx = 0; idx < MAX_CMD_HASH; ++idx)
- {
- showModuleCmdLoaded(HOSTSERV[idx], m->name.c_str(), u);
- showModuleCmdLoaded(OPERSERV[idx], m->name.c_str(), u);
- showModuleCmdLoaded(NICKSERV[idx], m->name.c_str(), u);
- showModuleCmdLoaded(CHANSERV[idx], m->name.c_str(), u);
- showModuleCmdLoaded(BOTSERV[idx], m->name.c_str(), u);
- showModuleCmdLoaded(MEMOSERV[idx], m->name.c_str(), u);
- }
+
+ showModuleCmdLoaded(HostServ, m->name.c_str(), u);
+ showModuleCmdLoaded(OperServ, m->name.c_str(), u);
+ showModuleCmdLoaded(NickServ, m->name.c_str(), u);
+ showModuleCmdLoaded(ChanServ, m->name.c_str(), u);
+ showModuleCmdLoaded(BotServ, m->name.c_str(), u);
+ showModuleCmdLoaded(MemoServ, m->name.c_str(), u);
}
else
- notice_lang(Config.s_OperServ, u, OPER_MODULE_NO_INFO, file);
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_NO_INFO, file.c_str());
+
return MOD_CONT;
}
@@ -62,6 +59,11 @@ class CommandOSModInfo : public Command
{
syntax_error(Config.s_OperServ, u, "MODINFO", OPER_MODULE_INFO_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODINFO);
+ }
};
class OSModInfo : public Module
@@ -72,31 +74,25 @@ class OSModInfo : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSModInfo());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODINFO);
+ this->AddCommand(OperServ, new CommandOSModInfo());
}
};
-int showModuleCmdLoaded(CommandHash *cmdList, const char *mod_name, User *u)
+static int showModuleCmdLoaded(BotInfo *bi, const ci::string &mod_name, User *u)
{
- Command *c;
- CommandHash *current;
+ if (!bi)
+ return 0;
+
int display = 0;
- for (current = cmdList; current; current = current->next)
+ for (std::map<ci::string, Command *>::iterator it = bi->Commands.begin(); it != bi->Commands.end(); ++it)
{
- for (c = current->c; c; c = c->next)
+ Command *c = it->second;
+
+ if (c->module && c->module->name == mod_name)
{
- if (c->mod_name && !stricmp(c->mod_name, mod_name))
- {
- notice_lang(Config.s_OperServ, u, OPER_MODULE_CMD_LIST, c->service, c->name.c_str());
- ++display;
- }
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_CMD_LIST, c->service, c->name.c_str());
+ ++display;
}
}
return display;
diff --git a/src/core/os_modlist.c b/src/core/os_modlist.cpp
index 3619a466b..a8ab244fd 100644
--- a/src/core/os_modlist.c
+++ b/src/core/os_modlist.cpp
@@ -23,7 +23,6 @@ class CommandOSModList : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- int idx;
int count = 0;
int showCore = 0;
int showThird = 1;
@@ -34,7 +33,6 @@ class CommandOSModList : public Command
int showDB = 1;
ci::string param = params.size() ? params[0] : "";
- ModuleHash *current = NULL;
char core[] = "Core";
char third[] = "3rd";
@@ -120,61 +118,60 @@ class CommandOSModList : public Command
notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST_HEADER);
- for (idx = 0; idx != MAX_CMD_HASH; ++idx)
+ for (std::deque<Module *>::iterator it = Modules.begin(); it != Modules.end(); ++it)
{
- for (current = MODULE_HASH[idx]; current; current = current->next)
+ Module *m = *it;
+
+ switch (m->type)
{
- switch (current->m->type)
- {
- case CORE:
- if (showCore)
- {
- notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), core);
- ++count;
- }
- break;
- case THIRD:
- if (showThird)
- {
- notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), third);
- ++count;
- }
- break;
- case PROTOCOL:
- if (showProto)
- {
- notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), proto);
- ++count;
- }
- break;
- case SUPPORTED:
- if (showSupported)
- {
- notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), supported);
- ++count;
- }
- break;
- case QATESTED:
- if (showQA)
- {
- notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), qa);
- ++count;
- }
- break;
- case ENCRYPTION:
- if (showEnc)
- {
- notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), enc);
- ++count;
- }
- break;
- case DATABASE:
- if (showDB)
- {
- notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, current->name, current->m->version.c_str(), db);
- ++count;
- }
- }
+ case CORE:
+ if (showCore)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), core);
+ ++count;
+ }
+ break;
+ case THIRD:
+ if (showThird)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), third);
+ ++count;
+ }
+ break;
+ case PROTOCOL:
+ if (showProto)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), proto);
+ ++count;
+ }
+ break;
+ case SUPPORTED:
+ if (showSupported)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), supported);
+ ++count;
+ }
+ break;
+ case QATESTED:
+ if (showQA)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), qa);
+ ++count;
+ }
+ break;
+ case ENCRYPTION:
+ if (showEnc)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), enc);
+ ++count;
+ }
+ break;
+ case DATABASE:
+ if (showDB)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_LIST, m->name.c_str(), m->version.c_str(), db);
+ ++count;
+ }
}
}
if (!count)
@@ -190,6 +187,11 @@ class CommandOSModList : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_MODLIST);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODLIST);
+ }
};
class OSModList : public Module
@@ -201,13 +203,7 @@ class OSModList : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSModList());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODLIST);
+ this->AddCommand(OperServ, new CommandOSModList());
}
};
diff --git a/src/core/os_modload.c b/src/core/os_modload.cpp
index 870c7b0a4..9265c8e72 100644
--- a/src/core/os_modload.c
+++ b/src/core/os_modload.cpp
@@ -23,19 +23,19 @@ class CommandOSModLoad : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- const char *name = params[0].c_str();
+ const std::string mname = params[0].c_str();
- Module *m = findModule(name);
+ Module *m = FindModule(mname);
if (m)
{
- notice_lang(Config.s_OperServ, u, OPER_MODULE_ALREADY_LOADED, name);
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_ALREADY_LOADED, mname.c_str());
return MOD_CONT;
}
- int status = ModuleManager::LoadModule(name, u);
+ int status = ModuleManager::LoadModule(mname, u);
if (status != MOD_ERR_OK)
{
- notice_lang(Config.s_OperServ, u, OPER_MODULE_LOAD_FAIL, name);
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_LOAD_FAIL, mname.c_str());
}
return MOD_CONT;
@@ -51,6 +51,11 @@ class CommandOSModLoad : public Command
{
syntax_error(Config.s_OperServ, u, "MODLOAD", OPER_MODULE_LOAD_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODLOAD);
+ }
};
class OSModLoad : public Module
@@ -63,13 +68,7 @@ class OSModLoad : public Module
this->SetType(CORE);
this->SetPermanent(true);
- this->AddCommand(OPERSERV, new CommandOSModLoad());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODLOAD);
+ this->AddCommand(OperServ, new CommandOSModLoad());
}
};
diff --git a/src/core/os_modunload.c b/src/core/os_modunload.cpp
index 6f6de9e81..77ef413ca 100644
--- a/src/core/os_modunload.c
+++ b/src/core/os_modunload.cpp
@@ -23,22 +23,22 @@ class CommandOSModUnLoad : public Command
CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- const char *name = params[0].c_str();
+ const std::string mname = params[0].c_str();
int status;
- Module *m = findModule(name);
+ Module *m = FindModule(mname);
if (!m)
{
- notice_lang(Config.s_OperServ, u, OPER_MODULE_ISNT_LOADED, name);
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_ISNT_LOADED, mname.c_str());
return MOD_CONT;
}
- Alog() << "Trying to unload module [" << name << "]";
+ Alog() << "Trying to unload module [" << mname << "]";
status = ModuleManager::UnloadModule(m, u);
if (status != MOD_ERR_OK)
- notice_lang(Config.s_OperServ, u, OPER_MODULE_REMOVE_FAIL, name);
+ notice_lang(Config.s_OperServ, u, OPER_MODULE_REMOVE_FAIL, mname.c_str());
return MOD_CONT;
}
@@ -53,6 +53,11 @@ class CommandOSModUnLoad : public Command
{
syntax_error(Config.s_OperServ, u, "MODUNLOAD", OPER_MODULE_UNLOAD_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODUNLOAD);
+ }
};
class OSModUnLoad : public Module
@@ -65,13 +70,7 @@ class OSModUnLoad : public Module
this->SetType(CORE);
this->SetPermanent(true);
- this->AddCommand(OPERSERV, new CommandOSModUnLoad());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_MODUNLOAD);
+ this->AddCommand(OperServ, new CommandOSModUnLoad());
}
};
diff --git a/src/core/os_news.c b/src/core/os_news.cpp
index 9daf1b443..7be0bc5f7 100644
--- a/src/core/os_news.c
+++ b/src/core/os_news.cpp
@@ -14,6 +14,8 @@
#include "module.h"
+#define lenof(a) (sizeof(a) / sizeof(*(a)))
+
/* List of messages for each news type. This simplifies message sending. */
#define MSG_SYNTAX 0
@@ -300,7 +302,7 @@ class NewsBase : public Command
return MOD_CONT;
}
public:
- NewsBase(const std::string &newstype) : Command(newstype, 1, 2, "operserv/news")
+ NewsBase(const ci::string &newstype) : Command(newstype, 1, 2, "operserv/news")
{
}
@@ -337,6 +339,11 @@ class CommandOSLogonNews : public NewsBase
{
syntax_error(Config.s_OperServ, u, "LOGONNEWS", NEWS_LOGON_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_LOGONNEWS);
+ }
};
class CommandOSOperNews : public NewsBase
@@ -361,6 +368,11 @@ class CommandOSOperNews : public NewsBase
{
syntax_error(Config.s_OperServ, u, "OPERNEWS", NEWS_OPER_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_OPERNEWS);
+ }
};
class CommandOSRandomNews : public NewsBase
@@ -385,6 +397,11 @@ class CommandOSRandomNews : public NewsBase
{
syntax_error(Config.s_OperServ, u, "RANDOMNEWS", NEWS_RANDOM_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RANDOMNEWS);
+ }
};
class OSNews : public Module
@@ -396,12 +413,12 @@ class OSNews : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSLogonNews());
- this->AddCommand(OPERSERV, new CommandOSOperNews());
- this->AddCommand(OPERSERV, new CommandOSRandomNews());
+ this->AddCommand(OperServ, new CommandOSLogonNews());
+ this->AddCommand(OperServ, new CommandOSOperNews());
+ this->AddCommand(OperServ, new CommandOSRandomNews());
- Implementation i[] = { I_OnOperServHelp, I_OnUserModeSet, I_OnUserConnect, I_OnDatabaseRead, I_OnDatabaseWrite };
- ModuleManager::Attach(i, this, 5);
+ Implementation i[] = { I_OnUserModeSet, I_OnUserConnect, I_OnDatabaseRead, I_OnDatabaseWrite };
+ ModuleManager::Attach(i, this, 4);
}
~OSNews()
@@ -411,13 +428,6 @@ class OSNews : public Module
News.clear();
}
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_LOGONNEWS);
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_OPERNEWS);
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RANDOMNEWS);
- }
-
void OnUserModeSet(User *u, UserModeName Name)
{
if (Name == UMODE_OPER)
diff --git a/src/core/os_noop.c b/src/core/os_noop.cpp
index c0fc33161..270373f0c 100644
--- a/src/core/os_noop.c
+++ b/src/core/os_noop.cpp
@@ -28,8 +28,6 @@ class CommandOSNOOP : public Command
if (cmd == "SET")
{
- User *u2;
- User *u3 = NULL;
std::string reason;
/* Remove the O:lines */
@@ -37,14 +35,16 @@ class CommandOSNOOP : public Command
reason = "NOOP command used by " + u->nick;
if (Config.WallOSNoOp)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 used NOOP on \2%s\2", u->nick.c_str(), server);
+ ircdproto->SendGlobops(OperServ, "\2%s\2 used NOOP on \2%s\2", u->nick.c_str(), server);
notice_lang(Config.s_OperServ, u, OPER_NOOP_SET, server);
/* Kill all the IRCops of the server */
- for (u2 = firstuser(); u2; u2 = u3)
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
{
- u3 = nextuser();
- if (u2 && is_oper(u2) && u2->server->name && Anope::Match(u2->server->name, server, true))
+ User *u2 = it->second;
+ ++it;
+
+ if (u2 && is_oper(u2) && Anope::Match(u2->server->GetName(), server, true))
kill_user(Config.s_OperServ, u2->nick.c_str(), reason.c_str());
}
}
@@ -68,6 +68,11 @@ class CommandOSNOOP : public Command
{
syntax_error(Config.s_OperServ, u, "NOOP", OPER_NOOP_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_NOOP);
+ }
};
class OSNOOP : public Module
@@ -79,13 +84,7 @@ class OSNOOP : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSNOOP());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_NOOP);
+ this->AddCommand(OperServ, new CommandOSNOOP());
}
};
diff --git a/src/core/os_oline.c b/src/core/os_oline.cpp
index 52f7d7ac0..d0ee5ea96 100644
--- a/src/core/os_oline.c
+++ b/src/core/os_oline.cpp
@@ -33,16 +33,16 @@ class CommandOSOLine : public Command
else if (u2 && flag[0] == '+')
{
ircdproto->SendSVSO(Config.s_OperServ, nick, flag);
- u2->SetMode(findbot(Config.s_OperServ), UMODE_OPER);
+ u2->SetMode(OperServ, UMODE_OPER);
notice_lang(Config.s_OperServ, u2, OPER_OLINE_IRCOP);
notice_lang(Config.s_OperServ, u, OPER_OLINE_SUCCESS, flag, nick);
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 used OLINE for %s", u->nick.c_str(), nick);
+ ircdproto->SendGlobops(OperServ, "\2%s\2 used OLINE for %s", u->nick.c_str(), nick);
}
else if (u2 && flag[0] == '-')
{
ircdproto->SendSVSO(Config.s_OperServ, nick, flag);
notice_lang(Config.s_OperServ, u, OPER_OLINE_SUCCESS, flag, nick);
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 used OLINE for %s", u->nick.c_str(), nick);
+ ircdproto->SendGlobops(OperServ, "\2%s\2 used OLINE for %s", u->nick.c_str(), nick);
}
else
this->OnSyntaxError(u, "");
@@ -59,6 +59,11 @@ class CommandOSOLine : public Command
{
syntax_error(Config.s_OperServ, u, "OLINE", OPER_OLINE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_OLINE);
+ }
};
class OSOLine : public Module
@@ -70,16 +75,10 @@ class OSOLine : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSOLine());
+ this->AddCommand(OperServ, new CommandOSOLine());
if (!ircd->omode)
throw ModuleException("Your IRCd does not support OMODE.");
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_OLINE);
}
};
diff --git a/src/core/os_quit.c b/src/core/os_quit.cpp
index 4c6d09587..41703c1b7 100644
--- a/src/core/os_quit.c
+++ b/src/core/os_quit.cpp
@@ -41,6 +41,11 @@ class CommandOSQuit : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_QUIT);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_QUIT);
+ }
};
class OSQuit : public Module
@@ -52,13 +57,7 @@ class OSQuit : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSQuit());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_QUIT);
+ this->AddCommand(OperServ, new CommandOSQuit());
}
};
diff --git a/src/core/os_reload.c b/src/core/os_reload.cpp
index 10afe2aa7..07fffa94f 100644
--- a/src/core/os_reload.c
+++ b/src/core/os_reload.cpp
@@ -43,6 +43,11 @@ class CommandOSReload : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_RELOAD);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RELOAD);
+ }
};
class OSReload : public Module
@@ -54,13 +59,7 @@ class OSReload : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSReload());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RELOAD);
+ this->AddCommand(OperServ, new CommandOSReload());
}
};
diff --git a/src/core/os_restart.c b/src/core/os_restart.cpp
index 051b92155..efb5bdada 100644
--- a/src/core/os_restart.c
+++ b/src/core/os_restart.cpp
@@ -41,6 +41,11 @@ class CommandOSRestart : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_RESTART);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RESTART);
+ }
};
class OSRestart : public Module
@@ -51,13 +56,7 @@ class OSRestart : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSRestart());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_RESTART);
+ this->AddCommand(OperServ, new CommandOSRestart());
}
};
diff --git a/src/core/os_session.c b/src/core/os_session.cpp
index f450cf6a1..34d34fcc4 100644
--- a/src/core/os_session.c
+++ b/src/core/os_session.cpp
@@ -14,13 +14,127 @@
#include "module.h"
+class ExceptionDelCallback : public NumberList
+{
+ protected:
+ User *u;
+ unsigned Deleted;
+ public:
+ ExceptionDelCallback(User *_u, const std::string &numlist) : NumberList(numlist, true), u(_u), Deleted(0)
+ {
+ }
+
+ ~ExceptionDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH);
+ else if (Deleted == 1)
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_DELETED_ONE);
+ else
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_DELETED_SEVERAL, Deleted);
+ }
+
+ virtual void HandleNumber(unsigned Number)
+ {
+ if (Number > nexceptions)
+ return;
+
+ ++Deleted;
+
+ DoDel(u, Number - 1);
+ }
+
+ static void DoDel(User *u, unsigned index)
+ {
+ FOREACH_MOD(I_OnExceptionDel, OnExceptionDel(u, &exceptions[index]));
+
+ delete [] exceptions[index].mask;
+ delete [] exceptions[index].reason;
+ --nexceptions;
+ memmove(exceptions + index, exceptions + index + 1, sizeof(Exception) * (nexceptions - index));
+ exceptions = static_cast<Exception *>(srealloc(exceptions, sizeof(Exception) * nexceptions));
+ }
+};
+
+class ExceptionListCallback : public NumberList
+{
+ protected:
+ User *u;
+ bool SentHeader;
+ public:
+ ExceptionListCallback(User *_u, const std::string &numlist) : NumberList(numlist, false), u(_u), SentHeader(false)
+ {
+ }
+
+ virtual void HandleNumber(unsigned Number)
+ {
+ if (Number > nexceptions)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER);
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_COLHEAD);
+ }
+
+ DoList(u, Number - 1);
+ }
+
+ static void DoList(User *u, unsigned index)
+ {
+ if (index >= nexceptions)
+ return;
+
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_FORMAT, index + 1, exceptions[index].limit, exceptions[index].mask);
+ }
+};
+
+class ExceptionViewCallback : public ExceptionListCallback
+{
+ public:
+ ExceptionViewCallback(User *_u, const std::string &numlist) : ExceptionListCallback(_u, numlist)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > nexceptions)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER);
+ }
+
+ DoList(u, Number - 1);
+ }
+
+ static void DoList(User *u, unsigned index)
+ {
+ if (index >= nexceptions)
+ return;
+
+ char timebuf[32], expirebuf[256];
+ struct tm tm;
+ time_t t = time(NULL);
+
+ tm = *localtime(exceptions[index].time ? &exceptions[index].time : &t);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+
+ expire_left(u->Account(), expirebuf, sizeof(expirebuf), exceptions[index].expires);
+
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_VIEW_FORMAT, index + 1, exceptions[index].mask, exceptions[index].who ? exceptions[index].who : "<unknown>", timebuf, expirebuf, exceptions[index].limit, exceptions[index].reason);
+ }
+};
+
class CommandOSSession : public Command
{
private:
CommandReturn DoList(User *u, const std::vector<ci::string> &params)
{
- Session *session;
- int mincount, i;
+ int mincount;
const char *param = params[1].c_str();
if ((mincount = atoi(param)) <= 1)
@@ -29,13 +143,13 @@ class CommandOSSession : public Command
{
notice_lang(Config.s_OperServ, u, OPER_SESSION_LIST_HEADER, mincount);
notice_lang(Config.s_OperServ, u, OPER_SESSION_LIST_COLHEAD);
- for (i = 0; i < 1024; ++i)
+
+ for (session_map::const_iterator it = SessionList.begin(); it != SessionList.end(); ++it)
{
- for (session = sessionlist[i]; session; session = session->next)
- {
- if (session->count >= mincount)
- notice_lang(Config.s_OperServ, u, OPER_SESSION_LIST_FORMAT, session->count, session->host);
- }
+ Session *session = it->second;
+
+ if (session->count >= mincount)
+ notice_lang(Config.s_OperServ, u, OPER_SESSION_LIST_FORMAT, session->count, session->host);
}
}
@@ -90,94 +204,12 @@ class CommandOSSession : public Command
{
syntax_error(Config.s_OperServ, u, "SESSION", OPER_SESSION_LIST_SYNTAX);
}
-};
-static int exception_del(User *u, const int index)
-{
- if (index < 0 || index >= nexceptions)
- return 0;
-
- FOREACH_MOD(I_OnExceptionDel, OnExceptionDel(u, &exceptions[index]));
-
- delete [] exceptions[index].mask;
- delete [] exceptions[index].reason;
- --nexceptions;
- memmove(exceptions + index, exceptions + index + 1, sizeof(Exception) * (nexceptions - index));
- exceptions = static_cast<Exception *>(srealloc(exceptions, sizeof(Exception) * nexceptions));
-
- return 1;
-}
-
-/* We use the "num" property to keep track of the position of each exception
- * when deleting using ranges. This is because an exception's position changes
- * as others are deleted. The positions will be recalculated once the process
- * is complete. -TheShadow
- */
-
-static int exception_del_callback(User *u, int num, va_list args)
-{
- int i;
- int *last = va_arg(args, int *);
-
- *last = num;
- for (i = 0; i < nexceptions; ++i)
- if (num - 1 == exceptions[i].num)
- break;
-
- if (i < nexceptions)
- return exception_del(u, i);
- else
- return 0;
-}
-
-static int exception_list(User *u, const int index, int *sent_header)
-{
- if (index < 0 || index >= nexceptions)
- return 0;
- if (!*sent_header) {
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER);
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_COLHEAD);
- *sent_header = 1;
- }
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_FORMAT, index + 1, exceptions[index].limit, exceptions[index].mask);
- return 1;
-}
-
-static int exception_list_callback(User *u, int num, va_list args)
-{
- int *sent_header = va_arg(args, int *);
-
- return exception_list(u, num - 1, sent_header);
-}
-
-static int exception_view(User *u, const int index, int *sent_header)
-{
- char timebuf[32], expirebuf[256];
- struct tm tm;
- time_t t = time(NULL);
-
- if (index < 0 || index >= nexceptions)
- return 0;
- if (!*sent_header) {
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER);
- *sent_header = 1;
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SESSION);
}
-
- tm = *localtime(exceptions[index].time ? &exceptions[index].time : &t);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
-
- expire_left(u->Account(), expirebuf, sizeof(expirebuf), exceptions[index].expires);
-
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_VIEW_FORMAT, index + 1, exceptions[index].mask, exceptions[index].who ? exceptions[index].who : "<unknown>", timebuf, expirebuf, exceptions[index].limit, exceptions[index].reason);
- return 1;
-}
-
-static int exception_view_callback(User *u, int num, va_list args)
-{
- int *sent_header = va_arg(args, int *);
-
- return exception_view(u, num - 1, sent_header);
-}
+};
class CommandOSException : public Command
{
@@ -189,12 +221,6 @@ class CommandOSException : public Command
unsigned last_param = 3;
int x;
- if (nexceptions >= 32767)
- {
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_TOO_MANY);
- return MOD_CONT;
- }
-
mask = params.size() > 1 ? params[1].c_str() : NULL;
if (mask && *mask == '+')
{
@@ -268,21 +294,7 @@ class CommandOSException : public Command
}
if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))
- {
- int count, deleted, last = -1;
- deleted = process_numlist(mask, &count, exception_del_callback, u, &last);
- if (!deleted)
- {
- if (count == 1)
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_SUCH_ENTRY, last);
- else
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH);
- }
- else if (deleted == 1)
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_DELETED_ONE);
- else
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_DELETED_SEVERAL, deleted);
- }
+ (new ExceptionDelCallback(u, mask))->Process();
else
{
int deleted = 0;
@@ -291,7 +303,7 @@ class CommandOSException : public Command
{
if (!stricmp(mask, exceptions[i].mask))
{
- exception_del(u, i);
+ ExceptionDelCallback::DoDel(u, i);
notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_DELETED, mask);
deleted = 1;
break;
@@ -368,44 +380,67 @@ class CommandOSException : public Command
CommandReturn DoList(User *u, const std::vector<ci::string> &params)
{
- int sent_header = 0, i;
+ int i;
expire_exceptions();
const char *mask = params.size() > 1 ? params[1].c_str() : NULL;
if (mask && strspn(mask, "1234567890,-") == strlen(mask))
- process_numlist(mask, NULL, exception_list_callback, u, &sent_header);
+ (new ExceptionListCallback(u, mask))->Process();
else
{
+ bool SentHeader = false;
+
for (i = 0; i < nexceptions; ++i)
{
if (!mask || Anope::Match(exceptions[i].mask, mask, false))
- exception_list(u, i, &sent_header);
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER);
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_COLHEAD);
+ }
+
+ ExceptionListCallback::DoList(u, i);
+ }
}
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH);
}
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH);
return MOD_CONT;
}
CommandReturn DoView(User *u, const std::vector<ci::string> &params)
{
- int sent_header = 0, i;
+ int i;
expire_exceptions();
const char *mask = params.size() > 1 ? params[1].c_str() : NULL;
if (mask && strspn(mask, "1234567890,-") == strlen(mask))
- process_numlist(mask, NULL, exception_view_callback, u, &sent_header);
+ (new ExceptionViewCallback(u, mask))->Process();
else
{
+ bool SentHeader = false;
+
for (i = 0; i < nexceptions; ++i)
{
if (!mask || Anope::Match(exceptions[i].mask, mask, false))
- exception_view(u, i, &sent_header);
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_LIST_HEADER);
+ }
+
+ ExceptionViewCallback::DoList(u, i);
+ }
}
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH);
}
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_EXCEPTION_NO_MATCH);
return MOD_CONT;
}
@@ -449,6 +484,11 @@ class CommandOSException : public Command
{
syntax_error(Config.s_OperServ, u, "EXCEPTION", OPER_EXCEPTION_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_EXCEPTION);
+ }
};
class OSSession : public Module
@@ -460,15 +500,8 @@ class OSSession : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSSession());
- this->AddCommand(OPERSERV, new CommandOSException());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SESSION);
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_EXCEPTION);
+ this->AddCommand(OperServ, new CommandOSSession());
+ this->AddCommand(OperServ, new CommandOSException());
}
};
diff --git a/src/core/os_set.c b/src/core/os_set.cpp
index dea5286d6..d51a13bd6 100644
--- a/src/core/os_set.c
+++ b/src/core/os_set.cpp
@@ -113,7 +113,7 @@ class CommandOSSet : public Command
if (ircd->join2msg)
{
c = findchan(Config.LogChannel);
- ircdproto->SendJoin(findbot(Config.s_GlobalNoticer), Config.LogChannel, c ? c->creation_time : time(NULL));
+ ircdproto->SendJoin(Global, Config.LogChannel, c ? c->creation_time : time(NULL));
}
LogChan = true;
Alog() << "Now sending log messages to " << Config.LogChannel;
@@ -123,7 +123,7 @@ class CommandOSSet : public Command
{
Alog() << "No longer sending log messages to a channel";
if (ircd->join2msg)
- ircdproto->SendPart(findbot(Config.s_GlobalNoticer), findchan(Config.LogChannel), NULL);
+ ircdproto->SendPart(Global, findchan(Config.LogChannel), NULL);
LogChan = false;
notice_lang(Config.s_OperServ, u, OPER_SET_LOGCHAN_OFF);
}
@@ -155,14 +155,14 @@ class CommandOSSet : public Command
u->isSuperAdmin = 1;
notice_lang(Config.s_OperServ, u, OPER_SUPER_ADMIN_ON);
Alog() << Config.s_OperServ << ": " << u->nick << " is a SuperAdmin";
- ircdproto->SendGlobops(findbot(Config.s_OperServ), getstring(OPER_SUPER_ADMIN_WALL_ON), u->nick.c_str());
+ ircdproto->SendGlobops(OperServ, getstring(OPER_SUPER_ADMIN_WALL_ON), u->nick.c_str());
}
else if (setting == "OFF")
{
u->isSuperAdmin = 0;
notice_lang(Config.s_OperServ, u, OPER_SUPER_ADMIN_OFF);
Alog() << Config.s_OperServ << ": " << u->nick << " is no longer a SuperAdmin";
- ircdproto->SendGlobops(findbot(Config.s_OperServ), getstring(OPER_SUPER_ADMIN_WALL_OFF), u->nick.c_str());
+ ircdproto->SendGlobops(OperServ, getstring(OPER_SUPER_ADMIN_WALL_OFF), u->nick.c_str());
}
else
notice_lang(Config.s_OperServ, u, OPER_SUPER_ADMIN_SYNTAX);
@@ -287,6 +287,11 @@ class CommandOSSet : public Command
{
syntax_error(Config.s_OperServ, u, "SET", OPER_SET_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SET);
+ }
};
class OSSet : public Module
@@ -298,13 +303,7 @@ class OSSet : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSSet());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SET);
+ this->AddCommand(OperServ, new CommandOSSet());
}
};
diff --git a/src/core/os_sgline.c b/src/core/os_sgline.c
deleted file mode 100644
index 4a4e5a13b..000000000
--- a/src/core/os_sgline.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-/*************************************************************************/
-
-#include "module.h"
-#include "hashcomp.h"
-
-int sgline_view_callback(SList *slist, int number, void *item, va_list args);
-int sgline_list_callback(SList *slist, int number, void *item, va_list args);
-int sgline_view(int number, SXLine *sx, User *u, int *sent_header);
-int sgline_list(int number, SXLine *sx, User *u, int *sent_header);
-
-static int sxline_del_callback(SList *slist, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(item), SX_SGLINE));
- return 1;
-}
-
-class CommandOSSGLine : public Command
-{
- private:
- CommandReturn OnAdd(User *u, const std::vector<ci::string> &params)
- {
- int deleted = 0;
- unsigned last_param = 2;
- const char *param, *expiry;
- char rest[BUFSIZE];
- time_t expires;
-
- param = params.size() > 1 ? params[1].c_str() : NULL;
- if (param && *param == '+')
- {
- expiry = param;
- param = params.size() > 2 ? params[2].c_str() : NULL;
- last_param = 3;
- }
- else
- expiry = NULL;
-
- expires = expiry ? dotime(expiry) : Config.SGLineExpiry;
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (expiry && isdigit(expiry[strlen(expiry) - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires && expires < 60)
- {
- notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
- return MOD_CONT;
- }
- else if (expires > 0)
- expires += time(NULL);
-
- if (!param)
- {
- this->OnSyntaxError(u, "ADD");
- return MOD_CONT;
- }
- snprintf(rest, sizeof(rest), "%s%s%s", param, params.size() > last_param ? " " : "", params.size() > last_param ? params[last_param].c_str() : "");
-
- if (std::string(rest).find(':') == std::string::npos)
- {
- this->OnSyntaxError(u, "ADD");
- return MOD_CONT;
- }
-
- sepstream sep(rest, ':');
- std::string mask;
- sep.GetToken(mask);
- std::string reason = sep.GetRemaining();
-
- if (!mask.empty() && !reason.empty()) {
- /* Clean up the last character of the mask if it is a space
- * See bug #761
- */
- unsigned masklen = mask.size();
- if (mask[masklen - 1] == ' ')
- mask.erase(masklen - 1);
-
- const char *cmask = mask.c_str();
-
- /* We first do some sanity check on the proposed mask. */
-
- if (!mask.empty() && strspn(cmask, "*?") == strlen(cmask)) {
- notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, cmask);
- return MOD_CONT;
- }
-
- deleted = add_sgline(u, cmask, u->nick.c_str(), expires, reason.c_str());
- if (deleted < 0)
- return MOD_CONT;
- else if (deleted)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL, deleted);
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_ADDED, cmask);
-
- if (Config.WallOSSGLine)
- {
- char buf[128];
-
- if (!expires)
- strcpy(buf, "does not expire");
- else
- {
- int wall_expiry = expires - time(NULL);
- const char *s = NULL;
-
- if (wall_expiry >= 86400)
- {
- wall_expiry /= 86400;
- s = "day";
- }
- else if (wall_expiry >= 3600)
- {
- wall_expiry /= 3600;
- s = "hour";
- }
- else if (wall_expiry >= 60)
- {
- wall_expiry /= 60;
- s = "minute";
- }
-
- snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
- }
-
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an SGLINE for %s (%s)", u->nick.c_str(), cmask, buf);
- }
-
- if (readonly)
- notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
-
- }
- else
- this->OnSyntaxError(u, "ADD");
-
- return MOD_CONT;
- }
-
- CommandReturn OnDel(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res = 0;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask)
- {
- this->OnSyntaxError(u, "DEL");
- return MOD_CONT;
- }
-
- if (!sglines.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))
- {
- /* Deleting a range */
- res = slist_delete_range(&sglines, mask, sxline_del_callback);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH);
- return MOD_CONT;
- }
- else if (res == 1)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED_ONE);
- else
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED_SEVERAL, res);
- }
- else {
- if ((res = slist_indexof(&sglines, const_cast<char *>(mask))) == -1)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NOT_FOUND, mask);
- return MOD_CONT;
- }
-
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(sglines.list[res]), SX_SGLINE));
- slist_delete(&sglines, res);
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_DELETED, mask);
- }
-
- if (readonly)
- notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
-
- return MOD_CONT;
- }
-
- CommandReturn OnList(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res, sent_header = 0;
-
- if (!sglines.count) {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&sglines, mask, &sgline_list_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
- else
- {
- int i;
- char *amask;
-
- for (i = 0; i < sglines.count; ++i)
- {
- amask = (static_cast<SXLine *>(sglines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- sgline_list(i + 1, static_cast<SXLine *>(sglines.list[i]), u, &sent_header);
- }
-
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH);
- else
- notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SGLine");
- }
-
- return MOD_CONT;
- }
-
- CommandReturn OnView(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res, sent_header = 0;
-
- if (!sglines.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&sglines, mask, &sgline_view_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
- else
- {
- int i;
- char *amask;
-
- for (i = 0; i < sglines.count; ++i)
- {
- amask = (static_cast<SXLine *>(sglines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- sgline_view(i + 1, static_cast<SXLine *>(sglines.list[i]), u, &sent_header);
- }
-
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_NO_MATCH);
- }
-
- return MOD_CONT;
- }
-
- CommandReturn OnClear(User *u)
- {
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, NULL, SX_SGLINE));
- slist_clear(&sglines, 1);
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_CLEAR);
-
- return MOD_CONT;
- }
- public:
- CommandOSSGLine() : Command("SGLINE", 1, 3, "operserv/sgline")
- {
- }
-
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
- {
- ci::string cmd = params[0];
-
- if (cmd == "ADD")
- return this->OnAdd(u, params);
- else if (cmd == "DEL")
- return this->OnDel(u, params);
- else if (cmd == "LIST")
- return this->OnList(u, params);
- else if (cmd == "VIEW")
- return this->OnView(u, params);
- else if (cmd == "CLEAR")
- return this->OnClear(u);
- else
- this->OnSyntaxError(u, "");
- return MOD_CONT;
- }
-
- bool OnHelp(User *u, const ci::string &subcommand)
- {
- notice_help(Config.s_OperServ, u, OPER_HELP_SGLINE);
- return true;
- }
-
- void OnSyntaxError(User *u, const ci::string &subcommand)
- {
- syntax_error(Config.s_OperServ, u, "SGLINE", OPER_SGLINE_SYNTAX);
- }
-};
-
-class OSSGLine : public Module
-{
- public:
- OSSGLine(const std::string &modname, const std::string &creator) : Module(modname, creator)
- {
-
- this->SetAuthor("Anope");
- this->SetVersion(VERSION_STRING);
- this->SetType(CORE);
-
- this->AddCommand(OPERSERV, new CommandOSSGLine());
-
- if (!ircd->sgline)
- throw ModuleException("Your IRCd does not support SGLine");
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SGLINE);
- }
-};
-
-/* Lists an SGLINE entry, prefixing it with the header if needed */
-int sgline_view(int number, SXLine *sx, User *u, int *sent_header)
-{
- char timebuf[32], expirebuf[256];
- struct tm tm;
-
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_VIEW_HEADER);
- *sent_header = 1;
- }
-
- tm = *localtime(&sx->seton);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
- expire_left(u->Account(), expirebuf, sizeof(expirebuf), sx->expires);
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_VIEW_FORMAT, number, sx->mask, sx->by, timebuf, expirebuf, sx->reason);
-
- return 1;
-}
-
-/* Callback for enumeration purposes */
-int sgline_view_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return sgline_view(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-/* Lists an SGLINE entry, prefixing it with the header if needed */
-int sgline_list(int number, SXLine *sx, User *u, int *sent_header)
-{
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_HEADER);
- *sent_header = 1;
- }
-
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_LIST_FORMAT, number, sx->mask, sx->reason);
-
- return 1;
-}
-
-/* Callback for enumeration purposes */
-int sgline_list_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return sgline_list(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-MODULE_INIT(OSSGLine)
diff --git a/src/core/os_shutdown.c b/src/core/os_shutdown.cpp
index be97153b4..772457602 100644
--- a/src/core/os_shutdown.c
+++ b/src/core/os_shutdown.cpp
@@ -41,6 +41,11 @@ class CommandOSShutdown : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_SHUTDOWN);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SHUTDOWN);
+ }
};
class OSShutdown : public Module
@@ -52,13 +57,7 @@ class OSShutdown : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSShutdown());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SHUTDOWN);
+ this->AddCommand(OperServ, new CommandOSShutdown());
}
};
diff --git a/src/core/os_snline.cpp b/src/core/os_snline.cpp
new file mode 100644
index 000000000..5463457de
--- /dev/null
+++ b/src/core/os_snline.cpp
@@ -0,0 +1,425 @@
+/* OperServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+#include "hashcomp.h"
+
+class SNLineDelCallback : public NumberList
+{
+ User *u;
+ unsigned Deleted;
+ public:
+ SNLineDelCallback(User *_u, const std::string &numlist) : NumberList(numlist, true), u(_u), Deleted(0)
+ {
+ }
+
+ ~SNLineDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH);
+ else if (Deleted == 0)
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_DELETED_ONE);
+ else
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_DELETED_SEVERAL, Deleted);
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SNLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ ++Deleted;
+ DoDel(u, x);
+ }
+
+ static void DoDel(User *u, XLine *x)
+ {
+ SNLine->DelXLine(x);
+ }
+};
+
+class SNLineListCallback : public NumberList
+{
+ protected:
+ User *u;
+ bool SentHeader;
+ public:
+ SNLineListCallback(User *_u, const std::string &numlist) : NumberList(numlist, false), u(_u), SentHeader(false)
+ {
+ }
+
+ ~SNLineListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH);
+ }
+
+ virtual void HandleNumber(unsigned Number)
+ {
+ XLine *x = SNLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_HEADER);
+ }
+
+ DoList(u, x, Number - 1);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str());
+ }
+};
+
+class SNLineViewCallback : public SNLineListCallback
+{
+ public:
+ SNLineViewCallback(User *_u, const std::string &numlist) : SNLineListCallback(_u, numlist)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SNLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_VIEW_HEADER);
+ }
+
+ DoList(u, x, Number - 1);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ char timebuf[32], expirebuf[256];
+ struct tm tm;
+
+ tm = *localtime(&x->Created);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires);
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf, expirebuf, x->Reason.c_str());
+ }
+};
+
+class CommandOSSNLine : public Command
+{
+ private:
+ CommandReturn OnAdd(User *u, const std::vector<ci::string> &params)
+ {
+ unsigned last_param = 2;
+ const char *param, *expiry;
+ char rest[BUFSIZE];
+ time_t expires;
+
+ param = params.size() > 1 ? params[1].c_str() : NULL;
+ if (param && *param == '+')
+ {
+ expiry = param;
+ param = params.size() > 2 ? params[2].c_str() : NULL;
+ last_param = 3;
+ }
+ else
+ expiry = NULL;
+
+ expires = expiry ? dotime(expiry) : Config.SNLineExpiry;
+ /* If the expiry given does not contain a final letter, it's in days,
+ * said the doc. Ah well.
+ */
+ if (expiry && isdigit(expiry[strlen(expiry) - 1]))
+ expires *= 86400;
+ /* Do not allow less than a minute expiry time */
+ if (expires && expires < 60)
+ {
+ notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
+ return MOD_CONT;
+ }
+ else if (expires > 0)
+ expires += time(NULL);
+
+ if (!param)
+ {
+ this->OnSyntaxError(u, "ADD");
+ return MOD_CONT;
+ }
+ snprintf(rest, sizeof(rest), "%s%s%s", param, params.size() > last_param ? " " : "", params.size() > last_param ? params[last_param].c_str() : "");
+
+ if (std::string(rest).find(':') == std::string::npos)
+ {
+ this->OnSyntaxError(u, "ADD");
+ return MOD_CONT;
+ }
+
+ sepstream sep(rest, ':');
+ ci::string mask;
+ sep.GetToken(mask);
+ std::string reason = sep.GetRemaining();
+
+ if (!mask.empty() && !reason.empty()) {
+ /* Clean up the last character of the mask if it is a space
+ * See bug #761
+ */
+ unsigned masklen = mask.size();
+ if (mask[masklen - 1] == ' ')
+ mask.erase(masklen - 1);
+
+ XLine *x = SNLine->Add(OperServ, u, mask, expires, reason);
+
+ if (!x)
+ return MOD_CONT;
+
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_ADDED, mask.c_str());
+
+ if (Config.WallOSSNLine)
+ {
+ char buf[128];
+
+ if (!expires)
+ strcpy(buf, "does not expire");
+ else
+ {
+ int wall_expiry = expires - time(NULL);
+ const char *s = NULL;
+
+ if (wall_expiry >= 86400)
+ {
+ wall_expiry /= 86400;
+ s = "day";
+ }
+ else if (wall_expiry >= 3600)
+ {
+ wall_expiry /= 3600;
+ s = "hour";
+ }
+ else if (wall_expiry >= 60)
+ {
+ wall_expiry /= 60;
+ s = "minute";
+ }
+
+ snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
+ }
+
+ ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an SNLINE for %s (%s)", u->nick.c_str(), mask.c_str(), buf);
+ }
+
+ if (readonly)
+ notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
+
+ }
+ else
+ this->OnSyntaxError(u, "ADD");
+
+ return MOD_CONT;
+ }
+
+ CommandReturn OnDel(User *u, const std::vector<ci::string> &params)
+ {
+ if (SNLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (mask.empty())
+ {
+ this->OnSyntaxError(u, "DEL");
+ return MOD_CONT;
+ }
+
+ if (isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SNLineDelCallback(u, mask.c_str()))->Process();
+ else
+ {
+ XLine *x = SNLine->HasEntry(mask);
+
+ if (!x)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_NOT_FOUND, mask.c_str());
+ return MOD_CONT;
+ }
+
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, X_SNLINE));
+
+ SNLineDelCallback::DoDel(u, x);
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_DELETED, mask.c_str());
+ }
+
+ if (readonly)
+ notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
+
+ return MOD_CONT;
+ }
+
+ CommandReturn OnList(User *u, const std::vector<ci::string> &params)
+ {
+ if (SNLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SNLineListCallback(u, mask.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < SNLine->GetCount(); ++i)
+ {
+ XLine *x = SNLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_HEADER);
+ }
+
+ SNLineListCallback::DoList(u, x, i);
+ }
+ }
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH);
+ else
+ notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SNLine");
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn OnView(User *u, const std::vector<ci::string> &params)
+ {
+ if (SNLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SNLineViewCallback(u, mask.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < SNLine->GetCount(); ++i)
+ {
+ XLine *x = SNLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_VIEW_HEADER);
+ }
+
+ SNLineViewCallback::DoList(u, x, i);
+ }
+ }
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_NO_MATCH);
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn OnClear(User *u)
+ {
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, NULL, X_SNLINE));
+ SNLine->Clear();
+ notice_lang(Config.s_OperServ, u, OPER_SNLINE_CLEAR);
+
+ return MOD_CONT;
+ }
+ public:
+ CommandOSSNLine() : Command("SNLINE", 1, 3, "operserv/snline")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ci::string cmd = params[0];
+
+ if (cmd == "ADD")
+ return this->OnAdd(u, params);
+ else if (cmd == "DEL")
+ return this->OnDel(u, params);
+ else if (cmd == "LIST")
+ return this->OnList(u, params);
+ else if (cmd == "VIEW")
+ return this->OnView(u, params);
+ else if (cmd == "CLEAR")
+ return this->OnClear(u);
+ else
+ this->OnSyntaxError(u, "");
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ notice_help(Config.s_OperServ, u, OPER_HELP_SNLINE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_OperServ, u, "SNLINE", OPER_SNLINE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SNLINE);
+ }
+};
+
+class OSSNLine : public Module
+{
+ public:
+ OSSNLine(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ this->AddCommand(OperServ, new CommandOSSNLine());
+
+ if (!ircd->snline)
+ throw ModuleException("Your IRCd does not support SNLine");
+ }
+};
+
+MODULE_INIT(OSSNLine)
diff --git a/src/core/os_sqline.c b/src/core/os_sqline.c
deleted file mode 100644
index c48791620..000000000
--- a/src/core/os_sqline.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-/*************************************************************************/
-
-#include "module.h"
-
-int sqline_view_callback(SList *slist, int number, void *item, va_list args);
-int sqline_list_callback(SList *slist, int number, void *item, va_list args);
-int sqline_view(int number, SXLine *sx, User *u, int *sent_header);
-int sqline_list(int number, SXLine *sx, User *u, int *sent_header);
-
-static int sxline_del_callback(SList *slist, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(item), SX_SQLINE));
- return 1;
-}
-
-class CommandOSSQLine : public Command
-{
- private:
- CommandReturn DoAdd(User *u, const std::vector<ci::string> &params)
- {
- int deleted = 0;
- unsigned last_param = 2;
- const char *expiry, *mask;
- char reason[BUFSIZE];
- time_t expires;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
- if (mask && *mask == '+')
- {
- expiry = mask;
- mask = params.size() > 2 ? params[2].c_str() : NULL;
- last_param = 3;
- }
- else
- expiry = NULL;
-
- expires = expiry ? dotime(expiry) : Config.SQLineExpiry;
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (expiry && isdigit(expiry[strlen(expiry) - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires != 0 && expires < 60)
- {
- notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
- return MOD_CONT;
- }
- else if (expires > 0)
- expires += time(NULL);
-
- if (params.size() <= last_param)
- {
- this->OnSyntaxError(u, "ADD");
- return MOD_CONT;
- }
- snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : "");
- if (mask && *reason)
- {
- /* We first do some sanity check on the proposed mask. */
- if (strspn(mask, "*") == strlen(mask))
- {
- notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
- return MOD_CONT;
- }
-
- /* Channel SQLINEs are only supported on Bahamut servers */
- if (*mask == '#' && !ircd->chansqline)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_CHANNELS_UNSUPPORTED);
- return MOD_CONT;
- }
-
- deleted = add_sqline(u, mask, u->nick.c_str(), expires, reason);
- if (deleted < 0)
- return MOD_CONT;
- else if (deleted)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_SEVERAL, deleted);
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_ADDED, mask);
-
- if (Config.WallOSSQLine)
- {
- char buf[128];
-
- if (!expires)
- strcpy(buf, "does not expire");
- else
- {
- int wall_expiry = expires - time(NULL);
- const char *s = NULL;
-
- if (wall_expiry >= 86400)
- {
- wall_expiry /= 86400;
- s = "day";
- }
- else if (wall_expiry >= 3600)
- {
- wall_expiry /= 3600;
- s = "hour";
- }
- else if (wall_expiry >= 60)
- {
- wall_expiry /= 60;
- s = "minute";
- }
-
- snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
- }
-
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an SQLINE for %s (%s)", u->nick.c_str(), mask, buf);
- }
-
- if (readonly)
- notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
-
- }
- else
- this->OnSyntaxError(u, "ADD");
-
- return MOD_CONT;
- }
-
- CommandReturn DoDel(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res = 0;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask)
- {
- this->OnSyntaxError(u, "DEL");
- return MOD_CONT;
- }
-
- if (!sqlines.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))
- {
- /* Deleting a range */
- res = slist_delete_range(&sqlines, mask, sxline_del_callback);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
- return MOD_CONT;
- }
- else if (res == 1)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_ONE);
- else
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_SEVERAL, res);
- }
- else {
- if ((res = slist_indexof(&sqlines, const_cast<char *>(mask))) == -1)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_NOT_FOUND, mask);
- return MOD_CONT;
- }
-
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(sqlines.list[res]), SX_SQLINE));
- slist_delete(&sqlines, res);
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED, mask);
- }
-
- if (readonly)
- notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
-
- return MOD_CONT;
- }
-
- CommandReturn DoList(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res, sent_header = 0;
-
- if (!sqlines.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&sqlines, mask, &sqline_list_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
- else
- {
- int i;
- char *amask;
-
- for (i = 0; i < sqlines.count; ++i)
- {
- amask = (static_cast<SXLine *>(sqlines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- sqline_list(i + 1, static_cast<SXLine *>(sqlines.list[i]), u, &sent_header);
- }
-
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
- else
- notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SQLine");
- }
-
- return MOD_CONT;
- }
-
- CommandReturn DoView(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res, sent_header = 0;
-
- if (!sqlines.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&sqlines, mask, &sqline_view_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
- else
- {
- int i;
- char *amask;
-
- for (i = 0; i < sqlines.count; ++i)
- {
- amask = (static_cast<SXLine *>(sqlines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- sqline_view(i + 1, static_cast<SXLine *>(sqlines.list[i]), u, &sent_header);
- }
-
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
- }
-
- return MOD_CONT;
- }
-
- CommandReturn DoClear(User *u)
- {
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, NULL, SX_SQLINE));
- slist_clear(&sqlines, 1);
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_CLEAR);
-
- return MOD_CONT;
- }
- public:
- CommandOSSQLine() : Command("SQLINE", 1, 4, "operserv/sqline")
- {
- }
-
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
- {
- ci::string cmd = params[0];
-
- if (cmd == "ADD")
- return this->DoAdd(u, params);
- else if (cmd == "DEL")
- return this->DoDel(u, params);
- else if (cmd == "LIST")
- return this->DoList(u, params);
- else if (cmd == "VIEW")
- return this->DoView(u, params);
- else if (cmd == "CLEAR")
- return this->DoClear(u);
- else
- this->OnSyntaxError(u, "");
- return MOD_CONT;
- }
-
- bool OnHelp(User *u, const ci::string &subcommand)
- {
- notice_help(Config.s_OperServ, u, OPER_HELP_SQLINE);
- return true;
- }
-
- void OnSyntaxError(User *u, const ci::string &subcommand)
- {
- syntax_error(Config.s_OperServ, u, "SQLINE", OPER_SQLINE_SYNTAX);
- }
-};
-
-class OSSQLine : public Module
-{
- public:
- OSSQLine(const std::string &modname, const std::string &creator) : Module(modname, creator)
- {
- this->SetAuthor("Anope");
- this->SetVersion(VERSION_STRING);
- this->SetType(CORE);
-
- this->AddCommand(OPERSERV, new CommandOSSQLine());
-
- if (!ircd->sqline)
- throw ModuleException("Your IRCd does not support QLines.");
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SQLINE);
- }
-};
-
-int sqline_view(int number, SXLine *sx, User *u, int *sent_header)
-{
- char timebuf[32], expirebuf[256];
- struct tm tm;
-
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_HEADER);
- *sent_header = 1;
- }
-
- tm = *localtime(&sx->seton);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
- expire_left(u->Account(), expirebuf, sizeof(expirebuf), sx->expires);
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_FORMAT, number, sx->mask, sx->by, timebuf, expirebuf, sx->reason);
-
- return 1;
-}
-
-/* Callback for enumeration purposes */
-int sqline_view_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return sqline_view(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-/* Lists an SQLINE entry, prefixing it with the header if needed */
-int sqline_list(int number, SXLine *sx, User *u, int *sent_header)
-{
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_HEADER);
- *sent_header = 1;
- }
-
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_FORMAT, number, sx->mask, sx->reason);
-
- return 1;
-}
-
-/* Callback for enumeration purposes */
-int sqline_list_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return sqline_list(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-MODULE_INIT(OSSQLine)
diff --git a/src/core/os_sqline.cpp b/src/core/os_sqline.cpp
new file mode 100644
index 000000000..37f22b14a
--- /dev/null
+++ b/src/core/os_sqline.cpp
@@ -0,0 +1,406 @@
+/* OperServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class SQLineDelCallback : public NumberList
+{
+ User *u;
+ unsigned Deleted;
+ public:
+ SQLineDelCallback(User *_u, const std::string &numlist) : NumberList(numlist, true), u(_u), Deleted(0)
+ {
+ }
+
+ ~SQLineDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
+ else if (Deleted == 0)
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_ONE);
+ else
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED_SEVERAL, Deleted);
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SQLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ ++Deleted;
+ DoDel(u, x - 1);
+ }
+
+ static void DoDel(User *u, XLine *x)
+ {
+ SQLine->DelXLine(x);
+ }
+};
+
+class SQLineListCallback : public NumberList
+{
+ protected:
+ User *u;
+ bool SentHeader;
+ public:
+ SQLineListCallback(User *_u, const std::string &numlist) : NumberList(numlist, false), u(_u), SentHeader(false)
+ {
+ }
+
+ ~SQLineListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
+ }
+
+ virtual void HandleNumber(unsigned Number)
+ {
+ XLine *x = SQLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_HEADER);
+ }
+
+ DoList(u, x, Number - 1);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str());
+ }
+};
+
+class SQLineViewCallback : public SQLineListCallback
+{
+ public:
+ SQLineViewCallback(User *_u, const std::string &numlist) : SQLineListCallback(_u, numlist)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SQLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_HEADER);
+ }
+
+ DoList(u, x, Number);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ char timebuf[32], expirebuf[256];
+ struct tm tm;
+
+ tm = *localtime(&x->Created);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires);
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf,
+expirebuf, x->Reason.c_str());
+ }
+};
+
+
+class CommandOSSQLine : public Command
+{
+ private:
+ CommandReturn DoAdd(User *u, const std::vector<ci::string> &params)
+ {
+ unsigned last_param = 2;
+ const char *expiry, *mask;
+ char reason[BUFSIZE];
+ time_t expires;
+
+ mask = params.size() > 1 ? params[1].c_str() : NULL;
+ if (mask && *mask == '+')
+ {
+ expiry = mask;
+ mask = params.size() > 2 ? params[2].c_str() : NULL;
+ last_param = 3;
+ }
+ else
+ expiry = NULL;
+
+ expires = expiry ? dotime(expiry) : Config.SQLineExpiry;
+ /* If the expiry given does not contain a final letter, it's in days,
+ * said the doc. Ah well.
+ */
+ if (expiry && isdigit(expiry[strlen(expiry) - 1]))
+ expires *= 86400;
+ /* Do not allow less than a minute expiry time */
+ if (expires != 0 && expires < 60)
+ {
+ notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
+ return MOD_CONT;
+ }
+ else if (expires > 0)
+ expires += time(NULL);
+
+ if (params.size() <= last_param)
+ {
+ this->OnSyntaxError(u, "ADD");
+ return MOD_CONT;
+ }
+ snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : "");
+ if (mask && *reason)
+ {
+ XLine *x = SQLine->Add(OperServ, u, mask, expires, reason);
+
+ if (!x)
+ return MOD_CONT;
+
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_ADDED, mask);
+
+ if (Config.WallOSSQLine)
+ {
+ char buf[128];
+
+ if (!expires)
+ strcpy(buf, "does not expire");
+ else
+ {
+ int wall_expiry = expires - time(NULL);
+ const char *s = NULL;
+
+ if (wall_expiry >= 86400)
+ {
+ wall_expiry /= 86400;
+ s = "day";
+ }
+ else if (wall_expiry >= 3600)
+ {
+ wall_expiry /= 3600;
+ s = "hour";
+ }
+ else if (wall_expiry >= 60)
+ {
+ wall_expiry /= 60;
+ s = "minute";
+ }
+
+ snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
+ }
+
+ ircdproto->SendGlobops(OperServ, "%s added an SQLINE for %s (%s)", u->nick.c_str(), mask, buf);
+ }
+
+ if (readonly)
+ notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
+
+ }
+ else
+ this->OnSyntaxError(u, "ADD");
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoDel(User *u, const std::vector<ci::string> &params)
+ {
+ if (SQLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (mask.empty())
+ {
+ this->OnSyntaxError(u, "DEL");
+ return MOD_CONT;
+ }
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SQLineDelCallback(u, mask.c_str()))->Process();
+ else
+ {
+ XLine *x = SQLine->HasEntry(mask);
+
+ if (!x)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_NOT_FOUND, mask.c_str());
+ return MOD_CONT;
+ }
+
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, X_SQLINE));
+
+ SQLineDelCallback::DoDel(u, x);
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_DELETED, mask.c_str());
+ }
+
+ if (readonly)
+ notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoList(User *u, const std::vector<ci::string> &params)
+ {
+ if (SQLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SQLineListCallback(u, mask.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < SQLine->GetCount(); ++i)
+ {
+ XLine *x = SQLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_HEADER);
+ }
+
+ SQLineListCallback::DoList(u, x, i);
+ }
+ }
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
+ else
+ notice_lang(Config.s_OperServ, u, END_OF_ANY_LIST, "SQLine");
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoView(User *u, const std::vector<ci::string> &params)
+ {
+ if (SQLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SQLineViewCallback(u, mask.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < SQLine->GetCount(); ++i)
+ {
+ XLine *x = SQLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_VIEW_HEADER);
+ }
+
+ SQLineViewCallback::DoList(u, x, i);
+ }
+ }
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_NO_MATCH);
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoClear(User *u)
+ {
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, NULL, X_SQLINE));
+ SGLine->Clear();
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_CLEAR);
+
+ return MOD_CONT;
+ }
+ public:
+ CommandOSSQLine() : Command("SQLINE", 1, 4, "operserv/sqline")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ci::string cmd = params[0];
+
+ if (cmd == "ADD")
+ return this->DoAdd(u, params);
+ else if (cmd == "DEL")
+ return this->DoDel(u, params);
+ else if (cmd == "LIST")
+ return this->DoList(u, params);
+ else if (cmd == "VIEW")
+ return this->DoView(u, params);
+ else if (cmd == "CLEAR")
+ return this->DoClear(u);
+ else
+ this->OnSyntaxError(u, "");
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ notice_help(Config.s_OperServ, u, OPER_HELP_SQLINE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_OperServ, u, "SQLINE", OPER_SQLINE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SQLINE);
+ }
+};
+
+class OSSQLine : public Module
+{
+ public:
+ OSSQLine(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion(VERSION_STRING);
+ this->SetType(CORE);
+
+ this->AddCommand(OperServ, new CommandOSSQLine());
+
+ if (!ircd->sqline)
+ throw ModuleException("Your IRCd does not support QLines.");
+ }
+};
+
+MODULE_INIT(OSSQLine)
diff --git a/src/core/os_staff.c b/src/core/os_staff.cpp
index f0e831bfc..930f8db7b 100644
--- a/src/core/os_staff.c
+++ b/src/core/os_staff.cpp
@@ -34,8 +34,10 @@ class CommandOSStaff : public Command
if (na)
{
/* We have to loop all users as some may be logged into an account but not a nick */
- for (User *u2 = firstuser(); u2; u2 = nextuser())
+ for (user_map::iterator uit = UserListByNick.begin(); uit != UserListByNick.end(); ++uit)
{
+ User *u2 = uit->second;
+
if (u2->Account() && u2->Account() == na->nc)
{
found = 1;
@@ -61,6 +63,11 @@ class CommandOSStaff : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_STAFF);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_STAFF);
+ }
};
class OSStaff : public Module
@@ -72,13 +79,7 @@ class OSStaff : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSStaff());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_STAFF);
+ this->AddCommand(OperServ, new CommandOSStaff());
}
};
diff --git a/src/core/os_stats.c b/src/core/os_stats.cpp
index 711e1f646..5b993ad8f 100644
--- a/src/core/os_stats.c
+++ b/src/core/os_stats.cpp
@@ -21,16 +21,19 @@ void get_operserv_stats(long *nrec, long *memuse);
* @param s The server to start counting from
* @return Amount of servers connected to server s
**/
-int stats_count_servers(Server *s)
+static int stats_count_servers(Server *s)
{
- int count = 0;
+ if (!s)
+ return 0;
+
+ int count = 1;
- while (s)
+ if (s->GetLinks())
{
- ++count;
- if (s->links)
- count += stats_count_servers(s->links);
- s = s->next;
+ for (std::list<Server *>::const_iterator it = s->GetLinks()->begin(); it != s->GetLinks()->end(); ++it)
+ {
+ count += stats_count_servers(*it);
+ }
}
return count;
@@ -43,7 +46,7 @@ class CommandOSStats : public Command
{
int timeout;
/* AKILLs */
- notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_COUNT, akills.count);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_COUNT, SGLine->GetCount());
timeout = Config.AutokillExpiry + 59;
if (timeout >= 172800)
notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_EXPIRE_DAYS, timeout / 86400);
@@ -59,30 +62,30 @@ class CommandOSStats : public Command
notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_EXPIRE_MIN);
else
notice_lang(Config.s_OperServ, u, OPER_STATS_AKILL_EXPIRE_NONE);
- if (ircd->sgline)
+ if (ircd->snline)
{
- /* SGLINEs */
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_COUNT, sglines.count);
- timeout = Config.SGLineExpiry + 59;
+ /* SNLINEs */
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_COUNT, SNLine->GetCount());
+ timeout = Config.SNLineExpiry + 59;
if (timeout >= 172800)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_DAYS, timeout / 86400);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_DAYS, timeout / 86400);
else if (timeout >= 86400)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_DAY);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_DAY);
else if (timeout >= 7200)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_HOURS, timeout / 3600);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_HOURS, timeout / 3600);
else if (timeout >= 3600)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_HOUR);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_HOUR);
else if (timeout >= 120)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_MINS, timeout / 60);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_MINS, timeout / 60);
else if (timeout >= 60)
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_MIN);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_MIN);
else
- notice_lang(Config.s_OperServ, u, OPER_STATS_SGLINE_EXPIRE_NONE);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SNLINE_EXPIRE_NONE);
}
if (ircd->sqline)
{
/* SQLINEs */
- notice_lang(Config.s_OperServ, u, OPER_STATS_SQLINE_COUNT, sqlines.count);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SQLINE_COUNT, SQLine->GetCount());
timeout = Config.SQLineExpiry + 59;
if (timeout >= 172800)
notice_lang(Config.s_OperServ, u, OPER_STATS_SQLINE_EXPIRE_DAYS, timeout / 86400);
@@ -102,7 +105,7 @@ class CommandOSStats : public Command
if (ircd->szline)
{
/* SZLINEs */
- notice_lang(Config.s_OperServ, u, OPER_STATS_SZLINE_COUNT, szlines.count);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_SZLINE_COUNT, SZLine->GetCount());
timeout = Config.SZLineExpiry + 59;
if (timeout >= 172800)
notice_lang(Config.s_OperServ, u, OPER_STATS_SZLINE_EXPIRE_DAYS, timeout / 86400);
@@ -214,9 +217,9 @@ class CommandOSStats : public Command
if (!buf.empty())
buf.erase(buf.begin());
- notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER, serv_uplink->name);
+ notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER, Me->GetUplink()->GetName().c_str());
notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_CAPAB, buf.c_str());
- notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER_COUNT, stats_count_servers(serv_uplink));
+ notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER_COUNT, stats_count_servers(Me->GetUplink()));
return MOD_CONT;
}
@@ -290,6 +293,11 @@ class CommandOSStats : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_STATS);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_STATS);
+ }
};
class OSStats : public Module
@@ -301,76 +309,80 @@ class OSStats : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSStats());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_STATS);
+ this->AddCommand(OperServ, new CommandOSStats());
}
};
void get_operserv_stats(long *nrec, long *memuse)
{
- int i;
+ unsigned i;
long mem = 0, count = 0, mem2 = 0, count2 = 0;
- Akill *ak;
- SXLine *sx;
+ XLine *x;
- count += akills.count;
- mem += akills.capacity;
- mem += akills.count * sizeof(Akill);
+ count += SGLine->GetCount();
+ mem += SGLine->GetCount() * sizeof(XLine);
- for (i = 0; i < akills.count; ++i)
+ for (i = 0; i < SGLine->GetCount(); ++i)
{
- ak = static_cast<Akill *>(akills.list[i]);
- mem += strlen(ak->user) + 1;
- mem += strlen(ak->host) + 1;
- mem += strlen(ak->by) + 1;
- mem += strlen(ak->reason) + 1;
+ x = SGLine->GetEntry(i);
+
+ mem += x->GetNick().length() + 1;
+ mem += x->GetUser().length() + 1;
+ mem += x->GetHost().length() + 1;
+ mem += x->Mask.length() + 1;
+ mem += x->By.length() + 1;
+ mem += x->Reason.length() + 1;
}
- if (ircd->sgline)
+ if (ircd->snline)
{
- count += sglines.count;
- mem += sglines.capacity;
- mem += sglines.count * sizeof(SXLine);
+ count += SNLine->GetCount();
+ mem += SNLine->GetCount() * sizeof(XLine);
- for (i = 0; i < sglines.count; ++i)
+ for (i = 0; i < SNLine->GetCount(); ++i)
{
- sx = static_cast<SXLine *>(sglines.list[i]);
- mem += strlen(sx->mask) + 1;
- mem += strlen(sx->by) + 1;
- mem += strlen(sx->reason) + 1;
+ x = SNLine->GetEntry(i);
+
+ mem += x->GetNick().length() + 1;
+ mem += x->GetUser().length() + 1;
+ mem += x->GetHost().length() + 1;
+ mem += x->Mask.length() + 1;
+ mem += x->By.length() + 1;
+ mem += x->Reason.length() + 1;
}
}
if (ircd->sqline)
{
- count += sqlines.count;
- mem += sqlines.capacity;
- mem += sqlines.count * sizeof(SXLine);
+ count += SQLine->GetCount();
+ mem += SGLine->GetCount() * sizeof(XLine);
- for (i = 0; i < sqlines.count; ++i)
+ for (i = 0; i < SQLine->GetCount(); ++i)
{
- sx = static_cast<SXLine *>(sqlines.list[i]);
- mem += strlen(sx->mask) + 1;
- mem += strlen(sx->by) + 1;
- mem += strlen(sx->reason) + 1;
+ x = SNLine->GetEntry(i);
+
+ mem += x->GetNick().length() + 1;
+ mem += x->GetUser().length() + 1;
+ mem += x->GetHost().length() + 1;
+ mem += x->Mask.length() + 1;
+ mem += x->By.length() + 1;
+ mem += x->Reason.length() + 1;
}
}
if (ircd->szline)
{
- count += szlines.count;
- mem += szlines.capacity;
- mem += szlines.count * sizeof(SXLine);
-
- for (i = 0; i < szlines.count; ++i)
+ count += SZLine->GetCount();
+ mem += SZLine->GetCount() * sizeof(XLine);
+
+ for (i = 0; i < SZLine->GetCount(); ++i)
{
- sx = static_cast<SXLine *>(szlines.list[i]);
- mem += strlen(sx->mask) + 1;
- mem += strlen(sx->by) + 1;
- mem += strlen(sx->reason) + 1;
+ x = SZLine->GetEntry(i);
+
+ mem += x->GetNick().length() + 1;
+ mem += x->GetUser().length() + 1;
+ mem += x->GetHost().length() + 1;
+ mem += x->Mask.length() + 1;
+ mem += x->By.length() + 1;
+ mem += x->Reason.length() + 1;
}
}
diff --git a/src/core/os_svsnick.c b/src/core/os_svsnick.cpp
index 856f460bc..d3b0a5eaa 100644
--- a/src/core/os_svsnick.c
+++ b/src/core/os_svsnick.cpp
@@ -54,14 +54,14 @@ class CommandOSSVSNick : public Command
/* Check for a nick in use or a forbidden/suspended nick */
if (!(u2 = finduser(nick)))
notice_lang(Config.s_OperServ, u, NICK_X_NOT_IN_USE, nick);
- else if (finduser(newnick.c_str()))
+ else if (finduser(newnick))
notice_lang(Config.s_OperServ, u, NICK_X_IN_USE, newnick.c_str());
- else if ((na = findnick(newnick.c_str())) && (na->HasFlag(NS_FORBIDDEN)))
+ else if ((na = findnick(newnick)) && (na->HasFlag(NS_FORBIDDEN)))
notice_lang(Config.s_OperServ, u, NICK_X_FORBIDDEN, newnick.c_str());
else
{
notice_lang(Config.s_OperServ, u, OPER_SVSNICK_NEWNICK, nick, newnick.c_str());
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s used SVSNICK to change %s to %s", u->nick.c_str(), nick, newnick.c_str());
+ ircdproto->SendGlobops(OperServ, "%s used SVSNICK to change %s to %s", u->nick.c_str(), nick, newnick.c_str());
ircdproto->SendForceNickChange(u2, newnick.c_str(), time(NULL));
}
return MOD_CONT;
@@ -77,6 +77,11 @@ class CommandOSSVSNick : public Command
{
syntax_error(Config.s_OperServ, u, "SVSNICK", OPER_SVSNICK_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SVSNICK);
+ }
};
class OSSVSNick : public Module
@@ -88,16 +93,10 @@ class OSSVSNick : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSSVSNick());
+ this->AddCommand(OperServ, new CommandOSSVSNick());
if (!ircd->svsnick)
throw ModuleException("Your IRCd does not support SVSNICK");
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SVSNICK);
}
};
diff --git a/src/core/os_szline.c b/src/core/os_szline.c
deleted file mode 100644
index b99844835..000000000
--- a/src/core/os_szline.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/* OperServ core functions
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-/*************************************************************************/
-
-#include "module.h"
-
-int szline_view_callback(SList *slist, int number, void *item, va_list args);
-int szline_list_callback(SList *slist, int number, void *item, va_list args);
-int szline_view(int number, SXLine *sx, User *u, int *sent_header);
-int szline_list(int number, SXLine *sx, User *u, int *sent_header);
-
-static int sxline_del_callback(SList *slist, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(item), SX_SZLINE));
- return 1;
-}
-
-class CommandOSSZLine : public Command
-{
- private:
- CommandReturn DoAdd(User *u, const std::vector<ci::string> &params)
- {
- int deleted = 0;
- unsigned last_param = 2;
- const char *expiry, *mask;
- char reason[BUFSIZE];
- time_t expires;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
- if (mask && *mask == '+')
- {
- expiry = mask;
- mask = params.size() > 2 ? params[2].c_str() : NULL;
- last_param = 3;
- }
- else
- expiry = NULL;
-
- expires = expiry ? dotime(expiry) : Config.SZLineExpiry;
- /* If the expiry given does not contain a final letter, it's in days,
- * said the doc. Ah well.
- */
- if (expiry && isdigit(expiry[strlen(expiry) - 1]))
- expires *= 86400;
- /* Do not allow less than a minute expiry time */
- if (expires != 0 && expires < 60)
- {
- notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
- return MOD_CONT;
- }
- else if (expires > 0)
- expires += time(NULL);
-
- if (params.size() <= last_param)
- {
- this->OnSyntaxError(u, "ADD");
- return MOD_CONT;
- }
- snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : "");
- if (mask && *reason)
- {
- /* We first do some sanity check on the proposed mask. */
-
- if (strchr(mask, '!') || strchr(mask, '@'))
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_ONLY_IPS);
- return MOD_CONT;
- }
-
- if (strspn(mask, "*?") == strlen(mask))
- {
- notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask);
- return MOD_CONT;
- }
-
- deleted = add_szline(u, mask, u->nick.c_str(), expires, reason);
- if (deleted < 0)
- return MOD_CONT;
- else if (deleted)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_SEVERAL, deleted);
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_ADDED, mask);
-
- if (Config.WallOSSZLine)
- {
- char buf[128];
-
- if (!expires)
- strcpy(buf, "does not expire");
- else
- {
- int wall_expiry = expires - time(NULL);
- const char *s = NULL;
-
- if (wall_expiry >= 86400)
- {
- wall_expiry /= 86400;
- s = "day";
- }
- else if (wall_expiry >= 3600)
- {
- wall_expiry /= 3600;
- s = "hour";
- }
- else if (wall_expiry >= 60)
- {
- wall_expiry /= 60;
- s = "minute";
- }
-
- snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
- }
-
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s added an SZLINE for %s (%s)", u->nick.c_str(), mask, buf);
- }
-
- if (readonly)
- notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
-
- }
- else
- this->OnSyntaxError(u, "ADD");
-
- return MOD_CONT;
- }
-
- CommandReturn DoDel(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res = 0;
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask)
- {
- this->OnSyntaxError(u, "DEL");
- return MOD_CONT;
- }
-
- if (!szlines.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask))
- {
- /* Deleting a range */
- res = slist_delete_range(&szlines, mask, sxline_del_callback);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
- return MOD_CONT;
- }
- else if (res == 1)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_ONE);
- else
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_SEVERAL, res);
- }
- else
- {
- if ((res = slist_indexof(&szlines, const_cast<char *>(mask))) == -1)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_NOT_FOUND, mask);
- return MOD_CONT;
- }
-
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, static_cast<SXLine *>(szlines.list[res]), SX_SZLINE));
- slist_delete(&szlines, res);
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED, mask);
- }
-
- if (readonly)
- notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
-
- return MOD_CONT;
- }
-
- CommandReturn DoList(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res, sent_header = 0;
-
- if (!szlines.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&szlines, mask, &szline_list_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
- else
- {
- int i;
- char *amask;
-
- for (i = 0; i < szlines.count; ++i)
- {
- amask = (static_cast<SXLine *>(szlines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- szline_list(i + 1, static_cast<SXLine *>(szlines.list[i]), u, &sent_header);
- }
-
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
- }
-
- return MOD_CONT;
- }
-
- CommandReturn DoView(User *u, const std::vector<ci::string> &params)
- {
- const char *mask;
- int res, sent_header = 0;
-
- if (!szlines.count)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY);
- return MOD_CONT;
- }
-
- mask = params.size() > 1 ? params[1].c_str() : NULL;
-
- if (!mask || (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)))
- {
- res = slist_enum(&szlines, mask, &szline_view_callback, u, &sent_header);
- if (!res)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
- return MOD_CONT;
- }
- }
- else
- {
- int i;
- char *amask;
-
- for (i = 0; i < szlines.count; ++i)
- {
- amask = (static_cast<SXLine *>(szlines.list[i]))->mask;
- if (!stricmp(mask, amask) || Anope::Match(amask, mask, false))
- szline_view(i + 1, static_cast<SXLine *>(szlines.list[i]), u, &sent_header);
- }
-
- if (!sent_header)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
- }
-
- return MOD_CONT;
- }
-
- CommandReturn DoClear(User *u)
- {
- FOREACH_MOD(I_OnDelSXLine, OnDelSXLine(u, NULL, SX_SZLINE));
- slist_clear(&szlines, 1);
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_CLEAR);
-
- return MOD_CONT;
- }
- public:
- CommandOSSZLine() : Command("SZLINE", 1, 4, "operserv/szline")
- {
- }
-
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
- {
- ci::string cmd = params[0];
-
- if (cmd == "ADD")
- return this->DoAdd(u, params);
- else if (cmd == "DEL")
- return this->DoDel(u, params);
- else if (cmd == "LIST")
- return this->DoList(u, params);
- else if (cmd == "VIEW")
- return this->DoView(u, params);
- else if (cmd == "CLEAR")
- return this->DoClear(u);
- else
- this->OnSyntaxError(u, "");
- return MOD_CONT;
- }
-
- bool OnHelp(User *u, const ci::string &subcommand)
- {
- notice_help(Config.s_OperServ, u, OPER_HELP_SZLINE);
- return true;
- }
-
- void OnSyntaxError(User *u, const ci::string &subcommand)
- {
- syntax_error(Config.s_OperServ, u, "SZLINE", OPER_SZLINE_SYNTAX);
- }
-};
-
-class OSSZLine : public Module
-{
- public:
- OSSZLine(const std::string &modname, const std::string &creator) : Module(modname, creator)
- {
- this->SetAuthor("Anope");
- this->SetVersion(VERSION_STRING);
- this->SetType(CORE);
-
- this->AddCommand(OPERSERV, new CommandOSSZLine());
-
- if (!ircd->szline)
- throw ModuleException("Your IRCd does not support ZLINEs");
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SZLINE);
- }
-};
-
-int szline_view(int number, SXLine *sx, User *u, int *sent_header)
-{
- char timebuf[32], expirebuf[256];
- struct tm tm;
-
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_HEADER);
- *sent_header = 1;
- }
-
- tm = *localtime(&sx->seton);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
- expire_left(u->Account(), expirebuf, sizeof(expirebuf), sx->expires);
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_FORMAT, number, sx->mask, sx->by, timebuf, expirebuf, sx->reason);
-
- return 1;
-}
-
-/* Callback for enumeration purposes */
-int szline_view_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return szline_view(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-/* Callback for enumeration purposes */
-int szline_list_callback(SList *slist, int number, void *item, va_list args)
-{
- User *u = va_arg(args, User *);
- int *sent_header = va_arg(args, int *);
-
- return szline_list(number, static_cast<SXLine *>(item), u, sent_header);
-}
-
-/* Lists an SZLINE entry, prefixing it with the header if needed */
-int szline_list(int number, SXLine *sx, User *u, int *sent_header)
-{
- if (!sx)
- return 0;
-
- if (!*sent_header)
- {
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_HEADER);
- *sent_header = 1;
- }
-
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_FORMAT, number, sx->mask, sx->reason);
-
- return 1;
-}
-
-MODULE_INIT(OSSZLine)
diff --git a/src/core/os_szline.cpp b/src/core/os_szline.cpp
new file mode 100644
index 000000000..2a8b642cd
--- /dev/null
+++ b/src/core/os_szline.cpp
@@ -0,0 +1,404 @@
+/* OperServ core functions
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class SZLineDelCallback : public NumberList
+{
+ User *u;
+ unsigned Deleted;
+ public:
+ SZLineDelCallback(User *_u, const std::string &numlist) : NumberList(numlist, true), u(_u), Deleted(0)
+ {
+ }
+
+ ~SZLineDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
+ else if (Deleted == 0)
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_ONE);
+ else
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED_SEVERAL, Deleted);
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SZLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ ++Deleted;
+ DoDel(u, x);
+ }
+
+ static void DoDel(User *u, XLine *x)
+ {
+ SZLine->DelXLine(x);
+ }
+};
+
+class SZLineListCallback : public NumberList
+{
+ protected:
+ User *u;
+ bool SentHeader;
+ public:
+ SZLineListCallback(User *_u, const std::string &numlist) : NumberList(numlist, false), u(_u), SentHeader(false)
+ {
+ }
+
+ ~SZLineListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
+ }
+
+ virtual void HandleNumber(unsigned Number)
+ {
+ XLine *x = SZLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_HEADER);
+ }
+
+ DoList(u, x, Number - 1);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_FORMAT, Number + 1, x->Mask.c_str(), x->Reason.c_str());
+ }
+};
+
+class SZLineViewCallback : public SZLineListCallback
+{
+ public:
+ SZLineViewCallback(User *_u, const std::string &numlist) : SZLineListCallback(_u, numlist)
+ {
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ XLine *x = SZLine->GetEntry(Number - 1);
+
+ if (!x)
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_HEADER);
+ }
+
+ DoList(u, x, Number - 1);
+ }
+
+ static void DoList(User *u, XLine *x, unsigned Number)
+ {
+ char timebuf[32], expirebuf[256];
+ struct tm tm;
+
+ tm = *localtime(&x->Created);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ expire_left(u->Account(), expirebuf, sizeof(expirebuf), x->Expires);
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_FORMAT, Number + 1, x->Mask.c_str(), x->By.c_str(), timebuf,
+expirebuf, x->Reason.c_str());
+ }
+};
+
+
+class CommandOSSZLine : public Command
+{
+ private:
+ CommandReturn DoAdd(User *u, const std::vector<ci::string> &params)
+ {
+ unsigned last_param = 2;
+ const char *expiry, *mask;
+ char reason[BUFSIZE];
+ time_t expires;
+
+ mask = params.size() > 1 ? params[1].c_str() : NULL;
+ if (mask && *mask == '+')
+ {
+ expiry = mask;
+ mask = params.size() > 2 ? params[2].c_str() : NULL;
+ last_param = 3;
+ }
+ else
+ expiry = NULL;
+
+ expires = expiry ? dotime(expiry) : Config.SZLineExpiry;
+ /* If the expiry given does not contain a final letter, it's in days,
+ * said the doc. Ah well.
+ */
+ if (expiry && isdigit(expiry[strlen(expiry) - 1]))
+ expires *= 86400;
+ /* Do not allow less than a minute expiry time */
+ if (expires != 0 && expires < 60)
+ {
+ notice_lang(Config.s_OperServ, u, BAD_EXPIRY_TIME);
+ return MOD_CONT;
+ }
+ else if (expires > 0)
+ expires += time(NULL);
+
+ if (params.size() <= last_param)
+ {
+ this->OnSyntaxError(u, "ADD");
+ return MOD_CONT;
+ }
+ snprintf(reason, sizeof(reason), "%s%s%s", params[last_param].c_str(), last_param == 2 && params.size() > 3 ? " " : "", last_param == 2 && params.size() > 3 ? params[3].c_str() : "");
+ if (mask && *reason)
+ {
+ XLine *x = SZLine->Add(OperServ, u, mask, expires, reason);
+
+ if (!x)
+ return MOD_CONT;
+
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_ADDED, mask);
+
+ if (Config.WallOSSZLine)
+ {
+ char buf[128];
+
+ if (!expires)
+ strcpy(buf, "does not expire");
+ else
+ {
+ int wall_expiry = expires - time(NULL);
+ const char *s = NULL;
+
+ if (wall_expiry >= 86400)
+ {
+ wall_expiry /= 86400;
+ s = "day";
+ }
+ else if (wall_expiry >= 3600)
+ {
+ wall_expiry /= 3600;
+ s = "hour";
+ }
+ else if (wall_expiry >= 60)
+ {
+ wall_expiry /= 60;
+ s = "minute";
+ }
+
+ snprintf(buf, sizeof(buf), "expires in %d %s%s", wall_expiry, s, wall_expiry == 1 ? "" : "s");
+ }
+
+ ircdproto->SendGlobops(OperServ, "%s added an SZLINE for %s (%s)", u->nick.c_str(), mask, buf);
+ }
+
+ if (readonly)
+ notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
+
+ }
+ else
+ this->OnSyntaxError(u, "ADD");
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoDel(User *u, const std::vector<ci::string> &params)
+ {
+ if (SZLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1].c_str() : "";
+
+ if (mask.empty())
+ {
+ this->OnSyntaxError(u, "DEL");
+ return MOD_CONT;
+ }
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SZLineDelCallback(u, mask.c_str()))->Process();
+ else
+ {
+ XLine *x = SZLine->HasEntry(mask);
+
+ if (!x)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_NOT_FOUND, mask.c_str());
+ return MOD_CONT;
+ }
+
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, x, X_SZLINE));
+
+ SZLineDelCallback::DoDel(u, x);
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_DELETED, mask.c_str());
+ }
+
+ if (readonly)
+ notice_lang(Config.s_OperServ, u, READ_ONLY_MODE);
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoList(User *u, const std::vector<ci::string> &params)
+ {
+ if (SZLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SZLineListCallback(u, mask.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < SZLine->GetCount(); ++i)
+ {
+ XLine *x = SZLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_HEADER);
+ }
+
+ SZLineListCallback::DoList(u, x, i);
+ }
+ }
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoView(User *u, const std::vector<ci::string> &params)
+ {
+ if (SZLine->GetList().empty())
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_LIST_EMPTY);
+ return MOD_CONT;
+ }
+
+ const ci::string mask = params.size() > 1 ? params[1] : "";
+
+ if (!mask.empty() && isdigit(mask[0]) && strspn(mask.c_str(), "1234567890,-") == mask.length())
+ (new SZLineViewCallback(u, mask.c_str()))->Process();
+ else
+ {
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < SZLine->GetCount(); ++i)
+ {
+ XLine *x = SZLine->GetEntry(i);
+
+ if (mask.empty() || (mask == x->Mask || Anope::Match(x->Mask, mask)))
+ {
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_VIEW_HEADER);
+ }
+
+ SZLineViewCallback::DoList(u, x, i);
+ }
+ }
+
+ if (!SentHeader)
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_NO_MATCH);
+ }
+
+ return MOD_CONT;
+ }
+
+ CommandReturn DoClear(User *u)
+ {
+ FOREACH_MOD(I_OnDelXLine, OnDelXLine(u, NULL, X_SZLINE));
+ SZLine->Clear();
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_CLEAR);
+
+ return MOD_CONT;
+ }
+ public:
+ CommandOSSZLine() : Command("SZLINE", 1, 4, "operserv/szline")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ci::string cmd = params[0];
+
+ if (cmd == "ADD")
+ return this->DoAdd(u, params);
+ else if (cmd == "DEL")
+ return this->DoDel(u, params);
+ else if (cmd == "LIST")
+ return this->DoList(u, params);
+ else if (cmd == "VIEW")
+ return this->DoView(u, params);
+ else if (cmd == "CLEAR")
+ return this->DoClear(u);
+ else
+ this->OnSyntaxError(u, "");
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ notice_help(Config.s_OperServ, u, OPER_HELP_SZLINE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_OperServ, u, "SZLINE", OPER_SZLINE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SZLINE);
+ }
+};
+
+class OSSZLine : public Module
+{
+ public:
+ OSSZLine(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion(VERSION_STRING);
+ this->SetType(CORE);
+
+ this->AddCommand(OperServ, new CommandOSSZLine());
+
+ if (!ircd->szline)
+ throw ModuleException("Your IRCd does not support ZLINEs");
+ }
+};
+
+MODULE_INIT(OSSZLine)
diff --git a/src/core/os_umode.c b/src/core/os_umode.cpp
index 4911aded3..bfd0e3777 100644
--- a/src/core/os_umode.c
+++ b/src/core/os_umode.cpp
@@ -41,13 +41,13 @@ class CommandOSUMode : public Command
notice_lang(Config.s_OperServ, u, NICK_X_NOT_IN_USE, nick);
else
{
- u2->SetModes(findbot(Config.s_OperServ), modes);
+ u2->SetModes(OperServ, modes);
notice_lang(Config.s_OperServ, u, OPER_UMODE_SUCCESS, nick);
notice_lang(Config.s_OperServ, u2, OPER_UMODE_CHANGED, u->nick.c_str());
if (Config.WallOSMode)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 used UMODE on %s", u->nick.c_str(), nick);
+ ircdproto->SendGlobops(OperServ, "\2%s\2 used UMODE on %s", u->nick.c_str(), nick);
}
return MOD_CONT;
}
@@ -62,6 +62,11 @@ class CommandOSUMode : public Command
{
syntax_error(Config.s_OperServ, u, "UMODE", OPER_UMODE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_UMODE);
+ }
};
class OSUMode : public Module
@@ -73,16 +78,10 @@ class OSUMode : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSUMode());
+ this->AddCommand(OperServ, new CommandOSUMode());
if (!ircd->umode)
throw ModuleException("Your IRCd does not support setting umodes");
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_UMODE);
}
};
diff --git a/src/core/os_update.c b/src/core/os_update.cpp
index 32ec6d804..0355db90e 100644
--- a/src/core/os_update.c
+++ b/src/core/os_update.cpp
@@ -33,6 +33,11 @@ class CommandOSUpdate : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_UPDATE);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_UPDATE);
+ }
};
class OSUpdate : public Module
@@ -44,13 +49,7 @@ class OSUpdate : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSUpdate());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_UPDATE);
+ this->AddCommand(OperServ, new CommandOSUpdate());
}
};
diff --git a/src/core/os_userlist.c b/src/core/os_userlist.cpp
index 93caa7a60..2a35299fd 100644
--- a/src/core/os_userlist.c
+++ b/src/core/os_userlist.cpp
@@ -55,32 +55,28 @@ class CommandOSUserList : public Command
}
else
{
- char mask[BUFSIZE];
- int i;
- User *u2;
-
notice_lang(Config.s_OperServ, u, OPER_USERLIST_HEADER);
- for (i = 0; i < 1024; ++i)
+ for (user_map::const_iterator uit = UserListByNick.begin(); uit != UserListByNick.end(); ++uit)
{
- for (u2 = userlist[i]; u2; u2 = u2->next)
+ User *u2 = uit->second;
+
+ if (pattern)
{
- if (pattern)
+ char mask[BUFSIZE];
+ snprintf(mask, sizeof(mask), "%s!%s@%s", u2->nick.c_str(), u2->GetIdent().c_str(), u2->GetDisplayedHost().c_str());
+ if (!Anope::Match(mask, pattern, false))
+ continue;
+ if (!Modes.empty())
{
- snprintf(mask, sizeof(mask), "%s!%s@%s", u2->nick.c_str(), u2->GetIdent().c_str(), u2->GetDisplayedHost().c_str());
- if (!Anope::Match(mask, pattern, false))
- continue;
- if (!Modes.empty())
+ for (std::list<UserModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it)
{
- for (std::list<UserModeName>::iterator it = Modes.begin(); it != Modes.end(); ++it)
- {
- if (!u2->HasMode(*it))
- continue;
- }
+ if (!u2->HasMode(*it))
+ continue;
}
}
- notice_lang(Config.s_OperServ, u, OPER_USERLIST_RECORD, u2->nick.c_str(), u2->GetIdent().c_str(), u2->GetDisplayedHost().c_str());
}
+ notice_lang(Config.s_OperServ, u, OPER_USERLIST_RECORD, u2->nick.c_str(), u2->GetIdent().c_str(), u2->GetDisplayedHost().c_str());
}
}
@@ -93,6 +89,11 @@ class CommandOSUserList : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_USERLIST);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_USERLIST);
+ }
};
class OSUserList : public Module
@@ -104,13 +105,7 @@ class OSUserList : public Module
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(OPERSERV, new CommandOSUserList());
-
- ModuleManager::Attach(I_OnOperServHelp, this);
- }
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_USERLIST);
+ this->AddCommand(OperServ, new CommandOSUserList());
}
};
diff --git a/src/core/ss_main.c b/src/core/ss_main.cpp
index 271f6f87e..d0578b16d 100644
--- a/src/core/ss_main.c
+++ b/src/core/ss_main.cpp
@@ -14,7 +14,6 @@
#include "module.h"
BotInfo *statserv = NULL;
-CommandHash *cmdTable[MAX_CMD_HASH];
class CommandSSHelp : public Command
{
@@ -40,8 +39,6 @@ class SSMain : public Module
this->SetType(CORE);
this->SetPermanent(true);
- this->AddCommand(cmdTable, new CommandSSHelp());
-
statserv = findbot("StatServ");
if (!statserv)
{
@@ -49,23 +46,19 @@ class SSMain : public Module
statserv = new BotInfo("StatServ", Config.ServiceUser, Config.ServiceHost, "Stats Service");
}
Alog() << "Done creating SS";
- statserv->cmdTable = cmdTable;
+
+ this->AddCommand(statserv, new CommandSSHelp());
}
~SSMain()
{
- CommandHash *current;
- Command *c;
- for (int i = 0; i < MAX_CMD_HASH; ++i)
+ if (statserv)
{
- for (current = cmdTable[i]; current; current = current->next)
+ for (std::map<ci::string, Command *>::iterator it = statserv->Commands.begin(); it != statserv->Commands.end(); ++it)
{
- for (c = current->c; c; c = c->next)
- this->DelCommand(cmdTable, c->name.c_str());
+ this->DelCommand(statserv, it->second);
}
- }
- if (statserv)
- {
+
ircdproto->SendQuit(statserv, "Quit due to module unload.");
delete statserv;
}
diff --git a/src/encrypt.c b/src/encrypt.cpp
index 4f76ee895..4f76ee895 100644
--- a/src/encrypt.c
+++ b/src/encrypt.cpp
diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp
index 65e546c9c..462064235 100644
--- a/src/hashcomp.cpp
+++ b/src/hashcomp.cpp
@@ -164,3 +164,46 @@ bool sepstream::StreamEnd()
{
return n == tokens.end();
}
+
+/** Return a hash value for a string
+ * @param s The string
+ * @return The hash value
+ */
+size_t hash_compare_std_string::operator()(const std::string &s) const
+{
+ register size_t t = 0;
+
+ for (std::string::const_iterator it = s.begin(); it != s.end(); ++it)
+ t = 5 * t + static_cast<const unsigned char>(*it);
+
+ return t;
+}
+
+/** Return a hash value for a string using case insensitivity
+ * @param s The string
+ * @return The hash value
+ */
+size_t hash_compare_ci_string::operator()(const ci::string &s) const
+{
+ register size_t t = 0;
+
+ for (ci::string::const_iterator it = s.begin(); it != s.end(); ++it)
+ t = 5 * t + ascii_case_insensitive_map[static_cast<const unsigned char>(*it)];
+
+ return t;
+}
+
+/** Return a hash value for a string using RFC1459 case sensitivity rules
+ * @param s The string
+ * @return The hash value
+ */
+size_t hash_compare_irc_string::operator()(const irc::string &s) const
+{
+ register size_t t = 0;
+
+ for (irc::string::const_iterator it = s.begin(); it != s.end(); ++it)
+ t = 5 * t + rfc_case_insensitive_map[static_cast<const unsigned char>(*it)];
+
+ return t;
+}
+
diff --git a/src/hostserv.c b/src/hostserv.cpp
index b34b272a3..8cce7783f 100644
--- a/src/hostserv.c
+++ b/src/hostserv.cpp
@@ -11,11 +11,9 @@
*
*/
-/*************************************************************************/
#include "services.h"
-#include "pseudo.h"
-
-#define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31))
+#include "modules.h"
+#include "language.h"
E int do_hs_sync(NickCore * nc, char *vIdent, char *hostmask,
char *creator, time_t time);
@@ -40,21 +38,20 @@ void get_hostserv_stats(long *nrec, long *memuse)
{
long count = 0, mem = 0;
- for (int i = 0; i < 1024; ++i)
+ for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it)
{
- for (NickAlias *na = nalists[i]; na; na = na->next)
- {
- if (!na->hostinfo.HasVhost())
- continue;
-
- if (!na->hostinfo.GetIdent().empty())
- mem += na->hostinfo.GetIdent().size();
- if (!na->hostinfo.GetHost().empty())
- mem += na->hostinfo.GetHost().size();
- if (!na->hostinfo.GetCreator().empty())
- mem += na->hostinfo.GetCreator().size();
- ++count;
- }
+ NickAlias *na = it->second;
+
+ if (!na->hostinfo.HasVhost())
+ continue;
+
+ if (!na->hostinfo.GetIdent().empty())
+ mem += na->hostinfo.GetIdent().size();
+ if (!na->hostinfo.GetHost().empty())
+ mem += na->hostinfo.GetHost().size();
+ if (!na->hostinfo.GetCreator().empty())
+ mem += na->hostinfo.GetCreator().size();
+ ++count;
}
*nrec = count;
@@ -82,25 +79,25 @@ void hostserv_init()
* @param buf Buffer holding the message
* @return void
*/
-void hostserv(User * u, char *buf)
+void hostserv(User *u, const std::string &buf)
{
- const char *cmd, *s;
-
- cmd = strtok(buf, " ");
-
- if (!cmd) {
+ if (!u || buf.empty())
return;
- } else if (stricmp(cmd, "\1PING") == 0) {
- if (!(s = strtok(NULL, ""))) {
- s = "";
- }
- ircdproto->SendCTCP(findbot(Config.s_HostServ), u->nick.c_str(), "PING %s", s);
- } else {
- if (ircd->vhost) {
- mod_run_cmd(Config.s_HostServ, u, HOSTSERV, cmd);
- } else {
- notice_lang(Config.s_HostServ, u, SERVICE_OFFLINE, Config.s_HostServ);
- }
+
+ if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1')
+ {
+ std::string command = buf;
+ command.erase(command.begin());
+ command.erase(command.end());
+ ircdproto->SendCTCP(HostServ, u->nick.c_str(), "%s", command.c_str());
+ }
+ else if (!ircd->vhost)
+ {
+ notice_lang(Config.s_HostServ, u, SERVICE_OFFLINE, Config.s_HostServ);
+ }
+ else
+ {
+ mod_run_cmd(HostServ, u, buf);
}
}
@@ -180,9 +177,9 @@ void HostServSyncVhosts(NickAlias *na)
if (!na || !na->hostinfo.HasVhost())
return;
- for (int i = 0; i < na->nc->aliases.count; i++)
+ for (std::list<NickAlias *>::iterator it = na->nc->aliases.begin(); it != na->nc->aliases.end(); ++it)
{
- NickAlias *nick = static_cast<NickAlias *>(na->nc->aliases.list[i]);
+ NickAlias *nick = *it;
nick->hostinfo.SetVhost(na->hostinfo.GetIdent(), na->hostinfo.GetHost(), na->hostinfo.GetCreator());
}
}
diff --git a/src/init.c b/src/init.cpp
index 5fc1a8ab2..5bc9f01d1 100644
--- a/src/init.c
+++ b/src/init.cpp
@@ -12,7 +12,8 @@
*/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
+
Uplink *uplink_server;
extern void moduleAddMsgs();
@@ -32,20 +33,18 @@ void introduce_user(const std::string &user)
lasttimes[LTSIZE - 1] = time(NULL);
#undef LTSIZE
/* We make the bots go online */
- BotInfo *bi;
- int i;
/* XXX: it might be nice to have this inside BotInfo's constructor, or something? */
- for (i = 0; i < 256; ++i)
+ for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it)
{
- for (bi = botlists[i]; bi; bi = bi->next)
+ BotInfo *bi = it->second;
+
+ ci::string ci_bi_nick(bi->nick.c_str());
+ if (user.empty() || ci_bi_nick == user)
{
- ci::string ci_bi_nick(bi->nick.c_str());
- if (user.empty() || ci_bi_nick == user)
- {
- ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, ircd->pseudoclient_mode, bi->uid);
- ircdproto->SendSQLine(bi->nick, "Reserved for services");
- }
+ ircdproto->SendClientIntroduction(bi->nick, bi->user, bi->host, bi->real, ircd->pseudoclient_mode, bi->uid);
+ XLine x(bi->nick.c_str(), "Reserved for services");
+ ircdproto->SendSQLine(&x);
}
}
}
@@ -197,13 +196,13 @@ int init_primary(int ac, char **av)
if (GetCommandLineArgument("version", 'v'))
{
- Alog(LOG_TERMINAL) << "Anope-" << version_number << version_flags << " -- " << version_build;
+ Alog(LOG_TERMINAL) << "Anope-" << version_number << " -- " << version_build;
return -1;
}
if (GetCommandLineArgument("help", 'h'))
{
- Alog(LOG_TERMINAL) << "Anope-" << version_number << version_flags << " -- " << version_build;
+ Alog(LOG_TERMINAL) << "Anope-" << version_number << " -- " << version_build;
Alog(LOG_TERMINAL) << "Anope IRC Services (http://www.anope.org)";
Alog(LOG_TERMINAL) << "Usage ./" << SERVICES_BIN << " [options] ...";
Alog(LOG_TERMINAL) << "-c, --config=filename.conf";
@@ -326,9 +325,35 @@ int init_primary(int ac, char **av)
}
/* Add IRCD Protocol Module; exit if there are errors */
- if (protocol_module_init()) {
+ if (protocol_module_init())
return -1;
- }
+
+ /* First thing, add our core bots internally. Before modules are loaded and before the database is read
+ * This is used for modules adding commands and for the BotInfo* poiners in the command classes.
+ * When these bots are loaded from the databases the proper user/host/rname are added.
+ *
+ * If a user renames a bot in the configuration file, the new bot gets created here, and the old bot
+ * that is in the database gets created aswell, on its old nick. The old nick remains in all the channels
+ * etc and the new bot becomes the new client to accept commands. The user can use /bs bot del later
+ * if they want the old bot deleted.
+ *
+ * Note that it is important this is after loading the protocol module. The ircd struct must exist for
+ * the ts6_ functions
+ */
+ if (Config.s_OperServ)
+ new BotInfo(Config.s_OperServ, Config.ServiceUser, Config.ServiceHost, Config.desc_OperServ);
+ if (Config.s_NickServ)
+ new BotInfo(Config.s_NickServ, Config.ServiceUser, Config.ServiceHost, Config.desc_NickServ);
+ if (Config.s_ChanServ)
+ new BotInfo(Config.s_ChanServ, Config.ServiceUser, Config.ServiceHost, Config.desc_ChanServ);
+ if (Config.s_HostServ)
+ new BotInfo(Config.s_HostServ, Config.ServiceUser, Config.ServiceHost, Config.desc_HostServ);
+ if (Config.s_MemoServ)
+ new BotInfo(Config.s_MemoServ, Config.ServiceUser, Config.ServiceHost, Config.desc_MemoServ);
+ if (Config.s_BotServ)
+ new BotInfo(Config.s_BotServ, Config.ServiceUser, Config.ServiceHost, Config.desc_BotServ);
+ if (Config.s_GlobalNoticer)
+ new BotInfo(Config.s_GlobalNoticer, Config.ServiceUser, Config.ServiceHost, Config.desc_GlobalNoticer);
/* Add Encryption Modules */
ModuleManager::LoadModuleList(Config.EncModuleList);
@@ -439,49 +464,6 @@ int init_secondary(int ac, char **av)
FOREACH_RESULT(I_OnLoadDatabase, OnLoadDatabase());
Alog() << "Databases loaded";
- /* this is only used on the first run of Anope. */
- if (!nbots)
- {
- if (Config.s_OperServ)
- new BotInfo(Config.s_OperServ, Config.ServiceUser, Config.ServiceHost, Config.desc_OperServ);
- if (Config.s_NickServ)
- new BotInfo(Config.s_NickServ, Config.ServiceUser, Config.ServiceHost, Config.desc_NickServ);
- if (Config.s_ChanServ)
- new BotInfo(Config.s_ChanServ, Config.ServiceUser, Config.ServiceHost, Config.desc_ChanServ);
- if (Config.s_HostServ)
- new BotInfo(Config.s_HostServ, Config.ServiceUser, Config.ServiceHost, Config.desc_HostServ);
- if (Config.s_MemoServ)
- new BotInfo(Config.s_MemoServ, Config.ServiceUser, Config.ServiceHost, Config.desc_MemoServ);
- if (Config.s_BotServ)
- new BotInfo(Config.s_BotServ, Config.ServiceUser, Config.ServiceHost, Config.desc_BotServ);
- if (Config.s_GlobalNoticer)
- new BotInfo(Config.s_GlobalNoticer, Config.ServiceUser, Config.ServiceHost, Config.desc_GlobalNoticer);
- }
- else
- {
- /* If a botname was changed in the config, reflect it */
- for (int i = 0; i < 256; ++i)
- {
- for (BotInfo *bi = botlists[i]; bi; bi = bi->next)
- {
- if (bi->HasFlag(BI_OPERSERV) && bi->nick != Config.s_OperServ)
- bi->ChangeNick(Config.s_OperServ);
- else if (bi->HasFlag(BI_NICKSERV) && bi->nick != Config.s_NickServ)
- bi->ChangeNick(Config.s_NickServ);
- else if (bi->HasFlag(BI_CHANSERV) && bi->nick != Config.s_ChanServ)
- bi->ChangeNick(Config.s_ChanServ);
- else if (bi->HasFlag(BI_HOSTSERV) && bi->nick != Config.s_HostServ)
- bi->ChangeNick(Config.s_HostServ);
- else if (bi->HasFlag(BI_MEMOSERV) && bi->nick != Config.s_MemoServ)
- bi->ChangeNick(Config.s_MemoServ);
- else if (bi->HasFlag(BI_BOTSERV) && bi->nick != Config.s_BotServ)
- bi->ChangeNick(Config.s_BotServ);
- else if (bi->HasFlag(BI_GLOBAL) && bi->nick != Config.s_GlobalNoticer)
- bi->ChangeNick(Config.s_GlobalNoticer);
- }
- }
- }
-
FOREACH_MOD(I_OnPostLoadDatabases, OnPostLoadDatabases());
return 0;
diff --git a/src/ircd.c b/src/ircd.cpp
index 70d961d81..70d961d81 100644
--- a/src/ircd.c
+++ b/src/ircd.cpp
diff --git a/src/language.c b/src/language.cpp
index 3f5c900e9..3f5c900e9 100644
--- a/src/language.c
+++ b/src/language.cpp
diff --git a/src/log.c b/src/log.cpp
index 0ed07a371..bf5fd10fb 100644
--- a/src/log.c
+++ b/src/log.cpp
@@ -12,7 +12,6 @@
*/
#include "services.h"
-#include "pseudo.h"
static FILE *logfile;
@@ -276,7 +275,7 @@ Alog::~Alog()
else if (Level == LOG_TERMINAL) // XXX dont use this yet unless you know we're at terminal and not daemonized
std::cout << buf.str() << std::endl;
if (Config.LogChannel && LogChan && !debug && findchan(Config.LogChannel)) {
- ircdproto->SendPrivmsg(findbot(Config.s_GlobalNoticer), Config.LogChannel, "%s", buf.str().c_str());
+ ircdproto->SendPrivmsg(Global, Config.LogChannel, "%s", buf.str().c_str());
}
errno = errno_save;
}
diff --git a/src/mail.c b/src/mail.c
deleted file mode 100644
index ef3d6cd4d..000000000
--- a/src/mail.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* Mail utility routines.
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-
-#include "services.h"
-#include "language.h"
-
-/*************************************************************************/
-
-/**
- * Begins to send a mail. Must be followed by a MailEnd call.
- * Returns NULL if the call failed. Error messages are
- * automatically sent to the user.
- * @param u the User struct
- * @param nr NickReqest Struct
- * @param subject Subject of the email
- * @param service Service to respond with
- * @return MailInfo struct
- */
-MailInfo *MailRegBegin(User * u, NickRequest * nr, char *subject,
- char *service)
-{
- int timeToWait = 0;
- if (!u || !nr || !subject || !service) {
- return NULL;
- }
-
- if (!Config.UseMail) {
- notice_lang(service, u, MAIL_DISABLED);
- } else if ((time(NULL) - u->lastmail < Config.MailDelay)) {
- timeToWait = Config.MailDelay - (time(NULL) - u->lastmail);
- notice_lang(service, u, MAIL_DELAYED, timeToWait);
- } else if (!nr->email) {
- notice_lang(service, u, MAIL_INVALID, nr->nick);
- } else {
- MailInfo *mail;
-
- mail = new MailInfo;
- mail->sender = u;
- mail->recipient = NULL;
- mail->recip = nr;
-
- if (!(mail->pipe = popen(Config.SendMailPath, "w"))) {
- delete mail;
- notice_lang(service, u, MAIL_LATER);
- return NULL;
- }
-
- fprintf(mail->pipe, "From: %s\n", Config.SendFrom);
- if (Config.DontQuoteAddresses) {
- fprintf(mail->pipe, "To: %s <%s>\n", nr->nick, nr->email);
- } else {
- fprintf(mail->pipe, "To: \"%s\" <%s>\n", nr->nick, nr->email);
- }
- fprintf(mail->pipe, "Subject: %s\n", subject);
- return mail;
- }
-
- return NULL;
-}
-
-/*************************************************************************/
-
-/**
- * Begins to send a mail. Must be followed by a MailEnd call.
- * Returns NULL if the call failed. Error messages are
- * automatically sent to the user.
- * @param u the User struct
- * @param nc NickCore Struct
- * @param subject Subject of the email
- * @param service Service to respond with
- * @return MailInfo struct
- */
-MailInfo *MailBegin(User * u, NickCore * nc, char *subject, char *service)
-{
- if (!u || !nc || !subject || !service) {
- return NULL;
- }
-
- if (!Config.UseMail) {
- notice_lang(service, u, MAIL_DISABLED);
- } else if (((time(NULL) - u->lastmail < Config.MailDelay)
- || (time(NULL) - nc->lastmail < Config.MailDelay))
- && !(u->Account() && u->Account()->IsServicesOper())) {
- notice_lang(service, u, MAIL_DELAYED, Config.MailDelay);
- } else if (!nc->email) {
- notice_lang(service, u, MAIL_INVALID, nc->display);
- } else {
- MailInfo *mail;
-
- mail = new MailInfo;
- mail->sender = u;
- mail->recipient = nc;
- mail->recip = NULL;
-
- if (!(mail->pipe = popen(Config.SendMailPath, "w"))) {
- delete mail;
- notice_lang(service, u, MAIL_LATER);
- return NULL;
- }
-
- fprintf(mail->pipe, "From: %s\n", Config.SendFrom);
- if (Config.DontQuoteAddresses) {
- fprintf(mail->pipe, "To: %s <%s>\n", nc->display, nc->email);
- } else {
- fprintf(mail->pipe, "To: \"%s\" <%s>\n", nc->display,
- nc->email);
- }
- fprintf(mail->pipe, "Subject: %s\n", subject);
-
- return mail;
- }
-
- return NULL;
-}
-
-/*************************************************************************/
-
-/**
- * new function to send memo mails
- * @param nc NickCore Struct
- * @return MailInfo struct
- */
-MailInfo *MailMemoBegin(NickCore * nc)
-{
-
- if (!nc)
- return NULL;
-
- if (!Config.UseMail || !nc->email) {
- return NULL;
-
- } else {
- MailInfo *mail;
-
- mail = new MailInfo;
- mail->sender = NULL;
- mail->recipient = nc;
- mail->recip = NULL;
-
- if (!(mail->pipe = popen(Config.SendMailPath, "w"))) {
- delete mail;
- return NULL;
- }
-
- fprintf(mail->pipe, "From: %s\n", Config.SendFrom);
- if (Config.DontQuoteAddresses) {
- fprintf(mail->pipe, "To: %s <%s>\n", nc->display, nc->email);
- } else {
- fprintf(mail->pipe, "To: \"%s\" <%s>\n", nc->display,
- nc->email);
- }
- fprintf(mail->pipe, "Subject: %s\n",
- getstring(MEMO_MAIL_SUBJECT));
- return mail;
- }
-}
-
-/*************************************************************************/
-
-/**
- * Finish to send the mail. Cleanup everything.
- * @param mail MailInfo Struct
- * @return void
- */
-void MailEnd(MailInfo * mail)
-{
- /* - param checking modified because we don't
- have an user sending this mail.
- Certus, 02.04.2004 */
-
- if (!mail || !mail->pipe) { /* removed sender check */
- return;
- }
-
- if (!mail->recipient && !mail->recip) {
- return;
- }
-
- pclose(mail->pipe);
-
- if (mail->sender) /* added sender check */
- mail->sender->lastmail = time(NULL);
-
- if (mail->recipient)
- mail->recipient->lastmail = time(NULL);
- else
- mail->recip->lastmail = time(NULL);
-
-
- delete mail;
-}
-
-/*************************************************************************/
-
-/**
- * Resets the MailDelay protection.
- * @param u the User struct
- * @param nc NickCore Struct
- * @return void
- */
-void MailReset(User * u, NickCore * nc)
-{
- if (u)
- u->lastmail = 0;
- if (nc)
- nc->lastmail = 0;
-}
-
-/*************************************************************************/
-
-/**
- * Checks whether we have a valid, common e-mail address.
- * This is NOT entirely RFC compliant, and won't be so, because I said
- * *common* cases. ;) It is very unlikely that e-mail addresses that
- * are really being used will fail the check.
- *
- * FIXME: rewrite this a bit cleaner.
- * @param email Email to Validate
- * @return int
- */
-int MailValidate(const char *email)
-{
- int has_period = 0, len;
- char copy[BUFSIZE], *domain;
-
- static char specials[] =
- { '(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']',
- ' '
- };
-
- if (!email)
- return 0;
- strlcpy(copy, email, sizeof(copy));
-
- domain = strchr(copy, '@');
- if (!domain)
- return 0;
- *domain = '\0';
- domain++;
-
- /* Don't accept NULL copy or domain. */
- if (*copy == 0 || *domain == 0)
- return 0;
-
- /* Check for forbidden characters in the name */
- for (unsigned int i = 0; i < strlen(copy); i++) {
-
- if (copy[i] <= 31 || copy[i] >= 127)
- return 0;
- for (unsigned int j = 0; j < 13; j++)
- if (copy[i] == specials[j])
- return 0;
- }
-
- /* Check for forbidden characters in the domain, and if it seems to be valid. */
- for (int i = 0; i < (len = strlen(domain)); i++) {
- if (domain[i] <= 31 || domain[i] >= 127)
- return 0;
- for (unsigned int j = 0; j < 13; j++)
- if (domain[i] == specials[j])
- return 0;
- if (domain[i] == '.') {
- if (i == 0 || i == len - 1)
- return 0;
- has_period = 1;
- }
- }
-
- if (!has_period)
- return 0;
-
- return 1;
-}
diff --git a/src/mail.cpp b/src/mail.cpp
new file mode 100644
index 000000000..9e1c60c6b
--- /dev/null
+++ b/src/mail.cpp
@@ -0,0 +1,151 @@
+#include "services.h"
+#include "language.h"
+
+MailThread::~MailThread()
+{
+ if (Success)
+ Alog() << "Successfully delivered mail for " << MailTo << " (" << Addr << ")";
+ else
+ Alog() << "Error delivering mail for " << MailTo << " (" << Addr << ")";
+}
+
+void MailThread::Run()
+{
+ FILE *pipe = popen(Config.SendMailPath, "w");
+
+ if (!pipe)
+ {
+ return;
+ }
+
+ fprintf(pipe, "From: %s\n", Config.SendFrom);
+ if (Config.DontQuoteAddresses)
+ fprintf(pipe, "To: %s <%s>\n", MailTo.c_str(), Addr.c_str());
+ else
+ fprintf(pipe, "To: \"%s\" <%s>\n", MailTo.c_str(), Addr.c_str());
+ fprintf(pipe, "Subject: %s\n", Subject.c_str());
+ fprintf(pipe, "%s", Message.c_str());
+ fprintf(pipe, "\n.\n");
+
+ pclose(pipe);
+
+ Success = true;
+}
+
+bool Mail(User *u, NickRequest *nr, const std::string &service, const std::string &subject, const std::string &message)
+{
+ if (!u || !nr || subject.empty() || service.empty() || message.empty())
+ return false;
+
+ time_t t = time(NULL);
+
+ if (!Config.UseMail)
+ notice_lang(service.c_str(), u, MAIL_DISABLED);
+ else if (t - u->lastmail < Config.MailDelay)
+ notice_lang(service.c_str(), u, MAIL_DELAYED, t - u->lastmail);
+ else if (!nr->email)
+ notice_lang(service.c_str(), u, MAIL_INVALID, nr->nick);
+ else
+ {
+ u->lastmail = nr->lastmail = t;
+ threadEngine.Start(new MailThread(nr->nick, nr->email, subject, message));
+ return true;
+ }
+
+ return false;
+}
+
+bool Mail(User *u, NickCore *nc, const std::string &service, const std::string &subject, const std::string &message)
+{
+ if (!u || !nc || subject.empty() || service.empty() || message.empty())
+ return false;
+
+ time_t t = time(NULL);
+
+ if (!Config.UseMail)
+ notice_lang(service.c_str(), u, MAIL_DISABLED);
+ else if (t - u->lastmail < Config.MailDelay)
+ notice_lang(service.c_str(), u, MAIL_DELAYED, t - u->lastmail);
+ else if (!nc->email)
+ notice_lang(service.c_str(), u, MAIL_INVALID, nc->display);
+ else
+ {
+ u->lastmail = nc->lastmail = t;
+ threadEngine.Start(new MailThread(nc->display, nc->email, subject, message));
+ return true;
+ }
+
+ return false;
+}
+
+bool Mail(NickCore *nc, const std::string &subject, const std::string &message)
+{
+ if (!Config.UseMail || !nc || !nc->email || subject.empty() || message.empty())
+ return false;
+
+ nc->lastmail = time(NULL);
+ threadEngine.Start(new MailThread(nc->display, nc->email, subject, message));
+
+ return true;
+}
+
+/**
+ * Checks whether we have a valid, common e-mail address.
+ * This is NOT entirely RFC compliant, and won't be so, because I said
+ * *common* cases. ;) It is very unlikely that e-mail addresses that
+ * are really being used will fail the check.
+ *
+ * @param email Email to Validate
+ * @return bool
+ */
+bool MailValidate(const std::string &email)
+{
+ bool has_period = false;
+ char copy[BUFSIZE];
+
+ static char specials[] = {
+ '(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', ' '
+ };
+
+ if (email.empty())
+ return false;
+ strlcpy(copy, email.c_str(), sizeof(copy));
+
+ char *domain = strchr(copy, '@');
+ if (!domain)
+ return false;
+ *domain++ = '\0';
+
+ /* Don't accept NULL copy or domain. */
+ if (!*copy || !*domain)
+ return false;
+
+ /* Check for forbidden characters in the name */
+ for (unsigned int i = 0; i < strlen(copy); i++)
+ {
+ if (copy[i] <= 31 || copy[i] >= 127)
+ return false;
+ for (unsigned int j = 0; j < 13; j++)
+ if (copy[i] == specials[j])
+ return false;
+ }
+
+ /* Check for forbidden characters in the domain */
+ for (unsigned int i = 0; i < strlen(domain); i++)
+ {
+ if (domain[i] <= 31 || domain[i] >= 127)
+ return false;
+ for (unsigned int j = 0; j < 13; j++)
+ if (domain[i] == specials[j])
+ return false;
+ if (domain[i] == '.')
+ {
+ if (i == 0 || i == strlen(domain) - 1)
+ return false;
+ has_period = true;
+ }
+ }
+
+ return has_period;
+}
+
diff --git a/src/main.c b/src/main.cpp
index d17d98a39..70c7f9e7e 100644
--- a/src/main.c
+++ b/src/main.cpp
@@ -43,7 +43,7 @@
std::string services_dir; /* -dir dirname */
std::string services_bin; /* Binary as specified by the user */
std::string orig_cwd; /* Original current working directory */
-std::string log_filename = LOG_FILENAME; /* -log filename */
+std::string log_filename = "services.log"; /* -log filename */
int debug = 0; /* -debug */
int readonly = 0; /* -readonly */
bool LogChan = false; /* -logchan */
@@ -83,7 +83,6 @@ const char version_number_dotted[] = VERSION_STRING_DOTTED;
const char version_build[] =
"build #" BUILD ", compiled " __DATE__ " " __TIME__;
/* the space is needed cause if you build with nothing it will complain */
-const char version_flags[] = " " VER_OS;
/******** Local variables! ********/
@@ -156,16 +155,6 @@ extern void expire_all()
expire_nicks();
expire_chans();
expire_requests();
- expire_akills();
- if (ircd->sgline) {
- expire_sglines();
- }
- if (ircd->sqline) {
- expire_sqlines();
- }
- if (ircd->szline) {
- expire_szlines();
- }
expire_exceptions();
FOREACH_MOD(I_OnDatabaseExpire, OnDatabaseExpire());
@@ -198,14 +187,20 @@ void do_restart_services()
if (!quitmsg)
quitmsg = "Restarting";
+ /* Send a quit for all of our bots */
+ for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it)
+ {
+ /* Don't use quitmsg here, it may contain information you don't want people to see */
+ ircdproto->SendQuit(it->second, "Restarting");
+ }
ircdproto->SendSquit(Config.ServerName, quitmsg);
/* Process to send the last bits of information before disconnecting */
socketEngine.Process();
delete UplinkSock;
close_log();
/* First don't unload protocol module, then do so */
- modules_unload_all(false);
- modules_unload_all(true);
+ ModuleManager::UnloadAll(false);
+ ModuleManager::UnloadAll(true);
chdir(binary_dir.c_str());
execve(services_bin.c_str(), my_av, my_envp);
if (!readonly) {
@@ -225,8 +220,6 @@ void do_restart_services()
static void services_shutdown()
{
- User *u, *next;
-
FOREACH_MOD(I_OnPreShutdown, OnPreShutdown());
if (!quitmsg)
@@ -234,14 +227,18 @@ static void services_shutdown()
Alog() << quitmsg;
if (started && UplinkSock)
{
+ /* Send a quit for all of our bots */
+ for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it)
+ {
+ /* Don't use quitmsg here, it may contain information you don't want people to see */
+ ircdproto->SendQuit(it->second, "Shutting down");
+ }
+
ircdproto->SendSquit(Config.ServerName, quitmsg);
- if (uplink)
- delete [] uplink;
- u = firstuser();
- while (u) {
- next = nextuser();
- delete u;
- u = next;
+
+ while (!UserListByNick.empty())
+ {
+ delete UserListByNick.begin()->second;
}
}
/* Process to send the last bits of information before disconnecting */
@@ -249,8 +246,8 @@ static void services_shutdown()
delete UplinkSock;
FOREACH_MOD(I_OnShutdown, OnShutdown());
/* First don't unload protocol module, then do so */
- modules_unload_all(false);
- modules_unload_all(true);
+ ModuleManager::UnloadAll(false);
+ ModuleManager::UnloadAll(true);
/* just in case they weren't all removed at least run once */
ModuleRunTimeDirCleanUp();
}
@@ -392,12 +389,20 @@ std::string GetFullProgDir(char *argv0)
static bool Connect()
{
/* Connect to the remote server */
- std::list<Uplink *>::iterator curr_uplink = Config.Uplinks.begin(), end_uplink = Config.Uplinks.end();
int servernum = 1;
- for (; curr_uplink != end_uplink; ++curr_uplink, ++servernum)
+ for (std::list<Uplink *>::iterator curr_uplink = Config.Uplinks.begin(); curr_uplink != Config.Uplinks.end(); ++curr_uplink, ++servernum)
{
uplink_server = *curr_uplink;
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnPreServerConnect, OnPreServerConnect(*curr_uplink, servernum));
+ if (MOD_RESULT != EVENT_CONTINUE)
+ {
+ if (MOD_RESULT == EVENT_STOP)
+ break;
+ return true;
+ }
+
try
{
new UplinkSocket(uplink_server->host, uplink_server->port, Config.LocalHost ? Config.LocalHost : "", uplink_server->ipv6);
@@ -412,6 +417,8 @@ static bool Connect()
return true;
}
+ uplink_server = NULL;
+
return false;
}
@@ -474,8 +481,6 @@ int main(int ac, char **av, char **envp)
if ((i = init_secondary(ac, av)) != 0)
return i;
- FOREACH_MOD(I_OnPreServerConnect, OnPreServerConnect());
-
/* If the first connect fails give up, don't sit endlessly trying to reconnect */
if (!Connect())
fatal_perror("Can't connect to any servers");
diff --git a/src/memory.c b/src/memory.cpp
index 4343bf5e6..4343bf5e6 100644
--- a/src/memory.c
+++ b/src/memory.cpp
diff --git a/src/memoserv.c b/src/memoserv.cpp
index 5236345f9..505b4ed18 100644
--- a/src/memoserv.c
+++ b/src/memoserv.cpp
@@ -12,14 +12,14 @@
*/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
+#include "language.h"
/*************************************************************************/
/* *INDENT-OFF* */
E void moduleAddMemoServCmds();
-static void new_memo_mail(NickCore *nc, Memo *m);
-E void rsend_notify(User *u, Memo *m, const char *chan);
+static bool SendMemoMail(NickCore *nc, Memo *m);
/*************************************************************************/
@@ -51,20 +51,21 @@ void ms_init()
* @param buf Buffer containing the privmsg
* @return void
*/
-void memoserv(User * u, char *buf)
+void memoserv(User *u, const std::string &buf)
{
- const char *cmd, *s;
-
- cmd = strtok(buf, " ");
- if (!cmd) {
+ if (!u || buf.empty())
return;
- } else if (stricmp(cmd, "\1PING") == 0) {
- if (!(s = strtok(NULL, ""))) {
- s = "";
- }
- ircdproto->SendCTCP(findbot(Config.s_MemoServ), u->nick.c_str(), "PING %s", s);
- } else {
- mod_run_cmd(Config.s_MemoServ, u, MEMOSERV, cmd);
+
+ if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1')
+ {
+ std::string command = buf;
+ command.erase(command.begin());
+ command.erase(command.end());
+ ircdproto->SendCTCP(MemoServ, u->nick.c_str(), "%s", command.c_str());
+ }
+ else
+ {
+ mod_run_cmd(MemoServ, u, buf);
}
}
@@ -272,7 +273,6 @@ void memo_send(User * u, const char *name, const char *text, int z)
if (z == 0 || z == 3)
notice_lang(Config.s_MemoServ, u, MEMO_SENT, name);
if (!ischan) {
- NickAlias *na;
NickCore *nc = (findnick(name))->nc;
FOREACH_MOD(I_OnMemoSend, OnMemoSend(u, nc, m));
@@ -280,10 +280,10 @@ void memo_send(User * u, const char *name, const char *text, int z)
if (Config.MSNotifyAll) {
if ((nc->HasFlag(NI_MEMO_RECEIVE))
&& get_ignore(name) == NULL) {
- int i;
- for (i = 0; i < nc->aliases.count; i++) {
- na = static_cast<NickAlias *>(nc->aliases.list[i]);
+ for (std::list<NickAlias *>::iterator it = nc->aliases.begin(); it != nc->aliases.end(); ++it)
+ {
+ NickAlias *na = *it;
User *user = finduser(na->nick);
if (user && user->IsIdentified())
notice_lang(Config.s_MemoServ, user,
@@ -300,7 +300,7 @@ void memo_send(User * u, const char *name, const char *text, int z)
/* if (MSNotifyAll) */
/* let's get out the mail if set in the nickcore - certus */
if (nc->HasFlag(NI_MEMO_MAIL))
- new_memo_mail(nc, m);
+ SendMemoMail(nc, m);
} else {
Channel *c;
@@ -356,32 +356,17 @@ int delmemo(MemoInfo * mi, int num)
/*************************************************************************/
-static void new_memo_mail(NickCore * nc, Memo * m)
+static bool SendMemoMail(NickCore *nc, Memo *m)
{
- MailInfo *mail = NULL;
+ char message[BUFSIZE];
- if (!nc || !m)
- return;
+ snprintf(message, sizeof(message), getstring(NICK_MAIL_TEXT), nc->display, m->sender.c_str(), m->number, m->text);
- mail = MailMemoBegin(nc);
- if (!mail) {
- return;
- }
- fprintf(mail->pipe, getstring(MEMO_MAIL_TEXT1), nc->display);
- fprintf(mail->pipe, "\n");
- fprintf(mail->pipe, getstring(MEMO_MAIL_TEXT2), m->sender.c_str(),
- m->number);
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, "%s", getstring(MEMO_MAIL_TEXT3));
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, "%s", m->text);
- fprintf(mail->pipe, "\n");
- MailEnd(mail);
- return;
+ return Mail(nc, getstring(MEMO_MAIL_SUBJECT), message);
}
-
/*************************************************************************/
+
/* Send receipt notification to sender. */
void rsend_notify(User * u, Memo * m, const char *chan)
diff --git a/src/messages.c b/src/messages.cpp
index 5bac88650..81c64b1fb 100644
--- a/src/messages.c
+++ b/src/messages.cpp
@@ -12,7 +12,7 @@
*/
#include "services.h"
-#include "messages.h"
+#include "modules.h"
#include "language.h"
/*************************************************************************/
@@ -101,44 +101,51 @@ int m_motd(const char *source)
/*************************************************************************/
-int m_privmsg(const char *source, const std::string &receiver, const char *msg)
+int m_privmsg(const std::string &source, const std::string &receiver, const std::string &message)
{
char *target;
time_t starttime, stoptime; /* When processing started and finished */
- BotInfo *bi;
- ChannelInfo *ci;
- User *u;
-
- if (!source || !*source || receiver.empty() || !msg) {
+ if (source.empty() || receiver.empty() || message.empty())
+ {
return MOD_CONT;
}
- u = finduser(source);
+ User *u = finduser(source);
+
+ if (!u)
+ {
+ Alog() << message << ": user record for " << source << " not found";
- if (!u) {
- Alog() << msg << ": user record for " << source << " not found";
- /* Two lookups naughty, however, this won't happen often. -- w00t */
- if (findbot(receiver))
+ BotInfo *bi = findbot(receiver);
+ if (bi)
{
- ircdproto->SendMessage(findbot(receiver), source, "%s", getstring(USER_RECORD_NOT_FOUND));
+ ircdproto->SendMessage(bi, source.c_str(), "%s", getstring(USER_RECORD_NOT_FOUND));
}
+
return MOD_CONT;
}
- if (receiver[0] == '#') {
- if (Config.s_BotServ && (ci = cs_findchan(receiver))) {
+ if (receiver[0] == '#' && Config.s_BotServ)
+ {
+ ChannelInfo *ci = cs_findchan(receiver);
+ if (ci)
+ {
/* Some paranoia checks */
- if (!ci->HasFlag(CI_FORBIDDEN) && ci->c && ci->bi) {
- botchanmsgs(u, ci, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX
+ if (!ci->HasFlag(CI_FORBIDDEN) && ci->c && ci->bi)
+ {
+ botchanmsgs(u, ci, message);
}
}
- } else {
+ }
+ else
+ {
/* Check if we should ignore. Operators always get through. */
- if (allow_ignore && !is_oper(u)) {
- IgnoreData *ign = get_ignore(source);
- if (ign) {
- target = myStrGetToken(msg, ' ', 0);
+ if (allow_ignore && !is_oper(u))
+ {
+ if (get_ignore(source.c_str()))
+ {
+ target = myStrGetToken(message.c_str(), ' ', 0);
Alog() << "Ignored message from " << source << " to " << receiver << " using command " << target;
delete [] target;
return MOD_CONT;
@@ -156,16 +163,18 @@ int m_privmsg(const char *source, const std::string &receiver, const char *msg)
if (servername != Config.ServerName)
return MOD_CONT;
}
- else if (Config.UseStrictPrivMsg) {
+ else if (Config.UseStrictPrivMsg)
+ {
Alog(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << source;
notice_lang(receiver, u, INVALID_TARGET, receiver.c_str(), receiver.c_str(),
Config.ServerName, receiver.c_str());
return MOD_CONT;
}
- starttime = time(NULL);
+ if (allow_ignore)
+ starttime = time(NULL);
- bi = findbot(botname);
+ BotInfo *bi = findbot(botname);
if (bi)
{
@@ -176,40 +185,37 @@ int m_privmsg(const char *source, const std::string &receiver, const char *msg)
{
notice_lang(Config.s_OperServ, u, ACCESS_DENIED);
if (Config.WallBadOS)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "Denied access to %s from %s!%s@%s (non-oper)", Config.s_OperServ, u->nick.c_str(), u->GetIdent().c_str(), u->host);
+ ircdproto->SendGlobops(OperServ, "Denied access to %s from %s!%s@%s (non-oper)", Config.s_OperServ, u->nick.c_str(), u->GetIdent().c_str(), u->host);
}
else
- operserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX
+ operserv(u, message);
}
else if (ci_bi_nick == Config.s_NickServ)
- nickserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX
- else if (ci_bi_nick== Config.s_ChanServ)
+ nickserv(u, message);
+ else if (ci_bi_nick == Config.s_ChanServ)
{
if (!is_oper(u) && Config.CSOpersOnly)
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
else
- chanserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX
+ chanserv(u, message);
}
else if (ci_bi_nick == Config.s_MemoServ)
- memoserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX
+ memoserv(u, message);
else if (Config.s_HostServ && ci_bi_nick == Config.s_HostServ)
- hostserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX
+ hostserv(u, message);
else if (Config.s_BotServ)
- {
- if (ci_bi_nick == Config.s_BotServ)
- botserv(u, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX
- else
- botmsgs(u, bi, const_cast<char *>(msg)); // XXX Unsafe cast, this needs reviewing -- CyberBotX
- }
+ botserv(u, bi, message);
}
/* Add to ignore list if the command took a significant amount of time. */
- if (allow_ignore) {
+ if (allow_ignore)
+ {
stoptime = time(NULL);
- if (stoptime > starttime && *source && !strchr(source, '.'))
- add_ignore(source, stoptime - starttime);
+ if (stoptime > starttime && source.find('.') == std::string::npos)
+ add_ignore(source.c_str(), stoptime - starttime);
}
}
+
return MOD_CONT;
}
@@ -218,7 +224,6 @@ int m_privmsg(const char *source, const std::string &receiver, const char *msg)
int m_stats(const char *source, int ac, const char **av)
{
User *u;
- NickCore *nc;
if (ac < 1)
return MOD_CONT;
@@ -248,7 +253,8 @@ int m_stats(const char *source, int ac, const char **av)
{
std::string nick = it->first, type = it->second;
- if ((nc = findcore(nick.c_str())))
+ NickCore *nc = findcore(nick);
+ if (nc)
ircdproto->SendNumeric(Config.ServerName, 243, source, "O * * %s %s 0", nick.c_str(), type.c_str());
}
@@ -277,8 +283,8 @@ int m_stats(const char *source, int ac, const char **av)
int m_version(const char *source, int ac, const char **av)
{
- if (source) ircdproto->SendNumeric(Config.ServerName, 351, source, "Anope-%s %s :%s - %s (%s) -- %s", version_number, Config.ServerName, ircd->name, version_flags,
- Config.EncModuleList.begin()->c_str(), version_build);
+ if (source)
+ ircdproto->SendNumeric(Config.ServerName, 351, source, "Anope-%s %s :%s -(%s) -- %s", version_number, Config.ServerName, ircd->name, Config.EncModuleList.begin()->c_str(), version_build);
return MOD_CONT;
}
@@ -318,20 +324,10 @@ int m_whois(const char *source, const char *who)
}
/* *INDENT-OFF* */
-void moduleAddMsgs() {
- Message *m;
- m = createMessage("STATS", m_stats); addCoreMessage(IRCD,m);
- m = createMessage("TIME", m_time); addCoreMessage(IRCD,m);
- m = createMessage("VERSION", m_version); addCoreMessage(IRCD,m);
-}
-
-/*************************************************************************/
-
-Message *find_message(const char *name)
+void moduleAddMsgs()
{
- Message *m;
- m = findMessage(IRCD, name);
- return m;
+ Anope::AddMessage("STATS", m_stats);
+ Anope::AddMessage("TIME", m_time);
+ Anope::AddMessage("VERSION", m_version);
}
-/*************************************************************************/
diff --git a/src/misc.c b/src/misc.cpp
index 338737007..51ff5e97c 100644
--- a/src/misc.c
+++ b/src/misc.cpp
@@ -27,6 +27,21 @@ struct arc4_stream {
/*************************************************************************/
+/** Check if a file exists
+ * @param filename The file
+ * @return true if the file exists, false if it doens't
+ */
+bool IsFile(const std::string &filename)
+{
+ struct stat fileinfo;
+ if (!stat(filename.c_str(), &fileinfo))
+ {
+ return true;
+ }
+
+ return false;
+}
+
/**
* toupper: Like the ANSI functions, but make sure we return an
* int instead of a (signed) char.
@@ -208,83 +223,92 @@ const char *merge_args(int argc, char **argv)
}
/*************************************************************************/
-/**
- * Process a string containing a number/range list in the form
- * "n1[-n2][,n3[-n4]]...", calling a caller-specified routine for each
- * number in the list. If the callback returns -1, stop immediately.
- * Returns the sum of all nonnegative return values from the callback.
- * If `count' is non-NULL, it will be set to the total number of times the
- * callback was called.
- *
- * The callback should be of type range_callback_t, which is defined as:
- * int (*range_callback_t)(User *u, int num, va_list args)
- * @param numstr
- * @param count_ret
- * @param callback Call back function
- * @param u User Struct
- * @param ... various args
- * @return int
- */
-int process_numlist(const char *numstr, int *count_ret,
- range_callback_t callback, User * u, ...)
-{
- int n1, n2, i;
- int res = 0, retval = 0, count = 0;
- va_list args, preserve;
- if (!numstr || !*numstr) {
- return -1;
- }
+NumberList::NumberList(const std::string &list, bool descending) : desc(descending)
+{
+ char *error;
+ commasepstream sep(list);
+ std::string token;
- va_start(args, u);
-
- /*
- * This algorithm ignores invalid characters, ignores a dash
- * when it precedes a comma, and ignores everything from the
- * end of a valid number or range to the next comma or null.
- */
- for (;;) {
- n1 = n2 = strtol(numstr, const_cast<char **>(&numstr), 10);
- numstr += strcspn(numstr, "0123456789,-");
- if (*numstr == '-') {
- numstr++;
- numstr += strcspn(numstr, "0123456789,");
- if (isdigit(*numstr)) {
- n2 = strtol(numstr, const_cast<char **>(&numstr), 10);
- numstr += strcspn(numstr, "0123456789,-");
+ sep.GetToken(token);
+ if (token.empty())
+ token = list;
+ do
+ {
+ size_t t = token.find('-');
+
+ if (t == std::string::npos)
+ {
+ unsigned num = strtol(token.c_str(), &error, 10);
+ if (*error == '\0')
+ {
+ numbers.insert(num);
}
- }
- for (i = n1; i <= n2 && i >= 0; i++) {
- VA_COPY(preserve, args);
- res = callback(u, i, preserve);
- va_end(preserve);
- count++;
- if (res < 0)
- break;
- retval += res;
- if (count >= 32767) {
- if (count_ret)
- *count_ret = count;
- return retval;
+ else
+ {
+ if (!this->InvalidRange(list))
+ {
+ delete this;
+ return;
+ }
}
}
- if (res < -1)
- break;
- numstr += strcspn(numstr, ",");
- if (*numstr)
- numstr++;
else
- break;
- }
- if (count_ret)
- *count_ret = count;
+ {
+ char *error2;
+ unsigned num1 = strtol(token.substr(0, t).c_str(), &error, 10);
+ unsigned num2 = strtol(token.substr(t + 1).c_str(), &error2, 10);
+ if (*error == '\0' && *error2 == '\0')
+ {
+ for (unsigned i = num1; i <= num2; ++i)
+ {
+ numbers.insert(i);
+ }
+ }
+ else
+ {
+ if (!this->InvalidRange(list))
+ {
+ delete this;
+ return;
+ }
+ }
+ }
+ } while (sep.GetToken(token));
+}
- va_end(args);
+NumberList::~NumberList()
+{
+}
+
+void NumberList::Process()
+{
+ if (this->desc)
+ {
+ for (std::set<unsigned>::reverse_iterator it = numbers.rbegin(); it != numbers.rend(); ++it)
+ {
+ this->HandleNumber(*it);
+ }
+ }
+ else
+ {
+ for (std::set<unsigned>::iterator it = numbers.begin(); it != numbers.end(); ++it)
+ {
+ this->HandleNumber(*it);
+ }
+ }
+
+ delete this;
+}
- return retval;
+void NumberList::HandleNumber(unsigned)
+{
}
-/*************************************************************************/
+bool NumberList::InvalidRange(const std::string &)
+{
+ return true;
+}
/**
* dotime: Return the number of seconds corresponding to the given time
@@ -804,16 +828,17 @@ int nickIsServices(const char *tempnick, int bot)
found++;
else if (Config.s_GlobalNoticer && (stricmp(nick, Config.s_GlobalNoticer) == 0))
found++;
- else if (Config.s_BotServ && bot) {
- BotInfo *bi;
- int i;
- for (i = 0; i < 256; i++) {
- for (bi = botlists[i]; bi; bi = bi->next) {
- ci::string ci_bi_nick(bi->nick.c_str());
- if (ci_bi_nick == nick) {
- found++;
- continue;
- }
+ else if (Config.s_BotServ && bot)
+ {
+ for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it)
+ {
+ BotInfo *bi = it->second;
+
+ ci::string ci_bi_nick(bi->nick.c_str());
+ if (ci_bi_nick == nick)
+ {
+ found++;
+ break;
}
}
}
diff --git a/src/modes.cpp b/src/modes.cpp
index 1685eea86..935d1e1b3 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -14,6 +14,9 @@
/* List of pairs of user/channels and their stacker info */
std::list<std::pair<void *, StackerInfo *> > ModeManager::StackerObjects;
+/* List of all modes Anope knows about */
+std::list<Mode *> ModeManager::Modes;
+
/* User modes */
std::map<char, UserMode *> ModeManager::UserModesByChar;
std::map<UserModeName, UserMode *> ModeManager::UserModesByName;
@@ -21,18 +24,15 @@ std::map<UserModeName, UserMode *> ModeManager::UserModesByName;
std::map<char, ChannelMode *> ModeManager::ChannelModesByChar;
std::map<ChannelModeName, ChannelMode *> ModeManager::ChannelModesByName;
/* Although there are two different maps for UserModes and ChannelModes
- * the pointers in each are the same. This is used to increase
- * efficiency.
+ * the pointers in each are the same. This is used to increase efficiency.
*/
-/* List of all modes Anope knows about */
-std::list<Mode *> ModeManager::Modes;
/* Number of generic modes we support */
unsigned GenericChannelModes = 0, GenericUserModes = 0;
/* Default mlocked modes on */
-std::bitset<128> DefMLockOn;
+Flags<ChannelModeName> DefMLockOn;
/* Default mlocked modes off */
-std::bitset<128> DefMLockOff;
+Flags<ChannelModeName> DefMLockOff;
/* Map for default mlocked mode parameters */
std::map<ChannelModeName, std::string> DefMLockParams;
/* Modes to set on bots when they join the channel */
@@ -42,10 +42,10 @@ std::list<ChannelModeStatus *> BotModes;
*/
void SetDefaultMLock()
{
- DefMLockOn.reset();
- DefMLockOff.reset();
+ DefMLockOn.ClearFlags();
+ DefMLockOff.ClearFlags();
DefMLockParams.clear();
- std::bitset<128> *ptr = NULL;
+ Flags<ChannelModeName> *ptr = NULL;
std::string modes, param;
spacesepstream sep(Config.MLock);
@@ -66,9 +66,9 @@ void SetDefaultMLock()
if (cm && (cm->Type == MODE_REGULAR || cm->Type == MODE_PARAM))
{
- ptr->set(cm->Name);
+ ptr->SetFlag(cm->Name);
- if (*ptr == DefMLockOn && cm->Type == MODE_PARAM)
+ if (ptr == &DefMLockOn && cm->Type == MODE_PARAM)
{
if (sep.GetToken(param))
{
@@ -77,7 +77,7 @@ void SetDefaultMLock()
else
{
Alog() << "Warning: Got default mlock mode " << cm->ModeChar << " with no param?";
- ptr->set(cm->Name, false);
+ ptr->UnsetFlag(cm->Name);
}
}
}
@@ -99,10 +99,11 @@ void SetDefaultMLock()
/** Default constructor
* @param mClass The type of mode this is
+ * @param mNameAsString The mode name as a string
* @param modeChar The mode char
* @param modeType The mode type
*/
-Mode::Mode(ModeClass mClass, char modeChar, ModeType modeType) : Class(mClass), ModeChar(modeChar), Type(modeType)
+Mode::Mode(ModeClass mClass, const std::string &mNameAsString, char modeChar, ModeType modeType) : Class(mClass), NameAsString(mNameAsString), ModeChar(modeChar), Type(modeType)
{
}
@@ -114,9 +115,10 @@ Mode::~Mode()
/** Default constructor
* @param mName The mode name
+ * @param mNameAsString The mode name as a string
* @param modeChar The mode char
*/
-UserMode::UserMode(UserModeName mName, char modeChar) : Mode(MC_USER, modeChar, MODE_REGULAR), Name(mName)
+UserMode::UserMode(UserModeName mName, const std::string &mNameAsString, char modeChar) : Mode(MC_USER, mNameAsString, modeChar, MODE_REGULAR), Name(mName)
{
}
@@ -128,18 +130,20 @@ UserMode::~UserMode()
/** Default constructor
* @param mName The mode name
+ * @param mNameAsString The mode name as a string
* @param modeChar The mode char
*/
-UserModeParam::UserModeParam(UserModeName mName, char modeChar) : UserMode(mName, modeChar)
+UserModeParam::UserModeParam(UserModeName mName, const std::string &mNameAsString, char modeChar) : UserMode(mName, mNameAsString, modeChar)
{
this->Type = MODE_PARAM;
}
/** Default constrcutor
* @param mName The mode name
+ * @param mNameAsString The mode name as a string
* @param modeChar The mode char
*/
-ChannelMode::ChannelMode(ChannelModeName mName, char modeChar) : Mode(MC_CHANNEL, modeChar, MODE_REGULAR), Name(mName)
+ChannelMode::ChannelMode(ChannelModeName mName, const std::string &mNameAsString, char modeChar) : Mode(MC_CHANNEL, mNameAsString, modeChar, MODE_REGULAR), Name(mName)
{
}
@@ -151,9 +155,10 @@ ChannelMode::~ChannelMode()
/** Default constructor
* @param mName The mode name
+ * @param mNameAsString The mode name as a string
* @param modeChar The mode char
*/
-ChannelModeList::ChannelModeList(ChannelModeName mName, char modeChar) : ChannelMode(mName, modeChar)
+ChannelModeList::ChannelModeList(ChannelModeName mName, const std::string &mNameAsString, char modeChar) : ChannelMode(mName, mNameAsString, modeChar)
{
this->Type = MODE_LIST;
}
@@ -166,10 +171,11 @@ ChannelModeList::~ChannelModeList()
/** Default constructor
* @param mName The mode name
+ * @param mNameAsString The mode name as a string
* @param modeChar The mode char
* @param MinusArg true if the mode sends no arg when unsetting
*/
-ChannelModeParam::ChannelModeParam(ChannelModeName mName, char modeChar, bool MinusArg) : ChannelMode(mName, modeChar), MinusNoArg(MinusArg)
+ChannelModeParam::ChannelModeParam(ChannelModeName mName, const std::string &mNameAsString, char modeChar, bool MinusArg) : ChannelMode(mName, mNameAsString, modeChar), MinusNoArg(MinusArg)
{
this->Type = MODE_PARAM;
}
@@ -182,10 +188,11 @@ ChannelModeParam::~ChannelModeParam()
/** Default constructor
* @param mName The mode name
+ * @param mNameAsString The mode name as a string
* @param modeChar The mode char
* @param mSymbol The symbol for the mode, eg @ % +
*/
-ChannelModeStatus::ChannelModeStatus(ChannelModeName mName, char modeChar, char mSymbol) : ChannelMode(mName, modeChar), Symbol(mSymbol)
+ChannelModeStatus::ChannelModeStatus(ChannelModeName mName, const std::string &mNameAsString, char modeChar, char mSymbol) : ChannelMode(mName, mNameAsString, modeChar), Symbol(mSymbol)
{
this->Type = MODE_STATUS;
}
diff --git a/src/module.cpp b/src/module.cpp
index 4582ac069..b30e2b6a7 100644
--- a/src/module.cpp
+++ b/src/module.cpp
@@ -24,31 +24,12 @@ Module::Module(const std::string &mname, const std::string &creator)
this->lang[i].argc = 0;
}
- int index = 0;
- ModuleHash *current = NULL;
- ModuleHash *newHash = NULL;
- ModuleHash *lastHash = NULL;
-
- index = CMD_HASH(this->name);
-
- for (current = MODULE_HASH[index]; current; current = current->next) {
- if (this->name ==current->name)
- throw CoreException("Module already exists!");
- lastHash = current;
- }
-
- if (!(newHash = new ModuleHash)) {
- fatal("Out of memory");
- }
+ if (FindModule(this->name))
+ throw CoreException("Module already exists!");
+
this->created = time(NULL);
- newHash->next = NULL;
- newHash->name = sstrdup(this->name.c_str());
- newHash->m = this;
-
- if (lastHash == NULL)
- MODULE_HASH[index] = newHash;
- else
- lastHash->next = newHash;
+
+ Modules.push_back(this);
}
Module::~Module()
@@ -60,85 +41,91 @@ Module::~Module()
remove(this->filename.c_str());
- int idx;
- CommandHash *current = NULL;
-
- Command *c;
-
/* Clear any active callbacks this module has */
ModuleManager::ClearCallBacks(this);
/**
* ok, im going to walk every hash looking for commands we own, now, not exactly elegant or efficiant :)
**/
- for (idx = 0; idx < MAX_CMD_HASH; idx++) {
- for (current = HS_cmdTable[idx]; current; current = current->next) {
- for (c = current->c; c; c = c->next) {
- if ((c->mod_name) && (strcmp(c->mod_name, this->name.c_str()) == 0)) {
- this->DelCommand(HOSTSERV, c->name.c_str());
- }
- }
+ if (HostServ)
+ {
+ for (std::map<ci::string, Command *>::iterator it = HostServ->Commands.begin(); it != HostServ->Commands.end();)
+ {
+ Command *c = it->second;
+ ++it;
+
+ if (c->module == this)
+ this->DelCommand(HostServ, c);
}
+ }
+
+ if (BotServ)
+ {
+ for (std::map<ci::string, Command *>::iterator it = BotServ->Commands.begin(); it != BotServ->Commands.end();)
+ {
+ Command *c = it->second;
+ ++it;
- for (current = BS_cmdTable[idx]; current; current = current->next) {
- for (c = current->c; c; c = c->next) {
- if ((c->mod_name) && (strcmp(c->mod_name, this->name.c_str()) == 0)) {
- this->DelCommand(BOTSERV, c->name.c_str());
- }
- }
+ if (c->module == this)
+ this->DelCommand(BotServ, c);
}
+ }
+
+ if (MemoServ)
+ {
+ for (std::map<ci::string, Command *>::iterator it = MemoServ->Commands.begin(); it != MemoServ->Commands.end();)
+ {
+ Command *c = it->second;
+ ++it;
- for (current = MS_cmdTable[idx]; current; current = current->next) {
- for (c = current->c; c; c = c->next) {
- if ((c->mod_name) && (strcmp(c->mod_name, this->name.c_str()) == 0)) {
- this->DelCommand(MEMOSERV, c->name.c_str());
- }
- }
+ if (c->module == this)
+ this->DelCommand(MemoServ, c);
}
+ }
+
+ if (NickServ)
+ {
+ for (std::map<ci::string, Command *>::iterator it = NickServ->Commands.begin(); it != NickServ->Commands.end();)
+ {
+ Command *c = it->second;
+ ++it;
- for (current = NS_cmdTable[idx]; current; current = current->next) {
- for (c = current->c; c; c = c->next) {
- if ((c->mod_name) && (strcmp(c->mod_name, this->name.c_str()) == 0)) {
- this->DelCommand(NICKSERV, c->name.c_str());
- }
- }
+ if (c->module == this)
+ this->DelCommand(NickServ, c);
}
+ }
+
+ if (ChanServ)
+ {
+ for (std::map<ci::string, Command *>::iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.end();)
+ {
+ Command *c = it->second;
+ ++it;
- for (current = CS_cmdTable[idx]; current; current = current->next) {
- for (c = current->c; c; c = c->next) {
- if ((c->mod_name) && (strcmp(c->mod_name, this->name.c_str()) == 0)) {
- this->DelCommand(CHANSERV, c->name.c_str());
- }
- }
+ if (c->module == this)
+ this->DelCommand(ChanServ, c);
}
+ }
- for (current = OS_cmdTable[idx]; current; current = current->next) {
- for (c = current->c; c; c = c->next) {
- if ((c->mod_name) && (stricmp(c->mod_name, this->name.c_str()) == 0)) {
- this->DelCommand(OPERSERV, c->name.c_str());
- }
- }
+ if (OperServ)
+ {
+ for (std::map<ci::string, Command *>::iterator it = OperServ->Commands.begin(); it != OperServ->Commands.end();)
+ {
+ Command *c = it->second;
+ ++it;
+
+ if (c->module == this)
+ this->DelCommand(OperServ, c);
}
}
- int index = 0;
- ModuleHash *lastHash = NULL;
- ModuleHash *mhash = NULL;
-
- index = CMD_HASH(this->name);
-
- for (mhash = MODULE_HASH[index]; mhash; mhash = mhash->next) {
- if (this->name == mhash->name) {
- if (!lastHash) {
- MODULE_HASH[index] = mhash->next;
- } else {
- lastHash->next = mhash->next;
- }
- delete [] mhash->name;
- delete mhash;
+ for (std::deque<Module *>::iterator it = Modules.begin(); it != Modules.end(); ++it)
+ {
+ if (*it == this)
+ {
+ Modules.erase(it);
break;
}
- lastHash = mhash;
}
}
diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp
index a9f1eb2f0..b11ad2829 100644
--- a/src/modulemanager.cpp
+++ b/src/modulemanager.cpp
@@ -18,7 +18,7 @@ void ModuleManager::LoadModuleList(std::list<std::string> &ModuleList)
{
for (std::list<std::string>::iterator it = ModuleList.begin(); it != ModuleList.end(); ++it)
{
- Module *m = findModule(it->c_str());
+ Module *m = FindModule(*it);
if (!m)
ModuleManager::LoadModule(*it, NULL);
}
@@ -79,16 +79,13 @@ static int moduleCopyFile(const char *name, const char *output)
static bool IsOneOfModuleTypeLoaded(MODType mt)
{
- int idx = 0;
- ModuleHash *current = NULL;
int pmods = 0;
- for (idx = 0; idx != MAX_CMD_HASH; idx++)
+ for (std::deque<Module *>::iterator it = Modules.begin(); it != Modules.end(); ++it)
{
- for (current = MODULE_HASH[idx]; current; current = current->next)
+ if ((*it)->type == mt)
{
- if (current->m->type == mt)
- pmods++;
+ ++pmods;
}
}
@@ -127,7 +124,7 @@ int ModuleManager::LoadModule(const std::string &modname, User * u)
if (modname.empty())
return MOD_ERR_PARAMS;
- if (findModule(modname.c_str()) != NULL)
+ if (FindModule(modname) != NULL)
return MOD_ERR_EXISTS;
Alog(LOG_DEBUG) << "trying to load [" << modname << "]";
@@ -164,10 +161,10 @@ int ModuleManager::LoadModule(const std::string &modname, User * u)
}
ano_modclearerr();
- func = function_cast<Module *(*)(const std::string &, const std::string &)>(dlsym(handle, "init_module"));
+ func = function_cast<Module *(*)(const std::string &, const std::string &)>(dlsym(handle, "AnopeInit"));
if (func == NULL && (err = dlerror()) != NULL)
{
- Alog() << "No magical init function found, not an Anope module";
+ Alog() << "No init function found, not an Anope module";
dlclose(handle);
return MOD_ERR_NOLOAD;
}
@@ -235,7 +232,7 @@ int ModuleManager::LoadModule(const std::string &modname, User * u)
if (u)
{
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s loaded module %s", u->nick.c_str(), modname.c_str());
+ ircdproto->SendGlobops(OperServ, "%s loaded module %s", u->nick.c_str(), modname.c_str());
notice_lang(Config.s_OperServ, u, OPER_MODULE_LOADED, modname.c_str());
/* If a user is loading this module, then the core databases have already been loaded
@@ -267,7 +264,7 @@ int ModuleManager::UnloadModule(Module *m, User *u)
if (u)
{
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "%s unloaded module %s", u->nick.c_str(), m->name.c_str());
+ ircdproto->SendGlobops(OperServ, "%s unloaded module %s", u->nick.c_str(), m->name.c_str());
notice_lang(Config.s_OperServ, u, OPER_MODULE_UNLOADED, m->name.c_str());
}
@@ -292,10 +289,10 @@ void ModuleManager::DeleteModule(Module *m)
handle = m->handle;
ano_modclearerr();
- destroy_func = function_cast<void (*)(Module *)>(dlsym(m->handle, "destroy_module"));
+ destroy_func = function_cast<void (*)(Module *)>(dlsym(m->handle, "AnopeFini"));
if (destroy_func == NULL && (err = dlerror()) != NULL)
{
- Alog() << "No magical destroy function found, chancing delete...";
+ Alog() << "No destroy function found, chancing delete...";
delete m; /* we just have to chance they haven't overwrote the delete operator then... */
}
else
@@ -468,3 +465,21 @@ void ModuleManager::ClearCallBacks(Module *m)
delete m->CallBacks.front();
}
+/** Unloading all modules, NEVER call this when Anope isn't shutting down.
+ * Ever.
+ * @param unload_proto true to unload the protocol module
+ */
+void ModuleManager::UnloadAll(bool unload_proto)
+{
+ for (std::deque<Module *>::iterator it = Modules.begin(); it != Modules.end();)
+ {
+ Module *m = *it++;
+
+ if (unload_proto || m->type != PROTOCOL)
+ DeleteModule(m);
+
+ if (Modules.empty())
+ break;
+ }
+}
+
diff --git a/src/modules.c b/src/modules.c
deleted file mode 100644
index 40c10144f..000000000
--- a/src/modules.c
+++ /dev/null
@@ -1,784 +0,0 @@
-/* Modular support
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-#include "modules.h"
-#include "language.h"
-#include "version.h"
-
-/**
- * Declare all the list's we want to use here
- **/
-CommandHash *HOSTSERV[MAX_CMD_HASH];
-CommandHash *BOTSERV[MAX_CMD_HASH];
-CommandHash *MEMOSERV[MAX_CMD_HASH];
-CommandHash *NICKSERV[MAX_CMD_HASH];
-CommandHash *CHANSERV[MAX_CMD_HASH];
-CommandHash *OPERSERV[MAX_CMD_HASH];
-MessageHash *IRCD[MAX_CMD_HASH];
-ModuleHash *MODULE_HASH[MAX_CMD_HASH];
-
-char *mod_current_buffer = NULL;
-
-char *ModuleGetErrStr(int status)
-{
- const char *module_err_str[] = {
- "Module, Okay - No Error", /* MOD_ERR_OK */
- "Module Error, Allocating memory", /* MOD_ERR_MEMORY */
- "Module Error, Not enough parameters", /* MOD_ERR_PARAMS */
- "Module Error, Already loaded", /* MOD_ERR_EXISTS */
- "Module Error, File does not exist", /* MOD_ERR_NOEXIST */
- "Module Error, No User", /* MOD_ERR_NOUSER */
- "Module Error, Error during load time or module returned MOD_STOP", /* MOD_ERR_NOLOAD */
- "Module Error, Unable to unload", /* MOD_ERR_NOUNLOAD */
- "Module Error, Incorrect syntax", /* MOD_ERR_SYNTAX */
- "Module Error, Unable to delete", /* MOD_ERR_NODELETE */
- "Module Error, Unknown Error occuried", /* MOD_ERR_UNKOWN */
- "Module Error, File I/O Error", /* MOD_ERR_FILE_IO */
- "Module Error, No Service found for request", /* MOD_ERR_NOSERVICE */
- "Module Error, No module name for request" /* MOD_ERR_NO_MOD_NAME */
- };
- return const_cast<char *>(module_err_str[status]);
-}
-
-
-/************************************************/
-
-/**
- * Load the ircd protocol module up
- **/
-int protocol_module_init()
-{
- int ret = 0;
-
- Alog() << "Loading IRCD Protocol Module: [" << Config.IRCDModule << "]";
- ret = ModuleManager::LoadModule(Config.IRCDModule, NULL);
-
- if (ret == MOD_ERR_OK)
- {
- findModule(Config.IRCDModule)->SetType(PROTOCOL);
- /* This is really NOT the correct place to do config checks, but
- * as we only have the ircd struct filled here, we have to over
- * here. -GD
- */
- if (ircd->ts6)
- {
- if (!Config.Numeric)
- {
- Alog() << "This IRCd protocol requires a server id to be set in Anope's configuration.";
- ret = -1;
- }
- else
- {
- ts6_uid_init();
- }
- }
- }
-
- return ret;
-}
-
-/**
- * Unload ALL loaded modules, no matter what kind of module it is.
- * Do NEVER EVER, and i mean NEVER (and if that isn't clear enough
- * yet, i mean: NEVER AT ALL) call this unless we're shutting down,
- * or we'll fuck up Anope badly (protocol handling won't work for
- * example). If anyone calls this function without a justified need
- * for it, i reserve the right to break their legs in a painful way.
- * And if that isn't enough discouragement, you'll wake up with your
- * both legs broken tomorrow ;) -GD
- */
-void modules_unload_all(bool unload_proto)
-{
- int idx;
- ModuleHash *mh, *next;
-
- for (idx = 0; idx < MAX_CMD_HASH; idx++) {
- mh = MODULE_HASH[idx];
- while (mh) {
- next = mh->next;
- if (unload_proto || (mh->m->type != PROTOCOL))
- ModuleManager::UnloadModule(mh->m, NULL);
- mh = next;
- }
- }
-}
-
-void Module::InsertLanguage(int langNumber, int ac, const char **av)
-{
- int i;
-
- Alog(LOG_DEBUG) << this->name << "Adding " << ac << " texts for language " << langNumber;
-
- if (this->lang[langNumber].argc > 0) {
- this->DeleteLanguage(langNumber);
- }
-
- this->lang[langNumber].argc = ac;
- this->lang[langNumber].argv = new char *[ac];
- for (i = 0; i < ac; i++) {
- this->lang[langNumber].argv[i] = sstrdup(av[i]);
- }
-}
-
-/**
- * Search the list of loaded modules for the given name.
- * @param name the name of the module to find
- * @return a pointer to the module found, or NULL
- */
-Module *findModule(const char *name)
-{
- int idx;
- ModuleHash *current = NULL;
- if (!name) {
- return NULL;
- }
- idx = CMD_HASH(name);
-
- for (current = MODULE_HASH[idx]; current; current = current->next) {
- if (stricmp(name, current->name) == 0) {
- return current->m;
- }
- }
- return NULL;
-
-}
-
-/*******************************************************************************
- * Command Functions
- *******************************************************************************/
-
-/** Add a command to a command table. Only for internal use.
- * only add if were unique, pos = 0;
- * if we want it at the "head" of that command, pos = 1
- * at the tail, pos = 2
- * @param cmdTable the table to add the command to
- * @param c the command to add
- * @return MOD_ERR_OK will be returned on success.
- */
-static int internal_addCommand(Module *m, CommandHash * cmdTable[], Command * c)
-{
- /* We can assume both param's have been checked by this point.. */
- int index = 0;
- CommandHash *current = NULL;
- CommandHash *newHash = NULL;
- CommandHash *lastHash = NULL;
-
- if (!cmdTable || !c) {
- return MOD_ERR_PARAMS;
- }
-
- index = CMD_HASH(c->name.c_str());
-
- for (current = cmdTable[index]; current; current = current->next) {
- if ((c->service) && (current->c) && (current->c->service)
- && (!strcmp(c->service, current->c->service) == 0)) {
- continue;
- }
- if ((stricmp(c->name.c_str(), current->name) == 0))
- {
- /* the cmd exists, throw an error */
- return MOD_ERR_EXISTS;
- }
- lastHash = current;
- }
-
- newHash = new CommandHash;
- newHash->next = NULL;
- newHash->name = sstrdup(c->name.c_str());
- newHash->c = c;
-
- if (lastHash == NULL)
- cmdTable[index] = newHash;
- else
- lastHash->next = newHash;
-
- return MOD_ERR_OK;
-}
-
-int Module::AddCommand(CommandHash * cmdTable[], Command * c)
-{
- int status;
-
- if (!cmdTable || !c) {
- return MOD_ERR_PARAMS;
- }
- c->core = 0;
- if (!c->mod_name) {
- c->mod_name = sstrdup(this->name.c_str());
- }
-
-
- if (cmdTable == HOSTSERV) {
- if (Config.s_HostServ) {
- c->service = sstrdup(Config.s_HostServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else if (cmdTable == BOTSERV) {
- if (Config.s_BotServ) {
- c->service = sstrdup(Config.s_BotServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else if (cmdTable == MEMOSERV) {
- if (Config.s_MemoServ) {
- c->service = sstrdup(Config.s_MemoServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else if (cmdTable == CHANSERV) {
- if (Config.s_ChanServ) {
- c->service = sstrdup(Config.s_ChanServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else if (cmdTable == NICKSERV) {
- if (Config.s_NickServ) {
- c->service = sstrdup(Config.s_NickServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else if (cmdTable == OPERSERV) {
- if (Config.s_OperServ) {
- c->service = sstrdup(Config.s_OperServ);
- } else {
- return MOD_ERR_NOSERVICE;
- }
- } else
- c->service = sstrdup("Unknown");
-
- status = internal_addCommand(this, cmdTable, c);
- if (status != MOD_ERR_OK)
- {
- Alog() << "ERROR! [ "<< status << "]";
- }
- return status;
-}
-
-
-/** Remove a command from the command hash. Only for internal use.
- * @param cmdTable the command table to remove the command from
- * @param c the command to remove
- * @param mod_name the name of the module who owns the command
- * @return MOD_ERR_OK will be returned on success
- */
-static int internal_delCommand(CommandHash * cmdTable[], Command * c, const char *mod_name)
-{
- int index = 0;
- CommandHash *current = NULL;
- CommandHash *lastHash = NULL;
- Command *tail = NULL, *last = NULL;
-
- if (!c || !cmdTable) {
- return MOD_ERR_PARAMS;
- }
-
- index = CMD_HASH(c->name.c_str());
- for (current = cmdTable[index]; current; current = current->next) {
- if (stricmp(c->name.c_str(), current->name) == 0) {
- if (!lastHash) {
- tail = current->c;
- if (tail->next) {
- while (tail) {
- if (mod_name && tail->mod_name
- && (stricmp(mod_name, tail->mod_name) == 0)) {
- if (last) {
- last->next = tail->next;
- } else {
- current->c = tail->next;
- }
- return MOD_ERR_OK;
- }
- last = tail;
- tail = tail->next;
- }
- } else {
- cmdTable[index] = current->next;
- delete [] current->name;
- return MOD_ERR_OK;
- }
- } else {
- tail = current->c;
- if (tail->next) {
- while (tail) {
- if (mod_name && tail->mod_name
- && (stricmp(mod_name, tail->mod_name) == 0)) {
- if (last) {
- last->next = tail->next;
- } else {
- current->c = tail->next;
- }
- return MOD_ERR_OK;
- }
- last = tail;
- tail = tail->next;
- }
- } else {
- lastHash->next = current->next;
- delete [] current->name;
- return MOD_ERR_OK;
- }
- }
- }
- lastHash = current;
- }
- return MOD_ERR_NOEXIST;
-}
-
-/**
- * Delete a command from the service given.
- * @param cmdTable the cmdTable for the services to remove the command from
- * @param name the name of the command to delete from the service
- * @return returns MOD_ERR_OK on success
- */
-int Module::DelCommand(CommandHash * cmdTable[], const char *dname)
-{
- Command *c = NULL;
- Command *cmd = NULL;
- int status = 0;
-
- c = findCommand(cmdTable, dname);
- if (!c) {
- return MOD_ERR_NOEXIST;
- }
-
-
- for (cmd = c; cmd; cmd = cmd->next)
- {
- if (cmd->mod_name && cmd->mod_name == this->name)
- {
- status = internal_delCommand(cmdTable, cmd, this->name.c_str());
- }
- }
- return status;
-}
-
-/**
- * Search the command table gieven for a command.
- * @param cmdTable the name of the command table to search
- * @param name the name of the command to look for
- * @return returns a pointer to the found command struct, or NULL
- */
-Command *findCommand(CommandHash * cmdTable[], const char *name)
-{
- int idx;
- CommandHash *current = NULL;
- if (!cmdTable || !name) {
- return NULL;
- }
-
- idx = CMD_HASH(name);
-
- for (current = cmdTable[idx]; current; current = current->next) {
- if (stricmp(name, current->name) == 0) {
- return current->c;
- }
- }
- return NULL;
-}
-
-/*******************************************************************************
- * Message Functions
- *******************************************************************************/
-
- /**
- * Create a new Message struct.
- * @param name the name of the message
- * @param func a pointer to the function to call when we recive this message
- * @return a new Message object
- **/
-Message *createMessage(const char *name,
- int (*func) (const char *source, int ac, const char **av))
-{
- Message *m = NULL;
- if (!name || !func) {
- return NULL;
- }
- if (!(m = new Message)) {
- fatal("Out of memory!");
- }
- m->name = sstrdup(name);
- m->func = func;
- m->core = 0;
- m->next = NULL;
- return m;
-}
-
-/**
- * find a message in the given table.
- * Looks up the message <name> in the MessageHash given
- * @param MessageHash the message table to search for this command, will almost always be IRCD
- * @param name the name of the command were looking for
- * @return NULL if we cant find it, or a pointer to the Message if we can
- **/
-Message *findMessage(MessageHash * msgTable[], const char *name)
-{
- int idx;
- MessageHash *current = NULL;
- if (!msgTable || !name) {
- return NULL;
- }
- idx = CMD_HASH(name);
-
- for (current = msgTable[idx]; current; current = current->next) {
- if (stricmp(name, current->name) == 0) {
- return current->m;
- }
- }
- return NULL;
-}
-
-/**
- * Add a message to the MessageHash.
- * @param msgTable the MessageHash we want to add a message to
- * @param m the Message we want to add
- * @param pos the position we want to add the message to, E.G. MOD_HEAD, MOD_TAIL, MOD_UNIQUE
- * @return MOD_ERR_OK on a successful add.
- **/
-
-int addMessage(MessageHash * msgTable[], Message * m, int pos)
-{
- /* We can assume both param's have been checked by this point.. */
- int index = 0;
- MessageHash *current = NULL;
- MessageHash *newHash = NULL;
- MessageHash *lastHash = NULL;
- Message *tail = NULL;
- int match = 0;
-
- if (!msgTable || !m || (pos < 0 || pos > 2)) {
- return MOD_ERR_PARAMS;
- }
-
- index = CMD_HASH(m->name);
-
- for (current = msgTable[index]; current; current = current->next) {
- match = stricmp(m->name, current->name);
- if (match == 0) { /* the msg exist's we are a addHead */
- if (pos == 1) {
- m->next = current->m;
- current->m = m;
- Alog(LOG_DEBUG) << "existing msg: ("<< static_cast<void *>(m->next)
- << "), new msg (" << static_cast<void *>(m) << ")";
- return MOD_ERR_OK;
- } else if (pos == 2) {
- tail = current->m;
- while (tail->next)
- tail = tail->next;
- Alog(LOG_DEBUG) << "existing msg: ("<< static_cast<void *>(tail)
- << "), new msg (" << static_cast<void *>(m) << ")";
- m->next = NULL;
- return MOD_ERR_OK;
- } else
- return MOD_ERR_EXISTS;
- }
- lastHash = current;
- }
-
- if (!(newHash = new MessageHash)) {
- fatal("Out of memory");
- }
- newHash->next = NULL;
- newHash->name = sstrdup(m->name);
- newHash->m = m;
-
- if (lastHash == NULL)
- msgTable[index] = newHash;
- else
- lastHash->next = newHash;
- return MOD_ERR_OK;
-}
-
-/**
- * Add the given message (m) to the MessageHash marking it as a core command
- * @param msgTable the MessageHash we want to add to
- * @param m the Message we are adding
- * @return MOD_ERR_OK on a successful add.
- **/
-int addCoreMessage(MessageHash * msgTable[], Message * m)
-{
- if (!msgTable || !m) {
- return MOD_ERR_PARAMS;
- }
- m->core = 1;
- return addMessage(msgTable, m, 0);
-}
-
-/**
- * remove the given message from the given message hash, for the given module
- * @param msgTable which MessageHash we are removing from
- * @param m the Message we want to remove
- * @return MOD_ERR_OK on success, althing else on fail.
- **/
-int delMessage(MessageHash * msgTable[], Message * m)
-{
- int index = 0;
- MessageHash *current = NULL;
- MessageHash *lastHash = NULL;
- Message *tail = NULL, *last = NULL;
-
- if (!m || !msgTable) {
- return MOD_ERR_PARAMS;
- }
-
- index = CMD_HASH(m->name);
-
- for (current = msgTable[index]; current; current = current->next) {
- if (stricmp(m->name, current->name) == 0) {
- if (!lastHash) {
- tail = current->m;
- if (tail->next) {
- while (tail) {
- if (last) {
- last->next = tail->next;
- } else {
- current->m = tail->next;
- }
- return MOD_ERR_OK;
- }
- } else {
- msgTable[index] = current->next;
- delete [] current->name;
- return MOD_ERR_OK;
- }
- } else {
- tail = current->m;
- if (tail->next) {
- while (tail) {
- if (last) {
- last->next = tail->next;
- } else {
- current->m = tail->next;
- }
- return MOD_ERR_OK;
- }
- } else {
- lastHash->next = current->next;
- delete [] current->name;
- return MOD_ERR_OK;
- }
- }
- }
- lastHash = current;
- }
- return MOD_ERR_NOEXIST;
-}
-
-/**
- * Destory a message, freeing its memory.
- * @param m the message to be destroyed
- * @return MOD_ERR_SUCCESS on success
- **/
-int destroyMessage(Message * m)
-{
- if (!m) {
- return MOD_ERR_PARAMS;
- }
- if (m->name) {
- delete [] m->name;
- }
- m->func = NULL;
- m->next = NULL;
- return MOD_ERR_OK;
-}
-
-/*******************************************************************************
- * Module Callback Functions
- *******************************************************************************/
-
- /* Check the current version of anope against a given version number
- * Specifiying -1 for minor,patch or build
- * @param major The major version of anope, the first part of the verison number
- * @param minor The minor version of anope, the second part of the version number
- * @param patch The patch version of anope, the third part of the version number
- * @param build The build revision of anope from SVN
- * @return True if the version newer than the version specified.
- **/
-bool moduleMinVersion(int major, int minor, int patch, int build)
-{
- bool ret = false;
- if (VERSION_MAJOR > major) { /* Def. new */
- ret = true;
- } else if (VERSION_MAJOR == major) { /* Might be newer */
- if (minor == -1) {
- return true;
- } /* They dont care about minor */
- if (VERSION_MINOR > minor) { /* Def. newer */
- ret = true;
- } else if (VERSION_MINOR == minor) { /* Might be newer */
- if (patch == -1) {
- return true;
- } /* They dont care about patch */
- if (VERSION_PATCH > patch) {
- ret = true;
- } else if (VERSION_PATCH == patch) {
-#if 0
-// XXX
- if (build == -1) {
- return true;
- } /* They dont care about build */
- if (VERSION_BUILD >= build) {
- ret = true;
- }
-#endif
- }
- }
- }
- return ret;
-}
-
-void Module::NoticeLang(const char *source, User * u, int number, ...)
-{
- va_list va;
- char buffer[4096], outbuf[4096];
- char *fmt = NULL;
- int mlang = Config.NSDefLanguage;
- char *s, *t, *buf;
-
- /* Find the users lang, and use it if we can */
- if (u && u->Account()) {
- mlang = u->Account()->language;
- }
-
- /* If the users lang isnt supported, drop back to English */
- if (this->lang[mlang].argc == 0)
- {
- mlang = LANG_EN_US;
- }
-
- /* If the requested lang string exists for the language */
- if (this->lang[mlang].argc > number) {
- fmt = this->lang[mlang].argv[number];
-
- buf = sstrdup(fmt);
- va_start(va, number);
- vsnprintf(buffer, 4095, buf, va);
- va_end(va);
- s = buffer;
- while (*s) {
- t = s;
- s += strcspn(s, "\n");
- if (*s)
- *s++ = '\0';
- strscpy(outbuf, t, sizeof(outbuf));
- u->SendMessage(source, "%s", outbuf);
- }
- delete [] buf;
- } else {
- Alog() << this->name << ": INVALID language string call, language: [" << mlang << "], String [" << number << "]";
- }
-}
-
-const char *Module::GetLangString(User * u, int number)
-{
- int mlang = Config.NSDefLanguage;
-
- /* Find the users lang, and use it if we can */
- if (u && u->Account())
- mlang = u->Account()->language;
-
- /* If the users lang isnt supported, drop back to English */
- if (this->lang[mlang].argc == 0)
- mlang = LANG_EN_US;
-
- /* If the requested lang string exists for the language */
- if (this->lang[mlang].argc > number) {
- return this->lang[mlang].argv[number];
- /* Return an empty string otherwise, because we might be used without
- * the return value being checked. If we would return NULL, bad things
- * would happen!
- */
- } else {
- Alog() << this->name << ": INVALID language string call, language: [" << mlang << "], String [" << number << "]";
- return "";
- }
-}
-
-void Module::DeleteLanguage(int langNumber)
-{
- if (this->lang[langNumber].argc)
- {
- for (int idx = 0; idx > this->lang[langNumber].argc; idx++)
- delete [] this->lang[langNumber].argv[idx];
- delete [] this->lang[langNumber].argv;
- this->lang[langNumber].argc = 0;
- }
-}
-
-void ModuleRunTimeDirCleanUp()
-{
-#ifndef _WIN32
- DIR *dirp;
- struct dirent *dp;
-#else
- BOOL fFinished;
- HANDLE hList;
- TCHAR szDir[MAX_PATH + 1];
- WIN32_FIND_DATA FileData;
- char buffer[_MAX_PATH];
-#endif
- char dirbuf[BUFSIZE];
- char filebuf[BUFSIZE];
-
- snprintf(dirbuf, BUFSIZE, "%s/modules/runtime", services_dir.c_str());
-
- Alog(LOG_DEBUG) << "Cleaning out Module run time directory (" << dirbuf << ") - this may take a moment please wait";
-
-
-#ifndef _WIN32
- if ((dirp = opendir(dirbuf)) == NULL)
- {
- Alog(LOG_DEBUG) << "cannot open directory (" << dirbuf << ")";
- return;
- }
- while ((dp = readdir(dirp)) != NULL) {
- if (dp->d_ino == 0) {
- continue;
- }
- if (!stricmp(dp->d_name, ".") || !stricmp(dp->d_name, "..")) {
- continue;
- }
- snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, dp->d_name);
- unlink(filebuf);
- }
- closedir(dirp);
-#else
- /* Get the current working directory: */
- if (_getcwd(buffer, _MAX_PATH) == NULL)
- {
- Alog(LOG_DEBUG) << "Unable to set Current working directory";
- }
- snprintf(szDir, sizeof(szDir), "%s\\%s\\*", buffer, dirbuf);
-
- hList = FindFirstFile(szDir, &FileData);
- if (hList != INVALID_HANDLE_VALUE) {
- fFinished = FALSE;
- while (!fFinished) {
- if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, FileData.cFileName);
- DeleteFile(filebuf);
- }
- if (!FindNextFile(hList, &FileData)) {
- if (GetLastError() == ERROR_NO_MORE_FILES) {
- fFinished = TRUE;
- }
- }
- }
- } else {
- Alog(LOG_DEBUG) << "Invalid File Handle. GetLastError() reports "<< static_cast<int>(GetLastError());
- }
- FindClose(hList);
-#endif
- Alog(LOG_DEBUG) << "Module run time directory has been cleaned out";
-}
-
-/* EOF */
diff --git a/src/modules.cpp b/src/modules.cpp
new file mode 100644
index 000000000..0044bcc56
--- /dev/null
+++ b/src/modules.cpp
@@ -0,0 +1,413 @@
+/* Modular support
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+#include "modules.h"
+#include "language.h"
+#include "version.h"
+
+std::multimap<std::string, Message *> MessageMap;
+std::deque<Module *> Modules;
+
+char *mod_current_buffer = NULL;
+
+char *ModuleGetErrStr(int status)
+{
+ const char *module_err_str[] = {
+ "Module, Okay - No Error", /* MOD_ERR_OK */
+ "Module Error, Allocating memory", /* MOD_ERR_MEMORY */
+ "Module Error, Not enough parameters", /* MOD_ERR_PARAMS */
+ "Module Error, Already loaded", /* MOD_ERR_EXISTS */
+ "Module Error, File does not exist", /* MOD_ERR_NOEXIST */
+ "Module Error, No User", /* MOD_ERR_NOUSER */
+ "Module Error, Error during load time or module returned MOD_STOP", /* MOD_ERR_NOLOAD */
+ "Module Error, Unable to unload", /* MOD_ERR_NOUNLOAD */
+ "Module Error, Incorrect syntax", /* MOD_ERR_SYNTAX */
+ "Module Error, Unable to delete", /* MOD_ERR_NODELETE */
+ "Module Error, Unknown Error occuried", /* MOD_ERR_UNKOWN */
+ "Module Error, File I/O Error", /* MOD_ERR_FILE_IO */
+ "Module Error, No Service found for request", /* MOD_ERR_NOSERVICE */
+ "Module Error, No module name for request" /* MOD_ERR_NO_MOD_NAME */
+ };
+ return const_cast<char *>(module_err_str[status]);
+}
+
+
+/************************************************/
+
+/**
+ * Load the ircd protocol module up
+ **/
+int protocol_module_init()
+{
+ int ret = 0;
+
+ Alog() << "Loading IRCD Protocol Module: [" << Config.IRCDModule << "]";
+ ret = ModuleManager::LoadModule(Config.IRCDModule, NULL);
+
+ if (ret == MOD_ERR_OK)
+ {
+ FindModule(Config.IRCDModule)->SetType(PROTOCOL);
+ /* This is really NOT the correct place to do config checks, but
+ * as we only have the ircd struct filled here, we have to over
+ * here. -GD
+ */
+ if (ircd->ts6)
+ {
+ if (!Config.Numeric)
+ {
+ Alog() << "This IRCd protocol requires a server id to be set in Anope's configuration.";
+ ret = -1;
+ }
+ }
+ }
+
+ return ret;
+}
+
+void Module::InsertLanguage(int langNumber, int ac, const char **av)
+{
+ int i;
+
+ Alog(LOG_DEBUG) << this->name << "Adding " << ac << " texts for language " << langNumber;
+
+ if (this->lang[langNumber].argc > 0) {
+ this->DeleteLanguage(langNumber);
+ }
+
+ this->lang[langNumber].argc = ac;
+ this->lang[langNumber].argv = new char *[ac];
+ for (i = 0; i < ac; i++) {
+ this->lang[langNumber].argv[i] = sstrdup(av[i]);
+ }
+}
+
+/**
+ * Search the list of loaded modules for the given name.
+ * @param name the name of the module to find
+ * @return a pointer to the module found, or NULL
+ */
+Module *FindModule(const std::string &name)
+{
+ for (std::deque<Module *>::iterator it = Modules.begin(); it != Modules.end(); ++it)
+ {
+ Module *m = *it;
+
+ if (m->name == name)
+ {
+ return m;
+ }
+ }
+
+ return NULL;
+}
+
+/** Add a message to Anope
+ * @param name The message name as sent by the IRCd
+ * @param func A callback function that will be called when this message is received
+ * @return The new message object
+ */
+Message *Anope::AddMessage(const std::string &name, int (*func)(const char *source, int ac, const char **av))
+{
+ Message *m = new Message;
+
+ m->name = name;
+ m->func = func;
+
+ MessageMap.insert(std::make_pair(m->name, m));
+
+ return m;
+}
+
+/** Deletes a message from Anope
+ * XXX Im not sure what will happen if this function is called indirectly from a message function pointed to by this message and there
+ * is more than one hook for this message.. must check
+ * @param m The message
+ * @return true if the message was found and deleted, else false
+ */
+bool Anope::DelMessage(Message *m)
+{
+ std::multimap<std::string, Message *>::iterator it = MessageMap.find(m->name);
+
+ if (it == MessageMap.end())
+ {
+ return false;
+ }
+
+ std::multimap<std::string, Message *>::iterator upper = MessageMap.upper_bound(m->name);
+
+ for (; it != upper; ++it)
+ {
+ if (it->second == m)
+ {
+ delete m;
+ MessageMap.erase(it);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*******************************************************************************
+ * Command Functions
+ *******************************************************************************/
+
+int Module::AddCommand(BotInfo *bi, Command *c)
+{
+ if (!bi || !c)
+ return MOD_ERR_PARAMS;
+
+ c->module = this;
+ c->service = bi;
+
+ std::pair<std::map<ci::string, Command *>::iterator, bool> it = bi->Commands.insert(std::make_pair(c->name, c));
+
+ if (it.second != true)
+ {
+ Alog() << "Error creating command " << c->name << ". Command already exists!";
+ delete c;
+ return MOD_ERR_EXISTS;
+ }
+
+ return MOD_ERR_OK;
+}
+
+/**
+ * Delete a command from the service given.
+ * @param cmdTable the cmdTable for the services to remove the command from
+ * @param name the name of the command to delete from the service
+ * @return returns MOD_ERR_OK on success
+ */
+int Module::DelCommand(BotInfo *bi, Command *c)
+{
+ if (!bi || !c)
+ return MOD_ERR_PARAMS;
+
+ if (!bi->Commands.erase(c->name))
+ return MOD_ERR_NOEXIST;
+
+ return MOD_ERR_OK;
+}
+
+/**
+ * Find a message in the message table
+ * @param name The name of the message were looking for
+ * @return NULL if we cant find it, or a pointer to the Message if we can
+ **/
+std::vector<Message *> FindMessage(const std::string &name)
+{
+ std::vector<Message *> messages;
+
+ std::multimap<std::string, Message *>::iterator it = MessageMap.find(name);
+
+ if (it == MessageMap.end())
+ return messages;
+
+ std::multimap<std::string, Message *>::iterator upper = MessageMap.upper_bound(name);
+
+ for (; it != upper; ++it)
+ messages.push_back(it->second);
+
+ return messages;
+}
+
+/*******************************************************************************
+ * Module Callback Functions
+ *******************************************************************************/
+
+ /* Check the current version of anope against a given version number
+ * Specifiying -1 for minor,patch or build
+ * @param major The major version of anope, the first part of the verison number
+ * @param minor The minor version of anope, the second part of the version number
+ * @param patch The patch version of anope, the third part of the version number
+ * @param build The build revision of anope from SVN
+ * @return True if the version newer than the version specified.
+ **/
+bool moduleMinVersion(int major, int minor, int patch, int build)
+{
+ bool ret = false;
+ if (VERSION_MAJOR > major) { /* Def. new */
+ ret = true;
+ } else if (VERSION_MAJOR == major) { /* Might be newer */
+ if (minor == -1) {
+ return true;
+ } /* They dont care about minor */
+ if (VERSION_MINOR > minor) { /* Def. newer */
+ ret = true;
+ } else if (VERSION_MINOR == minor) { /* Might be newer */
+ if (patch == -1) {
+ return true;
+ } /* They dont care about patch */
+ if (VERSION_PATCH > patch) {
+ ret = true;
+ } else if (VERSION_PATCH == patch) {
+#if 0
+// XXX
+ if (build == -1) {
+ return true;
+ } /* They dont care about build */
+ if (VERSION_BUILD >= build) {
+ ret = true;
+ }
+#endif
+ }
+ }
+ }
+ return ret;
+}
+
+void Module::NoticeLang(const char *source, User * u, int number, ...)
+{
+ va_list va;
+ char buffer[4096], outbuf[4096];
+ char *fmt = NULL;
+ int mlang = Config.NSDefLanguage;
+ char *s, *t, *buf;
+
+ /* Find the users lang, and use it if we can */
+ if (u && u->Account()) {
+ mlang = u->Account()->language;
+ }
+
+ /* If the users lang isnt supported, drop back to English */
+ if (this->lang[mlang].argc == 0)
+ {
+ mlang = LANG_EN_US;
+ }
+
+ /* If the requested lang string exists for the language */
+ if (this->lang[mlang].argc > number) {
+ fmt = this->lang[mlang].argv[number];
+
+ buf = sstrdup(fmt);
+ va_start(va, number);
+ vsnprintf(buffer, 4095, buf, va);
+ va_end(va);
+ s = buffer;
+ while (*s) {
+ t = s;
+ s += strcspn(s, "\n");
+ if (*s)
+ *s++ = '\0';
+ strscpy(outbuf, t, sizeof(outbuf));
+ u->SendMessage(source, "%s", outbuf);
+ }
+ delete [] buf;
+ } else {
+ Alog() << this->name << ": INVALID language string call, language: [" << mlang << "], String [" << number << "]";
+ }
+}
+
+const char *Module::GetLangString(User * u, int number)
+{
+ int mlang = Config.NSDefLanguage;
+
+ /* Find the users lang, and use it if we can */
+ if (u && u->Account())
+ mlang = u->Account()->language;
+
+ /* If the users lang isnt supported, drop back to English */
+ if (this->lang[mlang].argc == 0)
+ mlang = LANG_EN_US;
+
+ /* If the requested lang string exists for the language */
+ if (this->lang[mlang].argc > number) {
+ return this->lang[mlang].argv[number];
+ /* Return an empty string otherwise, because we might be used without
+ * the return value being checked. If we would return NULL, bad things
+ * would happen!
+ */
+ } else {
+ Alog() << this->name << ": INVALID language string call, language: [" << mlang << "], String [" << number << "]";
+ return "";
+ }
+}
+
+void Module::DeleteLanguage(int langNumber)
+{
+ if (this->lang[langNumber].argc)
+ {
+ for (int idx = 0; idx > this->lang[langNumber].argc; idx++)
+ delete [] this->lang[langNumber].argv[idx];
+ delete [] this->lang[langNumber].argv;
+ this->lang[langNumber].argc = 0;
+ }
+}
+
+void ModuleRunTimeDirCleanUp()
+{
+#ifndef _WIN32
+ DIR *dirp;
+ struct dirent *dp;
+#else
+ BOOL fFinished;
+ HANDLE hList;
+ TCHAR szDir[MAX_PATH + 1];
+ WIN32_FIND_DATA FileData;
+ char buffer[_MAX_PATH];
+#endif
+ char dirbuf[BUFSIZE];
+ char filebuf[BUFSIZE];
+
+ snprintf(dirbuf, BUFSIZE, "%s/modules/runtime", services_dir.c_str());
+
+ Alog(LOG_DEBUG) << "Cleaning out Module run time directory (" << dirbuf << ") - this may take a moment please wait";
+
+
+#ifndef _WIN32
+ if ((dirp = opendir(dirbuf)) == NULL)
+ {
+ Alog(LOG_DEBUG) << "cannot open directory (" << dirbuf << ")";
+ return;
+ }
+ while ((dp = readdir(dirp)) != NULL) {
+ if (dp->d_ino == 0) {
+ continue;
+ }
+ if (!stricmp(dp->d_name, ".") || !stricmp(dp->d_name, "..")) {
+ continue;
+ }
+ snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, dp->d_name);
+ unlink(filebuf);
+ }
+ closedir(dirp);
+#else
+ /* Get the current working directory: */
+ if (_getcwd(buffer, _MAX_PATH) == NULL)
+ {
+ Alog(LOG_DEBUG) << "Unable to set Current working directory";
+ }
+ snprintf(szDir, sizeof(szDir), "%s\\%s\\*", buffer, dirbuf);
+
+ hList = FindFirstFile(szDir, &FileData);
+ if (hList != INVALID_HANDLE_VALUE) {
+ fFinished = FALSE;
+ while (!fFinished) {
+ if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ snprintf(filebuf, BUFSIZE, "%s/%s", dirbuf, FileData.cFileName);
+ DeleteFile(filebuf);
+ }
+ if (!FindNextFile(hList, &FileData)) {
+ if (GetLastError() == ERROR_NO_MORE_FILES) {
+ fFinished = TRUE;
+ }
+ }
+ }
+ } else {
+ Alog(LOG_DEBUG) << "Invalid File Handle. GetLastError() reports "<< static_cast<int>(GetLastError());
+ }
+ FindClose(hList);
+#endif
+ Alog(LOG_DEBUG) << "Module run time directory has been cleaned out";
+}
+
+/* EOF */
diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt
index ad66663c3..a7feab5d0 100644
--- a/src/modules/CMakeLists.txt
+++ b/src/modules/CMakeLists.txt
@@ -1,5 +1,4 @@
-# Find all the *.c and *.cpp files within the current source directory, and sort the list
-file(GLOB MODULES_SRCS_C RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c")
+# Find all the *.cpp files within the current source directory, and sort the list
file(GLOB MODULES_SRCS_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp")
set(MODULES_SRCS ${MODULES_SRCS_C} ${MODULES_SRCS_CPP})
sort_list(MODULES_SRCS)
@@ -58,6 +57,7 @@ endforeach(SRC)
file(GLOB MODULES_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*")
remove_item_from_list(MODULES_FILES "CMakeFiles")
remove_item_from_list(MODULES_FILES "mysql")
+remove_item_from_list(MODULES_FILES "ssl")
# Iterate through this directory searching for subdirectories, and creating modules for those subdirectories
foreach(FILE ${MODULES_FILES})
diff --git a/src/modules/Makefile b/src/modules/Makefile
index 3ab2a7803..c69128ea3 100644
--- a/src/modules/Makefile
+++ b/src/modules/Makefile
@@ -8,8 +8,7 @@ MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \
'PROFILE=${PROFILE}' 'SHARED=${SHARED}' 'MODULEFLAGS=${MODULEFLAGS}'\
'MAKEBIN=${MAKEBIN}' 'MYSQLDIR=${MYSQLDIR}'
-OBJECTS= $(SRCS:.c=.so)
-OBJECTS+= $(SRCS:.cpp=.so)
+OBJECTS= $(SRCS:.cpp=.so)
CDEFS= -rdynamic -Wall
MYSQL_ARGS = -I$(MYSQLDIR)/include/ -L$(MYSQLDIR)/lib/ -Wl,-rpath -Wl,$(MYSQLDIR)/lib/ -lmysqlpp
@@ -25,16 +24,11 @@ install:
distclean: spotless
-.SUFFIXES: .c .cpp .so
-
-.c.so:
- $(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} \
- $(if $(shell grep RequiredLibraries $< | grep mysqlpp), $(MYSQL_ARGS)) \
- -I../${INCLUDEDIR} -o $@ $<
+.SUFFIXES: .cpp .so
.cpp.so:
$(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} \
- $(if $(shell grep RequiredLibraries $< | grep mysqlpp), $(MYSQL_ARGS)) \
+ $(if $(shell grep RequiredLibraries $< | grep mysqlpp), $(MYSQL_ARGS)) $(if $(shell grep RequiredLibraries $< | grep ssl), -lssl) $(if $(shell grep RequiredLibraries $< | grep crypt), -lcrypt) \
-I../${INCLUDEDIR} -o $@ $<
subs:
diff --git a/src/modules/cs_appendtopic.c b/src/modules/cs_appendtopic.cpp
index 22848b74a..a44e6d1a9 100644
--- a/src/modules/cs_appendtopic.c
+++ b/src/modules/cs_appendtopic.cpp
@@ -128,6 +128,11 @@ class CommandCSAppendTopic : public Command
{
me->NoticeLang(Config.s_ChanServ, u, LNG_APPENDTOPIC_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ me->NoticeLang(Config.s_ChanServ, u, LNG_CHAN_HELP);
+ }
};
class CSAppendTopic : public Module
@@ -141,7 +146,7 @@ class CSAppendTopic : public Module
this->SetVersion(VERSION);
this->SetType(SUPPORTED);
- this->AddCommand(CHANSERV, new CommandCSAppendTopic());
+ this->AddCommand(ChanServ, new CommandCSAppendTopic());
/* English (US) */
const char* langtable_en_us[] = {
@@ -222,12 +227,6 @@ class CSAppendTopic : public Module
this->InsertLanguage(LANG_PT, LNG_NUM_STRINGS, langtable_pt);
this->InsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru);
this->InsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it);
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- this->NoticeLang(Config.s_ChanServ, u, LNG_CHAN_HELP);
}
};
diff --git a/src/modules/cs_enforce.c b/src/modules/cs_enforce.cpp
index 435f07d79..271b9da05 100644
--- a/src/modules/cs_enforce.c
+++ b/src/modules/cs_enforce.cpp
@@ -216,6 +216,11 @@ class CommandCSEnforce : public Command
{
me->NoticeLang(Config.s_ChanServ, u, LNG_ENFORCE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ me->NoticeLang(Config.s_ChanServ, u, LNG_CHAN_HELP);
+ }
};
class CSEnforce : public Module
@@ -229,7 +234,7 @@ class CSEnforce : public Module
this->SetVersion(VERSION);
this->SetType(SUPPORTED);
- this->AddCommand(CHANSERV, new CommandCSEnforce());
+ this->AddCommand(ChanServ, new CommandCSEnforce());
/* English (US) */
const char* langtable_en_us[] = {
@@ -438,12 +443,6 @@ class CSEnforce : public Module
this->InsertLanguage(LANG_PT, LNG_NUM_STRINGS, langtable_pt);
this->InsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru);
this->InsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it);
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- this->NoticeLang(Config.s_ChanServ, u, LNG_CHAN_HELP);
}
};
diff --git a/src/modules/cs_tban.c b/src/modules/cs_tban.cpp
index 10f295b3d..5a768dc81 100644
--- a/src/modules/cs_tban.c
+++ b/src/modules/cs_tban.cpp
@@ -83,6 +83,11 @@ class CommandCSTBan : public Command
{
me->NoticeLang(Config.s_ChanServ, u, TBAN_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ me->NoticeLang(Config.s_ChanServ, u, TBAN_HELP);
+ }
};
class CSTBan : public Module
@@ -92,7 +97,7 @@ class CSTBan : public Module
{
me = this;
- this->AddCommand(CHANSERV, new CommandCSTBan());
+ this->AddCommand(ChanServ, new CommandCSTBan());
this->SetAuthor(AUTHOR);
this->SetVersion(VERSION);
@@ -154,12 +159,6 @@ class CSTBan : public Module
this->InsertLanguage(LANG_PT, LANG_NUM_STRINGS, langtable_pt);
this->InsertLanguage(LANG_RU, LANG_NUM_STRINGS, langtable_ru);
this->InsertLanguage(LANG_IT, LANG_NUM_STRINGS, langtable_it);
-
- ModuleManager::Attach(I_OnChanServHelp, this);
- }
- void OnChanServHelp(User *u)
- {
- this->NoticeLang(Config.s_ChanServ, u, TBAN_HELP);
}
};
@@ -181,7 +180,7 @@ class TempBan : public CallBack
{
Channel *c;
- if ((c = findchan(chan.c_str())) && c->ci)
+ if ((c = findchan(chan)) && c->ci)
{
c->RemoveMode(NULL, CMODE_BAN, mask);
}
@@ -203,7 +202,7 @@ int canBanUser(Channel * c, User * u, User * u2)
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
else if (is_excepted(ci, u2))
notice_lang(Config.s_ChanServ, u, CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str());
- else if (is_protected(u2))
+ else if (u2->IsProtected())
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
else
ok = 1;
diff --git a/src/modules/hs_request.c b/src/modules/hs_request.cpp
index ebc46dfe8..cc5637bef 100644
--- a/src/modules/hs_request.c
+++ b/src/modules/hs_request.cpp
@@ -205,6 +205,11 @@ class CommandHSRequest : public Command
{
me->NoticeLang(Config.s_HostServ, u, LNG_REQUEST_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ me->NoticeLang(Config.s_HostServ, u, LNG_HELP);
+ }
};
class CommandHSActivate : public Command
@@ -257,6 +262,11 @@ class CommandHSActivate : public Command
{
me->NoticeLang(Config.s_HostServ, u, LNG_ACTIVATE_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ me->NoticeLang(Config.s_HostServ, u, LNG_HELP_SETTER);
+ }
};
class CommandHSReject : public Command
@@ -339,7 +349,7 @@ class HSListBase : public Command
return MOD_CONT;
}
public:
- HSListBase(const std::string &cmd, int min, int max) : Command(cmd, min, max, "hostserv/set")
+ HSListBase(const ci::string &cmd, int min, int max) : Command(cmd, min, max, "hostserv/set")
{
}
@@ -378,10 +388,10 @@ class HSRequest : public Module
{
me = this;
- this->AddCommand(HOSTSERV, new CommandHSRequest());
- this->AddCommand(HOSTSERV, new CommandHSActivate());
- this->AddCommand(HOSTSERV, new CommandHSReject());
- this->AddCommand(HOSTSERV, new CommandHSWaiting());
+ this->AddCommand(HostServ, new CommandHSRequest());
+ this->AddCommand(HostServ, new CommandHSActivate());
+ this->AddCommand(HostServ, new CommandHSReject());
+ this->AddCommand(HostServ, new CommandHSWaiting());
this->SetAuthor(AUTHOR);
this->SetVersion(VERSION);
@@ -645,8 +655,8 @@ class HSRequest : public Module
this->InsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru);
this->InsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it);
- Implementation i[] = { I_OnHostServHelp, I_OnPreCommand, I_OnDatabaseRead, I_OnDatabaseWrite };
- ModuleManager::Attach(i, this, 4);
+ Implementation i[] = { I_OnPreCommand, I_OnDatabaseRead, I_OnDatabaseWrite };
+ ModuleManager::Attach(i, this, 3);
}
~HSRequest()
@@ -670,7 +680,7 @@ class HSRequest : public Module
if (!key.empty() && key == "+req")
{
std::vector<ci::string> emptyParams;
- Command *c = findCommand(HOSTSERV, "WAITING");
+ Command *c = FindCommand(HostServ, "WAITING");
c->Execute(u, emptyParams);
return EVENT_STOP;
}
@@ -698,12 +708,6 @@ class HSRequest : public Module
return EVENT_CONTINUE;
}
- void OnHostServHelp(User *u)
- {
- this->NoticeLang(Config.s_HostServ, u, LNG_HELP);
- this->NoticeLang(Config.s_HostServ, u, LNG_HELP_SETTER);
- }
-
EventReturn OnDatabaseRead(const std::vector<std::string> &params)
{
if (params[0] == "HS_REQUEST" && params.size() >= 5)
diff --git a/src/modules/mysql/db_mysql.h b/src/modules/mysql/db_mysql.h
index b62f52524..f2885408f 100644
--- a/src/modules/mysql/db_mysql.h
+++ b/src/modules/mysql/db_mysql.h
@@ -39,48 +39,6 @@ NickCoreFlagInfo NickCoreFlags[] = {
{"", static_cast<NickCoreFlag>(-1)}
};
-struct ChannelModeInfo
-{
- std::string Name;
- ChannelModeName Mode;
-};
-
-ChannelModeInfo ChannelModes[] = {
- {"CMODE_BLOCKCOLOR", CMODE_BLOCKCOLOR},
- {"CMODE_FLOOD", CMODE_FLOOD},
- {"CMODE_INVITE", CMODE_INVITE},
- {"CMODE_KEY", CMODE_KEY},
- {"CMODE_LIMIT", CMODE_LIMIT},
- {"CMODE_MODERATED", CMODE_MODERATED},
- {"CMODE_NOEXTERNAL", CMODE_NOEXTERNAL},
- {"CMODE_PRIVATE", CMODE_PRIVATE},
- {"CMODE_REGISTERED", CMODE_REGISTERED},
- {"CMODE_SECRET", CMODE_SECRET},
- {"CMODE_TOPIC", CMODE_TOPIC},
- {"CMODE_AUDITORIUM", CMODE_AUDITORIUM},
- {"CMODE_SSL", CMODE_SSL},
- {"CMODE_ADMINONLY", CMODE_ADMINONLY},
- {"CMODE_NOCTCP", CMODE_NOCTCP},
- {"CMODE_FILTER", CMODE_FILTER},
- {"CMODE_NOKNOCK", CMODE_NOKNOCK},
- {"CMODE_REDIRECT", CMODE_REDIRECT},
- {"CMODE_REGMODERATED", CMODE_REGMODERATED},
- {"CMODE_NONICK", CMODE_NONICK},
- {"CMODE_OPERONLY", CMODE_OPERONLY},
- {"CMODE_NONICK", CMODE_NONICK},
- {"CMODE_REGISTEREDONLY", CMODE_REGISTEREDONLY},
- {"CMODE_STRIPCOLOR", CMODE_STRIPCOLOR},
- {"CMODE_NONOTICE", CMODE_NONOTICE},
- {"CMODE_NOINVITE", CMODE_NOINVITE},
- {"CMODE_ALLINVITE", CMODE_ALLINVITE},
- {"CMODE_BLOCKCAPS", CMODE_BLOCKCAPS},
- {"CMODE_PERM", CMODE_PERM},
- {"CMODE_NICKFLOOD", CMODE_NICKFLOOD},
- {"CMODE_JOINFLOOD", CMODE_JOINFLOOD},
- {"CMODE_NOREJOIN", CMODE_NOREJOIN},
- {"", static_cast<ChannelModeName>(-1)}
-};
-
struct BotFlagInfo
{
std::string Name;
@@ -140,13 +98,6 @@ struct BotServFlagInfo
BotServFlagInfo BotServFlags[] = {
{"PRIVATE", BI_PRIVATE},
- {"CHANSERV", BI_CHANSERV},
- {"BOTSERV", BI_BOTSERV},
- {"HOSTSERV", BI_HOSTSERV},
- {"OPERSERV", BI_OPERSERV},
- {"MEMOSERV", BI_MEMOSERV},
- {"NICKSERV", BI_NICKSERV},
- {"GLOBAL", BI_GLOBAL},
{"", static_cast<BotFlag>(-1)}
};
@@ -169,7 +120,7 @@ MemoFlagInfo MemoFlags[] = {
inline std::string SQLAssign(const mysqlpp::String& s) { return s.c_str(); }
class DBMySQL;
-static DBMySQL *Me;
+static DBMySQL *me;
bool ExecuteQuery(mysqlpp::Query& query)
{
@@ -226,7 +177,7 @@ class DBMySQL : public Module
DBMySQL(const std::string &modname, const std::string &creator) : Module(modname, creator)
{
- Me = this;
+ me = this;
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
diff --git a/src/modules/mysql/db_mysql_execute.cpp b/src/modules/mysql/db_mysql_execute.cpp
index 0c7c4de65..2313edd37 100644
--- a/src/modules/mysql/db_mysql_execute.cpp
+++ b/src/modules/mysql/db_mysql_execute.cpp
@@ -1,24 +1,18 @@
/* RequiredLibraries: mysqlpp */
#include "db_mysql.h"
-#define HASH(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31))
class FakeNickCore : public NickCore
{
public:
FakeNickCore() : NickCore("-SQLUser")
{
- if (this->next)
- this->next->prev = this->prev;
- if (this->prev)
- this->prev->next = this->next;
- else
- nclists[HASH(this->display)] = this->next;
+ NickCoreList.erase(this->display);
}
~FakeNickCore()
{
- insert_core(this);
+ NickCoreList[this->display] = this;
Users.clear();
}
@@ -37,27 +31,17 @@ class FakeUser : public User
this->realname = sstrdup("Fake SQL User");
this->hostip = sstrdup("255.255.255.255");
this->vhost = NULL;
- this->server = serv_uplink; // XXX Need a good way to set this to ourself
-
- if (this->prev)
- this->prev->next = this->next;
- else
- userlist[HASH(this->nick.c_str())] = this->next;
- if (this->next)
- this->next->prev = this->prev;
+ this->server = Me;
+
+ UserListByNick.erase("-SQLUser");
--usercnt;
}
~FakeUser()
{
- this->server = serv_uplink; // XXX Need a good way to set this to ourself
-
- User **list = &userlist[HASH(this->nick.c_str())];
- this->next = *list;
- if (*list)
- (*list)->prev = this;
- *list = this;
+ UserListByNick["-SQLUser"] = this;
++usercnt;
+
nc = NULL;
}
@@ -68,21 +52,22 @@ class FakeUser : public User
NickCore *Account() const { return nc; }
const bool IsIdentified(bool) const { return nc ? true : false; }
+ const bool IsRecognized(bool) const { return true; }
} SQLUser;
class SQLTimer : public Timer
{
public:
- SQLTimer() : Timer(Me->Delay, time(NULL), true)
+ SQLTimer() : Timer(me->Delay, time(NULL), true)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "TRUNCATE TABLE `anope_commands`";
ExecuteQuery(query);
}
void Tick(time_t)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
mysqlpp::StoreQueryResult qres;
query << "SELECT * FROM `anope_commands`";
@@ -144,11 +129,7 @@ class SQLTimer : public Timer
continue;
}
- // XXX this whole strtok thing needs to die
- char *cmdbuf = sstrdup(qres[i]["command"].c_str());
- char *cmd = strtok(cmdbuf, " ");
- mod_run_cmd(bi->nick, u, bi->cmdTable, cmd);
- delete [] cmdbuf;
+ mod_run_cmd(bi, u, qres[i]["command"].c_str());
if (logout)
u->Logout();
@@ -171,7 +152,7 @@ class DBMySQLExecute : public DBMySQL
~DBMySQLExecute()
{
- TimerManager::DelTimer(_SQLTimer);
+ delete _SQLTimer;
}
};
diff --git a/src/modules/mysql/db_mysql_read.cpp b/src/modules/mysql/db_mysql_read.cpp
index 5c498b008..3c5fb359a 100644
--- a/src/modules/mysql/db_mysql_read.cpp
+++ b/src/modules/mysql/db_mysql_read.cpp
@@ -27,7 +27,7 @@ static std::vector<std::string> MakeVector(std::string buf)
static void LoadDatabase()
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
mysqlpp::StoreQueryResult qres;
query << "SELECT * FROM `anope_ns_core`";
@@ -166,7 +166,13 @@ static void LoadDatabase()
{
for (size_t i = 0; i < qres.num_rows(); ++i)
{
- BotInfo *bi = new BotInfo(SQLAssign(qres[i]["nick"]), SQLAssign(qres[i]["user"]), SQLAssign(qres[i]["host"]), SQLAssign(qres[i]["rname"]));
+ BotInfo *bi = findbot(SQLAssign(qres[i]["nick"]));
+ if (!bi)
+ bi = new BotInfo(SQLAssign(qres[i]["nick"]));
+ bi->user = SQLAssign(qres[i]["user"]);
+ bi->host = SQLAssign(qres[i]["host"]);
+ bi->real = SQLAssign(qres[i]["rname"]);
+
if (qres[i]["flags"].size())
{
spacesepstream sep(SQLAssign(qres[i]["flags"]));
@@ -266,52 +272,37 @@ static void LoadDatabase()
ci->bantype = atoi(qres[i]["bantype"].c_str());
if (qres[i]["mlock_on"].size())
{
+ std::vector<std::string> modes;
std::string buf;
+
spacesepstream sep(SQLAssign(qres[i]["mlock_on"]));
while (sep.GetToken(buf))
- {
- for (int j = 0; ChannelModes[j].Mode != -1; ++j)
- {
- if (buf == ChannelModes[j].Name)
- {
- ci->SetMLock(ChannelModes[j].Mode, true);
- break;
- }
- }
- }
+ modes.push_back(buf);
+
+ ci->Extend("db_mlock_modes_on", new ExtensibleItemRegular<std::vector<std::string> >(modes));
}
if (qres[i]["mlock_off"].size())
{
+ std::vector<std::string> modes;
std::string buf;
+
spacesepstream sep(SQLAssign(qres[i]["mlock_off"]));
while (sep.GetToken(buf))
- {
- for (int j = 0; ChannelModes[j].Mode != -1; ++j)
- {
- if (buf == ChannelModes[j].Name)
- {
- ci->SetMLock(ChannelModes[j].Mode, false);
- break;
- }
- }
- }
+ modes.push_back(buf);
+
+ ci->Extend("db_mlock_modes_off", new ExtensibleItemRegular<std::vector<std::string> >(modes));
}
if (qres[i]["mlock_params"].size())
{
- std::string buf;
+ std::vector<std::pair<std::string, std::string> > mlp;
+ std::string buf, buf2;
+
spacesepstream sep(SQLAssign(qres[i]["mlock_params"]));
- while (sep.GetToken(buf))
- {
- for (int j = 0; ChannelModes[j].Mode != -1; ++j)
- {
- if (buf == ChannelModes[j].Name)
- {
- sep.GetToken(buf);
- ci->SetMLock(ChannelModes[j].Mode, true, buf);
- break;
- }
- }
- }
+
+ while (sep.GetToken(buf) && sep.GetToken(buf2))
+ mlp.push_back(std::make_pair(buf, buf2));
+
+ ci->Extend("db_mlp", new ExtensibleItemRegular<std::vector<std::pair<std::string, std::string> > >(mlp));
}
if (qres[i]["entry_message"].size())
ci->entry_message = sstrdup(qres[i]["entry_message"].c_str());
@@ -629,42 +620,51 @@ static void LoadDatabase()
query << "SELECT * FROM `anope_os_akills`";
qres = StoreQuery(query);
- if (qres)
+ if (qres && SGLine)
{
for (size_t i = 0; i < qres.size(); ++i)
{
- Akill *ak = new Akill;
- ak->user = sstrdup(qres[i]["user"].c_str());
- ak->host = sstrdup(qres[i]["host"].c_str());
- ak->by = sstrdup(qres[i]["xby"].c_str());
- ak->reason = sstrdup(qres[i]["reason"].c_str());
- ak->seton = atol(qres[i]["seton"].c_str());
- ak->expires = atol(qres[i]["expire"].c_str());
- slist_add(&akills, ak);
+ ci::string user = qres[i]["user"].c_str();
+ ci::string host = qres[i]["host"].c_str();
+ ci::string by = qres[i]["xby"].c_str();
+ std::string reason = SQLAssign(qres[i]["reason"]);
+ time_t seton = atol(qres[i]["seton"].c_str());
+ time_t expires = atol(qres[i]["expire"].c_str());
+
+ XLine *x = SGLine->Add(NULL, NULL, user + "@" + host, expires, reason);
+ if (x)
+ {
+ x->By = by;
+ x->Created = seton;
+ }
}
}
- query << "SELECT * FROM `anope_os_sxlines`";
+ query << "SELECT * FROM `anope_os_xlines`";
qres = StoreQuery(query);
if (qres)
{
for (size_t i = 0; i < qres.size(); ++i)
{
- SXLine *sx = new SXLine;
- sx->mask = sstrdup(qres[i]["mask"].c_str());
- sx->by = sstrdup(qres[i]["xby"].c_str());
- sx->reason = sstrdup(qres[i]["reason"].c_str());
- sx->seton = atol(qres[i]["seton"].c_str());
- sx->expires = atol(qres[i]["expires"].c_str());
- if (qres[i]["type"] == "SGLINE")
- slist_add(&sglines, sx);
- else if (qres[i]["type"] == "SQLINE")
- slist_add(&sqlines, sx);
- else if (qres[i]["type"] == "SZLINE")
- slist_add(&szlines, sx);
- else
- delete sx;
+ ci::string mask = qres[i]["mask"].c_str();
+ ci::string by = qres[i]["xby"].c_str();
+ std::string reason = SQLAssign(qres[i]["reason"]);
+ time_t seton = atol(qres[i]["seton"].c_str());
+ time_t expires = atol(qres[i]["expires"].c_str());
+
+ XLine *x = NULL;
+ if (qres[i]["type"] == "SNLINE" && SNLine)
+ x = SNLine->Add(NULL, NULL, mask, expires, reason);
+ else if (qres[i]["type"] == "SQLINE" && SQLine)
+ x = SQLine->Add(NULL, NULL, mask, expires, reason);
+ else if (qres[i]["type"] == "SZLINE" && SZLine)
+ x = SZLine->Add(NULL, NULL,mask, expires, reason);
+ if (x)
+ {
+ x->By = by;
+ x->Created = seton;
+ }
}
}
}
diff --git a/src/modules/mysql/db_mysql_write.cpp b/src/modules/mysql/db_mysql_write.cpp
index b7b94a3a3..b5686fa2f 100644
--- a/src/modules/mysql/db_mysql_write.cpp
+++ b/src/modules/mysql/db_mysql_write.cpp
@@ -2,8 +2,6 @@
#include "db_mysql.h"
-static Module *me;
-
static std::string BuildFlagsList(ChannelInfo *ci)
{
std::string ret;
@@ -80,11 +78,16 @@ static std::string MakeMLock(ChannelInfo *ci, bool status)
{
std::string ret;
- for (int i = 0; ChannelModes[i].Mode != -1; ++i)
+ for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(); it != ModeManager::Modes.end(); ++it)
{
- if (ci->HasMLock(ChannelModes[i].Mode, status))
+ if ((*it)->Class == MC_CHANNEL)
{
- ret += " " + ChannelModes[i].Name;
+ ChannelMode *cm = dynamic_cast<ChannelMode *>(*it);
+
+ if (ci->HasMLock(cm->Name, status))
+ {
+ ret += " " + cm->NameAsString;
+ }
}
}
@@ -108,12 +111,17 @@ static std::string GetMLockParams(ChannelInfo *ci)
{
std::string ret;
- for (int i = 0; ChannelModes[i].Mode != -1; ++i)
+ for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(); it != ModeManager::Modes.end(); ++it)
{
- std::string param;
- if (ci->GetParam(ChannelModes[i].Mode, param))
+ if ((*it)->Class == MC_CHANNEL)
{
- ret += " " + ChannelModes[i].Name + " " + param;
+ ChannelMode *cm = dynamic_cast<ChannelMode *>(*it);
+
+ std::string param;
+ if (ci->GetParam(cm->Name, param))
+ {
+ ret += " " + cm->NameAsString + " " + param;
+ }
}
}
@@ -166,14 +174,14 @@ static BotInfo *CurBot = NULL;
void Write(const std::string &data)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_extra` (data) VALUES(" << mysqlpp::quote << data << ")";
ExecuteQuery(query);
}
void WriteMetadata(const std::string &key, const std::string &data)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_metadata` (name, value) VALUES(" << mysqlpp::quote << key << ", " << mysqlpp::quote << data << ")";
ExecuteQuery(query);
}
@@ -183,7 +191,7 @@ void WriteNickMetadata(const std::string &key, const std::string &data)
if (!CurNick)
throw CoreException("WriteNickMetadata without a nick to write");
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_ns_alias_metadata` (nick, name, value) VALUES(" << mysqlpp::quote << CurNick->nick << ", " << mysqlpp::quote << key << ", " << mysqlpp::quote << data << ")";
ExecuteQuery(query);
}
@@ -193,7 +201,7 @@ void WriteCoreMetadata(const std::string &key, const std::string &data)
if (!CurCore)
throw CoreException("WritCoreMetadata without a core to write");
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_ns_core_metadata` (nick, name, value) VALUES(" << mysqlpp::quote << CurCore->display << ", " << mysqlpp::quote << key << ", " << mysqlpp::quote << data << ")";
ExecuteQuery(query);
}
@@ -203,7 +211,7 @@ void WriteChannelMetadata(const std::string &key, const std::string &data)
if (!CurChannel)
throw CoreException("WriteChannelMetadata without a channel to write");
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_cs_info_metadata` (channel, name, value) VALUES(" << mysqlpp::quote << CurChannel->name << ", " << mysqlpp::quote << key << ", " << mysqlpp::quote << data << ")";
ExecuteQuery(query);
}
@@ -213,60 +221,53 @@ void WriteBotMetadata(const std::string &key, const std::string &data)
if (!CurBot)
throw CoreException("WriteBotMetadata without a bot to write");
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_bs_info_metadata` (botname, name, value) VALUES(" << mysqlpp::quote << CurBot->nick << ", " << mysqlpp::quote << key << ", " << mysqlpp::quote << data << ")";
ExecuteQuery(query);
}
static void SaveDatabases()
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
- query << "TRUNCATE TABLE `anope_ns_core`";
- ExecuteQuery(query);
query << "TRUNCATE TABLE `anope_ns_alias`";
ExecuteQuery(query);
- for (int i = 0; i < 1024; ++i)
+ for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it)
{
- for (NickAlias *na = nalists[i]; na; na = na->next)
- {
- me->OnNickRegister(na);
- }
+ me->OnNickRegister(it->second);
}
- query << "TRUNCATE TABLE `anope_ns_access`";
+ query << "TRUNCATE TABLE `anope_ns_core`";
ExecuteQuery(query);
query << "TRUNCATE TABLE `anope_ms_info`";
ExecuteQuery(query);
-
- for (int i = 0; i < 1024; ++i)
+
+ for (nickcore_map::const_iterator nit = NickCoreList.begin(); nit != NickCoreList.end(); ++nit)
{
- for (NickCore *nc = nclists[i]; nc; nc = nc->next)
+ NickCore *nc = nit->second;
+
+ for (std::vector<std::string>::iterator it = nc->access.begin(); it != nc->access.end(); ++it)
{
- for (std::vector<std::string>::iterator it = nc->access.begin(); it != nc->access.end(); ++it)
- {
- query << "INSERT DELAYED INTO `anope_ns_access` (display, access) VALUES(" << mysqlpp::quote << nc->display << ", " << mysqlpp::quote << *it << ")";
- ExecuteQuery(query);
- }
+ query << "INSERT DELAYED INTO `anope_ns_access` (display, access) VALUES(" << mysqlpp::quote << nc->display << ", " << mysqlpp::quote << *it << ")";
+ ExecuteQuery(query);
+ }
- for (unsigned j = 0; j < nc->memos.memos.size(); ++j)
- {
- Memo *m = nc->memos.memos[j];
+ for (unsigned j = 0; j < nc->memos.memos.size(); ++j)
+ {
+ Memo *m = nc->memos.memos[j];
- me->OnMemoSend(NULL, nc, m);
- }
+ me->OnMemoSend(NULL, nc, m);
}
}
+
query << "TRUNCATE TABLE `anope_bs_core`";
ExecuteQuery(query);
- for (int i = 0; i < 256; ++i)
+
+ for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it)
{
- for (BotInfo *bi = botlists[i]; bi; bi = bi->next)
- {
- me->OnBotCreate(bi);
- }
+ me->OnBotCreate(it->second);
}
query << "TRUNCATE TABLE `anope_cs_info`";
@@ -280,95 +281,86 @@ static void SaveDatabases()
query << "TRUNCATE TABLE `anope_cs_levels`";
ExecuteQuery(query);
- for (int i = 0; i < 256; ++i)
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
{
- for (ChannelInfo *ci = chanlists[i]; ci; ci = ci->next)
- {
- me->OnChanRegistered(ci);
-
- for (unsigned j = 0; j < ci->GetBadWordCount(); ++j)
- {
- BadWord *bw = ci->GetBadWord(j);
+ ChannelInfo *ci = it->second;
+
+ me->OnChanRegistered(ci);
- if (bw->InUse)
- {
- me->OnBadWordAdd(ci, bw);
- }
- }
+ for (unsigned j = 0; j < ci->GetBadWordCount(); ++j)
+ {
+ BadWord *bw = ci->GetBadWord(j);
- for (unsigned j = 0; j < ci->GetAccessCount(); ++j)
- {
- ChanAccess *access = ci->GetAccess(j);
+ me->OnBadWordAdd(ci, bw);
+ }
- if (access->in_use)
- {
- query << "INSERT DELAYED INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES('" << access->level << "', " << mysqlpp::quote << access->nc->display << ", " << mysqlpp::quote << ci->name << ", " << access->last_seen << ", " << mysqlpp::quote << access->creator << ") ON DUPLICATE KEY UPDATE level=VALUES(level), last_seen=VALUES(last_seen), creator=VALUES(creator)";
- ExecuteQuery(query);
- }
- }
+ for (unsigned j = 0; j < ci->GetAccessCount(); ++j)
+ {
+ ChanAccess *access = ci->GetAccess(j);
- for (unsigned j = 0; j < ci->GetAkickCount(); ++j)
- {
- AutoKick *ak = ci->GetAkick(j);
+ query << "INSERT DELAYED INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES('" << access->level << "', " << mysqlpp::quote << access->nc->display << ", " << mysqlpp::quote << ci->name << ", " << access->last_seen << ", " << mysqlpp::quote << access->creator << ") ON DUPLICATE KEY UPDATE level=VALUES(level), last_seen=VALUES(last_seen), creator=VALUES(creator)";
+ ExecuteQuery(query);
+ }
- if (ak->InUse)
- {
- me->OnAkickAdd(ci, ak);
- }
- }
+ for (unsigned j = 0; j < ci->GetAkickCount(); ++j)
+ {
+ AutoKick *ak = ci->GetAkick(j);
- for (int k = 0; k < CA_SIZE; ++k)
- {
- query << "INSERT DELAYED INTO `anope_cs_levels` (channel, position, level) VALUES(" << mysqlpp::quote << ci->name << ", '" << k << "', '" << ci->levels[k] << "') ON DUPLICATE KEY UPDATE position=VALUES(position), level=VALUES(level)";
- ExecuteQuery(query);
- }
+ me->OnAkickAdd(NULL, ci, ak);
+ }
+
+ for (int k = 0; k < CA_SIZE; ++k)
+ {
+ query << "INSERT DELAYED INTO `anope_cs_levels` (channel, position, level) VALUES(" << mysqlpp::quote << ci->name << ", '" << k << "', '" << ci->levels[k] << "') ON DUPLICATE KEY UPDATE position=VALUES(position), level=VALUES(level)";
+ ExecuteQuery(query);
+ }
- for (unsigned j = 0; j < ci->memos.memos.size(); ++j)
- {
- Memo *m = ci->memos.memos[j];
+ for (unsigned j = 0; j < ci->memos.memos.size(); ++j)
+ {
+ Memo *m = ci->memos.memos[j];
- me->OnMemoSend(NULL, ci, m);
- }
+ me->OnMemoSend(NULL, ci, m);
}
}
query << "TRUNCATE TABLE `anope_ns_request`";
ExecuteQuery(query);
- for (int i = 0; i < 1024; i++)
+ for (nickrequest_map::const_iterator it = NickRequestList.begin(); it != NickRequestList.end(); ++it)
{
- for (NickRequest *nr = nrlists[i]; nr; nr = nr->next)
- {
- me->OnMakeNickRequest(nr);
- }
+ me->OnMakeNickRequest(it->second);
}
- for (int i = 0; i < akills.count; ++i)
+ if (SGLine)
{
- Akill *ak = static_cast<Akill *>(akills.list[i]);
-
- me->OnAddAkill(NULL, ak);
+ for (unsigned i = 0; i < SGLine->GetCount(); ++i)
+ {
+ me->OnAddAkill(NULL, SGLine->GetEntry(i));
+ }
}
- for (int i = 0; i < sglines.count; ++i)
+ if (SZLine)
{
- SXLine *x = static_cast<SXLine *>(sglines.list[i]);
-
- me->OnAddSXLine(NULL, x, SX_SGLINE);
+ for (unsigned i = 0; i < SZLine->GetCount(); ++i)
+ {
+ me->OnAddXLine(NULL, SZLine->GetEntry(i), X_SZLINE);
+ }
}
- for (int i = 0; i < sqlines.count; ++i)
+ if (SQLine)
{
- SXLine *x = static_cast<SXLine *>(sqlines.list[i]);
-
- me->OnAddSXLine(NULL, x, SX_SQLINE);
+ for (unsigned i = 0; i < SQLine->GetCount(); ++i)
+ {
+ me->OnAddXLine(NULL, SQLine->GetEntry(i), X_SQLINE);
+ }
}
- for (int i = 0; i < szlines.count; ++i)
+ if (SNLine)
{
- SXLine *x = static_cast<SXLine *>(szlines.list[i]);
-
- me->OnAddSXLine(NULL, x, SX_SZLINE);
+ for (unsigned i = 0; i < SNLine->GetCount(); ++i)
+ {
+ me->OnAddXLine(NULL, SNLine->GetEntry(i), X_SNLINE);
+ }
}
for (int i = 0; i < nexceptions; ++i)
@@ -382,7 +374,7 @@ static void SaveDatabases()
class CommandSyncSQL : public Command
{
public:
- CommandSyncSQL(const std::string &cname) : Command(cname, 0, 0, "operserv/sqlsync")
+ CommandSyncSQL(const ci::string &cname) : Command(cname, 0, 0, "operserv/sqlsync")
{
}
@@ -399,6 +391,11 @@ class CommandSyncSQL : public Command
notice_help(Config.s_OperServ, u, OPER_HELP_SYNC);
return true;
}
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SQLSYNC);
+ }
};
class DBMySQLWrite : public DBMySQL
@@ -410,7 +407,7 @@ class DBMySQLWrite : public DBMySQL
ModuleManager::Attach(I_OnServerConnect, this);
- this->AddCommand(OPERSERV, new CommandSyncSQL("SQLSYNC"));
+ this->AddCommand(OperServ, new CommandSyncSQL("SQLSYNC"));
if (uplink_server)
OnServerConnect();
@@ -441,67 +438,51 @@ class DBMySQLWrite : public DBMySQL
/* MemoServ */
I_OnMemoSend, I_OnMemoDel,
/* OperServ */
- I_OnOperServHelp, I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel,
- I_OnAddSXLine, I_OnDelSXLine
+ I_OnAddAkill, I_OnDelAkill, I_OnExceptionAdd, I_OnExceptionDel,
+ I_OnAddXLine, I_OnDelXLine
};
- ModuleManager::Attach(i, this, 40);
- }
-
- void OnOperServHelp(User *u)
- {
- notice_lang(Config.s_OperServ, u, OPER_HELP_CMD_SQLSYNC);
+ ModuleManager::Attach(i, this, 39);
}
EventReturn OnSaveDatabase()
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "TRUNCATE TABLE `anope_os_core`";
ExecuteQuery(query);
query << "INSERT DELAYED INTO `anope_os_core` (maxusercnt, maxusertime, akills_count, sglines_count, sqlines_count, szlines_count) VALUES(";
- query << maxusercnt << ", " << maxusertime << ", " << akills.count << ", " << sqlines.count << ", " << sglines.count << ", " << szlines.count << ")";
+ query << maxusercnt << ", " << maxusertime << ", " << (SGLine ? SGLine->GetCount() : 0) << ", " << (SQLine ? SQLine->GetCount() : 0) << ", " << (SNLine ? SNLine->GetCount() : 0) << ", " << (SZLine ? SZLine->GetCount() : 0) << ")";
ExecuteQuery(query);
- for (int i = 0; i < 1024; ++i)
+ for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it)
{
- for (NickCore *nc = nclists[i]; nc; nc = nc->next)
- {
- CurCore = nc;
- FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteCoreMetadata, nc));
- }
+ CurCore = it->second;
+ FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteCoreMetadata, CurCore));
}
- for (int i = 0; i < 1024; ++i)
+ for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it)
{
- for (NickAlias *na = nalists[i]; na; na = na->next)
- {
- CurNick = na;
- FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteNickMetadata, na));
- }
+ CurNick = it->second;
+ FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteNickMetadata, CurNick));
}
- for (int i = 0; i < 256; ++i)
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
{
- for (ChannelInfo *ci = chanlists[i]; ci; ci = ci->next)
- {
- CurChannel = ci;
- FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteChannelMetadata, ci));
- }
+ CurChannel = it->second;
+ FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteChannelMetadata, CurChannel));
}
- for (int i = 0; i < 256; ++i)
+ for (botinfo_map::const_iterator it = BotListByNick.begin(); it != BotListByNick.end(); ++it)
{
- for (BotInfo *bi = botlists[i]; bi; bi = bi->next)
- {
- CurBot = bi;
- FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteBotMetadata, bi));
- /* This is for the core bots, bots added by users are already handled by an event */
- query << "INSERT DELAYED INTO `anope_bs_core` (nick, user, host, rname, flags, created, chancount) VALUES(";
- query << mysqlpp::quote << bi->nick << ", " << mysqlpp::quote << bi->user << ", " << mysqlpp::quote << bi->host;
- query << ", " << mysqlpp::quote << bi->real << ", '" << GetBotServFlags(bi) << "', " << bi->created << ", ";
- query << bi->chancount << ") ON DUPLICATE KEY UPDATE nick=VALUES(nick), user=VALUES(user), host=VALUES(host), rname=VALUES(rname), flags=VALUES(flags), created=VALUES(created), chancount=VALUES(created)";
- ExecuteQuery(query);
- }
+ CurBot = it->second;
+ FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteBotMetadata, CurBot));
+
+ /* This is for the core bots, bots added by users are already handled by an event */
+ query << "INSERT DELAYED INTO `anope_bs_core` (nick, user, host, rname, flags, created, chancount) VALUES(";
+ query << mysqlpp::quote << CurBot->nick << ", " << mysqlpp::quote << CurBot->user << ", " << mysqlpp::quote << CurBot->host;
+ query << ", " << mysqlpp::quote << CurBot->real << ", '" << GetBotServFlags(CurBot) << "', " << CurBot->created << ", ";
+ query << CurBot->chancount << ") ON DUPLICATE KEY UPDATE nick=VALUES(nick), user=VALUES(user), host=VALUES(host), rname=VALUES(rname), flags=VALUES(flags), created=VALUES(created), chancount=VALUES(created)";
+ ExecuteQuery(query);
}
FOREACH_MOD(I_OnDatabaseWrite, OnDatabaseWrite(Write));
@@ -511,14 +492,14 @@ class DBMySQLWrite : public DBMySQL
void OnPostCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> &params)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
if (service == Config.s_NickServ)
{
if (u->Account() && ((command == "SET" && !params.empty()) || (command == "SASET" && u->Account()->HasCommand("nickserv/saset") && params.size() > 1)))
{
ci::string cmd = (command == "SET" ? params[0] : params[1]);
- NickCore *nc = (command == "SET" ? u->Account() : findcore(params[0].c_str()));
+ NickCore *nc = (command == "SET" ? u->Account() : findcore(params[0]));
if (!nc)
return;
if (cmd == "PASSWORD" && params.size() > 1)
@@ -562,7 +543,7 @@ class DBMySQLWrite : public DBMySQL
{
if (command == "SET" && u->Account() && params.size() > 1)
{
- ChannelInfo *ci = cs_findchan(params[0].c_str());
+ ChannelInfo *ci = cs_findchan(params[0]);
if (!ci)
return;
if (!u->Account()->HasPriv("chanserv/set") && check_access(u, ci, CA_SET))
@@ -622,7 +603,7 @@ class DBMySQLWrite : public DBMySQL
{
if (command == "KICK" && params.size() > 2)
{
- ChannelInfo *ci = cs_findchan(params[0].c_str());
+ ChannelInfo *ci = cs_findchan(params[0]);
if (!ci)
return;
if (!check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration"))
@@ -660,12 +641,12 @@ class DBMySQLWrite : public DBMySQL
}
else if (command == "SET" && params.size() > 2)
{
- ChannelInfo *ci = cs_findchan(params[0].c_str());
+ ChannelInfo *ci = cs_findchan(params[0]);
if (ci && !check_access(u, ci, CA_SET) && !u->Account()->HasPriv("botserv/administration"))
return;
BotInfo *bi = NULL;
if (!ci)
- bi = findbot(params[0].c_str());
+ bi = findbot(params[0]);
if (bi && params[1] == "PRIVATE" && u->Account()->HasPriv("botserv/set/private"))
{
query << "UPDATE `anope_bs_core` SET `flags` = '" << GetBotServFlags(bi) << "' WHERE `nick` = " << mysqlpp::quote << bi->nick;
@@ -685,28 +666,28 @@ class DBMySQLWrite : public DBMySQL
void OnNickAddAccess(NickCore *nc, const std::string &entry)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_ns_access` (display, access) VALUES(" << mysqlpp::quote << nc->display << ", " << mysqlpp::quote << entry << ")";
ExecuteQuery(query);
}
void OnNickEraseAccess(NickCore *nc, const std::string &entry)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_ns_access` WHERE `display` = " << mysqlpp::quote << nc->display << " AND `access` = " << mysqlpp::quote << entry;
ExecuteQuery(query);
}
void OnNickClearAccess(NickCore *nc)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_ns_access` WHERE `display` = " << mysqlpp::quote << nc->display;
ExecuteQuery(query);
}
void OnDelCore(NickCore *nc)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_cs_access` WHERE `display` = " << mysqlpp::quote << nc->display;
ExecuteQuery(query);
query << "DELETE FROM `anope_cs_akick` WHERE `mask` = " << mysqlpp::quote << nc->display;
@@ -724,7 +705,7 @@ class DBMySQLWrite : public DBMySQL
void OnNickForbidden(NickAlias *na)
{
std::string flags = BuildFlagsList(na);
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "UPDATE `anope_ns_alias` SET `flags` = '" << (!flags.empty() ? flags : "") << "' WHERE `nick` = " << mysqlpp::quote << na->nick;
ExecuteQuery(query);
}
@@ -736,7 +717,7 @@ class DBMySQLWrite : public DBMySQL
void OnMakeNickRequest(NickRequest *nr)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_ns_request` (nick, passcode, password, email, requested) VALUES(" << mysqlpp::quote << nr->nick << ", ";
query << mysqlpp::quote << nr->passcode << ", " << mysqlpp::quote << nr->password << ", " << mysqlpp::quote << nr->email << ", '";
query << nr->requested << "')";
@@ -745,7 +726,7 @@ class DBMySQLWrite : public DBMySQL
void OnDelNickRequest(NickRequest *nr)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_ns_request` WHERE `nick` = " << mysqlpp::quote << nr->nick;
ExecuteQuery(query);
}
@@ -753,7 +734,7 @@ class DBMySQLWrite : public DBMySQL
void OnNickRegister(NickAlias *na)
{
std::string flags = BuildFlagsList(na);
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_ns_alias` (nick, last_quit, last_realname, last_usermask, time_registered, last_seen, flags, display) VALUES(";
query << mysqlpp::quote << na->nick << ", " << mysqlpp::quote << (na->last_quit ? na->last_quit : "") << ", ";
query << mysqlpp::quote << (na->last_realname ? na->last_realname : "") << ", ";
@@ -776,7 +757,7 @@ class DBMySQLWrite : public DBMySQL
void OnChangeCoreDisplay(NickCore *nc, const std::string &newdisplay)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "UPDATE `anope_ns_core` SET `display` = " << mysqlpp::quote << newdisplay << " WHERE `display` = " << mysqlpp::quote << nc->display;
ExecuteQuery(query);
query << "UPDATE `anope_ns_alias` SET `display` = " << mysqlpp::quote << newdisplay << " WHERE `display` = " << mysqlpp::quote << nc->display;
@@ -795,42 +776,42 @@ class DBMySQLWrite : public DBMySQL
void OnNickSuspend(NickAlias *na)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "UPDATE `anope_ns_core` SET `flags` = '" << BuildFlagsList(na->nc) << "' WHERE `display` = " << mysqlpp::quote << na->nc->display;
ExecuteQuery(query);
}
void OnAccessAdd(ChannelInfo *ci, User *u, NickAlias *na, int level)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" << level << ", " << mysqlpp::quote << na->nc->display << ", " << mysqlpp::quote << ci->name << ", " << time(NULL) << ", " << mysqlpp::quote << u->nick << ")";
ExecuteQuery(query);
}
void OnAccessDel(ChannelInfo *ci, User *u, NickCore *nc)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_cs_access` WHERE `display` = " << mysqlpp::quote << nc->display << " AND `channel` = " << mysqlpp::quote << ci->name;
ExecuteQuery(query);
}
void OnAccessChange(ChannelInfo *ci, User *u, NickAlias *na, int level)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_cs_access` (level, display, channel, last_seen, creator) VALUES (" << level << ", " << mysqlpp::quote << na->nc->display << ", " << mysqlpp::quote << ci->name << ", " << time(NULL) << ", " << mysqlpp::quote << u->nick << ") ON DUPLICATE KEY UPDATE level=VALUES(level), display=VALUES(display), channel=VALUES(channel), last_seen=VALUES(last_seen), creator=VALUES(creator)";
ExecuteQuery(query);
}
void OnAccessClear(ChannelInfo *ci, User *u)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_cs_access` WHERE `channel` = " << mysqlpp::quote << ci->name;
ExecuteQuery(query);
}
void OnLevelChange(User *u, ChannelInfo *ci, int pos, int what)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
if (pos >= 0)
{
@@ -849,7 +830,7 @@ class DBMySQLWrite : public DBMySQL
void OnChanForbidden(ChannelInfo *ci)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_cs_info` (name, time_registered, last_used, flags, forbidby, forbidreason) VALUES (";
query << mysqlpp::quote << ci->name << ", " << ci->time_registered << ", " << ci->last_used << ", '" << BuildFlagsList(ci) << "', " << mysqlpp::quote << ci->forbidby << ", " << mysqlpp::quote << ci->forbidreason << ")";
ExecuteQuery(query);
@@ -857,7 +838,7 @@ class DBMySQLWrite : public DBMySQL
void OnDelChan(ChannelInfo *ci)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_cs_access` WHERE `channel` = " << mysqlpp::quote << ci->name;
ExecuteQuery(query);
query << "DELETE FROM `anope_cs_akick` WHERE `channel` = " << mysqlpp::quote << ci->name;
@@ -874,7 +855,7 @@ class DBMySQLWrite : public DBMySQL
void OnChanRegistered(ChannelInfo *ci)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
std::string flags = BuildFlagsList(ci), mlockon = GetMLockOn(ci), mlockoff = GetMLockOff(ci), mlockparams = GetMLockParams(ci);
query << "INSERT DELAYED INTO `anope_cs_info` (name, founder, successor, descr, url, email, time_registered, last_used, last_topic, last_topic_setter, last_topic_time, flags, forbidby, forbidreason, bantype, mlock_on, mlock_off, mlock_params, entry_message, memomax, botnick, botflags, capsmin, capspercent, floodlines, floodsecs, repeattimes) VALUES(";
query << mysqlpp::quote << ci->name << ", " << mysqlpp::quote << (ci->founder ? ci->founder->display : "") << ", ";
@@ -895,7 +876,7 @@ class DBMySQLWrite : public DBMySQL
void OnChanSuspend(ChannelInfo *ci)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "UPDATE `anope_cs_info` SET `flags` = '" << BuildFlagsList(ci) << "' WHERE `name` = " << mysqlpp::quote << ci->name;
ExecuteQuery(query);
query << "UPDATE `anope_cs_info` SET `forbidby` = " << mysqlpp::quote << ci->forbidby << " WHERE `name` = " << mysqlpp::quote << ci->name;
@@ -906,7 +887,7 @@ class DBMySQLWrite : public DBMySQL
void OnAkickAdd(ChannelInfo *ci, AutoKick *ak)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_cs_akick` (channel, flags, mask, reason, creator, created, last_used) VALUES(";
query << mysqlpp::quote << ci->name << ", '";
if (ak->HasFlag(AK_ISNICK))
@@ -921,14 +902,14 @@ class DBMySQLWrite : public DBMySQL
void OnAkickDel(ChannelInfo *ci, AutoKick *ak)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_cs_akick` WHERE `channel`= " << mysqlpp::quote << ci->name << " AND `mask` = " << mysqlpp::quote << (ak->HasFlag(AK_ISNICK) ? ak->nc->display : ak->mask);
ExecuteQuery(query);
}
void OnBotCreate(BotInfo *bi)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_bs_core` (nick, user, host, rname, flags, created, chancount) VALUES(";
query << mysqlpp::quote << bi->nick << ", " << mysqlpp::quote << bi->user << ", " << mysqlpp::quote << bi->host << ", ";
query << mysqlpp::quote << bi->real << ", '" << GetBotServFlags(bi) << "', " << bi->created << ", " << bi->chancount << ") ";
@@ -943,7 +924,7 @@ class DBMySQLWrite : public DBMySQL
void OnBotDelete(BotInfo *bi)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_bs_core` WHERE `nick` = " << mysqlpp::quote << bi->nick;
ExecuteQuery(query);
query << "UPDATE `anope_cs_info` SET `botnick` = '' WHERE `botnick` = " << mysqlpp::quote << bi->nick;
@@ -952,7 +933,7 @@ class DBMySQLWrite : public DBMySQL
EventReturn OnBotAssign(User *sender, ChannelInfo *ci, BotInfo *bi)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "UPDATE `anope_cs_info` SET `botnick` = " << mysqlpp::quote << bi->nick << " WHERE `name` = " << mysqlpp::quote << ci->name;
ExecuteQuery(query);
return EVENT_CONTINUE;
@@ -960,7 +941,7 @@ class DBMySQLWrite : public DBMySQL
EventReturn OnBotUnAssign(User *sender, ChannelInfo *ci)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "UPDATE `anope_cs_info` SET `botnick` = '' WHERE `name` = " << mysqlpp::quote << ci->name;
ExecuteQuery(query);
return EVENT_CONTINUE;
@@ -968,7 +949,7 @@ class DBMySQLWrite : public DBMySQL
void OnBadWordAdd(ChannelInfo *ci, BadWord *bw)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_bs_badwords` (channel, word, type) VALUES(" << mysqlpp::quote << ci->name << ", " << mysqlpp::quote << bw->word << ", '";
switch (bw->type)
{
@@ -990,7 +971,7 @@ class DBMySQLWrite : public DBMySQL
void OnBadWordDel(ChannelInfo *ci, BadWord *bw)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_bs_badwords` WHERE `channel` = " << mysqlpp::quote << ci->name << " AND `word` = " << mysqlpp::quote << bw->word << " AND `type` = '";
switch (bw->type)
{
@@ -1012,7 +993,7 @@ class DBMySQLWrite : public DBMySQL
void OnMemoSend(User *, NickCore *nc, Memo *m)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_ms_info` (receiver, number, flags, time, sender, text, serv) VALUES(";
query << mysqlpp::quote << nc->display << ", " << m->number << ", '" << BuildFlagsList(m) << "', " << m->time << ", ";
query << mysqlpp::quote << m->sender << ", " << mysqlpp::quote << m->text << ", 'NICK')";
@@ -1021,7 +1002,7 @@ class DBMySQLWrite : public DBMySQL
void OnMemoSend(User *, ChannelInfo *ci, Memo *m)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_ms_info` (receiver, number, flags, time, sender, text, serv) VALUES(";
query << mysqlpp::quote << ci->name << ", " << m->number << ", '" << BuildFlagsList(m) << "', " << m->time << ", ";
query << mysqlpp::quote << m->sender << ", " << mysqlpp::quote << m->text << ", 'CHAN')";
@@ -1030,7 +1011,7 @@ class DBMySQLWrite : public DBMySQL
void OnMemoDel(NickCore *nc, MemoInfo *mi, int number)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
if (number)
query << "DELETE FROM `anope_ms_info` WHERE `receiver` = " << mysqlpp::quote << nc->display << " AND `number` = " << number;
else
@@ -1040,7 +1021,7 @@ class DBMySQLWrite : public DBMySQL
void OnMemoDel(ChannelInfo *ci, MemoInfo *mi, int number)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
if (number)
query << "DELETE FROM `anope_ms_info` WHERE `receiver` = " << mysqlpp::quote << ci->name << " AND `number` = " << number;
else
@@ -1048,21 +1029,21 @@ class DBMySQLWrite : public DBMySQL
ExecuteQuery(query);
}
- EventReturn OnAddAkill(User *, Akill *ak)
+ EventReturn OnAddAkill(User *, XLine *ak)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_os_akills` (user, host, xby, reason, seton, expire) VALUES(";
- query << mysqlpp::quote << ak->user << ", " << mysqlpp::quote << ak->host << ", " << mysqlpp::quote << ak->by;
- query << ", " << mysqlpp::quote << ak->reason << ", " << ak->seton << ", " << ak->expires << ")";
+ query << mysqlpp::quote << ak->GetUser().c_str() << ", " << mysqlpp::quote << ak->GetHost().c_str() << ", " << mysqlpp::quote << ak->By.c_str();
+ query << ", " << mysqlpp::quote << ak->Reason << ", " << ak->Created << ", " << ak->Expires << ")";
ExecuteQuery(query);
return EVENT_CONTINUE;
}
- void OnDelAkill(User *, Akill *ak)
+ void OnDelAkill(User *, XLine *ak)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
if (ak)
- query << "DELETE FROM `anope_os_akills` WHERE `host` = " << mysqlpp::quote << ak->host;
+ query << "DELETE FROM `anope_os_akills` WHERE `host` = " << mysqlpp::quote << ak->GetHost().c_str();
else
query << "TRUNCATE TABLE `anope_os_akills`";
ExecuteQuery(query);
@@ -1070,7 +1051,7 @@ class DBMySQLWrite : public DBMySQL
EventReturn OnExceptionAdd(User *, Exception *ex)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_os_exceptions` (mask, slimit, who, reason, time, expires) VALUES(";
query << mysqlpp::quote << ex->mask << ", " << ex->limit << ", " << mysqlpp::quote << ex->who << ", ";
query << mysqlpp::quote << ex->reason << ", " << ex->time << ", " << ex->expires << ")";
@@ -1080,32 +1061,32 @@ class DBMySQLWrite : public DBMySQL
void OnExceptionDel(User *, Exception *ex)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "DELETE FROM `anope_os_exceptions` WHERE `mask` = " << mysqlpp::quote << ex->mask;
ExecuteQuery(query);
}
- EventReturn OnAddSXLine(User *, SXLine *sx, SXLineType Type)
+ EventReturn OnAddXLine(User *, XLine *x, XLineType Type)
{
- mysqlpp::Query query(Me->Con);
+ mysqlpp::Query query(me->Con);
query << "INSERT DELAYED INTO `anope_os_sxlines` (type, mask, xby, reason, seton, expire) VALUES('";
- query << (Type == SX_SGLINE ? "SGLINE" : (Type == SX_SQLINE ? "SQLINE" : "SZLINE")) << "', ";
- query << mysqlpp::quote << sx->mask << ", " << mysqlpp::quote << sx->by << ", " << mysqlpp::quote << sx->reason;
- query << ", " << sx->seton << ", " << sx->expires << ")";
+ query << (Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) << "', ";
+ query << mysqlpp::quote << x->Mask.c_str() << ", " << mysqlpp::quote << x->By.c_str() << ", " << mysqlpp::quote << x->Reason;
+ query << ", " << x->Created << ", " << x->Expires << ")";
ExecuteQuery(query);
return EVENT_CONTINUE;
}
- void OnDelSXLine(User *, SXLine *sx, SXLineType Type)
+ void OnDelXLine(User *, XLine *x, XLineType Type)
{
- mysqlpp::Query query(Me->Con);
- if (sx)
+ mysqlpp::Query query(me->Con);
+ if (x)
{
- query << "DELETE FROM `anope_os_sxlines` WHERE `mask` = " << mysqlpp::quote << sx->mask << " AND `type` = '";
- query << (Type == SX_SGLINE ? "SGLINE" : (Type == SX_SQLINE ? "SQLINE" : "SZLINE")) << "'";
+ query << "DELETE FROM `anope_os_xlines` WHERE `mask` = " << mysqlpp::quote << x->Mask.c_str() << " AND `type` = '";
+ query << (Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) << "'";
}
else
- query << "DELETE FROM `anope_os_sxlines` WHERE `type` = '" << (Type == SX_SGLINE ? "SGLINE" : (Type == SX_SQLINE ? "SQLINE" : "SZLINE")) << "'";
+ query << "DELETE FROM `anope_os_xlines` WHERE `type` = '" << (Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) << "'";
ExecuteQuery(query);
}
};
diff --git a/src/modules/ns_maxemail.c b/src/modules/ns_maxemail.cpp
index e98dc62d7..2399dba68 100644
--- a/src/modules/ns_maxemail.c
+++ b/src/modules/ns_maxemail.cpp
@@ -127,20 +127,17 @@ class NSMaxEmail : public Module
int count_email_in_use(const char *email, User * u)
{
- NickCore *nc;
- int i;
int count = 0;
if (!email)
return 0;
- for (i = 0; i < 1024; ++i)
+ for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it)
{
- for (nc = nclists[i]; nc; nc = nc->next)
- {
- if (!(u->Account() && u->Account() == nc) && nc->email && !stricmp(nc->email, email))
- ++count;
- }
+ NickCore *nc = it->second;
+
+ if (!(u->Account() && u->Account() == nc) && nc->email && !stricmp(nc->email, email))
+ ++count;
}
return count;
diff --git a/src/modules/os_info.c b/src/modules/os_info.cpp
index 87d8ea298..38d9c99c5 100644
--- a/src/modules/os_info.c
+++ b/src/modules/os_info.cpp
@@ -116,6 +116,11 @@ class CommandNSOInfo : public Command
{
me->NoticeLang(Config.s_NickServ, u, OINFO_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ me->NoticeLang(Config.s_NickServ, u, OINFO_HELP_CMD);
+ }
};
class CommandCSOInfo : public Command
@@ -180,6 +185,11 @@ class CommandCSOInfo : public Command
{
me->NoticeLang(Config.s_ChanServ, u, OCINFO_SYNTAX);
}
+
+ void OnServHelp(User *u)
+ {
+ me->NoticeLang(Config.s_ChanServ, u, OCINFO_HELP_CMD);
+ }
};
class OSInfo : public Module
@@ -193,8 +203,8 @@ class OSInfo : public Module
this->SetVersion(VERSION);
this->SetType(SUPPORTED);
- this->AddCommand(NICKSERV, new CommandNSOInfo());
- this->AddCommand(CHANSERV, new CommandCSOInfo());
+ this->AddCommand(NickServ, new CommandNSOInfo());
+ this->AddCommand(ChanServ, new CommandCSOInfo());
const char* langtable_en_us[] = {
/* OINFO_SYNTAX */
@@ -409,83 +419,47 @@ class OSInfo : public Module
this->InsertLanguage(LANG_RU, LANG_NUM_STRINGS, langtable_ru);
this->InsertLanguage(LANG_IT, LANG_NUM_STRINGS, langtable_it);
- Implementation i[] = { I_OnNickServHelp, I_OnChanServHelp, I_OnPostCommand, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata };
- ModuleManager::Attach(i, this, 5);
+ Implementation i[] = { I_OnNickInfo, I_OnChanInfo, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata };
+ ModuleManager::Attach(i, this, 4);
}
~OSInfo()
{
- int i;
- NickCore *nc;
- ChannelInfo *ci;
-
OnSaveDatabase();
- for (i = 0; i < 1024; ++i)
+ for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it)
{
- /* Remove the nick Cores */
- for (nc = nclists[i]; nc; nc = nc->next)
- {
- nc->Shrink("os_info");
- }
+ NickCore *nc = it->second;
+
+ nc->Shrink("os_info");
}
- for (i = 0; i < 256; ++i)
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
{
- for (ci = chanlists[i]; ci; ci = ci->next)
- {
- ci->Shrink("os_info");
- }
+ ChannelInfo *ci = it->second;
+
+ ci->Shrink("os_info");
}
}
- void OnPostCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> &params)
+ void OnNickInfo(User *u, NickAlias *na, bool)
{
- if (command == "INFO")
+ if (is_oper(u))
{
- if (service == Config.s_NickServ)
- {
- const char *nick = params[0].c_str();
- NickAlias *na = NULL;
-
- if (is_oper(u)) /* Only show our goodies to opers */
- {
- if ((na = findnick(nick))) /* ok we've found the user */
- {
- /* If we have any info on this user */
- char *c;
- if (na->nc->GetExtArray("os_info", c))
- u->SendMessage(Config.s_NickServ, " OperInfo: %s", c);
- }
- }
- }
- else if (service == Config.s_ChanServ)
- {
- const char *chan = params[0].c_str();
- ChannelInfo *ci = NULL;
-
- if (is_oper(u)) /* Only show our goodies to opers */
- {
- if ((ci = cs_findchan(chan)))
- {
- /* If we have any info on this channel */
- char *c;
- if (ci->GetExtArray("os_info", c))
- u->SendMessage(Config.s_ChanServ, " OperInfo: %s", c);
- }
- }
- }
+ char *c;
+ if (na->nc->GetExtArray("os_info", c))
+ u->SendMessage(Config.s_NickServ, " OperInfo: %s", c);
}
}
- void OnNickServHelp(User *u)
- {
- this->NoticeLang(Config.s_NickServ, u, OINFO_HELP_CMD);
- }
-
- void OnChanServHelp(User *u)
+ void OnChanInfo(User *u, ChannelInfo *ci, bool)
{
- this->NoticeLang(Config.s_ChanServ, u, OCINFO_HELP_CMD);
+ if (is_oper(u))
+ {
+ char *c;
+ if (ci->GetExtArray("os_info", c))
+ u->SendMessage(Config.s_ChanServ, " OperInfo: %s", c);
+ }
}
void OnDatabaseWriteMetadata(void (*WriteMetadata)(const std::string &, const std::string &), NickCore *nc)
diff --git a/src/modules/ssl/m_ssl.cpp b/src/modules/ssl/m_ssl.cpp
new file mode 100644
index 000000000..be3e5da1f
--- /dev/null
+++ b/src/modules/ssl/m_ssl.cpp
@@ -0,0 +1,148 @@
+/* RequiredLibraries: ssl,crypt */
+
+#include "module.h"
+
+#include <openssl/bio.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+
+#define CERTFILE "anope.cert"
+#define KEYFILE "anope.key"
+
+static SSL_CTX *ctx;
+
+class SSLSocket : public Socket
+{
+ private:
+ SSL *sslsock;
+
+ int RecvInternal(char *buf, size_t sz) const
+ {
+ return SSL_read(sslsock, buf, sz);
+ }
+
+ int SendInternal(const std::string &buf) const
+ {
+ return SSL_write(sslsock, buf.c_str(), buf.size());
+ }
+ public:
+ SSLSocket(const std::string &nTargetHost, int nPort, const std::string &nBindHost = "", bool nIPv6 = false) : Socket(nTargetHost, nPort, nBindHost, nIPv6)
+ {
+ sslsock = SSL_new(ctx);
+
+ if (!sslsock)
+ throw CoreException("Unable to initialize SSL socket");
+
+ SSL_set_connect_state(sslsock);
+ SSL_set_fd(sslsock, Sock);
+ SSL_connect(sslsock);
+
+ UplinkSock = this;
+ }
+
+ ~SSLSocket()
+ {
+ SSL_shutdown(sslsock);
+ SSL_free(sslsock);
+
+ UplinkSock = NULL;
+ }
+
+ bool Read(const std::string &buf)
+ {
+ process(buf);
+ return true;
+ }
+};
+
+class SSLModule : public Module
+{
+ public:
+ SSLModule(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(SUPPORTED);
+ this->SetPermanent(true);
+
+ SSL_load_error_strings();
+ SSLeay_add_ssl_algorithms();
+
+ ctx = SSL_CTX_new(SSLv23_client_method());
+
+ if (!ctx)
+ {
+ throw ModuleException("Error initializing SSL CTX");
+ }
+
+ if (IsFile(CERTFILE))
+ {
+ if (!SSL_CTX_use_certificate_file(ctx, CERTFILE, SSL_FILETYPE_PEM))
+ {
+ SSL_CTX_free(ctx);
+ throw ModuleException("Error loading certificate");
+ }
+ }
+ else
+ {
+ Alog() << "m_ssl: No certificate file found";
+ }
+
+ if (IsFile(KEYFILE))
+ {
+ if (!SSL_CTX_use_PrivateKey_file(ctx, KEYFILE, SSL_FILETYPE_PEM))
+ {
+ SSL_CTX_free(ctx);
+ throw ModuleException("Error loading private key");
+ }
+ }
+ else
+ {
+ if (IsFile(CERTFILE))
+ {
+ SSL_CTX_free(ctx);
+ throw ModuleException("Error loading private key - file not found");
+ }
+ else
+ {
+ Alog() << "m_ssl: No private key found";
+ }
+ }
+
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
+ SSL_CTX_set_options(ctx, SSL_OP_TLS_ROLLBACK_BUG | SSL_OP_ALL);
+
+ ModuleManager::Attach(I_OnPreServerConnect, this);
+ }
+
+ ~SSLModule()
+ {
+ SSL_CTX_free(ctx);
+ }
+
+ EventReturn OnPreServerConnect(Uplink *u, int Number)
+ {
+ ConfigReader config;
+
+ if (config.ReadFlag("uplink", "ssl", "no", Number - 1))
+ {
+ try
+ {
+ new SSLSocket(u->host, u->port, Config.LocalHost ? Config.LocalHost : "", u->ipv6);
+ Alog() << "Connected to Server " << Number << " (" << u->host << ":" << u->port << ")";
+ }
+ catch (SocketException& ex)
+ {
+ Alog() << "Unable to connect with SSL to server" << Number << " (" << u->host << ":" << u->port << "), " << ex.GetReason();
+ }
+
+ return EVENT_ALLOW;
+ }
+
+ return EVENT_CONTINUE;
+ }
+};
+
+MODULE_INIT(SSLModule)
diff --git a/src/nickalias.cpp b/src/nickalias.cpp
index afd40ccd7..a196145b9 100644
--- a/src/nickalias.cpp
+++ b/src/nickalias.cpp
@@ -1,31 +1,24 @@
#include "services.h"
#include "modules.h"
-#define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31))
-
NickRequest::NickRequest(const std::string &nickname)
{
if (nickname.empty())
throw CoreException("Empty nick passed to NickRequest constructor");
- next = prev = NULL;
email = NULL;
requested = lastmail = 0;
this->nick = sstrdup(nickname.c_str());
- insert_requestnick(this); // till this is destroyed / redone in STL
+
+ NickRequestList[this->nick] = this;
}
NickRequest::~NickRequest()
{
FOREACH_MOD(I_OnDelNickRequest, OnDelNickRequest(this));
- if (this->next)
- this->next->prev = this->prev;
- if (this->prev)
- this->prev->next = this->next;
- else
- nrlists[HASH(this->nick)] = this->next;
+ NickRequestList.erase(this->nick);
if (this->nick)
delete [] this->nick;
@@ -44,14 +37,14 @@ NickAlias::NickAlias(const std::string &nickname, NickCore *nickcore)
else if (!nickcore)
throw CoreException("Empty nickcore passed to NickAlias constructor");
- next = prev = NULL;
nick = last_quit = last_realname = last_usermask = NULL;
time_registered = last_seen = 0;
this->nick = sstrdup(nickname.c_str());
this->nc = nickcore;
- slist_add(&nc->aliases, this);
- alpha_insert_alias(this);
+ nc->aliases.push_back(this);
+
+ NickAliasList[this->nick] = this;
for (std::list<std::pair<std::string, std::string> >::iterator it = Config.Opers.begin(); it != Config.Opers.end(); it++)
{
@@ -95,8 +88,12 @@ NickAlias::~NickAlias()
if (this->nc)
{
/* Next: see if our core is still useful. */
- slist_remove(&this->nc->aliases, this);
- if (this->nc->aliases.count == 0)
+ std::list<NickAlias *>::iterator it = std::find(this->nc->aliases.begin(), this->nc->aliases.end(), this);
+ if (it != this->nc->aliases.end())
+ {
+ nc->aliases.erase(it);
+ }
+ if (this->nc->aliases.empty())
{
delete this->nc;
this->nc = NULL;
@@ -110,12 +107,7 @@ NickAlias::~NickAlias()
}
/* Remove us from the aliases list */
- if (this->next)
- this->next->prev = this->prev;
- if (this->prev)
- this->prev->next = this->next;
- else
- nalists[HASH(this->nick)] = this->next;
+ NickAliasList.erase(this->nick);
delete [] this->nick;
if (this->last_usermask)
diff --git a/src/nickcore.cpp b/src/nickcore.cpp
index 1b01c3d54..cf92b0b3d 100644
--- a/src/nickcore.cpp
+++ b/src/nickcore.cpp
@@ -1,7 +1,5 @@
#include "services.h"
-#include "pseudo.h"
-
-#define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31))
+#include "modules.h"
/** Default constructor
* @param display The display nick
@@ -11,7 +9,6 @@ NickCore::NickCore(const std::string &coredisplay)
if (coredisplay.empty())
throw CoreException("Empty display passed to NickCore constructor");
- next = prev = NULL;
display = email = greet = url = NULL;
ot = NULL;
icq = 0;
@@ -19,13 +16,13 @@ NickCore::NickCore(const std::string &coredisplay)
lastmail = 0;
this->display = sstrdup(coredisplay.c_str());
- slist_init(&this->aliases);
- insert_core(this); // till hashing is redone..
/* Set default nick core flags */
for (size_t t = NI_BEGIN + 1; t != NI_END; ++t)
if (Config.NSDefFlags.HasFlag(static_cast<NickCoreFlag>(t)))
SetFlag(static_cast<NickCoreFlag>(t));
+
+ NickCoreList[this->display] = this;
}
/** Default destructor
@@ -51,12 +48,7 @@ NickCore::~NickCore()
cs_remove_nick(this);
/* Remove the core from the list */
- if (this->next)
- this->next->prev = this->prev;
- if (this->prev)
- this->prev->next = this->next;
- else
- nclists[HASH(this->display)] = this->next;
+ NickCoreList.erase(this->display);
/* Log .. */
Alog() << Config.s_NickServ << ": deleting nickname group " << this->display;
diff --git a/src/nickserv.c b/src/nickserv.cpp
index fc6627109..c14de6ae6 100644
--- a/src/nickserv.c
+++ b/src/nickserv.cpp
@@ -13,15 +13,12 @@
*/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
+#include "language.h"
-/*************************************************************************/
-
-#define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31))
-
-NickAlias *nalists[1024];
-NickCore *nclists[1024];
-NickRequest *nrlists[1024];
+nickalias_map NickAliasList;
+nickcore_map NickCoreList;
+nickrequest_map NickRequestList;
static std::map<std::string, NickServCollide *> NickServCollides;
static std::map<std::string, NickServRelease *> NickServReleases;
@@ -93,24 +90,21 @@ void moduleAddNickServCmds()
void get_aliases_stats(long *nrec, long *memuse)
{
long count = 0, mem = 0;
- int i;
- NickAlias *na;
- for (i = 0; i < 1024; i++)
+ for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end(); ++it)
{
- for (na = nalists[i]; na; na = na->next)
- {
- count++;
- mem += sizeof(*na);
- if (na->nick)
- mem += strlen(na->nick) + 1;
- if (na->last_usermask)
- mem += strlen(na->last_usermask) + 1;
- if (na->last_realname)
- mem += strlen(na->last_realname) + 1;
- if (na->last_quit)
- mem += strlen(na->last_quit) + 1;
- }
+ NickAlias *na = it->second;
+
+ count++;
+ mem += sizeof(*na);
+ if (na->nick)
+ mem += strlen(na->nick) + 1;
+ if (na->last_usermask)
+ mem += strlen(na->last_usermask) + 1;
+ if (na->last_realname)
+ mem += strlen(na->last_realname) + 1;
+ if (na->last_quit)
+ mem += strlen(na->last_quit) + 1;
}
*nrec = count;
*memuse = mem;
@@ -123,40 +117,38 @@ void get_aliases_stats(long *nrec, long *memuse)
void get_core_stats(long *nrec, long *memuse)
{
long count = 0, mem = 0;
- unsigned i, j;
- NickCore *nc;
+ unsigned j;
- for (i = 0; i < 1024; i++)
+ for (nickcore_map::const_iterator it = NickCoreList.begin(); it != NickCoreList.end(); ++it)
{
- for (nc = nclists[i]; nc; nc = nc->next)
+ NickCore *nc = it->second;
+
+ count++;
+ mem += sizeof(*nc);
+
+ if (nc->display)
+ mem += strlen(nc->display) + 1;
+ if (!nc->pass.empty())
+ mem += (nc->pass.capacity() + (2 * sizeof(size_t)) + (2 * sizeof(void*)));
+ if (nc->url)
+ mem += strlen(nc->url) + 1;
+ if (nc->email)
+ mem += strlen(nc->email) + 1;
+ if (nc->greet)
+ mem += strlen(nc->greet) + 1;
+
+ mem += sizeof(std::string) * nc->access.size();
+ for (j = 0; j < nc->access.size(); ++j)
+ mem += nc->GetAccess(j).length() + 1;
+
+ mem += nc->memos.memos.size() * sizeof(Memo);
+ for (j = 0; j < nc->memos.memos.size(); j++)
{
- count++;
- mem += sizeof(*nc);
-
- if (nc->display)
- mem += strlen(nc->display) + 1;
- if (!nc->pass.empty())
- mem += (nc->pass.capacity() + (2 * sizeof(size_t)) + (2 * sizeof(void*)));
- if (nc->url)
- mem += strlen(nc->url) + 1;
- if (nc->email)
- mem += strlen(nc->email) + 1;
- if (nc->greet)
- mem += strlen(nc->greet) + 1;
-
- mem += sizeof(std::string) * nc->access.size();
- for (j = 0; j < nc->access.size(); ++j)
- mem += nc->GetAccess(j).length() + 1;
-
- mem += nc->memos.memos.size() * sizeof(Memo);
- for (j = 0; j < nc->memos.memos.size(); j++)
- {
- if (nc->memos.memos[j]->text)
- mem += strlen(nc->memos.memos[j]->text) + 1;
- }
-
- mem += sizeof(void *) * nc->aliases.count;
+ if (nc->memos.memos[j]->text)
+ mem += strlen(nc->memos.memos[j]->text) + 1;
}
+
+ mem += sizeof(NickAlias *) * nc->aliases.size();
}
*nrec = count;
*memuse = mem;
@@ -176,27 +168,21 @@ void ns_init()
/* Main NickServ routine. */
-void nickserv(User * u, char *buf)
+void nickserv(User *u, const std::string &buf)
{
- const char *cmd, *s;
-
- cmd = strtok(buf, " ");
-
- if (!cmd)
- {
+ if (!u || buf.empty())
return;
- }
- else if (stricmp(cmd, "\1PING") == 0)
+
+ if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1')
{
- if (!(s = strtok(NULL, "")))
- {
- s = "";
- }
- ircdproto->SendCTCP(findbot(Config.s_NickServ), u->nick.c_str(), "PING %s", s);
+ std::string command = buf;
+ command.erase(command.begin());
+ command.erase(command.end());
+ ircdproto->SendCTCP(NickServ, u->nick.c_str(), "%s", command.c_str());
}
else
{
- mod_run_cmd(Config.s_NickServ, u, NICKSERV, cmd);
+ mod_run_cmd(NickServ, u, buf);
}
}
@@ -216,7 +202,7 @@ int validate_user(User * u)
NickAlias *na;
NickRequest *nr;
- if ((nr = findrequestnick(u->nick.c_str())))
+ if ((nr = findrequestnick(u->nick)))
{
notice_lang(Config.s_NickServ, u, NICK_IS_PREREG);
return 0;
@@ -293,138 +279,111 @@ int validate_user(User * u)
void expire_nicks()
{
- int i;
- NickAlias *na, *next;
time_t now = time(NULL);
- char *tmpnick;
- for (i = 0; i < 1024; i++)
+ for (nickalias_map::const_iterator it = NickAliasList.begin(); it != NickAliasList.end();)
{
- for (na = nalists[i]; na; na = next)
+ NickAlias *na = it->second;
+ ++it;
+
+ User *u = finduser(na->nick);
+ if (u && (na->nc->HasFlag(NI_SECURE) ? u->IsIdentified() : u->IsRecognized()))
{
- next = na->next;
+ Alog(LOG_DEBUG_2) << "NickServ: updating last seen time for " << na->nick;
+ na->last_seen = now;
+ continue;
+ }
- User *u = finduser(na->nick);
- if (u && (na->nc->HasFlag(NI_SECURE) ? u->IsIdentified() : u->IsRecognized()))
- {
- Alog(LOG_DEBUG_2) << "NickServ: updating last seen time for " << na->nick;
- na->last_seen = now;
+ if (Config.NSExpire && now - na->last_seen >= Config.NSExpire
+ && !na->HasFlag(NS_FORBIDDEN) && !na->HasFlag(NS_NO_EXPIRE)
+ && !na->nc->HasFlag(NI_SUSPENDED))
+ {
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnPreNickExpire, OnPreNickExpire(na));
+ if (MOD_RESULT == EVENT_STOP)
continue;
- }
-
- if (Config.NSExpire && now - na->last_seen >= Config.NSExpire
- && !na->HasFlag(NS_FORBIDDEN) && !na->HasFlag(NS_NO_EXPIRE)
- && !na->nc->HasFlag(NI_SUSPENDED))
- {
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnPreNickExpire, OnPreNickExpire(na));
- if (MOD_RESULT == EVENT_STOP)
- continue;
- Alog() << "Expiring nickname " << na->nick << " (group: " << na->nc->display << ") (e-mail: "
- << (na->nc->email ? na->nc->email : "none") << ")";
- tmpnick = sstrdup(na->nick);
- delete na;
- FOREACH_MOD(I_OnNickExpire, OnNickExpire(tmpnick));
- delete [] tmpnick;
- }
+ Alog() << "Expiring nickname " << na->nick << " (group: " << na->nc->display << ") (e-mail: "
+ << (na->nc->email ? na->nc->email : "none") << ")";
+ FOREACH_MOD(I_OnNickExpire, OnNickExpire(na));
+ delete na;
}
}
}
void expire_requests()
{
- int i;
- NickRequest *nr, *next;
time_t now = time(NULL);
- for (i = 0; i < 1024; i++)
+
+ for (nickrequest_map::const_iterator it = NickRequestList.begin(); it != NickRequestList.end(); ++it)
{
- for (nr = nrlists[i]; nr; nr = next)
+ NickRequest *nr = it->second;
+
+ if (Config.NSRExpire && now - nr->requested >= Config.NSRExpire)
{
- next = nr->next;
- if (Config.NSRExpire && now - nr->requested >= Config.NSRExpire)
- {
- Alog() << "Request for nick " << nr->nick << " expiring";
- delete nr;
- }
+ Alog() << "Request for nick " << nr->nick << " expiring";
+ delete nr;
}
}
}
/*************************************************************************/
-/*************************************************************************/
-/* Return the NickRequest structire for the given nick, or NULL */
NickRequest *findrequestnick(const char *nick)
{
- NickRequest *nr;
+ return findrequestnick(ci::string(nick));
+}
- if (!*nick || !nick)
- {
- Alog(LOG_DEBUG) << "findrequestnick() called with NULL values";
- return NULL;
- }
+NickRequest *findrequestnick(const std::string &nick)
+{
+ return findrequestnick(ci::string(nick.c_str()));
+}
- for (nr = nrlists[HASH(nick)]; nr; nr = nr->next)
- {
- if (stricmp(nr->nick, nick) == 0)
- {
- return nr;
- }
- }
+NickRequest *findrequestnick(const ci::string &nick)
+{
+ nickrequest_map::const_iterator it = NickRequestList.find(nick);
+
+ if (it != NickRequestList.end())
+ return it->second;
return NULL;
}
-/* Return the NickAlias structure for the given nick, or NULL if the nick
- * isn't registered. */
-
NickAlias *findnick(const char *nick)
{
- NickAlias *na;
-
- if (!nick || !*nick)
- {
- Alog(LOG_DEBUG) << "findnick() called with NULL values";
- return NULL;
- }
-
- for (na = nalists[HASH(nick)]; na; na = na->next)
- {
- if (stricmp(na->nick, nick) == 0)
- {
- return na;
- }
- }
- return NULL;
+ return findnick(ci::string(nick));
}
NickAlias *findnick(const std::string &nick)
{
- return findnick(nick.c_str());
+ return findnick(ci::string(nick.c_str()));
}
-/*************************************************************************/
+NickAlias *findnick(const ci::string &nick)
+{
+ nickalias_map::const_iterator it = NickAliasList.find(nick);
-/* Return the NickCore structure for the given nick, or NULL if the core
- * doesn't exist. */
+ if (it != NickAliasList.end())
+ return it->second;
+ return NULL;
+}
+
+/*************************************************************************/
NickCore *findcore(const char *nick)
{
- NickCore *nc;
+ return findcore(ci::string(nick));
+}
- if (!nick || !*nick)
- {
- Alog(LOG_DEBUG) << "findcore() called with NULL values";
- return NULL;
- }
+NickCore *findcore(const std::string &nick)
+{
+ return findcore(ci::string(nick.c_str()));
+}
- for (nc = nclists[HASH(nick)]; nc; nc = nc->next)
- {
- if (stricmp(nc->display, nick) == 0)
- {
- return nc;
- }
- }
+NickCore *findcore(const ci::string &nick)
+{
+ nickcore_map::const_iterator it = NickCoreList.find(nick);
+ if (it != NickCoreList.end())
+ return it->second;
return NULL;
}
@@ -497,78 +456,6 @@ bool is_on_access(User *u, NickCore *nc)
/*************************************************************************/
-/* Insert a nick alias alphabetically into the database. */
-
-void alpha_insert_alias(NickAlias * na)
-{
- NickAlias *ptr, *prev;
- char *nick;
- int index;
-
- if (!na)
- {
- Alog(LOG_DEBUG) << "alpha_insert_alias called with NULL values";
- return;
- }
-
- nick = na->nick;
- index = HASH(nick);
-
- for (prev = NULL, ptr = nalists[index];
- ptr && stricmp(ptr->nick, nick) < 0; prev = ptr, ptr = ptr->next);
- na->prev = prev;
- na->next = ptr;
- if (!prev)
- nalists[index] = na;
- else
- prev->next = na;
- if (ptr)
- ptr->prev = na;
-}
-
-/*************************************************************************/
-
-/* Insert a nick core into the database. */
-
-void insert_core(NickCore * nc)
-{
- int index;
-
- if (!nc)
- {
- Alog(LOG_DEBUG) << "insert_core called with NULL values";
- return;
- }
-
- index = HASH(nc->display);
-
- nc->prev = NULL;
- nc->next = nclists[index];
- if (nc->next)
- nc->next->prev = nc;
- nclists[index] = nc;
-}
-
-/*************************************************************************/
-void insert_requestnick(NickRequest * nr)
-{
- int index = HASH(nr->nick);
- if (!nr)
- {
- Alog(LOG_DEBUG) << "insert_requestnick called with NULL values";
- return;
- }
-
-
- nr->prev = NULL;
- nr->next = nrlists[index];
- if (nr->next)
- nr->next->prev = nr;
- nrlists[index] = nr;
-}
-
-/*************************************************************************/
-
/* Sets nc->display to newdisplay. If newdisplay is NULL, it will change
* it to the first alias in the list.
*/
@@ -576,40 +463,25 @@ void insert_requestnick(NickRequest * nr)
void change_core_display(NickCore * nc, const char *newdisplay)
{
- /*
- if (!newdisplay) {
- NickAlias *na;
-
- if (nc->aliases.count <= 0)
- return;
-
- na = static_cast<NickAlias *>(nc->aliases.list[0]);
- newdisplay = na->nick;
- }
- */
/* Log ... */
FOREACH_MOD(I_OnChangeCoreDisplay, OnChangeCoreDisplay(nc, newdisplay));
Alog() << Config.s_NickServ << ": changing " << nc->display << " nickname group display to " << newdisplay;
/* Remove the core from the list */
- if (nc->next)
- nc->next->prev = nc->prev;
- if (nc->prev)
- nc->prev->next = nc->next;
- else
- nclists[HASH(nc->display)] = nc->next;
+ NickCoreList.erase(nc->display);
delete [] nc->display;
nc->display = sstrdup(newdisplay);
- insert_core(nc);
+
+ NickCoreList[nc->display] = nc;
}
void change_core_display(NickCore * nc)
{
NickAlias *na;
- if (nc->aliases.count <= 0)
+ if (nc->aliases.empty())
return;
- na = static_cast<NickAlias *>(nc->aliases.list[0]);
+ na = nc->aliases.front();
change_core_display(nc,na->nick);
}
diff --git a/src/operserv.c b/src/operserv.c
deleted file mode 100644
index 455d74923..000000000
--- a/src/operserv.c
+++ /dev/null
@@ -1,1065 +0,0 @@
-/* OperServ functions.
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-
-#include "services.h"
-#include "pseudo.h"
-
-/*************************************************************************/
-
-/* AKILL, SGLINE, SQLINE and SZLINE lists */
-SList akills, sglines, sqlines, szlines;
-
-/*************************************************************************/
-
-static int is_akill_entry_equal(SList * slist, void *item1, void *item2);
-static void free_akill_entry(SList * slist, void *item);
-static int is_sgline_entry_equal(SList * slist, void *item1, void *item2);
-static void free_sgline_entry(SList * slist, void *item);
-static int is_sqline_entry_equal(SList * slist, void *item1, void *item2);
-static void free_sqline_entry(SList * slist, void *item);
-static int is_szline_entry_equal(SList * slist, void *item1, void *item2);
-static void free_szline_entry(SList * slist, void *item);
-
-/* News items */
-std::vector<NewsItem *> News;
-
-std::vector<std::bitset<32> > DefCon;
-int DefConModesSet = 0;
-/* Defcon modes mlocked on */
-Flags<ChannelModeName> DefConModesOn;
-/* Defcon modes mlocked off */
-Flags<ChannelModeName> DefConModesOff;
-/* Map of Modesa and Params for DefCon */
-std::map<ChannelModeName, std::string> DefConModesOnParams;
-
-bool SetDefConParam(ChannelModeName Name, std::string &buf)
-{
- return DefConModesOnParams.insert(std::make_pair(Name, buf)).second;
-}
-
-bool GetDefConParam(ChannelModeName Name, std::string *buf)
-{
- std::map<ChannelModeName, std::string>::iterator it = DefConModesOnParams.find(Name);
-
- buf->clear();
-
- if (it != DefConModesOnParams.end())
- {
- *buf = it->second;
- return true;
- }
-
- return false;
-}
-
-void UnsetDefConParam(ChannelModeName Name)
-{
- std::map<ChannelModeName, std::string>::iterator it = DefConModesOnParams.find(Name);
-
- if (it != DefConModesOnParams.end())
- {
- DefConModesOnParams.erase(it);
- }
-}
-
-/*************************************************************************/
-
-void moduleAddOperServCmds();
-/*************************************************************************/
-
-/* Options for the lists */
-SListOpts akopts = { 0, NULL, &is_akill_entry_equal, &free_akill_entry };
-
-SListOpts sgopts = { 0, NULL, &is_sgline_entry_equal, &free_sgline_entry };
-SListOpts sqopts =
- { SLISTF_SORT, NULL, &is_sqline_entry_equal, &free_sqline_entry };
-SListOpts szopts = { 0, NULL, &is_szline_entry_equal, &free_szline_entry };
-
-/*************************************************************************/
-/* *INDENT-OFF* */
-void moduleAddOperServCmds() {
- ModuleManager::LoadModuleList(Config.OperServCoreModules);
-}
-
-/* *INDENT-ON* */
-/*************************************************************************/
-/*************************************************************************/
-
-/* OperServ initialization. */
-
-void os_init()
-{
- moduleAddOperServCmds();
-
- slist_init(&akills);
- akills.opts = &akopts;
-
- if (ircd->sgline) {
- slist_init(&sglines);
- sglines.opts = &sgopts;
- }
- if (ircd->sqline) {
- slist_init(&sqlines);
- sqlines.opts = &sqopts;
- }
- if (ircd->szline) {
- slist_init(&szlines);
- szlines.opts = &szopts;
- }
-}
-
-/*************************************************************************/
-
-/* Main OperServ routine. */
-
-void operserv(User * u, char *buf)
-{
- const char *cmd;
- const char *s;
-
- Alog() << Config.s_OperServ << ": " << u->nick << ": " << buf;
-
- cmd = strtok(buf, " ");
- if (!cmd) {
- return;
- } else if (stricmp(cmd, "\1PING") == 0) {
- if (!(s = strtok(NULL, ""))) {
- s = "";
- }
- ircdproto->SendCTCP(findbot(Config.s_OperServ), u->nick.c_str(), "PING %s", s);
- } else {
- mod_run_cmd(Config.s_OperServ, u, OPERSERV, cmd);
- }
-}
-
-/*************************************************************************/
-/*********************** OperServ command functions **********************/
-/*************************************************************************/
-
-/*************************************************************************/
-
-
-Server *server_global(Server * s, char *msg)
-{
- Server *sl;
-
- while (s) {
- /* Do not send the notice to ourselves our juped servers */
- if (!s->HasFlag(SERVER_ISME) && !s->HasFlag(SERVER_JUPED))
- notice_server(Config.s_GlobalNoticer, s, "%s", msg);
-
- if (s->links) {
- sl = server_global(s->links, msg);
- if (sl)
- s = sl;
- else
- s = s->next;
- } else {
- s = s->next;
- }
- }
- return s;
-
-}
-
-void oper_global(char *nick, const char *fmt, ...)
-{
- va_list args;
- char msg[2048]; /* largest valid message is 512, this should cover any global */
- char dmsg[2048]; /* largest valid message is 512, this should cover any global */
-
- va_start(args, fmt);
- vsnprintf(msg, sizeof(msg), fmt, args);
- va_end(args);
-
- /* I don't like the way this is coded... */
- if ((nick) && (!Config.AnonymousGlobal)) {
- snprintf(dmsg, sizeof(dmsg), "[%s] %s", nick, msg);
- server_global(servlist, dmsg);
- } else {
- server_global(servlist, msg);
- }
-
-}
-
-/**************************************************************************/
-
-
-/************************************************************************/
-/*************************************************************************/
-
-/* Adds an AKILL to the list. Returns >= 0 on success, -1 if it fails, -2
- * if only the expiry time was changed.
- * The success result is the number of AKILLs that were deleted to successfully add one.
- */
-
-int add_akill(User * u, const char *mask, const char *by, const time_t expires,
- const char *reason)
-{
- int deleted = 0, i;
- char *user, *mask2, *host;
- Akill *entry;
-
- if (!mask) {
- return -1;
- }
-
- /* Checks whether there is an AKILL that already covers
- * the one we want to add, and whether there are AKILLs
- * that would be covered by this one. The masks AND the
- * expiry times are used to determine this, because some
- * AKILLs may become useful when another one expires.
- * If so, warn the user in the first case and cleanup
- * the useless AKILLs in the second.
- */
-
- if (akills.count > 0) {
-
- for (i = akills.count - 1; i >= 0; i--) {
- char amask[BUFSIZE];
-
- entry = static_cast<Akill *>(akills.list[i]);
-
- if (!entry)
- continue;
-
- snprintf(amask, sizeof(amask), "%s@%s", entry->user,
- entry->host);
-
- if (!stricmp(amask, mask)) {
- /* We change the AKILL expiry time if its current one is less than the new.
- * This is preferable to be sure we don't change an important AKILL
- * accidentely.
- */
- if (entry->expires >= expires || entry->expires == 0) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_EXISTS,
- mask);
- return -1;
- } else {
- entry->expires = expires;
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_CHANGED,
- amask);
- return -2;
- }
- }
-
- if (Anope::Match(mask, amask, false)
- && (entry->expires >= expires || entry->expires == 0)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_ALREADY_COVERED,
- mask, amask);
- return -1;
- }
-
- if (Anope::Match(amask, mask, false)
- && (entry->expires <= expires || expires == 0)) {
- slist_delete(&akills, i);
- deleted++;
- }
- }
-
- }
-
- /* We can now check whether the list is full or not. */
- if (slist_full(&akills)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_AKILL_REACHED_LIMIT,
- akills.limit);
- return -1;
- }
-
- /* We can now (really) add the AKILL. */
- mask2 = sstrdup(mask);
- host = strchr(mask2, '@');
-
- if (!host) {
- delete [] mask2;
- return -1;
- }
-
- user = mask2;
- *host = 0;
- host++;
-
- entry = new Akill;
-
- if (!entry) {
- delete [] mask2;
- return -1;
- }
-
- entry->user = sstrdup(user);
- entry->host = sstrdup(host);
- entry->by = sstrdup(by);
- entry->reason = sstrdup(reason);
- entry->seton = time(NULL);
- entry->expires = expires;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddAkill, OnAddAkill(u, entry));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete entry;
- return -1;
- }
-
- slist_add(&akills, entry);
-
- if (Config.AkillOnAdd)
- ircdproto->SendAkill(entry);
-
- delete [] mask2;
-
- return deleted;
-}
-
-/* Does the user match any AKILLs? */
-
-int check_akill(const char *nick, const char *username, const char *host,
- const char *vhost, const char *ip)
-{
- int i;
- Akill *ak;
-
- if (akills.count == 0)
- return 0;
-
- for (i = 0; i < akills.count; i++) {
- ak = static_cast<Akill *>(akills.list[i]);
- if (!ak)
- continue;
- if (Anope::Match(username, ak->user, false)
- && Anope::Match(host, ak->host, false)) {
- ircdproto->SendAkill(ak);
- return 1;
- }
- if (ircd->vhost) {
- if (vhost) {
- if (Anope::Match(username, ak->user, false)
- && Anope::Match(vhost, ak->host, false)) {
- ircdproto->SendAkill(ak);
- return 1;
- }
- }
- }
- if (ircd->nickip) {
- if (ip) {
- if (Anope::Match(username, ak->user, false)
- && Anope::Match(ip, ak->host, false)) {
- ircdproto->SendAkill(ak);
- return 1;
- }
- }
- }
-
- }
-
- return 0;
-}
-
-/* Delete any expired autokills. */
-
-void expire_akills()
-{
- int i;
- time_t now = time(NULL);
- Akill *ak;
-
- for (i = akills.count - 1; i >= 0; i--) {
- ak = static_cast<Akill *>(akills.list[i]);
-
- if (!ak->expires || ak->expires > now)
- continue;
-
- if (Config.WallAkillExpire)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "AKILL on %s@%s has expired",
- ak->user, ak->host);
- slist_delete(&akills, i);
- }
-}
-
-static void free_akill_entry(SList * slist, void *item)
-{
- Akill *ak = static_cast<Akill *>(item);
-
- /* Remove the AKILLs from all the servers */
- ircdproto->SendAkillDel(ak);
-
- /* Free the structure */
- delete [] ak->user;
- delete [] ak->host;
- delete [] ak->by;
- delete [] ak->reason;
- delete ak;
-}
-
-/* item1 is not an Akill pointer, but a char
- */
-
-static int is_akill_entry_equal(SList * slist, void *item1, void *item2)
-{
- char *ak1 = static_cast<char *>(item1), buf[BUFSIZE];
- Akill *ak2 = static_cast<Akill *>(item2);
-
- if (!ak1 || !ak2)
- return 0;
-
- snprintf(buf, sizeof(buf), "%s@%s", ak2->user, ak2->host);
-
- if (!stricmp(ak1, buf))
- return 1;
- else
- return 0;
-}
-
-
-/*************************************************************************/
-
-/* Adds an SGLINE to the list. Returns >= 0 on success, -1 if it failed, -2 if
- * only the expiry time changed.
- * The success result is the number of SGLINEs that were deleted to successfully add one.
- */
-
-int add_sgline(User * u, const char *mask, const char *by, time_t expires,
- const char *reason)
-{
- int deleted = 0, i;
- SXLine *entry;
- User *u2, *next;
- char buf[BUFSIZE];
- *buf = '\0';
-
- /* Checks whether there is an SGLINE that already covers
- * the one we want to add, and whether there are SGLINEs
- * that would be covered by this one.
- * If so, warn the user in the first case and cleanup
- * the useless SGLINEs in the second.
- */
-
- if (!mask) {
- return -1;
- }
-
- if (sglines.count > 0) {
-
- for (i = sglines.count - 1; i >= 0; i--) {
- entry = static_cast<SXLine *>(sglines.list[i]);
-
- if (!entry)
- continue;
-
- if (!stricmp(entry->mask, mask)) {
- if (entry->expires >= expires || entry->expires == 0) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_EXISTS,
- mask);
- return -1;
- } else {
- entry->expires = expires;
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_CHANGED,
- entry->mask);
- return -2;
- }
- }
-
- if (Anope::Match(mask, entry->mask, false )
- && (entry->expires >= expires || entry->expires == 0)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_ALREADY_COVERED,
- mask, entry->mask);
- return -1;
- }
-
- if (Anope::Match(entry->mask, mask, false)
- && (entry->expires <= expires || expires == 0)) {
- slist_delete(&sglines, i);
- deleted++;
- }
- }
-
- }
-
- /* We can now check whether the list is full or not. */
- if (slist_full(&sglines)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SGLINE_REACHED_LIMIT,
- sglines.limit);
- return -1;
- }
-
- /* We can now (really) add the SGLINE. */
- entry = new SXLine;
- if (!entry)
- return -1;
-
- entry->mask = sstrdup(mask);
- entry->by = sstrdup(by);
- entry->reason = sstrdup(reason);
- entry->seton = time(NULL);
- entry->expires = expires;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddSXLine, OnAddSXLine(u, entry, SX_SGLINE));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete entry;
- return -1;
- }
-
- slist_add(&sglines, entry);
-
- ircdproto->SendSGLine(entry);
-
- if (Config.KillonSGline && !ircd->sglineenforce) {
- snprintf(buf, (BUFSIZE - 1), "G-Lined: %s", entry->reason);
- u2 = firstuser();
- while (u2) {
- next = nextuser();
- if (!is_oper(u2)) {
- if (Anope::Match(u2->realname, entry->mask, false)) {
- kill_user(Config.ServerName, u2->nick, buf);
- }
- }
- u2 = next;
- }
- }
- return deleted;
-}
-
-/* Does the user match any SGLINEs? */
-
-int check_sgline(const char *nick, const char *realname)
-{
- int i;
- SXLine *sx;
-
- if (sglines.count == 0)
- return 0;
-
- for (i = 0; i < sglines.count; i++) {
- sx = static_cast<SXLine *>(sglines.list[i]);
- if (!sx)
- continue;
-
- if (Anope::Match(realname, sx->mask, false)) {
- ircdproto->SendSGLine(sx);
- /* We kill nick since s_sgline can't */
- ircdproto->SendSVSKill(NULL, finduser(nick), "G-Lined: %s", sx->reason);
- return 1;
- }
- }
-
- return 0;
-}
-
-/* Delete any expired SGLINEs. */
-
-void expire_sglines()
-{
- int i;
- time_t now = time(NULL);
- SXLine *sx;
-
- for (i = sglines.count - 1; i >= 0; i--) {
- sx = static_cast<SXLine *>(sglines.list[i]);
-
- if (!sx->expires || sx->expires > now)
- continue;
-
- if (Config.WallSGLineExpire)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "SGLINE on \2%s\2 has expired",
- sx->mask);
- slist_delete(&sglines, i);
- }
-}
-
-static void free_sgline_entry(SList * slist, void *item)
-{
- SXLine *sx = static_cast<SXLine *>(item);
-
- /* Remove the SGLINE from all the servers */
- ircdproto->SendSGLineDel(sx);
-
- /* Free the structure */
- delete [] sx->mask;
- delete [] sx->by;
- delete [] sx->reason;
- delete sx;
-}
-
-/* item1 is not an SXLine pointer, but a char */
-
-static int is_sgline_entry_equal(SList * slist, void *item1, void *item2)
-{
- char *sx1 = static_cast<char *>(item1);
- SXLine *sx2 = static_cast<SXLine *>(item2);
-
- if (!sx1 || !sx2)
- return 0;
-
- if (!stricmp(sx1, sx2->mask))
- return 1;
- else
- return 0;
-}
-
-/*************************************************************************/
-
-/* Adds an SQLINE to the list. Returns >= 0 on success, -1 if it failed, -2 if
- * only the expiry time changed.
- * The success result is the number of SQLINEs that were deleted to successfully add one.
- */
-
-int add_sqline(User * u, const char *mask, const char *by, time_t expires,
- const char *reason)
-{
- int deleted = 0, i;
- User *u2, *next;
- SXLine *entry;
- char buf[BUFSIZE];
- *buf = '\0';
-
- /* Checks whether there is an SQLINE that already covers
- * the one we want to add, and whether there are SQLINEs
- * that would be covered by this one.
- * If so, warn the user in the first case and cleanup
- * the useless SQLINEs in the second.
- */
-
- if (!mask) {
- return -1;
- }
-
- if (sqlines.count > 0) {
-
- for (i = sqlines.count - 1; i >= 0; i--) {
- entry = static_cast<SXLine *>(sqlines.list[i]);
-
- if (!entry)
- continue;
-
- if ((*mask == '#' && *entry->mask != '#') ||
- (*mask != '#' && *entry->mask == '#'))
- continue;
-
- if (!stricmp(entry->mask, mask)) {
- if (entry->expires >= expires || entry->expires == 0) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_EXISTS,
- mask);
- return -1;
- } else {
- entry->expires = expires;
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_CHANGED,
- entry->mask);
- return -2;
- }
- }
-
- if (Anope::Match(mask, entry->mask, false)
- && (entry->expires >= expires || entry->expires == 0)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_ALREADY_COVERED,
- mask, entry->mask);
- return -1;
- }
-
- if (Anope::Match(entry->mask, mask, false)
- && (entry->expires <= expires || expires == 0)) {
- slist_delete(&sqlines, i);
- deleted++;
- }
- }
-
- }
-
- /* We can now check whether the list is full or not. */
- if (slist_full(&sqlines)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SQLINE_REACHED_LIMIT,
- sqlines.limit);
- return -1;
- }
-
- /* We can now (really) add the SQLINE. */
- entry = new SXLine;
- if (!entry)
- return -1;
-
- entry->mask = sstrdup(mask);
- entry->by = sstrdup(by);
- entry->reason = sstrdup(reason);
- entry->seton = time(NULL);
- entry->expires = expires;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddSXLine, OnAddSXLine(u, entry, SX_SQLINE));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete entry;
- return -1;
- }
-
- slist_add(&sqlines, entry);
-
- sqline(entry->mask, entry->reason);
-
- if (Config.KillonSQline) {
- snprintf(buf, (BUFSIZE - 1), "Q-Lined: %s", entry->reason);
- u2 = firstuser();
- while (u2) {
- next = nextuser();
- if (!is_oper(u2)) {
- if (Anope::Match(u2->nick, entry->mask, false)) {
- kill_user(Config.ServerName, u2->nick, buf);
- }
- }
- u2 = next;
- }
- }
-
- return deleted;
-}
-
-/* Does the user match any SQLINEs? */
-
-int check_sqline(const char *nick, int nick_change)
-{
- int i;
- SXLine *sx;
- char reason[300];
-
- if (sqlines.count == 0)
- return 0;
-
- for (i = 0; i < sqlines.count; i++) {
- sx = static_cast<SXLine *>(sqlines.list[i]);
- if (!sx)
- continue;
-
- if (ircd->chansqline) {
- if (*sx->mask == '#')
- continue;
- }
-
- if (Anope::Match(nick, sx->mask, false)) {
- sqline(sx->mask, sx->reason);
- /* We kill nick since s_sqline can't */
- snprintf(reason, sizeof(reason), "Q-Lined: %s", sx->reason);
- kill_user(Config.s_OperServ, nick, reason);
- return 1;
- }
- }
-
- return 0;
-}
-
-int check_chan_sqline(const char *chan)
-{
- int i;
- SXLine *sx;
-
- if (sqlines.count == 0)
- return 0;
-
- for (i = 0; i < sqlines.count; i++) {
- sx = static_cast<SXLine *>(sqlines.list[i]);
- if (!sx)
- continue;
-
- if (*sx->mask != '#')
- continue;
-
- if (Anope::Match(chan, sx->mask, false)) {
- sqline(sx->mask, sx->reason);
- return 1;
- }
- }
-
- return 0;
-}
-
-/* Delete any expired SQLINEs. */
-
-void expire_sqlines()
-{
- int i;
- time_t now = time(NULL);
- SXLine *sx;
-
- for (i = sqlines.count - 1; i >= 0; i--) {
- sx = static_cast<SXLine *>(sqlines.list[i]);
-
- if (!sx->expires || sx->expires > now)
- continue;
-
- if (Config.WallSQLineExpire)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "SQLINE on \2%s\2 has expired",
- sx->mask);
-
- slist_delete(&sqlines, i);
- }
-}
-
-static void free_sqline_entry(SList * slist, void *item)
-{
- SXLine *sx = static_cast<SXLine *>(item);
-
- /* Remove the SQLINE from all the servers */
- ircdproto->SendSQLineDel(sx->mask);
-
- /* Free the structure */
- delete [] sx->mask;
- delete [] sx->by;
- delete [] sx->reason;
- delete sx;
-}
-
-/* item1 is not an SXLine pointer, but a char */
-
-static int is_sqline_entry_equal(SList * slist, void *item1, void *item2)
-{
- char *sx1 = static_cast<char *>(item1);
- SXLine *sx2 = static_cast<SXLine *>(item2);
-
- if (!sx1 || !sx2)
- return 0;
-
- if (!stricmp(sx1, sx2->mask))
- return 1;
- else
- return 0;
-}
-
-/*************************************************************************/
-
-/* Adds an SZLINE to the list. Returns >= 0 on success, -1 on error, -2 if
- * only the expiry time changed.
- * The success result is the number of SZLINEs that were deleted to successfully add one.
- */
-
-int add_szline(User * u, const char *mask, const char *by, time_t expires,
- const char *reason)
-{
- int deleted = 0, i;
- SXLine *entry;
-
- if (!mask) {
- return -1;
- }
-
- /* Checks whether there is an SZLINE that already covers
- * the one we want to add, and whether there are SZLINEs
- * that would be covered by this one.
- * If so, warn the user in the first case and cleanup
- * the useless SZLINEs in the second.
- */
-
- if (szlines.count > 0) {
-
- for (i = szlines.count - 1; i >= 0; i--) {
- entry = static_cast<SXLine *>(szlines.list[i]);
-
- if (!entry)
- continue;
-
- if (!stricmp(entry->mask, mask)) {
- if (entry->expires >= expires || entry->expires == 0) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_EXISTS,
- mask);
- return -1;
- } else {
- entry->expires = expires;
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_EXISTS,
- mask);
- return -2;
- }
- }
-
- if (Anope::Match(mask, entry->mask, false)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_ALREADY_COVERED,
- mask, entry->mask);
- return -1;
- }
-
- if (Anope::Match(entry->mask, mask, false)) {
- slist_delete(&szlines, i);
- deleted++;
- }
- }
-
- }
-
- /* We can now check whether the list is full or not. */
- if (slist_full(&szlines)) {
- if (u)
- notice_lang(Config.s_OperServ, u, OPER_SZLINE_REACHED_LIMIT,
- szlines.limit);
- return -1;
- }
-
- /* We can now (really) add the SZLINE. */
- entry = new SXLine;
- if (!entry)
- return -1;
-
- entry->mask = sstrdup(mask);
- entry->by = sstrdup(by);
- entry->reason = sstrdup(reason);
- entry->seton = time(NULL);
- entry->expires = expires;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(I_OnAddSXLine, OnAddSXLine(u, entry, SX_SZLINE));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete entry;
- return -1;
- }
-
- slist_add(&szlines, entry);
- ircdproto->SendSZLine(entry);
-
- return deleted;
-}
-
-/* Check and enforce any Zlines that we have */
-int check_szline(const char *nick, char *ip)
-{
- int i;
- SXLine *sx;
-
- if (szlines.count == 0) {
- return 0;
- }
-
- if (!ip) {
- return 0;
- }
-
- for (i = 0; i < szlines.count; i++) {
- sx = static_cast<SXLine *>(szlines.list[i]);
- if (!sx) {
- continue;
- }
-
- if (Anope::Match(ip, sx->mask, false)) {
- ircdproto->SendSZLine(sx);
- return 1;
- }
- }
-
- return 0;
-}
-
-
-/* Delete any expired SZLINEs. */
-
-void expire_szlines()
-{
- int i;
- time_t now = time(NULL);
- SXLine *sx;
-
- for (i = szlines.count - 1; i >= 0; i--) {
- sx = static_cast<SXLine *>(szlines.list[i]);
-
- if (!sx->expires || sx->expires > now)
- continue;
-
- if (Config.WallSZLineExpire)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "SZLINE on \2%s\2 has expired",
- sx->mask);
- slist_delete(&szlines, i);
- }
-}
-
-static void free_szline_entry(SList * slist, void *item)
-{
- SXLine *sx = static_cast<SXLine *>(item);
-
- /* Remove the SZLINE from all the servers */
- ircdproto->SendSZLineDel(sx);
-
- /* Free the structure */
- delete [] sx->mask;
- delete [] sx->by;
- delete [] sx->reason;
- delete sx;
-}
-
-/* item1 is not an SXLine pointer, but a char
- */
-
-static int is_szline_entry_equal(SList * slist, void *item1, void *item2)
-{
- char *sx1 = static_cast<char *>(item1);
- SXLine *sx2 = static_cast<SXLine *>(item2);
-
- if (!sx1 || !sx2)
- return 0;
-
- if (!stricmp(sx1, sx2->mask))
- return 1;
- else
- return 0;
-}
-
-/*************************************************************************/
-
-/** Check if a certain defcon option is currently in affect
- * @param Level The level
- * @return true and false
- */
-bool CheckDefCon(DefconLevel Level)
-{
- if (Config.DefConLevel)
- return DefCon[Config.DefConLevel][Level];
- return false;
-}
-
-/** Check if a certain defcon option is in a certain defcon level
- * @param level The defcon level
- * @param Level The defcon level name
- * @return true or false
- */
-bool CheckDefCon(int level, DefconLevel Level)
-{
- return DefCon[level][Level];
-}
-
-/** Add a defcon level option to a defcon level
- * @param level The defcon level
- * @param Level The defcon level option
- */
-void AddDefCon(int level, DefconLevel Level)
-{
- DefCon[level][Level] = true;
-}
-
-/** Remove a defcon level option from a defcon level
- * @param level The defcon level
- * @param Level The defcon level option
- */
-void DelDefCon(int level, DefconLevel Level)
-{
- DefCon[level][Level] = false;
-}
-
diff --git a/src/operserv.cpp b/src/operserv.cpp
new file mode 100644
index 000000000..8e3a3c90f
--- /dev/null
+++ b/src/operserv.cpp
@@ -0,0 +1,828 @@
+/* OperServ functions.
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ *
+ */
+
+#include "services.h"
+#include "modules.h"
+#include "language.h"
+
+std::vector<NewsItem *> News;
+
+std::vector<std::bitset<32> > DefCon;
+bool DefConModesSet = false;
+/* Defcon modes mlocked on */
+Flags<ChannelModeName> DefConModesOn;
+/* Defcon modes mlocked off */
+Flags<ChannelModeName> DefConModesOff;
+/* Map of Modesa and Params for DefCon */
+std::map<ChannelModeName, std::string> DefConModesOnParams;
+
+XLineManager *SGLine, *SZLine, *SQLine, *SNLine;
+
+void os_init()
+{
+ ModuleManager::LoadModuleList(Config.OperServCoreModules);
+
+ /* Yes, these are in this order for a reason. Most violent->least violent. */
+ XLineManager::RegisterXLineManager(SGLine = new SGLineManager());
+ XLineManager::RegisterXLineManager(SZLine = new SZLineManager());
+ XLineManager::RegisterXLineManager(SQLine = new SQLineManager());
+ XLineManager::RegisterXLineManager(SNLine = new SNLineManager());
+}
+
+void operserv(User *u, const std::string &buf)
+{
+ if (!u || buf.empty())
+ return;
+
+ Alog() << Config.s_OperServ << ": " << u->nick << ": " << buf;
+
+ if (buf.find("\1PING ", 0, 6) != std::string::npos && buf[buf.length() - 1] == '\1')
+ {
+ std::string command = buf;
+ command.erase(command.begin());
+ command.erase(command.end());
+ ircdproto->SendCTCP(OperServ, u->nick.c_str(), "%s", command.c_str());
+ }
+ else
+ {
+ mod_run_cmd(OperServ, u, buf);
+ }
+}
+
+bool SetDefConParam(ChannelModeName Name, std::string &buf)
+{
+ return DefConModesOnParams.insert(std::make_pair(Name, buf)).second;
+}
+
+bool GetDefConParam(ChannelModeName Name, std::string &buf)
+{
+ std::map<ChannelModeName, std::string>::iterator it = DefConModesOnParams.find(Name);
+
+ buf.clear();
+
+ if (it != DefConModesOnParams.end())
+ {
+ buf = it->second;
+ return true;
+ }
+
+ return false;
+}
+
+void UnsetDefConParam(ChannelModeName Name)
+{
+ std::map<ChannelModeName, std::string>::iterator it = DefConModesOnParams.find(Name);
+
+ if (it != DefConModesOnParams.end())
+ {
+ DefConModesOnParams.erase(it);
+ }
+}
+
+/** Check if a certain defcon option is currently in affect
+ * @param Level The level
+ * @return true and false
+ */
+bool CheckDefCon(DefconLevel Level)
+{
+ if (Config.DefConLevel)
+ return DefCon[Config.DefConLevel][Level];
+ return false;
+}
+
+/** Check if a certain defcon option is in a certain defcon level
+ * @param level The defcon level
+ * @param Level The defcon level name
+ * @return true or false
+ */
+bool CheckDefCon(int level, DefconLevel Level)
+{
+ return DefCon[level][Level];
+}
+
+/** Add a defcon level option to a defcon level
+ * @param level The defcon level
+ * @param Level The defcon level option
+ */
+void AddDefCon(int level, DefconLevel Level)
+{
+ DefCon[level][Level] = true;
+}
+
+/** Remove a defcon level option from a defcon level
+ * @param level The defcon level
+ * @param Level The defcon level option
+ */
+void DelDefCon(int level, DefconLevel Level)
+{
+ DefCon[level][Level] = false;
+}
+
+void server_global(Server *s, const std::string &message)
+{
+ /* Do not send the notice to ourselves our juped servers */
+ if (s != Me && !s->HasFlag(SERVER_JUPED))
+ notice_server(Config.s_GlobalNoticer, s, "%s", message.c_str());
+
+ if (s->GetLinks())
+ {
+ for (std::list<Server *>::const_iterator it = s->GetLinks()->begin(); it != s->GetLinks()->end(); ++it)
+ {
+ server_global(*it, message);
+ }
+ }
+}
+
+void oper_global(char *nick, const char *fmt, ...)
+{
+ va_list args;
+ char msg[2048]; /* largest valid message is 512, this should cover any global */
+
+ va_start(args, fmt);
+ vsnprintf(msg, sizeof(msg), fmt, args);
+ va_end(args);
+
+ if (nick && !Config.AnonymousGlobal)
+ {
+ std::string rmsg = std::string("[") + nick + std::string("] ") + msg;
+ server_global(Me->GetUplink(), rmsg.c_str());
+ }
+ else
+ server_global(Me->GetUplink(), msg);
+
+}
+
+/**************************************************************************/
+
+/* List of XLine managers we check users against in XLineManager::CheckAll */
+std::list<XLineManager *> XLineManager::XLineManagers;
+
+XLine::XLine(const ci::string &mask, const std::string &reason) : Mask(mask), Reason(reason)
+{
+ Expires = Created = 0;
+}
+
+XLine::XLine(const ci::string &mask, const ci::string &by, const time_t expires, const std::string &reason) : Mask(mask), By(by), Created(time(NULL)), Expires(expires), Reason(reason)
+{
+}
+
+ci::string XLine::GetNick() const
+{
+ size_t nick_t = Mask.find('!');
+
+ if (nick_t == ci::string::npos)
+ return "";
+
+ return Mask.substr(0, nick_t - 1);
+}
+
+ci::string XLine::GetUser() const
+{
+ size_t user_t = Mask.find('!'), host_t = Mask.find('@');
+
+ if (user_t == ci::string::npos)
+ {
+ return Mask.substr(0, host_t);
+ }
+ else if (host_t != ci::string::npos)
+ {
+ return Mask.substr((user_t != ci::string::npos ? user_t + 1 : 0), host_t);
+ }
+ else
+ {
+ return "";
+ }
+}
+
+ci::string XLine::GetHost() const
+{
+ size_t host_t = Mask.find('@');
+
+ if (host_t == ci::string::npos)
+ {
+ return Mask;
+ }
+ else
+ {
+ return Mask.substr(host_t + 1);
+ }
+}
+
+/** Constructor
+ */
+XLineManager::XLineManager()
+{
+}
+
+/** Destructor
+ * Clears all XLines in this XLineManager
+ */
+XLineManager::~XLineManager()
+{
+ Clear();
+}
+
+ /** Register a XLineManager, places it in XLineManagers for use in XLineManager::CheckAll
+ * It is important XLineManagers are registered in the proper order. Eg, if you had one akilling
+ * clients and one handing them free olines, you would want the akilling one first. This way if a client
+ * matches an entry on both of the XLineManagers, they would be akilled.
+ * @param xlm THe XLineManager
+ */
+void XLineManager::RegisterXLineManager(XLineManager *xlm)
+{
+ XLineManagers.push_back(xlm);
+}
+
+/** Unregister a XLineManager
+ * @param xlm The XLineManager
+ */
+void XLineManager::UnregisterXLineManager(XLineManager *xlm)
+{
+ std::list<XLineManager *>::iterator it = std::find(XLineManagers.begin(), XLineManagers.end(), xlm);
+
+ if (it != XLineManagers.end())
+ {
+ XLineManagers.erase(it);
+ }
+}
+
+/* Check a user against all known XLineManagers
+ * @param u The user
+ * @return A pair of the XLineManager the user was found in and the XLine they matched, both may be NULL for no match
+ */
+std::pair<XLineManager *, XLine *> XLineManager::CheckAll(User *u)
+{
+ std::pair<XLineManager *, XLine *> ret(NULL, NULL);
+
+ for (std::list<XLineManager *>::iterator it = XLineManagers.begin(); it != XLineManagers.end(); ++it)
+ {
+ XLineManager *xlm = *it;
+
+ XLine *x = xlm->Check(u);
+
+ if (x)
+ {
+ ret.first = xlm;
+ ret.second = x;;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/** Get the number of XLines in this XLineManager
+ * @return The number of XLines
+ */
+const size_t XLineManager::GetCount() const
+{
+ return XLines.size();
+}
+
+/** Get the XLine list
+ * @return The list
+ */
+const std::deque<XLine *>& XLineManager::GetList() const
+{
+ return XLines;
+}
+
+/** Add an entry to this XLineManager
+ * @param x The entry
+ */
+void XLineManager::AddXLine(XLine *x)
+{
+ XLines.push_back(x);
+}
+
+/** Delete an entry from this XLineManager
+ * @param x The entry
+ * @return true if the entry was found and deleted, else false
+ */
+bool XLineManager::DelXLine(XLine *x)
+{
+ std::deque<XLine *>::iterator it = std::find(XLines.begin(), XLines.end(), x);
+
+ if (it != XLines.end())
+ {
+ delete x;
+ XLines.erase(it);
+
+ return true;
+ }
+
+ return false;
+}
+
+/** Gets an entry by index
+ * @param index The index
+ * @return The XLine, or NULL if the index is out of bounds
+ */
+XLine *XLineManager::GetEntry(unsigned index) const
+{
+ if (index >= XLines.size())
+ return NULL;
+
+ return XLines[index];
+}
+
+/** Clear the XLine list
+ */
+void XLineManager::Clear()
+{
+ for (std::deque<XLine *>::iterator it = XLines.begin(); it != XLines.end(); ++it)
+ {
+ delete *it;
+ }
+ XLines.clear();
+}
+
+/** Add an entry to this XLine Manager
+ * @param bi The bot error replies should be sent from
+ * @param u The user adding the XLine
+ * @param mask The mask of the XLine
+ * @param expires When this should expire
+ * @param reaosn The reason
+ * @return A pointer to the XLine
+ */
+XLine *XLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason)
+{
+ return NULL;
+}
+
+/** Delete an XLine, eg, remove it from the IRCd.
+ * @param x The xline
+ */
+void XLineManager::Del(XLine *x)
+{
+}
+
+/** Checks if a mask can/should be added to the XLineManager
+ * @param mask The mask
+ * @param expires When the mask would expire
+ * @return A pair of int and XLine*.
+ * 1 - Mask already exists
+ * 2 - Mask already exists, but the expiry time was changed
+ * 3 - Mask is already covered by another mask
+ * In each case the XLine it matches/is covered by is returned in XLine*
+ */
+std::pair<int, XLine *> XLineManager::CanAdd(const ci::string &mask, time_t expires)
+{
+ std::pair<int, XLine *> ret(0, NULL);
+
+ for (unsigned i = 0; i < GetCount(); ++i)
+ {
+ XLine *x = GetEntry(i);
+ ret.second = x;
+
+ if (x->Mask == mask)
+ {
+ if (x->Expires == 0 || x->Expires >= expires)
+ {
+ ret.first = 1;
+ break;
+ }
+ else
+ {
+ x->Expires = expires;
+
+ ret.first = 2;
+ break;
+ }
+ }
+ else if (Anope::Match(mask, x->Mask) && (x->Expires == 0 || x->Expires >= expires))
+ {
+ ret.first = 3;
+ break;
+ }
+ else if (Anope::Match(x->Mask, mask) && (expires == 0 || x->Expires <= expires))
+ {
+ this->DelXLine(x);
+ --i;
+ }
+ }
+
+ return ret;
+}
+
+/** Checks if this list has an entry
+ * @param mask The mask
+ * @return The XLine the user matches, or NULL
+ */
+XLine *XLineManager::HasEntry(const ci::string &mask) const
+{
+ for (unsigned i = 0; i < XLines.size(); ++i)
+ {
+ XLine *x = XLines[i];
+
+ if (x->Mask == mask)
+ {
+ return x;
+ }
+ }
+
+ return NULL;
+}
+
+/** Check a user against all of the xlines in this XLineManager
+ * @param u The user
+ * @return The xline the user marches, if any. Also calls OnMatch()
+ */
+XLine *XLineManager::Check(User *u)
+{
+ const time_t now = time(NULL);
+
+ for (std::deque<XLine *>::iterator it = XLines.begin(); it != XLines.end(); ++it)
+ {
+ XLine *x = *it;
+
+ if (x->Expires && x->Expires < now)
+ {
+ OnExpire(x);
+ delete x;
+ it = XLines.erase(it);
+ --it;
+ continue;
+ }
+
+ if (!x->GetNick().empty() && !Anope::Match(u->nick.c_str(), x->GetNick()))
+ continue;
+
+ if (!x->GetUser().empty() && !Anope::Match(u->GetIdent().c_str(), x->GetUser()))
+ continue;
+
+ if (x->GetHost().empty() || ((u->hostip && Anope::Match(u->hostip, x->GetHost())) || Anope::Match(u->host, x->GetHost()) || (!u->chost.empty() && Anope::Match(u->chost.c_str(), x->GetHost())) || (u->vhost && Anope::Match(u->vhost, x->GetHost()))))
+ {
+ OnMatch(u, x);
+ return x;
+ }
+ }
+
+ return NULL;
+}
+
+/** Called when a user matches a xline in this XLineManager
+ * @param u The user
+ * @param x The XLine they match
+ */
+void XLineManager::OnMatch(User *u, XLine *x)
+{
+}
+
+/** Called when an XLine expires
+ * @param x The xline
+ */
+void XLineManager::OnExpire(XLine *x)
+{
+}
+
+XLine *SGLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason)
+{
+ if (mask.find('!') != ci::string::npos)
+ {
+ if (bi && u)
+ notice_lang(bi->nick.c_str(), u, OPER_AKILL_NO_NICK);
+ return NULL;
+ }
+
+ if (mask.find('@') == ci::string::npos)
+ {
+ if (bi && u)
+ notice_lang(bi->nick.c_str(), u, BAD_USERHOST_MASK);
+ return NULL;
+ }
+
+ if (strspn(mask.c_str(), "~@.*?") == mask.length())
+ {
+ if (bi && u)
+ notice_lang(bi->nick.c_str(), u, USERHOST_MASK_TOO_WIDE, mask.c_str());
+ return NULL;
+ }
+
+ std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires);
+ if (canAdd.first)
+ {
+ if (bi && u)
+ {
+ if (canAdd.first == 1)
+ notice_lang(bi->nick.c_str(), u, OPER_AKILL_EXISTS, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ notice_lang(bi->nick.c_str(), u, OPER_AKILL_CHANGED, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ notice_lang(bi->nick.c_str(), u, OPER_AKILL_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str());
+ }
+
+ return canAdd.second;
+ }
+
+ std::string realreason = reason;
+ if (u && Config.AddAkiller)
+ realreason = "[" + u->nick + "]" + reason;
+
+ XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, realreason);
+
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnAddAkill, OnAddAkill(u, x));
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ delete x;
+ return NULL;
+ }
+
+ this->AddXLine(x);
+
+ if (Config.AkillOnAdd)
+ ircdproto->SendAkill(x);
+
+ return x;
+}
+
+void SGLineManager::Del(XLine *x)
+{
+ ircdproto->SendAkillDel(x);
+}
+
+void SGLineManager::OnMatch(User *u, XLine *x)
+{
+ ircdproto->SendAkill(x);
+}
+
+void SGLineManager::OnExpire(XLine *x)
+{
+ if (Config.WallAkillExpire)
+ ircdproto->SendGlobops(OperServ, "AKILL on %s has expired", x->Mask.c_str());
+}
+
+XLine *SNLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason)
+{
+ if (!mask.empty() && strspn(mask.c_str(), "*?") == mask.length())
+ {
+ if (bi && u)
+ notice_lang(bi->nick.c_str(), u, USERHOST_MASK_TOO_WIDE, mask.c_str());
+ return NULL;
+ }
+
+ std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires);
+ if (canAdd.first)
+ {
+ if (bi && u)
+ {
+ if (canAdd.first == 1)
+ notice_lang(bi->nick.c_str(), u, OPER_SNLINE_EXISTS, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ notice_lang(bi->nick.c_str(), u, OPER_SNLINE_CHANGED, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ notice_lang(bi->nick.c_str(), u, OPER_SNLINE_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str());
+ }
+
+ return canAdd.second;
+ }
+
+ XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, reason);
+
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, X_SNLINE));
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ delete x;
+ return NULL;
+ }
+
+ this->AddXLine(x);
+
+ if (Config.KillonSNline && !ircd->sglineenforce)
+ {
+ std::string rreason = "G-Lined: " + reason;
+
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
+ {
+ User *user = it->second;
+ ++it;
+
+ if (!is_oper(user) && Anope::Match(user->realname, x->Mask))
+ {
+ kill_user(Config.ServerName, user->nick, rreason.c_str());
+ }
+ }
+ }
+
+ return x;
+}
+
+void SNLineManager::Del(XLine *x)
+{
+ ircdproto->SendSGLineDel(x);
+}
+
+void SNLineManager::OnMatch(User *u, XLine *x)
+{
+ ircdproto->SendSGLine(x);
+
+ std::string reason = "G-Lined: " + x->Reason;
+ kill_user(Config.s_OperServ, u->nick, reason.c_str());
+}
+
+void SNLineManager::OnExpire(XLine *x)
+{
+ if (Config.WallSNLineExpire)
+ ircdproto->SendGlobops(OperServ, "SNLINE on \2%s\2 has expired", x->Mask.c_str());
+}
+
+XLine *SQLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason)
+{
+ if (strspn(mask.c_str(), "*") == mask.length())
+ {
+ if (bi && u)
+ notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask.c_str());
+ return NULL;
+ }
+
+ if (mask[0] == '#' && !ircd->chansqline)
+ {
+ if (bi && u)
+ notice_lang(Config.s_OperServ, u, OPER_SQLINE_CHANNELS_UNSUPPORTED);
+ return NULL;
+ }
+
+ std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires);
+ if (canAdd.first)
+ {
+ if (bi && u)
+ {
+ if (canAdd.first == 1)
+ notice_lang(bi->nick.c_str(), u, OPER_SQLINE_EXISTS, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ notice_lang(bi->nick.c_str(), u, OPER_SQLINE_CHANGED, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ notice_lang(bi->nick.c_str(), u, OPER_SQLINE_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str());
+ }
+
+ return canAdd.second;
+ }
+
+ XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, reason);
+
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, X_SQLINE));
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ delete x;
+ return NULL;
+ }
+
+ this->AddXLine(x);
+
+ if (Config.KillonSQline)
+ {
+ std::string rreason = "Q-Lined: " + reason;
+
+ if (mask[0] == '#')
+ {
+ for (channel_map::const_iterator cit = ChannelList.begin(); cit != ChannelList.end(); ++cit)
+ {
+ Channel *c = cit->second;
+
+ if (!Anope::Match(c->name.c_str(), mask))
+ continue;
+ for (CUserList::iterator it = c->users.begin(); it != c->users.end();)
+ {
+ UserContainer *uc = *it;
+ ++it;
+
+ if (is_oper(uc->user))
+ continue;
+ c->Kick(NULL, uc->user, "%s", reason.c_str());
+ }
+ }
+ }
+ else
+ {
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
+ {
+ User *user = it->second;
+ ++it;
+
+ if (!is_oper(user) && Anope::Match(user->nick.c_str(), x->Mask))
+ {
+ kill_user(Config.ServerName, user->nick, rreason.c_str());
+ }
+ }
+ }
+ }
+
+ ircdproto->SendSQLine(x);
+
+ return x;
+}
+
+void SQLineManager::Del(XLine *x)
+{
+ ircdproto->SendSQLineDel(x);
+}
+
+void SQLineManager::OnMatch(User *u, XLine *x)
+{
+ ircdproto->SendSQLine(x);
+
+ char reason[300];
+ snprintf(reason, sizeof(reason), "Q-Lined: %s", x->Reason.c_str());
+ kill_user(Config.s_OperServ, u->nick, reason);
+}
+
+void SQLineManager::OnExpire(XLine *x)
+{
+ if (Config.WallSQLineExpire)
+ ircdproto->SendGlobops(OperServ, "SQLINE on \2%s\2 has expired", x->Mask.c_str());
+}
+
+bool SQLineManager::Check(Channel *c)
+{
+ if (ircd->chansqline && SQLine)
+ {
+ for (std::deque<XLine *>::const_iterator it = SGLine->GetList().begin(); it != SGLine->GetList().end(); ++it)
+ {
+ XLine *x = *it;
+
+ if (Anope::Match(c->name.c_str(), x->Mask))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+XLine *SZLineManager::Add(BotInfo *bi, User *u, const ci::string &mask, time_t expires, const std::string &reason)
+{
+ if (mask.find('!') != ci::string::npos || mask.find('@') != ci::string::npos)
+ {
+ notice_lang(Config.s_OperServ, u, OPER_SZLINE_ONLY_IPS);
+ return NULL;
+ }
+
+ if (strspn(mask.c_str(), "*?") == mask.length())
+ {
+ notice_lang(Config.s_OperServ, u, USERHOST_MASK_TOO_WIDE, mask.c_str());
+ return NULL;
+ }
+
+ std::pair<int, XLine *> canAdd = this->CanAdd(mask, expires);
+ if (canAdd.first)
+ {
+ if (bi && u)
+ {
+ if (canAdd.first == 1)
+ notice_lang(bi->nick.c_str(), u, OPER_SZLINE_EXISTS, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ notice_lang(bi->nick.c_str(), u, OPER_SZLINE_CHANGED, canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ notice_lang(bi->nick.c_str(), u, OPER_SZLINE_ALREADY_COVERED, mask.c_str(), canAdd.second->Mask.c_str());
+ }
+
+ return canAdd.second;
+ }
+
+ XLine *x = new XLine(mask, u ? u->nick.c_str() : "", expires, reason);
+
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnAddXLine, OnAddXLine(u, x, X_SZLINE));
+ if (MOD_RESULT == EVENT_STOP)
+ {
+ delete x;
+ return NULL;
+ }
+
+ this->AddXLine(x);
+
+ ircdproto->SendSZLine(x);
+
+ return x;
+}
+
+void SZLineManager::Del(XLine *x)
+{
+ ircdproto->SendSZLineDel(x);
+}
+
+void SZLineManager::OnMatch(User *u, XLine *x)
+{
+ ircdproto->SendSZLine(x);
+}
+
+void SZLineManager::OnExpire(XLine *x)
+{
+ if (Config.WallSZLineExpire)
+ ircdproto->SendGlobops(OperServ, "SZLINE on \2%s\2 has expired", x->Mask.c_str());
+}
+
diff --git a/src/opertype.cpp b/src/opertype.cpp
index fb0689add..0ee6d000f 100644
--- a/src/opertype.cpp
+++ b/src/opertype.cpp
@@ -16,26 +16,44 @@ OperType::OperType(const ci::string &nname) : name(nname)
bool OperType::HasCommand(const std::string &cmdstr) const
{
- for (std::list<std::string>::const_iterator it = this->commands.begin(); it != this->commands.end(); it++)
+ for (std::list<std::string>::const_iterator it = this->commands.begin(); it != this->commands.end(); ++it)
{
if (Anope::Match(cmdstr, *it))
{
return true;
}
}
+ for (std::set<OperType *>::const_iterator iit = this->inheritances.begin(); iit != this->inheritances.end(); ++iit)
+ {
+ OperType *ot = *iit;
+
+ if (ot->HasCommand(cmdstr))
+ {
+ return true;
+ }
+ }
return false;
}
bool OperType::HasPriv(const std::string &privstr) const
{
- for (std::list<std::string>::const_iterator it = this->privs.begin(); it != this->privs.end(); it++)
+ for (std::list<std::string>::const_iterator it = this->privs.begin(); it != this->privs.end(); ++it)
{
if (Anope::Match(privstr, *it))
{
return true;
}
}
+ for (std::set<OperType *>::const_iterator iit = this->inheritances.begin(); iit != this->inheritances.end(); ++iit)
+ {
+ OperType *ot = *iit;
+
+ if (ot->HasPriv(privstr))
+ {
+ return true;
+ }
+ }
return false;
}
@@ -55,3 +73,8 @@ const ci::string &OperType::GetName() const
return this->name;
}
+void OperType::Inherits(OperType *ot)
+{
+ this->inheritances.insert(ot);
+}
+
diff --git a/src/process.c b/src/process.cpp
index ca9e2c069..7a015c64b 100644
--- a/src/process.c
+++ b/src/process.cpp
@@ -12,7 +12,6 @@
*/
#include "services.h"
-#include "messages.h"
#include "modules.h"
/*************************************************************************/
@@ -283,14 +282,12 @@ int split_buf(char *buf, const char ***argv, int colon_special)
void process(const std::string &buffer)
{
int retVal = 0;
- Message *current = NULL;
char source[64];
char cmd[64];
char buf[512]; /* Longest legal IRC command line */
char *s;
int ac; /* Parameters for the command */
const char **av;
- Message *m;
/* zero out the buffers before we do much else */
*buf = '\0';
@@ -346,19 +343,21 @@ void process(const std::string &buffer)
}
/* Do something with the message. */
- m = find_message(cmd);
- if (m) {
- if (m->func) {
- retVal = m->func(source, ac, av);
- if (retVal == MOD_CONT) {
- current = m->next;
- while (current && current->func && retVal == MOD_CONT) {
- retVal = current->func(source, ac, av);
- current = current->next;
- }
- }
+ std::vector<Message *> messages = FindMessage(cmd);
+
+ if (!messages.empty())
+ {
+ retVal = MOD_CONT;
+
+ for (std::vector<Message *>::iterator it = messages.begin(); retVal == MOD_CONT && it != messages.end(); ++it)
+ {
+ Message *m = *it;
+
+ if (m->func)
+ retVal = m->func(source, ac, av);
}
- } else
+ }
+ else
Alog(LOG_DEBUG) << "unknown message from server (" << buffer << ")";
/* Free argument list we created */
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 2188e86ba..761df1ca1 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -153,12 +153,12 @@ void IRCDProto::SendPrivmsg(BotInfo *bi, const char *dest, const char *fmt, ...)
void IRCDProto::SendGlobalNotice(BotInfo *bi, Server *dest, const char *msg)
{
- send_cmd(ircd->ts6 ? bi->uid : bi->nick, "NOTICE %s%s :%s", ircd->globaltldprefix, dest->name, msg);
+ send_cmd(ircd->ts6 ? bi->uid : bi->nick, "NOTICE %s%s :%s", ircd->globaltldprefix, dest->GetName().c_str(), msg);
}
void IRCDProto::SendGlobalPrivmsg(BotInfo *bi, Server *dest, const char *msg)
{
- send_cmd(ircd->ts6 ? bi->uid : bi->nick, "PRIVMSG %s%s :%s", ircd->globaltldprefix, dest->name, msg);
+ send_cmd(ircd->ts6 ? bi->uid : bi->nick, "PRIVMSG %s%s :%s", ircd->globaltldprefix, dest->GetName().c_str(), msg);
}
void IRCDProto::SendQuit(const char *nick, const char *)
diff --git a/src/protocol/CMakeLists.txt b/src/protocol/CMakeLists.txt
index a74b49a89..abca56caf 100644
--- a/src/protocol/CMakeLists.txt
+++ b/src/protocol/CMakeLists.txt
@@ -1,5 +1,4 @@
-# Find all the *.c and *.cpp files within the current source directory, and sort the list
-file(GLOB PROTOCOL_SRCS_C RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c")
+# Find all the *.cpp files within the current source directory, and sort the list
file(GLOB PROTOCOL_SRCS_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp")
set(PROTOCOL_SRCS ${PROTOCOL_SRCS_C} ${PROTOCOL_SRCS_CPP})
sort_list(PROTOCOL_SRCS)
diff --git a/src/protocol/Makefile b/src/protocol/Makefile
index a40d009c2..7221ab2e2 100644
--- a/src/protocol/Makefile
+++ b/src/protocol/Makefile
@@ -8,8 +8,7 @@ MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \
'PROFILE=${PROFILE}' 'SHARED=${SHARED}' 'MODULEFLAGS=${MODULEFLAGS}'\
'MAKEBIN=${MAKEBIN}'
-OBJECTS= $(SRCS:.c=.so)
-OBJECTS+= $(SRCS:.cpp=.so)
+OBJECTS= $(SRCS:.cpp=.so)
CDEFS= -rdynamic -Wall
all: modules subs
@@ -21,10 +20,7 @@ install:
distclean: clean spotless
-.SUFFIXES: .c .cpp .so
-
-.c.so:
- $(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} -I../${INCLUDEDIR} -o $@ $<
+.SUFFIXES: .cpp .so
.cpp.so:
$(MAKEBIN) $(CC) ${CFLAGS} ${CDEFS} ${MODULEFLAGS} -I../${INCLUDEDIR} -o $@ $<
diff --git a/src/protocol/bahamut.c b/src/protocol/bahamut.cpp
index 1e38a4aa2..d55a08123 100644
--- a/src/protocol/bahamut.c
+++ b/src/protocol/bahamut.cpp
@@ -14,7 +14,7 @@
/*************************************************************************/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
IRCDVar myIrcd[] = {
{"Bahamut 1.8.x", /* ircd name */
@@ -23,7 +23,7 @@ IRCDVar myIrcd[] = {
"+o", /* Channel Umode used by Botserv bots */
1, /* SVSNICK */
0, /* Vhost */
- 1, /* Supports SGlines */
+ 1, /* Supports SNlines */
1, /* Supports SQlines */
1, /* Supports SZlines */
3, /* Number of server args */
@@ -141,35 +141,33 @@ class BahamutIRCdProto : public IRCDProto
}
/* SQLINE */
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(NULL, "SQLINE %s :%s", mask.c_str(), reason.c_str());
+ send_cmd(NULL, "SQLINE %s :%s", x->Mask.c_str(), x->Reason.c_str());
}
- /* UNSGLINE */
- void SendSGLineDel(SXLine *sx)
+ /* UNSLINE */
+ void SendSGLineDel(XLine *x)
{
- send_cmd(NULL, "UNSGLINE 0 :%s", sx->mask);
+ send_cmd(NULL, "UNSGLINE 0 :%s", x->Mask.c_str());
}
/* UNSZLINE */
- void SendSZLineDel(SXLine *sx)
+ void SendSZLineDel(XLine *x)
{
/* this will likely fail so its only here for legacy */
- send_cmd(NULL, "UNSZLINE 0 %s", sx->mask);
+ send_cmd(NULL, "UNSZLINE 0 %s", x->Mask.c_str());
/* this is how we are supposed to deal with it */
- send_cmd(NULL, "RAKILL %s *", sx->mask);
+ send_cmd(NULL, "RAKILL %s *", x->Mask.c_str());
}
/* SZLINE */
- void SendSZLine(SXLine *sx)
+ void SendSZLine(XLine *x)
{
/* this will likely fail so its only here for legacy */
- send_cmd(NULL, "SZLINE %s :%s", sx->mask, sx->reason);
+ send_cmd(NULL, "SZLINE %s :%s", x->Mask.c_str(), x->Reason.c_str());
/* this is how we are supposed to deal with it */
- send_cmd(NULL, "AKILL %s * %d %s %ld :%s", sx->mask, 172800, sx->by, static_cast<long>(time(NULL)), sx->reason);
+ send_cmd(NULL, "AKILL %s * %d %s %ld :%s", x->Mask.c_str(), 172800, x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SVSNOOP */
@@ -179,15 +177,15 @@ class BahamutIRCdProto : public IRCDProto
}
/* SGLINE */
- void SendSGLine(SXLine *sx)
+ void SendSGLine(XLine *x)
{
- send_cmd(NULL, "SGLINE %d :%s:%s", static_cast<int>(strlen(sx->mask)), sx->mask, sx->reason);
+ send_cmd(NULL, "SGLINE %d :%s:%s", static_cast<int>(x->Mask.length()), x->Mask.c_str(), x->Reason.c_str());
}
/* RAKILL */
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
- send_cmd(NULL, "RAKILL %s %s", ak->host, ak->user);
+ send_cmd(NULL, "RAKILL %s %s", x->GetHost().c_str(), x->GetUser().c_str());
}
/* TOPIC */
@@ -197,11 +195,9 @@ class BahamutIRCdProto : public IRCDProto
}
/* UNSQLINE */
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(NULL, "UNSQLINE %s", user.c_str());
+ send_cmd(NULL, "UNSQLINE %s", x->Mask.c_str());
}
/* JOIN - SJOIN */
@@ -210,12 +206,12 @@ class BahamutIRCdProto : public IRCDProto
send_cmd(user->nick, "SJOIN %ld %s", static_cast<long>(chantime), channel);
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = ak->expires - time(NULL);
+ time_t timeleft = x->Expires - time(NULL);
if (timeleft > 172800) timeleft = 172800;
- send_cmd(NULL, "AKILL %s %s %d %s %ld :%s", ak->host, ak->user, static_cast<int>(timeleft), ak->by, static_cast<long>(time(NULL)), ak->reason);
+ send_cmd(NULL, "AKILL %s %s %d %s %ld :%s", x->GetHost().c_str(), x->GetUser().c_str(), static_cast<int>(timeleft), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/*
@@ -265,7 +261,7 @@ class BahamutIRCdProto : public IRCDProto
/* nc_change was = 1, and there is no na->status */
void SendUnregisteredNick(User *u)
{
- BotInfo *bi = findbot(Config.s_NickServ);
+ BotInfo *bi = NickServ;
u->RemoveMode(bi, UMODE_REGISTERED);
ircdproto->SendMode(bi, u, "+d 1");
}
@@ -273,15 +269,15 @@ class BahamutIRCdProto : public IRCDProto
/* SERVER */
void SendServer(Server *server)
{
- send_cmd(NULL, "SERVER %s %d :%s", server->name, server->hops, server->desc);
+ send_cmd(NULL, "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str());
}
void SendConnect()
{
+ Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, "");
bahamut_cmd_pass(uplink_server->password);
bahamut_cmd_capab();
- me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, "");
- SendServer(me_server);
+ SendServer(Me);
bahamut_cmd_svinfo();
bahamut_cmd_burst();
}
@@ -299,7 +295,7 @@ class BahamutIRCdProto : public IRCDProto
u->Account()->Shrink("authenticationtoken");
u->Account()->Extend("authenticationtoken", new ExtensibleItemPointerArray<char>(sstrdup(svidbuf)));
- BotInfo *bi = findbot(Config.s_NickServ);
+ BotInfo *bi = NickServ;
u->SetMode(bi, UMODE_REGISTERED);
ircdproto->SendMode(bi, u, "+d %s", svidbuf);
}
@@ -575,11 +571,7 @@ int anope_event_436(const char *source, int ac, const char **av)
/* EVENT : SERVER */
int anope_event_server(const char *source, int ac, const char **av)
{
- if (!stricmp(av[1], "1")) {
- uplink = sstrdup(av[0]);
- }
-
- do_server(source, av[0], av[1], av[2], "");
+ do_server(source, av[0], atoi(av[1]), av[2], "");
return MOD_CONT;
}
@@ -711,8 +703,8 @@ int anope_event_error(const char *source, int ac, const char **av)
int anope_event_burst(const char *source, int ac, const char **av)
{
- Server *s;
- s = findserver(servlist, source);
+ Server *s = Server::Find(source ? source : "");
+
if (!ac) {
/* for future use - start burst */
} else {
@@ -720,9 +712,10 @@ int anope_event_burst(const char *source, int ac, const char **av)
* finished bursting. If there was no source, then our uplink
* server finished bursting. -GD
*/
- if (!s && serv_uplink)
- s = serv_uplink;
- finish_sync(s, 1);
+ if (!s)
+ s = Me->GetUplink();
+ if (s)
+ s->Sync(true);
}
return MOD_CONT;
}
@@ -737,73 +730,71 @@ bool ChannelModeFlood::IsValid(const std::string &value)
return false;
}
-void moduleAddIRCDMsgs() {
- Message *m;
-
- /* now add the commands */
- m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m);
- m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m);
- m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m);
- m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m);
- m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m);
- m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m);
- m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m);
- m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m);
- m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m);
- m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m);
- m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m);
- m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m);
- m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m);
- m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m);
- m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m);
- m = createMessage("SVSMODE", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m);
- m = createMessage("CS", anope_event_cs); addCoreMessage(IRCD,m);
- m = createMessage("HS", anope_event_hs); addCoreMessage(IRCD,m);
- m = createMessage("MS", anope_event_ms); addCoreMessage(IRCD,m);
- m = createMessage("NS", anope_event_ns); addCoreMessage(IRCD,m);
- m = createMessage("OS", anope_event_os); addCoreMessage(IRCD,m);
- m = createMessage("SJOIN", anope_event_sjoin); addCoreMessage(IRCD,m);
- m = createMessage("ERROR", anope_event_error); addCoreMessage(IRCD,m);
- m = createMessage("BURST", anope_event_burst); addCoreMessage(IRCD,m);
-}
-
-void moduleAddModes()
+void moduleAddIRCDMsgs()
+{
+ Anope::AddMessage("436", anope_event_436);
+ Anope::AddMessage("AWAY", anope_event_away);
+ Anope::AddMessage("JOIN", anope_event_join);
+ Anope::AddMessage("KICK", anope_event_kick);
+ Anope::AddMessage("KILL", anope_event_kill);
+ Anope::AddMessage("MODE", anope_event_mode);
+ Anope::AddMessage("MOTD", anope_event_motd);
+ Anope::AddMessage("NICK", anope_event_nick);
+ Anope::AddMessage("PART", anope_event_part);
+ Anope::AddMessage("PING", anope_event_ping);
+ Anope::AddMessage("PRIVMSG", anope_event_privmsg);
+ Anope::AddMessage("QUIT", anope_event_quit);
+ Anope::AddMessage("SERVER", anope_event_server);
+ Anope::AddMessage("SQUIT", anope_event_squit);
+ Anope::AddMessage("TOPIC", anope_event_topic);
+ Anope::AddMessage("WHOIS", anope_event_whois);
+ Anope::AddMessage("SVSMODE", anope_event_mode);
+ Anope::AddMessage("CAPAB", anope_event_capab);
+ Anope::AddMessage("CS", anope_event_cs);
+ Anope::AddMessage("HS", anope_event_hs);
+ Anope::AddMessage("MS", anope_event_ms);
+ Anope::AddMessage("NS", anope_event_ns);
+ Anope::AddMessage("OS", anope_event_os);
+ Anope::AddMessage("SJOIN", anope_event_sjoin);
+ Anope::AddMessage("ERROR", anope_event_error);
+ Anope::AddMessage("BURST", anope_event_burst);
+}
+
+static void AddModes()
{
/* Add user modes */
- ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, 'A'));
- ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R'));
- ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a'));
- ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
- ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
- ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r'));
- ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's'));
- ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
- ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd'));
+ ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, "UMODE_SERV_ADMIN", 'A'));
+ ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, "UMODE_REGPRIV", 'R'));
+ ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, "UMODE_ADMIN", 'a'));
+ ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i'));
+ ModeManager::AddUserMode(new UserMode(UMODE_OPER,"UMODE_OPER", 'o'));
+ ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, "UMODE_REGISTERED", 'r'));
+ ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, "UMODE_SNOMASK", 's'));
+ ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w'));
+ ModeManager::AddUserMode(new UserMode(UMODE_DEAF, "UMODE_DEAF", 'd'));
/* b/e/I */
ModeManager::AddChannelMode(new ChannelModeBan('b'));
/* v/h/o/a/q */
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', '+'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', '@'));
/* Add channel modes */
- ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i'));
ModeManager::AddChannelMode(new ChannelModeFlood('f'));
ModeManager::AddChannelMode(new ChannelModeKey('k'));
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p'));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p'));
ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, "CMODE_REGMODERATED", 'M'));
ModeManager::AddChannelMode(new ChannelModeOper('O'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R'));
}
class ProtoBahamut : public Module
@@ -824,7 +815,7 @@ class ProtoBahamut : public Module
Capab.SetFlag(c[i]);
moduleAddIRCDMsgs();
- moduleAddModes();
+ AddModes();
pmodule_ircd_proto(&ircd_proto);
diff --git a/src/protocol/inspircd11.c b/src/protocol/inspircd11.cpp
index b5c55cfa8..09c329f0c 100644
--- a/src/protocol/inspircd11.c
+++ b/src/protocol/inspircd11.cpp
@@ -14,7 +14,7 @@
/*************************************************************************/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
#include "hashcomp.h"
#ifndef _WIN32
@@ -40,7 +40,7 @@ IRCDVar myIrcd[] = {
"+ao", /* Channel Umode used by Botserv bots */
1, /* SVSNICK */
1, /* Vhost */
- 1, /* Supports SGlines */
+ 1, /* Supports SNlines */
1, /* Supports SQlines */
1, /* Supports SZlines */
4, /* Number of server args */
@@ -97,7 +97,7 @@ void inspircd_cmd_chghost(const char *nick, const char *vhost)
send_cmd(Config.s_OperServ, "CHGHOST %s %s", nick, vhost);
}
else
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST not loaded!");
+ ircdproto->SendGlobops(OperServ, "CHGHOST not loaded!");
}
int anope_event_idle(const char *source, int ac, const char **av)
@@ -119,9 +119,9 @@ void inspircd_cmd_pass(const char *pass)
class InspIRCdProto : public IRCDProto
{
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
- send_cmd(Config.s_OperServ, "GLINE %s@%s", ak->user, ak->host);
+ send_cmd(Config.s_OperServ, "GLINE %s", x->Mask.c_str());
}
void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic)
@@ -142,13 +142,13 @@ class InspIRCdProto : public IRCDProto
}
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = ak->expires - time(NULL);
+ time_t timeleft = x->Expires - time(NULL);
if (timeleft > 172800)
timeleft = 172800;
- send_cmd(Config.ServerName, "ADDLINE G %s@%s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL)), static_cast<long>(timeleft), ak->reason);
+ send_cmd(Config.ServerName, "ADDLINE G %s %s %ld %ld :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), static_cast<long>(timeleft), x->Reason.c_str());
}
void SendSVSKillInternal(BotInfo *source, User *user, const char *buf)
@@ -204,7 +204,7 @@ class InspIRCdProto : public IRCDProto
/* SERVER services-dev.chatspike.net password 0 :Description here */
void SendServer(Server *server)
{
- send_cmd(Config.ServerName, "SERVER %s %s %d :%s", server->name, currentpass, server->hops, server->desc);
+ send_cmd(Config.ServerName, "SERVER %s %s %d :%s", server->GetName().c_str(), currentpass, server->GetHops(), server->GetDescription().c_str());
}
/* JOIN */
@@ -214,19 +214,15 @@ class InspIRCdProto : public IRCDProto
}
/* UNSQLINE */
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(Config.s_OperServ, "QLINE %s", user.c_str());
+ send_cmd(Config.s_OperServ, "QLINE %s", x->Mask.c_str());
}
/* SQLINE */
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(Config.ServerName, "ADDLINE Q %s %s %ld 0 :%s", mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), reason.c_str());
+ send_cmd(Config.ServerName, "ADDLINE Q %s %s %ld 0 :%s", x->Mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SQUIT */
@@ -248,11 +244,11 @@ class InspIRCdProto : public IRCDProto
void SendConnect()
{
+ Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, "");
inspircd_cmd_pass(uplink_server->password);
- me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, "");
- SendServer(me_server);
+ SendServer(Me);
send_cmd(NULL, "BURST");
- send_cmd(Config.ServerName, "VERSION :Anope-%s %s :%s - %s (%s) -- %s", version_number, Config.ServerName, ircd->name, version_flags, Config.EncModuleList.begin()->c_str(), version_build);
+ send_cmd(Config.ServerName, "VERSION :Anope-%s %s :%s - (%s) -- %s", version_number, Config.ServerName, ircd->name, Config.EncModuleList.begin()->c_str(), version_build);
}
/* CHGIDENT */
@@ -264,7 +260,7 @@ class InspIRCdProto : public IRCDProto
}
send_cmd(Config.s_OperServ, "CHGIDENT %s %s", nick, vIdent);
} else {
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT not loaded!");
+ ircdproto->SendGlobops(OperServ, "CHGIDENT not loaded!");
}
}
@@ -281,21 +277,21 @@ class InspIRCdProto : public IRCDProto
}
/* UNSZLINE */
- void SendSZLineDel(SXLine *sx)
+ void SendSZLineDel(XLine *x)
{
- send_cmd(Config.s_OperServ, "ZLINE %s", sx->mask);
+ send_cmd(Config.s_OperServ, "ZLINE %s", x->Mask.c_str());
}
/* SZLINE */
- void SendSZLine(SXLine *sx)
+ void SendSZLine(XLine *x)
{
- send_cmd(Config.ServerName, "ADDLINE Z %s %s %ld 0 :%s", sx->mask, sx->by, static_cast<long>(time(NULL)), sx->reason);
+ send_cmd(Config.ServerName, "ADDLINE Z %s %s %ld 0 :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SVSMODE +- */
void SendUnregisteredNick(User *u)
{
- u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ u->RemoveMode(NickServ, UMODE_REGISTERED);
}
void SendSVSJoin(const char *source, const char *nick, const char *chan, const char *param)
@@ -325,7 +321,7 @@ class InspIRCdProto : public IRCDProto
u->Account()->Shrink("authenticationtoken");
u->Account()->Extend("authenticationtoken", new ExtensibleItemPointerArray<char>(sstrdup(svidbuf)));
- u->SetMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ u->SetMode(NickServ, UMODE_REGISTERED);
}
} ircd_proto;
@@ -823,10 +819,7 @@ int anope_event_chghost(const char *source, int ac, const char **av)
/* EVENT: SERVER */
int anope_event_server(const char *source, int ac, const char **av)
{
- if (!stricmp(av[1], "1")) {
- uplink = sstrdup(av[0]);
- }
- do_server(source, av[0], av[1], av[2], "");
+ do_server(source, av[0], atoi(av[1]), av[2], "");
return MOD_CONT;
}
@@ -923,7 +916,7 @@ int anope_event_capab(const char *source, int ac, const char **av)
ModeManager::AddChannelMode(new ChannelModeInvite('I'));
continue;
default:
- ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, "", modebuf[t]));
}
}
@@ -936,7 +929,7 @@ int anope_event_capab(const char *source, int ac, const char **av)
ModeManager::AddChannelMode(new ChannelModeKey('k'));
continue;
default:
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t]));
}
}
@@ -950,13 +943,13 @@ int anope_event_capab(const char *source, int ac, const char **av)
ModeManager::AddChannelMode(new ChannelModeFlood('f'));
continue;
case 'l':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l', true));
continue;
case 'L':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, "CMODE_REDIRECT", 'L', true));
continue;
default:
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t], true));
}
}
@@ -966,67 +959,67 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modebuf[t])
{
case 'i':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i'));
continue;
case 'm':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm'));
continue;
case 'n':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n'));
continue;
case 'p':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p'));
continue;
case 's':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's'));
continue;
case 't':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't'));
continue;
case 'r':
ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
continue;
case 'c':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c'));
continue;
case 'u':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, "CMODE_AUDITORIUM", 'u'));
continue;
case 'z':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, "CMODE_SSL", 'z'));
continue;
case 'A':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, 'A'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, "CMODE_ALLINVITE", 'A'));
continue;
case 'C':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, "CMODE_NOCTCP", 'C'));
continue;
case 'G':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, "CMODE_FILTER", 'G'));
continue;
case 'K':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, "CMODE_NOKNOCK", 'K'));
continue;
case 'N':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, "CMODE_NONICK", 'N'));
continue;
case 'O':
ModeManager::AddChannelMode(new ChannelModeOper('O'));
continue;
case 'Q':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, "CMODE_NOKICK", 'Q'));
continue;
case 'R':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R'));
continue;
case 'S':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, "CMODE_STRIPCOLOR", 'S'));
continue;
case 'V':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, 'V'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, "CMODE_NOINVITE", 'V'));
continue;
default:
- ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_END, "", modebuf[t]));
}
}
}
@@ -1040,19 +1033,19 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modes[t])
{
case 'q':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '~'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', '~'));
continue;
case 'a':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '&'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, "CMODE_PROTECT", 'a', '&'));
continue;
case 'o':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', '@'));
continue;
case 'h':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, "CMODE_HALFOP", 'h', '%'));
continue;
case 'v':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', '+'));
continue;
}
}
@@ -1083,13 +1076,13 @@ int anope_event_capab(const char *source, int ac, const char **av)
return MOD_STOP;
}
if (!has_svsholdmod) {
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "SVSHOLD missing, Usage disabled until module is loaded.");
+ ircdproto->SendGlobops(OperServ, "SVSHOLD missing, Usage disabled until module is loaded.");
}
if (!has_chghostmod) {
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST missing, Usage disabled until module is loaded.");
+ ircdproto->SendGlobops(OperServ, "CHGHOST missing, Usage disabled until module is loaded.");
}
if (!has_chgidentmod) {
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT missing, Usage disabled until module is loaded.");
+ ircdproto->SendGlobops(OperServ, "CHGIDENT missing, Usage disabled until module is loaded.");
}
ircd->svshold = has_svsholdmod;
}
@@ -1100,45 +1093,44 @@ int anope_event_capab(const char *source, int ac, const char **av)
int anope_event_endburst(const char *source, int ac, const char **av)
{
- finish_sync(serv_uplink, 1);
+ Me->GetUplink()->Sync(true);
return MOD_CONT;
}
-void moduleAddIRCDMsgs() {
- Message *m;
-
- m = createMessage("ENDBURST", anope_event_endburst); addCoreMessage(IRCD, m);
- m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m);
- m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m);
- m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m);
- m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m);
- m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m);
- m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m);
- m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m);
- m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m);
- m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m);
- m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m);
- m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m);
- m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m);
- m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m);
- m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m);
- m = createMessage("RSQUIT", anope_event_rsquit); addCoreMessage(IRCD,m);
- m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m);
- m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m);
- m = createMessage("SVSMODE", anope_event_mode) ;addCoreMessage(IRCD,m);
- m = createMessage("FHOST", anope_event_chghost); addCoreMessage(IRCD,m);
- m = createMessage("CHGIDENT", anope_event_chgident); addCoreMessage(IRCD,m);
- m = createMessage("FNAME", anope_event_chgname); addCoreMessage(IRCD,m);
- m = createMessage("SETHOST", anope_event_sethost); addCoreMessage(IRCD,m);
- m = createMessage("SETIDENT", anope_event_setident); addCoreMessage(IRCD,m);
- m = createMessage("SETNAME", anope_event_setname); addCoreMessage(IRCD,m);
- m = createMessage("FJOIN", anope_event_fjoin); addCoreMessage(IRCD,m);
- m = createMessage("FMODE", anope_event_fmode); addCoreMessage(IRCD,m);
- m = createMessage("FTOPIC", anope_event_ftopic); addCoreMessage(IRCD,m);
- m = createMessage("OPERTYPE", anope_event_opertype); addCoreMessage(IRCD,m);
- m = createMessage("IDLE", anope_event_idle); addCoreMessage(IRCD,m);
+void moduleAddIRCDMsgs()
+{
+ Anope::AddMessage("ENDBURST", anope_event_endburst);
+ Anope::AddMessage("436", anope_event_436);
+ Anope::AddMessage("AWAY", anope_event_away);
+ Anope::AddMessage("JOIN", anope_event_join);
+ Anope::AddMessage("KICK", anope_event_kick);
+ Anope::AddMessage("KILL", anope_event_kill);
+ Anope::AddMessage("MODE", anope_event_mode);
+ Anope::AddMessage("MOTD", anope_event_motd);
+ Anope::AddMessage("NICK", anope_event_nick);
+ Anope::AddMessage("CAPAB",anope_event_capab);
+ Anope::AddMessage("PART", anope_event_part);
+ Anope::AddMessage("PING", anope_event_ping);
+ Anope::AddMessage("PRIVMSG", anope_event_privmsg);
+ Anope::AddMessage("QUIT", anope_event_quit);
+ Anope::AddMessage("SERVER", anope_event_server);
+ Anope::AddMessage("SQUIT", anope_event_squit);
+ Anope::AddMessage("RSQUIT", anope_event_rsquit);
+ Anope::AddMessage("TOPIC", anope_event_topic);
+ Anope::AddMessage("WHOIS", anope_event_whois);
+ Anope::AddMessage("SVSMODE", anope_event_mode);
+ Anope::AddMessage("FHOST", anope_event_chghost);
+ Anope::AddMessage("CHGIDENT", anope_event_chgident);
+ Anope::AddMessage("FNAME", anope_event_chgname);
+ Anope::AddMessage("SETHOST", anope_event_sethost);
+ Anope::AddMessage("SETIDENT", anope_event_setident);
+ Anope::AddMessage("SETNAME", anope_event_setname);
+ Anope::AddMessage("FJOIN", anope_event_fjoin);
+ Anope::AddMessage("FMODE", anope_event_fmode);
+ Anope::AddMessage("FTOPIC", anope_event_ftopic);
+ Anope::AddMessage("OPERTYPE", anope_event_opertype);
+ Anope::AddMessage("IDLE", anope_event_idle);
}
bool ChannelModeFlood::IsValid(const std::string &value)
@@ -1153,13 +1145,13 @@ bool ChannelModeFlood::IsValid(const std::string &value)
static void AddModes()
{
- ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, 'g'));
- ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h'));
- ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
- ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
- ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r'));
- ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
- ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
+ ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, "UMODE_CALLERID", 'g'));
+ ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, "UMODE_HELPOP", 'h'));
+ ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i'));
+ ModeManager::AddUserMode(new UserMode(UMODE_OPER, "UMODE_OPER", 'o'));
+ ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, "UMODE_REGISTERED", 'r'));
+ ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w'));
+ ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, "UMODE_CLOAK", 'x'));
}
class ProtoInspIRCd : public Module
@@ -1171,7 +1163,7 @@ class ProtoInspIRCd : public Module
this->SetVersion(VERSION_STRING);
this->SetType(PROTOCOL);
- pmodule_ircd_version("inspircdIRCd 1.1");
+ pmodule_ircd_version("InspIRCd 1.1");
pmodule_ircd_var(myIrcd);
pmodule_ircd_useTSMode(0);
diff --git a/src/protocol/inspircd12.cpp b/src/protocol/inspircd12.cpp
index 4ad390f00..9a9f88fea 100644
--- a/src/protocol/inspircd12.cpp
+++ b/src/protocol/inspircd12.cpp
@@ -14,7 +14,7 @@
/*************************************************************************/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
#include "hashcomp.h"
#ifndef _WIN32
@@ -40,7 +40,7 @@ IRCDVar myIrcd[] = {
"+ao", /* Channel Umode used by Botserv bots */
1, /* SVSNICK */
1, /* Vhost */
- 0, /* Supports SGlines */
+ 0, /* Supports SNlines */
1, /* Supports SQlines */
1, /* Supports SZlines */
4, /* Number of server args */
@@ -94,11 +94,11 @@ void inspircd_cmd_chghost(const char *nick, const char *vhost)
{
if (has_chghostmod != 1)
{
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST not loaded!");
+ ircdproto->SendGlobops(OperServ, "CHGHOST not loaded!");
return;
}
- BotInfo *bi = findbot(Config.s_OperServ);
+ BotInfo *bi = OperServ;
send_cmd(bi->uid, "CHGHOST %s %s", nick, vhost);
}
@@ -123,10 +123,10 @@ void inspircd_cmd_pass(const char *pass)
class InspIRCdProto : public IRCDProto
{
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
- BotInfo *bi = findbot(Config.s_OperServ);
- send_cmd(bi->uid, "GLINE %s@%s", ak->user, ak->host);
+ BotInfo *bi = OperServ;
+ send_cmd(bi->uid, "GLINE %s", x->Mask.c_str());
}
void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic)
@@ -147,14 +147,14 @@ class InspIRCdProto : public IRCDProto
}
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = ak->expires - time(NULL);
- if (timeleft > 172800 || !ak->expires)
+ time_t timeleft = x->Expires - time(NULL);
+ if (timeleft > 172800 || !x->Expires)
timeleft = 172800;
- BotInfo *bi = findbot(Config.s_OperServ);
- send_cmd(bi->uid, "ADDLINE G %s@%s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL)), static_cast<long>(timeleft), ak->reason);
+ BotInfo *bi = OperServ;
+ send_cmd(bi->uid, "ADDLINE G %s@%s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(time(NULL)), static_cast<long>(timeleft), x->Reason.c_str());
}
void SendSVSKillInternal(BotInfo *source, User *user, const char *buf)
@@ -209,7 +209,7 @@ class InspIRCdProto : public IRCDProto
/* SERVER services-dev.chatspike.net password 0 :Description here */
void SendServer(Server *server)
{
- send_cmd(NULL, "SERVER %s %s %d %s :%s", server->name, currentpass, server->hops, server->suid, server->desc);
+ send_cmd(NULL, "SERVER %s %s %d %s :%s", server->GetName().c_str(), currentpass, server->GetHops(), server->GetSID().c_str(), server->GetDescription().c_str());
}
/* JOIN */
@@ -219,19 +219,15 @@ class InspIRCdProto : public IRCDProto
}
/* UNSQLINE */
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(TS6SID, "DELLINE Q %s", user.c_str());
+ send_cmd(TS6SID, "DELLINE Q %s", x->Mask.c_str());
}
/* SQLINE */
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(TS6SID, "ADDLINE Q %s %s %ld 0 :%s", mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), reason.c_str());
+ send_cmd(TS6SID, "ADDLINE Q %s %s %ld 0 :%s", x->Mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SQUIT */
@@ -252,11 +248,11 @@ class InspIRCdProto : public IRCDProto
void SendConnect()
{
+ Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, TS6SID);
inspircd_cmd_pass(uplink_server->password);
- me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, TS6SID);
- SendServer(me_server);
+ SendServer(Me);
send_cmd(TS6SID, "BURST");
- send_cmd(TS6SID, "VERSION :Anope-%s %s :%s - %s (%s) -- %s", version_number, Config.ServerName, ircd->name, version_flags, Config.EncModuleList.begin()->c_str(), version_build);
+ send_cmd(TS6SID, "VERSION :Anope-%s %s :%s - (%s) -- %s", version_number, Config.ServerName, ircd->name, Config.EncModuleList.begin()->c_str(), version_build);
}
/* CHGIDENT */
@@ -264,11 +260,11 @@ class InspIRCdProto : public IRCDProto
{
if (has_chgidentmod == 0)
{
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT not loaded!");
+ ircdproto->SendGlobops(OperServ, "CHGIDENT not loaded!");
}
else
{
- BotInfo *bi = findbot(Config.s_OperServ);
+ BotInfo *bi = OperServ;
send_cmd(bi->uid, "CHGIDENT %s %s", nick, vIdent);
}
}
@@ -276,33 +272,33 @@ class InspIRCdProto : public IRCDProto
/* SVSHOLD - set */
void SendSVSHold(const char *nick)
{
- BotInfo *bi = findbot(Config.s_OperServ);
+ BotInfo *bi = OperServ;
send_cmd(bi->uid, "SVSHOLD %s %u :%s", nick, static_cast<unsigned>(Config.NSReleaseTimeout), "Being held for registered user");
}
/* SVSHOLD - release */
void SendSVSHoldDel(const char *nick)
{
- BotInfo *bi = findbot(Config.s_OperServ);
+ BotInfo *bi = OperServ;
send_cmd(bi->uid, "SVSHOLD %s", nick);
}
/* UNSZLINE */
- void SendSZLineDel(SXLine *sx)
+ void SendSZLineDel(XLine *x)
{
- send_cmd(TS6SID, "DELLINE Z %s", sx->mask);
+ send_cmd(TS6SID, "DELLINE Z %s", x->Mask.c_str());
}
/* SZLINE */
- void SendSZLine(SXLine *sx)
+ void SendSZLine(XLine *x)
{
- send_cmd(TS6SID, "ADDLINE Z %s %s %ld 0 :%s", sx->mask, sx->by, static_cast<long>(time(NULL)), sx->reason);
+ send_cmd(TS6SID, "ADDLINE Z %s %s %ld 0 :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SVSMODE -r */
void SendUnregisteredNick(User *u)
{
- u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ u->RemoveMode(NickServ, UMODE_REGISTERED);
}
void SendSVSJoin(const char *source, const char *nick, const char *chan, const char *param)
@@ -362,7 +358,7 @@ class InspIRCdProto : public IRCDProto
if (!u->Account())
return;
- u->SetMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ u->SetMode(NickServ, UMODE_REGISTERED);
}
} ircd_proto;
@@ -397,8 +393,8 @@ int anope_event_mode(const char *source, int ac, const char **av)
users modes, we have to kludge this
as it slightly breaks RFC1459
*/
- User *u = find_byuid(source);
- User *u2 = find_byuid(av[0]);
+ User *u = finduser(source);
+ User *u2 = finduser(av[0]);
// This can happen with server-origin modes.
if (u == NULL)
@@ -554,7 +550,7 @@ int anope_event_fjoin(const char *source, int ac, const char **av)
}
buf.erase(buf.begin());
- User *u = find_byuid(buf);
+ User *u = finduser(buf);
if (!u)
{
Alog(LOG_DEBUG) << "FJOIN for nonexistant user " << buf << " on " << c->name;
@@ -646,7 +642,7 @@ int anope_event_topic(const char *source, int ac, const char **av)
{
Channel *c = findchan(av[0]);
time_t topic_time = time(NULL);
- User *u = find_byuid(source);
+ User *u = finduser(source);
if (!c)
{
@@ -688,12 +684,10 @@ int anope_event_squit(const char *source, int ac, const char **av)
int anope_event_rsquit(const char *source, int ac, const char **av)
{
/* On InspIRCd we must send a SQUIT when we recieve RSQUIT for a server we have juped */
- Server *s = findserver(servlist, av[0]);
- if (!s)
- s = findserver_uid(servlist, av[0]);
+ Server *s = Server::Find(av[0]);
if (s && s->HasFlag(SERVER_JUPED))
{
- send_cmd(TS6SID, "SQUIT %s :%s", s->suid, ac > 1 ? av[1] : "");
+ send_cmd(TS6SID, "SQUIT %s :%s", s->GetSID().c_str(), ac > 1 ? av[1] : "");
}
do_squit(source, ac, av);
@@ -710,7 +704,7 @@ int anope_event_quit(const char *source, int ac, const char **av)
int anope_event_kill(const char *source, int ac, const char **av)
{
- User *u = find_byuid(av[0]);
+ User *u = finduser(av[0]);
BotInfo *bi = findbot(av[0]);
m_kill(u ? u->nick.c_str() : (bi ? bi->nick : av[0]), av[1]);
return MOD_CONT;
@@ -837,7 +831,7 @@ int anope_event_uid(const char *source, int ac, const char **av)
User *user;
NickAlias *na;
struct in_addr addy;
- Server *s = findserver_uid(servlist, source);
+ Server *s = Server::Find(source ? source : "");
uint32 *ad = reinterpret_cast<uint32 *>(&addy);
int ts = strtoul(av[1], NULL, 10);
@@ -846,11 +840,11 @@ int anope_event_uid(const char *source, int ac, const char **av)
user = prev_u_intro;
prev_u_intro = NULL;
if (user) na = findnick(user->nick);
- if (user && user->server->sync == SSYNC_IN_PROGRESS && (!na || na->nc != user->Account()))
+ if (user && !user->server->IsSynced() && (!na || na->nc != user->Account()))
{
validate_user(user);
if (user->HasMode(UMODE_REGISTERED))
- user->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ user->RemoveMode(NickServ, UMODE_REGISTERED);
}
user = NULL;
@@ -858,14 +852,14 @@ int anope_event_uid(const char *source, int ac, const char **av)
user = do_nick("", av[2], /* nick */
av[5], /* username */
av[3], /* realhost */
- s->name, /* server */
+ s->GetName().c_str(), /* server */
av[ac - 1], /* realname */
ts, htonl(*ad), av[4], av[0]);
if (user)
{
UserSetInternalModes(user, 1, &av[8]);
user->SetCloakedHost(av[4]);
- if (user->server->sync == SSYNC_IN_PROGRESS)
+ if (!user->server->IsSynced())
{
prev_u_intro = user;
}
@@ -903,24 +897,17 @@ int anope_event_chghost(const char *source, int ac, const char **av)
*/
int anope_event_server(const char *source, int ac, const char **av)
{
- if (!stricmp(av[2], "0"))
- {
- uplink = sstrdup(av[0]);
- }
- do_server(source, av[0], av[2], av[4], av[3]);
+ do_server(source, av[0], atoi(av[2]), av[4], av[3]);
return MOD_CONT;
}
int anope_event_privmsg(const char *source, int ac, const char **av)
{
- User *u = find_byuid(source);
- BotInfo *bi = findbot(av[0]);
-
- if (!u)
+ if (!finduser(source))
return MOD_CONT; // likely a message from a server, which can happen.
- m_privmsg(u->nick.c_str(), bi ? bi->nick: av[0], av[1]);
+ m_privmsg(source, av[0], av[1]);
return MOD_CONT;
}
@@ -944,7 +931,7 @@ int anope_event_metadata(const char *source, int ac, const char **av)
return MOD_CONT;
else if (!strcmp(av[1], "accountname"))
{
- if ((u = find_byuid(av[0])))
+ if ((u = finduser(av[0])))
{
/* Identify the user for this account - Adam */
u->AutoID(av[2]);
@@ -1026,14 +1013,14 @@ int anope_event_capab(const char *source, int ac, const char **av)
continue;
/* InspIRCd sends q and a here if they have no prefixes */
case 'q':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '@'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', '@'));
continue;
case 'a':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT , 'a', '@'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT , "CMODE_PROTECT", 'a', '@'));
continue;
// XXX list modes needs a bit of a rewrite, we need to be able to support +g here
default:
- ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, "", modebuf[t]));
}
}
@@ -1046,7 +1033,7 @@ int anope_event_capab(const char *source, int ac, const char **av)
ModeManager::AddChannelMode(new ChannelModeKey('k'));
continue;
default:
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t]));
}
}
@@ -1056,25 +1043,25 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modebuf[t])
{
case 'F':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NICKFLOOD, 'F', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NICKFLOOD, "CMODE_NICKFLOOD", 'F', true));
continue;
case 'J':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NOREJOIN, 'J', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NOREJOIN, "CMODE_NOREJOIN", 'J', true));
continue;
case 'L':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, "CMODE_REDIRECT", 'L', true));
continue;
case 'f':
ModeManager::AddChannelMode(new ChannelModeFlood('f', true));
continue;
case 'j':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, 'j', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, "CMODE_JOINFLOOD", 'j', true));
continue;
case 'l':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l', true));
continue;
default:
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t], true));
}
}
@@ -1084,79 +1071,79 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modebuf[t])
{
case 'A':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, 'A'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, "CMODE_ALLINVITE", 'A'));
continue;
case 'B':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCAPS, 'B'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCAPS, "CMODE_BLOCKCAPS", 'B'));
continue;
case 'C':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, "CMODE_NOCTCP", 'C'));
continue;
case 'D':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_DELAYEDJOIN, 'D'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_DELAYEDJOIN, "CMODE_DELAYEDJOIN", 'D'));
continue;
case 'G':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, "CMODE_FILTER", 'G'));
continue;
case 'K':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, "CMODE_NOKNOCK", 'K'));
continue;
case 'M':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, "CMODE_REGMODERATED", 'M'));
continue;
case 'N':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, "CMODE_NONICK", 'N'));
continue;
case 'O':
ModeManager::AddChannelMode(new ChannelModeOper('O'));
continue;
case 'P':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, "CMODE_PERM", 'P'));
continue;
case 'Q':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, "CMODE_NOKICK", 'Q'));
continue;
case 'R':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R'));
continue;
case 'S':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, "CMODE_STRIPCOLOR", 'S'));
continue;
case 'T':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, 'T'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, "CMODE_NONOTICE", 'T'));
continue;
case 'c':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c'));
continue;
case 'i':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i'));
continue;
case 'm':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm'));
continue;
case 'n':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n'));
continue;
case 'p':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p'));
continue;
case 'r':
ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
continue;
case 's':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's'));
continue;
case 't':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't'));
continue;
case 'u':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, "CMODE_AUDITORIUM", 'u'));
continue;
case 'z':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, "CMODE_SSL", 'z'));
continue;
default:
- ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_END, "", modebuf[t]));
}
}
}
@@ -1173,64 +1160,64 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modebuf[t])
{
case 'h':
- ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h'));
+ ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, "UMODE_HELPOP", 'h'));
continue;
case 's':
- ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, 'S'));
+ ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, "UMODE_STRIPCOLOR", 'S'));
continue;
case 'B':
- ModeManager::AddUserMode(new UserMode(UMODE_BOT, 'B'));
+ ModeManager::AddUserMode(new UserMode(UMODE_BOT, "UMODE_BOT", 'B'));
continue;
case 'G':
- ModeManager::AddUserMode(new UserMode(UMODE_FILTER, 'G'));
+ ModeManager::AddUserMode(new UserMode(UMODE_FILTER, "UMODE_FILTER", 'G'));
continue;
case 'H':
- ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, 'H'));
+ ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, "UMODE_HIDEOPER", 'H'));
continue;
case 'I':
- ModeManager::AddUserMode(new UserMode(UMODE_PRIV, 'I'));
+ ModeManager::AddUserMode(new UserMode(UMODE_PRIV, "UMODE_PRIV", 'I'));
continue;
case 'Q':
- ModeManager::AddUserMode(new UserMode(UMODE_HIDDEN, 'Q'));
+ ModeManager::AddUserMode(new UserMode(UMODE_HIDDEN, "UMODE_HIDDEN", 'Q'));
continue;
case 'R':
- ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R'));
+ ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, "UMODE_REGPRIV", 'R'));
continue;
case 'S':
- ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, 'S'));
+ ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, "UMODE_STRIPCOLOR", 'S'));
continue;
case 'W':
- ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, 'W'));
+ ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, "UMODE_WHOIS", 'W'));
continue;
case 'c':
- ModeManager::AddUserMode(new UserMode(UMODE_COMMONCHANS, 'c'));
+ ModeManager::AddUserMode(new UserMode(UMODE_COMMONCHANS, "UMODE_COMMONCHANS", 'c'));
continue;
case 'g':
- ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, 'g'));
+ ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, "UMODE_CALLERID", 'g'));
continue;
case 'i':
- ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
+ ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i'));
continue;
case 'k':
- ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, 'k'));
+ ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, "UMODE_PROTECTED", 'k'));
continue;
case 'o':
- ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
+ ModeManager::AddUserMode(new UserMode(UMODE_OPER, "UMODE_OPER", 'o'));
continue;
case 'r':
- ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r'));
+ ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, "UMODE_REGISTERED", 'r'));
continue;
case 'w':
- ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
+ ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w'));
continue;
case 'x':
- ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
+ ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, "UMODE_CLOAK", 'x'));
continue;
case 'd':
- ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd'));
+ ModeManager::AddUserMode(new UserMode(UMODE_DEAF, "UMODE_DEAF", 'd'));
continue;
default:
- ModeManager::AddUserMode(new UserMode(UMODE_END, modebuf[t]));
+ ModeManager::AddUserMode(new UserMode(UMODE_END, "", modebuf[t]));
}
}
}
@@ -1245,19 +1232,19 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modes[t])
{
case 'q':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', chars[t]));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', chars[t]));
continue;
case 'a':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', chars[t]));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, "CMODE_PROTECT", 'a', chars[t]));
continue;
case 'o':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', chars[t]));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', chars[t]));
continue;
case 'h':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', chars[t]));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, "CMODE_HALFOP", 'h', chars[t]));
continue;
case 'v':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', chars[t]));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', chars[t]));
continue;
}
}
@@ -1288,13 +1275,13 @@ int anope_event_capab(const char *source, int ac, const char **av)
return MOD_STOP;
}
if (!has_svsholdmod) {
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "SVSHOLD missing, Usage disabled until module is loaded.");
+ ircdproto->SendGlobops(OperServ, "SVSHOLD missing, Usage disabled until module is loaded.");
}
if (!has_chghostmod) {
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST missing, Usage disabled until module is loaded.");
+ ircdproto->SendGlobops(OperServ, "CHGHOST missing, Usage disabled until module is loaded.");
}
if (!has_chgidentmod) {
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT missing, Usage disabled until module is loaded.");
+ ircdproto->SendGlobops(OperServ, "CHGIDENT missing, Usage disabled until module is loaded.");
}
ircd->svshold = has_svsholdmod;
}
@@ -1308,7 +1295,8 @@ int anope_event_endburst(const char *source, int ac, const char **av)
{
NickAlias *na;
User *u = prev_u_intro;
- Server *s = findserver_uid(servlist, source);
+ Server *s = Server::Find(source ? source : "");
+
if (!s)
{
throw new CoreException("Got ENDBURST without a source");
@@ -1318,56 +1306,55 @@ int anope_event_endburst(const char *source, int ac, const char **av)
* If not, validate the user. ~ Viper*/
prev_u_intro = NULL;
if (u) na = findnick(u->nick);
- if (u && u->server->sync == SSYNC_IN_PROGRESS && (!na || na->nc != u->Account()))
+ if (u && !u->server->IsSynced() && (!na || na->nc != u->Account()))
{
validate_user(u);
if (u->HasMode(UMODE_REGISTERED))
- u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ u->RemoveMode(NickServ, UMODE_REGISTERED);
}
- Alog() << "Processed ENDBURST for " << s->name;
+ Alog() << "Processed ENDBURST for " << s->GetName();
- finish_sync(s, 1);
+ s->Sync(true);
return MOD_CONT;
}
-void moduleAddIRCDMsgs() {
- Message *m;
-
- m = createMessage("ENDBURST", anope_event_endburst); addCoreMessage(IRCD, m);
- m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m);
- m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m);
- m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m);
- m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m);
- m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m);
- m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m);
- m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m);
- m = createMessage("UID", anope_event_uid); addCoreMessage(IRCD,m);
- m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m);
- m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m);
- m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m);
- m = createMessage("TIME", anope_event_time); addCoreMessage(IRCD,m);
- m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m);
- m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m);
- m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m);
- m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m);
- m = createMessage("RSQUIT", anope_event_rsquit); addCoreMessage(IRCD,m);
- m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m);
- m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m);
- m = createMessage("SVSMODE", anope_event_mode) ;addCoreMessage(IRCD,m);
- m = createMessage("FHOST", anope_event_chghost); addCoreMessage(IRCD,m);
- m = createMessage("CHGIDENT", anope_event_chgident); addCoreMessage(IRCD,m);
- m = createMessage("FNAME", anope_event_chgname); addCoreMessage(IRCD,m);
- m = createMessage("SETHOST", anope_event_sethost); addCoreMessage(IRCD,m);
- m = createMessage("SETIDENT", anope_event_setident); addCoreMessage(IRCD,m);
- m = createMessage("SETNAME", anope_event_setname); addCoreMessage(IRCD,m);
- m = createMessage("FJOIN", anope_event_fjoin); addCoreMessage(IRCD,m);
- m = createMessage("FMODE", anope_event_fmode); addCoreMessage(IRCD,m);
- m = createMessage("FTOPIC", anope_event_ftopic); addCoreMessage(IRCD,m);
- m = createMessage("OPERTYPE", anope_event_opertype); addCoreMessage(IRCD,m);
- m = createMessage("IDLE", anope_event_idle); addCoreMessage(IRCD,m);
- m = createMessage("METADATA", anope_event_metadata); addCoreMessage(IRCD,m);
+void moduleAddIRCDMsgs()
+{
+ Anope::AddMessage("ENDBURST", anope_event_endburst);
+ Anope::AddMessage("436", anope_event_436);
+ Anope::AddMessage("AWAY", anope_event_away);
+ Anope::AddMessage("JOIN", anope_event_join);
+ Anope::AddMessage("KICK", anope_event_kick);
+ Anope::AddMessage("KILL", anope_event_kill);
+ Anope::AddMessage("MODE", anope_event_mode);
+ Anope::AddMessage("MOTD", anope_event_motd);
+ Anope::AddMessage("NICK", anope_event_nick);
+ Anope::AddMessage("UID", anope_event_uid);
+ Anope::AddMessage("CAPAB", anope_event_capab);
+ Anope::AddMessage("PART", anope_event_part);
+ Anope::AddMessage("PING", anope_event_ping);
+ Anope::AddMessage("TIME", anope_event_time);
+ Anope::AddMessage("PRIVMSG", anope_event_privmsg);
+ Anope::AddMessage("QUIT", anope_event_quit);
+ Anope::AddMessage("SERVER", anope_event_server);
+ Anope::AddMessage("SQUIT", anope_event_squit);
+ Anope::AddMessage("RSQUIT", anope_event_rsquit);
+ Anope::AddMessage("TOPIC", anope_event_topic);
+ Anope::AddMessage("WHOIS", anope_event_whois);
+ Anope::AddMessage("SVSMODE", anope_event_mode);
+ Anope::AddMessage("FHOST", anope_event_chghost);
+ Anope::AddMessage("CHGIDENT", anope_event_chgident);
+ Anope::AddMessage("FNAME", anope_event_chgname);
+ Anope::AddMessage("SETHOST", anope_event_sethost);
+ Anope::AddMessage("SETIDENT", anope_event_setident);
+ Anope::AddMessage("SETNAME", anope_event_setname);
+ Anope::AddMessage("FJOIN", anope_event_fjoin);
+ Anope::AddMessage("FMODE", anope_event_fmode);
+ Anope::AddMessage("FTOPIC", anope_event_ftopic);
+ Anope::AddMessage("OPERTYPE", anope_event_opertype);
+ Anope::AddMessage("IDLE", anope_event_idle);
+ Anope::AddMessage("METADATA", anope_event_metadata);
}
bool ChannelModeFlood::IsValid(const std::string &value)
@@ -1413,7 +1400,7 @@ class ProtoInspIRCd : public Module
/* InspIRCd 1.2 doesn't set -r on nick change, remove -r here. Note that if we have to set +r later
* this will cancel out this -r, resulting in no mode changes.
*/
- u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ u->RemoveMode(NickServ, UMODE_REGISTERED);
}
};
diff --git a/src/protocol/inspircd20.cpp b/src/protocol/inspircd20.cpp
index 4b37e8c1c..4d333658c 100644
--- a/src/protocol/inspircd20.cpp
+++ b/src/protocol/inspircd20.cpp
@@ -1,4 +1,4 @@
-/* inspircd 1.2 functions
+/* Inspircd 2.0 functions
*
* (C) 2003-2010 Anope Team
* Contact us at team@anope.org
@@ -14,7 +14,7 @@
/*************************************************************************/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
#include "hashcomp.h"
#ifndef _WIN32
@@ -40,7 +40,7 @@ IRCDVar myIrcd[] = {
"+ao", /* Channel Umode used by Botserv bots */
1, /* SVSNICK */
1, /* Vhost */
- 0, /* Supports SGlines */
+ 0, /* Supports SNlines */
1, /* Supports SQlines */
1, /* Supports SZlines */
4, /* Number of server args */
@@ -93,11 +93,11 @@ void inspircd_cmd_chghost(const char *nick, const char *vhost)
{
if (has_chghostmod != 1)
{
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST not loaded!");
+ ircdproto->SendGlobops(OperServ, "CHGHOST not loaded!");
return;
}
- BotInfo *bi = findbot(Config.s_OperServ);
+ BotInfo *bi = OperServ;
send_cmd(bi->uid, "CHGHOST %s %s", nick, vhost);
}
@@ -122,10 +122,10 @@ void inspircd_cmd_pass(const char *pass)
class InspIRCdProto : public IRCDProto
{
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
- BotInfo *bi = findbot(Config.s_OperServ);
- send_cmd(bi->uid, "GLINE %s@%s", ak->user, ak->host);
+ BotInfo *bi = OperServ;
+ send_cmd(bi->uid, "GLINE %s", x->Mask.c_str());
}
void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic)
@@ -146,14 +146,14 @@ class InspIRCdProto : public IRCDProto
}
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = ak->expires - time(NULL);
- if (timeleft > 172800 || !ak->expires)
+ time_t timeleft = x->Expires - time(NULL);
+ if (timeleft > 172800 || !x->Expires)
timeleft = 172800;
- BotInfo *bi = findbot(Config.s_OperServ);
- send_cmd(bi->uid, "ADDLINE G %s@%s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL)), static_cast<long>(timeleft), ak->reason);
+ BotInfo *bi = OperServ;
+ send_cmd(bi->uid, "ADDLINE G %s@%s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(time(NULL)), static_cast<long>(timeleft), x->Reason.c_str());
}
void SendSVSKillInternal(BotInfo *source, User *user, const char *buf)
@@ -208,7 +208,7 @@ class InspIRCdProto : public IRCDProto
/* SERVER services-dev.chatspike.net password 0 :Description here */
void SendServer(Server *server)
{
- send_cmd(NULL, "SERVER %s %s %d %s :%s", server->name, currentpass, server->hops, server->suid, server->desc);
+ send_cmd(NULL, "SERVER %s %s %d %s :%s", server->GetName().c_str(), currentpass, server->GetHops(), server->GetSID().c_str(), server->GetDescription().c_str());
}
/* JOIN */
@@ -218,19 +218,15 @@ class InspIRCdProto : public IRCDProto
}
/* UNSQLINE */
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(TS6SID, "DELLINE Q %s", user.c_str());
+ send_cmd(TS6SID, "DELLINE Q %s", x->Mask.c_str());
}
/* SQLINE */
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(TS6SID, "ADDLINE Q %s %s %ld 0 :%s", mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), reason.c_str());
+ send_cmd(TS6SID, "ADDLINE Q %s %s %ld 0 :%s", x->Mask.c_str(), Config.s_OperServ, static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SQUIT */
@@ -251,11 +247,11 @@ class InspIRCdProto : public IRCDProto
void SendConnect()
{
+ Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, TS6SID);
inspircd_cmd_pass(uplink_server->password);
- me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, TS6SID);
- SendServer(me_server);
+ SendServer(Me);
send_cmd(TS6SID, "BURST");
- send_cmd(TS6SID, "VERSION :Anope-%s %s :%s - %s (%s) -- %s", version_number, Config.ServerName, ircd->name, version_flags, Config.EncModuleList.begin()->c_str(), version_build);
+ send_cmd(TS6SID, "VERSION :Anope-%s %s :%s - (%s) -- %s", version_number, Config.ServerName, ircd->name, Config.EncModuleList.begin()->c_str(), version_build);
}
/* CHGIDENT */
@@ -263,11 +259,11 @@ class InspIRCdProto : public IRCDProto
{
if (has_chgidentmod == 0)
{
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT not loaded!");
+ ircdproto->SendGlobops(OperServ, "CHGIDENT not loaded!");
}
else
{
- BotInfo *bi = findbot(Config.s_OperServ);
+ BotInfo *bi = OperServ;
send_cmd(bi->uid, "CHGIDENT %s %s", nick, vIdent);
}
}
@@ -275,33 +271,33 @@ class InspIRCdProto : public IRCDProto
/* SVSHOLD - set */
void SendSVSHold(const char *nick)
{
- BotInfo *bi = findbot(Config.s_OperServ);
+ BotInfo *bi = OperServ;
send_cmd(bi->uid, "SVSHOLD %s %u :%s", nick, static_cast<unsigned>(Config.NSReleaseTimeout), "Being held for registered user");
}
/* SVSHOLD - release */
void SendSVSHoldDel(const char *nick)
{
- BotInfo *bi = findbot(Config.s_OperServ);
+ BotInfo *bi = OperServ;
send_cmd(bi->uid, "SVSHOLD %s", nick);
}
/* UNSZLINE */
- void SendSZLineDel(SXLine *sx)
+ void SendSZLineDel(XLine *x)
{
- send_cmd(TS6SID, "DELLINE Z %s", sx->mask);
+ send_cmd(TS6SID, "DELLINE Z %s", x->Mask.c_str());
}
/* SZLINE */
- void SendSZLine(SXLine *sx)
+ void SendSZLine(XLine *x)
{
- send_cmd(TS6SID, "ADDLINE Z %s %s %ld 0 :%s", sx->mask, sx->by, static_cast<long>(time(NULL)), sx->reason);
+ send_cmd(TS6SID, "ADDLINE Z %s %s %ld 0 :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SVSMODE -r */
void SendUnregisteredNick(User *u)
{
- u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ u->RemoveMode(NickServ, UMODE_REGISTERED);
}
void SendSVSJoin(const char *source, const char *nick, const char *chan, const char *param)
@@ -361,7 +357,7 @@ class InspIRCdProto : public IRCDProto
if (!u->Account())
return;
- u->SetMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ u->SetMode(NickServ, UMODE_REGISTERED);
}
} ircd_proto;
@@ -396,8 +392,8 @@ int anope_event_mode(const char *source, int ac, const char **av)
users modes, we have to kludge this
as it slightly breaks RFC1459
*/
- User *u = find_byuid(source);
- User *u2 = find_byuid(av[0]);
+ User *u = finduser(source);
+ User *u2 = finduser(av[0]);
// This can happen with server-origin modes.
if (u == NULL)
@@ -553,7 +549,7 @@ int anope_event_fjoin(const char *source, int ac, const char **av)
}
buf.erase(buf.begin());
- User *u = find_byuid(buf);
+ User *u = finduser(buf);
if (!u)
{
Alog(LOG_DEBUG) << "FJOIN for nonexistant user " << buf << " on " << c->name;
@@ -645,7 +641,7 @@ int anope_event_topic(const char *source, int ac, const char **av)
{
Channel *c = findchan(av[0]);
time_t topic_time = time(NULL);
- User *u = find_byuid(source);
+ User *u = finduser(source);
if (!c)
{
@@ -687,12 +683,10 @@ int anope_event_squit(const char *source, int ac, const char **av)
int anope_event_rsquit(const char *source, int ac, const char **av)
{
/* On InspIRCd we must send a SQUIT when we recieve RSQUIT for a server we have juped */
- Server *s = findserver(servlist, av[0]);
- if (!s)
- s = findserver_uid(servlist, av[0]);
+ Server *s = Server::Find(av[0]);
if (s && s->HasFlag(SERVER_JUPED))
{
- send_cmd(TS6SID, "SQUIT %s :%s", s->suid, ac > 1 ? av[1] : "");
+ send_cmd(TS6SID, "SQUIT %s :%s", s->GetSID().c_str(), ac > 1 ? av[1] : "");
}
do_squit(source, ac, av);
@@ -709,7 +703,7 @@ int anope_event_quit(const char *source, int ac, const char **av)
int anope_event_kill(const char *source, int ac, const char **av)
{
- User *u = find_byuid(av[0]);
+ User *u = finduser(av[0]);
BotInfo *bi = findbot(av[0]);
m_kill(u ? u->nick.c_str() : (bi ? bi->nick : av[0]), av[1]);
return MOD_CONT;
@@ -836,7 +830,7 @@ int anope_event_uid(const char *source, int ac, const char **av)
User *user;
NickAlias *na;
struct in_addr addy;
- Server *s = findserver_uid(servlist, source);
+ Server *s = Server::Find(source ? source : "");
uint32 *ad = reinterpret_cast<uint32 *>(&addy);
int ts = strtoul(av[1], NULL, 10);
@@ -845,11 +839,11 @@ int anope_event_uid(const char *source, int ac, const char **av)
user = prev_u_intro;
prev_u_intro = NULL;
if (user) na = findnick(user->nick);
- if (user && user->server->sync == SSYNC_IN_PROGRESS && (!na || na->nc != user->Account()))
+ if (user && !user->server->IsSynced() && (!na || na->nc != user->Account()))
{
validate_user(user);
if (user->HasMode(UMODE_REGISTERED))
- user->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ user->RemoveMode(NickServ, UMODE_REGISTERED);
}
user = NULL;
@@ -857,14 +851,14 @@ int anope_event_uid(const char *source, int ac, const char **av)
user = do_nick("", av[2], /* nick */
av[5], /* username */
av[3], /* realhost */
- s->name, /* server */
+ s->GetName().c_str(), /* server */
av[ac - 1], /* realname */
ts, htonl(*ad), av[4], av[0]);
if (user)
{
UserSetInternalModes(user, 1, &av[8]);
user->SetCloakedHost(av[4]);
- if (user->server->sync == SSYNC_IN_PROGRESS)
+ if (!user->server->IsSynced())
{
prev_u_intro = user;
}
@@ -902,24 +896,17 @@ int anope_event_chghost(const char *source, int ac, const char **av)
*/
int anope_event_server(const char *source, int ac, const char **av)
{
- if (!stricmp(av[2], "0"))
- {
- uplink = sstrdup(av[0]);
- }
- do_server(source, av[0], av[2], av[4], av[3]);
+ do_server(source, av[0], atoi(av[2]), av[4], av[3]);
return MOD_CONT;
}
int anope_event_privmsg(const char *source, int ac, const char **av)
{
- User *u = find_byuid(source);
- BotInfo *bi = findbot(av[0]);
-
- if (!u)
+ if (!finduser(source))
return MOD_CONT; // likely a message from a server, which can happen.
- m_privmsg(u->nick.c_str(), bi ? bi->nick: av[0], av[1]);
+ m_privmsg(source, av[0], av[1]);
return MOD_CONT;
}
@@ -943,7 +930,7 @@ int anope_event_metadata(const char *source, int ac, const char **av)
return MOD_CONT;
else if (!strcmp(av[1], "accountname"))
{
- if ((u = find_byuid(av[0])))
+ if ((u = finduser(av[0])))
{
/* Identify the user for this account - Adam */
u->AutoID(av[2]);
@@ -1025,14 +1012,14 @@ int anope_event_capab(const char *source, int ac, const char **av)
continue;
/* InspIRCd sends q and a here if they have no prefixes */
case 'q':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '@'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', '@'));
continue;
case 'a':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT , 'a', '@'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT , "CMODE_PROTECT", 'a', '@'));
continue;
// XXX list modes needs a bit of a rewrite, we need to be able to support +g here
default:
- ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, "", modebuf[t]));
}
}
@@ -1045,7 +1032,7 @@ int anope_event_capab(const char *source, int ac, const char **av)
ModeManager::AddChannelMode(new ChannelModeKey('k'));
continue;
default:
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t]));
}
}
@@ -1055,25 +1042,25 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modebuf[t])
{
case 'F':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NICKFLOOD, 'F', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NICKFLOOD, "CMODE_NICKFLOOD", 'F', true));
continue;
case 'J':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NOREJOIN, 'J', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NOREJOIN, "CMODE_NOREJOIN", 'J', true));
continue;
case 'L':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, "CMODE_REDIRECT", 'L', true));
continue;
case 'f':
ModeManager::AddChannelMode(new ChannelModeFlood('f', true));
continue;
case 'j':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, 'j', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, "CMODE_JOINFLOOD", 'j', true));
continue;
case 'l':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l', true));
continue;
default:
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t], true));
}
}
@@ -1083,79 +1070,79 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modebuf[t])
{
case 'A':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, 'A'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, "CMODE_ALLINVITE", 'A'));
continue;
case 'B':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCAPS, 'B'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCAPS, "CMODE_BLOCKCAPS", 'B'));
continue;
case 'C':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, "CMODE_NOCTCP", 'C'));
continue;
case 'D':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_DELAYEDJOIN, 'D'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_DELAYEDJOIN, "CMODE_DELAYEDJOIN", 'D'));
continue;
case 'G':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, "CMODE_FILTER", 'G'));
continue;
case 'K':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, "CMODE_NOKNOCK", 'K'));
continue;
case 'M':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, "CMODE_REGMODERATED", 'M'));
continue;
case 'N':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, "CMODE_NONICK", 'N'));
continue;
case 'O':
ModeManager::AddChannelMode(new ChannelModeOper('O'));
continue;
case 'P':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, "CMODE_PERM", 'P'));
continue;
case 'Q':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, "CMODE_NOKICK", 'Q'));
continue;
case 'R':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R'));
continue;
case 'S':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, "CMODE_STRIPCOLOR", 'S'));
continue;
case 'T':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, 'T'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, "CMODE_NONOTICE", 'T'));
continue;
case 'c':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c'));
continue;
case 'i':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i'));
continue;
case 'm':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm'));
continue;
case 'n':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n'));
continue;
case 'p':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p'));
continue;
case 'r':
ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
continue;
case 's':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's'));
continue;
case 't':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't'));
continue;
case 'u':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, "CMODE_AUDITORIUM", 'u'));
continue;
case 'z':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, "CMODE_SSL", 'z'));
continue;
default:
- ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_END, "", modebuf[t]));
}
}
}
@@ -1172,64 +1159,64 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modebuf[t])
{
case 'h':
- ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h'));
+ ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, "UMODE_HELPOP", 'h'));
continue;
case 's':
- ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, 'S'));
+ ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, "UMODE_STRIPCOLOR", 'S'));
continue;
case 'B':
- ModeManager::AddUserMode(new UserMode(UMODE_BOT, 'B'));
+ ModeManager::AddUserMode(new UserMode(UMODE_BOT, "UMODE_BOT", 'B'));
continue;
case 'G':
- ModeManager::AddUserMode(new UserMode(UMODE_FILTER, 'G'));
+ ModeManager::AddUserMode(new UserMode(UMODE_FILTER, "UMODE_FILTER", 'G'));
continue;
case 'H':
- ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, 'H'));
+ ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, "UMODE_HIDEOPER", 'H'));
continue;
case 'I':
- ModeManager::AddUserMode(new UserMode(UMODE_PRIV, 'I'));
+ ModeManager::AddUserMode(new UserMode(UMODE_PRIV, "UMODE_PRIV", 'I'));
continue;
case 'Q':
- ModeManager::AddUserMode(new UserMode(UMODE_HIDDEN, 'Q'));
+ ModeManager::AddUserMode(new UserMode(UMODE_HIDDEN, "UMODE_HIDDEN", 'Q'));
continue;
case 'R':
- ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R'));
+ ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, "UMODE_REGPRIV", 'R'));
continue;
case 'S':
- ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, 'S'));
+ ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, "UMODE_STRIPCOLOR", 'S'));
continue;
case 'W':
- ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, 'W'));
+ ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, "UMODE_WHOIS", 'W'));
continue;
case 'c':
- ModeManager::AddUserMode(new UserMode(UMODE_COMMONCHANS, 'c'));
+ ModeManager::AddUserMode(new UserMode(UMODE_COMMONCHANS, "UMODE_COMMONCHANS", 'c'));
continue;
case 'g':
- ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, 'g'));
+ ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, "UMODE_CALLERID", 'g'));
continue;
case 'i':
- ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
+ ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i'));
continue;
case 'k':
- ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, 'k'));
+ ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, "UMODE_PROTECTED", 'k'));
continue;
case 'o':
- ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
+ ModeManager::AddUserMode(new UserMode(UMODE_OPER, "UMODE_OPER", 'o'));
continue;
case 'r':
- ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r'));
+ ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, "UMODE_REGISTERED", 'r'));
continue;
case 'w':
- ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
+ ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w'));
continue;
case 'x':
- ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
+ ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, "UMODE_CLOAK", 'x'));
continue;
case 'd':
- ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd'));
+ ModeManager::AddUserMode(new UserMode(UMODE_DEAF, "UMODE_DEAF", 'd'));
continue;
default:
- ModeManager::AddUserMode(new UserMode(UMODE_END, modebuf[t]));
+ ModeManager::AddUserMode(new UserMode(UMODE_END, "", modebuf[t]));
}
}
}
@@ -1244,19 +1231,19 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modes[t])
{
case 'q':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', chars[t]));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', chars[t]));
continue;
case 'a':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', chars[t]));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, "CMODE_PROTECT", 'a', chars[t]));
continue;
case 'o':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', chars[t]));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', chars[t]));
continue;
case 'h':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', chars[t]));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, "CMODE_HALFOP", 'h', chars[t]));
continue;
case 'v':
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', chars[t]));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', chars[t]));
continue;
}
}
@@ -1287,13 +1274,13 @@ int anope_event_capab(const char *source, int ac, const char **av)
return MOD_STOP;
}
if (!has_svsholdmod) {
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "SVSHOLD missing, Usage disabled until module is loaded.");
+ ircdproto->SendGlobops(OperServ, "SVSHOLD missing, Usage disabled until module is loaded.");
}
if (!has_chghostmod) {
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGHOST missing, Usage disabled until module is loaded.");
+ ircdproto->SendGlobops(OperServ, "CHGHOST missing, Usage disabled until module is loaded.");
}
if (!has_chgidentmod) {
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "CHGIDENT missing, Usage disabled until module is loaded.");
+ ircdproto->SendGlobops(OperServ, "CHGIDENT missing, Usage disabled until module is loaded.");
}
ircd->svshold = has_svsholdmod;
}
@@ -1307,7 +1294,8 @@ int anope_event_endburst(const char *source, int ac, const char **av)
{
NickAlias *na;
User *u = prev_u_intro;
- Server *s = findserver_uid(servlist, source);
+ Server *s = Server::Find(source ? source : "");
+
if (!s)
{
throw new CoreException("Got ENDBURST without a source");
@@ -1317,56 +1305,55 @@ int anope_event_endburst(const char *source, int ac, const char **av)
* If not, validate the user. ~ Viper*/
prev_u_intro = NULL;
if (u) na = findnick(u->nick);
- if (u && u->server->sync == SSYNC_IN_PROGRESS && (!na || na->nc != u->Account()))
+ if (u && !u->server->IsSynced() && (!na || na->nc != u->Account()))
{
validate_user(u);
if (u->HasMode(UMODE_REGISTERED))
- u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ u->RemoveMode(NickServ, UMODE_REGISTERED);
}
- Alog() << "Processed ENDBURST for " << s->name;
+ Alog() << "Processed ENDBURST for " << s->GetName();
- finish_sync(s, 1);
+ s->Sync(true);
return MOD_CONT;
}
-void moduleAddIRCDMsgs() {
- Message *m;
-
- m = createMessage("ENDBURST", anope_event_endburst); addCoreMessage(IRCD, m);
- m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m);
- m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m);
- m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m);
- m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m);
- m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m);
- m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m);
- m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m);
- m = createMessage("UID", anope_event_uid); addCoreMessage(IRCD,m);
- m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m);
- m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m);
- m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m);
- m = createMessage("TIME", anope_event_time); addCoreMessage(IRCD,m);
- m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m);
- m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m);
- m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m);
- m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m);
- m = createMessage("RSQUIT", anope_event_rsquit); addCoreMessage(IRCD,m);
- m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m);
- m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m);
- m = createMessage("SVSMODE", anope_event_mode) ;addCoreMessage(IRCD,m);
- m = createMessage("FHOST", anope_event_chghost); addCoreMessage(IRCD,m);
- m = createMessage("CHGIDENT", anope_event_chgident); addCoreMessage(IRCD,m);
- m = createMessage("FNAME", anope_event_chgname); addCoreMessage(IRCD,m);
- m = createMessage("SETHOST", anope_event_sethost); addCoreMessage(IRCD,m);
- m = createMessage("SETIDENT", anope_event_setident); addCoreMessage(IRCD,m);
- m = createMessage("SETNAME", anope_event_setname); addCoreMessage(IRCD,m);
- m = createMessage("FJOIN", anope_event_fjoin); addCoreMessage(IRCD,m);
- m = createMessage("FMODE", anope_event_fmode); addCoreMessage(IRCD,m);
- m = createMessage("FTOPIC", anope_event_ftopic); addCoreMessage(IRCD,m);
- m = createMessage("OPERTYPE", anope_event_opertype); addCoreMessage(IRCD,m);
- m = createMessage("IDLE", anope_event_idle); addCoreMessage(IRCD,m);
- m = createMessage("METADATA", anope_event_metadata); addCoreMessage(IRCD,m);
+void moduleAddIRCDMsgs()
+{
+ Anope::AddMessage("ENDBURST", anope_event_endburst);
+ Anope::AddMessage("436", anope_event_436);
+ Anope::AddMessage("AWAY", anope_event_away);
+ Anope::AddMessage("JOIN", anope_event_join);
+ Anope::AddMessage("KICK", anope_event_kick);
+ Anope::AddMessage("KILL", anope_event_kill);
+ Anope::AddMessage("MODE", anope_event_mode);
+ Anope::AddMessage("MOTD", anope_event_motd);
+ Anope::AddMessage("NICK", anope_event_nick);
+ Anope::AddMessage("UID", anope_event_uid);
+ Anope::AddMessage("CAPAB", anope_event_capab);
+ Anope::AddMessage("PART", anope_event_part);
+ Anope::AddMessage("PING", anope_event_ping);
+ Anope::AddMessage("TIME", anope_event_time);
+ Anope::AddMessage("PRIVMSG", anope_event_privmsg);
+ Anope::AddMessage("QUIT", anope_event_quit);
+ Anope::AddMessage("SERVER", anope_event_server);
+ Anope::AddMessage("SQUIT", anope_event_squit);
+ Anope::AddMessage("RSQUIT", anope_event_rsquit);
+ Anope::AddMessage("TOPIC", anope_event_topic);
+ Anope::AddMessage("WHOIS", anope_event_whois);
+ Anope::AddMessage("SVSMODE", anope_event_mode);
+ Anope::AddMessage("FHOST", anope_event_chghost);
+ Anope::AddMessage("CHGIDENT", anope_event_chgident);
+ Anope::AddMessage("FNAME", anope_event_chgname);
+ Anope::AddMessage("SETHOST", anope_event_sethost);
+ Anope::AddMessage("SETIDENT", anope_event_setident);
+ Anope::AddMessage("SETNAME", anope_event_setname);
+ Anope::AddMessage("FJOIN", anope_event_fjoin);
+ Anope::AddMessage("FMODE", anope_event_fmode);
+ Anope::AddMessage("FTOPIC", anope_event_ftopic);
+ Anope::AddMessage("OPERTYPE", anope_event_opertype);
+ Anope::AddMessage("IDLE", anope_event_idle);
+ Anope::AddMessage("METADATA", anope_event_metadata);
}
bool ChannelModeFlood::IsValid(const std::string &value)
@@ -1409,7 +1396,6 @@ class ProtoInspIRCd : public Module
void OnUserNickChange(User *u, const std::string &)
{
- /* InspIRCd 2.0 removes r on nick change and doesn't tell services, even though it tells the user */
u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED));
}
};
diff --git a/src/protocol/ratbox.c b/src/protocol/ratbox.cpp
index 8d0a84826..339113e33 100644
--- a/src/protocol/ratbox.c
+++ b/src/protocol/ratbox.cpp
@@ -12,7 +12,9 @@
*/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
+
+static char *TS6UPLINK = NULL; // XXX is this needed?
IRCDVar myIrcd[] = {
{"Ratbox 2.0+", /* ircd name */
@@ -21,7 +23,7 @@ IRCDVar myIrcd[] = {
"+o", /* Channel Umode used by Botserv bots */
0, /* SVSNICK */
0, /* Vhost */
- 1, /* Supports SGlines */
+ 1, /* Supports SNlines */
1, /* Supports SQlines */
0, /* Supports SZlines */
3, /* Number of server args */
@@ -134,36 +136,32 @@ class RatboxProto : public IRCDTS6Proto
send_cmd(TS6SID, "OPERWALL :%s", buf);
}
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(TS6SID, "RESV * %s :%s", mask.c_str(), reason.c_str());
+ send_cmd(TS6SID, "RESV * %s :%s", x->Mask.c_str(), x->Reason.c_str());
}
- void SendSGLineDel(SXLine *sx)
+ void SendSGLineDel(XLine *x)
{
- BotInfo *bi = findbot(Config.s_OperServ);
- send_cmd(bi ? bi->uid : Config.s_OperServ, "UNXLINE * %s", sx->mask);
+ BotInfo *bi = OperServ;
+ send_cmd(bi ? bi->uid : Config.s_OperServ, "UNXLINE * %s", x->Mask.c_str());
}
- void SendSGLine(SXLine *sx)
+ void SendSGLine(XLine *x)
{
- BotInfo *bi = findbot(Config.s_OperServ);
- send_cmd(bi ? bi->uid : Config.s_OperServ, "XLINE * %s 0 :%s", sx->mask, sx->reason);
+ BotInfo *bi = OperServ;
+ send_cmd(bi ? bi->uid : Config.s_OperServ, "XLINE * %s 0 :%s", x->Mask.c_str(), x->Reason.c_str());
}
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
- BotInfo *bi = findbot(Config.s_OperServ);
- send_cmd(bi ? bi->uid : Config.s_OperServ, "UNKLINE * %s %s", ak->user, ak->host);
+ BotInfo *bi = OperServ;
+ send_cmd(bi ? bi->uid : Config.s_OperServ, "UNKLINE * %s %s", x->GetUser().c_str(), x->GetHost().c_str());
}
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(TS6SID, "UNRESV * %s", user.c_str());
+ send_cmd(TS6SID, "UNRESV * %s", x->Mask.c_str());
}
void SendJoin(BotInfo *user, const char *channel, time_t chantime)
@@ -171,10 +169,10 @@ class RatboxProto : public IRCDTS6Proto
send_cmd(NULL, "SJOIN %ld %s + :%s", static_cast<long>(chantime), channel, user->uid.c_str());
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
- BotInfo *bi = findbot(Config.s_OperServ);
- send_cmd(bi ? bi->uid : Config.s_OperServ, "KLINE * %ld %s %s :%s", static_cast<long>(ak->expires - time(NULL)), ak->user, ak->host, ak->reason);
+ BotInfo *bi = OperServ;
+ send_cmd(bi ? bi->uid : Config.s_OperServ, "KLINE * %ld %s %s :%s", static_cast<long>(x->Expires - time(NULL)), x->GetUser().c_str(), x->GetHost().c_str(), x->Reason.c_str());
}
void SendSVSKillInternal(BotInfo *source, User *user, const char *buf)
@@ -190,16 +188,16 @@ class RatboxProto : public IRCDTS6Proto
/* SERVER name hop descript */
void SendServer(Server *server)
{
- send_cmd(NULL, "SERVER %s %d :%s", server->name, server->hops, server->desc);
+ send_cmd(NULL, "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str());
}
void SendConnect()
{
+ Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, TS6SID);
ratbox_cmd_pass(uplink_server->password);
ratbox_cmd_capab();
/* Make myself known to myself in the serverlist */
- me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, TS6SID);
- SendServer(me_server);
+ SendServer(Me);
ratbox_cmd_svinfo();
}
@@ -380,7 +378,7 @@ int anope_event_sjoin(const char *source, int ac, const char **av)
Status.push_back(cm);
}
- User *u = find_byuid(buf);
+ User *u = finduser(buf);
if (!u)
{
Alog(LOG_DEBUG) << "SJOIN for nonexistant user " << buf << " on " << c->name;
@@ -457,14 +455,13 @@ int anope_event_sjoin(const char *source, int ac, const char **av)
*/
int anope_event_nick(const char *source, int ac, const char **av)
{
- Server *s;
User *user;
if (ac == 9)
{
- s = findserver_uid(servlist, source);
+ Server *s = Server::Find(source ? source : "");
/* Source is always the server */
- user = do_nick("", av[0], av[4], av[5], s->name, av[8],
+ user = do_nick("", av[0], av[4], av[5], s->GetName().c_str(), av[8],
strtoul(av[2], NULL, 10), 0, "*", av[7]);
if (user)
{
@@ -510,7 +507,7 @@ int anope_event_topic(const char *source, int ac, const char **av)
if (ac > 1 && *av[1])
c->topic = sstrdup(av[1]);
- u = find_byuid(source);
+ u = finduser(source);
c->topic_setter = u ? u->nick : source;
c->topic_time = topic_time;
@@ -593,7 +590,7 @@ int anope_event_away(const char *source, int ac, const char **av)
{
User *u = NULL;
- u = find_byuid(source);
+ u = finduser(source);
m_away(u ? u->nick.c_str() : source, (ac ? av[0] : NULL));
return MOD_CONT;
}
@@ -645,7 +642,7 @@ int anope_event_privmsg(const char *source, int ac, const char **av)
return MOD_CONT;
}
- u = find_byuid(source);
+ u = finduser(source);
bi = findbot(av[0]);
// XXX: this is really the same as charybdis
m_privmsg(source, av[0], av[1]);
@@ -660,7 +657,7 @@ int anope_event_part(const char *source, int ac, const char **av)
return MOD_CONT;
}
- u = find_byuid(source);
+ u = finduser(source);
do_part(u ? u->nick.c_str() : source, ac, av);
return MOD_CONT;
@@ -681,27 +678,24 @@ int anope_event_whois(const char *source, int ac, const char **av)
int anope_event_server(const char *source, int ac, const char **av)
{
if (!stricmp(av[1], "1")) {
- uplink = sstrdup(av[0]);
if (TS6UPLINK) {
- do_server(source, av[0], av[1], av[2], TS6UPLINK);
+ do_server(source, av[0], atoi(av[1]), av[2], TS6UPLINK);
} else {
- do_server(source, av[0], av[1], av[2], "");
+ do_server(source, av[0], atoi(av[1]), av[2], "");
}
} else {
- do_server(source, av[0], av[1], av[2], "");
+ do_server(source, av[0], atoi(av[1]), av[2], "");
}
return MOD_CONT;
}
int anope_event_sid(const char *source, int ac, const char **av)
{
- Server *s;
-
/* :42X SID trystan.nomadirc.net 2 43X :ircd-ratbox test server */
- s = findserver_uid(servlist, source);
+ Server *s = Server::Find(source);
- do_server(s->name, av[0], av[1], av[3], av[2]);
+ do_server(s->GetName(), av[0], atoi(av[1]), av[3], av[2]);
return MOD_CONT;
}
@@ -721,7 +715,7 @@ int anope_event_quit(const char *source, int ac, const char **av)
return MOD_CONT;
}
- u = find_byuid(source);
+ u = finduser(source);
do_quit(u ? u->nick.c_str() : source, ac, av);
return MOD_CONT;
@@ -738,8 +732,8 @@ int anope_event_mode(const char *source, int ac, const char **av)
if (*av[0] == '#' || *av[0] == '&') {
do_cmode(source, ac, av);
} else {
- u = find_byuid(source);
- u2 = find_byuid(av[0]);
+ u = finduser(source);
+ u2 = finduser(av[0]);
av[0] = u2->nick.c_str();
do_umode(u->nick.c_str(), ac, av);
}
@@ -813,43 +807,41 @@ int anope_event_error(const char *source, int ac, const char **av)
void moduleAddIRCDMsgs()
{
- Message *m;
-
- m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m);
- m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m);
- m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m);
- m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m);
- m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m);
- m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("TMODE", anope_event_tmode); addCoreMessage(IRCD,m);
- m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m);
- m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m);
- m = createMessage("BMASK", anope_event_bmask); addCoreMessage(IRCD,m);
- m = createMessage("UID", anope_event_nick); addCoreMessage(IRCD,m);
- m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m);
- m = createMessage("PASS", anope_event_pass); addCoreMessage(IRCD,m);
- m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m);
- m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m);
- m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m);
- m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m);
- m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m);
- m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m);
- m = createMessage("TB", anope_event_tburst); addCoreMessage(IRCD,m);
- m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m);
- m = createMessage("CAPAB", anope_event_capab); addCoreMessage(IRCD,m);
- m = createMessage("SJOIN", anope_event_sjoin); addCoreMessage(IRCD,m);
- m = createMessage("ERROR", anope_event_error); addCoreMessage(IRCD,m);
- m = createMessage("SID", anope_event_sid); addCoreMessage(IRCD,m);
+ Anope::AddMessage("436", anope_event_436);
+ Anope::AddMessage("AWAY", anope_event_away);
+ Anope::AddMessage("JOIN", anope_event_join);
+ Anope::AddMessage("KICK", anope_event_kick);
+ Anope::AddMessage("KILL", anope_event_kill);
+ Anope::AddMessage("MODE", anope_event_mode);
+ Anope::AddMessage("TMODE", anope_event_tmode);
+ Anope::AddMessage("MOTD", anope_event_motd);
+ Anope::AddMessage("NICK", anope_event_nick);
+ Anope::AddMessage("BMASK", anope_event_bmask);
+ Anope::AddMessage("UID", anope_event_nick);
+ Anope::AddMessage("PART", anope_event_part);
+ Anope::AddMessage("PASS", anope_event_pass);
+ Anope::AddMessage("PING", anope_event_ping);
+ Anope::AddMessage("PRIVMSG", anope_event_privmsg);
+ Anope::AddMessage("QUIT", anope_event_quit);
+ Anope::AddMessage("SERVER", anope_event_server);
+ Anope::AddMessage("SQUIT", anope_event_squit);
+ Anope::AddMessage("TOPIC", anope_event_topic);
+ Anope::AddMessage("TB", anope_event_tburst);
+ Anope::AddMessage("WHOIS", anope_event_whois);
+ Anope::AddMessage("CAPAB", anope_event_capab);
+ Anope::AddMessage("SJOIN", anope_event_sjoin);
+ Anope::AddMessage("ERROR", anope_event_error);
+ Anope::AddMessage("SID", anope_event_sid);
}
-void moduleAddModes()
+static void AddModes()
{
/* Add user modes */
- ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a'));
- ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
- ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
- ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's'));
- ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
+ ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, "UMODE_ADMIN", 'a'));
+ ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i'));
+ ModeManager::AddUserMode(new UserMode(UMODE_OPER, "UMODE_OPER", 'o'));
+ ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, "UMODE_SNOMASK", 's'));
+ ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w'));
/* b/e/I */
ModeManager::AddChannelMode(new ChannelModeBan('b'));
@@ -857,18 +849,18 @@ void moduleAddModes()
ModeManager::AddChannelMode(new ChannelModeInvite('I'));
/* v/h/o/a/q */
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', '+'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', '@'));
/* Add channel modes */
- ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i'));
ModeManager::AddChannelMode(new ChannelModeKey('k'));
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
- ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't'));
}
class ProtoRatbox : public Module
@@ -892,7 +884,7 @@ class ProtoRatbox : public Module
for (unsigned i = 0; i < 5; ++i)
Capab.SetFlag(c[i]);
- moduleAddModes();
+ AddModes();
pmodule_ircd_proto(&ircd_proto);
moduleAddIRCDMsgs();
diff --git a/src/protocol/unreal32.c b/src/protocol/unreal32.cpp
index 3564fecd6..65ee9d3e2 100644
--- a/src/protocol/unreal32.c
+++ b/src/protocol/unreal32.cpp
@@ -14,7 +14,7 @@
/*************************************************************************/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
IRCDVar myIrcd[] = {
{"UnrealIRCd 3.2.x", /* ircd name */
@@ -23,7 +23,7 @@ IRCDVar myIrcd[] = {
"+ao", /* Channel Umode used by Botserv bots */
1, /* SVSNICK */
1, /* Vhost */
- 1, /* Supports SGlines */
+ 1, /* Supports SNlines */
1, /* Supports SQlines */
1, /* Supports SZlines */
3, /* Number of server args */
@@ -133,9 +133,9 @@ class UnrealIRCdProto : public IRCDProto
send_cmd(NULL, "f %s %s", server, set ? "+" : "-");
}
- void SendAkillDel(Akill *ak)
+ void SendAkillDel(XLine *x)
{
- send_cmd(NULL, "BD - G %s %s %s", ak->user, ak->host, Config.s_OperServ);
+ send_cmd(NULL, "BD - G %s %s %s", x->GetUser().c_str(), x->GetHost().c_str(), Config.s_OperServ);
}
void SendTopic(BotInfo *whosets, Channel *c, const char *whosetit, const char *topic)
@@ -145,7 +145,7 @@ class UnrealIRCdProto : public IRCDProto
void SendVhostDel(User *u)
{
- BotInfo *bi = findbot(Config.s_HostServ);
+ BotInfo *bi = HostServ;
u->RemoveMode(bi, UMODE_CLOAK);
u->RemoveMode(bi, UMODE_VHOST);
ModeManager::ProcessModes();
@@ -153,12 +153,12 @@ class UnrealIRCdProto : public IRCDProto
ModeManager::ProcessModes();
}
- void SendAkill(Akill *ak)
+ void SendAkill(XLine *x)
{
// Calculate the time left before this would expire, capping it at 2 days
- time_t timeleft = ak->expires - time(NULL);
+ time_t timeleft = x->Expires - time(NULL);
if (timeleft > 172800) timeleft = 172800;
- send_cmd(NULL, "BD + G %s %s %s %ld %ld :%s", ak->user, ak->host, ak->by, static_cast<long>(time(NULL) + timeleft), static_cast<long>(ak->expires), ak->reason);
+ send_cmd(NULL, "BD + G %s %s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(time(NULL) + timeleft), static_cast<long>(x->Expires), x->Reason.c_str());
}
void SendSVSKillInternal(BotInfo *source, User *user, const char *buf)
@@ -216,9 +216,9 @@ class UnrealIRCdProto : public IRCDProto
void SendServer(Server *server)
{
if (Config.Numeric)
- send_cmd(NULL, "SERVER %s %d :U0-*-%s %s", server->name, server->hops, Config.Numeric, server->desc);
+ send_cmd(NULL, "SERVER %s %d :U0-*-%s %s", server->GetName().c_str(), server->GetHops(), Config.Numeric, server->GetDescription().c_str());
else
- send_cmd(NULL, "SERVER %s %d :%s", server->name, server->hops, server->desc);
+ send_cmd(NULL, "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str());
}
/* JOIN */
@@ -228,31 +228,21 @@ class UnrealIRCdProto : public IRCDProto
}
/* unsqline
- ** parv[0] = sender
- ** parv[1] = nickmask
*/
- void SendSQLineDel(const std::string &user)
+ void SendSQLineDel(XLine *x)
{
- if (user.empty())
- return;
- send_cmd(NULL, "d %s", user.c_str());
+ send_cmd(NULL, "d %s", x->Mask.c_str());
}
/* SQLINE */
/*
- ** parv[0] = sender
- ** parv[1] = nickmask
- ** parv[2] = reason
- **
** - Unreal will translate this to TKL for us
**
*/
- void SendSQLine(const std::string &mask, const std::string &reason)
+ void SendSQLine(XLine *x)
{
- if (mask.empty() || reason.empty())
- return;
- send_cmd(NULL, "c %s :%s", mask.c_str(), reason.c_str());
+ send_cmd(NULL, "c %s :%s", x->Mask.c_str(), x->Reason.c_str());
}
/*
@@ -286,10 +276,10 @@ class UnrealIRCdProto : public IRCDProto
void SendConnect()
{
+ Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, (Config.Numeric ? Config.Numeric : ""));
unreal_cmd_capab();
unreal_cmd_pass(uplink_server->password);
- me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, (Config.Numeric ? Config.Numeric : ""));
- SendServer(me_server);
+ SendServer(Me);
}
/* SVSHOLD - set */
@@ -309,33 +299,33 @@ class UnrealIRCdProto : public IRCDProto
/*
* SVSNLINE - :realname mask
*/
- void SendSGLineDel(SXLine *sx)
+ void SendSGLineDel(XLine *x)
{
- send_cmd(NULL, "BR - :%s", sx->mask);
+ send_cmd(NULL, "BR - :%s", x->Mask.c_str());
}
/* UNSZLINE */
- void SendSZLineDel(SXLine *sx)
+ void SendSZLineDel(XLine *x)
{
- send_cmd(NULL, "BD - Z * %s %s", sx->mask, Config.s_OperServ);
+ send_cmd(NULL, "BD - Z * %s %s", x->Mask.c_str(), Config.s_OperServ);
}
/* SZLINE */
- void SendSZLine(SXLine *sx)
+ void SendSZLine(XLine *x)
{
- send_cmd(NULL, "BD + Z * %s %s %ld %ld :%s", sx->mask, sx->by, static_cast<long>(time(NULL) + 172800), static_cast<long>(time(NULL)), sx->reason);
+ send_cmd(NULL, "BD + Z * %s %s %ld %ld :%s", x->Mask.c_str(), x->By.c_str(), static_cast<long>(time(NULL) + 172800), static_cast<long>(time(NULL)), x->Reason.c_str());
}
/* SGLINE */
/*
* SVSNLINE + reason_where_is_space :realname mask with spaces
*/
- void SendSGLine(SXLine *sx)
+ void SendSGLine(XLine *x)
{
char edited_reason[BUFSIZE];
- strlcpy(edited_reason, sx->reason, BUFSIZE);
+ strlcpy(edited_reason, x->Reason.c_str(), BUFSIZE);
strnrepl(edited_reason, BUFSIZE, " ", "_");
- send_cmd(NULL, "BR + %s :%s", edited_reason, sx->mask);
+ send_cmd(NULL, "BR + %s :%s", edited_reason, x->Mask.c_str());
}
/* SVSMODE -b */
@@ -418,14 +408,14 @@ class UnrealIRCdProto : public IRCDProto
u->Account()->Shrink("authenticationtoken");
u->Account()->Extend("authenticationtoken", new ExtensibleItemPointerArray<char>(sstrdup(svidbuf)));
- BotInfo *bi = findbot(Config.s_NickServ);
+ BotInfo *bi = NickServ;
u->SetMode(bi, UMODE_REGISTERED);
ircdproto->SendMode(bi, u, "+d %s", svidbuf);
}
void SendUnregisteredNick(User *u)
{
- BotInfo *bi = findbot(Config.s_NickServ);
+ BotInfo *bi = NickServ;
u->RemoveMode(bi, UMODE_REGISTERED);
ircdproto->SendMode(bi, u, "+d 1");
}
@@ -462,7 +452,7 @@ int anope_event_capab(const char *source, int ac, const char **av)
ModeManager::AddChannelMode(new ChannelModeInvite('I'));
continue;
default:
- ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, "", modebuf[t]));
}
}
@@ -478,10 +468,10 @@ int anope_event_capab(const char *source, int ac, const char **av)
ModeManager::AddChannelMode(new ChannelModeFlood('f'));
continue;
case 'L':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L'));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, "CMODE_REDIRECT", 'L'));
continue;
default:
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t]));
}
}
@@ -491,13 +481,13 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modebuf[t])
{
case 'l':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, "CMODE_LIMIT", 'l', true));
continue;
case 'j':
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, 'j', true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, "CMODE_JOINFLOOD", 'j', true));
continue;
default:
- ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true));
+ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, "", modebuf[t], true));
}
}
@@ -507,31 +497,31 @@ int anope_event_capab(const char *source, int ac, const char **av)
switch (modebuf[t])
{
case 'p':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, "CMODE_PRIVATE", 'p'));
continue;
case 's':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, "CMODE_SECRET", 's'));
continue;
case 'm':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, "CMODE_MODERATED", 'm'));
continue;
case 'n':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, "CMODE_NOEXTERNAL", 'n'));
continue;
case 't':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, "CMODE_TOPIC", 't'));
continue;
case 'i':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, "CMODE_INVITE", 'i'));
continue;
case 'r':
ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
continue;
case 'R':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, "CMODE_REGISTEREDONLY", 'R'));
continue;
case 'c':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, "CMODE_BLOCKCOLOR", 'c'));
continue;
case 'O':
ModeManager::AddChannelMode(new ChannelModeOper('O'));
@@ -540,40 +530,40 @@ int anope_event_capab(const char *source, int ac, const char **av)
ModeManager::AddChannelMode(new ChannelModeAdmin('A'));
continue;
case 'Q':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, "CMODE_NOKICK", 'Q'));
continue;
case 'K':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, "CMODE_NOKNOCK", 'K'));
continue;
case 'V':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, 'V'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, "CMODE_NOINVITE", 'V'));
continue;
case 'C':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, "CMODE_NOCTCP", 'C'));
continue;
case 'u':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, "CMODE_AUDITORIUM", 'u'));
continue;
case 'z':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, "CMODE_SSL", 'z'));
continue;
case 'N':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, "CMODE_NONICK", 'N'));
continue;
case 'S':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, "CMODE_STRIPCOLOR", 'S'));
continue;
case 'M':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, "CMODE_REGMODERATED", 'M'));
continue;
case 'T':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, 'T'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, "CMODE_NONOTICE", 'T'));
continue;
case 'G':
- ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G'));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, "CMODE_FILTER", 'G'));
continue;
default:
- ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t]));
+ ModeManager::AddChannelMode(new ChannelMode(CMODE_END, "", modebuf[t]));
}
}
}
@@ -604,9 +594,9 @@ int anope_event_ping(const char *source, int ac, const char **av)
*/
int anope_event_pong(const char *source, int ac, const char **av)
{
- Server *s = findserver(servlist, source);
- if (s && !is_sync(s))
- finish_sync(s, 0);
+ Server *s = Server::Find(source);
+ if (s && !s->IsSynced())
+ s->Sync(false);
return MOD_CONT;
}
@@ -701,7 +691,7 @@ int anope_event_mode(const char *source, int ac, const char **av)
/* This is used to strip the TS from the end of the mode stirng */
int anope_event_gmode(const char *source, int ac, const char **av)
{
- if (findserver(servlist, source))
+ if (Server::Find(source))
--ac;
return anope_event_mode(source, ac, av);
}
@@ -966,16 +956,15 @@ int anope_event_server(const char *source, int ac, const char **av)
char *upnumeric;
if (!stricmp(av[1], "1")) {
- uplink = sstrdup(av[0]);
vl = myStrGetToken(av[2], ' ', 0);
upnumeric = myStrGetToken(vl, '-', 2);
desc = myStrGetTokenRemainder(av[2], ' ', 1);
- do_server(source, av[0], av[1], desc, upnumeric);
+ do_server(source, av[0], atoi(av[1]), desc, upnumeric);
delete [] vl;
delete [] desc;
delete [] upnumeric;
} else {
- do_server(source, av[0], av[1], av[2], "");
+ do_server(source, av[0], atoi(av[1]), av[2], "");
}
ircdproto->SendPing(Config.ServerName, av[0]);
@@ -1021,12 +1010,10 @@ int anope_event_error(const char *source, int ac, const char **av)
int anope_event_sdesc(const char *source, int ac, const char **av)
{
- Server *s;
- s = findserver(servlist, source);
+ Server *s = Server::Find(source ? source : "");
- if (s) {
- s->desc = const_cast<char *>(av[0]); // XXX Unsafe cast -- CyberBotX
- }
+ if (s)
+ s->SetDescription(av[0]);
return MOD_CONT;
}
@@ -1188,75 +1175,74 @@ int anope_event_sjoin(const char *source, int ac, const char **av)
return MOD_CONT;
}
-void moduleAddIRCDMsgs() {
- Message *m;
-
- m = createMessage("436", anope_event_436); addCoreMessage(IRCD,m);
- m = createMessage("AWAY", anope_event_away); addCoreMessage(IRCD,m);
- m = createMessage("6", anope_event_away); addCoreMessage(IRCD,m);
- m = createMessage("JOIN", anope_event_join); addCoreMessage(IRCD,m);
- m = createMessage("C", anope_event_join); addCoreMessage(IRCD,m);
- m = createMessage("KICK", anope_event_kick); addCoreMessage(IRCD,m);
- m = createMessage("H", anope_event_kick); addCoreMessage(IRCD,m);
- m = createMessage("KILL", anope_event_kill); addCoreMessage(IRCD,m);
- m = createMessage(".", anope_event_kill); addCoreMessage(IRCD,m);
- m = createMessage("MODE", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("G", anope_event_gmode); addCoreMessage(IRCD,m);
- m = createMessage("MOTD", anope_event_motd); addCoreMessage(IRCD,m);
- m = createMessage("F", anope_event_motd); addCoreMessage(IRCD,m);
- m = createMessage("NICK", anope_event_nick); addCoreMessage(IRCD,m);
- m = createMessage("&", anope_event_nick); addCoreMessage(IRCD,m);
- m = createMessage("PART", anope_event_part); addCoreMessage(IRCD,m);
- m = createMessage("D", anope_event_part); addCoreMessage(IRCD,m);
- m = createMessage("PING", anope_event_ping); addCoreMessage(IRCD,m);
- m = createMessage("8", anope_event_ping); addCoreMessage(IRCD,m);
- m = createMessage("PONG", anope_event_pong); addCoreMessage(IRCD,m);
- m = createMessage("9", anope_event_pong); addCoreMessage(IRCD,m);
- m = createMessage("PRIVMSG", anope_event_privmsg); addCoreMessage(IRCD,m);
- m = createMessage("!", anope_event_privmsg); addCoreMessage(IRCD,m);
- m = createMessage("QUIT", anope_event_quit); addCoreMessage(IRCD,m);
- m = createMessage(",", anope_event_quit); addCoreMessage(IRCD,m);
- m = createMessage("SERVER", anope_event_server); addCoreMessage(IRCD,m);
- m = createMessage("'", anope_event_server); addCoreMessage(IRCD,m);
- m = createMessage("SQUIT", anope_event_squit); addCoreMessage(IRCD,m);
- m = createMessage("-", anope_event_squit); addCoreMessage(IRCD,m);
- m = createMessage("TOPIC", anope_event_topic); addCoreMessage(IRCD,m);
- m = createMessage(")", anope_event_topic); addCoreMessage(IRCD,m);
- m = createMessage("SVSMODE", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("n", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("SVS2MODE", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("v", anope_event_mode); addCoreMessage(IRCD,m);
- m = createMessage("WHOIS", anope_event_whois); addCoreMessage(IRCD,m);
- m = createMessage("#", anope_event_whois); addCoreMessage(IRCD,m);
- m = createMessage("PROTOCTL", anope_event_capab); addCoreMessage(IRCD,m);
- m = createMessage("_", anope_event_capab); addCoreMessage(IRCD,m);
- m = createMessage("CHGHOST", anope_event_chghost); addCoreMessage(IRCD,m);
- m = createMessage("AL", anope_event_chghost); addCoreMessage(IRCD,m);
- m = createMessage("CHGIDENT", anope_event_chgident); addCoreMessage(IRCD,m);
- m = createMessage("AZ", anope_event_chgident); addCoreMessage(IRCD,m);
- m = createMessage("CHGNAME", anope_event_chgname); addCoreMessage(IRCD,m);
- m = createMessage("BK", anope_event_chgname); addCoreMessage(IRCD,m);
- m = createMessage("NETINFO", anope_event_netinfo); addCoreMessage(IRCD,m);
- m = createMessage("AO", anope_event_netinfo); addCoreMessage(IRCD,m);
- m = createMessage("SETHOST", anope_event_sethost); addCoreMessage(IRCD,m);
- m = createMessage("AA", anope_event_sethost); addCoreMessage(IRCD,m);
- m = createMessage("SETIDENT", anope_event_setident); addCoreMessage(IRCD,m);
- m = createMessage("AD", anope_event_setident); addCoreMessage(IRCD,m);
- m = createMessage("SETNAME", anope_event_setname); addCoreMessage(IRCD,m);
- m = createMessage("AE", anope_event_setname); addCoreMessage(IRCD,m);
- m = createMessage("ERROR", anope_event_error); addCoreMessage(IRCD,m);
- m = createMessage("5", anope_event_error); addCoreMessage(IRCD,m);
- m = createMessage("UMODE2", anope_event_umode2); addCoreMessage(IRCD,m);
- m = createMessage("|", anope_event_umode2); addCoreMessage(IRCD,m);
- m = createMessage("SJOIN", anope_event_sjoin); addCoreMessage(IRCD,m);
- m = createMessage("~", anope_event_sjoin); addCoreMessage(IRCD,m);
- m = createMessage("SDESC", anope_event_sdesc); addCoreMessage(IRCD,m);
- m = createMessage("AG", anope_event_sdesc); addCoreMessage(IRCD,m);
+void moduleAddIRCDMsgs()
+{
+ Anope::AddMessage("436", anope_event_436);
+ Anope::AddMessage("AWAY", anope_event_away);
+ Anope::AddMessage("6", anope_event_away);
+ Anope::AddMessage("JOIN", anope_event_join);
+ Anope::AddMessage("C", anope_event_join);
+ Anope::AddMessage("KICK", anope_event_kick);
+ Anope::AddMessage("H", anope_event_kick);
+ Anope::AddMessage("KILL", anope_event_kill);
+ Anope::AddMessage(".", anope_event_kill);
+ Anope::AddMessage("MODE", anope_event_mode);
+ Anope::AddMessage("G", anope_event_gmode);
+ Anope::AddMessage("MOTD", anope_event_motd);
+ Anope::AddMessage("F", anope_event_motd);
+ Anope::AddMessage("NICK", anope_event_nick);
+ Anope::AddMessage("&", anope_event_nick);
+ Anope::AddMessage("PART", anope_event_part);
+ Anope::AddMessage("D", anope_event_part);
+ Anope::AddMessage("PING", anope_event_ping);
+ Anope::AddMessage("8", anope_event_ping);
+ Anope::AddMessage("PONG", anope_event_pong);
+ Anope::AddMessage("9", anope_event_pong);
+ Anope::AddMessage("PRIVMSG", anope_event_privmsg);
+ Anope::AddMessage("!", anope_event_privmsg);
+ Anope::AddMessage("QUIT", anope_event_quit);
+ Anope::AddMessage(",", anope_event_quit);
+ Anope::AddMessage("SERVER", anope_event_server);
+ Anope::AddMessage("'", anope_event_server);
+ Anope::AddMessage("SQUIT", anope_event_squit);
+ Anope::AddMessage("-", anope_event_squit);
+ Anope::AddMessage("TOPIC", anope_event_topic);
+ Anope::AddMessage(")", anope_event_topic);
+ Anope::AddMessage("SVSMODE", anope_event_mode);
+ Anope::AddMessage("n", anope_event_mode);
+ Anope::AddMessage("SVS2MODE", anope_event_mode);
+ Anope::AddMessage("v", anope_event_mode);
+ Anope::AddMessage("WHOIS", anope_event_whois);
+ Anope::AddMessage("#", anope_event_whois);
+ Anope::AddMessage("PROTOCTL", anope_event_capab);
+ Anope::AddMessage("_", anope_event_capab);
+ Anope::AddMessage("CHGHOST", anope_event_chghost);
+ Anope::AddMessage("AL", anope_event_chghost);
+ Anope::AddMessage("CHGIDENT", anope_event_chgident);
+ Anope::AddMessage("AZ", anope_event_chgident);
+ Anope::AddMessage("CHGNAME", anope_event_chgname);
+ Anope::AddMessage("BK", anope_event_chgname);
+ Anope::AddMessage("NETINFO", anope_event_netinfo);
+ Anope::AddMessage("AO", anope_event_netinfo);
+ Anope::AddMessage("SETHOST", anope_event_sethost);
+ Anope::AddMessage("AA", anope_event_sethost);
+ Anope::AddMessage("SETIDENT", anope_event_setident);
+ Anope::AddMessage("AD", anope_event_setident);
+ Anope::AddMessage("SETNAME", anope_event_setname);
+ Anope::AddMessage("AE", anope_event_setname);
+ Anope::AddMessage("ERROR", anope_event_error);
+ Anope::AddMessage("5", anope_event_error);
+ Anope::AddMessage("UMODE2", anope_event_umode2);
+ Anope::AddMessage("|", anope_event_umode2);
+ Anope::AddMessage("SJOIN", anope_event_sjoin);
+ Anope::AddMessage("~", anope_event_sjoin);
+ Anope::AddMessage("SDESC", anope_event_sdesc);
+ Anope::AddMessage("AG", anope_event_sdesc);
/* The non token version of these is in messages.c */
- m = createMessage("2", m_stats); addCoreMessage(IRCD,m);
- m = createMessage(">", m_time); addCoreMessage(IRCD,m);
- m = createMessage("+", m_version); addCoreMessage(IRCD,m);
+ Anope::AddMessage("2", m_stats);
+ Anope::AddMessage(">", m_time);
+ Anope::AddMessage("+", m_version);
}
/* Borrowed part of this check from UnrealIRCd */
@@ -1292,39 +1278,39 @@ bool ChannelModeFlood::IsValid(const std::string &value2)
static void AddModes()
{
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%'));
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, "CMODE_VOICE", 'v', '+'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, "CMODE_HALFOP", 'h', '%'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, "CMODE_OP", 'o', '@'));
/* Unreal sends +q as * and +a as ~ */
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '~'));
- ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '*'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, "CMODE_PROTECT", 'a', '~'));
+ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, "CMODE_OWNER", 'q', '*')); /* Unreal sends +q as * */
/* Add user modes */
- ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, 'A'));
- ModeManager::AddUserMode(new UserMode(UMODE_BOT, 'B'));
- ModeManager::AddUserMode(new UserMode(UMODE_CO_ADMIN, 'C'));
- ModeManager::AddUserMode(new UserMode(UMODE_FILTER, 'G'));
- ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, 'H'));
- ModeManager::AddUserMode(new UserMode(UMODE_NETADMIN, 'N'));
- ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R'));
- ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, 'S'));
- ModeManager::AddUserMode(new UserMode(UMODE_NO_CTCP, 'T'));
- ModeManager::AddUserMode(new UserMode(UMODE_WEBTV, 'V'));
- ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, 'W'));
- ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a'));
- ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd'));
- ModeManager::AddUserMode(new UserMode(UMODE_GLOBOPS, 'g'));
- ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h'));
- ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
- ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
- ModeManager::AddUserMode(new UserMode(UMODE_PRIV, 'p'));
- ModeManager::AddUserMode(new UserMode(UMODE_GOD, 'q'));
- ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r'));
- ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's'));
- ModeManager::AddUserMode(new UserMode(UMODE_VHOST, 't'));
- ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
- ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
- ModeManager::AddUserMode(new UserMode(UMODE_SSL, 'z'));
+ ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, "UMODE_SERV_ADMIN", 'A'));
+ ModeManager::AddUserMode(new UserMode(UMODE_BOT, "UMODE_BOT", 'B'));
+ ModeManager::AddUserMode(new UserMode(UMODE_CO_ADMIN, "UMODE_CO_ADMIN", 'C'));
+ ModeManager::AddUserMode(new UserMode(UMODE_FILTER, "UMODE_FILTER", 'G'));
+ ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, "UMODE_HIDEOPER", 'H'));
+ ModeManager::AddUserMode(new UserMode(UMODE_NETADMIN, "UMODE_NETADMIN", 'N'));
+ ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, "UMODE_REGPRIV", 'R'));
+ ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, "UMODE_PROTECTED", 'S'));
+ ModeManager::AddUserMode(new UserMode(UMODE_NO_CTCP, "UMODE_NO_CTCP", 'T'));
+ ModeManager::AddUserMode(new UserMode(UMODE_WEBTV, "UMODE_WEBTV", 'V'));
+ ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, "UMODE_WHOIS", 'W'));
+ ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, "UMODE_ADMIN", 'a'));
+ ModeManager::AddUserMode(new UserMode(UMODE_DEAF, "UMODE_DEAF", 'd'));
+ ModeManager::AddUserMode(new UserMode(UMODE_GLOBOPS, "UMODE_GLOBOPS", 'g'));
+ ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, "UMODE_HELPOP", 'h'));
+ ModeManager::AddUserMode(new UserMode(UMODE_INVIS, "UMODE_INVIS", 'i'));
+ ModeManager::AddUserMode(new UserMode(UMODE_OPER, "UMODE_OPER", 'o'));
+ ModeManager::AddUserMode(new UserMode(UMODE_PRIV, "UMODE_PRIV", 'p'));
+ ModeManager::AddUserMode(new UserMode(UMODE_GOD, "UMODE_GOD", 'q'));
+ ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, "UMODE_REGISTERED", 'r'));
+ ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, "UMODE_SNOMASK", 's'));
+ ModeManager::AddUserMode(new UserMode(UMODE_VHOST, "UMODE_VHOST", 't'));
+ ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, "UMODE_WALLOPS", 'w'));
+ ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, "UMODE_CLOAK", 'x'));
+ ModeManager::AddUserMode(new UserMode(UMODE_SSL, "UMODE_SSL", 'z'));
}
class ProtoUnreal : public Module
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index 8eb4b28f0..8ee823e33 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -23,7 +23,6 @@ ChannelInfo::ChannelInfo(const std::string &chname)
if (chname.empty())
throw CoreException("Empty channel passed to ChannelInfo constructor");
- next = prev = NULL;
founder = successor = NULL;
desc = url = email = last_topic = forbidby = forbidreason = NULL;
last_topic_time = 0;
@@ -61,7 +60,8 @@ ChannelInfo::ChannelInfo(const std::string &chname)
this->ttb[i] = 0;
reset_levels(this);
- alpha_insert_chan(this);
+
+ RegisteredChannelList[this->name.c_str()] = this;
}
/** Default destructor, cleans up the channel complete and removes it from the internal list
@@ -84,12 +84,8 @@ ChannelInfo::~ChannelInfo()
this->c->ci = NULL;
}
- if (this->next)
- this->next->prev = this->prev;
- if (this->prev)
- this->prev->next = this->next;
- else
- chanlists[static_cast<unsigned char>(tolower(this->name[1]))] = this->next;
+ RegisteredChannelList.erase(this->name.c_str());
+
if (this->desc)
delete [] this->desc;
if (this->url)
@@ -142,7 +138,6 @@ ChannelInfo::~ChannelInfo()
void ChannelInfo::AddAccess(NickCore *nc, int16 level, const std::string &creator, int32 last_seen)
{
ChanAccess *new_access = new ChanAccess();
- new_access->in_use = 1;
new_access->nc = nc;
new_access->level = level;
new_access->last_seen = last_seen;
@@ -185,7 +180,7 @@ ChanAccess *ChannelInfo::GetAccess(NickCore *nc, int16 level)
return NULL;
for (unsigned i = 0; i < access.size(); i++)
- if (access[i]->in_use && access[i]->nc == nc && (level ? access[i]->level == level : true))
+ if (access[i]->nc == nc && (level ? access[i]->level == level : true))
return access[i];
return NULL;
@@ -214,25 +209,16 @@ void ChannelInfo::EraseAccess(unsigned index)
access.erase(access.begin() + index);
}
-/** Cleans the channel access list
- *
- * Cleans up the access list so it no longer contains entries no longer in use.
- */
-void ChannelInfo::CleanAccess()
-{
- for (unsigned j = access.size(); j > 0; --j)
- if (!access[j - 1]->in_use)
- EraseAccess(j - 1);
-}
-
/** Clear the entire channel access list
*
* Clears the entire access list by deleting every item and then clearing the vector.
*/
void ChannelInfo::ClearAccess()
{
- while (access.begin() != access.end())
+ while (!access.empty())
+ {
EraseAccess(0);
+ }
}
/** Add an akick entry to the channel by NickCore
@@ -249,7 +235,6 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, NickCore *akicknc, cons
return NULL;
AutoKick *autokick = new AutoKick();
- autokick->InUse = true;
autokick->SetFlag(AK_ISNICK);
autokick->nc = akicknc;
autokick->reason = reason;
@@ -259,8 +244,6 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, NickCore *akicknc, cons
akick.push_back(autokick);
- FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(this, autokick));
-
return autokick;
}
@@ -276,7 +259,6 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, const std::string &mask
{
AutoKick *autokick = new AutoKick();
autokick->mask = mask;
- autokick->InUse = true;
autokick->reason = reason;
autokick->creator = user;
autokick->addtime = t;
@@ -284,8 +266,6 @@ AutoKick *ChannelInfo::AddAkick(const std::string &user, const std::string &mask
akick.push_back(autokick);
- FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(this, autokick));
-
return autokick;
}
@@ -310,40 +290,27 @@ const unsigned ChannelInfo::GetAkickCount() const
}
/** Erase an entry from the channel akick list
- * @param akick The akick
+ * @param index The index of the akick
*/
-void ChannelInfo::EraseAkick(AutoKick *autokick)
+void ChannelInfo::EraseAkick(unsigned index)
{
- std::vector<AutoKick *>::iterator it = std::find(akick.begin(), akick.end(), autokick);
-
- if (it != akick.end())
- {
- FOREACH_MOD(I_OnAkickDel, OnAkickDel(this, *it));
-
- delete *it;
- akick.erase(it);
- }
+ if (akick.empty() || index > akick.size())
+ return;
+
+ delete akick[index];
+ akick.erase(akick.begin() + index);
}
/** Clear the whole akick list
*/
void ChannelInfo::ClearAkick()
{
- for (unsigned i = akick.size(); i > 0; --i)
+ while (!akick.empty())
{
- EraseAkick(akick[i - 1]);
+ EraseAkick(0);
}
}
-/** Clean all of the nonused entries from the akick list
- */
-void ChannelInfo::CleanAkick()
-{
- for (unsigned i = akick.size(); i > 0; --i)
- if (!akick[i - 1]->InUse)
- EraseAkick(akick[i - 1]);
-}
-
/** Add a badword to the badword list
* @param word The badword
* @param type The type (SINGLE START END)
@@ -352,7 +319,6 @@ void ChannelInfo::CleanAkick()
BadWord *ChannelInfo::AddBadWord(const std::string &word, BadWordType type)
{
BadWord *bw = new BadWord;
- bw->InUse = true;
bw->word = word;
bw->type = type;
@@ -384,37 +350,98 @@ const unsigned ChannelInfo::GetBadWordCount() const
}
/** Remove a badword
- * @param badword The badword
+ * @param index The index of the badword
*/
-void ChannelInfo::EraseBadWord(BadWord *badword)
+void ChannelInfo::EraseBadWord(unsigned index)
{
- std::vector<BadWord *>::iterator it = std::find(badwords.begin(), badwords.end(), badword);
-
- if (it != badwords.end())
- {
- FOREACH_MOD(I_OnBadWordDel, OnBadWordDel(this, *it));
- delete *it;
- badwords.erase(it);
- }
+ if (badwords.empty() || index >= badwords.size())
+ return;
+
+ delete badwords[index];
+ badwords.erase(badwords.begin() + index);
}
/** Clear all badwords from the channel
*/
void ChannelInfo::ClearBadWords()
{
- for (unsigned i = badwords.size(); i > 0; --i)
+ while (!badwords.empty())
{
- EraseBadWord(badwords[i - 1]);
+ EraseBadWord(0);
}
}
-/** Clean all of the nonused entries from the badwords list
+/** Loads MLocked modes from extensible. This is used from database loading because Anope doesn't know what modes exist
+ * until after it connects to the IRCd.
*/
-void ChannelInfo::CleanBadWords()
+void ChannelInfo::LoadMLock()
{
- for (unsigned i = badwords.size(); i > 0; --i)
- if (!badwords[i - 1]->InUse)
- EraseBadWord(badwords[i - 1]);
+ std::vector<std::string> modenames;
+
+ if (this->GetExtRegular("db_mlock_modes_on", modenames))
+ {
+ for (std::vector<std::string>::iterator it = modenames.begin(); it != modenames.end(); ++it)
+ {
+ for (std::list<Mode *>::iterator mit = ModeManager::Modes.begin(); mit != ModeManager::Modes.end(); ++mit)
+ {
+ if ((*mit)->Class == MC_CHANNEL)
+ {
+ ChannelMode *cm = dynamic_cast<ChannelMode *>(*mit);
+
+ if (cm->NameAsString == *it)
+ {
+ this->SetMLock(cm->Name, true);
+ }
+ }
+ }
+ }
+
+ this->Shrink("db_mlock_modes_on");
+ }
+
+ if (this->GetExtRegular("db_mlock_modes_off", modenames))
+ {
+ for (std::vector<std::string>::iterator it = modenames.begin(); it != modenames.end(); ++it)
+ {
+ for (std::list<Mode *>::iterator mit = ModeManager::Modes.begin(); mit != ModeManager::Modes.end(); ++mit)
+ {
+ if ((*mit)->Class == MC_CHANNEL)
+ {
+ ChannelMode *cm = dynamic_cast<ChannelMode *>(*mit);
+
+ if (cm->NameAsString == *it)
+ {
+ this->SetMLock(cm->Name, false);
+ }
+ }
+ }
+ }
+
+ this->Shrink("db_mlock_modes_off");
+ }
+
+ std::vector<std::pair<std::string, std::string> > params;
+
+ if (this->GetExtRegular("db_mlp", params))
+ {
+ for (std::vector<std::pair<std::string, std::string> >::iterator it = params.begin(); it != params.end(); ++it)
+ {
+ for (std::list<Mode *>::iterator mit = ModeManager::Modes.begin(); mit != ModeManager::Modes.end(); ++mit)
+ {
+ if ((*mit)->Class == MC_CHANNEL)
+ {
+ ChannelMode *cm = dynamic_cast<ChannelMode *>(*mit);
+
+ if (cm->NameAsString == it->first)
+ {
+ this->SetMLock(cm->Name, true, it->second);
+ }
+ }
+ }
+ }
+
+ this->Shrink("db_mlp");
+ }
}
/** Check if a mode is mlocked
@@ -425,9 +452,9 @@ void ChannelInfo::CleanBadWords()
const bool ChannelInfo::HasMLock(ChannelModeName Name, bool status)
{
if (status)
- return mlock_on[Name];
+ return mlock_on.HasFlag(Name);
else
- return mlock_off[Name];
+ return mlock_off.HasFlag(Name);
}
/** Set a mlock
@@ -438,8 +465,6 @@ const bool ChannelInfo::HasMLock(ChannelModeName Name, bool status)
*/
bool ChannelInfo::SetMLock(ChannelModeName Name, bool status, const std::string param)
{
- size_t value = Name;
-
if (!status && !param.empty())
throw CoreException("Was told to mlock a mode negatively with a param?");
@@ -449,8 +474,8 @@ bool ChannelInfo::SetMLock(ChannelModeName Name, bool status, const std::string
return false;
/* First, remove this everywhere */
- mlock_on[value] = false;
- mlock_off[value] = false;
+ mlock_on.UnsetFlag(Name);
+ mlock_off.UnsetFlag(Name);
std::map<ChannelModeName, std::string>::iterator it = Params.find(Name);
if (it != Params.end())
@@ -459,9 +484,9 @@ bool ChannelInfo::SetMLock(ChannelModeName Name, bool status, const std::string
}
if (status)
- mlock_on[value] = true;
+ mlock_on.SetFlag(Name);
else
- mlock_off[value] = true;
+ mlock_off.SetFlag(Name);
if (status && !param.empty())
{
@@ -477,15 +502,13 @@ bool ChannelInfo::SetMLock(ChannelModeName Name, bool status, const std::string
*/
bool ChannelInfo::RemoveMLock(ChannelModeName Name)
{
- size_t value = Name;
-
EventReturn MOD_RESULT;
FOREACH_RESULT(I_OnUnMLock, OnUnMLock(Name));
if (MOD_RESULT == EVENT_STOP)
return false;
- mlock_on[value] = false;
- mlock_off[value] = false;
+ mlock_on.UnsetFlag(Name);
+ mlock_off.UnsetFlag(Name);
std::map<ChannelModeName, std::string>::iterator it = Params.find(Name);
if (it != Params.end())
@@ -500,8 +523,8 @@ bool ChannelInfo::RemoveMLock(ChannelModeName Name)
*/
void ChannelInfo::ClearMLock()
{
- mlock_on.reset();
- mlock_off.reset();
+ mlock_on.ClearFlags();
+ mlock_off.ClearFlags();
}
/** Get the number of mlocked modes for this channel
@@ -511,9 +534,9 @@ void ChannelInfo::ClearMLock()
const size_t ChannelInfo::GetMLockCount(bool status) const
{
if (status)
- return mlock_on.count();
+ return mlock_on.FlagCount();
else
- return mlock_off.count();
+ return mlock_off.FlagCount();
}
/** Get a param from the channel
@@ -564,7 +587,7 @@ void ChannelInfo::ClearParams()
*/
bool ChannelInfo::CheckKick(User *user)
{
- AutoKick *akick;
+ AutoKick *autokick;
bool set_modes = false, do_kick = false;
NickCore *nc;
char mask[BUFSIZE];
@@ -573,13 +596,19 @@ bool ChannelInfo::CheckKick(User *user)
if (!user || !this->c)
return false;
- if (user->isSuperAdmin == 1)
+ if (user->isSuperAdmin)
return false;
/* We don't enforce services restrictions on clients on ulined services
* as this will likely lead to kick/rejoin floods. ~ Viper */
- if (is_ulined(user->server->name))
+ if (user->server->IsULined())
+ return false;
+
+ if (!do_kick && user->IsProtected())
return false;
+
+ if (ircd->chansqline && SQLineManager::Check(this->c))
+ do_kick = true;
if (!is_oper(user) && (this->HasFlag(CI_SUSPENDED) || this->HasFlag(CI_FORBIDDEN)))
{
@@ -589,34 +618,34 @@ bool ChannelInfo::CheckKick(User *user)
do_kick = true;
}
+ if (!do_kick && ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(this, user) == 1)
+ return false;
+
if (user->Account() || user->IsRecognized())
nc = user->Account();
else
nc = NULL;
- if (!do_kick && ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(this, user) == 1)
- return false;
-
- for (unsigned j = 0; j < this->GetAkickCount(); ++j)
+ if (!do_kick)
{
- akick = this->GetAkick(j);
-
- if (!akick->InUse || do_kick)
- continue;
-
- if ((akick->HasFlag(AK_ISNICK) && akick->nc == nc)
- || (!akick->HasFlag(AK_ISNICK)
- && match_usermask(akick->mask.c_str(), user)))
+ for (unsigned j = 0; j < this->GetAkickCount(); ++j)
{
- Alog(LOG_DEBUG_2) << user->nick << " matched akick " << (akick->HasFlag(AK_ISNICK) ?
-akick->nc->display : akick->mask);
- akick->last_used = time(NULL);
- if (akick->HasFlag(AK_ISNICK))
- get_idealban(this, user, mask, sizeof(mask));
- else
- strlcpy(mask, akick->mask.c_str(), sizeof(mask));
- reason = !akick->reason.empty() ? akick->reason.c_str() : Config.CSAutokickReason;
- do_kick = true;
+ autokick = this->GetAkick(j);
+
+ if ((autokick->HasFlag(AK_ISNICK) && autokick->nc == nc)
+ || (!autokick->HasFlag(AK_ISNICK)
+ && match_usermask(autokick->mask.c_str(), user)))
+ {
+ Alog(LOG_DEBUG_2) << user->nick << " matched akick " << (autokick->HasFlag(AK_ISNICK) ? autokick->nc->display : autokick->mask);
+ autokick->last_used = time(NULL);
+ if (autokick->HasFlag(AK_ISNICK))
+ get_idealban(this, user, mask, sizeof(mask));
+ else
+ strlcpy(mask, autokick->mask.c_str(), sizeof(mask));
+ reason = !autokick->reason.empty() ? autokick->reason.c_str() : Config.CSAutokickReason;
+ do_kick = true;
+ break;
+ }
}
}
@@ -631,7 +660,7 @@ akick->nc->display : akick->mask);
if (!do_kick)
return false;
- Alog(LOG_DEBUG) << "channel: Autokicking "<< user->GetMask() << " from " << this->name;
+ Alog(LOG_DEBUG) << "Autokicking "<< user->GetMask() << " from " << this->name;
/* If the channel isn't syncing and doesn't have any users, join ChanServ
* NOTE: we use usercount == 1 here as there is one user, but they are about to be destroyed
@@ -648,7 +677,7 @@ akick->nc->display : akick->mask);
}
/* Join ChanServ */
- ircdproto->SendJoin(findbot(Config.s_ChanServ), this->name.c_str(), this->c->creation_time);
+ ircdproto->SendJoin(ChanServ, this->name.c_str(), this->c->creation_time);
/* Set a timer for this channel to part ChanServ later */
new ChanServTimer(this->c);
diff --git a/src/send.c b/src/send.cpp
index e16856598..4209e2a1b 100644
--- a/src/send.c
+++ b/src/send.cpp
@@ -32,6 +32,15 @@ void send_cmd(const char *source, const char *fmt, ...)
vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ if (!UplinkSock)
+ {
+ if (source)
+ Alog(LOG_DEBUG) << "Attemtped to send \"" << source << " " << buf << "\" with UplinkSock NULL";
+ else
+ Alog(LOG_DEBUG) << "Attemtped to send \"" << buf << "\" with UplinkSock NULL";
+ return;
+ }
+
if (source)
{
UplinkSock->Write(":%s %s", source, buf);
@@ -59,6 +68,15 @@ void send_cmd(const std::string &source, const char *fmt, ...)
vsnprintf(buf, BUFSIZE - 1, fmt, args);
+ if (!UplinkSock)
+ {
+ if (!source.empty())
+ Alog(LOG_DEBUG) << "Attemtped to send \"" << source << " " << buf << "\" with UplinkSock NULL";
+ else
+ Alog(LOG_DEBUG) << "Attemtped to send " << buf << "\" with UplinkSock NULL";
+ return;
+ }
+
if (!source.empty())
{
UplinkSock->Write(":%s %s", source.c_str(), buf);
diff --git a/src/servers.c b/src/servers.c
deleted file mode 100644
index 0978e8f30..000000000
--- a/src/servers.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/* Routines to maintain a list of connected servers
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-
-#include "services.h"
-#include "modules.h"
-
-Server *servlist = NULL;
-Server *me_server = NULL; /* This are we */
-Server *serv_uplink = NULL; /* This is our uplink */
-Flags<CapabType> Capab;
-char *uplink;
-char *TS6UPLINK;
-char *TS6SID;
-
-/* For first_server / next_server */
-static Server *server_cur;
-
-CapabInfo Capab_Info[] = {
- {"NOQUIT", CAPAB_NOQUIT},
- {"TSMODE", CAPAB_TSMODE},
- {"UNCONNECT", CAPAB_UNCONNECT},
- {"NICKIP", CAPAB_NICKIP},
- {"SSJOIN", CAPAB_NSJOIN},
- {"ZIP", CAPAB_ZIP},
- {"BURST", CAPAB_BURST},
- {"TS5", CAPAB_TS5},
- {"TS3", CAPAB_TS3},
- {"DKEY", CAPAB_DKEY},
- {"PT4", CAPAB_PT4},
- {"SCS", CAPAB_SCS},
- {"QS", CAPAB_QS},
- {"UID", CAPAB_UID},
- {"KNOCK", CAPAB_KNOCK},
- {"CLIENT", CAPAB_CLIENT},
- {"IPV6", CAPAB_IPV6},
- {"SSJ5", CAPAB_SSJ5},
- {"SN2", CAPAB_SN2},
- {"TOK1", CAPAB_TOKEN},
- {"TOKEN", CAPAB_TOKEN},
- {"VHOST", CAPAB_VHOST},
- {"SSJ3", CAPAB_SSJ3},
- {"SJB64", CAPAB_SJB64},
- {"CHANMODES", CAPAB_CHANMODE},
- {"NICKCHARS", CAPAB_NICKCHARS},
- {"", CAPAB_END}
-};
-
-/*************************************************************************/
-
-/**
- * Return the first server in the server struct
- * @param flag Server Flag, see services.h
- * @return Server Struct
- */
-Server *first_server(ServerFlag flag)
-{
- server_cur = servlist;
-
- while (server_cur && !server_cur->HasFlag(flag))
- server_cur = next_server(flag);
- return server_cur;
-}
-
-/*************************************************************************/
-
-/**
- * Return the next server in the server struct
- * @param flags Server Flags, see services.h
- * @return Server Struct
- */
-Server *next_server(ServerFlag flag)
-{
- if (!server_cur)
- return NULL;
-
- do {
- if (server_cur->links) {
- server_cur = server_cur->links;
- } else if (server_cur->next) {
- server_cur = server_cur->next;
- } else {
- do {
- server_cur = server_cur->uplink;
- if (server_cur && server_cur->next) {
- server_cur = server_cur->next;
- break;
- }
- } while (server_cur);
- }
- } while (server_cur && !server_cur->HasFlag(flag));
-
- return server_cur;
-}
-
-/*************************************************************************/
-
-/**
- * This function makes a new Server structure and links it in the right
- * places in the linked list if a Server struct to it's uplink if provided.
- * It can also be NULL to indicate it's the uplink and should be first in
- * the server list.
- * @param server_uplink Server struct
- * @param name Server Name
- * @param desc Server Description
- * @param flags Server Flags, see services.h
- * @param suid Server Universal ID
- * @return Server Struct
- */
-Server *new_server(Server * server_uplink, const char *name, const char *desc,
- ServerFlag flag, const std::string &suid)
-{
- Server *serv;
-
- Alog(LOG_DEBUG) << "Creating " << name << "(" << suid << ") uplinked to " << (server_uplink ? server_uplink->name : "No uplink");
- serv = new Server;
- if (!name)
- name = "";
- serv->name = sstrdup(name);
- serv->desc = sstrdup(desc);
- if (flag != SERVER_START)
- serv->SetFlag(flag);
- serv->uplink = server_uplink;
- if (!suid.empty())
- serv->suid = sstrdup(suid.c_str());
- else
- serv->suid = NULL;
-
- serv->sync = SSYNC_IN_PROGRESS;
- serv->links = NULL;
- serv->prev = NULL;
-
- if (!server_uplink) {
- serv->hops = 0;
- serv->next = servlist;
- if (servlist)
- servlist->prev = serv;
- servlist = serv;
- } else {
- serv->hops = server_uplink->hops + 1;
- serv->next = server_uplink->links;
- if (server_uplink->links)
- server_uplink->links->prev = serv;
- server_uplink->links = serv;
- }
-
- /* Check if this is our uplink server */
- if ((server_uplink == me_server) && flag != SERVER_JUPED)
- {
- // XXX: Apparantly we set ourselves as serv_uplink before we (really) set the uplink when we recieve SERVER. This is wrong and ugly.
- if (serv_uplink != NULL)
- {
- /* Bring in our pseudo-clients */
- introduce_user("");
-
- /* And hybrid needs Global joined in the logchan */
- if (LogChan && ircd->join2msg) {
- /* XXX might desync */
- ircdproto->SendJoin(findbot(Config.s_GlobalNoticer), Config.LogChannel, time(NULL));
- }
- }
- serv_uplink = serv;
- serv->SetFlag(SERVER_ISUPLINK);
- }
-
- return serv;
-}
-
-/*************************************************************************/
-
-/**
- * Remove and free a Server structure. This function is the most complete
- * remove treatment a server can get, as it first quits all clients which
- * still pretend to be on this server, then it walks through all connected
- * servers and disconnects them too. If all mess is cleared, the server
- * itself will be too.
- * @param Server struct
- * @param reason the server quit
- * @return void
- */
-static void delete_server(Server * serv, const char *quitreason)
-{
- Server *s, *snext;
- User *u, *unext;
- NickAlias *na;
-
- if (!serv) {
- Alog(LOG_DEBUG) << "delete_server() called with NULL arg!";
- return;
- }
-
- Alog(LOG_DEBUG) << "delete_server() called, deleting " << serv->name << "(" << serv->suid << ") uplinked to "
- << (serv->uplink ? serv->uplink->name : "NOTHING") << "("
- << (serv->uplink ? serv->uplink->suid : "NOSUIDUPLINK") << ")";
-
- if (Capab.HasFlag(CAPAB_NOQUIT) || Capab.HasFlag(CAPAB_QS))
- {
- u = firstuser();
- while (u)
- {
- unext = nextuser();
- if (u->server == serv)
- {
- if ((na = findnick(u->nick)) && !na->HasFlag(NS_FORBIDDEN)
- && (!na->nc->HasFlag(NI_SUSPENDED))
- && (u->IsRecognized() || u->IsIdentified())) {
- na->last_seen = time(NULL);
- if (na->last_quit)
- delete [] na->last_quit;
- na->last_quit = (quitreason ? sstrdup(quitreason) : NULL);
- }
- if (Config.LimitSessions && !is_ulined(u->server->name)) {
- del_session(u->host);
- }
- delete u;
- }
- u = unext;
- }
- Alog(LOG_DEBUG) << "delete_server() cleared all users";
- }
-
- s = serv->links;
- while (s) {
- snext = s->next;
- delete_server(s, quitreason);
- s = snext;
- }
-
- Alog(LOG_DEBUG) << "delete_server() cleared all servers";
-
- delete [] serv->name;
- delete [] serv->desc;
- if (serv->prev)
- serv->prev->next = serv->next;
- if (serv->next)
- serv->next->prev = serv->prev;
- if (serv->uplink->links == serv)
- serv->uplink->links = serv->next;
-
- Alog(LOG_DEBUG) << "delete_server() completed";
-}
-
-/*************************************************************************/
-
-/**
- * Find a server by name, returns NULL if not found
- * @param s Server struct
- * @param name Server Name
- * @return Server struct
- */
-Server *findserver(Server * s, const char *name)
-{
- Server *sl;
-
- if (!name || !*name) {
- return NULL;
- }
-
- Alog(LOG_DEBUG) << "findserver(" << name << ")";
-
- while (s && (stricmp(s->name, name) != 0))
- {
- Alog(LOG_DEBUG_3) << "Compared " << s->name << ", not a match";
- if (s->links)
- {
- sl = findserver(s->links, name);
- if (sl)
- {
- s = sl;
- }
- else
- {
- s = s->next;
- }
- }
- else
- {
- s = s->next;
- }
- }
-
- Alog(LOG_DEBUG) << "findserver(" << name << ") -> " << static_cast<void *>(s);
- return s;
-}
-
-/*************************************************************************/
-
-/**
- * Find a server by UID, returns NULL if not found
- * @param s Server struct
- * @param name Server Name
- * @return Server struct
- */
-Server *findserver_uid(Server * s, const char *name)
-{
- Server *sl;
-
- if (!name || !*name) {
- return NULL;
- }
-
- Alog(LOG_DEBUG) << "findserver_uid(" << name << ")";
-
- while (s && s->suid && (stricmp(s->suid, name) != 0))
- {
- Alog(LOG_DEBUG_3) << "Compared " << s->suid << ", not a match";
- if (s->links)
- {
- sl = findserver_uid(s->links, name);
- if (sl)
- {
- s = sl;
- }
- else
- {
- s = s->next;
- }
- }
- else
- {
- s = s->next;
- }
- }
-
- Alog(LOG_DEBUG) << "findserver_uid(" << name << ") -> " << static_cast<void *>(s);
- return s;
-}
-
-/*************************************************************************/
-
-/**
- * Find if the server is synced with the network
- * @param s Server struct
- * @param name Server Name
- * @return Not Synced returns -1, Synced returns 1, Error returns 0
- */
-int anope_check_sync(const char *name)
-{
- Server *s;
- s = findserver(servlist, name);
-
- if (!s)
- return 0;
-
- if (is_sync(s))
- return 1;
- else
- return -1;
-}
-
-/*************************************************************************/
-
-/**
- * Handle adding the server to the Server struct
- * @param source Name of the uplink if any
- * @param servername Name of the server being linked
- * @param hops Number of hops to reach this server
- * @param descript Description of the server
- * @param numeric Server Numberic/SUID
- * @return void
- */
-void do_server(const char *source, const char *servername, const char *hops,
- const char *descript, const std::string &numeric)
-{
- Server *s, *newserver;
-
- Alog(LOG_DEBUG) << "Server introduced (" << servername << ")" << (*source ? " from " : "") << (*source ? source : "");
-
-
- if (source[0] == '\0')
- s = me_server;
- else
- s = findserver(servlist, source);
-
- if (s == NULL)
- s = findserver_uid(servlist, source);
-
- if (s == NULL)
- throw CoreException("Recieved a server from a nonexistant uplink?");
-
- /* Create a server structure. */
- newserver = new_server(s, servername, descript, SERVER_START, numeric);
-
- /* Announce services being online. */
- if (Config.GlobalOnCycle && Config.GlobalOnCycleUP)
- notice_server(Config.s_GlobalNoticer, newserver, "%s", Config.GlobalOnCycleUP);
-
- /* Let modules know about the connection */
- FOREACH_MOD(I_OnNewServer, OnNewServer(newserver));
-}
-
-/*************************************************************************/
-
-/**
- * Handle removing the server from the Server struct
- * @param source Name of the server leaving
- * @param ac Number of arguments in av
- * @param av Agruments as part of the SQUIT
- * @return void
- */
-void do_squit(const char *source, int ac, const char **av)
-{
- char buf[BUFSIZE];
- Server *s;
-
- if (ircd->ts6) {
- s = findserver_uid(servlist, av[0]);
- if (!s) {
- s = findserver(servlist, av[0]);
- }
- } else {
- s = findserver(servlist, av[0]);
- }
- if (!s)
- {
- Alog() << "SQUIT for nonexistent server (" << av[0] << ")!!";
- return;
- }
- FOREACH_MOD(I_OnServerQuit, OnServerQuit(s));
-
- /* If this is a juped server, send a nice global to inform the online
- * opers that we received it.
- */
- if (s->HasFlag(SERVER_JUPED))
- {
- snprintf(buf, BUFSIZE, "Received SQUIT for juped server %s",
- s->name);
- ircdproto->SendGlobops(findbot(Config.s_OperServ), buf);
- }
-
- snprintf(buf, sizeof(buf), "%s %s", s->name,
- (s->uplink ? s->uplink->name : ""));
-
- if (s->uplink == me_server && Capab.HasFlag(CAPAB_UNCONNECT))
- {
- Alog(LOG_DEBUG) << "Sending UNCONNECT SQUIT for " << s->name;
- /* need to fix */
- ircdproto->SendSquit(s->name, buf);
- }
-
- delete_server(s, buf);
-}
-
-/*************************************************************************/
-
-/** Handle parsing the CAPAB/PROTOCTL messages
- * @param ac Number of args
- * @param av Args
- */
-void CapabParse(int ac, const char **av)
-{
- for (int i = 0; i < ac; ++i)
- {
- for (unsigned j = 0; !Capab_Info[j].Token.empty(); ++j)
- {
- if (av[i] == Capab_Info[j].Token)
- {
- Capab.SetFlag(Capab_Info[j].Flag);
-
- if (Capab_Info[j].Token == "NICKIP" && !ircd->nickip)
- ircd->nickip = 1;
- break;
- }
- }
- }
-}
-
-/*************************************************************************/
-
-/**
- * Search the uline servers array to find out if the server that just set the
- * mode is in our uline list
- * @param server Server Setting the mode
- * @return int 0 if not found, 1 if found
- */
-int is_ulined(const char *server)
-{
- int j;
-
- for (j = 0; j < Config.NumUlines; j++) {
- if (stricmp(Config.Ulines[j], server) == 0) {
- return 1;
- }
- }
-
- return 0;
-}
-
-/*************************************************************************/
-
-/**
- * See if the current server is synced, or has an unknown sync state
- * (in which case we pretend it is always synced)
- * @param server Server of which we want to know the state
- * @return int 0 if not synced, 1 if synced
- */
-int is_sync(Server * server)
-{
- if (server->sync == SSYNC_DONE)
- return 1;
- return 0;
-}
-
-/*************************************************************************/
-
-/* Finish the syncing process for this server and (optionally) for all
- * it's leaves as well
- * @param serv Server to finish syncing
- * @param sync_links Should all leaves be synced as well? (1: yes, 0: no)
- * @return void
- */
-void finish_sync(Server * serv, int sync_links)
-{
- Server *s;
-
- if (!serv || is_sync(serv))
- return;
-
- /* Mark each server as in sync */
- s = serv;
- do {
- if (!is_sync(s))
- {
- Alog(LOG_DEBUG) << "Finishing sync for server " << s->name;
- s->sync = SSYNC_DONE;
- }
-
- if (!sync_links)
- break;
-
- if (s->links) {
- s = s->links;
- } else if (s->next) {
- s = s->next;
- } else {
- do {
- s = s->uplink;
- if (s == serv)
- s = NULL;
- if (s == me_server)
- s = NULL;
- } while (s && !(s->next));
- if (s)
- s = s->next;
- }
- } while (s);
-
- if (serv == serv_uplink)
- {
- FOREACH_MOD(I_OnFinishSync, OnFinishSync(serv));
- ircdproto->SendEOB();
- }
-
- /* Do some general stuff which should only be done once */
- // XXX: this doesn't actually match the description. finish_sync(), depending on the ircd, can be called multiple times
- // Perhaps this should be done if serv == serv_uplink?
- restore_unsynced_topics();
- Alog() << "Server " << serv->name << " is done syncing";
-
- FOREACH_MOD(I_OnServerSync, OnServerSync(s));
- if (serv == serv_uplink)
- {
- FOREACH_MOD(I_OnUplinkSync, OnUplinkSync());
- }
-}
-
-/*******************************************************************/
-
-/* TS6 UID generator common code.
- *
- * Derived from atheme-services, uid.c (hg 2954:116d46894b4c).
- * -nenolod
- */
-static int ts6_uid_initted = 0;
-static char ts6_new_uid[10]; /* allow for \0 */
-static unsigned int ts6_uid_index = 9; /* last slot in uid buf */
-
-void ts6_uid_init()
-{
- snprintf(ts6_new_uid, 10, "%sAAAAAA", TS6SID);
- ts6_uid_initted = 1;
-}
-
-void ts6_uid_increment(unsigned int slot)
-{
- if (slot != strlen(TS6SID)) {
- if (ts6_new_uid[slot] == 'Z')
- ts6_new_uid[slot] = '0';
- else if (ts6_new_uid[slot] == '9') {
- ts6_new_uid[slot] = 'A';
- ts6_uid_increment(slot - 1);
- } else
- ts6_new_uid[slot]++;
- } else {
- if (ts6_new_uid[slot] == 'Z')
- for (slot = 3; slot < 9; slot++)
- ts6_new_uid[slot] = 'A';
- else
- ts6_new_uid[slot]++;
- }
-}
-
-const char *ts6_uid_retrieve()
-{
- if (ircd->ts6 == 0)
- {
- Alog(LOG_DEBUG) << "ts6_uid_retrieve(): TS6 not supported on this ircd";
- return "";
- }
-
- if (ts6_uid_initted != 1)
- {
- throw CoreException("TS6 IRCd and ts6_uid_init() hasn't been called!");
- }
-
- ts6_uid_increment(ts6_uid_index - 1);
- return ts6_new_uid;
-}
-
-/*******************************************************************/
-
-/*
- * TS6 generator code, provided by DukePyrolator
- */
-
-static int ts6_sid_initted = 0;
-static char ts6_new_sid[4];
-
-static void ts6_sid_increment(unsigned pos)
-{
- /*
- * An SID must be exactly 3 characters long, starts with a digit,
- * and the other two characters are A-Z or digits
- * The rules for generating an SID go like this...
- * --> ABCDEFGHIJKLMNOPQRSTUVWXYZ --> 0123456789 --> WRAP
- */
- if (!pos)
- {
- /* At pos 0, if we hit '9', we've run out of available SIDs,
- * reset the SID to the smallest possible value and try again. */
- if (ts6_new_sid[pos] == '9')
- {
- ts6_new_sid[0] = '0';
- ts6_new_sid[1] = 'A';
- ts6_new_sid[2] = 'A';
- }
- else
- // But if we haven't, just keep incrementing merrily.
- ++ts6_new_sid[0];
- }
- else
- {
- if (ts6_new_sid[pos] == 'Z')
- ts6_new_sid[pos] = '0';
- else if (ts6_new_sid[pos] == '9')
- {
- ts6_new_sid[pos] = 'A';
- ts6_sid_increment(pos - 1);
- }
- else
- ++ts6_new_sid[pos];
- }
-}
-
-const char *ts6_sid_retrieve()
-{
- if (!ircd->ts6)
- {
- Alog(LOG_DEBUG) << "ts6_sid_retrieve(): TS6 not supported on this ircd";
- return "";
- }
-
- if (!ts6_sid_initted)
- {
- // Initialize ts6_new_sid with the services server SID
- snprintf(ts6_new_sid, 4, "%s", TS6SID);
- ts6_sid_initted = 1;
- }
- while (1)
- {
- // Check if the new SID is used by a known server
- if (!findserver_uid(servlist, ts6_new_sid))
- // return the new SID
- return ts6_new_sid;
-
- // Add one to the last SID
- ts6_sid_increment(2);
- }
- /* not reached */
- return "";
-}
-
-/* EOF */
diff --git a/src/servers.cpp b/src/servers.cpp
new file mode 100644
index 000000000..88b326f47
--- /dev/null
+++ b/src/servers.cpp
@@ -0,0 +1,585 @@
+/* Routines to maintain a list of connected servers
+ *
+ * (C) 2003-2010 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+
+#include "services.h"
+#include "modules.h"
+
+char *TS6SID = NULL;
+
+/* Anope */
+Server *Me = NULL;
+
+CapabInfo Capab_Info[] = {
+ {"NOQUIT", CAPAB_NOQUIT},
+ {"TSMODE", CAPAB_TSMODE},
+ {"UNCONNECT", CAPAB_UNCONNECT},
+ {"NICKIP", CAPAB_NICKIP},
+ {"SSJOIN", CAPAB_NSJOIN},
+ {"ZIP", CAPAB_ZIP},
+ {"BURST", CAPAB_BURST},
+ {"TS5", CAPAB_TS5},
+ {"TS3", CAPAB_TS3},
+ {"DKEY", CAPAB_DKEY},
+ {"PT4", CAPAB_PT4},
+ {"SCS", CAPAB_SCS},
+ {"QS", CAPAB_QS},
+ {"UID", CAPAB_UID},
+ {"KNOCK", CAPAB_KNOCK},
+ {"CLIENT", CAPAB_CLIENT},
+ {"IPV6", CAPAB_IPV6},
+ {"SSJ5", CAPAB_SSJ5},
+ {"SN2", CAPAB_SN2},
+ {"TOK1", CAPAB_TOKEN},
+ {"TOKEN", CAPAB_TOKEN},
+ {"VHOST", CAPAB_VHOST},
+ {"SSJ3", CAPAB_SSJ3},
+ {"SJB64", CAPAB_SJB64},
+ {"CHANMODES", CAPAB_CHANMODE},
+ {"NICKCHARS", CAPAB_NICKCHARS},
+ {"", CAPAB_END}
+};
+
+Flags<CapabType> Capab;
+
+/** Constructor
+ * @param uplink The uplink this server is from, is only NULL when creating Me
+ * @param name The server name
+ * @param hops Hops from services server
+ * @param description Server rdescription
+ * @param sid Server sid/numeric
+ */
+Server::Server(Server *uplink, const std::string &name, unsigned int hops, const std::string &description, const std::string &sid) : Name(name), Hops(hops), Description(description), SID(sid), UplinkServer(uplink)
+{
+ Links = NULL;
+
+ SetFlag(SERVER_SYNCING);
+
+ Alog(LOG_DEBUG) << "Creating " << GetName() << " (" << GetSID() << ") uplinked to " << (UplinkServer ? UplinkServer->GetName() : "no uplink");
+
+ /* Add this server to our uplinks leaf list */
+ if (UplinkServer)
+ UplinkServer->AddLink(this);
+
+ if (Me && UplinkServer && Me == UplinkServer)
+ {
+ /* Bring in our pseudo-clients */
+ introduce_user("");
+
+ /* And some IRCds needs Global joined in the logchan */
+ if (LogChan && ircd->join2msg)
+ {
+ /* XXX might desync */
+ ircdproto->SendJoin(Global, Config.LogChannel, time(NULL));
+ }
+ }
+}
+
+/** Destructor
+ */
+Server::~Server()
+{
+ Alog(LOG_DEBUG) << "Deleting server " << GetName() << " (" << GetSID() << ") uplinked to " << GetName();
+
+ if (Capab.HasFlag(CAPAB_NOQUIT) || Capab.HasFlag(CAPAB_QS))
+ {
+ time_t t = time(NULL);
+
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();)
+ {
+ User *u = it->second;
+ ++it;
+
+ if (u->server == this)
+ {
+ NickAlias *na = findnick(u->nick);
+ if (na && !na->HasFlag(NS_FORBIDDEN) && (!na->nc->HasFlag(NI_SUSPENDED)) && (u->IsRecognized() || u->IsIdentified()))
+ {
+ na->last_seen = t;
+ if (na->last_quit)
+ delete [] na->last_quit;
+ na->last_quit = (!QReason.empty() ? sstrdup(QReason.c_str()) : NULL);
+ }
+
+ if (Config.LimitSessions && !u->server->IsULined())
+ {
+ del_session(u->host);
+ }
+
+ delete u;
+ }
+ }
+
+ Alog(LOG_DEBUG) << "Finished removing all users for " << GetName();
+ }
+
+ if (Links)
+ {
+ for (std::list<Server *>::iterator it = Links->begin(); it != Links->end(); ++it)
+ {
+ delete *it;
+ }
+ }
+
+ delete Links;
+}
+
+/** Delete this server with a reason
+ * @param reason The reason
+ */
+void Server::Delete(const std::string &reason)
+{
+ QReason = reason;
+ delete this;
+}
+
+/** Get the name for this server
+ * @return The name
+ */
+const std::string& Server::GetName() const
+{
+ return Name;
+}
+
+/** Get the number of hops this server is from services
+ * @return Number of hops
+ */
+unsigned int Server::GetHops() const
+{
+ return Hops;
+}
+
+/** Set the server description
+ * @param desc The new description
+ */
+void Server::SetDescription(const std::string& desc)
+{
+ Description = desc;
+}
+
+/** Get the server description
+ * @return The server description
+ */
+const std::string& Server::GetDescription() const
+{
+ return Description;
+}
+
+/** Get the server numeric/SID
+ * @return The numeric/SID
+ */
+const std::string& Server::GetSID() const
+{
+ return SID;
+}
+
+/** Get the list of links this server has, or NULL if it has none
+ * @return A list of servers
+ */
+const std::list<Server*>* Server::GetLinks() const
+{
+ return Links;
+}
+
+/** Get the uplink server for this server, if this is our uplink will be Me
+ * @return The servers uplink
+ */
+Server* Server::GetUplink() const
+{
+ return UplinkServer;
+}
+
+/** Adds a link to this server
+ * @param s The linking server
+ */
+void Server::AddLink(Server *s)
+{
+ /* This is only used for Me, initially we start services with an uplink of NULL, then
+ * connect to the server which introduces itself and has us as the uplink, which calls this
+ */
+ if (!UplinkServer)
+ {
+ UplinkServer = s;
+ }
+ else
+ {
+ if (!Links)
+ {
+ Links = new std::list<Server *>();
+ }
+
+ Links->push_back(s);
+ }
+
+ Alog() << "Server " << s->GetName() << " introduced from " << GetName();
+}
+
+/** Delinks a server from this server
+ * @param s The server
+ */
+void Server::DelLink(Server *s)
+{
+ if (!Links)
+ throw CoreException("Server::DelLink called on " + GetName() + " for " + s->GetName() + " but we have no links?");
+
+ for (std::list<Server *>::iterator it = Links->begin(); it != Links->end(); ++it)
+ {
+ if (*it == s)
+ {
+ Links->erase(it);
+ break;
+ }
+ }
+
+ if (Links->empty())
+ {
+ delete Links;
+ Links = NULL;
+ }
+
+ Alog() << "Server " << s->GetName() << " quit from " << GetName();
+}
+
+/** Finish syncing this server and optionally all links to it
+ * @param SyncLinks True to sync the links for this server too (if any)
+ */
+void Server::Sync(bool SyncLinks)
+{
+ if (IsSynced())
+ return;
+
+ UnsetFlag(SERVER_SYNCING);
+
+ if (SyncLinks && Links)
+ {
+ for (std::list<Server *>::iterator it = Links->begin(); it != Links->end(); ++it)
+ {
+ (*it)->Sync(true);
+ }
+ }
+
+ if (this == Me->GetUplink())
+ {
+ FOREACH_MOD(I_OnPreUplinkSync, OnPreUplinkSync(this));
+ ircdproto->SendEOB();
+ Me->UnsetFlag(SERVER_SYNCING);
+ }
+
+ Alog() << "Server " << GetName() << " is done syncing";
+
+ FOREACH_MOD(I_OnServerSync, OnServerSync(this));
+
+ if (this == Me->GetUplink())
+ {
+ FOREACH_MOD(I_OnUplinkSync, OnUplinkSync(this));
+ restore_unsynced_topics();
+ }
+}
+
+/** Check if this server is synced
+ * @return true or false
+ */
+bool Server::IsSynced() const
+{
+ return !HasFlag(SERVER_SYNCING);
+}
+
+/** Check if this server is ULined
+ * @return true or false
+ */
+bool Server::IsULined() const
+{
+ for (int j = 0; j < Config.NumUlines; ++j)
+ if (!stricmp(Config.Ulines[j], GetName().c_str()))
+ return true;
+ return false;
+}
+
+/** Find a server
+ * @param name The name or SID/numeric
+ * @param s The server list to search for this server on, defaults to our Uplink
+ * @return The server
+ */
+Server* Server::Find(const std::string &name, Server *s)
+{
+ if (!s)
+ s = Me->GetUplink();
+ if (s->GetName() == name || s->GetSID() == name)
+ return s;
+
+ if (s->GetLinks())
+ {
+ for (std::list<Server *>::const_iterator it = s->GetLinks()->begin(); it != s->GetLinks()->end(); ++it)
+ {
+ Server *serv = *it;
+
+ if (serv->GetName() == name || serv->GetSID() == name)
+ return serv;
+ Server *server = Server::Find(name, serv);
+ if (server)
+ return server;
+ }
+ }
+
+ return NULL;
+}
+
+/*************************************************************************/
+
+/**
+ * Handle adding the server to the Server struct
+ * @param source Name of the uplink if any
+ * @param servername Name of the server being linked
+ * @param hops Number of hops to reach this server
+ * @param descript Description of the server
+ * @param numeric Server Numberic/SUID
+ * @return void
+ */
+void do_server(const std::string &source, const std::string &servername, unsigned int hops, const std::string &descript, const std::string &numeric)
+{
+ if (source.empty())
+ Alog(LOG_DEBUG) << "Server " << servername << " introduced";
+ else
+ Alog(LOG_DEBUG) << "Server introduced (" << servername << ")" << " from " << source;
+
+ Server *s = NULL;
+
+ if (!source.empty())
+ {
+ s = Server::Find(source);
+
+ if (!s)
+ throw CoreException("Recieved a server from a nonexistant uplink?");
+ }
+ else
+ s = Me;
+
+ /* Create a server structure. */
+ Server *newserver = new Server(s, servername, hops, descript, numeric);
+
+ /* Announce services being online. */
+ if (Config.GlobalOnCycle && Config.GlobalOnCycleUP)
+ notice_server(Config.s_GlobalNoticer, newserver, "%s", Config.GlobalOnCycleUP);
+
+ /* Let modules know about the connection */
+ FOREACH_MOD(I_OnNewServer, OnNewServer(newserver));
+}
+
+/*************************************************************************/
+
+/**
+ * Handle removing the server from the Server struct
+ * @param source Name of the server leaving
+ * @param ac Number of arguments in av
+ * @param av Agruments as part of the SQUIT
+ * @return void
+ */
+void do_squit(const char *source, int ac, const char **av)
+{
+ char buf[BUFSIZE];
+ Server *s = Server::Find(av[0]);
+
+ if (!s)
+ {
+ Alog() << "SQUIT for nonexistent server (" << av[0] << ")!!";
+ return;
+ }
+
+ FOREACH_MOD(I_OnServerQuit, OnServerQuit(s));
+
+ /* If this is a juped server, send a nice global to inform the online
+ * opers that we received it.
+ */
+ if (s->HasFlag(SERVER_JUPED))
+ {
+ snprintf(buf, BUFSIZE, "Received SQUIT for juped server %s", s->GetName().c_str());
+ ircdproto->SendGlobops(OperServ, buf);
+ }
+
+ snprintf(buf, sizeof(buf), "%s %s", s->GetName().c_str(), s->GetUplink()->GetName().c_str());
+
+ if (s->GetUplink() == Me->GetUplink() && Capab.HasFlag(CAPAB_UNCONNECT))
+ {
+ Alog(LOG_DEBUG) << "Sending UNCONNECT SQUIT for " << s->GetName();
+ /* need to fix */
+ ircdproto->SendSquit(s->GetName().c_str(), buf);
+ }
+
+ s->Delete(buf);
+}
+
+/*************************************************************************/
+
+/** Handle parsing the CAPAB/PROTOCTL messages
+ * @param ac Number of args
+ * @param av Args
+ */
+void CapabParse(int ac, const char **av)
+{
+ for (int i = 0; i < ac; ++i)
+ {
+ for (unsigned j = 0; !Capab_Info[j].Token.empty(); ++j)
+ {
+ if (av[i] == Capab_Info[j].Token)
+ {
+ Capab.SetFlag(Capab_Info[j].Flag);
+
+ if (Capab_Info[j].Token == "NICKIP" && !ircd->nickip)
+ ircd->nickip = 1;
+ break;
+ }
+ }
+ }
+
+ /* Apply MLock now that we know what modes exist (capab is parsed after modes are added to Anope) */
+ for (registered_channel_map::iterator it = RegisteredChannelList.begin(); it != RegisteredChannelList.end(); ++it)
+ {
+ ChannelInfo *ci = it->second;
+
+ ci->LoadMLock();
+ }
+}
+
+/*************************************************************************/
+
+/* TS6 UID generator common code.
+ *
+ * Derived from atheme-services, uid.c (hg 2954:116d46894b4c).
+ * -nenolod
+ */
+static bool ts6_uid_initted = false;
+static char ts6_new_uid[10];
+
+static void ts6_uid_increment(unsigned int slot)
+{
+ if (slot != strlen(TS6SID))
+ {
+ if (ts6_new_uid[slot] == 'Z')
+ ts6_new_uid[slot] = '0';
+ else if (ts6_new_uid[slot] == '9')
+ {
+ ts6_new_uid[slot] = 'A';
+ ts6_uid_increment(slot - 1);
+ }
+ else
+ ++ts6_new_uid[slot];
+ }
+ else
+ {
+ if (ts6_new_uid[slot] == 'Z')
+ for (slot = 3; slot < 9; slot++)
+ ts6_new_uid[slot] = 'A';
+ else
+ ++ts6_new_uid[slot];
+ }
+}
+
+/** Recieve the next UID in our list
+ * @return The UID
+ */
+const char *ts6_uid_retrieve()
+{
+ if (ircd->ts6 == 0)
+ {
+ Alog(LOG_DEBUG) << "ts6_uid_retrieve(): TS6 not supported on this ircd";
+ return "";
+ }
+
+ if (!ts6_uid_initted)
+ {
+ snprintf(ts6_new_uid, 10, "%sAAAAAA", TS6SID);
+ ts6_uid_initted = true;
+ }
+
+ ts6_uid_increment(8);
+ return ts6_new_uid;
+}
+
+/*******************************************************************/
+
+/*
+ * TS6 generator code, provided by DukePyrolator
+ */
+
+static bool ts6_sid_initted = false;
+static char ts6_new_sid[4];
+
+static void ts6_sid_increment(unsigned pos)
+{
+ /*
+ * An SID must be exactly 3 characters long, starts with a digit,
+ * and the other two characters are A-Z or digits
+ * The rules for generating an SID go like this...
+ * --> ABCDEFGHIJKLMNOPQRSTUVWXYZ --> 0123456789 --> WRAP
+ */
+ if (!pos)
+ {
+ /* At pos 0, if we hit '9', we've run out of available SIDs,
+ * reset the SID to the smallest possible value and try again. */
+ if (ts6_new_sid[pos] == '9')
+ {
+ ts6_new_sid[0] = '0';
+ ts6_new_sid[1] = 'A';
+ ts6_new_sid[2] = 'A';
+ }
+ else
+ // But if we haven't, just keep incrementing merrily.
+ ++ts6_new_sid[0];
+ }
+ else
+ {
+ if (ts6_new_sid[pos] == 'Z')
+ ts6_new_sid[pos] = '0';
+ else if (ts6_new_sid[pos] == '9')
+ {
+ ts6_new_sid[pos] = 'A';
+ ts6_sid_increment(pos - 1);
+ }
+ else
+ ++ts6_new_sid[pos];
+ }
+}
+
+/** Return the next SID in our list
+ * @return The SID
+ */
+const char *ts6_sid_retrieve()
+{
+ if (!ircd->ts6)
+ {
+ Alog(LOG_DEBUG) << "ts6_sid_retrieve(): TS6 not supported on this ircd";
+ return "";
+ }
+
+ if (!ts6_sid_initted)
+ {
+ // Initialize ts6_new_sid with the services server SID
+ snprintf(ts6_new_sid, 4, "%s", TS6SID);
+ ts6_sid_initted = true;
+ }
+
+ while (1)
+ {
+ // Check if the new SID is used by a known server
+ if (!Server::Find(ts6_new_sid))
+ // return the new SID
+ return ts6_new_sid;
+
+ // Add one to the last SID
+ ts6_sid_increment(2);
+ }
+ /* not reached */
+ return "";
+}
+
+/* EOF */
diff --git a/src/sessions.c b/src/sessions.cpp
index 0891bec93..e0c20e185 100644
--- a/src/sessions.c
+++ b/src/sessions.cpp
@@ -12,7 +12,8 @@
*/
#include "services.h"
-#include "pseudo.h"
+#include "modules.h"
+#include "language.h"
/*************************************************************************/
@@ -50,14 +51,7 @@
/*************************************************************************/
-/* I'm sure there is a better way to hash the list of hosts for which we are
- * storing session information. This should be sufficient for the mean time.
- * -TheShadow */
-
-#define HASH(host) (((host)[0]&31)<<5 | ((host)[1]&31))
-
-Session *sessionlist[1024];
-int32 nsessions = 0;
+session_map SessionList;
Exception *exceptions = NULL;
int16 nexceptions = 0;
@@ -68,19 +62,17 @@ int16 nexceptions = 0;
void get_session_stats(long *nrec, long *memuse)
{
- Session *session;
- long mem;
- int i;
+ long mem = sizeof(Session) * SessionList.size();
- mem = sizeof(Session) * nsessions;
- for (i = 0; i < 1024; i++) {
- for (session = sessionlist[i]; session; session = session->next) {
- mem += strlen(session->host) + 1;
- }
+ for (session_map::const_iterator it = SessionList.begin(); it != SessionList.end(); ++it)
+ {
+ Session *session = it->second;
+
+ mem += strlen(session->host) + 1;
}
- *nrec = nsessions;
*memuse = mem;
+ *nrec = SessionList.size();
}
void get_exception_stats(long *nrec, long *memuse)
@@ -101,23 +93,12 @@ void get_exception_stats(long *nrec, long *memuse)
/********************* Internal Session Functions ************************/
/*************************************************************************/
-Session *findsession(const char *host)
+Session *findsession(const std::string &host)
{
- Session *session;
- int i;
-
- if (!host) {
- return NULL;
- }
-
- for (i = 0; i < 1024; i++) {
- for (session = sessionlist[i]; session; session = session->next) {
- if (stricmp(host, session->host) == 0) {
- return session;
- }
- }
- }
+ session_map::const_iterator it = SessionList.find(host);
+ if (it != SessionList.end())
+ return it->second;
return NULL;
}
@@ -128,7 +109,7 @@ Session *findsession(const char *host)
int add_session(const char *nick, const char *host, char *hostip)
{
- Session *session, **list;
+ Session *session;
Exception *exception;
int sessionlimit = 0;
@@ -141,9 +122,9 @@ int add_session(const char *nick, const char *host, char *hostip)
if (sessionlimit != 0 && session->count >= sessionlimit) {
if (Config.SessionLimitExceeded)
- ircdproto->SendMessage(findbot(Config.s_OperServ), nick, Config.SessionLimitExceeded, host);
+ ircdproto->SendMessage(OperServ, nick, Config.SessionLimitExceeded, host);
if (Config.SessionLimitDetailsLoc)
- ircdproto->SendMessage(findbot(Config.s_OperServ), nick, "%s", Config.SessionLimitDetailsLoc);
+ ircdproto->SendMessage(OperServ, nick, "%s", Config.SessionLimitDetailsLoc);
/* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was
* decremented in do_quit, which caused problems and fixed here
@@ -159,10 +140,10 @@ int add_session(const char *nick, const char *host, char *hostip)
if (Config.MaxSessionKill && session->hits >= Config.MaxSessionKill) {
char akillmask[BUFSIZE];
snprintf(akillmask, sizeof(akillmask), "*@%s", host);
- add_akill(NULL, akillmask, Config.s_OperServ,
- time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded");
- ircdproto->SendGlobops(findbot(Config.s_OperServ),
- "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask);
+ XLine *x = new XLine(ci::string("*@") + host, Config.s_OperServ, time(NULL) + Config.SessionAutoKillExpiry, "Session limit exceeded");
+ if (x)
+ x->By = Config.s_OperServ;
+ ircdproto->SendGlobops(OperServ, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask);
}
return 0;
} else {
@@ -171,25 +152,18 @@ int add_session(const char *nick, const char *host, char *hostip)
}
}
- nsessions++;
session = new Session;
session->host = sstrdup(host);
- list = &sessionlist[HASH(session->host)];
- session->prev = NULL;
- session->next = *list;
- if (*list)
- (*list)->prev = session;
- *list = session;
session->count = 1;
session->hits = 0;
+ SessionList[session->host] = session;
+
return 1;
}
void del_session(const char *host)
{
- Session *session;
-
if (!Config.LimitSessions) {
Alog(LOG_DEBUG) << "del_session called when LimitSessions is disabled";
return;
@@ -202,12 +176,12 @@ void del_session(const char *host)
Alog(LOG_DEBUG_2) << "del_session() called";
- session = findsession(host);
+ Session *session = findsession(host);
if (!session) {
if (debug)
{
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "WARNING: Tried to delete non-existant session: \2%s", host);
+ ircdproto->SendGlobops(OperServ, "WARNING: Tried to delete non-existant session: \2%s", host);
Alog(LOG_DEBUG) << "session: Tried to delete non-existant session: " << host;
}
return;
@@ -218,20 +192,13 @@ void del_session(const char *host)
return;
}
- if (session->prev)
- session->prev->next = session->next;
- else
- sessionlist[HASH(session->host)] = session->next;
- if (session->next)
- session->next->prev = session->prev;
+ SessionList.erase(session->host);
Alog(LOG_DEBUG_2) << "del_session(): free session structure";
delete [] session->host;
delete session;
- nsessions--;
-
Alog(LOG_DEBUG_2) << "del_session() done";
}
@@ -249,7 +216,7 @@ void expire_exceptions()
if (exceptions[i].expires == 0 || exceptions[i].expires > now)
continue;
if (Config.WallExceptionExpire)
- ircdproto->SendGlobops(findbot(Config.s_OperServ),
+ ircdproto->SendGlobops(OperServ,
"Session limit exception for %s has expired.",
exceptions[i].mask);
delete [] exceptions[i].mask;
diff --git a/src/slist.c b/src/slist.c
deleted file mode 100644
index d01d58ecd..000000000
--- a/src/slist.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/* Services list handler implementation.
- *
- * (C) 2003-2010 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- *
- *
- */
-
-#include "services.h"
-#include "slist.h"
-
-static SListOpts slist_defopts = { 0, NULL, NULL, NULL };
-
-/*************************************************************************/
-
-/**
- * Adds a pointer to the list. Returns the index of the new item.
- * Returns -2 if there are too many items in the list, -3 if the
- * item already exists when the flags of the list contain SLISTF_NODUP.
- * @param slist Slist Struct
- * @param item Item being added
- * @return int
- */
-int slist_add(SList * slist, void *item)
-{
- if (slist->limit != 0 && slist->count >= slist->limit)
- return -2;
- if (slist->opts && (slist->opts->flags & SLISTF_NODUP)
- && slist_indexof(slist, item) != -1)
- return -3;
- if (slist->capacity == slist->count)
- slist_setcapacity(slist, slist->capacity + 1);
-
- if (slist->opts && (slist->opts->flags & SLISTF_SORT)
- && slist->opts->compareitem) {
- int i;
-
- for (i = 0; i < slist->count; i++) {
- if (slist->opts->compareitem(slist, item, slist->list[i]) <= 0) {
- memmove(&slist->list[i + 1], &slist->list[i],
- sizeof(void *) * (slist->count - i));
- slist->list[i] = item;
- break;
- }
- }
-
- if (i == slist->count)
- slist->list[slist->count] = item;
- } else {
- slist->list[slist->count] = item;
- }
-
- return slist->count++;
-}
-
-/*************************************************************************/
-
-/**
- * Clears the list. If free is 1, the freeitem function will be called
- * for each item before clearing.
- * @param slist Slist Struct
- * @param mustfree What is being freed
- * @return void
- */
-void slist_clear(SList * slist, int mustfree)
-{
- if (mustfree && slist->opts && slist->opts->freeitem && slist->count) {
- int i;
-
- for (i = 0; i < slist->count; i++)
- if (slist->list[i])
- slist->opts->freeitem(slist, slist->list[i]);
- }
-
- if (slist->list) {
- free(slist->list);
- slist->list = NULL;
- }
- slist->capacity = 0;
- slist->count = 0;
-}
-
-/*************************************************************************/
-
-/**
- * Deletes an item from the list, by index. Returns 1 if successful,
- * 0 otherwise.
- * @param slist Slist Struct
- * @param index beign deleted
- * @return int Returns 1 if successful, 0 otherwise.
- */
-int slist_delete(SList * slist, int index)
-{
- /* Range check */
- if (index >= slist->count)
- return 0;
-
- if (slist->list[index] && slist->opts && slist->opts->freeitem)
- slist->opts->freeitem(slist, slist->list[index]);
-
- slist->list[index] = NULL;
- slist->count--;
-
- if (index < slist->count)
- memmove(&slist->list[index], &slist->list[index + 1],
- sizeof(void *) * (slist->count - index));
-
- slist_setcapacity(slist, slist->capacity - 1);
-
- return 1;
-}
-
-/*************************************************************************/
-
-/**
- * Deletes a range of entries. Return -1 if the permission was denied,
- * 0 if no records were deleted, or the number of records deleted
- * @param slist Slist Struct
- * @param range Range to delete
- * @param cb Call back function
- * @param ... various args
- * @return int
- */
-int slist_delete_range(SList * slist, const char *crange, slist_delcheckcb_t cb, ...)
-{
- int count = 0, i, n1, n2;
- va_list args, preserve;
- char *range = const_cast<char *>(crange); // XXX: unsafe cast
-
- va_start(args, cb);
-
- for (;;) {
- n1 = n2 = strtol(range, &range, 10);
- range += strcspn(range, "0123456789,-");
-
- if (*range == '-') {
- range++;
- range += strcspn(range, "0123456789,");
- if (isdigit(*range)) {
- n2 = strtol(range, &range, 10);
- range += strcspn(range, "0123456789,-");
- }
- }
-
- for (i = n1; i <= n2 && i > 0 && i <= slist->count; i++) {
-
- if (!slist->list[i - 1])
- continue;
-
- /* copy this off the stack for safety's sake --nenolod */
- VA_COPY(preserve, args);
-
- if (cb && !cb(slist, slist->list[i - 1], preserve)) {
- va_end(preserve);
- return -1;
- }
-
- /* if it's to be freed, lets free it */
- if (slist->opts && slist->opts->freeitem)
- slist->opts->freeitem(slist, slist->list[i - 1]);
- slist->list[i - 1] = NULL;
-
- /* and release the copied list */
- va_end(preserve);
-
- count++;
- }
-
- range += strcspn(range, ",");
- if (*range)
- range++;
- else
- break;
- }
-
- /* We only really delete the items from the list after having processed
- * everything because it would change the position of the items in the
- * list otherwise.
- */
- slist_pack(slist);
-
- va_end(args);
- return count;
-}
-
-/*************************************************************************/
-
-/**
- * Enumerates all entries of the list. If range is not NULL, will only
- * enumerate entries that are in the range. Returns the total number
- * of entries enumerated.
- * @param slit Slist struct
- * @param range Range to enum
- * @param cb Call back function
- * @param ... various args
- * @return int
- */
-int slist_enum(SList * slist, const char *crange, slist_enumcb_t cb, ...)
-{
- int count = 0, i, res;
- va_list args, preserve;
- char *range = const_cast<char *>(crange); // XXX: unsafe cast
-
- va_start(args, cb);
-
- if (!range) {
- for (i = 0; i < slist->count; i++) {
- if (!slist->list[i]) {
- Alog() << "SList: warning: NULL pointer in the list (?)";
- continue;
- }
-
- /* copy off stack for safety */
- VA_COPY(preserve, args);
-
- res = cb(slist, i + 1, slist->list[i], preserve);
- if (res < 0) {
- va_end(preserve);
- break;
- }
-
- /* and release our copy */
- va_end(preserve);
-
- count += res;
- }
- } else {
- int n1, n2;
-
- for (;;) {
- res = 0;
- n1 = n2 = strtol(range, &range, 10);
- range += strcspn(range, "0123456789,-");
- if (*range == '-') {
- range++;
- range += strcspn(range, "0123456789,");
- if (isdigit(*range)) {
- n2 = strtol(range, &range, 10);
- range += strcspn(range, "0123456789,-");
- }
- }
- for (i = n1; i <= n2 && i > 0 && i <= slist->count; i++) {
- if (!slist->list[i - 1]) {
- Alog() << "SList: warning: NULL pointer in the list (?)";
- continue;
- }
-
- /* copy off stack for safety */
- VA_COPY(preserve, args);
-
- res = cb(slist, i, slist->list[i - 1], preserve);
- if (res < 0) {
- va_end(preserve);
- break;
- }
- count += res;
-
- /* and release our copy */
- va_end(preserve);
- }
- if (res < -1)
- break;
- range += strcspn(range, ",");
- if (*range)
- range++;
- else
- break;
- }
- }
-
- va_end(args);
-
- return count;
-}
-
-/*************************************************************************/
-
-/**
- * Determines whether the list is full.
- * @param slist Slist Struct
- * @return int
- */
-int slist_full(SList * slist)
-{
- if (slist->limit != 0 && slist->count >= slist->limit)
- return 1;
- else
- return 0;
-}
-
-/*************************************************************************/
-
-/**
- * Initialization of the list.
- * @param slist Slist Struct
- * @return int
- */
-void slist_init(SList * slist)
-{
- memset(slist, 0, sizeof(SList));
- slist->limit = SLIST_DEFAULT_LIMIT;
- slist->opts = &slist_defopts;
-}
-
-/*************************************************************************/
-
-/**
- * Returns the index of an item in the list, -1 if inexistant.
- * @param slist Slist Struct
- * @param item Item index
- * @return int
- */
-int slist_indexof(SList * slist, void *item)
-{
- int16 i;
- void *entry;
-
- if (slist->count == 0)
- return -1;
-
- for (i = 0, entry = slist->list[0]; i < slist->count;
- i++, entry = slist->list[i]) {
- if ((slist->opts
- && slist->opts->isequal) ? (slist->opts->isequal(slist, item,
- entry))
- : (item == entry))
- return i;
- }
-
- return -1;
-}
-
-/*************************************************************************/
-
-/**
- * Removes all NULL pointers from the list.
- * @param slist Slist Struct
- * @return void
- */
-void slist_pack(SList * slist)
-{
- int i;
-
- for (i = slist->count - 1; i >= 0; i--)
- if (!slist->list[i])
- slist_delete(slist, i);
-}
-
-/*************************************************************************/
-
-/**
- * Removes a specific item from the list. Returns the old index of the
- * deleted item, or -1 if the item was not found.
- * @param slist Slist Struct
- * @param item to remove
- * @return int
- */
-int slist_remove(SList * slist, void *item)
-{
- int index = slist_indexof(slist, item);
- if (index == -1)
- return -1;
- slist_delete(slist, index);
- return index;
-}
-
-/*************************************************************************/
-
-/**
- * Sets the maximum capacity of the list
- * @param slist Slist Struct
- * @param capacity How large the list can be
- * @return int
- */
-int slist_setcapacity(SList * slist, int16 capacity)
-{
- if (slist->capacity == capacity)
- return 1;
- slist->capacity = capacity;
- if (slist->capacity)
- slist->list =
- static_cast<void **>(srealloc(slist->list, sizeof(void *) * slist->capacity));
- else {
- free(slist->list);
- slist->list = NULL;
- }
- if (slist->capacity < slist->count)
- slist->count = slist->capacity;
- return 1;
-}
diff --git a/src/threadengine.cpp b/src/threadengine.cpp
new file mode 100644
index 000000000..ea652e1f2
--- /dev/null
+++ b/src/threadengine.cpp
@@ -0,0 +1,37 @@
+#include "services.h"
+
+ThreadEngine threadEngine;
+
+/** Threads constructor
+ */
+Thread::Thread() : Exit(false)
+{
+}
+
+/** Threads destructor
+ */
+Thread::~Thread()
+{
+}
+
+/** Sets the exit state as true informing the thread we want it to shut down
+ */
+void Thread::SetExitState()
+{
+ Exit = true;
+}
+
+/** Returns the exit state of the thread
+ * @return true if we want to exit
+ */
+bool Thread::GetExitState() const
+{
+ return Exit;
+}
+
+/** Called to run the thread, should be overloaded
+ */
+void Thread::Run()
+{
+}
+
diff --git a/src/threadengine_pthread.cpp b/src/threadengine_pthread.cpp
new file mode 100644
index 000000000..9d9bf160d
--- /dev/null
+++ b/src/threadengine_pthread.cpp
@@ -0,0 +1,113 @@
+#include "services.h"
+
+/* Threadengine attributes used by this thread engine */
+static pthread_attr_t threadengine_attr;
+
+/** Entry point used for the threads
+ * @param parameter A Thread* cast to a void*
+ */
+static void *entry_point(void *parameter)
+{
+ Thread *thread = static_cast<Thread *>(parameter);
+ thread->Run();
+ if (!thread->GetExitState())
+ {
+ thread->Join();
+ }
+ delete thread;
+ pthread_exit(0);
+}
+
+/** Threadengines constructor
+ */
+ThreadEngine::ThreadEngine()
+{
+ if (pthread_attr_init(&threadengine_attr))
+ {
+ throw CoreException("ThreadEngine: Error calling pthread_attr_init");
+ }
+}
+
+/** Threadengines destructor
+ */
+ThreadEngine::~ThreadEngine()
+{
+ pthread_attr_destroy(&threadengine_attr);
+}
+
+/** Join to the thread, sets the exit state to true
+ */
+void Thread::Join()
+{
+ SetExitState();
+ pthread_join(Handle, NULL);
+}
+
+/** Start a new thread
+ * @param thread A pointer to a newley allocated thread
+ */
+void ThreadEngine::Start(Thread *thread)
+{
+ if (pthread_create(&thread->Handle, &threadengine_attr, entry_point, thread))
+ {
+ delete thread;
+ throw CoreException("Unable to create thread: " + std::string(strerror(errno)));
+ }
+}
+
+/** Constructor
+ */
+Mutex::Mutex()
+{
+ pthread_mutex_init(&mutex, NULL);
+}
+
+/** Destructor
+ */
+Mutex::~Mutex()
+{
+ pthread_mutex_destroy(&mutex);
+}
+
+/** Attempt to lock the mutex, will hang until a lock can be achieved
+ */
+void Mutex::Lock()
+{
+ pthread_mutex_lock(&mutex);
+}
+
+/** Unlock the mutex, it must be locked first
+ */
+void Mutex::Unlock()
+{
+ pthread_mutex_unlock(&mutex);
+}
+
+/** Constructor
+ */
+Condition::Condition() : Mutex()
+{
+ pthread_cond_init(&cond, NULL);
+}
+
+/** Destructor
+ */
+Condition::~Condition()
+{
+ pthread_cond_destroy(&cond);
+}
+
+/** Called to wakeup the waiter
+ */
+void Condition::Wakeup()
+{
+ pthread_cond_signal(&cond);
+}
+
+/** Called to wait for a Wakeup() call
+ */
+void Condition::Wait()
+{
+ pthread_cond_wait(&cond, &mutex);
+}
+
diff --git a/src/threadengine_win32.cpp b/src/threadengine_win32.cpp
new file mode 100644
index 000000000..5ee2f4596
--- /dev/null
+++ b/src/threadengine_win32.cpp
@@ -0,0 +1,109 @@
+#include "services.h"
+
+/** Entry point for the thread
+ * @param paramter A Thread* cast to a void*
+ */
+static DWORD WINAPI entry_point(void *parameter)
+{
+ Thread *thread = static_cast<Thread *>(parameter);
+ thread->Run();
+ if (!thread->GetExitState())
+ {
+ thread->Join();
+ }
+ delete thread;
+ return 0;
+}
+
+/** Threadengines constructor
+ */
+ThreadEngine::ThreadEngine()
+{
+}
+
+/** Threadengines destructor
+ */
+ThreadEngine::~ThreadEngine()
+{
+}
+
+/** Join to the thread, sets the exit state to true
+ */
+void Thread::Join()
+{
+ SetExitState();
+ WaitForSingleObject(Handle, INFINITE);
+}
+
+/** Start a new thread
+ * @param thread A pointer to a newley allocated thread
+ */
+void ThreadEngine::Start(Thread *thread)
+{
+ thread->Handle = CreateThread(NULL, 0, entry_point, thread, 0, NULL);
+
+ if (!thread->Handle)
+ {
+ delete thread;
+ throw CoreException("Unable to create thread: " + std::string(dlerror()));
+ }
+}
+
+/** Constructor
+ */
+Mutex::Mutex()
+{
+ InitializeCriticalSection(&mutex);
+}
+
+/** Destructor
+ */
+Mutex::~Mutex()
+{
+ DeleteCriticalSection(&mutex);
+}
+
+/** Attempt to lock the mutex, will hang until a lock can be achieved
+ */
+void Mutex::Lock()
+{
+ EnterCriticalSection(&mutex);
+}
+
+/** Unlock the mutex, it must be locked first
+ */
+void Mutex::Unlock()
+{
+ LeaveCriticalSection(&mutex);
+}
+
+/** Constructor
+ */
+Condition::Condition() : Mutex()
+{
+ cond = CreateEvent(NULL, false, false, NULL);
+}
+
+/** Destructor
+ */
+Condition::~Condition()
+{
+ CloseHandle(cond);
+}
+
+/** Called to wakeup the waiter
+ */
+void Condition::Wakeup()
+{
+ PulseEvent(cond);
+}
+
+/** Called to wait for a Wakeup() call
+ */
+void Condition::Wait()
+{
+ LeaveCriticalSection(&mutex);
+ WaitForSingleObject(cond, INFINITE);
+ EnterCriticalSection(&mutex);
+}
+
diff --git a/src/tools/db-convert.c b/src/tools/db-convert.c
index 0f8a35ebc..4e3d01034 100644
--- a/src/tools/db-convert.c
+++ b/src/tools/db-convert.c
@@ -969,7 +969,7 @@ int main(int argc, char *argv[])
fs << "OS AKILL " << user << " " << host << " " << by << " " << seton << " " << expires << " :" << reason << std::endl;
free(user); free(host); free(by); free(reason);
}
- /* SGLINES */
+ /* SNLINES */
read_int16(&capacity, f);
for (i = 0; i < capacity; i++)
{
@@ -978,7 +978,7 @@ int main(int argc, char *argv[])
SAFE(read_string(&reason, f));
SAFE(read_int32(&seton, f));
SAFE(read_int32(&expires, f));
- fs << "OS SGLINE " << mask << " " << by << " " << seton << " " << expires << " :" << reason << std::endl;
+ fs << "OS SNLINE " << mask << " " << by << " " << seton << " " << expires << " :" << reason << std::endl;
free(mask); free(by); free(reason);
}
/* SQLINES */
diff --git a/src/users.c b/src/users.cpp
index e32363259..a1890f6c5 100644
--- a/src/users.c
+++ b/src/users.cpp
@@ -15,10 +15,11 @@
#include "modules.h"
#include "language.h"
-#define HASH(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31))
-User *userlist[1024];
-
-#define HASH2(nick) (((nick)[0]&31)<<5 | ((nick)[1]&31))
+/* Hash maps used for users. Note UserListByUID will not be used on non-TS6 IRCds, and should never
+ * be assumed to have users
+ */
+user_map UserListByNick;
+user_uid_map UserListByUID;
int32 opcnt = 0;
uint32 usercnt = 0, maxusercnt = 0;
@@ -29,16 +30,12 @@ time_t maxusertime;
User::User(const std::string &snick, const std::string &suid)
{
- User **list;
-
if (snick.empty())
throw "what the craq, empty nick passed to constructor";
// XXX: we should also duplicate-check here.
/* we used to do this by calloc, no more. */
- this->next = NULL;
- this->prev = NULL;
host = hostip = vhost = realname = NULL;
server = NULL;
nc = NULL;
@@ -47,13 +44,10 @@ User::User(const std::string &snick, const std::string &suid)
this->nick = snick;
this->uid = suid;
- list = &userlist[HASH(this->nick)];
- this->next = *list;
- if (*list)
- (*list)->prev = this;
-
- *list = this;
+ UserListByNick[snick.c_str()] = this;
+ if (!suid.empty())
+ UserListByUID[suid] = this;
this->nc = NULL;
@@ -72,8 +66,6 @@ User::User(const std::string &snick, const std::string &suid)
void User::SetNewNick(const std::string &newnick)
{
- User **list;
-
/* Sanity check to make sure we don't segfault */
if (newnick.empty())
{
@@ -82,22 +74,11 @@ void User::SetNewNick(const std::string &newnick)
Alog(LOG_DEBUG) << this->nick << " changed nick to " << newnick;
- if (this->prev)
- this->prev->next = this->next;
- else
- userlist[HASH(this->nick)] = this->next;
-
- if (this->next)
- this->next->prev = this->prev;
+ UserListByNick.erase(this->nick.c_str());
this->nick = newnick;
- list = &userlist[HASH(this->nick)];
- this->next = *list;
- this->prev = NULL;
- if (*list)
- (*list)->prev = this;
- *list = this;
+ UserListByNick[this->nick.c_str()] = this;
OnAccess = false;
NickAlias *na = findnick(this->nick);
@@ -211,7 +192,7 @@ void User::SetRealname(const std::string &srealname)
this->realname = sstrdup(srealname.c_str());
NickAlias *na = findnick(this->nick);
- if (na && (this->IsIdentified(true) || (!na->nc->HasFlag(NI_SECURE) && this->IsRecognized())))
+ if (na && (this->IsIdentified(true) || this->IsRecognized(true)))
{
if (na->last_realname)
delete [] na->last_realname;
@@ -231,7 +212,7 @@ User::~User()
Alog() << "LOGUSERS: " << this->GetMask() << (ircd->vhost ? " => " : " ")
<< (ircd->vhost ? this->GetDisplayedHost() : "")
- << " (" << srealname << ") left the network (" << this->server->name << ").";
+ << " (" << srealname << ") left the network (" << this->server->GetName() << ").";
delete [] srealname;
}
@@ -247,13 +228,10 @@ User::~User()
{
this->chans.front()->chan->DeleteUser(this);
}
-
- if (this->prev)
- this->prev->next = this->next;
- else
- userlist[HASH(this->nick)] = this->next;
- if (this->next)
- this->next->prev = this->prev;
+
+ UserListByNick.erase(this->nick.c_str());
+ if (!this->uid.empty())
+ UserListByUID.erase(this->uid);
NickAlias *na = findnick(this->nick);
if (na)
@@ -380,7 +358,7 @@ void User::Collide(NickAlias *na)
snprintf(randbuf, sizeof(randbuf), "%d", getrandom16());
guestnick = std::string(Config.NSGuestNickPrefix) + std::string(randbuf);
}
- while (finduser(guestnick.c_str()));
+ while (finduser(guestnick));
notice_lang(Config.s_NickServ, this, FORCENICKCHANGE_CHANGING, guestnick.c_str());
ircdproto->SendForceNickChange(this, guestnick.c_str(), time(NULL));
@@ -434,7 +412,7 @@ void User::AutoID(const std::string &account)
delete [] na->last_realname;
na->last_realname = sstrdup(this->realname);
na->last_seen = time(NULL);
- this->SetMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ this->SetMode(NickServ, UMODE_REGISTERED);
this->UpdateHost();
check_memos(this);
@@ -499,10 +477,21 @@ const bool User::IsIdentified(bool CheckNick) const
}
/** Check if the user is recognized for their nick (on the nicks access list)
+ * @param CheckSecure Only returns true if the user has secure off
* @return true or false
*/
-const bool User::IsRecognized() const
+const bool User::IsRecognized(bool CheckSecure) const
{
+ if (CheckSecure && OnAccess)
+ {
+ NickAlias *na = findnick(this->nick);
+
+ if (!na || !na->nc->HasFlag(NI_SECURE))
+ {
+ return false;
+ }
+ }
+
return OnAccess;
}
@@ -514,12 +503,11 @@ void User::UpdateHost()
return;
NickAlias *na = findnick(this->nick);
-
OnAccess = false;
if (na)
OnAccess = is_on_access(this, na->nc);
- if (na && (this->IsIdentified(true) || (!na->nc->HasFlag(NI_SECURE) && this->IsRecognized())))
+ if (na && (this->IsIdentified(true) || this->IsRecognized(true)))
{
if (na->last_usermask)
delete [] na->last_usermask;
@@ -529,66 +517,13 @@ void User::UpdateHost()
}
}
-/*************************************************************************/
-
-/* Return statistics. Pointers are assumed to be valid. */
-
-void get_user_stats(long *nusers, long *memuse)
-{
- long count = 0, mem = 0;
- int i;
- User *user;
-
- for (i = 0; i < 1024; i++) {
- for (user = userlist[i]; user; user = user->next) {
- count++;
- mem += sizeof(*user);
- if (user->host)
- mem += strlen(user->host) + 1;
- if (ircd->vhost) {
- if (user->vhost)
- mem += strlen(user->vhost) + 1;
- }
- if (user->realname)
- mem += strlen(user->realname) + 1;
- if (user->server->name)
- mem += strlen(user->server->name) + 1;
- mem += (sizeof(ChannelContainer) * user->chans.size());
- }
- }
- *nusers = count;
- *memuse = mem;
-}
-
-/*************************************************************************/
-
-/* Find a user by nick. Return NULL if user could not be found. */
-
-User *finduser(const std::string &nick)
-{
- User *user;
-
- Alog(LOG_DEBUG_3) << "finduser("<< nick << ")";
-
- if (isdigit(nick[0]) && ircd->ts6)
- return find_byuid(nick);
-
- ci::string ci_nick(nick.c_str());
-
- user = userlist[HASH(nick)];
- while (user && ci_nick != user->nick)
- user = user->next;
- Alog(LOG_DEBUG_3) << "finduser(" << nick << ") -> " << static_cast<void *>(user);
- return user;
-}
-
/** Check if the user has a mode
* @param Name Mode name
* @return true or false
*/
const bool User::HasMode(UserModeName Name) const
{
- return modes[Name];
+ return modes.HasFlag(Name);
}
/** Set a mode internally on the user, the IRCd is not informed
@@ -600,7 +535,7 @@ void User::SetModeInternal(UserMode *um, const std::string &Param)
if (!um)
return;
- modes[um->Name] = true;
+ modes.SetFlag(um->Name);
if (!Param.empty())
{
Params.insert(std::make_pair(um->Name, Param));
@@ -617,7 +552,7 @@ void User::RemoveModeInternal(UserMode *um)
if (!um)
return;
- modes[um->Name] = false;
+ modes.UnsetFlag(um->Name);
std::map<UserModeName, std::string>::iterator it = Params.find(um->Name);
if (it != Params.end())
{
@@ -694,16 +629,16 @@ void User::RemoveMode(BotInfo *bi, char ModeChar)
/** Set a string of modes on a user
* @param bi The client setting the mode
- * @param modes The modes
+ * @param umodes The modes
*/
-void User::SetModes(BotInfo *bi, const char *modes, ...)
+void User::SetModes(BotInfo *bi, const char *umodes, ...)
{
char buf[BUFSIZE] = "";
va_list args;
std::string modebuf, sbuf;
int add = -1;
- va_start(args, modes);
- vsnprintf(buf, BUFSIZE - 1, modes, args);
+ va_start(args, umodes);
+ vsnprintf(buf, BUFSIZE - 1, umodes, args);
va_end(args);
spacesepstream sep(buf);
@@ -756,82 +691,74 @@ ChannelContainer *User::FindChannel(Channel *c)
return NULL;
}
-/*************************************************************************/
-
-/* Iterate over all users in the user list. Return NULL at end of list. */
-
-static User *current;
-static int next_index;
-
-User *firstuser()
+/** Check if the user is protected from kicks and negative mode changes
+ * @return true or false
+ */
+bool User::IsProtected() const
{
- next_index = 0;
- current = NULL;
- while (next_index < 1024 && current == NULL)
- current = userlist[next_index++];
- Alog(LOG_DEBUG) << "firstuser() returning " << (current ? current->nick : "NULL (end of list)");
- return current;
-}
+ if (this->HasMode(UMODE_PROTECTED) || this->HasMode(UMODE_GOD))
+ return true;
-User *nextuser()
-{
- if (current)
- current = current->next;
- if (!current && next_index < 1024) {
- while (next_index < 1024 && current == NULL)
- current = userlist[next_index++];
- }
- Alog(LOG_DEBUG) << "nextuser() returning " << (current ? current->nick : "NULL (end of list)");
- return current;
+ return false;
}
-User *find_byuid(const std::string &uid)
+/*************************************************************************/
+
+void get_user_stats(long *nusers, long *memuse)
{
- User *u, *next;
+ long count = 0, mem = 0;
+
+ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *user = it->second;
- u = first_uid();
- while (u) {
- next = next_uid();
- if (u->GetUID() == uid) {
- return u;
+ count++;
+ mem += sizeof(*user);
+ if (user->host)
+ mem += strlen(user->host) + 1;
+ if (ircd->vhost)
+ {
+ if (user->vhost)
+ mem += strlen(user->vhost) + 1;
}
- u = next;
+ if (user->realname)
+ mem += strlen(user->realname) + 1;
+ mem += user->server->GetName().length() + 1;
+ mem += (sizeof(ChannelContainer) * user->chans.size());
}
- return NULL;
+ *nusers = count;
+ *memuse = mem;
}
-static User *current_uid;
-static int next_index_uid;
+User *finduser(const char *nick)
+{
+ return finduser(ci::string(nick));
+}
-User *first_uid()
+User *finduser(const std::string &nick)
{
- next_index_uid = 0;
- current_uid = NULL;
- while (next_index_uid < 1024 && current_uid == NULL) {
- current_uid = userlist[next_index_uid++];
- }
- Alog(LOG_DEBUG_2) << "first_uid() returning "
- << (current_uid ? current_uid->nick : "NULL (end of list)") << " "
- << (current_uid ? current_uid->GetUID() : "");
- return current_uid;
+ return finduser(ci::string(nick.c_str()));
}
-User *next_uid()
+User *finduser(const ci::string &nick)
{
- if (current_uid)
- current_uid = current_uid->next;
- if (!current_uid && next_index_uid < 1024) {
- while (next_index_uid < 1024 && current_uid == NULL)
- current_uid = userlist[next_index_uid++];
+ if (isdigit(nick[0]) && ircd->ts6)
+ {
+ user_uid_map::const_iterator it = UserListByUID.find(nick.c_str());
+
+ if (it != UserListByUID.end())
+ return it->second;
+ return NULL;
}
- Alog(LOG_DEBUG_2) << "next_uid() returning "
- << (current_uid ? current_uid->nick : "NULL (end of list)") << " "
- << (current_uid ? current_uid->GetUID() : "");
- return current_uid;
+
+ user_map::const_iterator it = UserListByNick.find(nick);
+
+ if (it != UserListByNick.end())
+ return it->second;
+ return NULL;
}
/*************************************************************************/
-/*************************************************************************/
/* Handle a server NICK command. */
@@ -862,6 +789,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const
ntoa(addr, ipbuf, sizeof(ipbuf));
}
+ Server *serv = Server::Find(server);
if (Config.LogUsers)
{
@@ -886,7 +814,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const
<< (ircd->nickvhost && vhost ? " => " : "")
<< (ircd->nickvhost && vhost ? vhost : "") << ") (" << logrealname << ") "
<< (ircd->nickip ? "[" : "") << (ircd->nickip ? ipbuf : "") << (ircd->nickip ? "]" : "")
- << " connected to the network (" << server << ").";
+ << " connected to the network (" << serv->GetName() << ").";
delete [] logrealname;
}
@@ -894,7 +822,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const
user = new User(nick, uid ? uid : "");
user->SetIdent(username);
user->host = sstrdup(host);
- user->server = findserver(servlist, server);
+ user->server = serv;
user->realname = sstrdup(realname);
user->timestamp = ts;
user->my_signon = time(NULL);
@@ -914,20 +842,11 @@ User *do_nick(const char *source, const char *nick, const char *username, const
if (MOD_RESULT == EVENT_STOP)
return finduser(nick);
- check_akill(nick, username, host, vhost, ipbuf);
-
- if (ircd->sgline)
- check_sgline(nick, realname);
-
- if (ircd->sqline)
- check_sqline(nick, 0);
-
- if (ircd->szline && ircd->nickip)
- check_szline(nick, ipbuf);
-
- if (Config.LimitSessions && !is_ulined(server))
+ if (Config.LimitSessions && !serv->IsULined())
add_session(nick, host, ipbuf);
+ XLineManager::CheckAll(user);
+
/* User is no longer connected, return */
if (!finduser(nick))
return NULL;
@@ -937,11 +856,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const
else
{
/* An old user changing nicks. */
- if (ircd->ts6)
- user = find_byuid(source);
-
- if (!user)
- user = finduser(source);
+ user = finduser(source);
if (!user) {
Alog() << "user: NICK from nonexistent nick " << source;
@@ -954,8 +869,8 @@ User *do_nick(const char *source, const char *nick, const char *username, const
{
const char *logrealname = normalizeBuffer(user->realname);
Alog() << "LOGUSERS: " << user->nick << " (" << user->GetIdent() << "@" << user->host
- << (ircd->vhost ? " => " : "") << (ircd->vhost ? user->GetDisplayedHost() : "") << ") ("
- << logrealname << ") " << "changed nick to " << nick << " (" << user->server->name << ").";
+ << (ircd->vhost ? " => " : "") << (ircd->vhost ? user->GetDisplayedHost() : "") << ") ("
+ << logrealname << ") " << "changed nick to " << nick << " (" << user->server->GetName() << ").";
if (logrealname)
delete [] logrealname;
}
@@ -1002,7 +917,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const
if (ircd->sqline)
{
- if (!is_oper(user) && check_sqline(user->nick.c_str(), 1))
+ if (!is_oper(user) && SQLine->Check(user))
return NULL;
}
}
@@ -1055,9 +970,8 @@ void do_quit(const char *source, int ac, const char **av)
delete [] na->last_quit;
na->last_quit = *av[0] ? sstrdup(av[0]) : NULL;
}
- if (Config.LimitSessions && !is_ulined(user->server->name)) {
+ if (Config.LimitSessions && !user->server->IsULined())
del_session(user->host);
- }
FOREACH_MOD(I_OnUserQuit, OnUserQuit(user, *av[0] ? av[0] : ""));
delete user;
}
@@ -1088,7 +1002,7 @@ void do_kill(const std::string &nick, const std::string &msg)
delete [] na->last_quit;
na->last_quit = !msg.empty() ? sstrdup(msg.c_str()) : NULL;
}
- if (Config.LimitSessions && !is_ulined(user->server->name)) {
+ if (Config.LimitSessions && !user->server->IsULined()) {
del_session(user->host);
}
delete user;
@@ -1097,18 +1011,6 @@ void do_kill(const std::string &nick, const std::string &msg)
/*************************************************************************/
/*************************************************************************/
-/* Is the given user protected from kicks and negative mode changes? */
-
-int is_protected(User * user)
-{
- if (user && user->HasMode(UMODE_PROTECTED))
- return 1;
-
- return 0;
-}
-
-/*************************************************************************/
-
/* Is the given nick an oper? */
int is_oper(User * user)
@@ -1308,14 +1210,14 @@ void UserSetInternalModes(User *user, int ac, const char **av)
{
++opcnt;
if (Config.WallOper)
- ircdproto->SendGlobops(findbot(Config.s_OperServ), "\2%s\2 is now an IRC operator.", user->nick.c_str());
+ ircdproto->SendGlobops(OperServ, "\2%s\2 is now an IRC operator.", user->nick.c_str());
}
else
--opcnt;
break;
case UMODE_REGISTERED:
if (add && !user->IsIdentified())
- user->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED);
+ user->RemoveMode(NickServ, UMODE_REGISTERED);
break;
case UMODE_CLOAK:
case UMODE_VHOST: