From d3d64c27b199622c90075d6f59dd08e44acbb378 Mon Sep 17 00:00:00 2001 From: Adam- Date: Tue, 13 Oct 2009 21:26:38 +0000 Subject: Complete rewrite of everything associated with modes, this breaks saving and reading mlocked modes from the databases until the new databases are implemented git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2560 5417fbe8-f217-4b02-8779-1006273d7864 --- src/Makefile | 3 +- src/botserv.c | 26 +- src/channels.c | 927 ++++++++++++++++++++++++-------------------- src/chanserv.c | 584 ++++++++++++---------------- src/core/cs_access.c | 2 +- src/core/cs_akick.c | 3 +- src/core/cs_ban.c | 4 +- src/core/cs_clear.c | 111 ++---- src/core/cs_drop.c | 4 +- src/core/cs_forbid.c | 21 +- src/core/cs_getkey.c | 5 +- src/core/cs_info.c | 7 +- src/core/cs_modes.c | 138 ++++--- src/core/cs_register.c | 11 +- src/core/cs_set.c | 100 ++--- src/core/cs_xop.c | 4 +- src/core/os_chanlist.c | 29 +- src/core/os_clearmodes.c | 107 +---- src/core/os_userlist.c | 27 +- src/ircd.c | 127 ------ src/modes.cpp | 364 +++++++++++++++++ src/modules.c | 58 --- src/modules/cs_enforce.c | 9 +- src/modules/cs_tban.c | 4 +- src/nickserv.c | 4 +- src/operserv.c | 83 ++-- src/protocol/bahamut.c | 411 +++----------------- src/protocol/inspircd11.c | 423 ++++---------------- src/protocol/inspircd12.cpp | 406 ++++--------------- src/protocol/ratbox.c | 379 +++--------------- src/protocol/unreal32.c | 533 ++++++------------------- src/users.c | 82 +++- 32 files changed, 1869 insertions(+), 3127 deletions(-) create mode 100644 src/modes.cpp (limited to 'src') diff --git a/src/Makefile b/src/Makefile index a54d194c4..2f8845b4d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ OBJS = actions.o base64.o bots.o botserv.o channels.o chanserv.o command.o comm config.o datafiles.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \ memory.o memoserv.o messages.o misc.o modules.o news.o nickserv.o operserv.o \ process.o protocol.o send.o servers.o sessions.o slist.o sockutil.o opertype.o users.o module.o modulemanager.o configreader.o \ - wildcard.o nickcore.o nickalias.o timers.o + wildcard.o nickcore.o nickalias.o timers.o modes.o INCLUDES = ../include/commands.h ../include/defs.h ../include/language.h \ ../include/pseudo.h ../include/sysconf.h ../include/config.h \ @@ -33,6 +33,7 @@ services: $(OBJS) $(MAKEBIN) $(CC) $(CFLAGS) $(OBJS) $(ANOPELIBS) $(MLIBS) -o $@ $(LDFLAGS) $(OBJS): Makefile +modes.o: modes.cpp $(INCLUDES) timers.o: timers.cpp $(INCLUDES) nickcore.o: nickcore.cpp $(INCLUDES) nickalias.o: nickalias.cpp $(INCLUDES) diff --git a/src/botserv.c b/src/botserv.c index 3fc4c5c11..0e4f37600 100644 --- a/src/botserv.c +++ b/src/botserv.c @@ -772,12 +772,19 @@ void bot_join(ChannelInfo * ci) } } + std::string Limit; + int limit = 0; + if (ci->c->GetParam(CMODE_LIMIT, &Limit)) + { + limit = atoi(Limit.c_str()); + } + /* Should we be invited? */ - if ((ci->c->mode & anope_get_invite_mode()) - || (ci->c->limit && ci->c->usercount >= ci->c->limit)) + if (ci->c->HasMode(CMODE_INVITE) + || (limit && ci->c->usercount >= limit)) ircdproto->SendNoticeChanops(NULL, ci->c->name, - "%s invited %s into the channel.", - ci->bi->nick, ci->bi->nick); + "%s invited %s into the channel.", + ci->bi->nick, ci->bi->nick); } ircdproto->SendJoin(ci->bi, ci->c->name, ci->c->creation_time); ircdproto->SendBotOp(ci->bi->nick, ci->c->name); @@ -877,7 +884,8 @@ void bot_raw_ban(User * requester, ChannelInfo * ci, char *nick, if (!u) return; - if (ircd->protectedumode) { + if ((ModeManager::FindUserModeByName(UMODE_PROTECTED))) + { if (is_protected(u) && (requester != u)) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(ACCESS_DENIED)); @@ -889,7 +897,8 @@ void bot_raw_ban(User * requester, ChannelInfo * ci, char *nick, && (get_access(u, ci) >= get_access(requester, ci))) return; - if (ircd->except) { + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT)) + { if (is_excepted(ci, u) == 1) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(BOT_EXCEPT)); @@ -953,7 +962,8 @@ void bot_raw_kick(User * requester, ChannelInfo * ci, char *nick, if (!u || !is_on_chan(ci->c, u)) return; - if (ircd->protectedumode) { + if ((ModeManager::FindUserModeByName(UMODE_PROTECTED))) + { if (is_protected(u) && (requester != u)) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(ACCESS_DENIED)); @@ -1007,7 +1017,7 @@ void bot_raw_mode(User * requester, ChannelInfo * ci, const char *mode, snprintf(buf, BUFSIZE - 1, "%ld", static_cast(time(NULL))); - if (ircd->protectedumode) { + if ((ModeManager::FindUserModeByName(UMODE_PROTECTED))) { if (is_protected(u) && *mode == '-' && (requester != u)) { ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", getstring(ACCESS_DENIED)); diff --git a/src/channels.c b/src/channels.c index f41219109..5984065e0 100644 --- a/src/channels.c +++ b/src/channels.c @@ -20,7 +20,279 @@ Channel *chanlist[1024]; #define HASH(chan) ((chan)[1] ? ((chan)[1]&31)<<5 | ((chan)[2]&31) : 0) -/**************************** External Calls *****************************/ +/*************************************************************************/ + +/** + * See if a channel has a mode + * @param Name The mode name + * @return true or false + */ +bool Channel::HasMode(ChannelModeName Name) +{ + return modes[(size_t)Name]; +} + +/** + * Set a mode on a channel + * @param Name The mode name + */ +void Channel::SetMode(ChannelModeName Name) +{ + modes[(size_t)Name] = true; +} + +/** + * Set a mode on a channel + * @param Mode The mode + */ +void Channel::SetMode(char Mode) +{ + ChannelMode *cm; + + if ((cm = ModeManager::FindChannelModeByChar(Mode))) + { + SetMode(cm->Name); + } +} + +/** + * Remove a mode from a channel + * @param Name The mode name + */ +void Channel::RemoveMode(ChannelModeName Name) +{ + modes[(size_t)Name] = false; +} + +/** + * Remove a mode from a channel + * @param Mode The mode + */ +void Channel::RemoveMode(char Mode) +{ + ChannelMode *cm; + + if ((cm = ModeManager::FindChannelModeByChar(Mode))) + { + RemoveMode(cm->Name); + } +} + +/** Set a channel mode param on the channel + * @param Name The mode + * @param param The param + * @param true on success + */ +bool Channel::SetParam(ChannelModeName Name, std::string &Value) +{ + return Params.insert(std::make_pair(Name, Value)).second; +} + +/** Unset a param from the channel + * @param Name The mode + */ +void Channel::UnsetParam(ChannelModeName Name) +{ + std::map::iterator it = Params.find(Name); + + if (it != Params.end()) + { + Params.erase(it); + } +} + +/** Get a param from the channel + * @param Name The mode + * @param Target a string to put the param into + * @return true on success + */ +const bool Channel::GetParam(ChannelModeName Name, std::string *Target) +{ + std::map::iterator it = Params.find(Name); + + (*Target).clear(); + + if (it != Params.end()) + { + *Target = it->second; + return true; + } + + return false; +} + +/** Check if a mode is set and has a param + * @param Name The mode + */ +const bool Channel::HasParam(ChannelModeName Name) +{ + std::map::iterator it = Params.find(Name); + + if (it != Params.end()) + { + return true; + } + + return false; +} + +/*************************************************************************/ + +/** Clear all the modes from the channel + * @param client The client unsetting the modes + */ +void Channel::ClearModes(char *client) +{ + ChannelMode *cm; + ChannelModeParam *cmp; + std::string buf, buf2; + const char *argv[2]; + BotInfo *sender = (client ? findbot(client) : whosends(ci)); + + for (size_t n = CMODE_BEGIN + 1; n != CMODE_END; ++n) + { + cm = ModeManager::FindChannelModeByName((ChannelModeName)n); + + if (cm && this->HasMode(cm->Name)) + { + if (cm->Type == MODE_REGULAR) + { + buf = '-'; + buf += cm->ModeChar; + + argv[0] = buf.c_str(); + + ircdproto->SendMode(sender, this->name, "-%c", cm->ModeChar); + chan_set_modes(sender->nick, this, 1, argv, 0); + } + else if (cm->Type == MODE_PARAM) + { + cmp = static_cast(cm); + + buf = '-'; + buf += cmp->ModeChar; + buf2.clear(); + + if (!cmp->MinusNoArg) + { + buf2 = this->GetParam(cmp->Name, &buf2); + } + + argv[0] = buf.c_str(); + if (!buf2.empty()) + { + argv[1] = buf2.c_str(); + + ircdproto->SendMode(sender, this->name, "-%c %s", cm->ModeChar, buf2.c_str()); + chan_set_modes(sender->nick, this, 2, argv, 0); + } + else + { + argv[1] = NULL; + + ircdproto->SendMode(sender, this->name, "-%c", cm->ModeChar); + chan_set_modes(sender->nick, this, 1, argv, 0); + } + } + } + } + + modes.reset(); +} + +/** Clear all the bans from the channel + * @param client The client unsetting the modes + */ +void Channel::ClearBans(char *client) +{ + Entry *entry, *nexte; + BotInfo *sender = (client ? findbot(client) : whosends(ci)); + ChannelModeList *cml; + std::string buf; + const char *argv[2]; + + cml = static_cast(ModeManager::FindChannelModeByName(CMODE_BAN)); + + if (cml && this->bans && this->bans->count) + { + buf = '-'; + buf += cml->ModeChar; + + for (entry = this->bans->entries; entry; entry = nexte) + { + nexte = entry->next; + + argv[0] = buf.c_str(); + argv[1] = sstrdup(entry->mask); + ircdproto->SendMode(sender, this->name, "%s %s", buf.c_str(), entry->mask); + chan_set_modes(sender->nick, this, 2, argv, 0); + delete [] argv[1]; + } + } +} + +/** Clear all the excepts from the channel + * @param client The client unsetting the modes + */ +void Channel::ClearExcepts(char *client) +{ + Entry *entry, *nexte; + BotInfo *sender = (client ? findbot(client) : whosends(ci)); + ChannelModeList *cml; + std::string buf; + const char *argv[2]; + + cml = static_cast(ModeManager::FindChannelModeByName(CMODE_EXCEPT)); + + if (cml && this->excepts && this->excepts->count) + { + buf = '+'; + buf += cml->ModeChar; + + for (entry = this->excepts->entries; entry; entry = nexte) + { + nexte = entry->next; + + argv[0] = buf.c_str(); + argv[1] = sstrdup(entry->mask); + ircdproto->SendMode(sender, this->name, "%s %s", buf.c_str(), entry->mask); + chan_set_modes(sender->nick, this, 2, argv, 0); + delete [] argv[1]; + } + } +} + +/** Clear all the invites from the channel + * @param client The client unsetting the modes + */ +void Channel::ClearInvites(char *client) +{ + Entry *entry, *nexte; + BotInfo *sender = (client ? findbot(client) : whosends(ci)); + ChannelModeList *cml; + std::string buf; + const char *argv[2]; + + cml = static_cast(ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE)); + + if (cml && this->invites && this->invites->count) + { + buf = '-'; + buf += cml->ModeChar; + + for (entry = this->invites->entries; entry; entry = nexte) + { + nexte = entry->next; + + argv[0] = buf.c_str(); + argv[1] = sstrdup(entry->mask); + ircdproto->SendMode(sender, this->name, "%s %s", buf.c_str(), entry->mask); + chan_set_modes(sender->nick, this, 2, argv, 0); + delete [] argv[1]; + } + } +} + /*************************************************************************/ void chan_deluser(User * user, Channel * c) @@ -66,33 +338,50 @@ void chan_deluser(User * user, Channel * c) char *chan_get_modes(Channel * chan, int complete, int plus) { static char res[BUFSIZE]; - char *end = res; - - if (chan->mode) { - unsigned int n = 0; - CBModeInfo *cbmi = cbmodeinfos; - - do { - if (chan->mode & cbmi->flag) - *end++ = cbmi->mode; - } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1); - - if (complete) { - cbmi = cbmodeinfos; + char params[BUFSIZE]; + char *end = res, *value, *pend = params, *pend2 = params; + std::string param; + ChannelMode *cm; + ChannelModeParam *cmp; + std::map::iterator it; + + if (!chan->modes.count()) + { + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; - do { - if (cbmi->getvalue && (chan->mode & cbmi->flag) && - (plus || !(cbmi->flags & CBM_MINUS_NO_ARG))) { - char *value = cbmi->getvalue(chan); + if (chan->HasMode(cm->Name)) + { + *end++ = it->first; - if (value) { - *end++ = ' '; - while (*value) - *end++ = *value++; + if (complete) + { + if (cm->Type == MODE_PARAM) + { + cmp = static_cast(cm); + + if (plus || !cmp->MinusNoArg) + { + chan->GetParam(cmp->Name, ¶m); + + if (!param.empty()) + { + value = const_cast(param.c_str()); + + *pend++ = ' '; + + while (*value) + *pend++ = *value++; + } + } } } - } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1); + } } + + while (*pend2) + *end++ = *pend2++; } *end = 0; @@ -156,128 +445,158 @@ void chan_remove_user_status(Channel * chan, User * user, int16 status) /*************************************************************************/ -void chan_set_modes(const char *source, Channel * chan, int ac, const char **av, - int check) +void chan_set_modes(const char *source, Channel *chan, int ac, const char **av, int check) { - int add = 1; - const char *modes = av[0]; + int add = 1, i, real_ac = ac; + ChannelMode *cm; + ChannelModeStatus *cms; + ChannelModeList *cml; + ChannelModeParam *cmp; + const char *modes, **real_av = av; char mode; - CBMode *cbm; - CMMode *cmm; - CUMode *cum; - unsigned char botmode = 0; BotInfo *bi; + unsigned char botmode = 0; User *user; - int i, real_ac = ac; - const char **real_av = av; + + modes = av[0]; if (debug) - alog("debug: Changing modes for %s to %s", chan->name, - merge_args(ac, av)); + alog("debug: Changing modes for %s to %s", chan->name, merge_args(ac, av)); ac--; - while ((mode = *modes++)) { - - switch (mode) { - case '+': - add = 1; - continue; - case '-': - add = 0; - continue; + while ((mode = *modes++)) + { + switch (mode) + { + case '+': + add = 1; + continue; + case '-': + add = 0; + continue; } - if (static_cast(mode) < 0) { - if (debug) - alog("Debug: Malformed mode detected on %s.", chan->name); - continue; - } + if ((cm = ModeManager::FindChannelModeByChar(mode))) + { + /* v/h/o/a/q etc */ + if (cm->Type == MODE_STATUS) + { + cms = static_cast(cm); - if ((cum = &cumodes[static_cast(mode)])->status != 0) { - if (ac == 0) { - alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); - continue; - } - ac--; - av++; + if (ac == 0) + { + alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); + continue; + } - if ((cum->flags & CUF_PROTECT_BOTSERV) && !add) { - if ((bi = findbot(*av))) { - if (!botmode || botmode != mode) { - ircdproto->SendMode(bi, chan->name, "+%c %s", - mode, bi->nick); - botmode = mode; - continue; - } else { - botmode = mode; - continue; + ac--; + av++; + + if (cms->ProtectBotServ && !add) + { + if ((bi = findbot(*av))) + { + if (!botmode || botmode != mode) + { + ircdproto->SendMode(bi, chan->name, "+%c %s", mode, bi->nick); + botmode = mode; + continue; + } + else + { + botmode = mode; + continue; + } } } - } else { - if ((bi = findbot(*av))) { + else if ((bi = findbot(*av))) continue; - } - } - if (!(user = finduser(*av)) - && !(ircd->ts6 && (user = find_byuid(*av)))) { - if (debug) { - alog("debug: MODE %s %c%c for nonexistent user %s", - chan->name, (add ? '+' : '-'), mode, *av); + if (!(user = finduser(*av)) && !(ircd->ts6 && (user = find_byuid(*av)))) + { + if (debug) + { + alog("debug: MODE %s %c%c for nonexistent user %s", + chan->name, (add ? '+' : '-'), mode, *av); + } + continue; } - continue; - } - if (debug) - alog("debug: Setting %c%c on %s for %s", (add ? '+' : '-'), - mode, chan->name, user->nick); + if (debug) + alog("debug: Setting %c%c on %s for %s", (add ? '+' : '-'), + mode, chan->name, user->nick); - if (add) { - chan_set_user_status(chan, user, cum->status); - /* If this does +o, remove any DEOPPED flag */ - } else { - chan_remove_user_status(chan, user, cum->status); + if (add) + chan_set_user_status(chan, user, cms->Status); + /* If this does +o, remove any DEOPPED flag */ + else + chan_remove_user_status(chan, user, cms->Status); } + /* b/e/I etc */ + else if (cm->Type == MODE_LIST) + { + cml = static_cast(cm); + + if (ac == 0) + { + alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); + continue; + } + + ac--; + av++; - } else if ((cbm = &cbmodes[static_cast(mode)])->flag != 0) { - if (check >= 0) { if (add) - chan->mode |= cbm->flag; + cml->AddMask(chan, *av); else - chan->mode &= ~cbm->flag; + cml->DelMask(chan, *av); } + else + { + if (check >= 0) + { + if (add) + chan->SetMode(mode); + else + chan->RemoveMode(mode); + } + + if (cm->Type == MODE_PARAM) + { + cmp = static_cast(cm); + + if (add || !cmp->MinusNoArg) + { + if (ac == 0) + { + alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); + continue; + } + + ac--; + av++; + } - if (cbm->setvalue) { - if (add || !(cbm->flags & CBM_MINUS_NO_ARG)) { - if (ac == 0) { - alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); + if (*av && !cmp->IsValid(*av)) continue; + if (add) + { + std::string Param = *av; + chan->SetParam(cmp->Name, Param); } - ac--; - av++; + else + chan->UnsetParam(cmp->Name); } - cbm->setvalue(chan, add ? *av : NULL); - } - if (check < 0) { - if (add) - chan->mode |= cbm->flag; - else - chan->mode &= ~cbm->flag; - } - } else if ((cmm = &cmmodes[static_cast(mode)])->addmask) { - if (ac == 0) { - alog("channel: mode %c%c with no parameter (?) for channel %s", add ? '+' : '-', mode, chan->name); - continue; + if (check < 0) + { + if (add) + chan->SetMode(mode); + else + chan->RemoveMode(mode); + } } - - ac--; - av++; - if (add) - cmm->addmask(chan, *av); - else - cmm->delmask(chan, *av); } } @@ -297,6 +616,7 @@ void chan_set_modes(const char *source, Channel * chan, int ac, const char **av, */ real_ac--; real_av++; + for (i = 0; i < real_ac; i++) { if ((user = finduser(*real_av)) && is_on_chan(chan, user)) @@ -328,19 +648,24 @@ void chan_set_modes(const char *source, Channel * chan, int ac, const char **av, void chan_set_user_status(Channel * chan, User * user, int16 status) { struct u_chanlist *uc; + UserMode *um; + char av[3]; if (debug >= 2) alog("debug: setting user status (%d) on %s for %s", status, user->nick, chan->name); - if (HelpChannel && ircd->supporthelper && (status & CUS_OP) + if (HelpChannel && ((um = ModeManager::FindUserModeByName(UMODE_HELPOP))) && (status & CUS_OP) && (stricmp(chan->name, HelpChannel) == 0) && (!chan->ci || check_access(user, chan->ci, CA_AUTOOP))) { if (debug) { - alog("debug: %s being given +h for having %d status in %s", + alog("debug: %s being given helpop for having %d status in %s", user->nick, status, chan->name); } - common_svsmode(user, "+h", NULL); + + snprintf(av, sizeof(av), "+%c", um->ModeChar); + + common_svsmode(user, av, NULL); } for (uc = user->chans; uc; uc = uc->next) { @@ -429,6 +754,7 @@ void get_channel_stats(long *nrec, long *memuse) struct c_userlist *cu; BanData *bd; int i; + std::string buf; for (i = 0; i < 1024; i++) { for (chan = chanlist[i]; chan; chan = chan->next) { @@ -436,23 +762,17 @@ void get_channel_stats(long *nrec, long *memuse) mem += sizeof(*chan); if (chan->topic) mem += strlen(chan->topic) + 1; - if (chan->key) - mem += strlen(chan->key) + 1; - if (ircd->fmode) { - if (chan->flood) - mem += strlen(chan->flood) + 1; - } - if (ircd->Lmode) { - if (chan->redirect) - mem += strlen(chan->redirect) + 1; - } + if (chan->GetParam(CMODE_KEY, &buf)) + mem += buf.length() + 1; + if (chan->GetParam(CMODE_FLOOD, &buf)) + mem += buf.length() + 1; + if (chan->GetParam(CMODE_REDIRECT, &buf)) + mem += buf.length() + 1; mem += get_memuse(chan->bans); - if (ircd->except) { + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT)) mem += get_memuse(chan->excepts); - } - if (ircd->invitemode) { + if (ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE)) mem += get_memuse(chan->invites); - } for (cu = chan->users; cu; cu = cu->next) { mem += sizeof(*cu); if (cu->ud) { @@ -756,12 +1076,13 @@ void do_sjoin(const char *source, int ac, const char **av) Server *serv; struct c_userlist *cu; const char *s = NULL; - char *buf, *end, cubuf[7], *end2; + char *buf, *end, cubuf[7], *end2, value; const char *modes[6]; int is_sqlined = 0; int ts = 0; int is_created = 0; int keep_their_modes = 1; + ChannelModeList *cml; serv = findserver(servlist, source); @@ -792,9 +1113,9 @@ void do_sjoin(const char *source, int ac, const char **av) bot_join(c->ci); } /* Make sure +r is set */ - if (ircd->chanreg && ircd->regmode) + if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) { - c->mode |= ircd->regmode; + c->SetMode(CMODE_REGISTERED); ircdproto->SendMode(whosends(c->ci), c->name, "+r"); } } @@ -827,8 +1148,12 @@ void do_sjoin(const char *source, int ac, const char **av) if (ircd->sjoinbanchar) { if (*s == ircd->sjoinbanchar && keep_their_modes) { - buf = myStrGetToken(s, ircd->sjoinbanchar, 1); - add_ban(c, buf); + buf = myStrGetToken(s, ircd->sjoinbanchar, 1); + + cml = static_cast(ModeManager::FindChannelModeByName(CMODE_BAN)); + if (cml->IsValid(buf)) + cml->AddMask(c, buf); + delete [] buf; if (!end) break; @@ -839,7 +1164,11 @@ void do_sjoin(const char *source, int ac, const char **av) if (ircd->sjoinexchar) { if (*s == ircd->sjoinexchar && keep_their_modes) { buf = myStrGetToken(s, ircd->sjoinexchar, 1); - add_exception(c, buf); + + cml = static_cast(ModeManager::FindChannelModeByName(CMODE_EXCEPT)); + if (cml->IsValid(buf)) + cml->AddMask(c, buf); + delete [] buf; if (!end) break; @@ -851,7 +1180,11 @@ void do_sjoin(const char *source, int ac, const char **av) if (ircd->sjoininvchar) { if (*s == ircd->sjoininvchar && keep_their_modes) { buf = myStrGetToken(s, ircd->sjoininvchar, 1); - add_invite(c, buf); + + cml = static_cast(ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE)); + if (cml->IsValid(buf)) + cml->AddMask(c, buf); + delete [] buf; if (!end) break; @@ -860,11 +1193,13 @@ void do_sjoin(const char *source, int ac, const char **av) } } - while (csmodes[static_cast(*s)] != 0) - *end2++ = csmodes[static_cast(*s++)]; + while ((value = ModeManager::GetStatusChar(*s))) + { + *end2++ = value; + *s++; + } *end2 = 0; - if (ircd->ts6) { user = find_byuid(s); if (!user) @@ -944,8 +1279,11 @@ void do_sjoin(const char *source, int ac, const char **av) end2 = cubuf + 1; - while (csmodes[static_cast(*s)] != 0) - *end2++ = csmodes[static_cast(*s++)]; + while ((value = ModeManager::GetStatusChar(*s))) + { + *end2++ = value; + *s++; + } *end2 = 0; if (ircd->ts6) { @@ -1017,8 +1355,11 @@ void do_sjoin(const char *source, int ac, const char **av) end2 = cubuf + 1; - while (csmodes[static_cast(*s)] != 0) - *end2++ = csmodes[static_cast(*s++)]; + while ((value = ModeManager::GetStatusChar(*s))) + { + *end2++ = value; + *s++; + } *end2 = 0; if (ircd->ts6) { @@ -1264,95 +1605,6 @@ void do_topic(const char *source, int ac, const char **av) /**************************** Internal Calls *****************************/ /*************************************************************************/ -void add_ban(Channel * chan, const char *mask) -{ - Entry *ban; - /* check for NULL values otherwise we will segfault */ - if (!chan || !mask) { - if (debug) { - alog("debug: add_ban called with NULL values"); - } - return; - } - - /* Check if the list already exists, if not create it. - * Create a new ban and add it to the list.. ~ Viper */ - if (!chan->bans) - chan->bans = list_create(); - ban = entry_add(chan->bans, mask); - - if (!ban) - fatal("Creating new ban entry failed"); - - /* Check whether it matches a botserv bot after adding internally - * and parsing it through cidr support. ~ Viper */ - if (s_BotServ && BSSmartJoin && chan->ci && chan->ci->bi - && chan->usercount >= BSMinUsers) { - BotInfo *bi = chan->ci->bi; - - if (entry_match(ban, bi->nick, bi->user, bi->host, 0)) { - ircdproto->SendMode(bi, chan->name, "-b %s", mask); - entry_delete(chan->bans, ban); - return; - } - } - - if (debug) - alog("debug: Added ban %s to channel %s", mask, chan->name); -} - -/*************************************************************************/ - -void add_exception(Channel * chan, const char *mask) -{ - Entry *exception; - - if (!chan || !mask) { - if (debug) - alog("debug: add_exception called with NULL values"); - return; - } - - /* Check if the list already exists, if not create it. - * Create a new exception and add it to the list.. ~ Viper */ - if (!chan->excepts) - chan->excepts = list_create(); - exception = entry_add(chan->excepts, mask); - - if (!exception) - fatal("Creating new exception entry failed"); - - if (debug) - alog("debug: Added except %s to channel %s", mask, chan->name); -} - -/*************************************************************************/ - -void add_invite(Channel * chan, const char *mask) -{ - Entry *invite; - - if (!chan || !mask) { - if (debug) - alog("debug: add_invite called with NULL values"); - return; - } - - /* Check if the list already exists, if not create it. - * Create a new invite and add it to the list.. ~ Viper */ - if (!chan->invites) - chan->invites = list_create(); - invite = entry_add(chan->invites, mask); - - if (!invite) - fatal("Creating new exception entry failed"); - - if (debug) - alog("debug: Added invite %s to channel %s", mask, chan->name); -} - -/*************************************************************************/ - /** * Set the correct modes, or remove the ones granted without permission, * for the specified user on ths specified channel. This doesn't give @@ -1364,13 +1616,16 @@ void add_invite(Channel * chan, const char *mask) **/ void chan_set_correct_modes(User * user, Channel * c, int give_modes) { - char *tmp; char modebuf[BUFSIZE]; char userbuf[BUFSIZE]; int status; int add_modes = 0; int rem_modes = 0; ChannelInfo *ci; + ChannelMode *owner, *admin; + + owner = ModeManager::FindChannelModeByName(CMODE_OWNER); + admin = ModeManager::FindChannelModeByName(CMODE_PROTECT); if (!c || !(ci = c->ci)) return; @@ -1390,14 +1645,13 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) */ if (give_modes && (get_ignore(user->nick) == NULL) && (!user->nc || !(user->nc->flags & NI_AUTOOP))) { - if (ircd->owner && is_founder(user, ci)) + if (owner && is_founder(user, ci)) add_modes |= CUS_OWNER; - else if ((ircd->protect || ircd->admin) - && check_access(user, ci, CA_AUTOPROTECT)) + else if (admin && check_access(user, ci, CA_AUTOPROTECT)) add_modes |= CUS_PROTECT; if (check_access(user, ci, CA_AUTOOP)) add_modes |= CUS_OP; - else if (ircd->halfop && check_access(user, ci, CA_AUTOHALFOP)) + else if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && check_access(user, ci, CA_AUTOHALFOP)) add_modes |= CUS_HALFOP; else if (check_access(user, ci, CA_AUTOVOICE)) add_modes |= CUS_VOICE; @@ -1412,16 +1666,16 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) if (((ci->flags & CI_SECUREOPS) || (c->usercount == 1) || check_access(user, ci, CA_AUTODEOP)) && !is_ulined(user->server->name)) { - if (ircd->owner && (status & CUS_OWNER) && !is_founder(user, ci)) + if (owner && (status & CUS_OWNER) && !is_founder(user, ci)) rem_modes |= CUS_OWNER; - if ((ircd->protect || ircd->admin) && (status & CUS_PROTECT) + if (admin && (status & CUS_PROTECT) && !check_access(user, ci, CA_AUTOPROTECT) && !check_access(user, ci, CA_PROTECTME)) rem_modes |= CUS_PROTECT; if ((status & CUS_OP) && !check_access(user, ci, CA_AUTOOP) && !check_access(user, ci, CA_OPDEOPME)) rem_modes |= CUS_OP; - if (ircd->halfop && (status & CUS_HALFOP) + if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && (status & CUS_HALFOP) && !check_access(user, ci, CA_AUTOHALFOP) && !check_access(user, ci, CA_HALFOPME)) rem_modes |= CUS_HALFOP; @@ -1439,18 +1693,14 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) if (add_modes > 0) { strcat(modebuf, "+"); if ((add_modes & CUS_OWNER) && !(status & CUS_OWNER)) { - tmp = stripModePrefix(ircd->ownerset); - strcat(modebuf, tmp); - delete [] tmp; + strcat(modebuf, &owner->ModeChar); strcat(userbuf, " "); strcat(userbuf, user->nick); } else { add_modes &= ~CUS_OWNER; } if ((add_modes & CUS_PROTECT) && !(status & CUS_PROTECT)) { - tmp = stripModePrefix(ircd->adminset); - strcat(modebuf, tmp); - delete [] tmp; + strcat(modebuf, &admin->ModeChar); strcat(userbuf, " "); strcat(userbuf, user->nick); } else { @@ -1481,16 +1731,12 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) if (rem_modes > 0) { strcat(modebuf, "-"); if (rem_modes & CUS_OWNER) { - tmp = stripModePrefix(ircd->ownerset); - strcat(modebuf, tmp); - delete [] tmp; + strcat(modebuf, &owner->ModeChar); strcat(userbuf, " "); strcat(userbuf, user->nick); } if (rem_modes & CUS_PROTECT) { - tmp = stripModePrefix(ircd->adminset); - strcat(modebuf, tmp); - delete [] tmp; + strcat(modebuf, &admin->ModeChar); strcat(userbuf, " "); strcat(userbuf, user->nick); } @@ -1607,8 +1853,6 @@ Channel *chan_create(const char *chan, time_t ts) c->topic = NULL; *c->topic_setter = 0; c->topic_time = 0; - c->mode = c->limit = 0; - c->key = c->redirect = c->flood = NULL; c->bans = c->excepts = c->invites = NULL; c->users = NULL; c->usercount = 0; @@ -1656,24 +1900,14 @@ void chan_delete(Channel * c) if (c->topic) delete [] c->topic; - if (c->key) - delete [] c->key; - if (ircd->fmode) { - if (c->flood) - delete [] c->flood; - } - if (ircd->Lmode) { - if (c->redirect) - delete [] c->redirect; - } - if (c->bans && c->bans->count) { while (c->bans->entries) { entry_delete(c->bans, c->bans->entries); } } - if (ircd->except) { + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT)) + { if (c->excepts && c->excepts->count) { while (c->excepts->entries) { entry_delete(c->excepts, c->excepts->entries); @@ -1681,7 +1915,8 @@ void chan_delete(Channel * c) } } - if (ircd->invitemode) { + if (ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE)) + { if (c->invites && c->invites->count) { while (c->invites->entries) { entry_delete(c->invites, c->invites->entries); @@ -1701,109 +1936,6 @@ void chan_delete(Channel * c) /*************************************************************************/ -void del_ban(Channel * chan, const char *mask) -{ - AutoKick *akick; - Entry *ban; - - /* Sanity check as it seems some IRCD will just send -b without a mask */ - if (!mask || !chan->bans || (chan->bans->count == 0)) - return; - - ban = elist_find_mask(chan->bans, mask); - - if (ban) { - entry_delete(chan->bans, ban); - - if (debug) - alog("debug: Deleted ban %s from channel %s", mask, - chan->name); - } - - if (chan->ci && (akick = is_stuck(chan->ci, mask))) - stick_mask(chan->ci, akick); -} - -/*************************************************************************/ - -void del_exception(Channel * chan, const char *mask) -{ - Entry *exception; - - /* Sanity check as it seems some IRCD will just send -e without a mask */ - if (!mask || !chan->excepts || (chan->excepts->count == 0)) - return; - - exception = elist_find_mask(chan->excepts, mask); - - if (exception) { - entry_delete(chan->excepts, exception); - - if (debug) - alog("debug: Deleted except %s to channel %s", mask, - chan->name); - } -} - -/*************************************************************************/ - -void del_invite(Channel * chan, const char *mask) -{ - Entry *invite; - - /* Sanity check as it seems some IRCD will just send -I without a mask */ - if (!mask || !chan->invites || (chan->invites->count == 0)) { - return; - } - - invite = elist_find_mask(chan->invites, mask); - - if (invite) { - entry_delete(chan->invites, invite); - - if (debug) - alog("debug: Deleted invite %s to channel %s", mask, - chan->name); - } -} - - -/*************************************************************************/ - -char *get_flood(Channel * chan) -{ - return chan->flood; -} - -/*************************************************************************/ - -char *get_key(Channel * chan) -{ - return chan->key; -} - -/*************************************************************************/ - -char *get_limit(Channel * chan) -{ - static char limit[16]; - - if (chan->limit == 0) - return NULL; - - snprintf(limit, sizeof(limit), "%lu", static_cast(chan->limit)); - return limit; -} - -/*************************************************************************/ - -char *get_redirect(Channel * chan) -{ - return chan->redirect; -} - -/*************************************************************************/ - Channel *join_user_update(User * user, Channel * chan, const char *name, time_t chants) { @@ -1838,9 +1970,9 @@ Channel *join_user_update(User * user, Channel * chan, const char *name, bot_join(chan->ci); } /* Make sure +r is set */ - if (ircd->chanreg && ircd->regmode) + if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) { - chan->mode |= ircd->regmode; + chan->SetMode(CMODE_REGISTERED); ircdproto->SendMode(whosends(chan->ci), chan->name, "+r"); } } @@ -1867,53 +1999,6 @@ Channel *join_user_update(User * user, Channel * chan, const char *name, /*************************************************************************/ -void set_flood(Channel * chan, const char *value) -{ - if (chan->flood) - delete [] chan->flood; - chan->flood = value ? sstrdup(value) : NULL; - - if (debug) - alog("debug: Flood mode for channel %s set to %s", chan->name, - chan->flood ? chan->flood : "no flood settings"); -} - -/*************************************************************************/ - -void chan_set_key(Channel * chan, const char *value) -{ - if (chan->key) - delete [] chan->key; - chan->key = value ? sstrdup(value) : NULL; - - if (debug) - alog("debug: Key of channel %s set to %s", chan->name, - chan->key ? chan->key : "no key"); -} - -/*************************************************************************/ - -void set_limit(Channel * chan, const char *value) -{ - chan->limit = value ? strtoul(value, NULL, 10) : 0; - - if (debug) - alog("debug: Limit of channel %s set to %u", chan->name, - chan->limit); -} - -/*************************************************************************/ - -void set_redirect(Channel * chan, const char *value) -{ - if (chan->redirect) - delete [] chan->redirect; - chan->redirect = value ? sstrdup(value) : NULL; - - if (debug) - alog("debug: Redirect of channel %s set to %s", chan->name, - chan->redirect ? chan->redirect : "no redirect"); -} void do_mass_mode(char *modes) { diff --git a/src/chanserv.c b/src/chanserv.c index 819d3c03e..a581ded69 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -104,21 +104,6 @@ LevelInfo levelinfo[] = { }; int levelinfo_maxwidth = 0; -CSModeUtil csmodeutils[] = { - { "DEOP", "deop", "-o", CI_OPNOTICE, CA_OPDEOP, CA_OPDEOPME }, - { "OP", "op", "+o", CI_OPNOTICE, CA_OPDEOP, CA_OPDEOPME }, - { "DEVOICE", "devoice", "-v", 0, CA_VOICE, CA_VOICEME }, - { "VOICE", "voice", "+v", 0, CA_VOICE, CA_VOICEME }, - { "DEHALFOP", "dehalfop", "-h", 0, CA_HALFOP, CA_HALFOPME }, - { "HALFOP", "halfop", "+h", 0, CA_HALFOP, CA_HALFOPME }, - /* These get set later */ - { "DEPROTECT", "", "", 0, CA_PROTECT, CA_PROTECTME }, - { "PROTECT", "", "", 0, CA_PROTECT, CA_PROTECTME }, - { "DEOWNER", "", "", 0, ACCESS_FOUNDER, ACCESS_FOUNDER}, - { "OWNER", "", "", 0, ACCESS_FOUNDER, ACCESS_FOUNDER}, - { NULL } -}; - /*************************************************************************/ void moduleAddChanServCmds() { @@ -156,54 +141,68 @@ class ChanServTimer : public Timer char *get_mlock_modes(ChannelInfo * ci, int complete) { static char res[BUFSIZE]; + char *end, *value; + ChannelMode *cm; + ChannelModeParam *cmp; + std::map::iterator it; + std::string param; - char *end = res; - - if (ci->mlock_on || ci->mlock_off) { - unsigned int n = 0; - CBModeInfo *cbmi = cbmodeinfos; + memset(&res, '\0', sizeof(res)); + end = res; - if (ci->mlock_on) { + if (ci->mlock_on.count() || ci->mlock_off.count()) + { + if (ci->mlock_on.count()) + { *end++ = '+'; - n++; - do { - if (ci->mlock_on & cbmi->flag) - *end++ = cbmi->mode; - } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1); + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; - cbmi = cbmodeinfos; + if (ci->HasMLock(cm->Name, true)) + *end++ = it->first; + } } - if (ci->mlock_off) { + if (ci->mlock_off.count()) + { *end++ = '-'; - n++; - do { - if (ci->mlock_off & cbmi->flag) - *end++ = cbmi->mode; - } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1); + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; - cbmi = cbmodeinfos; + if (ci->HasMLock(cm->Name, false)) + *end++ = it->first; + } } - if (ci->mlock_on && complete) { - do { - if (cbmi->csgetvalue && (ci->mlock_on & cbmi->flag)) { - char *value = cbmi->csgetvalue(ci); + if (ci->mlock_on.count() && complete) + { + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; + + if (cm->Type == MODE_PARAM) + { + cmp = static_cast(cm); + + ci->GetParam(cmp->Name, ¶m); + + if (!param.empty()) + { + value = const_cast(param.c_str()); - if (value) { *end++ = ' '; while (*value) *end++ = *value++; } } - } while ((++cbmi)->flag != 0 && ++n < sizeof(res) - 1); + } } } - *end = 0; - return res; } @@ -216,6 +215,7 @@ void get_chanserv_stats(long *nrec, long *memuse) long count = 0, mem = 0; unsigned i, j; ChannelInfo *ci; + std::string param; for (i = 0; i < 256; i++) { for (ci = chanlists[i]; ci; ci = ci->next) { @@ -239,16 +239,16 @@ void get_chanserv_stats(long *nrec, long *memuse) if (ci->akick[j].creator) mem += strlen(ci->akick[j].creator) + 1; } - if (ci->mlock_key) - mem += strlen(ci->mlock_key) + 1; - if (ircd->fmode) { - if (ci->mlock_flood) - mem += strlen(ci->mlock_flood) + 1; - } - if (ircd->Lmode) { - if (ci->mlock_redirect) - mem += strlen(ci->mlock_redirect) + 1; - } + + if (ci->GetParam(CMODE_KEY, ¶m)) + mem += param.length() + 1; + + if (ci->GetParam(CMODE_FLOOD, ¶m)) + mem += param.length() + 1; + + if (ci->GetParam(CMODE_REDIRECT, ¶m)) + mem += param.length() + 1; + if (ci->last_topic) mem += strlen(ci->last_topic) + 1; if (ci->entry_message) @@ -477,12 +477,40 @@ void load_cs_dbase() ci->akick = NULL; } - SAFE(read_int32(&ci->mlock_on, f)); - SAFE(read_int32(&ci->mlock_off, f)); - SAFE(read_int32(&ci->mlock_limit, f)); - SAFE(read_string(&ci->mlock_key, f)); - SAFE(read_string(&ci->mlock_flood, f)); - SAFE(read_string(&ci->mlock_redirect, f)); + //SAFE(read_int32(&ci->mlock_on, f)); + //SAFE(read_int32(&ci->mlock_off, f)); + // Clearly this doesn't work + SAFE(read_int32(&tmp32, f)); + SAFE(read_int32(&tmp32, f)); + + SAFE(read_int32(&tmp32, f)); + if (tmp32) + { + std::ostringstream limit; + limit << tmp32; + ci->SetParam(CMODE_LIMIT, limit.str()); + } + + SAFE(read_string(&s, f)); + if (s) + { + ci->SetParam(CMODE_KEY, std::string(s)); + delete [] s; + } + + SAFE(read_string(&s, f)); + if (s) + { + ci->SetParam(CMODE_FLOOD, std::string(s)); + delete [] s; + } + + SAFE(read_string(&s, f)); + if (s) + { + ci->SetParam(CMODE_REDIRECT, std::string(s)); + delete [] s; + } SAFE(read_int16(&tmp16, f)); if (tmp16) ci->memos.memos.resize(tmp16); @@ -598,6 +626,7 @@ void save_cs_dbase() unsigned i, j; ChannelInfo *ci; static time_t lastwarn = 0; + std::string param; if (!(f = open_db(s_ChanServ, ChanDBName, "w", CHAN_VERSION))) return; @@ -661,12 +690,24 @@ void save_cs_dbase() } } - SAFE(write_int32(ci->mlock_on, f)); - SAFE(write_int32(ci->mlock_off, f)); - SAFE(write_int32(ci->mlock_limit, f)); - SAFE(write_string(ci->mlock_key, f)); - SAFE(write_string(ci->mlock_flood, f)); - SAFE(write_string(ci->mlock_redirect, f)); + //SAFE(write_int32(ci->mlock_on, f)); + //SAFE(write_int32(ci->mlock_off, f)); + // Clearly this doesnt work + SAFE(write_int32(NULL, f)); + SAFE(write_int32(NULL, f)); + + ci->GetParam(CMODE_LIMIT, ¶m); + SAFE(write_int32(param.empty() ? NULL : atoi(param.c_str()), f)); + + ci->GetParam(CMODE_KEY, ¶m); + SAFE(write_string(param.empty() ? NULL : param.c_str(), f)); + + ci->GetParam(CMODE_FLOOD, ¶m); + SAFE(write_string(param.empty() ? NULL : param.c_str(), f)); + + ci->GetParam(CMODE_REDIRECT, ¶m); + SAFE(write_string(param.empty() ? NULL : param.c_str(), f)); + SAFE(write_int16(ci->memos.memos.size(), f)); SAFE(write_int16(ci->memos.memomax, f)); for (j = 0; j < ci->memos.memos.size(); j++) { @@ -730,16 +771,18 @@ void save_cs_dbase() void check_modes(Channel * c) { - char modebuf[64], argbuf[BUFSIZE], *end = modebuf, *end2 = argbuf; - uint32 modes = 0; + time_t t = time(NULL); ChannelInfo *ci; - CBModeInfo *cbmi; - CBMode *cbm; + ChannelMode *cm; + ChannelModeParam *cmp; + char modebuf[64], argbuf[BUFSIZE], *end = modebuf, *end2 = argbuf, *value, *csvalue; + std::map::iterator it; + std::string param, ciparam; - if (!c) { - if (debug) { + if (!c) + { + if (debug) alog("debug: check_modes called with NULL values"); - } return; } @@ -747,148 +790,136 @@ void check_modes(Channel * c) return; /* Check for mode bouncing */ - if (c->server_modecount >= 3 && c->chanserv_modecount >= 3) { - ircdproto->SendGlobops(NULL, - "Warning: unable to set modes on channel %s. " - "Are your servers' U:lines configured correctly?", - c->name); + if (c->server_modecount >= 3 && c->chanserv_modecount >= 3) + { + ircdproto->SendGlobops(NULL, "Warning: unable to set modes on channel %s. Are your servers' U:lines configured correctly?", c->name); alog("%s: Bouncy modes on channel %s", s_ChanServ, c->name); c->bouncy_modes = 1; return; } - if (c->chanserv_modetime != time(NULL)) { + if (c->chanserv_modetime != time(NULL)) + { c->chanserv_modecount = 0; - c->chanserv_modetime = time(NULL); + c->chanserv_modetime = t; } c->chanserv_modecount++; /* Check if the channel is registered; if not remove mode -r */ - if (!(ci = c->ci)) { - if (ircd->regmode) { - if (c->mode & ircd->regmode) { - c->mode &= ~ircd->regmode; - ircdproto->SendMode(whosends(ci), c->name, "-r"); - } + if (!(ci = c->ci)) + { + if (c->HasMode(CMODE_REGISTERED)) + { + c->RemoveMode(CMODE_REGISTERED); + ircdproto->SendMode(whosends(ci), c->name, "-r"); } /* Channels that are not regged also need the defcon modes.. ~ Viper */ /* return; */ } - /* Initialize the modes-var to set all modes not set yet but which should - * be set as by mlock and defcon. - */ - if (ci) - modes = ~c->mode & ci->mlock_on; - if (DefConModesSet) - modes |= (~c->mode & DefConModesOn); - - /* Initialize the buffers */ *end++ = '+'; - cbmi = cbmodeinfos; - do { - if (modes & cbmi->flag) { - *end++ = cbmi->mode; - c->mode |= cbmi->flag; + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; + + /* If this channel does not have the mode and the mode is mlocked/defcon'd */ + if (!c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, true)) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true))) + { + *end++ = it->first; + c->SetMode(cm->Name); /* Add the eventual parameter and modify the Channel structure */ - if (cbmi->getvalue && cbmi->csgetvalue) { - char *value; - /* Check if it's a defcon or mlock mode */ - if (DefConModesOn & cbmi->flag) - value = cbmi->csgetvalue(&DefConModesCI); + if (cm->Type == MODE_PARAM) + { + cmp = static_cast(cm); + + param.clear(); + if (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true)) + DefConModesCI.GetParam(cmp->Name, ¶m); else if (ci) - value = cbmi->csgetvalue(ci); - else { - value = NULL; - if (debug) - alog ("Warning: setting modes with unknown origin."); - } + ci->GetParam(cmp->Name, ¶m); + else + alog("Warning: Got no param for mode %c on channel %s but was expecting one", cmp->ModeChar, c->name); - cbm = &cbmodes[static_cast(cbmi->mode)]; - cbm->setvalue(c, value); + if (!param.empty()) + { + value = const_cast(param.c_str()); - if (value) { *end2++ = ' '; while (*value) *end2++ = *value++; } } - } else if (cbmi->getvalue && cbmi->csgetvalue - && ((ci && (ci->mlock_on & cbmi->flag)) - || (DefConModesOn & cbmi->flag)) - && (c->mode & cbmi->flag)) { - char *value = cbmi->getvalue(c); - char *csvalue; - - /* Check if it's a defcon or mlock mode */ - if (DefConModesOn & cbmi->flag) - csvalue = cbmi->csgetvalue(&DefConModesCI); + } + /* If this is a param mode and its mlocked or defcon has it set negative */ + else if (cm->Type == MODE_PARAM && c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, true) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true)))) + { + cmp = static_cast(cm); + + c->GetParam(cmp->Name, ¶m); + + if (DefConModesSet && DefConModesCI.HasMLock(cm->Name, true)) + DefConModesCI.GetParam(cmp->Name, &ciparam); else if (ci) - csvalue = cbmi->csgetvalue(ci); - else { - csvalue = NULL; - if (debug) - alog ("Warning: setting modes with unknown origin."); - } + ci->GetParam(cmp->Name, &ciparam); + else + alog("Warning: Got no param for mode %c on channel %s but was expecting one", cmp->ModeChar, c->name); + + if (!param.empty() && !ciparam.empty() && param != ciparam) + { + value = const_cast(param.c_str()); + csvalue = const_cast(ciparam.c_str()); - /* Lock and actual values don't match, so fix the mode */ - if (value && csvalue && strcmp(value, csvalue)) { - *end++ = cbmi->mode; + *end++ = it->first; - cbm = &cbmodes[static_cast(cbmi->mode)]; - cbm->setvalue(c, csvalue); + c->SetParam(cmp->Name, ciparam); *end2++ = ' '; while (*csvalue) *end2++ = *csvalue++; } } - } while ((++cbmi)->flag != 0); + } - if (*(end - 1) == '+') - end--; + *end++ = '-'; - modes = 0; - if (ci) { - modes = c->mode & ci->mlock_off; - /* Make sure we don't remove a mode just set by defcon.. ~ Viper */ - if (DefConModesSet) - modes &= ~(modes & DefConModesOn); - } - if (DefConModesSet) - modes |= c->mode & DefConModesOff; + for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it) + { + cm = it->second; - if (modes) { - *end++ = '-'; - cbmi = cbmodeinfos; + /* If the channel has the mode */ + if (c->HasMode(cm->Name) && (ci && ci->HasMLock(cm->Name, false)) || (DefConModesSet && DefConModesCI.HasMLock(cm->Name, false))) + { + *end++ = it->first; + c->RemoveMode(cm->Name); - do { - if (modes & cbmi->flag) { - *end++ = cbmi->mode; - c->mode &= ~cbmi->flag; + /* Add the eventual parameter */ + if (cm->Type == MODE_PARAM) + { + cmp = static_cast(cm); - /* Add the eventual parameter and clean up the Channel structure */ - if (cbmi->getvalue) { - cbm = &cbmodes[static_cast(cbmi->mode)]; + if (!cmp->MinusNoArg) + { + c->GetParam(cmp->Name, ¶m); - if (!(cbm->flags & CBM_MINUS_NO_ARG)) { - char *value = cbmi->getvalue(c); + if (!param.empty()) + { + value = const_cast(param.c_str()); - if (value) { - *end2++ = ' '; - while (*value) - *end2++ = *value++; - } - } + *end2++ = ' '; - cbm->setvalue(c, NULL); + while (*value) + *end++ = *value++; + } } } - } while ((++cbmi)->flag != 0); + } } + if (*(end - 1) == '-') + end--; + if (end == modebuf) return; @@ -903,12 +934,13 @@ void check_modes(Channel * c) int check_valid_admin(User * user, Channel * chan, int servermode) { + ChannelMode *cm; + if (!chan || !chan->ci) return 1; - if (!ircd->admin) { + if (!(cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) return 0; - } /* They will be kicked; no need to deop, no need to update our internal struct too */ if (chan->ci->flags & CI_FORBIDDEN) @@ -916,14 +948,14 @@ int check_valid_admin(User * user, Channel * chan, int servermode) if (servermode && !check_access(user, chan->ci, CA_AUTOPROTECT)) { notice_lang(s_ChanServ, user, CHAN_IS_REGISTERED, s_ChanServ); - ircdproto->SendMode(whosends(chan->ci), chan->name, "%s %s", - ircd->adminunset, user->nick); + ircdproto->SendMode(whosends(chan->ci), chan->name, "-%s %s", + cm->ModeChar, user->nick); return 0; } if (check_access(user, chan->ci, CA_AUTODEOP)) { - ircdproto->SendMode(whosends(chan->ci), chan->name, "%s %s", - ircd->adminunset, user->nick); + ircdproto->SendMode(whosends(chan->ci), chan->name, "-%s %s", + cm->ModeChar, user->nick); return 0; } @@ -938,7 +970,7 @@ int check_valid_admin(User * user, Channel * chan, int servermode) int check_valid_op(User * user, Channel * chan, int servermode) { - char *tmp; + ChannelMode *owner, *protect, *halfop; if (!chan || !chan->ci) return 1; @@ -946,34 +978,37 @@ int check_valid_op(User * user, Channel * chan, int servermode) if (chan->ci->flags & CI_FORBIDDEN) return 0; + owner = ModeManager::FindChannelModeByName(CMODE_OWNER); + protect = ModeManager::FindChannelModeByName(CMODE_PROTECT); + halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP); + if (servermode && !check_access(user, chan->ci, CA_AUTOOP)) { notice_lang(s_ChanServ, user, CHAN_IS_REGISTERED, s_ChanServ); - if (ircd->halfop) { - if (ircd->owner && ircd->protect) { + if (halfop) + { + if (owner && protect) + { if (check_access(user, chan->ci, CA_AUTOHALFOP)) { - tmp = stripModePrefix(ircd->ownerunset); ircdproto->SendMode(whosends(chan->ci), chan->name, - "%so%s %s %s %s", ircd->adminunset, - tmp, user->nick, + "-%so%s %s %s %s", protect->ModeChar, + owner->ModeChar, user->nick, user->nick, user->nick); - delete [] tmp; } else { - tmp = stripModePrefix(ircd->ownerunset); ircdproto->SendMode(whosends(chan->ci), chan->name, - "%sho%s %s %s %s %s", - ircd->adminunset, tmp, + "-%sho%s %s %s %s %s", + protect->ModeChar, + owner->ModeChar, user->nick, user->nick, user->nick, user->nick); - delete [] tmp; } - } else if (!ircd->owner && ircd->protect) { + } else if (!owner && protect) { if (check_access(user, chan->ci, CA_AUTOHALFOP)) { ircdproto->SendMode(whosends(chan->ci), chan->name, - "%so %s %s", ircd->adminunset, + "-%so %s %s", protect->ModeChar, user->nick, user->nick); } else { ircdproto->SendMode(whosends(chan->ci), chan->name, - "%soh %s %s %s", ircd->adminunset, + "-%soh %s %s %s", protect->ModeChar, user->nick, user->nick, user->nick); } } else { @@ -993,14 +1028,12 @@ int check_valid_op(User * user, Channel * chan, int servermode) } if (check_access(user, chan->ci, CA_AUTODEOP)) { - if (ircd->halfop) { - if (ircd->owner && ircd->protect) { - tmp = stripModePrefix(ircd->ownerunset); + if (halfop) { + if (owner && protect) { ircdproto->SendMode(whosends(chan->ci), chan->name, - "%sho%s %s %s %s %s", ircd->adminunset, - tmp, user->nick, user->nick, + "-%sho%s %s %s %s %s", protect->ModeChar, + owner->ModeChar, user->nick, user->nick, user->nick, user->nick); - delete [] tmp; } else { ircdproto->SendMode(whosends(chan->ci), chan->name, "-ho %s %s", user->nick, user->nick); @@ -1083,18 +1116,16 @@ int check_should_halfop(User * user, char *chan) int check_should_owner(User * user, char *chan) { - char *tmp; ChannelInfo *ci = cs_findchan(chan); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER); if (!ci || (ci->flags & CI_FORBIDDEN) || *chan == '+') return 0; if (((ci->flags & CI_SECUREFOUNDER) && is_real_founder(user, ci)) || (!(ci->flags & CI_SECUREFOUNDER) && is_founder(user, ci))) { - tmp = stripModePrefix(ircd->ownerset); - ircdproto->SendMode(whosends(ci), chan, "+o%s %s %s", tmp, user->nick, + ircdproto->SendMode(whosends(ci), chan, "+o%s %s %s", cm->ModeChar, user->nick, user->nick); - delete [] tmp; return 1; } @@ -1105,17 +1136,15 @@ int check_should_owner(User * user, char *chan) int check_should_protect(User * user, char *chan) { - char *tmp; ChannelInfo *ci = cs_findchan(chan); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT); if (!ci || (ci->flags & CI_FORBIDDEN) || *chan == '+') return 0; if (check_access(user, ci, CA_AUTOPROTECT)) { - tmp = stripModePrefix(ircd->adminset); - ircdproto->SendMode(whosends(ci), chan, "+o%s %s %s", tmp, user->nick, + ircdproto->SendMode(whosends(ci), chan, "+o%s %s %s", cm->ModeChar, user->nick, user->nick); - delete [] tmp; return 1; } @@ -1181,7 +1210,7 @@ int check_kick(User * user, const char *chan, time_t chants) * * UltimateIRCd 3.x at least informs channel staff when a joining user is matching an exempt. */ - if (ircd->except && is_excepted(ci, user) == 1) { + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, user) == 1) { return 0; } @@ -1460,10 +1489,13 @@ void cs_remove_nick(const NickCore * nc) } } else { alog("%s: Deleting channel %s owned by deleted nick %s", s_ChanServ, ci->name, nc->display); - if (ircd->regmode) { + + if ((ModeManager::FindChannelModeByName(CMODE_REGISTERED))) + { /* Maybe move this to delchan() ? */ - if ((ci->c) && (ci->c->mode & ircd->regmode)) { - ci->c->mode &= ~ircd->regmode; + if (ci->c && ci->c->HasMode(CMODE_REGISTERED)) + { + ci->c->RemoveMode(CMODE_REGISTERED); ircdproto->SendMode(whosends(ci), ci->name, "-r"); } } @@ -1752,16 +1784,6 @@ int delchan(ChannelInfo * ci) if (ci->entry_message) delete [] ci->entry_message; - if (ci->mlock_key) - delete [] ci->mlock_key; - if (ircd->fmode) { - if (ci->mlock_flood) - delete [] ci->mlock_flood; - } - if (ircd->Lmode) { - if (ci->mlock_redirect) - delete [] ci->mlock_redirect; - } if (ci->last_topic) delete [] ci->last_topic; if (ci->forbidby) @@ -1999,137 +2021,9 @@ int get_idealban(ChannelInfo * ci, User * u, char *ret, int retlen) } } -/*************************************************************************/ - -char *cs_get_flood(ChannelInfo * ci) -{ - if (!ci) { - return NULL; - } else { - if (ircd->fmode) - return ci->mlock_flood; - else - return NULL; - } -} - -/*************************************************************************/ - -char *cs_get_key(ChannelInfo * ci) -{ - if (!ci) { - return NULL; - } else { - return ci->mlock_key; - } -} - -/*************************************************************************/ - -char *cs_get_limit(ChannelInfo * ci) -{ - static char limit[16]; - - if (!ci) { - return NULL; - } - - if (ci->mlock_limit == 0) - return NULL; - - snprintf(limit, sizeof(limit), "%lu", - static_cast(ci->mlock_limit)); - return limit; -} - -/*************************************************************************/ - -char *cs_get_redirect(ChannelInfo * ci) -{ - if (!ci) { - return NULL; - } else { - if (ircd->Lmode) - return ci->mlock_redirect; - else - return NULL; - } -} /*************************************************************************/ -void cs_set_flood(ChannelInfo * ci, const char *value) -{ - if (!ci) { - return; - } - - if (ci->mlock_flood) - delete [] ci->mlock_flood; - - /* This looks ugly, but it works ;) */ - if (ircdproto->IsFloodModeParamValid(value)) { - ci->mlock_flood = sstrdup(value); - } else { - ci->mlock_on &= ~ircd->chan_fmode; - ci->mlock_flood = NULL; - } -} - -/*************************************************************************/ - -void cs_set_key(ChannelInfo * ci, const char *value) -{ - if (!ci) { - return; - } - - if (ci->mlock_key) - delete [] ci->mlock_key; - - /* Don't allow keys with a coma */ - if (value && *value != ':' && !strchr(value, ',')) { - ci->mlock_key = sstrdup(value); - } else { - ci->mlock_on &= ~anope_get_key_mode(); - ci->mlock_key = NULL; - } -} - -/*************************************************************************/ - -void cs_set_limit(ChannelInfo * ci, const char *value) -{ - if (!ci) { - return; - } - - ci->mlock_limit = value ? strtoul(value, NULL, 10) : 0; - - if (ci->mlock_limit <= 0) - ci->mlock_on &= ~anope_get_limit_mode(); -} - -/*************************************************************************/ - -void cs_set_redirect(ChannelInfo * ci, const char *value) -{ - if (!ci) { - return; - } - - if (ci->mlock_redirect) - delete [] ci->mlock_redirect; - - /* Don't allow keys with a coma */ - if (value && *value == '#') { - ci->mlock_redirect = sstrdup(value); - } else { - ci->mlock_on &= ~ircd->chan_lmode; - ci->mlock_redirect = NULL; - } -} - int get_access_level(ChannelInfo * ci, NickAlias * na) { ChanAccess *access; @@ -2150,13 +2044,15 @@ int get_access_level(ChannelInfo * ci, NickAlias * na) const char *get_xop_level(int level) { + ChannelMode *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP); + if (level < ACCESS_VOP) { return "Err"; - } else if (ircd->halfop && level < ACCESS_HOP) { + } else if (halfop && level < ACCESS_HOP) { return "VOP"; - } else if (!ircd->halfop && level < ACCESS_AOP) { + } else if (!halfop && level < ACCESS_AOP) { return "VOP"; - } else if (ircd->halfop && level < ACCESS_AOP) { + } else if (halfop && level < ACCESS_AOP) { return "HOP"; } else if (level < ACCESS_SOP) { return "AOP"; diff --git a/src/core/cs_access.c b/src/core/cs_access.c index 59f772dee..2fbca088a 100644 --- a/src/core/cs_access.c +++ b/src/core/cs_access.c @@ -112,7 +112,7 @@ class CommandCSAccess : public Command /* We still allow LIST in xOP mode, but not others */ else if ((ci->flags & CI_XOP) && !is_list) { - if (ircd->halfop) + if (ModeManager::FindChannelModeByName(CMODE_HALFOP)) notice_lang(s_ChanServ, u, CHAN_ACCESS_XOP_HOP, s_ChanServ); else notice_lang(s_ChanServ, u, CHAN_ACCESS_XOP, s_ChanServ); diff --git a/src/core/cs_akick.c b/src/core/cs_akick.c index bd928b316..a9e38fbd2 100644 --- a/src/core/cs_akick.c +++ b/src/core/cs_akick.c @@ -229,7 +229,8 @@ class CommandCSAKick : public Command } /* Check excepts BEFORE we get this far */ - if (ircd->except) { + if (ModeManager::FindChannelModeByName(CMODE_EXCEPT)) + { if (is_excepted_mask(ci, mask) == 1) { notice_lang(s_ChanServ, u, CHAN_EXCEPTED, mask, chan); if (freemask) diff --git a/src/core/cs_ban.c b/src/core/cs_ban.c index bd65f1ac8..9901479ae 100644 --- a/src/core/cs_ban.c +++ b/src/core/cs_ban.c @@ -62,9 +62,9 @@ class CommandCSBan : public Command * Dont ban/kick the user on channels where he is excepted * to prevent services <-> server wars. */ - } else if (ircd->except && is_excepted(ci, u2)) { + } else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && is_excepted(ci, u2)) { notice_lang(s_ChanServ, u, CHAN_EXCEPTED, u2->nick, ci->name); - } else if (ircd->protectedumode && is_protected(u2)) { + } else if (is_protected(u2)) { notice_lang(s_ChanServ, u, ACCESS_DENIED); } else { const char *av[3]; diff --git a/src/core/cs_clear.c b/src/core/cs_clear.c index f9e9ab8bd..699c70a2f 100644 --- a/src/core/cs_clear.c +++ b/src/core/cs_clear.c @@ -29,6 +29,11 @@ class CommandCSClear : public Command ci::string what = params[1]; Channel *c = findchan(chan); ChannelInfo *ci; + ChannelMode *owner, *admin; + std::string modebuf; + + owner = ModeManager::FindChannelModeByName(CMODE_OWNER); + admin = ModeManager::FindChannelModeByName(CMODE_PROTECT); if (c) ci = c->ci; @@ -38,90 +43,22 @@ class CommandCSClear : public Command } else if (!u || !check_access(u, ci, CA_CLEAR)) { notice_lang(s_ChanServ, u, ACCESS_DENIED); } else if (what == "bans") { - const char *av[2]; - Entry *ban, *bnext; - - if (c->bans && c->bans->count) { - for (ban = c->bans->entries; ban; ban = bnext) { - bnext = ban->next; - av[0] = "-b"; - av[1] = ban->mask; - ircdproto->SendMode(whosends(ci), chan, "-b %s", ban->mask); - chan_set_modes(whosends(ci)->nick, c, 2, av, 0); - } - } + c->ClearBans(); notice_lang(s_ChanServ, u, CHAN_CLEARED_BANS, chan); - } else if (ircd->except && what == "excepts") { - const char *av[2]; - Entry *except, *bnext; - - if (c->excepts && c->excepts->count) { - for (except = c->excepts->entries; except; except = bnext) { - bnext = except->next; - av[0] = "-e"; - av[1] = except->mask; - ircdproto->SendMode(whosends(ci), chan, "-e %s", except->mask); - chan_set_modes(whosends(ci)->nick, c, 2, av, 0); - } - } + } else if (ModeManager::FindChannelModeByName(CMODE_EXCEPT) && what == "excepts") { + c->ClearExcepts(); + notice_lang(s_ChanServ, u, CHAN_CLEARED_EXCEPTS, chan); - } else if (ircd->invitemode && what == "invites") { - const char *av[2]; - Entry *invite, *bnext; - - if (c->invites && c->invites->count) { - for (invite = c->invites->entries; invite; invite = bnext) { - bnext = invite->next; - av[0] = "-I"; - av[1] = invite->mask; - ircdproto->SendMode(whosends(ci), chan, "-I %s", invite->mask); - chan_set_modes(whosends(ci)->nick, c, 2, av, 0); - } - } + } else if (ModeManager::FindChannelModeByName(CMODE_INVITE) && what == "invites") { + c->ClearInvites(); + notice_lang(s_C