diff options
Diffstat (limited to 'src/chanserv.c')
-rw-r--r-- | src/chanserv.c | 4064 |
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; -} - -/*************************************************************************/ |