summaryrefslogtreecommitdiff
path: root/chanserv.c
diff options
context:
space:
mode:
authorsvn svn@31f1291d-b8d6-0310-a050-a5561fc1590b <svn svn@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864>2004-03-28 21:59:56 +0000
committersvn svn@31f1291d-b8d6-0310-a050-a5561fc1590b <svn svn@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864>2004-03-28 21:59:56 +0000
commit55bf4dbcabf378e9472b7d31d6edf87f6ac853e9 (patch)
tree7a9454ea6b8750256e242cf6d5fba3ca7a4b5044 /chanserv.c
Initial Anope Import
git-svn-id: svn://svn.anope.org/anope/trunk@1 31f1291d-b8d6-0310-a050-a5561fc1590b git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@1 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'chanserv.c')
-rw-r--r--chanserv.c6187
1 files changed, 6187 insertions, 0 deletions
diff --git a/chanserv.c b/chanserv.c
new file mode 100644
index 000000000..796a7817a
--- /dev/null
+++ b/chanserv.c
@@ -0,0 +1,6187 @@
+/* ChanServ functions.
+ *
+ * (C) 2003 Anope Team
+ * Contact us at info@anope.org
+ *
+ * Please read COPYING and README for furhter details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id: chanserv.c,v 1.55 2004/03/17 20:08:49 ribosome Exp $
+ *
+ */
+
+/*************************************************************************/
+
+#include "services.h"
+#include "pseudo.h"
+
+/*************************************************************************/
+/* *INDENT-OFF* */
+
+ChannelInfo *chanlists[256];
+
+static int def_levels[][2] = {
+ { CA_AUTOOP, 5 },
+ { CA_AUTOVOICE, 3 },
+ { CA_AUTODEOP, -1 },
+ { CA_NOJOIN, -2 },
+ { CA_INVITE, 5 },
+ { CA_AKICK, 10 },
+ { CA_SET, ACCESS_INVALID },
+ { CA_CLEAR, ACCESS_INVALID },
+ { CA_UNBAN, 5 },
+ { CA_OPDEOP, 5 },
+ { CA_ACCESS_LIST, 1 },
+ { CA_ACCESS_CHANGE, 10 },
+ { CA_MEMO, 10 },
+ { CA_ASSIGN, ACCESS_INVALID },
+ { CA_BADWORDS, 10 },
+ { CA_NOKICK, 1 },
+ { CA_FANTASIA, 3 },
+ { CA_SAY, 5 },
+ { CA_GREET, 5 },
+ { CA_VOICEME, 3 },
+ { CA_VOICE, 5 },
+ { CA_GETKEY, 5 },
+ { CA_AUTOHALFOP, 4 },
+ { CA_AUTOPROTECT, 10 },
+ { CA_OPDEOPME, 5 },
+ { CA_HALFOPME, 4 },
+ { CA_HALFOP, 5 },
+ { CA_PROTECTME, 10 },
+ { CA_PROTECT, ACCESS_INVALID },
+ { CA_KICKME, 5 },
+ { CA_KICK, 5 },
+ { CA_SIGNKICK, ACCESS_INVALID },
+ { CA_BANME, 5 },
+ { CA_BAN, 5 },
+ { CA_TOPIC, ACCESS_INVALID },
+ { CA_INFO, ACCESS_INVALID },
+ { -1 }
+};
+
+typedef struct {
+ int what;
+ char *name;
+ int desc;
+} LevelInfo;
+static LevelInfo levelinfo[] = {
+ { CA_AUTODEOP, "AUTODEOP", CHAN_LEVEL_AUTODEOP },
+#ifdef HAS_HALFOP
+ { CA_AUTOHALFOP, "AUTOHALFOP", CHAN_LEVEL_AUTOHALFOP },
+#endif
+ { CA_AUTOOP, "AUTOOP", CHAN_LEVEL_AUTOOP },
+#ifdef IRC_UNREAL
+ { CA_AUTOPROTECT, "AUTOPROTECT", CHAN_LEVEL_AUTOPROTECT },
+#endif
+#ifdef IRC_VIAGRA
+ { CA_AUTOPROTECT, "AUTOPROTECT", CHAN_LEVEL_AUTOPROTECT },
+#endif
+#ifdef IRC_ULTIMATE3
+ { CA_AUTOPROTECT, "AUTOADMIN", CHAN_LEVEL_AUTOPROTECT },
+#endif
+ { CA_AUTOVOICE, "AUTOVOICE", CHAN_LEVEL_AUTOVOICE },
+ { CA_NOJOIN, "NOJOIN", CHAN_LEVEL_NOJOIN },
+ { CA_SIGNKICK, "SIGNKICK", CHAN_LEVEL_SIGNKICK },
+
+ { CA_ACCESS_LIST, "ACC-LIST", CHAN_LEVEL_ACCESS_LIST },
+ { CA_ACCESS_CHANGE, "ACC-CHANGE", CHAN_LEVEL_ACCESS_CHANGE },
+ { CA_AKICK, "AKICK", CHAN_LEVEL_AKICK },
+ { CA_SET, "SET", CHAN_LEVEL_SET },
+
+ { CA_BAN, "BAN", CHAN_LEVEL_BAN },
+ { CA_BANME, "BANME", CHAN_LEVEL_BANME },
+ { CA_CLEAR, "CLEAR", CHAN_LEVEL_CLEAR },
+ { CA_GETKEY, "GETKEY", CHAN_LEVEL_GETKEY },
+#ifdef HAS_HALFOP
+ { CA_HALFOP, "HALFOP", CHAN_LEVEL_HALFOP },
+ { CA_HALFOPME, "HALFOPME", CHAN_LEVEL_HALFOPME },
+#endif
+ { CA_INFO, "INFO", CHAN_LEVEL_INFO },
+ { CA_KICK, "KICK", CHAN_LEVEL_KICK },
+ { CA_KICKME, "KICKME", CHAN_LEVEL_KICKME },
+ { CA_INVITE, "INVITE", CHAN_LEVEL_INVITE },
+ { CA_OPDEOP, "OPDEOP", CHAN_LEVEL_OPDEOP },
+ { CA_OPDEOPME, "OPDEOPME", CHAN_LEVEL_OPDEOPME },
+#ifdef IRC_UNREAL
+ { CA_PROTECT, "PROTECT", CHAN_LEVEL_PROTECT },
+ { CA_PROTECTME, "PROTECTME", CHAN_LEVEL_PROTECTME },
+#endif
+#ifdef IRC_VIAGRA
+ { CA_PROTECT, "PROTECT", CHAN_LEVEL_PROTECT },
+ { CA_PROTECTME, "PROTECTME", CHAN_LEVEL_PROTECTME },
+#endif
+#ifdef IRC_ULTIMATE3
+ { CA_PROTECT, "ADMIN", CHAN_LEVEL_PROTECT },
+ { CA_PROTECTME, "ADMINME", CHAN_LEVEL_PROTECTME },
+#endif
+ { CA_TOPIC, "TOPIC", CHAN_LEVEL_TOPIC },
+ { CA_UNBAN, "UNBAN", CHAN_LEVEL_UNBAN },
+ { CA_VOICE, "VOICE", CHAN_LEVEL_VOICE },
+ { CA_VOICEME, "VOICEME", CHAN_LEVEL_VOICEME },
+
+ { CA_MEMO, "MEMO", CHAN_LEVEL_MEMO },
+
+ { CA_ASSIGN, "ASSIGN", CHAN_LEVEL_ASSIGN },
+ { CA_BADWORDS, "BADWORDS", CHAN_LEVEL_BADWORDS },
+ { CA_FANTASIA, "FANTASIA", CHAN_LEVEL_FANTASIA },
+ { CA_GREET, "GREET", CHAN_LEVEL_GREET },
+ { CA_NOKICK, "NOKICK", CHAN_LEVEL_NOKICK },
+ { CA_SAY, "SAY", CHAN_LEVEL_SAY },
+
+ { -1 }
+};
+static int levelinfo_maxwidth = 0;
+
+CSModeUtil csmodeutils[] = {
+ { "DEOP", "!deop", "-o", CI_OPNOTICE, CA_OPDEOP, CA_OPDEOPME },
+ { "OP", "!op", "+o", CI_OPNOTICE, CA_OPDEOP, CA_OPDEOPME },
+ { "DEVOICE", "!devoice", "-v", 0 , CA_VOICE, CA_VOICEME },
+ { "VOICE", "!voice", "+v", 0 , CA_VOICE, CA_VOICEME },
+#ifdef HAS_HALFOP
+ { "DEHALFOP", "!dehalfop", "-h", 0 , CA_HALFOP, CA_HALFOPME },
+ { "HALFOP", "!halfop", "+h", 0 , CA_HALFOP, CA_HALFOPME },
+#endif
+#ifdef IRC_UNREAL
+ { "DEPROTECT", "!deprotect", "-a", 0 , CA_PROTECT, CA_PROTECTME },
+ { "PROTECT", "!protect", "+a", 0 , CA_PROTECT, CA_PROTECTME },
+#endif
+#ifdef IRC_VIAGRA
+ { "DEPROTECT", "!deprotect", "-a", 0 , CA_PROTECT, CA_PROTECTME },
+ { "PROTECT", "!protect", "+a", 0 , CA_PROTECT, CA_PROTECTME },
+#endif
+#ifdef IRC_ULTIMATE3
+ { "DEPROTECT", "!deadmin", "-a", 0 , CA_PROTECT, CA_PROTECTME },
+ { "PROTECT", "!admin", "+a", 0 , CA_PROTECT, CA_PROTECTME },
+#endif
+
+ { NULL }
+};
+
+int xop_msgs[4][14] = {
+ { CHAN_AOP_SYNTAX,
+ CHAN_AOP_DISABLED,
+ CHAN_AOP_NICKS_ONLY,
+ CHAN_AOP_ADDED,
+ CHAN_AOP_MOVED,
+ CHAN_AOP_NO_SUCH_ENTRY,
+ CHAN_AOP_NOT_FOUND,
+ CHAN_AOP_NO_MATCH,
+ CHAN_AOP_DELETED,
+ CHAN_AOP_DELETED_ONE,
+ CHAN_AOP_DELETED_SEVERAL,
+ CHAN_AOP_LIST_EMPTY,
+ CHAN_AOP_LIST_HEADER,
+ CHAN_AOP_CLEAR
+ },
+ { CHAN_SOP_SYNTAX,
+ CHAN_SOP_DISABLED,
+ CHAN_SOP_NICKS_ONLY,
+ CHAN_SOP_ADDED,
+ CHAN_SOP_MOVED,
+ CHAN_SOP_NO_SUCH_ENTRY,
+ CHAN_SOP_NOT_FOUND,
+ CHAN_SOP_NO_MATCH,
+ CHAN_SOP_DELETED,
+ CHAN_SOP_DELETED_ONE,
+ CHAN_SOP_DELETED_SEVERAL,
+ CHAN_SOP_LIST_EMPTY,
+ CHAN_SOP_LIST_HEADER,
+ CHAN_SOP_CLEAR
+ },
+ { CHAN_VOP_SYNTAX,
+ CHAN_VOP_DISABLED,
+ CHAN_VOP_NICKS_ONLY,
+ CHAN_VOP_ADDED,
+ CHAN_VOP_MOVED,
+ CHAN_VOP_NO_SUCH_ENTRY,
+ CHAN_VOP_NOT_FOUND,
+ CHAN_VOP_NO_MATCH,
+ CHAN_VOP_DELETED,
+ CHAN_VOP_DELETED_ONE,
+ CHAN_VOP_DELETED_SEVERAL,
+ CHAN_VOP_LIST_EMPTY,
+ CHAN_VOP_LIST_HEADER,
+ CHAN_VOP_CLEAR
+ },
+ { CHAN_HOP_SYNTAX,
+ CHAN_HOP_DISABLED,
+ CHAN_HOP_NICKS_ONLY,
+ CHAN_HOP_ADDED,
+ CHAN_HOP_MOVED,
+ CHAN_HOP_NO_SUCH_ENTRY,
+ CHAN_HOP_NOT_FOUND,
+ CHAN_HOP_NO_MATCH,
+ CHAN_HOP_DELETED,
+ CHAN_HOP_DELETED_ONE,
+ CHAN_HOP_DELETED_SEVERAL,
+ CHAN_HOP_LIST_EMPTY,
+ CHAN_HOP_LIST_HEADER,
+ CHAN_HOP_CLEAR
+ }
+};
+
+/* *INDENT-ON* */
+/*************************************************************************/
+
+static void alpha_insert_chan(ChannelInfo * ci);
+static ChannelInfo *makechan(const char *chan);
+static int delchan(ChannelInfo * ci);
+static void reset_levels(ChannelInfo * ci);
+static int is_real_founder(User * user, ChannelInfo * ci);
+static int is_identified(User * user, ChannelInfo * ci);
+static void make_unidentified(User * u, ChannelInfo * ci);
+
+static int do_help(User * u);
+static int do_register(User * u);
+static int do_identify(User * u);
+static int do_logout(User * u);
+static int do_drop(User * u);
+static int do_set(User * u);
+static int do_set_founder(User * u, ChannelInfo * ci, char *param);
+static int do_set_successor(User * u, ChannelInfo * ci, char *param);
+static int do_set_password(User * u, ChannelInfo * ci, char *param);
+static int do_set_desc(User * u, ChannelInfo * ci, char *param);
+static int do_set_url(User * u, ChannelInfo * ci, char *param);
+static int do_set_email(User * u, ChannelInfo * ci, char *param);
+static int do_set_entrymsg(User * u, ChannelInfo * ci, char *param);
+static int do_set_bantype(User * u, ChannelInfo * ci, char *param);
+static int do_set_mlock(User * u, ChannelInfo * ci, char *param);
+static int do_set_keeptopic(User * u, ChannelInfo * ci, char *param);
+static int do_set_topiclock(User * u, ChannelInfo * ci, char *param);
+static int do_set_private(User * u, ChannelInfo * ci, char *param);
+static int do_set_secureops(User * u, ChannelInfo * ci, char *param);
+static int do_set_securefounder(User * u, ChannelInfo * ci, char *param);
+static int do_set_restricted(User * u, ChannelInfo * ci, char *param);
+static int do_set_secure(User * u, ChannelInfo * ci, char *param);
+static int do_set_signkick(User * u, ChannelInfo * ci, char *param);
+static int do_set_opnotice(User * u, ChannelInfo * ci, char *param);
+static int do_set_xop(User * u, ChannelInfo * ci, char *param);
+static int do_set_peace(User * u, ChannelInfo * ci, char *param);
+static int do_set_noexpire(User * u, ChannelInfo * ci, char *param);
+static int do_xop(User * u, char *xname, int xlev, int *xmsgs);
+static int do_aop(User * u);
+#ifdef HAS_HALFOP
+static int do_hop(User * u);
+#endif
+static int do_sop(User * u);
+static int do_vop(User * u);
+static int do_access(User * u);
+static int do_akick(User * u);
+static int do_info(User * u);
+static int do_list(User * u);
+static int do_invite(User * u);
+static int do_levels(User * u);
+static int do_util(User * u, CSModeUtil * util);
+static int do_op(User * u);
+static int do_deop(User * u);
+static int do_voice(User * u);
+static int do_devoice(User * u);
+#ifdef HAS_HALFOP
+static int do_halfop(User * u);
+static int do_dehalfop(User * u);
+#endif
+#ifdef IRC_UNREAL
+static int do_protect(User * u);
+static int do_deprotect(User * u);
+static int do_owner(User * u);
+static int do_deowner(User * u);
+#endif
+#ifdef IRC_VIAGRA
+static int do_protect(User * u);
+static int do_deprotect(User * u);
+static int do_owner(User * u);
+static int do_deowner(User * u);
+#endif
+#ifdef IRC_ULTIMATE3
+static int do_protect(User * u);
+static int do_deprotect(User * u);
+#endif
+static int do_cs_kick(User * u);
+static int do_ban(User * u);
+static int do_cs_topic(User * u);
+static int do_unban(User * u);
+static int do_clear(User * u);
+static int do_getkey(User * u);
+static int do_getpass(User * u);
+static int do_sendpass(User * u);
+static int do_forbid(User * u);
+static int do_suspend(User * u);
+static int do_unsuspend(User * u);
+static int do_status(User * u);
+void moduleAddChanServCmds(void);
+/*************************************************************************/
+/* *INDENT-OFF* */
+void moduleAddChanServCmds(void) {
+ Command *c;
+ c = createCommand("HELP", do_help, NULL, -1, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("REGISTER", do_register, NULL, CHAN_HELP_REGISTER, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("IDENTIFY", do_identify, NULL, CHAN_HELP_IDENTIFY, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("LOGOUT", do_logout, NULL, -1,CHAN_HELP_LOGOUT, CHAN_SERVADMIN_HELP_LOGOUT,CHAN_SERVADMIN_HELP_LOGOUT, CHAN_SERVADMIN_HELP_LOGOUT); addCoreCommand(CHANSERV,c);
+ c = createCommand("DROP", do_drop, NULL, -1,CHAN_HELP_DROP, CHAN_SERVADMIN_HELP_DROP,CHAN_SERVADMIN_HELP_DROP, CHAN_SERVADMIN_HELP_DROP); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET", do_set, NULL, CHAN_HELP_SET,-1, CHAN_SERVADMIN_HELP_SET,CHAN_SERVADMIN_HELP_SET, CHAN_SERVADMIN_HELP_SET); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET FOUNDER", NULL, NULL, CHAN_HELP_SET_FOUNDER, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET SUCCESSOR", NULL, NULL, CHAN_HELP_SET_SUCCESSOR, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET PASSWORD", NULL, NULL, CHAN_HELP_SET_PASSWORD, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET DESC", NULL, NULL, CHAN_HELP_SET_DESC, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET URL", NULL, NULL, CHAN_HELP_SET_URL, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET EMAIL", NULL, NULL, CHAN_HELP_SET_EMAIL, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET ENTRYMSG", NULL, NULL, CHAN_HELP_SET_ENTRYMSG, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET BANTYPE", NULL, NULL, CHAN_HELP_SET_BANTYPE, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET PRIVATE", NULL, NULL, CHAN_HELP_SET_PRIVATE, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET KEEPTOPIC", NULL, NULL, CHAN_HELP_SET_KEEPTOPIC, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET TOPICLOCK", NULL, NULL, CHAN_HELP_SET_TOPICLOCK, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET MLOCK", NULL, NULL, CHAN_HELP_SET_MLOCK, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET RESTRICTED", NULL, NULL, CHAN_HELP_SET_RESTRICTED, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET SECURE", NULL, NULL, CHAN_HELP_SET_SECURE, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET SECUREOPS", NULL, NULL, CHAN_HELP_SET_SECUREOPS, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET SECUREFOUNDER", NULL, NULL, CHAN_HELP_SET_SECUREFOUNDER, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET SIGNKICK", NULL, NULL, CHAN_HELP_SET_SIGNKICK, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET OPNOTICE", NULL, NULL, CHAN_HELP_SET_OPNOTICE, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET XOP", NULL, NULL, CHAN_HELP_SET_XOP, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET PEACE", NULL, NULL, CHAN_HELP_SET_PEACE, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SET NOEXPIRE", NULL, NULL, -1, -1,CHAN_SERVADMIN_HELP_SET_NOEXPIRE,CHAN_SERVADMIN_HELP_SET_NOEXPIRE,CHAN_SERVADMIN_HELP_SET_NOEXPIRE); addCoreCommand(CHANSERV,c);
+ c = createCommand("AOP", do_aop, NULL, CHAN_HELP_AOP, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+#ifdef HAS_HALFOP
+ c = createCommand("HOP", do_hop, NULL, CHAN_HELP_HOP, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+#endif
+ c = createCommand("SOP", do_sop, NULL, CHAN_HELP_SOP, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("VOP", do_vop, NULL, CHAN_HELP_VOP, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("ACCESS", do_access, NULL, CHAN_HELP_ACCESS, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("ACCESS LEVELS", NULL, NULL, CHAN_HELP_ACCESS_LEVELS, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("AKICK", do_akick, NULL, CHAN_HELP_AKICK, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("LEVELS", do_levels, NULL, CHAN_HELP_LEVELS, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("INFO", do_info, NULL, CHAN_HELP_INFO,-1, CHAN_SERVADMIN_HELP_INFO, CHAN_SERVADMIN_HELP_INFO,CHAN_SERVADMIN_HELP_INFO); addCoreCommand(CHANSERV,c);
+ c = createCommand("LIST", do_list, NULL, -1,CHAN_HELP_LIST, CHAN_SERVADMIN_HELP_LIST,CHAN_SERVADMIN_HELP_LIST, CHAN_SERVADMIN_HELP_LIST); addCoreCommand(CHANSERV,c);
+ c = createCommand("OP", do_op, NULL, CHAN_HELP_OP, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("DEOP", do_deop, NULL, CHAN_HELP_DEOP, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("VOICE", do_voice, NULL, CHAN_HELP_VOICE, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("DEVOICE", do_devoice, NULL, CHAN_HELP_DEVOICE, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+#ifdef HAS_HALFOP
+ c = createCommand("HALFOP", do_halfop, NULL, CHAN_HELP_HALFOP, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("DEHALFOP", do_dehalfop, NULL, CHAN_HELP_DEHALFOP, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+#endif
+#ifdef IRC_UNREAL
+ c = createCommand("PROTECT", do_protect, NULL, CHAN_HELP_PROTECT, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("DEPROTECT",do_deprotect,NULL, CHAN_HELP_DEPROTECT, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("OWNER", do_owner, NULL, CHAN_HELP_OWNER, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("DEOWNER", do_deowner, NULL, CHAN_HELP_DEOWNER, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+#endif
+#ifdef IRC_VIAGRA
+ c = createCommand("PROTECT", do_protect, NULL, CHAN_HELP_PROTECT, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("DEPROTECT",do_deprotect,NULL, CHAN_HELP_DEPROTECT, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("OWNER", do_owner, NULL, CHAN_HELP_OWNER, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("DEOWNER", do_deowner, NULL, CHAN_HELP_DEOWNER, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+#endif
+#ifdef IRC_ULTIMATE3
+ c = createCommand("ADMIN", do_protect, NULL, CHAN_HELP_PROTECT, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("DEADMIN",do_deprotect,NULL, CHAN_HELP_DEPROTECT, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+#endif
+ c = createCommand("KICK", do_cs_kick, NULL, CHAN_HELP_KICK, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("BAN", do_ban, NULL, CHAN_HELP_BAN, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("TOPIC", do_cs_topic, NULL, CHAN_HELP_TOPIC, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("INVITE", do_invite, NULL, CHAN_HELP_INVITE, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("UNBAN", do_unban, NULL, CHAN_HELP_UNBAN, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("CLEAR", do_clear, NULL, CHAN_HELP_CLEAR, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("GETKEY", do_getkey, NULL, CHAN_HELP_GETKEY, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("SENDPASS", do_sendpass, NULL, CHAN_HELP_SENDPASS, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
+ c = createCommand("GETPASS", do_getpass, is_services_admin, -1,-1, CHAN_SERVADMIN_HELP_GETPASS,CHAN_SERVADMIN_HELP_GETPASS, CHAN_SERVADMIN_HELP_GETPASS); addCoreCommand(CHANSERV,c);
+ c = createCommand("FORBID", do_forbid, is_services_admin, -1,-1, CHAN_SERVADMIN_HELP_FORBID,CHAN_SERVADMIN_HELP_FORBID, CHAN_SERVADMIN_HELP_FORBID); addCoreCommand(CHANSERV,c);
+ c = createCommand("SUSPEND", do_suspend, is_services_admin, -1,-1, CHAN_SERVADMIN_HELP_SUSPEND,CHAN_SERVADMIN_HELP_SUSPEND, CHAN_SERVADMIN_HELP_SUSPEND); addCoreCommand(CHANSERV,c);
+ c = createCommand("UNSUSPEND", do_unsuspend, is_services_admin, -1,-1, CHAN_SERVADMIN_HELP_UNSUSPEND,CHAN_SERVADMIN_HELP_UNSUSPEND, CHAN_SERVADMIN_HELP_UNSUSPEND); addCoreCommand(CHANSERV,c);
+ c = createCommand("STATUS", do_status, is_services_admin, -1,-1, CHAN_SERVADMIN_HELP_STATUS,CHAN_SERVADMIN_HELP_STATUS, CHAN_SERVADMIN_HELP_STATUS); addCoreCommand(CHANSERV,c);
+}
+
+/* *INDENT-ON* */
+/*************************************************************************/
+/*************************************************************************/
+
+/* Returns modes for mlock in a nice way. */
+
+static char *get_mlock_modes(ChannelInfo * ci, int complete)
+{
+ static char res[BUFSIZE];
+
+ char *end = res;
+
+ if (ci->mlock_on || ci->mlock_off) {
+ int n = 0;
+ CBModeInfo *cbmi = cbmodeinfos;
+
+ if (ci->mlock_on) {
+ *end++ = '+';
+ n++;
+
+ do {
+ if (ci->mlock_on & cbmi->flag)
+ *end++ = cbmi->mode;
+ } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1);
+
+ cbmi = cbmodeinfos;
+ }
+
+ if (ci->mlock_off) {
+ *end++ = '-';
+ n++;
+
+ do {
+ if (ci->mlock_off & cbmi->flag)
+ *end++ = cbmi->mode;
+ } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1);
+
+ cbmi = cbmodeinfos;
+ }
+
+ if (ci->mlock_on && complete) {
+ do {
+ if (cbmi->csgetvalue && (ci->mlock_on & cbmi->flag)) {
+ char *value = cbmi->csgetvalue(ci);
+
+ if (value) {
+ *end++ = ' ';
+ while (*value)
+ *end++ = *value++;
+ }
+ }
+ } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1);
+ }
+ }
+
+ *end = 0;
+
+ return res;
+}
+
+/* Display total number of registered channels and info about each; or, if
+ * a specific channel is given, display information about that channel
+ * (like /msg ChanServ INFO <channel>). If count_only != 0, then only
+ * display the number of registered channels (the channel parameter is
+ * ignored).
+ */
+
+void listchans(int count_only, const char *chan)
+{
+ int count = 0;
+ ChannelInfo *ci;
+ int i;
+
+ if (count_only) {
+
+ for (i = 0; i < 256; i++) {
+ for (ci = chanlists[i]; ci; ci = ci->next)
+ count++;
+ }
+ printf("%d channels registered.\n", count);
+
+ } else if (chan) {
+
+ struct tm *tm;
+ char buf[BUFSIZE];
+
+ if (!(ci = cs_findchan(chan))) {
+ printf("Channel %s not registered.\n", chan);
+ return;
+ }
+ if (ci->flags & CI_VERBOTEN) {
+ printf("Channel %s is FORBIDden.\n", ci->name);
+ } else {
+ printf("Information about channel %s:\n", ci->name);
+ printf(" Founder: %s\n", ci->founder->display);
+ printf(" Description: %s\n", ci->desc);
+ tm = localtime(&ci->time_registered);
+ strftime(buf, sizeof(buf),
+ getstring(NULL, STRFTIME_DATE_TIME_FORMAT), tm);
+ printf(" Registered: %s\n", buf);
+ tm = localtime(&ci->last_used);
+ strftime(buf, sizeof(buf),
+ getstring(NULL, STRFTIME_DATE_TIME_FORMAT), tm);
+ printf(" Last used: %s\n", buf);
+ if (ci->last_topic) {
+ printf(" Last topic: %s\n", ci->last_topic);
+ printf(" Topic set by: %s\n", ci->last_topic_setter);
+ }
+ if (ci->url)
+ printf(" URL: %s\n", ci->url);
+ if (ci->email)
+ printf(" E-mail address: %s\n", ci->email);
+ printf(" Options: ");
+ if (!ci->flags) {
+ printf("None\n");
+ } else {
+ int need_comma = 0;
+ static const char commastr[] = ", ";
+ if (ci->flags & CI_PRIVATE) {
+ printf("Private");
+ need_comma = 1;
+ }
+ if (ci->flags & CI_KEEPTOPIC) {
+ printf("%sTopic Retention",
+ need_comma ? commastr : "");
+ need_comma = 1;
+ }
+ if (ci->flags & CI_TOPICLOCK) {
+ printf("%sTopic Lock", need_comma ? commastr : "");
+ need_comma = 1;
+ }
+ if (ci->flags & CI_SECUREOPS) {
+ printf("%sSecure Ops", need_comma ? commastr : "");
+ need_comma = 1;
+ }
+ if (ci->flags & CI_RESTRICTED) {
+ printf("%sRestricted Access",
+ need_comma ? commastr : "");
+ need_comma = 1;
+ }
+ if (ci->flags & CI_SECURE) {
+ printf("%sSecure", need_comma ? commastr : "");
+ need_comma = 1;
+ }
+ if (ci->flags & CI_NO_EXPIRE) {
+ printf("%sNo Expire", need_comma ? commastr : "");
+ need_comma = 1;
+ }
+ printf("\n");
+ }
+ if (ci->mlock_on || ci->mlock_off)
+ printf(" Mode lock: %s\n", get_mlock_modes(ci, 1));
+ }
+
+ } else {
+
+ for (i = 0; i < 256; i++) {
+ for (ci = chanlists[i]; ci; ci = ci->next) {
+ printf(" %s %-20s %s\n",
+ ci->flags & CI_NO_EXPIRE ? "!" : " ", ci->name,
+ ci->
+ flags & CI_VERBOTEN ? "Disallowed (FORBID)" : ci->
+ desc);
+ count++;
+ }
+ }
+ printf("%d channels registered.\n", count);
+
+ }
+}
+
+/*************************************************************************/
+
+/* Return information on memory use. Assumes pointers are valid. */
+
+void get_chanserv_stats(long *nrec, long *memuse)
+{
+ long count = 0, mem = 0;
+ int i, j;
+ ChannelInfo *ci;
+
+ 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->accesscount * sizeof(ChanAccess);
+ mem += ci->akickcount * sizeof(AutoKick);
+ for (j = 0; j < ci->akickcount; j++) {
+ if (!(ci->akick[j].flags & AK_ISNICK)
+ && ci->akick[j].u.mask)
+ mem += strlen(ci->akick[j].u.mask) + 1;
+ if (ci->akick[j].reason)
+ mem += strlen(ci->akick[j].reason) + 1;
+ if (ci->akick[j].creator)
+ mem += strlen(ci->akick[j].creator) + 1;
+ }
+ if (ci->mlock_key)
+ mem += strlen(ci->mlock_key) + 1;
+#ifdef HAS_FMODE
+ if (ci->mlock_flood)
+ mem += strlen(ci->mlock_flood) + 1;
+#endif
+#ifdef HAS_LMODE
+ if (ci->mlock_redirect)
+ mem += strlen(ci->mlock_redirect) + 1;
+#endif
+ 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.memocount * sizeof(Memo);
+ for (j = 0; j < ci->memos.memocount; 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->bwcount * sizeof(BadWord);
+ for (j = 0; j < ci->bwcount; j++)
+ if (ci->badwords[j].word)
+ mem += strlen(ci->badwords[j].word) + 1;
+ }
+ }
+ *nrec = count;
+ *memuse = mem;
+}
+
+/*************************************************************************/
+/*************************************************************************/
+
+/* ChanServ initialization. */
+
+void cs_init(void)
+{
+ Command *cmd;
+ moduleAddChanServCmds();
+ cmd = findCommand(CHANSERV, "REGISTER");
+ if (cmd)
+ cmd->help_param1 = s_NickServ;
+ cmd = findCommand(CHANSERV, "SET SECURE");
+ if (cmd)
+ cmd->help_param1 = s_NickServ;
+ cmd = findCommand(CHANSERV, "SET SUCCESSOR");
+ if (cmd)
+ cmd->help_param1 = (char *) (long) CSMaxReg;
+}
+
+/*************************************************************************/
+
+/* Main ChanServ routine. */
+
+void chanserv(User * u, char *buf)
+{
+ char *cmd, *s;
+
+ cmd = strtok(buf, " ");
+
+ if (!cmd) {
+ return;
+ } else if (stricmp(cmd, "\1PING") == 0) {
+ if (!(s = strtok(NULL, "")))
+ s = "\1";
+ notice(s_ChanServ, u->nick, "\1PING %s", s);
+ } else if (skeleton) {
+ notice_lang(s_ChanServ, u, SERVICE_OFFLINE, s_ChanServ);
+ } else {
+ mod_run_cmd(s_ChanServ, u, CHANSERV, cmd);
+ }
+}
+
+/*************************************************************************/
+
+/* Load/save data files. */
+
+
+#define SAFE(x) do { \
+ if ((x) < 0) { \
+ if (!forceload) \
+ fatal("Read error on %s", ChanDBName); \
+ failed = 1; \
+ break; \
+ } \
+} while (0)
+
+void load_cs_dbase(void)
+{
+ dbFILE *f;
+ int ver, i, j, c;
+ ChannelInfo *ci, **last, *prev;
+ int failed = 0;
+
+ if (!(f = open_db(s_ChanServ, ChanDBName, "r", CHAN_VERSION)))
+ return;
+
+ ver = get_file_version(f);
+
+ for (i = 0; i < 256 && !failed; i++) {
+ int16 tmp16;
+ int32 tmp32;
+ int n_levels;
+ char *s;
+ NickAlias *na;
+
+ last = &chanlists[i];
+ prev = NULL;
+ while ((c = getc_db(f)) != 0) {
+ if (c != 1)
+ fatal("Invalid format in %s", ChanDBName);
+ ci = scalloc(sizeof(ChannelInfo), 1);
+ *last = ci;
+ last = &ci->next;
+ ci->prev = prev;
+ prev = ci;
+ SAFE(read_buffer(ci->name, f));
+ SAFE(read_string(&s, f));
+ if (s) {
+ if (ver >= 13)
+ ci->founder = findcore(s);
+ else {
+ na = findnick(s);
+ if (na)
+ ci->founder = na->nc;
+ else
+ ci->founder = NULL;
+ }
+ free(s);
+ } else
+ ci->founder = NULL;
+ if (ver >= 7) {
+ SAFE(read_string(&s, f));
+ if (s) {
+ if (ver >= 13)
+ ci->successor = findcore(s);
+ else {
+ na = findnick(s);
+ if (na)
+ ci->successor = na->nc;
+ else
+ ci->successor = NULL;
+ }
+ free(s);
+ } else
+ ci->successor = NULL;
+ } else {
+ ci->successor = NULL;
+ }
+ SAFE(read_buffer(ci->founderpass, f));
+ SAFE(read_string(&ci->desc, f));
+ if (!ci->desc)
+ ci->desc = sstrdup("");
+ SAFE(read_string(&ci->url, f));
+ SAFE(read_string(&ci->email, f));
+ SAFE(read_int32(&tmp32, f));
+ ci->time_registered = tmp32;
+ SAFE(read_int32(&tmp32, f));
+ ci->last_used = tmp32;
+ SAFE(read_string(&ci->last_topic, f));
+ SAFE(read_buffer(ci->last_topic_setter, f));
+ SAFE(read_int32(&tmp32, f));
+ ci->last_topic_time = tmp32;
+ SAFE(read_int32(&ci->flags, f));
+#ifdef USE_ENCRYPTION
+ if (!(ci->flags & (CI_ENCRYPTEDPW | CI_VERBOTEN))) {
+ if (debug)
+ alog("debug: %s: encrypting password for %s on load",
+ s_ChanServ, ci->name);
+ if (encrypt_in_place(ci->founderpass, PASSMAX) < 0)
+ fatal("%s: load database: Can't encrypt %s password!",
+ s_ChanServ, ci->name);
+ ci->flags |= CI_ENCRYPTEDPW;
+ }
+#else
+ if (ci->flags & CI_ENCRYPTEDPW) {
+ /* Bail: it makes no sense to continue with encrypted
+ * passwords, since we won't be able to verify them */
+ fatal("%s: load database: password for %s encrypted "
+ "but encryption disabled, aborting",
+ s_ChanServ, ci->name);
+ }
+#endif
+ /* Leaveops cleanup */
+ if (ver <= 13 && (ci->flags & 0x00000020))
+ ci->flags &= ~0x00000020;
+ /* Temporary flags cleanup */
+ ci->flags &= ~CI_INHABIT;
+
+ if (ver >= 9) {
+ SAFE(read_string(&ci->forbidby, f));
+ SAFE(read_string(&ci->forbidreason, f));
+ } else {
+ ci->forbidreason = NULL;
+ ci->forbidby = NULL;
+ }
+ if (ver >= 9)
+ SAFE(read_int16(&tmp16, f));
+ else
+ tmp16 = CSDefBantype;
+ ci->bantype = tmp16;
+ SAFE(read_int16(&tmp16, f));
+ n_levels = tmp16;
+ ci->levels = scalloc(2 * CA_SIZE, 1);
+ reset_levels(ci);
+ for (j = 0; j < n_levels; j++) {
+ if (j < CA_SIZE)
+ SAFE(read_int16(&ci->levels[j], f));
+ else
+ SAFE(read_int16(&tmp16, f));
+ }
+ /* To avoid levels list silly hacks */
+ if (ver < 10)
+ ci->levels[CA_OPDEOPME] = ci->levels[CA_OPDEOP];
+ if (ver < 11) {
+ ci->levels[CA_KICKME] = ci->levels[CA_OPDEOP];
+ ci->levels[CA_KICK] = ci->levels[CA_OPDEOP];
+ }
+ if (ver < 15) {
+
+ /* Old Ultimate levels import */
+ /* We now conveniently use PROTECT internals for Ultimate's ADMIN support - ShadowMaster */
+ /* Doh, must of course be done before we change the values were trying to import - ShadowMaster */
+ ci->levels[CA_AUTOPROTECT] = ci->levels[32];
+ ci->levels[CA_PROTECTME] = ci->levels[33];
+ ci->levels[CA_PROTECT] = ci->levels[34];
+
+ ci->levels[CA_BANME] = ci->levels[CA_OPDEOP];
+ ci->levels[CA_BAN] = ci->levels[CA_OPDEOP];
+ ci->levels[CA_TOPIC] = ACCESS_INVALID;
+
+
+ }
+
+ SAFE(read_int16(&ci->accesscount, f));
+ if (ci->accesscount) {
+ ci->access = scalloc(ci->accesscount, sizeof(ChanAccess));
+ for (j = 0; j < ci->accesscount; j++) {
+ SAFE(read_int16(&ci->access[j].in_use, f));
+ if (ci->access[j].in_use) {
+ SAFE(read_int16(&ci->access[j].level, f));
+ SAFE(read_string(&s, f));
+ if (s) {
+ if (ver >= 13)
+ ci->access[j].nc = findcore(s);
+ else {
+ na = findnick(s);
+ if (na)
+ ci->access[j].nc = na->nc;
+ else
+ ci->access[j].nc = NULL;
+ }
+ free(s);
+ }
+ if (ci->access[j].nc == NULL)
+ ci->access[j].in_use = 0;
+ if (ver >= 11) {
+ SAFE(read_int32(&tmp32, f));
+ ci->access[j].last_seen = tmp32;
+ } else {
+ ci->access[j].last_seen = 0; /* Means we have never seen the user */
+ }
+ }
+ }
+ } else {
+ ci->access = NULL;
+ }
+
+ SAFE(read_int16(&ci->akickcount, f));
+ if (ci->akickcount) {
+ ci->akick = scalloc(ci->akickcount, sizeof(AutoKick));
+ for (j = 0; j < ci->akickcount; j++) {
+ if (ver >= 15) {
+ SAFE(read_int16(&ci->akick[j].flags, f));
+ } else {
+ SAFE(read_int16(&tmp16, f));
+ if (tmp16)
+ ci->akick[j].flags |= AK_USED;
+ }
+ if (ci->akick[j].flags & AK_USED) {
+ if (ver < 15) {
+ SAFE(read_int16(&tmp16, f));
+ if (tmp16)
+ ci->akick[j].flags |= AK_ISNICK;
+ }
+ SAFE(read_string(&s, f));
+ if (ci->akick[j].flags & AK_ISNICK) {
+ if (ver >= 13) {
+ ci->akick[j].u.nc = findcore(s);
+ } else {
+ na = findnick(s);
+ if (na)
+