summaryrefslogtreecommitdiff
path: root/src/chanserv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/chanserv.c')
-rw-r--r--src/chanserv.c4064
1 files changed, 15 insertions, 4049 deletions
diff --git a/src/chanserv.c b/src/chanserv.c
index 6ee7d0056..4d197770e 100644
--- a/src/chanserv.c
+++ b/src/chanserv.c
@@ -102,7 +102,7 @@ LevelInfo levelinfo[] = {
{ CA_SAY, "SAY", CHAN_LEVEL_SAY },
{ -1 }
};
-static int levelinfo_maxwidth = 0;
+int levelinfo_maxwidth = 0;
CSModeUtil csmodeutils[] = {
{ "DEOP", "!deop", "-o", CI_OPNOTICE, CA_OPDEOP, CA_OPDEOPME },
@@ -116,207 +116,20 @@ CSModeUtil csmodeutils[] = {
{ 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* */
/*************************************************************************/
void alpha_insert_chan(ChannelInfo * ci);
-static ChannelInfo *makechan(const char *chan);
+ChannelInfo *makechan(const char *chan);
int delchan(ChannelInfo * ci);
void reset_levels(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);
-static int do_hop(User * u);
-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);
-static int do_halfop(User * u);
-static int do_dehalfop(User * u);
-static int do_protect(User * u);
-static int do_deprotect(User * u);
-static int do_owner(User * u);
-static int do_deowner(User * u);
-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);
+int is_identified(User * user, ChannelInfo * ci);
+
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, -1,CHAN_SERVADMIN_HELP_LOGOUT, CHAN_SERVADMIN_HELP_LOGOUT); addCoreCommand(CHANSERV,c);
- c = createCommand("DROP", do_drop, NULL, -1,CHAN_HELP_DROP, -1,CHAN_SERVADMIN_HELP_DROP, CHAN_SERVADMIN_HELP_DROP); addCoreCommand(CHANSERV,c);
- c = createCommand("SET", do_set, NULL, CHAN_HELP_SET,-1, -1,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, -1,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);
- c = createCommand("HOP", do_hop, NULL, CHAN_HELP_HOP, -1,-1,-1,-1); addCoreCommand(CHANSERV,c);
- 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);
- 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);
- 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);
- 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);
- 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, -1, CHAN_SERVADMIN_HELP_GETPASS, CHAN_SERVADMIN_HELP_GETPASS); addCoreCommand(CHANSERV,c);
- c = createCommand("FORBID", do_forbid, is_services_admin, -1, -1, -1, CHAN_SERVADMIN_HELP_FORBID, CHAN_SERVADMIN_HELP_FORBID); addCoreCommand(CHANSERV,c);
- c = createCommand("SUSPEND", do_suspend, is_services_admin, -1, -1, -1, CHAN_SERVADMIN_HELP_SUSPEND, CHAN_SERVADMIN_HELP_SUSPEND); addCoreCommand(CHANSERV,c);
- c = createCommand("UNSUSPEND",do_unsuspend, is_services_admin, -1, -1, -1, CHAN_SERVADMIN_HELP_UNSUSPEND, CHAN_SERVADMIN_HELP_UNSUSPEND); addCoreCommand(CHANSERV,c);
- c = createCommand("STATUS", do_status, is_services_admin, -1, -1, -1, CHAN_SERVADMIN_HELP_STATUS, CHAN_SERVADMIN_HELP_STATUS); addCoreCommand(CHANSERV,c);
+ modules_core_init(ChanServCoreNumber, ChanServCoreModules);
}
/* *INDENT-ON* */
@@ -325,7 +138,7 @@ void moduleAddChanServCmds(void) {
/* Returns modes for mlock in a nice way. */
-static char *get_mlock_modes(ChannelInfo * ci, int complete)
+char *get_mlock_modes(ChannelInfo * ci, int complete)
{
static char res[BUFSIZE];
@@ -1739,18 +1552,21 @@ void record_topic(const char *chan)
if (readonly)
return;
+
c = findchan(chan);
if (!c || !(ci = c->ci))
return;
+
if (ci->last_topic)
free(ci->last_topic);
+
if (c->topic)
ci->last_topic = sstrdup(c->topic);
else
ci->last_topic = NULL;
+
strscpy(ci->last_topic_setter, c->topic_setter, NICKMAX);
ci->last_topic_time = c->topic_time;
- send_event(EVENT_TOPIC_UPDATED, chan);
}
/*************************************************************************/
@@ -1883,7 +1699,7 @@ void expire_chans()
next = ci->next;
if (!ci->c && now - ci->last_used >= CSExpire
&& !(ci->flags & (CI_VERBOTEN | CI_NO_EXPIRE))) {
- send_event(EVENT_CHAN_EXPIRE, ci->name);
+ send_event(EVENT_CHAN_EXPIRE, 1, ci->name);
alog("Expiring channel %s (founder: %s)", ci->name,
(ci->founder ? ci->founder->display : "(none)"));
delchan(ci);
@@ -2092,7 +1908,7 @@ void alpha_insert_chan(ChannelInfo * ci)
* structure if the channel was successfully registered, NULL otherwise.
* Assumes channel does not already exist. */
-static ChannelInfo *makechan(const char *chan)
+ChannelInfo *makechan(const char *chan)
{
int i;
ChannelInfo *ci;
@@ -2322,7 +2138,7 @@ int is_real_founder(User * user, ChannelInfo * ci)
/* Has the given user password-identified as founder for the channel? */
-static int is_identified(User * user, ChannelInfo * ci)
+int is_identified(User * user, ChannelInfo * ci)
{
struct u_chaninfolist *c;
@@ -2437,29 +2253,6 @@ int get_idealban(ChannelInfo * ci, User * u, char *ret, int retlen)
/*************************************************************************/
-static void make_unidentified(User * u, ChannelInfo * ci)
-{
- struct u_chaninfolist *uci;
-
- if (!u || !ci)
- return;
-
- for (uci = u->founder_chans; uci; uci = uci->next) {
- if (uci->chan == ci) {
- if (uci->next)
- uci->next->prev = uci->prev;
- if (uci->prev)
- uci->prev->next = uci->next;
- else
- u->founder_chans = uci->next;
- free(uci);
- break;
- }
- }
-}
-
-/*************************************************************************/
-
char *cs_get_flood(ChannelInfo * ci)
{
if (!ci) {
@@ -2544,7 +2337,7 @@ void cs_set_key(ChannelInfo * ci, char *value)
if (value && *value != ':' && !strchr(value, ',')) {
ci->mlock_key = sstrdup(value);
} else {
- ci->mlock_on &= ~CMODE_k;
+ ci->mlock_on &= ~anope_get_key_mode();
ci->mlock_key = NULL;
}
}
@@ -2560,7 +2353,7 @@ void cs_set_limit(ChannelInfo * ci, char *value)
ci->mlock_limit = value ? strtoul(value, NULL, 10) : 0;
if (ci->mlock_limit <= 0)
- ci->mlock_on &= ~CMODE_l;
+ ci->mlock_on &= ~anope_get_limit_mode();
}
/*************************************************************************/
@@ -2634,1019 +2427,8 @@ char *get_xop_level(int level)
/*********************** ChanServ command routines ***********************/
/*************************************************************************/
-static int do_help(User * u)
-{
- char *cmd = strtok(NULL, "");
-
- if (!cmd) {
- notice_help(s_ChanServ, u, CHAN_HELP);
- if (ircd->extrahelp) {
- notice_help(s_ChanServ, u, ircd->extrahelp);
- }
- if (CSExpire >= 86400)
- notice_help(s_ChanServ, u, CHAN_HELP_EXPIRES,
- CSExpire / 86400);
- if (is_services_oper(u))
- notice_help(s_ChanServ, u, CHAN_SERVADMIN_HELP);
- moduleDisplayHelp(2, u);
- } else if (stricmp(cmd, "LEVELS DESC") == 0) {
- int i;
- notice_help(s_ChanServ, u, CHAN_HELP_LEVELS_DESC);
- 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++) {
- notice_help(s_ChanServ, u, CHAN_HELP_LEVELS_DESC_FORMAT,
- levelinfo_maxwidth, levelinfo[i].name,
- getstring(u->na, levelinfo[i].desc));
- }
- } else {
- mod_help_cmd(s_ChanServ, u, CHANSERV, cmd);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_register(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *pass = strtok(NULL, " ");
- char *desc = strtok(NULL, "");
- NickCore *nc;
- Channel *c;
- ChannelInfo *ci;
- struct u_chaninfolist *uc;
- int is_servadmin = is_services_admin(u);
-#ifdef USE_ENCRYPTION
- char founderpass[PASSMAX + 1];
-#endif
-
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_REGISTER_DISABLED);
- return MOD_CONT;
- }
-
- if (checkDefCon(DEFCON_NO_NEW_CHANNELS)) {
- notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED);
- return MOD_CONT;
- }
-
- if (!desc) {
- syntax_error(s_ChanServ, u, "REGISTER", CHAN_REGISTER_SYNTAX);
- } else if (*chan == '&') {
- notice_lang(s_ChanServ, u, CHAN_REGISTER_NOT_LOCAL);
- } else if (*chan != '#') {
- notice_lang(s_ChanServ, u, CHAN_SYMBOL_REQUIRED);
- } else if (!u->na || !(nc = u->na->nc)) {
- notice_lang(s_ChanServ, u, CHAN_MUST_REGISTER_NICK, s_NickServ);
- } else if (!nick_recognized(u)) {
- notice_lang(s_ChanServ, u, CHAN_MUST_IDENTIFY_NICK, s_NickServ,
- s_NickServ);
- } else if (!(c = findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_REGISTER_NONE_CHANNEL, chan);
- } else if ((ci = cs_findchan(chan)) != NULL) {
- if (ci->flags & CI_VERBOTEN) {
- alog("%s: Attempt to register FORBIDden channel %s by %s!%s@%s", s_ChanServ, ci->name, u->nick, u->username, u->host);
- notice_lang(s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan);
- } else {
- notice_lang(s_ChanServ, u, CHAN_ALREADY_REGISTERED, chan);
- }
- } else if (!stricmp(chan, "#")) {
- notice_lang(s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan);
- } else if (!chan_has_user_status(c, u, CUS_OP)) {
- notice_lang(s_ChanServ, u, CHAN_MUST_BE_CHANOP);
-
- } else if (!is_servadmin && nc->channelmax > 0
- && nc->channelcount >= nc->channelmax) {
- notice_lang(s_ChanServ, u,
- nc->channelcount >
- nc->
- channelmax ? CHAN_EXCEEDED_CHANNEL_LIMIT :
- CHAN_REACHED_CHANNEL_LIMIT, nc->channelmax);
- } else if (stricmp(u->nick, pass) == 0
- || (StrictPasswords && strlen(pass) < 5)) {
- notice_lang(s_ChanServ, u, MORE_OBSCURE_PASSWORD);
- } else if (!(ci = makechan(chan))) {
- alog("%s: makechan() failed for REGISTER %s", s_ChanServ, chan);
- notice_lang(s_ChanServ, u, CHAN_REGISTRATION_FAILED);
-
-#ifdef USE_ENCRYPTION
- } else if (strscpy(founderpass, pass, PASSMAX + 1),
- encrypt_in_place(founderpass, PASSMAX) < 0) {
- alog("%s: Couldn't encrypt password for %s (REGISTER)",
- s_ChanServ, chan);
- notice_lang(s_ChanServ, u, CHAN_REGISTRATION_FAILED);
- delchan(ci);
-#endif
-
- } else {
- c->ci = ci;
- ci->c = c;
- ci->bantype = CSDefBantype;
- ci->flags = CSDefFlags;
- ci->mlock_on = ircd->defmlock;
- ci->memos.memomax = MSMaxMemos;
- ci->last_used = ci->time_registered;
- ci->founder = nc;
-#ifdef USE_ENCRYPTION
- if (strlen(pass) > PASSMAX)
- notice_lang(s_ChanServ, u, PASSWORD_TRUNCATED, PASSMAX);
- memset(pass, 0, strlen(pass));
- memcpy(ci->founderpass, founderpass, PASSMAX);
- ci->flags |= CI_ENCRYPTEDPW;
-#else
- if (strlen(pass) > PASSMAX - 1) /* -1 for null byte */
- notice_lang(s_ChanServ, u, PASSWORD_TRUNCATED, PASSMAX - 1);
- strscpy(ci->founderpass, pass, PASSMAX);
-#endif
- ci->desc = sstrdup(desc);
- if (c->topic) {
- ci->last_topic = sstrdup(c->topic);
- strscpy(ci->last_topic_setter, c->topic_setter, NICKMAX);
- ci->last_topic_time = c->topic_time;
- } else {
- /* Set this to something, otherwise it will maliform the topic */
- strscpy(ci->last_topic_setter, s_ChanServ, NICKMAX);
- }
- ci->bi = NULL;
- ci->botflags = BSDefFlags;
- ci->founder->channelcount++;
- alog("%s: Channel '%s' registered by %s!%s@%s", s_ChanServ, chan,
- u->nick, u->username, u->host);
- notice_lang(s_ChanServ, u, CHAN_REGISTERED, chan, u->nick);
-#ifndef USE_ENCRYPTION
- notice_lang(s_ChanServ, u, CHAN_PASSWORD_IS, ci->founderpass);
-#endif
- uc = scalloc(sizeof(*uc), 1);
- uc->next = u->founder_chans;
- uc->prev = NULL;
- if (u->founder_chans)
- u->founder_chans->prev = uc;
- u->founder_chans = uc;
- uc->chan = ci;
- /* Implement new mode lock */
- check_modes(c);
- /* On most ircds you do not receive the admin/owner mode till its registered */
- if (ircd->admin) {
- anope_cmd_mode(s_ChanServ, chan, "%s %s", ircd->adminset,
- u->nick);
- }
- if (ircd->owner && ircd->ownerset) {
- anope_cmd_mode(s_ChanServ, chan, "%s %s", ircd->ownerset,
- u->nick);
- }
- send_event(EVENT_CHAN_REGISTERED, chan);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_identify(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *pass = strtok(NULL, " ");
- ChannelInfo *ci;
- struct u_chaninfolist *uc;
-
- if (!pass) {
- syntax_error(s_ChanServ, u, "IDENTIFY", CHAN_IDENTIFY_SYNTAX);
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!nick_identified(u)) {
- notice_lang(s_ChanServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ);
- } else if (is_founder(u, ci)) {
- notice_lang(s_ChanServ, u, NICK_ALREADY_IDENTIFIED);
- } else {
- int res;
-
- if ((res = check_password(pass, ci->founderpass)) == 1) {
- if (!is_identified(u, ci)) {
- uc = scalloc(sizeof(*uc), 1);
- uc->next = u->founder_chans;
- if (u->founder_chans)
- u->founder_chans->prev = uc;
- u->founder_chans = uc;
- uc->chan = ci;
- alog("%s: %s!%s@%s identified for %s", s_ChanServ, u->nick,
- u->username, u->host, ci->name);
- }
-
- notice_lang(s_ChanServ, u, CHAN_IDENTIFY_SUCCEEDED, chan);
- } else if (res < 0) {
- alog("%s: check_password failed for %s", s_ChanServ, ci->name);
- notice_lang(s_ChanServ, u, CHAN_IDENTIFY_FAILED);
- } else {
- alog("%s: Failed IDENTIFY for %s by %s!%s@%s",
- s_ChanServ, ci->name, u->nick, u->username, u->host);
- notice_lang(s_ChanServ, u, PASSWORD_INCORRECT);
- bad_password(u);
- }
-
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_logout(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *nick = strtok(NULL, " ");
- ChannelInfo *ci;
- User *u2 = NULL;
- int is_servadmin = is_services_admin(u);
-
- if (!chan || (!nick && !is_servadmin)) {
- syntax_error(s_ChanServ, u, "LOGOUT",
- (!is_servadmin ? CHAN_LOGOUT_SYNTAX :
- CHAN_LOGOUT_SERVADMIN_SYNTAX));
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (!is_servadmin && (ci->flags & CI_VERBOTEN)) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (nick && !(u2 = finduser(nick))) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_IN_USE, nick);
- } else if (!is_servadmin && u2 != u && !is_real_founder(u, ci)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else {
- if (u2) {
- make_unidentified(u2, ci);
- notice_lang(s_ChanServ, u, CHAN_LOGOUT_SUCCEEDED, nick, chan);
- alog("%s: User %s!%s@%s has been logged out of channel %s.",
- s_ChanServ, u2->nick, u2->username, u2->host, chan);
- } else {
- int i;
- for (i = 0; i < 1024; i++)
- for (u2 = userlist[i]; u2; u2 = u2->next)
- make_unidentified(u2, ci);
- notice_lang(s_ChanServ, u, CHAN_LOGOUT_ALL_SUCCEEDED, chan);
- alog("%s: All users identified have been logged out of channel %s.", s_ChanServ, chan);
- }
-
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_drop(User * u)
-{
- char *chan = strtok(NULL, " ");
- ChannelInfo *ci;
- int is_servadmin = is_services_admin(u);
-
- if (readonly && !is_servadmin) {
- notice_lang(s_ChanServ, u, CHAN_DROP_DISABLED);
- return MOD_CONT;
- }
-
- if (!chan) {
- syntax_error(s_ChanServ, u, "DROP", CHAN_DROP_SYNTAX);
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (!is_servadmin && (ci->flags & CI_VERBOTEN)) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!is_servadmin && (ci->flags & CI_SUSPENDED)) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!is_servadmin
- && (ci->
- flags & CI_SECUREFOUNDER ? !is_real_founder(u,
- ci) :
- !is_founder(u, ci))) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else {
- int level = get_access(u, ci);
-
- if (readonly) /* in this case we know they're a Services admin */
- notice_lang(s_ChanServ, u, READ_ONLY_MODE);
-
- if (ci->c) {
- if (ircd->regmode) {
- ci->c->mode &= ~ircd->regmode;
- anope_cmd_mode(whosends(ci), ci->name, "-r");
- }
- }
-
- if (ircd->chansqline && (ci->flags & CI_VERBOTEN)) {
- anope_cmd_unsqline(ci->name);
- }
-
- alog("%s: Channel %s dropped by %s!%s@%s (founder: %s)",
- s_ChanServ, ci->name, u->nick, u->username,
- u->host, (ci->founder ? ci->founder->display : "(none)"));
-
- delchan(ci);
-
- /* We must make sure that the Services admin has not normally the right to
- * drop the channel before issuing the wallops.
- */
- if (WallDrop && is_servadmin && level < ACCESS_FOUNDER)
- anope_cmd_global(s_ChanServ,
- "\2%s\2 used DROP on channel \2%s\2", u->nick,
- chan);
-
- notice_lang(s_ChanServ, u, CHAN_DROPPED, chan);
- send_event(EVENT_CHAN_DROP, chan);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-/* Main SET routine. Calls other routines as follows:
- * do_set_command(User *command_sender, ChannelInfo *ci, char *param);
- * The parameter passed is the first space-delimited parameter after the
- * option name, except in the case of DESC, TOPIC, and ENTRYMSG, in which
- * it is the entire remainder of the line. Additional parameters beyond
- * the first passed in the function call can be retrieved using
- * strtok(NULL, toks).
- */
-static int do_set(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *cmd = strtok(NULL, " ");
- char *param;
- ChannelInfo *ci;
- int is_servadmin = is_services_admin(u);
-
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_SET_DISABLED);
- return MOD_CONT;
- }
-
- if (cmd) {
- if (stricmp(cmd, "DESC") == 0 || stricmp(cmd, "ENTRYMSG") == 0)
- param = strtok(NULL, "");
- else
- param = strtok(NULL, " ");
- } else {
- param = NULL;
- }
-
- if (!param && (!cmd || (stricmp(cmd, "SUCCESSOR") != 0 &&
- stricmp(cmd, "URL") != 0 &&
- stricmp(cmd, "EMAIL") != 0 &&
- stricmp(cmd, "ENTRYMSG") != 0))) {
- syntax_error(s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!is_servadmin && !check_access(u, ci, CA_SET)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else if (stricmp(cmd, "FOUNDER") == 0) {
- if (!is_servadmin
- && (ci->
- flags & CI_SECUREFOUNDER ? !is_real_founder(u,
- ci) :
- !is_founder(u, ci))) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else {
- do_set_founder(u, ci, param);
- }
- } else if (stricmp(cmd, "SUCCESSOR") == 0) {
- if (!is_servadmin
- && (ci->
- flags & CI_SECUREFOUNDER ? !is_real_founder(u,
- ci) :
- !is_founder(u, ci))) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else {
- do_set_successor(u, ci, param);
- }
- } else if (stricmp(cmd, "PASSWORD") == 0) {
- if (!is_servadmin
- && (ci->
- flags & CI_SECUREFOUNDER ? !is_real_founder(u,
- ci) :
- !is_founder(u, ci))) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else {
- do_set_password(u, ci, param);
- }
- } else if (stricmp(cmd, "DESC") == 0) {
- do_set_desc(u, ci, param);
- } else if (stricmp(cmd, "URL") == 0) {
- do_set_url(u, ci, param);
- } else if (stricmp(cmd, "EMAIL") == 0) {
- do_set_email(u, ci, param);
- } else if (stricmp(cmd, "ENTRYMSG") == 0) {
- do_set_entrymsg(u, ci, param);
- } else if (stricmp(cmd, "TOPIC") == 0) {
- notice_lang(s_ChanServ, u, OBSOLETE_COMMAND, "TOPIC");
- } else if (stricmp(cmd, "BANTYPE") == 0) {
- do_set_bantype(u, ci, param);
- } else if (stricmp(cmd, "MLOCK") == 0) {
- do_set_mlock(u, ci, param);
- } else if (stricmp(cmd, "KEEPTOPIC") == 0) {
- do_set_keeptopic(u, ci, param);
- } else if (stricmp(cmd, "TOPICLOCK") == 0) {
- do_set_topiclock(u, ci, param);
- } else if (stricmp(cmd, "PRIVATE") == 0) {
- do_set_private(u, ci, param);
- } else if (stricmp(cmd, "SECUREOPS") == 0) {
- do_set_secureops(u, ci, param);
- } else if (stricmp(cmd, "SECUREFOUNDER") == 0) {
- if (!is_servadmin
- && (ci->
- flags & CI_SECUREFOUNDER ? !is_real_founder(u,
- ci) :
- !is_founder(u, ci))) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else {
- do_set_securefounder(u, ci, param);
- }
- } else if (stricmp(cmd, "RESTRICTED") == 0) {
- do_set_restricted(u, ci, param);
- } else if (stricmp(cmd, "SECURE") == 0) {
- do_set_secure(u, ci, param);
- } else if (stricmp(cmd, "SIGNKICK") == 0) {
- do_set_signkick(u, ci, param);
- } else if (stricmp(cmd, "OPNOTICE") == 0) {
- do_set_opnotice(u, ci, param);
- } else if (stricmp(cmd, "XOP") == 0) {
- do_set_xop(u, ci, param);
- } else if (stricmp(cmd, "PEACE") == 0) {
- do_set_peace(u, ci, param);
- } else if (stricmp(cmd, "NOEXPIRE") == 0) {
- do_set_noexpire(u, ci, param);
- } else {
- notice_lang(s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, cmd);
- notice_lang(s_ChanServ, u, MORE_INFO, s_ChanServ, "SET");
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_founder(User * u, ChannelInfo * ci, char *param)
-{
- NickAlias *na = findnick(param);
- NickCore *nc, *nc0 = ci->founder;
-
- if (!na) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_REGISTERED, param);
- return MOD_CONT;
- } else if (na->status & NS_VERBOTEN) {
- notice_lang(s_ChanServ, u, NICK_X_FORBIDDEN, param);
- return MOD_CONT;
- }
-
- nc = na->nc;
- if (nc->channelmax > 0 && nc->channelcount >= nc->channelmax
- && !is_services_admin(u)) {
- notice_lang(s_ChanServ, u, CHAN_SET_FOUNDER_TOO_MANY_CHANS, param);
- return MOD_CONT;
- }
-
- alog("%s: Changing founder of %s from %s to %s by %s!%s@%s",
- s_ChanServ, ci->name, ci->founder->display, nc->display, u->nick,
- u->username, u->host);
-
- /* 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(s_ChanServ, u, CHAN_FOUNDER_CHANGED, ci->name, param);
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_successor(User * u, ChannelInfo * ci, char *param)
-{
- NickAlias *na;
- NickCore *nc;
-
- if (param) {
- na = findnick(param);
-
- if (!na) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_REGISTERED, param);
- return MOD_CONT;
- }
- if (na->status & NS_VERBOTEN) {
- notice_lang(s_ChanServ, u, NICK_X_FORBIDDEN, param);
- return MOD_CONT;
- }
- if (na->nc == ci->founder) {
- notice_lang(s_ChanServ, u, CHAN_SUCCESSOR_IS_FOUNDER, param,
- ci->name);
- return MOD_CONT;
- }
- nc = na->nc;
-
- } else {
- nc = NULL;
- }
-
- alog("%s: Changing successor of %s from %s to %s by %s!%s@%s",
- s_ChanServ, ci->name,
- (ci->successor ? ci->successor->display : "none"),
- (nc ? nc->display : "none"), u->nick, u->username, u->host);
-
- ci->successor = nc;
-
- if (nc)
- notice_lang(s_ChanServ, u, CHAN_SUCCESSOR_CHANGED, ci->name,
- param);
- else
- notice_lang(s_ChanServ, u, CHAN_SUCCESSOR_UNSET, ci->name);
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_password(User * u, ChannelInfo * ci, char *param)
-{
- int len = strlen(param);
-
- if (stricmp(u->nick, param) == 0 || (StrictPasswords && len < 5)) {
- notice_lang(s_ChanServ, u, MORE_OBSCURE_PASSWORD);
- return MOD_CONT;
- }
-#ifdef USE_ENCRYPTION
- if (len > PASSMAX) {
- len = PASSMAX;
- param[len] = 0;
- notice_lang(s_ChanServ, u, PASSWORD_TRUNCATED, PASSMAX);
- }
-
- if (encrypt(param, len, ci->founderpass, PASSMAX) < 0) {
- memset(param, 0, strlen(param));
- alog("%s: Failed to encrypt password for %s (set)", s_ChanServ,
- ci->name);
- notice_lang(s_ChanServ, u, CHAN_SET_PASSWORD_FAILED);
- return MOD_CONT;
- }
-
- memset(param, 0, strlen(param));
- notice_lang(s_ChanServ, u, CHAN_PASSWORD_CHANGED, ci->name);
-
-#else /* !USE_ENCRYPTION */
- if (strlen(param) > PASSMAX - 1) /* -1 for null byte */
- notice_lang(s_ChanServ, u, PASSWORD_TRUNCATED, PASSMAX - 1);
- strscpy(ci->founderpass, param, PASSMAX);
- notice_lang(s_ChanServ, u, CHAN_PASSWORD_CHANGED_TO, ci->name,
- ci->founderpass);
-#endif /* USE_ENCRYPTION */
-
- if (get_access(u, ci) < ACCESS_FOUNDER) {
- alog("%s: %s!%s@%s set password as Services admin for %s",
- s_ChanServ, u->nick, u->username, u->host, ci->name);
- if (WallSetpass)
- anope_cmd_global(s_ChanServ,
- "\2%s\2 set password as Services admin for channel \2%s\2",
- u->nick, ci->name);
- } else {
- alog("%s: %s!%s@%s changed password of %s (founder: %s)",
- s_ChanServ, u->nick, u->username, u->host,
- ci->name, ci->founder->display);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_desc(User * u, ChannelInfo * ci, char *param)
-{
- if (ci->desc)
- free(ci->desc);
- ci->desc = sstrdup(param);
- notice_lang(s_ChanServ, u, CHAN_DESC_CHANGED, ci->name, param);
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_url(User * u, ChannelInfo * ci, char *param)
-{
- if (ci->url)
- free(ci->url);
- if (param) {
- ci->url = sstrdup(param);
- notice_lang(s_ChanServ, u, CHAN_URL_CHANGED, ci->name, param);
- } else {
- ci->url = NULL;
- notice_lang(s_ChanServ, u, CHAN_URL_UNSET, ci->name);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_email(User * u, ChannelInfo * ci, char *param)
-{
- if (ci->email)
- free(ci->email);
- if (param) {
- ci->email = sstrdup(param);
- notice_lang(s_ChanServ, u, CHAN_EMAIL_CHANGED, ci->name, param);
- } else {
- ci->email = NULL;
- notice_lang(s_ChanServ, u, CHAN_EMAIL_UNSET, ci->name);
- }
- return MOD_CONT;
-}
-
/*************************************************************************/
-static int do_set_entrymsg(User * u, ChannelInfo * ci, char *param)
-{
- if (ci->entry_message)
- free(ci->entry_message);
- if (param) {
- ci->entry_message = sstrdup(param);
- notice_lang(s_ChanServ, u, CHAN_ENTRY_MSG_CHANGED, ci->name,
- param);
- } else {
- ci->entry_message = NULL;
- notice_lang(s_ChanServ, u, CHAN_ENTRY_MSG_UNSET, ci->name);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_mlock(User * u, ChannelInfo * ci, char *param)
-{
- int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
- unsigned char mode;
- CBMode *cbm;
-
- if (checkDefCon(DEFCON_NO_MLOCK_CHANGE)) {
- notice_lang(s_ChanServ, u, OPER_DEFCON_DENIED);
- return MOD_CONT;
- }
-
- /* Reinitialize everything */
- if (ircd->chanreg) {
- ci->mlock_on = ircd->regmode;
- } else {
- ci->mlock_on = 0;
- }
- ci->mlock_off = ci->mlock_limit = 0;
- ci->mlock_key = NULL;
- if (ircd->fmode) {
- ci->mlock_flood = NULL;
- }
- if (ircd->Lmode) {
- ci->mlock_redirect = NULL;
- }
-
- while ((mode = *param++)) {
- switch (mode) {
- case '+':
- add = 1;
- continue;
- case '-':
- add = 0;
- continue;
- default:
- if (add < 0)
- continue;
- }
-
- if ((int) mode < 128 && (cbm = &cbmodes[(int) mode])->flag != 0) {
- if ((cbm->flags & CBM_NO_MLOCK)
- || ((cbm->flags & CBM_NO_USER_MLOCK) && !is_oper(u))) {
- notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_IMPOSSIBLE_CHAR,
- mode);
- } else if (add) {
- ci->mlock_on |= cbm->flag;
- ci->mlock_off &= ~cbm->flag;
- if (cbm->cssetvalue)
- cbm->cssetvalue(ci, strtok(NULL, " "));
- } else {
- ci->mlock_off |= cbm->flag;
- if (ci->mlock_on & cbm->flag) {
- ci->mlock_on &= ~cbm->flag;
- if (cbm->cssetvalue)
- cbm->cssetvalue(ci, NULL);
- }
- }
- } else {
- notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_UNKNOWN_CHAR, mode);
- }
- } /* while (*param) */
-
- if (ircd->Lmode) {
- /* We can't mlock +L if +l is not mlocked as well. */
- if ((ci->mlock_on & ircd->chan_lmode) && !(ci->mlock_on & CMODE_l)) {
- ci->mlock_on &= ~ircd->chan_lmode;
- free(ci->mlock_redirect);
- notice_lang(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 (ircd->noknock && ircd->knock_needs_i) {
- if ((ci->mlock_on & ircd->noknock) && !(ci->mlock_on & CMODE_i)) {
- ci->mlock_on &= ~ircd->noknock;
- notice_lang(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(s_ChanServ, u, CHAN_MLOCK_CHANGED, ci->name,
- get_mlock_modes(ci, 0));
- }
-
- /* Implement the new lock. */
- if (ci->c)
- check_modes(ci->c);
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_bantype(User * u, ChannelInfo * ci, char *param)
-{
- char *endptr;
-
- int16 bantype = strtol(param, &endptr, 10);
-
- if (*endptr != 0 || bantype < 0 || bantype > 3) {
- notice_lang(s_ChanServ, u, CHAN_SET_BANTYPE_INVALID, param);
- } else {
- ci->bantype = bantype;
- notice_lang(s_ChanServ, u, CHAN_SET_BANTYPE_CHANGED, ci->name,
- ci->bantype);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_keeptopic(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_KEEPTOPIC;
- notice_lang(s_ChanServ, u, CHAN_SET_KEEPTOPIC_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_KEEPTOPIC;
- notice_lang(s_ChanServ, u, CHAN_SET_KEEPTOPIC_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET KEEPTOPIC",
- CHAN_SET_KEEPTOPIC_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_topiclock(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_TOPICLOCK;
- notice_lang(s_ChanServ, u, CHAN_SET_TOPICLOCK_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_TOPICLOCK;
- notice_lang(s_ChanServ, u, CHAN_SET_TOPICLOCK_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET TOPICLOCK",
- CHAN_SET_TOPICLOCK_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_private(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_PRIVATE;
- notice_lang(s_ChanServ, u, CHAN_SET_PRIVATE_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_PRIVATE;
- notice_lang(s_ChanServ, u, CHAN_SET_PRIVATE_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET PRIVATE",
- CHAN_SET_PRIVATE_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_secureops(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_SECUREOPS;
- notice_lang(s_ChanServ, u, CHAN_SET_SECUREOPS_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_SECUREOPS;
- notice_lang(s_ChanServ, u, CHAN_SET_SECUREOPS_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET SECUREOPS",
- CHAN_SET_SECUREOPS_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_securefounder(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_SECUREFOUNDER;
- notice_lang(s_ChanServ, u, CHAN_SET_SECUREFOUNDER_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_SECUREFOUNDER;
- notice_lang(s_ChanServ, u, CHAN_SET_SECUREFOUNDER_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET SECUREFOUNDER",
- CHAN_SET_SECUREFOUNDER_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_restricted(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_RESTRICTED;
- if (ci->levels[CA_NOJOIN] < 0)
- ci->levels[CA_NOJOIN] = 0;
- notice_lang(s_ChanServ, u, CHAN_SET_RESTRICTED_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_RESTRICTED;
- if (ci->levels[CA_NOJOIN] >= 0)
- ci->levels[CA_NOJOIN] = -2;
- notice_lang(s_ChanServ, u, CHAN_SET_RESTRICTED_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET RESTRICTED",
- CHAN_SET_RESTRICTED_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_secure(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_SECURE;
- notice_lang(s_ChanServ, u, CHAN_SET_SECURE_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_SECURE;
- notice_lang(s_ChanServ, u, CHAN_SET_SECURE_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET SECURE", CHAN_SET_SECURE_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_signkick(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_SIGNKICK;
- ci->flags &= ~CI_SIGNKICK_LEVEL;
- notice_lang(s_ChanServ, u, CHAN_SET_SIGNKICK_ON, ci->name);
- } else if (stricmp(param, "LEVEL") == 0) {
- ci->flags |= CI_SIGNKICK_LEVEL;
- ci->flags &= ~CI_SIGNKICK;
- notice_lang(s_ChanServ, u, CHAN_SET_SIGNKICK_LEVEL, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~(CI_SIGNKICK | CI_SIGNKICK_LEVEL);
- notice_lang(s_ChanServ, u, CHAN_SET_SIGNKICK_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET SIGNKICK",
- CHAN_SET_SIGNKICK_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_opnotice(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_OPNOTICE;
- notice_lang(s_ChanServ, u, CHAN_SET_OPNOTICE_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_OPNOTICE;
- notice_lang(s_ChanServ, u, CHAN_SET_OPNOTICE_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET OPNOTICE",
- CHAN_SET_OPNOTICE_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-#define CHECKLEV(lev) ((ci->levels[(lev)] != ACCESS_INVALID) && (access->level >= ci->levels[(lev)]))
-
-static int do_set_xop(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- if (!(ci->flags & CI_XOP)) {
- int i;
- ChanAccess *access;
-
- for (access = ci->access, i = 0; i < ci->accesscount;
- access++, 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 (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 (ircd->halfop) {
- if (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 {
- access->in_use = 0;
- access->nc = NULL;
- }
- }
-
- reset_levels(ci);
- ci->flags |= CI_XOP;
- }
-
- alog("%s: %s!%s@%s enabled XOP for %s", s_ChanServ, u->nick,
- u->username, u->host, ci->name);
- notice_lang(s_ChanServ, u, CHAN_SET_XOP_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_XOP;
-
- alog("%s: %s!%s@%s disabled XOP for %s", s_ChanServ, u->nick,
- u->username, u->host, ci->name);
- notice_lang(s_ChanServ, u, CHAN_SET_XOP_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET XOP", CHAN_SET_XOP_SYNTAX);
- }
- return MOD_CONT;
-}
-
-#undef CHECKLEV
-
-/*************************************************************************/
-
-static int do_set_peace(User * u, ChannelInfo * ci, char *param)
-{
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_PEACE;
- notice_lang(s_ChanServ, u, CHAN_SET_PEACE_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_PEACE;
- notice_lang(s_ChanServ, u, CHAN_SET_PEACE_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET PEACE", CHAN_SET_PEACE_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_set_noexpire(User * u, ChannelInfo * ci, char *param)
-{
- if (!is_services_admin(u)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- return MOD_CONT;
- }
- if (stricmp(param, "ON") == 0) {
- ci->flags |= CI_NO_EXPIRE;
- notice_lang(s_ChanServ, u, CHAN_SET_NOEXPIRE_ON, ci->name);
- } else if (stricmp(param, "OFF") == 0) {
- ci->flags &= ~CI_NO_EXPIRE;
- notice_lang(s_ChanServ, u, CHAN_SET_NOEXPIRE_OFF, ci->name);
- } else {
- syntax_error(s_ChanServ, u, "SET NOEXPIRE",
- CHAN_SET_NOEXPIRE_SYNTAX);
- }
- return MOD_CONT;
-}
/*************************************************************************/
@@ -3654,655 +2436,6 @@ static int do_set_noexpire(User * u, ChannelInfo * ci, char *param)
* `perm' is incremented whenever a permission-denied error occurs
*/
-static int xop_del(User * u, ChanAccess * access, int *perm, int uacc,
- int xlev)
-{
- if (!access->in_use || access->level != xlev)
- return 0;
- if (!is_services_admin(u) && uacc <= access->level) {
- (*perm)++;
- return 0;
- }
- access->nc = NULL;
- access->in_use = 0;
- return 1;
-}
-
-static 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->accesscount)
- return 0;
- *last = num;
-
- return xop_del(u, &ci->access[num - 1], perm, uacc, xlev);
-}
-
-
-static int xop_list(User * u, int index, ChannelInfo * ci,
- int *sent_header, int xlev, int xmsg)
-{
- ChanAccess *access = &ci->access[index];
-
- if (!access->in_use || access->level != xlev)
- return 0;
-
- if (!*sent_header) {
- notice_lang(s_ChanServ, u, xmsg, ci->name);
- *sent_header = 1;
- }
-
- notice_lang(s_ChanServ, u, CHAN_XOP_LIST_FORMAT, index + 1,
- access->nc->display);
- return 1;
-}
-
-static 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->accesscount)
- return 0;
-
- return xop_list(u, num - 1, ci, sent_header, xlev, xmsg);
-}
-
-
-static int do_xop(User * u, char *xname, int xlev, int *xmsgs)
-{
- char *chan = strtok(NULL, " ");
- char *cmd = strtok(NULL, " ");
- char *nick = strtok(NULL, " ");
-
- ChannelInfo *ci;
- NickAlias *na;
- NickCore *nc;
-
- int i;
- int change = 0;
- short ulev;
- int is_list = (cmd && stricmp(cmd, "LIST") == 0);
- int is_servadmin = is_services_admin(u);
- ChanAccess *access;
-
- /* If CLEAR, we don't need any parameters.
- * If LIST, we don't *require* any parameters, but we can take any.
- * If DEL or ADD we require a nick. */
- if (!cmd || ((is_list || !stricmp(cmd, "CLEAR")) ? 0 : !nick)) {
- syntax_error(s_ChanServ, u, xname, xmsgs[0]);
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!(ci->flags & CI_XOP)) {
- notice_lang(s_ChanServ, u, CHAN_XOP_ACCESS, s_ChanServ);
- } else if (stricmp(cmd, "ADD") == 0) {
- if (readonly) {
- notice_lang(s_ChanServ, u, xmsgs[1]);
- return MOD_CONT;
- }
-
- ulev = get_access(u, ci);
-
- if ((xlev >= ulev || ulev < ACCESS_AOP) && !is_servadmin) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- return MOD_CONT;
- }
-
- na = findnick(nick);
- if (!na) {
- notice_lang(s_ChanServ, u, xmsgs[2]);
- return MOD_CONT;
- } else if (na->status & NS_VERBOTEN) {
- notice_lang(s_ChanServ, u, NICK_X_FORBIDDEN, na->nick);
- return MOD_CONT;
- }
-
- nc = na->nc;
- for (access = ci->access, i = 0; i < ci->accesscount;
- access++, i++) {
- if (access->nc == nc) {
- /**
- * Patch provided by PopCorn to prevert AOP's reducing SOP's levels
- **/
- if ((access->level >= ulev) && (!is_servadmin)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- return MOD_CONT;
- }
- change++;
- break;
- }
- }
-
- if (!change) {
- for (i = 0; i < ci->accesscount; i++)
- if (!ci->access[i].in_use)
- break;
-
- if (i == ci->accesscount) {
- if (i < CSAccessMax) {
- ci->accesscount++;
- ci->access =
- srealloc(ci->access,
- sizeof(ChanAccess) * ci->accesscount);
- } else {
- notice_lang(s_ChanServ, u, CHAN_XOP_REACHED_LIMIT,
- CSAccessMax);
- return MOD_CONT;
- }
- }
-
- access = &ci->access[i];
- access->nc = nc;
- }
-
- access->in_use = 1;
- access->level = xlev;
- access->last_seen = 0;
-
- alog("%s: %s!%s@%s (level %d) %s access level %d to %s (group %s) on channel %s", s_ChanServ, u->nick, u->username, u->host, ulev, change ? "changed" : "set", access->level, na->nick, nc->display, ci->name);
-
- if (!change) {
- notice_lang(s_ChanServ, u, xmsgs[3], access->nc->display,
- ci->name);
- } else {
- notice_lang(s_ChanServ, u, xmsgs[4], access->nc->display,
- ci->name);
- }
-
- } else if (stricmp(cmd, "DEL") == 0) {
- int deleted, a, b;
- if (readonly) {
- notice_lang(s_ChanServ, u, xmsgs[1]);
- return MOD_CONT;
- }
-
- if (ci->accesscount == 0) {
- notice_lang(s_ChanServ, u, xmsgs[11], chan);
- return MOD_CONT;
- }
-
- ulev = get_access(u, ci);
-
- /* 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, xlev);
- if (!deleted) {
- if (perm) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else if (count == 1) {
- notice_lang(s_ChanServ, u, xmsgs[5], last, ci->name);
- } else {
- notice_lang(s_ChanServ, u, xmsgs[7], ci->name);
- }
- } else if (deleted == 1) {
- notice_lang(s_ChanServ, u, xmsgs[9], ci->name);
- } else {
- notice_lang(s_ChanServ, u, xmsgs[10], deleted, ci->name);
- }
- } else {
- na = findnick(nick);
- if (!na) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_REGISTERED, nick);
- return MOD_CONT;
- }
- nc = na->nc;
-
- for (i = 0; i < ci->accesscount; i++)
- if (ci->access[i].nc == nc && ci->access[i].level == xlev)
- break;
-
- if (i == ci->accesscount) {
- notice_lang(s_ChanServ, u, xmsgs[6], nick, chan);
- return MOD_CONT;
- }
-
- access = &ci->access[i];
- if (!is_servadmin && ulev <= access->level) {
- deleted = 0;
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else {
- notice_lang(s_ChanServ, u, xmsgs[8], access->nc->display,
- ci->name);
- access->nc = NULL;
- access->in_use = 0;
- deleted = 1;
- }
- }
- if (deleted) {
- /* Reordering - DrStein */
- for (b = 0; b < ci->accesscount; b++) {
- if (ci->access[b].in_use) {
- for (a = 0; a < ci->accesscount; a++) {
- if (a > b)
- break;
- if (!ci->access[a].in_use) {
- ci->access[a].in_use = 1;
- ci->access[a].level = ci->access[b].level;
- ci->access[a].nc = ci->access[b].nc;
- ci->access[a].last_seen =
- ci->access[b].last_seen;
- ci->access[b].nc = NULL;
- ci->access[b].in_use = 0;
- break;
- }
- }
- }
- }
- }
- } else if (stricmp(cmd, "LIST") == 0) {
- int sent_header = 0;
-
- ulev = get_access(u, ci);
-
- if (!is_servadmin && ulev < ACCESS_AOP) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- return MOD_CONT;
- }
-
- if (ci->accesscount == 0) {
- notice_lang(s_ChanServ, u, xmsgs[11], ci->name);
- return MOD_CONT;
- }
-
- if (nick && strspn(nick, "1234567890,-") == strlen(nick)) {
- process_numlist(nick, NULL, xop_list_callback, u, ci,
- &sent_header, xlev, xmsgs[12]);
- } else {
- for (i = 0; i < ci->accesscount; i++) {
- if (nick && ci->access[i].nc
- && !match_wild_nocase(nick, ci->access[i].nc->display))
- continue;
- xop_list(u, i, ci, &sent_header, xlev, xmsgs[12]);
- }
- }
- if (!sent_header)
- notice_lang(s_ChanServ, u, xmsgs[7], chan);
- } else if (stricmp(cmd, "CLEAR") == 0) {
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_DISABLED);
- return MOD_CONT;
- }
-
- if (ci->accesscount == 0) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan);
- return MOD_CONT;
- }
-
- if (!is_servadmin && !is_founder(u, ci)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- return MOD_CONT;
- }
-
- for (i = 0; i < ci->accesscount; i++) {
- if (ci->access[i].in_use && ci->access[i].level == xlev) {
- ci->access[i].nc = NULL;
- ci->access[i].in_use = 0;
- }
- }
-
- notice_lang(s_ChanServ, u, xmsgs[13], ci->name);
- } else {
- syntax_error(s_ChanServ, u, xname, xmsgs[0]);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_aop(User * u)
-{
- return do_xop(u, "AOP", ACCESS_AOP, xop_msgs[0]);
-}
-
-/*************************************************************************/
-
-static int do_hop(User * u)
-{
- return do_xop(u, "HOP", ACCESS_HOP, xop_msgs[3]);
-}
-
-/*************************************************************************/
-
-static int do_sop(User * u)
-{
- return do_xop(u, "SOP", ACCESS_SOP, xop_msgs[1]);
-}
-
-/*************************************************************************/
-
-static int do_vop(User * u)
-{
- return do_xop(u, "VOP", ACCESS_VOP, xop_msgs[2]);
-}
-
-/*************************************************************************/
-
-/* `last' is set to the last index this routine was called with
- * `perm' is incremented whenever a permission-denied error occurs
- */
-
-static int access_del(User * u, ChanAccess * access, int *perm, int uacc)
-{
- if (!access->in_use)
- return 0;
- if (!is_services_admin(u) && uacc <= access->level) {
- (*perm)++;
- return 0;
- }
- access->nc = NULL;
- access->in_use = 0;
- 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->accesscount)
- return 0;
- *last = num;
- return access_del(u, &ci->access[num - 1], perm, uacc);
-}
-
-
-static int access_list(User * u, int index, ChannelInfo * ci,
- int *sent_header)
-{
- ChanAccess *access = &ci->access[index];
- char *xop;
-
- if (!access->in_use)
- return 0;
-
- if (!*sent_header) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name);
- *sent_header = 1;
- }
-
- if (ci->flags & CI_XOP) {
- xop = get_xop_level(access->level);
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_XOP_FORMAT, index + 1,
- xop, access->nc->display);
- } else {
- notice_lang(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->accesscount)
- return 0;
- return access_list(u, num - 1, ci, sent_header);
-}
-
-
-static int do_access(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *cmd = strtok(NULL, " ");
- char *nick = strtok(NULL, " ");
- char *s = strtok(NULL, " ");
-
- ChannelInfo *ci;
- NickAlias *na;
- NickCore *nc;
- ChanAccess *access;
-
- int i;
- int level = 0, ulev;
- int is_list = (cmd && stricmp(cmd, "LIST") == 0);
- int is_servadmin = is_services_admin(u);
-
- /* 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 (!cmd || ((is_list || !stricmp(cmd, "CLEAR")) ? 0 :
- (stricmp(cmd, "DEL") == 0) ? (!nick || s) : !s)) {
- syntax_error(s_ChanServ, u, "ACCESS", CHAN_ACCESS_SYNTAX);
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- /* We still allow LIST in xOP mode, but not others */
- } else if ((ci->flags & CI_XOP) && !is_list) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_XOP, s_ChanServ);
- } else if (((is_list && !check_access(u, ci, CA_ACCESS_LIST))
- || (!is_list && !check_access(u, ci, CA_ACCESS_CHANGE)))
- && !is_servadmin) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else if (stricmp(cmd, "ADD") == 0) {
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_DISABLED);
- return MOD_CONT;
- }
-
- level = atoi(s);
- ulev = get_access(u, ci);
-
- if (!is_servadmin && level >= ulev) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- return MOD_CONT;
- }
-
- if (level == 0) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_NONZERO);
- return MOD_CONT;
- } else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_RANGE,
- ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
- return MOD_CONT;
- }
-
- na = findnick(nick);
- if (!na) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_NICKS_ONLY);
- return MOD_CONT;
- }
- if (na->status & NS_VERBOTEN) {
- notice_lang(s_ChanServ, u, NICK_X_FORBIDDEN, nick);
- return MOD_CONT;
- }
-
- nc = na->nc;
- for (access = ci->access, i = 0; i < ci->accesscount;
- access++, i++) {
- if (access->nc == nc) {
- /* Don't allow lowering from a level >= ulev */
- if (!is_servadmin && access->level >= ulev) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- return MOD_CONT;
- }
- if (access->level == level) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_UNCHANGED,
- access->nc->display, chan, level);
- return MOD_CONT;
- }
- access->level = level;
- alog("%s: %s!%s@%s (level %d) set access level %d to %s (group %s) on channel %s", s_ChanServ, u->nick, u->username, u->host, ulev, access->level, na->nick, nc->display, ci->name);
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_CHANGED,
- access->nc->display, chan, level);
- return MOD_CONT;
- }
- }
-
- for (i = 0; i < ci->accesscount; i++) {
- if (!ci->access[i].in_use)
- break;
- }
- if (i == ci->accesscount) {
- if (i < CSAccessMax) {
- ci->accesscount++;
- ci->access =
- srealloc(ci->access,
- sizeof(ChanAccess) * ci->accesscount);
- } else {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_REACHED_LIMIT,
- CSAccessMax);
- return MOD_CONT;
- }
- }
-
- access = &ci->access[i];
- access->nc = nc;
- access->in_use = 1;
- access->level = level;
- access->last_seen = 0;
-
- alog("%s: %s!%s@%s (level %d) set access level %d to %s (group %s) on channel %s", s_ChanServ, u->nick, u->username, u->host, ulev, access->level, na->nick, nc->display, ci->name);
- notice_lang(s_ChanServ, u, CHAN_ACCESS_ADDED, nc->display,
- ci->name, access->level);
- } else if (stricmp(cmd, "DEL") == 0) {
- int deleted, a, b;
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_DISABLED);
- return MOD_CONT;
- }
-
- if (ci->accesscount == 0) {
- notice_lang(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(s_ChanServ, u, PERMISSION_DENIED);
- } else if (count == 1) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_NO_SUCH_ENTRY,
- last, ci->name);
- } else {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_NO_MATCH,
- ci->name);
- }
- } else if (deleted == 1) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_DELETED_ONE,
- ci->name);
- } else {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_DELETED_SEVERAL,
- deleted, ci->name);
- }
- } else {
- na = findnick(nick);
- if (!na) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_REGISTERED, nick);
- return MOD_CONT;
- }
- nc = na->nc;
- for (i = 0; i < ci->accesscount; i++) {
- if (ci->access[i].nc == nc)
- break;
- }
- if (i == ci->accesscount) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_NOT_FOUND, nick,
- chan);
- return MOD_CONT;
- }
- access = &ci->access[i];
- if (!is_servadmin && get_access(u, ci) <= access->level) {
- deleted = 0;
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_DELETED,
- access->nc->display, ci->name);
- alog("%s: %s!%s@%s (level %d) deleted access of %s (group %s) on %s", s_ChanServ, u->nick, u->username, u->host, get_access(u, ci), na->nick, access->nc->display, chan);
- access->nc = NULL;
- access->in_use = 0;
- deleted = 1;
- }
- }
-
- if (deleted) {
- /* Reordering - DrStein */
- for (b = 0; b < ci->accesscount; b++) {
- if (ci->access[b].in_use) {
- for (a = 0; a < ci->accesscount; a++) {
- if (a > b)
- break;
- if (!ci->access[a].in_use) {
- ci->access[a].in_use = 1;
- ci->access[a].level = ci->access[b].level;
- ci->access[a].nc = ci->access[b].nc;
- ci->access[a].last_seen =
- ci->access[b].last_seen;
- ci->access[b].nc = NULL;
- ci->access[b].in_use = 0;
- break;
- }
- }
- }
- }
- }
- } else if (stricmp(cmd, "LIST") == 0) {
- int sent_header = 0;
-
- if (ci->accesscount == 0) {
- notice_lang(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->accesscount; i++) {
- if (nick && ci->access[i].nc
- && !match_wild_nocase(nick, ci->access[i].nc->display))
- continue;
- access_list(u, i, ci, &sent_header);
- }
- }
- if (!sent_header) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_NO_MATCH, chan);
- } else {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name);
- }
- } else if (stricmp(cmd, "CLEAR") == 0) {
-
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_DISABLED);
- return MOD_CONT;
- }
-
- if (!is_servadmin && !is_founder(u, ci)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- return MOD_CONT;
- }
-
- free(ci->access);
- ci->access = NULL;
- ci->accesscount = 0;
-
- notice_lang(s_ChanServ, u, CHAN_ACCESS_CLEAR, ci->name);
- alog("%s: %s!%s@%s (level %d) cleared access list on %s",
- s_ChanServ, u->nick, u->username, u->host,
- get_access(u, ci), chan);
-
- } else {
- syntax_error(s_ChanServ, u, "ACCESS", CHAN_ACCESS_SYNTAX);
- }
- return MOD_CONT;
-}
/*************************************************************************/
@@ -4392,2170 +2525,3 @@ void stick_all(ChannelInfo * ci)
free(av[0]);
}
}
-
-/* `last' is set to the last index this routine was called with */
-static int akick_del(User * u, AutoKick * akick)
-{
- if (!(akick->flags & AK_USED))
- return 0;
- if (akick->flags & AK_ISNICK) {
- akick->u.nc = NULL;
- } else {
- free(akick->u.mask);
- akick->u.mask = NULL;
- }
- if (akick->reason) {
- free(akick->reason);
- akick->reason = NULL;
- }
- if (akick->creator) {
- free(akick->creator);
- akick->creator = NULL;
- }
- akick->addtime = 0;
- akick->flags = 0;
- return 1;
-}
-
-static int akick_del_callback(User * u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *last = va_arg(args, int *);
- if (num < 1 || num > ci->akickcount)
- return 0;
- *last = num;
- return akick_del(u, &ci->akick[num - 1]);
-}
-
-
-static int akick_list(User * u, int index, ChannelInfo * ci,
- int *sent_header)
-{
- AutoKick *akick = &ci->akick[index];
-
- if (!(akick->flags & AK_USED))
- return 0;
- if (!*sent_header) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name);
- *sent_header = 1;
- }
-
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_FORMAT, index + 1,
- ((akick->flags & AK_ISNICK) ? akick->u.nc->
- display : akick->u.mask),
- (akick->reason ? akick->
- reason : getstring(u->na, NO_REASON)));
- return 1;
-}
-
-static 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->akickcount)
- return 0;
- return akick_list(u, num - 1, ci, sent_header);
-}
-
-static int akick_view(User * u, int index, ChannelInfo * ci,
- int *sent_header)
-{
- AutoKick *akick = &ci->akick[index];
- char timebuf[64];
- struct tm tm;
-
- if (!(akick->flags & AK_USED))
- return 0;
- if (!*sent_header) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name);
- *sent_header = 1;
- }
-
- if (akick->addtime) {
- tm = *localtime(&akick->addtime);
- strftime_lang(timebuf, sizeof(timebuf), u,
- STRFTIME_SHORT_DATE_FORMAT, &tm);
- } else {
- snprintf(timebuf, sizeof(timebuf), getstring(u->na, UNKNOWN));
- }
-
- notice_lang(s_ChanServ, u,
- ((akick->
- flags & AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK :
- CHAN_AKICK_VIEW_FORMAT), index + 1,
- ((akick->flags & AK_ISNICK) ? akick->u.nc->
- display : akick->u.mask),
- akick->creator ? akick->creator : getstring(u->na,
- UNKNOWN),
- timebuf,
- (akick->reason ? akick->
- reason : getstring(u->na, NO_REASON)));
- return 1;
-}
-
-static 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->akickcount)
- return 0;
- return akick_view(u, num - 1, ci, sent_header);
-}
-
-static int do_akick(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *cmd = strtok(NULL, " ");
- char *mask = strtok(NULL, " ");
- char *reason = strtok(NULL, "");
- ChannelInfo *ci;
- AutoKick *akick;
- int i;
- Channel *c;
- struct c_userlist *cu = NULL;
- struct c_userlist *next;
- char *argv[3];
- int count = 0;
-
- if (!cmd || (!mask && (!stricmp(cmd, "ADD") || !stricmp(cmd, "STICK")
- || !stricmp(cmd, "UNSTICK")
- || !stricmp(cmd, "DEL")))) {
-
- syntax_error(s_ChanServ, u, "AKICK", CHAN_AKICK_SYNTAX);
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!check_access(u, ci, CA_AKICK) && !is_services_admin(u)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else if (stricmp(cmd, "ADD") == 0) {
-
- NickAlias *na = findnick(mask);
- NickCore *nc = NULL;
- char *nick, *user, *host;
-
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
- return MOD_CONT;
- }
-
- if (!na) {
- split_usermask(mask, &nick, &user, &host);
- mask =
- scalloc(strlen(nick) + strlen(user) + strlen(host) + 3, 1);
- sprintf(mask, "%s!%s@%s", nick, user, host);
- free(nick);
- free(user);
- free(host);
- } else {
- if (na->status & NS_VERBOTEN) {
- notice_lang(s_ChanServ, u, NICK_X_FORBIDDEN, mask);
- return MOD_CONT;
- }
- nc = na->nc;
- }
-
- /* Check excepts BEFORE we get this far */
- if (ircd->except) {
- if (is_excepted_mask(ci, mask) == 1) {
- notice_lang(s_ChanServ, u, CHAN_EXCEPTED, mask, chan);
- return MOD_CONT;
- }
- }
-
- for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
- if (!(akick->flags & AK_USED))
- continue;
- if ((akick->flags & AK_ISNICK) ? akick->u.nc == nc
- : stricmp(akick->u.mask, mask) == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_ALREADY_EXISTS,
- (akick->flags & AK_ISNICK) ? akick->u.nc->
- display : akick->u.mask, chan);
- return MOD_CONT;
- }
- }
-
- for (i = 0; i < ci->akickcount; i++) {
- if (!(ci->akick[i].flags & AK_USED))
- break;
- }
- if (i == ci->akickcount) {
- if (ci->akickcount >= CSAutokickMax) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_REACHED_LIMIT,
- CSAutokickMax);
- return MOD_CONT;
- }
- ci->akickcount++;
- ci->akick =
- srealloc(ci->akick, sizeof(AutoKick) * ci->akickcount);
- }
- akick = &ci->akick[i];
- akick->flags = AK_USED;
- if (nc) {
- akick->flags |= AK_ISNICK;
- akick->u.nc = nc;
- } else {
- akick->u.mask = mask;
- }
- akick->creator = sstrdup(u->nick);
- akick->addtime = time(NULL);
- if (reason) {
- if (strlen(reason) > 200)
- reason[200] = '\0';
- akick->reason = sstrdup(reason);
- } else {
- akick->reason = NULL;
- }
-
- /* Auto ENFORCE #63 */
- c = findchan(ci->name);
- if (c) {
- cu = c->users;
- while (cu) {
- next = cu->next;
- if (check_kick(cu->user, c->name)) {
- argv[0] = sstrdup(c->name);
- argv[1] = sstrdup(cu->user->nick);
- if (akick->reason)
- argv[2] = sstrdup(akick->reason);
- else
- argv[2] = sstrdup("none");
-
- do_kick(s_ChanServ, 3, argv);
-
- free(argv[2]);
- free(argv[1]);
- free(argv[0]);
- count++;
-
- }
- cu = next;
- }
- }
- notice_lang(s_ChanServ, u, CHAN_AKICK_ADDED, mask, chan);
-
- if (count)
- notice_lang(s_ChanServ, u, CHAN_AKICK_ENFORCE_DONE, chan,
- count);
-
- } else if (stricmp(cmd, "STICK") == 0) {
- NickAlias *na;
- NickCore *nc;
-
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
- return MOD_CONT;
- }
-
- if (ci->akickcount == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
- return MOD_CONT;
- }
-
- na = findnick(mask);
- nc = (na ? na->nc : NULL);
-
- for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
- if (!(akick->flags & AK_USED) || (akick->flags & AK_ISNICK))
- continue;
- if (!stricmp(akick->u.mask, mask))
- break;
- }
-
- if (i == ci->akickcount) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask,
- ci->name);
- return MOD_CONT;
- }
-
- akick->flags |= AK_STUCK;
- notice_lang(s_ChanServ, u, CHAN_AKICK_STUCK, akick->u.mask,
- ci->name);
-
- if (ci->c)
- stick_mask(ci, akick);
- } else if (stricmp(cmd, "UNSTICK") == 0) {
- NickAlias *na;
- NickCore *nc;
-
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
- return MOD_CONT;
- }
-
- if (ci->akickcount == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
- return MOD_CONT;
- }
-
- na = findnick(mask);
- nc = (na ? na->nc : NULL);
-
- for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
- if (!(akick->flags & AK_USED) || (akick->flags & AK_ISNICK))
- continue;
- if (!stricmp(akick->u.mask, mask))
- break;
- }
-
- if (i == ci->akickcount) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask,
- ci->name);
- return MOD_CONT;
- }
-
- akick->flags &= ~AK_STUCK;
- notice_lang(s_ChanServ, u, CHAN_AKICK_UNSTUCK, akick->u.mask,
- ci->name);
-
- } else if (stricmp(cmd, "DEL") == 0) {
- int deleted, a, b;
-
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
- return MOD_CONT;
- }
-
- if (ci->akickcount == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, chan);
- return MOD_CONT;
- }
-
- /* Special case: is it a number/list? Only do search if it isn't. */
- if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
- int count, last = -1;
- deleted = process_numlist(mask, &count, akick_del_callback, u,
- ci, &last);
- if (!deleted) {
- if (count == 1) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_NO_SUCH_ENTRY,
- last, ci->name);
- } else {
- notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH,
- ci->name);
- }
- } else if (deleted == 1) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED_ONE,
- ci->name);
- } else {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED_SEVERAL,
- deleted, ci->name);
- }
- } else {
- NickAlias *na = findnick(mask);
- NickCore *nc = (na ? na->nc : NULL);
-
- for (akick = ci->akick, i = 0; i < ci->akickcount;
- akick++, i++) {
- if (!(akick->flags & AK_USED))
- continue;
- if (((akick->flags & AK_ISNICK) && akick->u.nc == nc)
- || (!(akick->flags & AK_ISNICK)
- && stricmp(akick->u.mask, mask) == 0))
- break;
- }
- if (i == ci->akickcount) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask,
- chan);
- return MOD_CONT;
- }
- notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED, mask, chan);
- akick_del(u, akick);
- deleted = 1;
- }
- if (deleted) {
- /* Reordering - DrStein */
- for (b = 0; b < ci->akickcount; b++) {
- if (ci->akick[b].flags & AK_USED) {
- for (a = 1; a < ci->akickcount; a++) {
- if (a > b)
- break;
- if (!(ci->akick[a].flags & AK_USED)) {
- ci->akick[a].flags = ci->akick[b].flags;
- if (ci->akick[b].flags & AK_ISNICK) {
- ci->akick[a].u.nc = ci->akick[b].u.nc;
- } else {
- ci->akick[a].u.mask =
- sstrdup(ci->akick[b].u.mask);
- }
- ci->akick[a].reason =
- sstrdup(ci->akick[b].reason);
- ci->akick[a].creator =
- sstrdup(ci->akick[b].creator);
- ci->akick[a].addtime = ci->akick[b].addtime;
-
- akick_del(u, &ci->akick[b]);
- break;
- }
- }
- }
- }
- }
- } else if (stricmp(cmd, "LIST") == 0) {
- int sent_header = 0;
-
- if (ci->akickcount == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, chan);
- return MOD_CONT;
- }
- if (mask && isdigit(*mask) &&
- strspn(mask, "1234567890,-") == strlen(mask)) {
- process_numlist(mask, NULL, akick_list_callback, u, ci,
- &sent_header);
- } else {
- for (akick = ci->akick, i = 0; i < ci->akickcount;
- akick++, i++) {
- if (!(akick->flags & AK_USED))
- continue;
- if (mask) {
- if (!(akick->flags & AK_ISNICK)
- && !match_wild_nocase(mask, akick->u.mask))
- continue;
- if ((akick->flags & AK_ISNICK)
- && !match_wild_nocase(mask, akick->u.nc->display))
- continue;
- }
- akick_list(u, i, ci, &sent_header);
- }
- }
- if (!sent_header)
- notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH, chan);
-
- } else if (stricmp(cmd, "VIEW") == 0) {
- int sent_header = 0;
-
- if (ci->akickcount == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, chan);
- return MOD_CONT;
- }
- if (mask && isdigit(*mask) &&
- strspn(mask, "1234567890,-") == strlen(mask)) {
- process_numlist(mask, NULL, akick_view_callback, u, ci,
- &sent_header);
- } else {
- for (akick = ci->akick, i = 0; i < ci->akickcount;
- akick++, i++) {
- if (!(akick->flags & AK_USED))
- continue;
- if (mask) {
- if (!(akick->flags & AK_ISNICK)
- && !match_wild_nocase(mask, akick->u.mask))
- continue;
- if ((akick->flags & AK_ISNICK)
- && !match_wild_nocase(mask, akick->u.nc->display))
- continue;
- }
- akick_view(u, i, ci, &sent_header);
- }
- }
- if (!sent_header)
- notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH, chan);
-
- } else if (stricmp(cmd, "ENFORCE") == 0) {
- Channel *c = findchan(ci->name);
- struct c_userlist *cu = NULL;
- struct c_userlist *next;
- char *argv[3];
- int count = 0;
-
- if (!c) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, ci->name);
- return MOD_CONT;
- }
-
- cu = c->users;
-
- while (cu) {
- next = cu->next;
- if (check_kick(cu->user, c->name)) {
- argv[0] = sstrdup(c->name);
- argv[1] = sstrdup(cu->user->nick);
- argv[2] = sstrdup(CSAutokickReason);
-
- do_kick(s_ChanServ, 3, argv);
-
- free(argv[2]);
- free(argv[1]);
- free(argv[0]);
-
- count++;
- }
- cu = next;
- }
-
- notice_lang(s_ChanServ, u, CHAN_AKICK_ENFORCE_DONE, chan, count);
-
- } else if (stricmp(cmd, "CLEAR") == 0) {
-
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
- return MOD_CONT;
- }
-
- for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
- if (!(akick->flags & AK_USED))
- continue;
- akick_del(u, akick);
- }
-
- free(ci->akick);
- ci->akick = NULL;
- ci->akickcount = 0;
-
- notice_lang(s_ChanServ, u, CHAN_AKICK_CLEAR, ci->name);
-
- } else {
- syntax_error(s_ChanServ, u, "AKICK", CHAN_AKICK_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_levels(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *cmd = strtok(NULL, " ");
- char *what = strtok(NULL, " ");
- char *s = strtok(NULL, " ");
- char *error;
-
- ChannelInfo *ci;
- 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
- || ((stricmp(cmd, "SET") == 0) ? !s
- : ((strnicmp(cmd, "DIS", 3) == 0)) ? (!what || s) : !!what)) {
- syntax_error(s_ChanServ, u, "LEVELS", CHAN_LEVELS_SYNTAX);
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (ci->flags & CI_XOP) {
- notice_lang(s_ChanServ, u, CHAN_LEVELS_XOP);
- } else if (!is_founder(u, ci) && !is_services_admin(u)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else if (stricmp(cmd, "SET") == 0) {
- level = strtol(s, &error, 10);
-
- if (*error != '\0') {
- syntax_error(s_ChanServ, u, "LEVELS", CHAN_LEVELS_SYNTAX);
- return MOD_CONT;
- }
-
- if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER) {
- notice_lang(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;
-
- alog("%s: %s!%s@%s set level %s on channel %s to %d",
- s_ChanServ, u->nick, u->username, u->host,
- levelinfo[i].name, ci->name, level);
- notice_lang(s_ChanServ, u, CHAN_LEVELS_CHANGED,
- levelinfo[i].name, chan, level);
- return MOD_CONT;
- }
- }
-
- notice_lang(s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what, s_ChanServ);
-
- } else if (stricmp(cmd, "DIS") == 0 || stricmp(cmd, "DISABLE") == 0) {
- for (i = 0; levelinfo[i].what >= 0; i++) {
- if (stricmp(levelinfo[i].name, what) == 0) {
- ci->levels[levelinfo[i].what] = ACCESS_INVALID;
-
- alog("%s: %s!%s@%s disabled level %s on channel %s",
- s_ChanServ, u->nick, u->username, u->host,
- levelinfo[i].name, ci->name);
- notice_lang(s_ChanServ, u, CHAN_LEVELS_DISABLED,
- levelinfo[i].name, chan);
- return MOD_CONT;
- }
- }
-
- notice_lang(s_ChanServ, u, CHAN_LEVELS_UNKNOWN, what, s_ChanServ);
- } else if (stricmp(cmd, "LIST") == 0) {
- int i;
-
- notice_lang(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(s_ChanServ, u, CHAN_LEVELS_LIST_DISABLED,
- levelinfo_maxwidth, levelinfo[i].name);
- } else {
- notice_lang(s_ChanServ, u, CHAN_LEVELS_LIST_DISABLED,
- levelinfo_maxwidth, levelinfo[i].name);
- }
- } else if (j == ACCESS_FOUNDER) {
- notice_lang(s_ChanServ, u, CHAN_LEVELS_LIST_FOUNDER,
- levelinfo_maxwidth, levelinfo[i].name);
- } else {
- notice_lang(s_ChanServ, u, CHAN_LEVELS_LIST_NORMAL,
- levelinfo_maxwidth, levelinfo[i].name, j);
- }
- }
-
- } else if (stricmp(cmd, "RESET") == 0) {
- reset_levels(ci);
-
- alog("%s: %s!%s@%s reset levels definitions on channel %s",
- s_ChanServ, u->nick, u->username, u->host, ci->name);
- notice_lang(s_ChanServ, u, CHAN_LEVELS_RESET, chan);
- } else {
- syntax_error(s_ChanServ, u, "LEVELS", CHAN_LEVELS_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-/* SADMINS and users, who have identified for a channel, can now cause it's
- * Enstry Message and Successor to be displayed by supplying the ALL parameter.
- * Syntax: INFO channel [ALL]
- * -TheShadow (29 Mar 1999)
- */
-
-static int do_info(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *param = strtok(NULL, " ");
- ChannelInfo *ci;
- char buf[BUFSIZE], *end;
- struct tm *tm;
- int need_comma = 0;
- const char *commastr = getstring(u->na, COMMA_SPACE);
- int is_servadmin = is_services_admin(u);
- int show_all = 0;
- time_t expt;
-
- if (!chan) {
- syntax_error(s_ChanServ, u, "INFO", CHAN_INFO_SYNTAX);
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- if (is_oper(u) && ci->forbidby)
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN_OPER, chan,
- ci->forbidby,
- (ci->forbidreason ? ci->
- forbidreason : getstring(u->na, NO_REASON)));
- else
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!ci->founder) {
- /* Paranoia... this shouldn't be able to happen */
- delchan(ci);
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else {
-
- /* Should we show all fields? Only for sadmins and identified users */
- if (param && stricmp(param, "ALL") == 0 &&
- (check_access(u, ci, CA_INFO) || is_servadmin))
- show_all = 1;
-
- notice_lang(s_ChanServ, u, CHAN_INFO_HEADER, chan);
- notice_lang(s_ChanServ, u, CHAN_INFO_NO_FOUNDER,
- ci->founder->display);
-
- if (show_all && ci->successor)
- notice_lang(s_ChanServ, u, CHAN_INFO_NO_SUCCESSOR,
- ci->successor->display);
-
- notice_lang(s_ChanServ, u, CHAN_INFO_DESCRIPTION, ci->desc);
- tm = localtime(&ci->time_registered);
- strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm);
- notice_lang(s_ChanServ, u, CHAN_INFO_TIME_REGGED, buf);
- tm = localtime(&ci->last_used);
- strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm);
- notice_lang(s_ChanServ, u, CHAN_INFO_LAST_USED, buf);
- if (ci->last_topic && (show_all || (!(ci->mlock_on & CMODE_s)
- && (!ci->c
- || !(ci->c->
- mode & CMODE_s))))) {
- notice_lang(s_ChanServ, u, CHAN_INFO_LAST_TOPIC,
- ci->last_topic);
- notice_lang(s_ChanServ, u, CHAN_INFO_TOPIC_SET_BY,
- ci->last_topic_setter);
- }
-
- if (ci->entry_message && show_all)
- notice_lang(s_ChanServ, u, CHAN_INFO_ENTRYMSG,
- ci->entry_message);
- if (ci->url)
- notice_lang(s_ChanServ, u, CHAN_INFO_URL, ci->url);
- if (ci->email)
- notice_lang(s_ChanServ, u, CHAN_INFO_EMAIL, ci->email);
-
- if (show_all) {
- notice_lang(s_ChanServ, u, CHAN_INFO_BANTYPE, ci->bantype);
-
- end = buf;
- *end = 0;
- if (ci->flags & CI_KEEPTOPIC) {
- end += snprintf(end, sizeof(buf) - (end - buf), "%s",
- getstring(u->na, CHAN_INFO_OPT_KEEPTOPIC));
- need_comma = 1;
- }
- if (ci->flags & CI_OPNOTICE) {
- end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
- need_comma ? commastr : "",
- getstring(u->na, CHAN_INFO_OPT_OPNOTICE));
- need_comma = 1;
- }
- if (ci->flags & CI_PEACE) {
- end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
- need_comma ? commastr : "",
- getstring(u->na, CHAN_INFO_OPT_PEACE));
- need_comma = 1;
- }
- if (ci->flags & CI_PRIVATE) {
- end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
- need_comma ? commastr : "",
- getstring(u->na, CHAN_INFO_OPT_PRIVATE));
- need_comma = 1;
- }
- if (ci->flags & CI_RESTRICTED) {
- end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
- need_comma ? commastr : "",
- getstring(u->na,
- CHAN_INFO_OPT_RESTRICTED));
- need_comma = 1;
- }
- if (ci->flags & CI_SECURE) {
- end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
- need_comma ? commastr : "",
- getstring(u->na, CHAN_INFO_OPT_SECURE));
- need_comma = 1;
- }
- if (ci->flags & CI_SECUREOPS) {
- end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
- need_comma ? commastr : "",
- getstring(u->na, CHAN_INFO_OPT_SECUREOPS));
- need_comma = 1;
- }
- if (ci->flags & CI_SECUREFOUNDER) {
- end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
- need_comma ? commastr : "",
- getstring(u->na,
- CHAN_INFO_OPT_SECUREFOUNDER));
- need_comma = 1;
- }
- if ((ci->flags & CI_SIGNKICK)
- || (ci->flags & CI_SIGNKICK_LEVEL)) {
- end +=
- snprintf(end, sizeof(buf) - (end - buf), "%s%s",
- need_comma ? commastr : "", getstring(u->na,
- CHAN_INFO_OPT_SIGNKICK));
- need_comma = 1;
- }
- if (ci->flags & CI_TOPICLOCK) {
- end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
- need_comma ? commastr : "",
- getstring(u->na, CHAN_INFO_OPT_TOPICLOCK));
- need_comma = 1;
- }
- if (ci->flags & CI_XOP) {
- end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
- need_comma ? commastr : "",
- getstring(u->na, CHAN_INFO_OPT_XOP));
- need_comma = 1;
- }
- notice_lang(s_ChanServ, u, CHAN_INFO_OPTIONS,
- *buf ? buf : getstring(u->na, CHAN_INFO_OPT_NONE));
- notice_lang(s_ChanServ, u, CHAN_INFO_MODE_LOCK,
- get_mlock_modes(ci, 1));
-
- }
- if (show_all) {
- if (ci->flags & CI_NO_EXPIRE) {
- notice_lang(s_ChanServ, u, CHAN_INFO_NO_EXPIRE);
- } else {
- if (is_servadmin) {
- expt = ci->last_used + CSExpire;
- tm = localtime(&expt);
- strftime_lang(buf, sizeof(buf), u,
- STRFTIME_DATE_TIME_FORMAT, tm);
- notice_lang(s_ChanServ, u, CHAN_INFO_EXPIRE, buf);
- }
- }
- }
- if (ci->flags & CI_SUSPENDED) {
- notice_lang(s_ChanServ, u, CHAN_X_SUSPENDED, ci->forbidby,
- (ci->forbidreason ? ci->
- forbidreason : getstring(u->na, NO_REASON)));
- }
-
- if (!show_all && (check_access(u, ci, CA_INFO) || is_servadmin))
- notice_lang(s_ChanServ, u, NICK_INFO_FOR_MORE, s_ChanServ,
- ci->name);
-
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_list(User * u)
-{
- char *pattern = strtok(NULL, " ");
- ChannelInfo *ci;
- int nchans, i;
- char buf[BUFSIZE];
- int is_servadmin = is_services_admin(u);
- int count = 0, from = 0, to = 0;
- char *tmp = NULL;
- char *s = NULL;
- char *keyword;
- int32 matchflags = 0;
-
-
- if (CSListOpersOnly && (!u || !is_oper(u))) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- return MOD_CONT;
- }
-
- if (!pattern) {
- syntax_error(s_ChanServ, u, "LIST",
- is_servadmin ? CHAN_LIST_SERVADMIN_SYNTAX :
- CHAN_LIST_SYNTAX);
- } else {
-
- if (pattern) {
- if (pattern[0] == '#') {
- tmp = myStrGetOnlyToken((pattern + 1), '-', 0); /* Read FROM out */
- if (!tmp) {
- return MOD_CONT;
- }
- for (s = tmp; *s; s++) {
- if (!isdigit(*s)) {
- return MOD_CONT;
- }
- }
- from = atoi(tmp);
- tmp = myStrGetTokenRemainder(pattern, '-', 1); /* Read TO out */
- if (!tmp) {
- return MOD_CONT;
- }
- for (s = tmp; *s; s++) {
- if (!isdigit(*s)) {
- return MOD_CONT;
- }
- }
- to = atoi(tmp);
- pattern = sstrdup("*");
- }
- }
-
- nchans = 0;
-
- while (is_servadmin && (keyword = strtok(NULL, " "))) {
- if (stricmp(keyword, "FORBIDDEN") == 0)
- matchflags |= CI_VERBOTEN;
- if (stricmp(keyword, "SUSPENDED") == 0)
- matchflags |= CI_SUSPENDED;
- if (stricmp(keyword, "NOEXPIRE") == 0)
- matchflags |= CI_NO_EXPIRE;
- }
-
- notice_lang(s_ChanServ, u, CHAN_LIST_HEADER, pattern);
- for (i = 0; i < 256; i++) {
- for (ci = chanlists[i]; ci; ci = ci->next) {
- if (!is_servadmin && ((ci->flags & CI_PRIVATE)
- || (ci->flags & CI_VERBOTEN)))
- continue;
- if ((matchflags != 0) && !(ci->flags & matchflags))
- continue;
-
- if (stricmp(pattern, ci->name) == 0
- || match_wild_nocase(pattern, ci->name)) {
- if ((((count + 1 >= from) && (count + 1 <= to))
- || ((from == 0) && (to == 0)))
- && (++nchans <= CSListMax)) {
- char noexpire_char = ' ';
- if (is_servadmin && (ci->flags & CI_NO_EXPIRE))
- noexpire_char = '!';
-
- if (ci->flags & CI_VERBOTEN) {
- snprintf(buf, sizeof(buf),
- "%-20s [Forbidden]", ci->name);
- } else if (ci->flags & CI_SUSPENDED) {
- snprintf(buf, sizeof(buf),
- "%-20s [Suspended]", ci->name);
- } else {
- snprintf(buf, sizeof(buf), "%-20s %s",
- ci->name, ci->desc ? ci->desc : "");
- }
-
- notice_user(s_ChanServ, u, " %c%s",
- noexpire_char, buf);
- }
- count++;
- }
- }
- }
- notice_lang(s_ChanServ, u, CHAN_LIST_END,
- nchans > CSListMax ? CSListMax : nchans, nchans);
- }
- return MOD_CONT;
-
-}
-
-/*************************************************************************/
-
-static int do_invite(User * u)
-{
- char *chan = strtok(NULL, " ");
- Channel *c;
- ChannelInfo *ci;
-
- if (!chan) {
- syntax_error(s_ChanServ, u, "INVITE", CHAN_INVITE_SYNTAX);
- } else if (!(c = findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
- } else if (!(ci = c->ci)) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!u || !check_access(u, ci, CA_INVITE)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else {
- anope_cmd_invite(whosends(ci), chan, u->nick);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-/* do_util: not a command, but does the job of other */
-
-static int do_util(User * u, CSModeUtil * util)
-{
- char *av[2];
- char *chan = strtok(NULL, " ");
- char *nick = strtok(NULL, " ");
-
- Channel *c;
- ChannelInfo *ci;
- User *u2;
-
- int is_same;
-
- if (!chan) {
- struct u_chanlist *uc;
-
- av[0] = util->mode;
- av[1] = u->nick;
-
- /* Sets the mode to the user on every channels he is on. */
-
- for (uc = u->chans; uc; uc = uc->next) {
- if ((ci = uc->chan->ci) && !(ci->flags & CI_VERBOTEN)
- && check_access(u, ci, util->levelself)) {
- anope_cmd_mode(whosends(ci), uc->chan->name, "%s %s",
- util->mode, u->nick);
- chan_set_modes(s_ChanServ, uc->chan, 2, av, 1);
-
- if (util->notice && ci->flags & util->notice)
- notice(whosends(ci), uc->chan->name,
- "%s command used for %s by %s", util->name,
- u->nick, u->nick);
- }
- }
-
- return MOD_CONT;
- } else if (!nick) {
- nick = u->nick;
- }
-
- is_same = (nick == u->nick) ? 1 : (stricmp(nick, u->nick) == 0);
-
- if (!(c = findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
- } else if (!(ci = c->ci)) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, c->name);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, ci->name);
- } else if (is_same ? !(u2 = u) : !(u2 = finduser(nick))) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_IN_USE, nick);
- } else if (!is_on_chan(c, u2)) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_ON_CHAN, u2->nick, c->name);
- } else if (is_same ? !check_access(u, ci, util->levelself) :
- !check_access(u, ci, util->level)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else if (*util->mode == '-' && !is_same && (ci->flags & CI_PEACE)
- && (get_access(u2, ci) >= get_access(u, ci))) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else if (*util->mode == '-' && is_protected(u2)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else {
- anope_cmd_mode(whosends(ci), c->name, "%s %s", util->mode,
- u2->nick);
-
- av[0] = util->mode;
- av[1] = u2->nick;
- chan_set_modes(s_ChanServ, c, 2, av, 1);
-
- if (util->notice && ci->flags & util->notice)
- notice(whosends(ci), c->name, "%s command used for %s by %s",
- util->name, u2->nick, u->nick);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_op(User * u)
-{
- return do_util(u, &csmodeutils[MUT_OP]);
-}
-
-/*************************************************************************/
-
-static int do_deop(User * u)
-{
- return do_util(u, &csmodeutils[MUT_DEOP]);
-}
-
-/*************************************************************************/
-
-static int do_voice(User * u)
-{
- return do_util(u, &csmodeutils[MUT_VOICE]);
-}
-
-/*************************************************************************/
-
-static int do_devoice(User * u)
-{
- return do_util(u, &csmodeutils[MUT_DEVOICE]);
-}
-
-/*************************************************************************/
-
-static int do_halfop(User * u)
-{
- if (ircd->halfop) {
- return do_util(u, &csmodeutils[MUT_HALFOP]);
- } else {
- return MOD_CONT;
- }
-}
-
-/*************************************************************************/
-
-static int do_dehalfop(User * u)
-{
- if (ircd->halfop) {
- return do_util(u, &csmodeutils[MUT_DEHALFOP]);
- } else {
- return MOD_CONT;
- }
-}
-
-/*************************************************************************/
-
-static int do_protect(User * u)
-{
- if (ircd->protect || ircd->admin) {
- return do_util(u, &csmodeutils[MUT_PROTECT]);
- } else {
- return MOD_CONT;
- }
-}
-
-/*************************************************************************/
-
-static int do_deprotect(User * u)
-{
- if (ircd->protect || ircd->admin) {
- return do_util(u, &csmodeutils[MUT_DEPROTECT]);
- } else {
- return MOD_CONT;
- }
-}
-
-/*************************************************************************/
-
-static int do_owner(User * u)
-{
- char *av[2];
- char *chan = strtok(NULL, " ");
-
- Channel *c;
- ChannelInfo *ci;
- struct u_chanlist *uc;
-
- if (!ircd->owner) {
- return MOD_CONT;
- }
-
- if (!chan) {
- av[0] = sstrdup(ircd->ownerset);
- av[1] = u->nick;
-
- /* Sets the mode to the user on every channels he is on. */
-
- for (uc = u->chans; uc; uc = uc->next) {
- if ((ci = uc->chan->ci) && !(ci->flags & CI_VERBOTEN)
- && is_founder(u, ci)) {
- anope_cmd_mode(whosends(ci), uc->chan->name, "%s %s",
- av[0], u->nick);
- chan_set_modes(s_ChanServ, uc->chan, 2, av, 1);
- }
- }
-
- free(av[0]);
- return MOD_CONT;
- }
-
- if (!(c = findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
- } else if (!(ci = c->ci)) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, c->name);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, ci->name);
- } else if (!is_on_chan(c, u)) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_ON_CHAN, u->nick, c->name);
- } else if (!is_founder(u, ci)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else {
- anope_cmd_mode(whosends(ci), c->name, "%s %s", ircd->ownerset,
- u->nick);
-
- av[0] = sstrdup(ircd->ownerset);
- av[1] = u->nick;
- chan_set_modes(s_ChanServ, c, 2, av, 1);
- free(av[0]);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_deowner(User * u)
-{
- char *av[2];
- char *chan = strtok(NULL, " ");
-
- Channel *c;
- ChannelInfo *ci;
- struct u_chanlist *uc;
-
- if (!ircd->owner) {
- return MOD_CONT;
- }
-
- if (!chan) {
- av[0] = sstrdup(ircd->ownerunset);
- av[1] = u->nick;
-
- /* Sets the mode to the user on every channels he is on. */
-
- for (uc = u->chans; uc; uc = uc->next) {
- if ((ci = uc->chan->ci) && !(ci->flags & CI_VERBOTEN)
- && is_founder(u, ci)) {
- anope_cmd_mode(whosends(ci), uc->chan->name, "%s %s",
- av[0], u->nick);
- chan_set_modes(s_ChanServ, uc->chan, 2, av, 1);
- }
- }
-
- free(av[0]);
- return MOD_CONT;
- }
-
- if (!(c = findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
- } else if (!(ci = c->ci)) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, c->name);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, ci->name);
- } else if (!is_on_chan(c, u)) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_ON_CHAN, u->nick, c->name);
- } else if (!is_founder(u, ci)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else {
- anope_cmd_mode(whosends(ci), c->name, "%s %s", ircd->ownerunset,
- u->nick);
-
- av[0] = sstrdup(ircd->ownerunset);
- av[1] = u->nick;
- chan_set_modes(s_ChanServ, c, 2, av, 1);
- free(av[0]);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_cs_kick(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *params = strtok(NULL, " ");
- char *reason = strtok(NULL, "");
-
- Channel *c;
- ChannelInfo *ci;
- User *u2;
-
- int is_same;
-
- if (!reason) {
- reason = "Requested";
- } else {
- if (strlen(reason) > 200)
- reason[200] = '\0';
- }
-
- if (!chan) {
- struct u_chanlist *uc, *next;
-
- /* Kicks the user on every channels he is on. */
-
- for (uc = u->chans; uc; uc = next) {
- next = uc->next;
- if ((ci = uc->chan->ci) && !(ci->flags & CI_VERBOTEN)
- && check_access(u, ci, CA_KICKME)) {
- char *av[3];
-
- if ((ci->flags & CI_SIGNKICK)
- || ((ci->flags & CI_SIGNKICK_LEVEL)
- && !check_access(u, ci, CA_SIGNKICK)))
- anope_cmd_kick(whosends(ci), ci->name, u->nick,
- "%s (%s)", reason, u->nick);
- else
- anope_cmd_kick(whosends(ci), ci->name, u->nick, "%s",
- reason);
- av[0] = ci->name;
- av[1] = u->nick;
- av[2] = reason;
- do_kick(s_ChanServ, 3, av);
- }
- }
-
- return MOD_CONT;
- } else if (!params) {
- params = u->nick;
- }
-
- is_same = (params == u->nick) ? 1 : (stricmp(params, u->nick) == 0);
-
- if (!(c = findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
- } else if (!(ci = c->ci)) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (is_same ? !(u2 = u) : !(u2 = finduser(params))) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_IN_USE, params);
- } else if (!is_on_chan(c, u2)) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_ON_CHAN, u2->nick, c->name);
- } else if (!is_same ? !check_access(u, ci, CA_KICK) :
- !check_access(u, ci, CA_KICKME)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else if (!is_same && (ci->flags & CI_PEACE)
- && (get_access(u2, ci) >= get_access(u, ci))) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else if (is_protected(u2)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else {
- char *av[3];
-
- if ((ci->flags & CI_SIGNKICK)
- || ((ci->flags & CI_SIGNKICK_LEVEL)
- && !check_access(u, ci, CA_SIGNKICK)))
- anope_cmd_kick(whosends(ci), ci->name, params, "%s (%s)",
- reason, u->nick);
- else
- anope_cmd_kick(whosends(ci), ci->name, params, "%s", reason);
- av[0] = ci->name;
- av[1] = params;
- av[2] = reason;
- do_kick(s_ChanServ, 3, av);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_ban(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *params = strtok(NULL, " ");
- char *reason = strtok(NULL, "");
-
- Channel *c;
- ChannelInfo *ci;
- User *u2;
-
- int is_same;
-
- if (!reason) {
- reason = "Requested";
- } else {
- if (strlen(reason) > 200)
- reason[200] = '\0';
- }
-
- if (!chan) {
- struct u_chanlist *uc, *next;
-
- /* Bans the user on every channels he is on. */
-
- for (uc = u->chans; uc; uc = next) {
- next = uc->next;
- if ((ci = uc->chan->ci) && !(ci->flags & CI_VERBOTEN)
- && check_access(u, ci, CA_BANME)) {
- char *av[3];
- char mask[BUFSIZE];
-
- /*
- * Dont ban/kick the user on channels where he is excepted
- * to prevent services <-> server wars.
- */
- if (ircd->except) {
- if (is_excepted(ci, u))
- notice_lang(s_ChanServ, u, CHAN_EXCEPTED,
- u->nick, ci->name);
- continue;
- }
- if (is_protected(u)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- continue;
- }
-
- av[0] = sstrdup("+b");
- get_idealban(ci, u, mask, sizeof(mask));
- av[1] = mask;
- anope_cmd_mode(whosends(ci), uc->chan->name, "+b %s",
- av[1]);
- chan_set_modes(s_ChanServ, uc->chan, 2, av, 1);
- free(av[0]);
-
- if ((ci->flags & CI_SIGNKICK)
- || ((ci->flags & CI_SIGNKICK_LEVEL)
- && !check_access(u, ci, CA_SIGNKICK)))
- anope_cmd_kick(whosends(ci), ci->name, u->nick,
- "%s (%s)", reason, u->nick);
- else
- anope_cmd_kick(whosends(ci), ci->name, u->nick, "%s",
- reason);
- av[0] = ci->name;
- av[1] = u->nick;
- av[2] = reason;
- do_kick(s_ChanServ, 3, av);
- }
- }
-
- return MOD_CONT;
- } else if (!params) {
- params = u->nick;
- }
-
- is_same = (params == u->nick) ? 1 : (stricmp(params, u->nick) == 0);
-
- if (!(c = findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
- } else if (!(ci = c->ci)) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (is_same ? !(u2 = u) : !(u2 = finduser(params))) {
- notice_lang(s_ChanServ, u, NICK_X_NOT_IN_USE, params);
- } else if (!is_same ? !check_access(u, ci, CA_BAN) :
- !check_access(u, ci, CA_BANME)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else if (!is_same && (ci->flags & CI_PEACE)
- && (get_access(u2, ci) >= get_access(u, ci))) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- /*
- * Dont ban/kick the user on channels where he is excepted
- * to prevent services <-> server wars.
- */
- } else if (ircd->except && is_excepted(ci, u2)) {
- notice_lang(s_ChanServ, u, CHAN_EXCEPTED, u2->nick, ci->name);
- } else if (ircd->protectedumode && is_protected(u2)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else {
- char *av[3];
- char mask[BUFSIZE];
-
- av[0] = sstrdup("+b");
- get_idealban(ci, u2, mask, sizeof(mask));
- av[1] = mask;
- anope_cmd_mode(whosends(ci), c->name, "+b %s", av[1]);
- chan_set_modes(s_ChanServ, c, 2, av, 1);
- free(av[0]);
-
- /* We still allow host banning while not allowing to kick */
- if (!is_on_chan(c, u2))
- return MOD_CONT;
-
- if ((ci->flags & CI_SIGNKICK)
- || ((ci->flags & CI_SIGNKICK_LEVEL)
- && !check_access(u, ci, CA_SIGNKICK)))
- anope_cmd_kick(whosends(ci), ci->name, params, "%s (%s)",
- reason, u->nick);
- else
- anope_cmd_kick(whosends(ci), ci->name, params, "%s", reason);
-
- av[0] = ci->name;
- av[1] = params;
- av[2] = reason;
- do_kick(s_ChanServ, 3, av);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_cs_topic(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *topic = strtok(NULL, "");
-
- Channel *c;
- ChannelInfo *ci;
-
- if (!chan) {
- syntax_error(s_ChanServ, u, "TOPIC", CHAN_TOPIC_SYNTAX);
- } else if (!(c = findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
- } else if (!(ci = c->ci)) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, c->name);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, ci->name);
- } else if (!is_services_admin(u) && !check_access(u, ci, CA_TOPIC)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else {
- if (ci->last_topic)
- free(ci->last_topic);
- ci->last_topic = topic ? sstrdup(topic) : NULL;
- strscpy(ci->last_topic_setter, u->nick, NICKMAX);
- ci->last_topic_time = time(NULL);
-
- if (c->topic)
- free(c->topic);
- c->topic = topic ? sstrdup(topic) : NULL;
- strscpy(c->topic_setter, u->nick, NICKMAX);
- if (ircd->topictsbackward) {
- c->topic_time = c->topic_time - 1;
- } else {
- c->topic_time = ci->last_topic_time;
- }
-
- if (is_services_admin(u) && !check_access(u, ci, CA_TOPIC))
- alog("%s: %s!%s@%s changed topic of %s as services admin.",
- s_ChanServ, u->nick, u->username, u->host, c->name);
- if (ircd->join2set) {
- if (whosends(ci) == s_ChanServ) {
- anope_cmd_join(s_ChanServ, c->name, time(NULL));
- anope_cmd_mode(NULL, c->name, "+o %s", s_ChanServ);
- }
- }
- anope_cmd_topic(whosends(ci), c->name, u->nick, topic ? topic : "",
- c->topic_time);
- if (ircd->join2set) {
- if (whosends(ci) == s_ChanServ) {
- anope_cmd_part(s_ChanServ, c->name, NULL);
- }
- }
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_unban(User * u)
-{
- char *chan = strtok(NULL, " ");
- Channel *c;
- ChannelInfo *ci;
-
- if (!chan) {
- syntax_error(s_ChanServ, u, "UNBAN", CHAN_UNBAN_SYNTAX);
- } else if (!(c = findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
- } else if (!(ci = c->ci)) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!check_access(u, ci, CA_UNBAN)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else {
- common_unban(ci, u->nick);
- notice_lang(s_ChanServ, u, CHAN_UNBANNED, chan);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_clear(User * u)
-{
- char *chan = strtok(NULL, " ");
- char *what = strtok(NULL, " ");
- char tmp[BUFSIZE];
- Channel *c;
- ChannelInfo *ci;
-
- if (!what) {
- syntax_error(s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX);
- } else if (!(c = findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
- } else if (!(ci = c->ci)) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!u || !check_access(u, ci, CA_CLEAR)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else if (stricmp(what, "bans") == 0) {
- char *av[2];
- int i;
-
- /* Save original ban info */
- int count = c->bancount;
- char **bans = scalloc(sizeof(char *) * count, 1);
- for (i = 0; i < count; i++)
- bans[i] = sstrdup(c->bans[i]);
-
- for (i = 0; i < count; i++) {
- av[0] = sstrdup("-b");
- av[1] = bans[i];
- anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]);
- chan_set_modes(whosends(ci), c, 2, av, 0);
- free(av[1]);
- free(av[0]);
- }
- notice_lang(s_ChanServ, u, CHAN_CLEARED_BANS, chan);
- free(bans);
- } else if (ircd->except && stricmp(what, "excepts") == 0) {
- char *av[2];
- int i;
-
- /* Save original except info */
- int count = c->exceptcount;
- char **excepts = scalloc(sizeof(char *) * count, 1);
- for (i = 0; i < count; i++)
- excepts[i] = sstrdup(c->excepts[i]);
-
- for (i = 0; i < count; i++) {
- av[0] = sstrdup("-e");
- av[1] = excepts[i];
- anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]);
- chan_set_modes(whosends(ci), c, 2, av, 0);
- free(av[1]);
- free(av[0]);
- }
- notice_lang(s_ChanServ, u, CHAN_CLEARED_EXCEPTS, chan);
- free(excepts);
-
- } else if (ircd->invitemode && stricmp(what, "invites") == 0) {
- char *av[2];
- int i;
-
- /* Save original except info */
- int count = c->invitecount;
- char **invites = scalloc(sizeof(char *) * count, 1);
- for (i = 0; i < count; i++)
- invites[i] = sstrdup(c->invite[i]);
-
- for (i = 0; i < count; i++) {
- av[0] = sstrdup("-I");
- av[1] = invites[i];
- anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]);
- chan_set_modes(whosends(ci), c, 2, av, 0);
- free(av[1]);
- free(av[0]);
- }
- notice_lang(s_ChanServ, u, CHAN_CLEARED_INVITES, chan);
- free(invites);
-
- } else if (stricmp(what, "modes") == 0) {
- char buf[BUFSIZE], *end = buf;
- char *argv[2];
-
- if (c->mode) {
- /* Clear modes the bulk of the modes */
- anope_cmd_mode(whosends(ci), c->name, "%s",
- ircd->modestoremove);
- argv[0] = sstrdup(ircd->modestoremove);
- chan_set_modes(whosends(ci), c, 1, argv, 0);
- free(argv[0]);
-
- /* to prevent the internals from complaining send -k, -L, -f by themselves if we need
- to send them - TSL */
- if (c->key) {
- anope_cmd_mode(whosends(ci), c->name, "-k %s", c->key);
- argv[0] = sstrdup("-k");
- argv[1] = c->key;
- chan_set_modes(whosends(ci), c, 2, argv, 0);
- free(argv[0]);
- }
- if (ircd->Lmode && c->redirect) {
- anope_cmd_mode(whosends(ci), c->name, "-L %s",
- c->redirect);
- argv[0] = sstrdup("-L");
- argv[1] = c->redirect;
- chan_set_modes(whosends(ci), c, 2, argv, 0);
- free(argv[0]);
- }
- if (ircd->fmode && c->flood) {
- if (flood_mode_char_remove) {
- anope_cmd_mode(whosends(ci), c->name, "%s %s",
- flood_mode_char_remove, c->flood);
- argv[0] = sstrdup(flood_mode_char_remove);
- argv[1] = c->flood;
- chan_set_modes(whosends(ci), c, 2, argv, 0);
- free(argv[0]);
- } else {
- if (debug) {
- alog("debug: flood_mode_char_remove was not set unable to remove flood/throttle modes");
- }
- }
- }
- check_modes(c);
- }
-
-
-
- /* TODO: decide if the above implementation is better than this one. */
-
- if (0) {
- CBModeInfo *cbmi = cbmodeinfos;
- CBMode *cbm;
-
- do {
- if (c->mode & cbmi->flag)
- *end++ = cbmi->mode;
- } while ((++cbmi)->flag != 0);
-
- cbmi = cbmodeinfos;
-
- do {
- if (cbmi->getvalue && (c->mode & cbmi->flag)
- && !(cbmi->flags & CBM_MINUS_NO_ARG)) {
- char *value = cbmi->getvalue(c);
-
- if (value) {
- *end++ = ' ';
- while (*value)
- *end++ = *value++;
-
- /* Free the value */
- cbm = &cbmodes[(int) cbmi->mode];
- cbm->setvalue(c, NULL);
- }
- }
- } while ((++cbmi)->flag != 0);
-
- *end = 0;
-
- anope_cmd_mode(whosends(ci), c->name, "-%s", buf);
- c->mode = 0;
- check_modes(c);
- }
- notice_lang(s_ChanServ, u, CHAN_CLEARED_MODES, chan);
- } else if (stricmp(what, "ops") == 0) {
- char *av[3];
- struct c_userlist *cu, *next;
-
- if (ircd->svsmode_ucmode) {
- av[0] = sstrdup(chan);
- anope_cmd_svsmode_chan(av[0], "-o", NULL);
- if (ircd->owner) {
- anope_cmd_svsmode_chan(av[0], ircd->ownerunset, NULL);
- }
- if (ircd->protect || ircd->admin) {
- anope_cmd_svsmode_chan(av[0], ircd->adminunset, NULL);
- }
- for (cu = c->users; cu; cu = next) {
- next = cu->next;
- av[0] = sstrdup(chan);
- if (!chan_has_user_status(c, cu->user, CUS_OP)) {
- if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) {
- if (!chan_has_user_status(c, cu->user, CUS_OWNER)) {
- continue;
- } else {
- snprintf(tmp, BUFSIZE, "%so",
- ircd->ownerunset);
- av[1] = sstrdup(tmp);
-
- }
- } else {
- snprintf(tmp, BUFSIZE, "%so", ircd->adminunset);
- av[1] = sstrdup(tmp);
- }
- } else {
- av[1] = sstrdup("-o");
- }
- av[2] = sstrdup(cu->user->nick);
- do_cmode(s_ChanServ, 3, av);
- free(av[2]);
- free(av[1]);
- free(av[0]);
- }
- } else {
- for (cu = c->users; cu; cu = next) {
- next = cu->next;
- av[0] = sstrdup(chan);
- if (!chan_has_user_status(c, cu->user, CUS_OP)) {
- if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) {
- if (!chan_has_user_status(c, cu->user, CUS_OWNER)) {
- continue;
- } else {
- snprintf(tmp, BUFSIZE, "%so",
- ircd->ownerunset);
- av[1] = sstrdup(tmp);
- }
- } else {
- snprintf(tmp, BUFSIZE, "%so", ircd->adminunset);
- av[1] = sstrdup(tmp);
- }
- } else {
- av[1] = sstrdup("-o");
- }
- av[2] = sstrdup(cu->user->nick);
- anope_cmd_mode(whosends(ci), av[0], "%s :%s", av[1],
- av[2]);
- do_cmode(s_ChanServ, 3, av);
- free(av[2]);
- free(av[1]);
- free(av[0]);
- }
- }
- notice_lang(s_ChanServ, u, CHAN_CLEARED_OPS, chan);
- } else if (ircd->halfop && stricmp(what, "hops") == 0) {
- char *av[3];
- struct c_userlist *cu, *next;
-
- for (cu = c->users; cu; cu = next) {
- next = cu->next;
- if (!chan_has_user_status(c, cu->user, CUS_HALFOP))
- continue;
- av[0] = sstrdup(chan);
- av[1] = sstrdup("-h");
- av[2] = sstrdup(cu->user->nick);
- if (ircd->svsmode_ucmode) {
- anope_cmd_svsmode_chan(av[0], av[1], NULL);
- do_cmode(s_ChanServ, 3, av);
- break;
- } else {
- anope_cmd_mode(whosends(ci), av[0], "%s :%s", av[1],
- av[2]);
- }
- do_cmode(s_ChanServ, 3, av);
- free(av[2]);
- free(av[1]);
- free(av[0]);
- }
- notice_lang(s_ChanServ, u, CHAN_CLEARED_HOPS, chan);
- } else if (stricmp(what, "voices") == 0) {
- char *av[3];
- struct c_userlist *cu, *next;
-
- for (cu = c->users; cu; cu = next) {
- next = cu->next;
- if (!chan_has_user_status(c, cu->user, CUS_VOICE))
- continue;
- av[0] = sstrdup(chan);
- av[1] = sstrdup("-v");
- av[2] = sstrdup(cu->user->nick);
- if (ircd->svsmode_ucmode) {
- anope_cmd_svsmode_chan(av[0], av[1], NULL);
- do_cmode(s_ChanServ, 3, av);
- break;
- } else {
- anope_cmd_mode(whosends(ci), av[0], "%s :%s", av[1],
- av[2]);
- }
- do_cmode(s_ChanServ, 3, av);
- free(av[2]);
- free(av[1]);
- free(av[0]);
- }
- notice_lang(s_ChanServ, u, CHAN_CLEARED_VOICES, chan);
- } else if (stricmp(what, "users") == 0) {
- char *av[3];
- struct c_userlist *cu, *next;
- char buf[256];
-
- snprintf(buf, sizeof(buf), "CLEAR USERS command from %s", u->nick);
-
- for (cu = c->users; cu; cu = next) {
- next = cu->next;
- av[0] = sstrdup(chan);
- av[1] = sstrdup(cu->user->nick);
- av[2] = sstrdup(buf);
- anope_cmd_kick(whosends(ci), av[0], av[1], av[2]);
- do_kick(s_ChanServ, 3, av);
- free(av[2]);
- free(av[1]);
- free(av[0]);
- }
- notice_lang(s_ChanServ, u, CHAN_CLEARED_USERS, chan);
- } else {
- syntax_error(s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_getkey(User * u)
-{
- char *chan = strtok(NULL, " ");
- ChannelInfo *ci;
-
- if (!chan) {
- syntax_error(s_ChanServ, u, "GETKEY", CHAN_GETKEY_SYNTAX);
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (!check_access(u, ci, CA_GETKEY)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else if (!ci->c || !ci->c->key) {
- notice_lang(s_ChanServ, u, CHAN_GETKEY_NOKEY, chan);
- } else {
- notice_lang(s_ChanServ, u, CHAN_GETKEY_KEY, chan, ci->c->key);
- }
-
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_getpass(User * u)
-{
-#ifndef USE_ENCRYPTION
- char *chan = strtok(NULL, " ");
- ChannelInfo *ci;
-#endif
-
- /* Assumes that permission checking has already been done. */
-#ifdef USE_ENCRYPTION
- notice_lang(s_ChanServ, u, CHAN_GETPASS_UNAVAILABLE);
-#else
- if (!chan) {
- syntax_error(s_ChanServ, u, "GETPASS", CHAN_GETPASS_SYNTAX);
- } else if (!(ci = cs_findchan(chan))) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else if (CSRestrictGetPass && !is_services_root(u)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else {
- alog("%s: %s!%s@%s used GETPASS on %s",
- s_ChanServ, u->nick, u->username, u->host, ci->name);
- if (WallGetpass) {
- anope_cmd_global(s_ChanServ,
- "\2%s\2 used GETPASS on channel \2%s\2",
- u->nick, chan);
- }
- notice_lang(s_ChanServ, u, CHAN_GETPASS_PASSWORD_IS,
- chan, ci->founderpass);
- }
-#endif
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_sendpass(User * u)
-{
-#ifndef USE_ENCRYPTION
- char *chan = strtok(NULL, " ");
- ChannelInfo *ci;
- NickCore *founder;
-#endif
-
-#ifdef USE_ENCRYPTION
- notice_lang(s_ChanServ, u, CHAN_SENDPASS_UNAVAILABLE);
-#else
- if (!chan) {
- syntax_error(s_ChanServ, u, "SENDPASS", CHAN_SENDPASS_SYNTAX);
- } else if (RestrictMail && !is_oper(u)) {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- } else if (!(ci = cs_findchan(chan)) || !(founder = ci->founder)) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- } else {
- char buf[BUFSIZE];
- MailInfo *mail;
-
- snprintf(buf, sizeof(buf),
- getstring2(founder, CHAN_SENDPASS_SUBJECT), ci->name);
- mail = MailBegin(u, founder, buf, s_ChanServ);
- if (!mail)
- return MOD_CONT;
-
- fprintf(mail->pipe, getstring2(founder, CHAN_SENDPASS_HEAD));
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring2(founder, CHAN_SENDPASS_LINE_1),
- ci->name);
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring2(founder, CHAN_SENDPASS_LINE_2),
- ci->founderpass);
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring2(founder, CHAN_SENDPASS_LINE_3));
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring2(founder, CHAN_SENDPASS_LINE_4));
- fprintf(mail->pipe, "\n\n");
- fprintf(mail->pipe, getstring2(founder, CHAN_SENDPASS_LINE_5),
- NetworkName);
- fprintf(mail->pipe, "\n.\n");
-
- MailEnd(mail);
-
- alog("%s: %s!%s@%s used SENDPASS on %s", s_ChanServ, u->nick,
- u->username, u->host, chan);
- notice_lang(s_ChanServ, u, CHAN_SENDPASS_OK, chan);
- }
-#endif
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_forbid(User * u)
-{
- ChannelInfo *ci;
- char *chan = strtok(NULL, " ");
- char *reason = strtok(NULL, "");
-
- Channel *c;
-
- /* Assumes that permission checking has already been done. */
- if (!chan || (ForceForbidReason && !reason)) {
- syntax_error(s_ChanServ, u, "FORBID",
- (ForceForbidReason ? CHAN_FORBID_SYNTAX_REASON :
- CHAN_FORBID_SYNTAX));
- return MOD_CONT;
- }
- if (readonly)
- notice_lang(s_ChanServ, u, READ_ONLY_MODE);
- if ((ci = cs_findchan(chan)) != NULL)
- delchan(ci);
- ci = makechan(chan);
- if (ci) {
- ci->flags |= CI_VERBOTEN;
- ci->forbidby = sstrdup(u->nick);
- if (reason)
- ci->forbidreason = sstrdup(reason);
-
- if ((c = findchan(ci->name))) {
- struct c_userlist *cu, *next;
- char *av[3];
-
- for (cu = c->users; cu; cu = next) {
- next = cu->next;
-
- if (is_oper(cu->user))
- continue;
-
- av[0] = c->name;
- av[1] = cu->user->nick;
- av[2] = reason ? reason : "CHAN_FORBID_REASON";
- anope_cmd_kick(s_ChanServ, av[0], av[1], av[2]);
- do_kick(s_ChanServ, 3, av);
- }
- }
-
- if (WallForbid)
- anope_cmd_global(s_ChanServ,
- "\2%s\2 used FORBID on channel \2%s\2",
- u->nick, ci->name);
-
- if (ircd->chansqline) {
- anope_cmd_sqline(ci->name, ((reason) ? reason : "Forbidden"));
- }
-
- alog("%s: %s set FORBID for channel %s", s_ChanServ, u->nick,
- ci->name);
- notice_lang(s_ChanServ, u, CHAN_FORBID_SUCCEEDED, chan);
- send_event(EVENT_CHAN_FORBIDDEN, chan);
- } else {
- alog("%s: Valid FORBID for %s by %s failed", s_ChanServ, ci->name,
- u->nick);
- notice_lang(s_ChanServ, u, CHAN_FORBID_FAILED, chan);
- }
- return MOD_CONT;
-}
-
- /*************************************************************************/
-
-static int do_suspend(User * u)
-{
- ChannelInfo *ci;
- char *chan = strtok(NULL, " ");
- char *reason = strtok(NULL, "");
-
- Channel *c;
-
- /* Assumes that permission checking has already been done. */
- if (!chan || (ForceForbidReason && !reason)) {
- syntax_error(s_ChanServ, u, "SUSPEND",
- (ForceForbidReason ? CHAN_SUSPEND_SYNTAX_REASON :
- CHAN_SUSPEND_SYNTAX));
- return MOD_CONT;
- }
-
- /* Only SUSPEND existing channels, otherwise use FORBID (bug #54) */
- if ((ci = cs_findchan(chan)) == NULL) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- return MOD_CONT;
- }
-
- /* You should not SUSPEND a FORBIDEN channel */
- if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan);
- return MOD_CONT;
- }
-
- if (readonly)
- notice_lang(s_ChanServ, u, READ_ONLY_MODE);
-
- if (ci) {
- ci->flags |= CI_SUSPENDED;
- ci->forbidby = sstrdup(u->nick);
- if (reason)
- ci->forbidreason = sstrdup(reason);
-
- if ((c = findchan(ci->name))) {
- struct c_userlist *cu, *next;
- char *av[3];
-
- for (cu = c->users; cu; cu = next) {
- next = cu->next;
-
- if (is_oper(cu->user))
- continue;
-
- av[0] = c->name;
- av[1] = cu->user->nick;
- av[2] = reason ? reason : "CHAN_SUSPEND_REASON";
- anope_cmd_kick(s_ChanServ, av[0], av[1], av[2]);
- do_kick(s_ChanServ, 3, av);
- }
- }
-
- if (WallForbid)
- anope_cmd_global(s_ChanServ,
- "\2%s\2 used SUSPEND on channel \2%s\2",
- u->nick, ci->name);
-
- alog("%s: %s set SUSPEND for channel %s", s_ChanServ, u->nick,
- ci->name);
- notice_lang(s_ChanServ, u, CHAN_SUSPEND_SUCCEEDED, chan);
- send_event(EVENT_CHAN_SUSPENDED, chan);
- } else {
- alog("%s: Valid SUSPEND for %s by %s failed", s_ChanServ, ci->name,
- u->nick);
- notice_lang(s_ChanServ, u, CHAN_SUSPEND_FAILED, chan);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_unsuspend(User * u)
-{
- ChannelInfo *ci;
- char *chan = strtok(NULL, " ");
-
- /* Assumes that permission checking has already been done. */
- if (!chan) {
- syntax_error(s_ChanServ, u, "UNSUSPEND", CHAN_UNSUSPEND_SYNTAX);
- return MOD_CONT;
- }
- if (chan[0] != '#') {
- notice_lang(s_ChanServ, u, CHAN_UNSUSPEND_ERROR);
- return MOD_CONT;
- }
- if (readonly)
- notice_lang(s_ChanServ, u, READ_ONLY_MODE);
-
- ci = cs_findchan(chan);
-
- if (ci) {
- ci->flags &= ~CI_SUSPENDED;
- ci->forbidreason = NULL;
- ci->forbidby = NULL;
-
- if (WallForbid)
- anope_cmd_global(s_ChanServ,
- "\2%s\2 used UNSUSPEND on channel \2%s\2",
- u->nick, ci->name);
-
- alog("%s: %s set UNSUSPEND for channel %s", s_ChanServ, u->nick,
- ci->name);
- notice_lang(s_ChanServ, u, CHAN_UNSUSPEND_SUCCEEDED, chan);
- send_event(EVENT_CHAN_UNSUSPEND, chan);
- } else {
- alog("%s: Valid UNSUSPEND for %s by %s failed", s_ChanServ,
- chan, u->nick);
- notice_lang(s_ChanServ, u, CHAN_UNSUSPEND_FAILED, chan);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/
-
-static int do_status(User * u)
-{
- ChannelInfo *ci;
- User *u2;
- char *nick, *chan;
- char *temp;
-
- chan = strtok(NULL, " ");
- nick = strtok(NULL, " ");
- if (!nick || strtok(NULL, " ")) {
- notice_lang(s_ChanServ, u, CHAN_STATUS_SYNTAX);
- return MOD_CONT;
- }
- if (!(ci = cs_findchan(chan))) {
- temp = chan;
- chan = nick;
- nick = temp;
- ci = cs_findchan(chan);
- }
- if (!ci) {
- notice_lang(s_ChanServ, u, CHAN_STATUS_NOT_REGGED, temp);
- } else if (ci->flags & CI_VERBOTEN) {
- notice_lang(s_ChanServ, u, CHAN_STATUS_FORBIDDEN, chan);
- return MOD_CONT;
- } else if ((u2 = finduser(nick)) != NULL) {
- notice_lang(s_ChanServ, u, CHAN_STATUS_INFO, chan, nick,
- get_access(u2, ci));
- } else { /* !u2 */
- notice_lang(s_ChanServ, u, CHAN_STATUS_NOTONLINE, nick);
- }
- return MOD_CONT;
-}
-
-/*************************************************************************/