diff options
author | Adam <Adam@drink-coca-cola.info> | 2010-04-29 17:31:34 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2010-06-18 20:58:52 -0400 |
commit | c1d161dec451ea790ff87078b5d80b1f71a3e9f0 (patch) | |
tree | 2ada0230d0411d10bb1e710d701874d253a4d4aa /src | |
parent | 73e93305c10f349742fad3b2197c6c5dd3aea34e (diff) |
Rewrote all of the server handling code
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 26 | ||||
-rw-r--r-- | src/bots.cpp | 3 | ||||
-rw-r--r-- | src/botserv.c | 2 | ||||
-rw-r--r-- | src/channels.c | 12 | ||||
-rw-r--r-- | src/core/cs_modes.c | 2 | ||||
-rw-r--r-- | src/core/cs_xop.c | 2 | ||||
-rw-r--r-- | src/core/os_defcon.c | 6 | ||||
-rw-r--r-- | src/core/os_jupe.c | 12 | ||||
-rw-r--r-- | src/core/os_noop.c | 2 | ||||
-rw-r--r-- | src/core/os_stats.c | 21 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/modules.c | 4 | ||||
-rw-r--r-- | src/operserv.c | 47 | ||||
-rw-r--r-- | src/protocol.cpp | 4 | ||||
-rw-r--r-- | src/protocol/bahamut.c | 23 | ||||
-rw-r--r-- | src/protocol/inspircd11.c | 13 | ||||
-rw-r--r-- | src/protocol/inspircd12.cpp | 29 | ||||
-rw-r--r-- | src/protocol/ratbox.c | 26 | ||||
-rw-r--r-- | src/protocol/unreal32.c | 23 | ||||
-rw-r--r-- | src/regchannel.cpp | 2 | ||||
-rw-r--r-- | src/servers.c | 702 | ||||
-rw-r--r-- | src/servers.cpp | 576 | ||||
-rw-r--r-- | src/users.c | 21 |
23 files changed, 702 insertions, 858 deletions
diff --git a/src/Makefile b/src/Makefile index 949e7e8ec..be4004ec9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,8 +1,8 @@ OBJS = actions.o base64.o bots.o botserv.o channels.o chanserv.o command.o commands.o compat.o \ - config.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \ - memory.o memoserv.o messages.o misc.o modules.o nickserv.o operserv.o \ - process.o protocol.o send.o servers.o sessions.o slist.o sockets.o opertype.o users.o module.o modulemanager.o configreader.o \ - wildcard.o nickcore.o nickalias.o timers.o modes.o regchannel.o + config.o configreader.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \ + memory.o memoserv.o messages.o misc.o modes.o modules.o module.o modulemanager.o nickalias.o \ + nickcore.o nickserv.o operserv.o process.o protocol.o regchannel.o send.o servers.o sessions.o slist.o \ + sockets.o timers.o opertype.o users.o wildcard.o INCLUDES = ../include/commands.h ../include/defs.h ../include/language.h \ ../include/pseudo.h ../include/sysconf.h ../include/config.h \ @@ -33,20 +33,17 @@ services: $(OBJS) $(MAKEBIN) $(CC) $(CFLAGS) $(OBJS) $(ANOPELIBS) $(MLIBS) -o $@ $(LDFLAGS) $(OBJS): Makefile -modes.o: modes.cpp $(INCLUDES) -timers.o: timers.cpp $(INCLUDES) -nickcore.o: nickcore.cpp $(INCLUDES) -nickalias.o: nickalias.cpp $(INCLUDES) actions.o: actions.c $(INCLUDES) base64.o: base64.c $(INCLUDES) bots.o: bots.cpp $(INCLUDES) botserv.o: botserv.c $(INCLUDES) channels.o: channels.c $(INCLUDES) chanserv.o: chanserv.c $(INCLUDES) -command.o: command.cpp $(INCLUDES) +command.o: command.cpp $(INCLUDES) commands.o: commands.c $(INCLUDES) compat.o: compat.c $(INCLUDES) config.o: config.c $(INCLUDES) +configreader.o: configreader.cpp $(INCLUDES) encrypt.o: encrypt.c $(INCLUDES) init.o: init.c $(INCLUDES) ircd.o: ircd.c $(INCLUDES) @@ -58,23 +55,26 @@ main.o: main.c $(INCLUDES) memory.o: memory.c $(INCLUDES) memoserv.o: memoserv.c $(INCLUDES) messages.o: messages.c $(INCLUDES) +modes.o: modes.cpp $(INCLUDES) modules.o: modules.c $(INCLUDES) module.o: module.cpp $(INCLUDES) modulemanager.o: modulemanager.cpp $(INCLUDES) misc.o: misc.c $(INCLUDES) +nickalias.o: nickalias.cpp $(INCLUDES) +nickcore.o: nickcore.cpp $(INCLUDES) nickserv.o: nickserv.c $(INCLUDES) operserv.o: operserv.c $(INCLUDES) +opertype.o: opertype.cpp $(INCLUDES) process.o: process.c $(INCLUDES) protocol.o: protocol.cpp $(INCLUDES) regchannel.o: regchannel.cpp $(INCLUDES) send.o: send.c $(INCLUDES) -servers.o: servers.c $(INCLUDES) +servers.o: servers.cpp $(INCLUDES) sessions.o: sessions.c $(INCLUDES) slist.o: slist.c $(INCLUDES) -sockets.o: sockets.cpp $(INCLUDES) -opertype.o: opertype.cpp $(INCLUDES) +sockets.o: sockets.cpp $(INCLUDES) +timers.o: timers.cpp $(INCLUDES) users.o: users.c $(INCLUDES) -vsnprintf.o: vsnprintf.c $(INCLUDES) wildcard.o: wildcard.cpp $(INCLUDES) modules: DUMMY diff --git a/src/bots.cpp b/src/bots.cpp index e663d9225..f65f2a35e 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -63,8 +63,7 @@ BotInfo::BotInfo(const std::string &nnick, const std::string &nuser, const std:: insert_bot(this); // XXX, this is ugly, but it needs to stay until hashing of bots is redone in STL. // If we're synchronised with the uplink already, call introduce_user() for this bot. - if (serv_uplink && serv_uplink->sync == SSYNC_DONE) - { + if (Me && Me->GetUplink()->IsSynced()) ircdproto->SendClientIntroduction(this->nick, this->user, this->host, this->real, ircd->pseudoclient_mode, this->uid); ircdproto->SendSQLine(this->nick, "Reserved for services"); } diff --git a/src/botserv.c b/src/botserv.c index 54b968dec..05c8ea2bd 100644 --- a/src/botserv.c +++ b/src/botserv.c @@ -665,7 +665,7 @@ static void check_ban(ChannelInfo *ci, User *u, int ttbtype) return; /* Don't ban ulines */ - if (is_ulined(u->server->name)) + if (u->server->IsULined()) return; bd->ttb[ttbtype]++; diff --git a/src/channels.c b/src/channels.c index b98a2f579..557894eff 100644 --- a/src/channels.c +++ b/src/channels.c @@ -118,7 +118,7 @@ void Channel::Sync() stick_all(this->ci); } - if (serv_uplink && is_sync(serv_uplink) && !this->topic_sync) + if (Me && Me->IsSynced() && !this->topic_sync) restore_topic(name.c_str()); } @@ -146,7 +146,7 @@ void Channel::JoinUser(User *user) } /* Added channelname to entrymsg - 30.03.2004, Certus */ /* Also, don't send the entrymsg when bursting -GD */ - if (this->ci && this->ci->entry_message && is_sync(user->server)) + if (this->ci && this->ci->entry_message && user->server->IsSynced()) user->SendMessage(whosends(this->ci)->nick, "[%s] %s", this->name.c_str(), this->ci->entry_message); } @@ -158,7 +158,7 @@ void Channel::JoinUser(User *user) * But don't join the bot if the channel is persistant - Adam * But join persistant channels when syncing with our uplink- DP **/ - if (Config.s_BotServ && this->ci && this->ci->bi && ((serv_uplink->sync == SSYNC_IN_PROGRESS) || !this->ci->HasFlag(CI_PERSIST))) + if (Config.s_BotServ && this->ci && this->ci->bi && (!Me->IsSynced() || !this->ci->HasFlag(CI_PERSIST))) { if (this->users.size() == Config.BSMinUsers) bot_join(this->ci); @@ -172,7 +172,7 @@ void Channel::JoinUser(User *user) * to has synced, or we'll get greet-floods when the net * recovers from a netsplit. -GD */ - if (is_sync(user->server)) + if (user->server->IsSynced()) { ircdproto->SendPrivmsg(this->ci->bi, this->name.c_str(), "[%s] %s", user->Account()->display, user->Account()->greet); this->ci->bi->lastmsg = time(NULL); @@ -975,7 +975,7 @@ bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...) va_end(args); /* May not kick ulines */ - if (is_ulined(u->server->name)) + if (u->server->IsULined()) return false; EventReturn MOD_RESULT; @@ -1513,7 +1513,7 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) c->SetMode(NULL, CMODE_VOICE, user->nick); } /* If this channel has secureops or the user matches autodeop or the channel is syncing and this is the first user and they are not ulined, check to remove modes */ - if ((ci->HasFlag(CI_SECUREOPS) || check_access(user, ci, CA_AUTODEOP) || (c->HasFlag(CH_SYNCING) && c->users.size() == 1)) && !is_ulined(user->server->name)) + if ((ci->HasFlag(CI_SECUREOPS) || check_access(user, ci, CA_AUTODEOP) || (c->HasFlag(CH_SYNCING) && c->users.size() == 1)) && !user->server->IsULined()) { if (owner && c->HasUserStatus(user, CMODE_OWNER) && !IsFounder(user, ci)) c->RemoveMode(NULL, CMODE_OWNER, user->nick); diff --git a/src/core/cs_modes.c b/src/core/cs_modes.c index 3df93d912..06e737eff 100644 --- a/src/core/cs_modes.c +++ b/src/core/cs_modes.c @@ -380,7 +380,7 @@ class CSModes : public Module this->AddCommand(CHANSERV, new CommandCSVoice()); this->AddCommand(CHANSERV, new CommandCSDeVoice()); - if (serv_uplink && is_sync(serv_uplink)) + if (Me && Me->IsSynced()) OnUplinkSync(); Implementation i[] = { diff --git a/src/core/cs_xop.c b/src/core/cs_xop.c index a6f980ad0..18ff222b1 100644 --- a/src/core/cs_xop.c +++ b/src/core/cs_xop.c @@ -544,7 +544,7 @@ class CSXOP : public Module this->AddCommand(CHANSERV, new CommandCSAOP()); this->AddCommand(CHANSERV, new CommandCSVOP()); - if (serv_uplink && is_sync(serv_uplink)) + if (Me && Me->IsSynced()) OnUplinkSync(); Implementation i[] = { diff --git a/src/core/os_defcon.c b/src/core/os_defcon.c index 403ac1281..654ed89cc 100644 --- a/src/core/os_defcon.c +++ b/src/core/os_defcon.c @@ -156,13 +156,11 @@ class OSDEFCON : public Module EventReturn OnPreUserConnect(User *u) { - std::string mask; - - if (u && is_sync(u->server) && CheckDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(u->server->name)) + if (u->server->IsSynced() && CheckDefCon(DEFCON_AKILL_NEW_CLIENTS) && !u->server->IsULined()) { if (CheckDefCon(DEFCON_AKILL_NEW_CLIENTS)) { - mask = "*@" + std::string(u->host); + std::string mask = "*@" + std::string(u->host); Alog() << "DEFCON: adding akill for " << mask; add_akill(NULL, mask.c_str(), Config.s_OperServ, time(NULL) + Config.DefConAKILL, diff --git a/src/core/os_jupe.c b/src/core/os_jupe.c index 9af3d3176..899dd4ea4 100644 --- a/src/core/os_jupe.c +++ b/src/core/os_jupe.c @@ -25,18 +25,20 @@ class CommandOSJupe : public Command { const char *jserver = params[0].c_str(); const char *reason = params.size() > 1 ? params[1].c_str() : NULL; - Server *server = findserver(servlist, jserver); + Server *server = Server::Find(jserver); if (!isValidHost(jserver, 3)) notice_lang(Config.s_OperServ, u, OPER_JUPE_HOST_ERROR); - else if (server && (server->HasFlag(SERVER_ISME) || server->HasFlag(SERVER_ISUPLINK))) + else if (server && (server == Me || server == Me->GetUplink())) notice_lang(Config.s_OperServ, u, OPER_JUPE_INVALID_SERVER); - else { + else + { char rbuf[256]; snprintf(rbuf, sizeof(rbuf), "Juped by %s%s%s", u->nick.c_str(), reason ? ": " : "", reason ? reason : ""); - if (findserver(servlist, jserver)) + if (server) ircdproto->SendSquit(jserver, rbuf); - Server *juped_server = new_server(me_server, jserver, rbuf, SERVER_JUPED, ircd->ts6 ? ts6_sid_retrieve() : ""); + Server *juped_server = new Server(Me, jserver, 0, rbuf, ircd->ts6 ? ts6_sid_retrieve() : ""); + juped_server->SetFlag(SERVER_JUPED); ircdproto->SendServer(juped_server); if (Config.WallOSJupe) diff --git a/src/core/os_noop.c b/src/core/os_noop.c index c0fc33161..eec054ea4 100644 --- a/src/core/os_noop.c +++ b/src/core/os_noop.c @@ -44,7 +44,7 @@ class CommandOSNOOP : public Command for (u2 = firstuser(); u2; u2 = u3) { u3 = nextuser(); - if (u2 && is_oper(u2) && u2->server->name && Anope::Match(u2->server->name, server, true)) + if (u2 && is_oper(u2) && Anope::Match(u2->server->GetName(), server, true)) kill_user(Config.s_OperServ, u2->nick.c_str(), reason.c_str()); } } diff --git a/src/core/os_stats.c b/src/core/os_stats.c index 711e1f646..9dae3474a 100644 --- a/src/core/os_stats.c +++ b/src/core/os_stats.c @@ -21,16 +21,19 @@ void get_operserv_stats(long *nrec, long *memuse); * @param s The server to start counting from * @return Amount of servers connected to server s **/ -int stats_count_servers(Server *s) +static int stats_count_servers(Server *s) { - int count = 0; + if (!s) + return 0; + + int count = 1; - while (s) + if (s->GetLinks()) { - ++count; - if (s->links) - count += stats_count_servers(s->links); - s = s->next; + for (std::list<Server *>::const_iterator it = s->GetLinks()->begin(); it != s->GetLinks()->end(); ++it) + { + count += stats_count_servers(*it); + } } return count; @@ -214,9 +217,9 @@ class CommandOSStats : public Command if (!buf.empty()) buf.erase(buf.begin()); - notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER, serv_uplink->name); + notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER, Me->GetUplink()->GetName().c_str()); notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_CAPAB, buf.c_str()); - notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER_COUNT, stats_count_servers(serv_uplink)); + notice_lang(Config.s_OperServ, u, OPER_STATS_UPLINK_SERVER_COUNT, stats_count_servers(Me->GetUplink())); return MOD_CONT; } diff --git a/src/main.c b/src/main.c index d17d98a39..234a2e023 100644 --- a/src/main.c +++ b/src/main.c @@ -235,8 +235,6 @@ static void services_shutdown() if (started && UplinkSock) { ircdproto->SendSquit(Config.ServerName, quitmsg); - if (uplink) - delete [] uplink; u = firstuser(); while (u) { next = nextuser(); diff --git a/src/modules.c b/src/modules.c index af3aa2f4d..97a3b55c6 100644 --- a/src/modules.c +++ b/src/modules.c @@ -76,10 +76,6 @@ int protocol_module_init() Alog() << "This IRCd protocol requires a server id to be set in Anope's configuration."; ret = -1; } - else - { - ts6_uid_init(); - } } } diff --git a/src/operserv.c b/src/operserv.c index 455d74923..a5d0f0d61 100644 --- a/src/operserv.c +++ b/src/operserv.c @@ -144,60 +144,49 @@ void operserv(User * u, char *buf) /*************************************************************************/ /*********************** OperServ command functions **********************/ -/*************************************************************************/ +/******************************* + * ******************************************/ /*************************************************************************/ -Server *server_global(Server * s, char *msg) +void server_global(Server *s, const std::string &message) { - Server *sl; - - while (s) { - /* Do not send the notice to ourselves our juped servers */ - if (!s->HasFlag(SERVER_ISME) && !s->HasFlag(SERVER_JUPED)) - notice_server(Config.s_GlobalNoticer, s, "%s", msg); - - if (s->links) { - sl = server_global(s->links, msg); - if (sl) - s = sl; - else - s = s->next; - } else { - s = s->next; + /* Do not send the notice to ourselves our juped servers */ + if (s != Me && !s->HasFlag(SERVER_JUPED)) + notice_server(Config.s_GlobalNoticer, s, "%s", message.c_str()); + + if (s->GetLinks()) + { + for (std::list<Server *>::const_iterator it = s->GetLinks()->begin(); it != s->GetLinks()->end(); ++it) + { + server_global(*it, message); } } - return s; - } void oper_global(char *nick, const char *fmt, ...) { va_list args; char msg[2048]; /* largest valid message is 512, this should cover any global */ - char dmsg[2048]; /* largest valid message is 512, this should cover any global */ va_start(args, fmt); vsnprintf(msg, sizeof(msg), fmt, args); va_end(args); /* I don't like the way this is coded... */ - if ((nick) && (!Config.AnonymousGlobal)) { - snprintf(dmsg, sizeof(dmsg), "[%s] %s", nick, msg); - server_global(servlist, dmsg); - } else { - server_global(servlist, msg); + if (nick && !Config.AnonymousGlobal) + { + std::string rmsg = std::string("[") + nick + std::string("] ") + msg; + server_global(Me->GetUplink(), rmsg.c_str()); } + else + server_global(Me->GetUplink(), msg); } /**************************************************************************/ - -/************************************************************************/ -/*************************************************************************/ - /* Adds an AKILL to the list. Returns >= 0 on success, -1 if it fails, -2 * if only the expiry time was changed. * The success result is the number of AKILLs that were deleted to successfully add one. diff --git a/src/protocol.cpp b/src/protocol.cpp index 2188e86ba..761df1ca1 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -153,12 +153,12 @@ void IRCDProto::SendPrivmsg(BotInfo *bi, const char *dest, const char *fmt, ...) void IRCDProto::SendGlobalNotice(BotInfo *bi, Server *dest, const char *msg) { - send_cmd(ircd->ts6 ? bi->uid : bi->nick, "NOTICE %s%s :%s", ircd->globaltldprefix, dest->name, msg); + send_cmd(ircd->ts6 ? bi->uid : bi->nick, "NOTICE %s%s :%s", ircd->globaltldprefix, dest->GetName().c_str(), msg); } void IRCDProto::SendGlobalPrivmsg(BotInfo *bi, Server *dest, const char *msg) { - send_cmd(ircd->ts6 ? bi->uid : bi->nick, "PRIVMSG %s%s :%s", ircd->globaltldprefix, dest->name, msg); + send_cmd(ircd->ts6 ? bi->uid : bi->nick, "PRIVMSG %s%s :%s", ircd->globaltldprefix, dest->GetName().c_str(), msg); } void IRCDProto::SendQuit(const char *nick, const char *) diff --git a/src/protocol/bahamut.c b/src/protocol/bahamut.c index 1e38a4aa2..d84d3f25a 100644 --- a/src/protocol/bahamut.c +++ b/src/protocol/bahamut.c @@ -273,15 +273,15 @@ class BahamutIRCdProto : public IRCDProto /* SERVER */ void SendServer(Server *server) { - send_cmd(NULL, "SERVER %s %d :%s", server->name, server->hops, server->desc); + send_cmd(NULL, "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str()); } void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, ""); bahamut_cmd_pass(uplink_server->password); bahamut_cmd_capab(); - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, ""); - SendServer(me_server); + SendServer(Me); bahamut_cmd_svinfo(); bahamut_cmd_burst(); } @@ -575,11 +575,7 @@ int anope_event_436(const char *source, int ac, const char **av) /* EVENT : SERVER */ int anope_event_server(const char *source, int ac, const char **av) { - if (!stricmp(av[1], "1")) { - uplink = sstrdup(av[0]); - } - - do_server(source, av[0], av[1], av[2], ""); + do_server(source, av[0], atoi(av[1]), av[2], ""); return MOD_CONT; } @@ -711,8 +707,8 @@ int anope_event_error(const char *source, int ac, const char **av) int anope_event_burst(const char *source, int ac, const char **av) { - Server *s; - s = findserver(servlist, source); + Server *s = Server::Find(source ? source : ""); + if (!ac) { /* for future use - start burst */ } else { @@ -720,9 +716,10 @@ int anope_event_burst(const char *source, int ac, const char **av) * finished bursting. If there was no source, then our uplink * server finished bursting. -GD */ - if (!s && serv_uplink) - s = serv_uplink; - finish_sync(s, 1); + if (!s) + s = Me->GetUplink(); + if (s) + s->Sync(true); } return MOD_CONT; } diff --git a/src/protocol/inspircd11.c b/src/protocol/inspircd11.c index b5c55cfa8..764b887de 100644 --- a/src/protocol/inspircd11.c +++ b/src/protocol/inspircd11.c @@ -204,7 +204,7 @@ class InspIRCdProto : public IRCDProto /* SERVER services-dev.chatspike.net password 0 :Description here */ void SendServer(Server *server) { - send_cmd(Config.ServerName, "SERVER %s %s %d :%s", server->name, currentpass, server->hops, server->desc); + send_cmd(Config.ServerName, "SERVER %s %s %d :%s", server->GetName().c_str(), currentpass, server->GetHops(), server->GetDescription().c_str()); } /* JOIN */ @@ -248,9 +248,9 @@ class InspIRCdProto : public IRCDProto void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, ""); inspircd_cmd_pass(uplink_server->password); - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, ""); - SendServer(me_server); + SendServer(Me); send_cmd(NULL, "BURST"); send_cmd(Config.ServerName, "VERSION :Anope-%s %s :%s - %s (%s) -- %s", version_number, Config.ServerName, ircd->name, version_flags, Config.EncModuleList.begin()->c_str(), version_build); } @@ -823,10 +823,7 @@ int anope_event_chghost(const char *source, int ac, const char **av) /* EVENT: SERVER */ int anope_event_server(const char *source, int ac, const char **av) { - if (!stricmp(av[1], "1")) { - uplink = sstrdup(av[0]); - } - do_server(source, av[0], av[1], av[2], ""); + do_server(source, av[0], atoi(av[1]), av[2], ""); return MOD_CONT; } @@ -1100,7 +1097,7 @@ int anope_event_capab(const char *source, int ac, const char **av) int anope_event_endburst(const char *source, int ac, const char **av) { - finish_sync(serv_uplink, 1); + Me->GetUplink()->Sync(true); return MOD_CONT; } diff --git a/src/protocol/inspircd12.cpp b/src/protocol/inspircd12.cpp index 4ad390f00..5ff9db94b 100644 --- a/src/protocol/inspircd12.cpp +++ b/src/protocol/inspircd12.cpp @@ -209,7 +209,7 @@ class InspIRCdProto : public IRCDProto /* SERVER services-dev.chatspike.net password 0 :Description here */ void SendServer(Server *server) { - send_cmd(NULL, "SERVER %s %s %d %s :%s", server->name, currentpass, server->hops, server->suid, server->desc); + send_cmd(NULL, "SERVER %s %s %d %s :%s", server->GetName().c_str(), currentpass, server->GetHops(), server->GetSID().c_str(), server->GetDescription().c_str()); } /* JOIN */ @@ -252,9 +252,9 @@ class InspIRCdProto : public IRCDProto void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, TS6SID); inspircd_cmd_pass(uplink_server->password); - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, TS6SID); - SendServer(me_server); + SendServer(Me); send_cmd(TS6SID, "BURST"); send_cmd(TS6SID, "VERSION :Anope-%s %s :%s - %s (%s) -- %s", version_number, Config.ServerName, ircd->name, version_flags, Config.EncModuleList.begin()->c_str(), version_build); } @@ -837,7 +837,7 @@ int anope_event_uid(const char *source, int ac, const char **av) User *user; NickAlias *na; struct in_addr addy; - Server *s = findserver_uid(servlist, source); + Server *s = Server::Find(source ? source : ""); uint32 *ad = reinterpret_cast<uint32 *>(&addy); int ts = strtoul(av[1], NULL, 10); @@ -846,7 +846,7 @@ int anope_event_uid(const char *source, int ac, const char **av) user = prev_u_intro; prev_u_intro = NULL; if (user) na = findnick(user->nick); - if (user && user->server->sync == SSYNC_IN_PROGRESS && (!na || na->nc != user->Account())) + if (user && !user->server->IsSynced() && (!na || na->nc != user->Account())) { validate_user(user); if (user->HasMode(UMODE_REGISTERED)) @@ -858,14 +858,14 @@ int anope_event_uid(const char *source, int ac, const char **av) user = do_nick("", av[2], /* nick */ av[5], /* username */ av[3], /* realhost */ - s->name, /* server */ + s->GetName().c_str(), /* server */ av[ac - 1], /* realname */ ts, htonl(*ad), av[4], av[0]); if (user) { UserSetInternalModes(user, 1, &av[8]); user->SetCloakedHost(av[4]); - if (user->server->sync == SSYNC_IN_PROGRESS) + if (!user->server->IsSynced()) { prev_u_intro = user; } @@ -903,11 +903,7 @@ int anope_event_chghost(const char *source, int ac, const char **av) */ int anope_event_server(const char *source, int ac, const char **av) { - if (!stricmp(av[2], "0")) - { - uplink = sstrdup(av[0]); - } - do_server(source, av[0], av[2], av[4], av[3]); + do_server(source, av[0], atoi(av[2]), av[4], av[3]); return MOD_CONT; } @@ -1308,7 +1304,8 @@ int anope_event_endburst(const char *source, int ac, const char **av) { NickAlias *na; User *u = prev_u_intro; - Server *s = findserver_uid(servlist, source); + Server *s = Server::Find(source ? source : ""); + if (!s) { throw new CoreException("Got ENDBURST without a source"); @@ -1318,16 +1315,16 @@ int anope_event_endburst(const char *source, int ac, const char **av) * If not, validate the user. ~ Viper*/ prev_u_intro = NULL; if (u) na = findnick(u->nick); - if (u && u->server->sync == SSYNC_IN_PROGRESS && (!na || na->nc != u->Account())) + if (u && !u->server->IsSynced() && (!na || na->nc != u->Account())) { validate_user(u); if (u->HasMode(UMODE_REGISTERED)) u->RemoveMode(findbot(Config.s_NickServ), UMODE_REGISTERED); } - Alog() << "Processed ENDBURST for " << s->name; + Alog() << "Processed ENDBURST for " << s->GetName(); - finish_sync(s, 1); + s->Sync(true); return MOD_CONT; } diff --git a/src/protocol/ratbox.c b/src/protocol/ratbox.c index 8d0a84826..ace2a650c 100644 --- a/src/protocol/ratbox.c +++ b/src/protocol/ratbox.c @@ -14,6 +14,8 @@ #include "services.h" #include "pseudo.h" +static char *TS6UPLINK = NULL; // XXX is this needed? + IRCDVar myIrcd[] = { {"Ratbox 2.0+", /* ircd name */ "+oi", /* Modes used by pseudoclients */ @@ -190,16 +192,16 @@ class RatboxProto : public IRCDTS6Proto /* SERVER name hop descript */ void SendServer(Server *server) { - send_cmd(NULL, "SERVER %s %d :%s", server->name, server->hops, server->desc); + send_cmd(NULL, "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str()); } void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, TS6SID); ratbox_cmd_pass(uplink_server->password); ratbox_cmd_capab(); /* Make myself known to myself in the serverlist */ - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, TS6SID); - SendServer(me_server); + SendServer(Me); ratbox_cmd_svinfo(); } @@ -457,14 +459,13 @@ int anope_event_sjoin(const char *source, int ac, const char **av) */ int anope_event_nick(const char *source, int ac, const char **av) { - Server *s; User *user; if (ac == 9) { - s = findserver_uid(servlist, source); + Server *s = Server::Find(source ? source : ""); /* Source is always the server */ - user = do_nick("", av[0], av[4], av[5], s->name, av[8], + user = do_nick("", av[0], av[4], av[5], s->GetName().c_str(), av[8], strtoul(av[2], NULL, 10), 0, "*", av[7]); if (user) { @@ -681,27 +682,24 @@ int anope_event_whois(const char *source, int ac, const char **av) int anope_event_server(const char *source, int ac, const char **av) { if (!stricmp(av[1], "1")) { - uplink = sstrdup(av[0]); if (TS6UPLINK) { - do_server(source, av[0], av[1], av[2], TS6UPLINK); + do_server(source, av[0], atoi(av[1]), av[2], TS6UPLINK); } else { - do_server(source, av[0], av[1], av[2], ""); + do_server(source, av[0], atoi(av[1]), av[2], ""); } } else { - do_server(source, av[0], av[1], av[2], ""); + do_server(source, av[0], atoi(av[1]), av[2], ""); } return MOD_CONT; } int anope_event_sid(const char *source, int ac, const char **av) { - Server *s; - /* :42X SID trystan.nomadirc.net 2 43X :ircd-ratbox test server */ - s = findserver_uid(servlist, source); + Server *s = Server::Find(source); - do_server(s->name, av[0], av[1], av[3], av[2]); + do_server(s->GetName(), av[0], atoi(av[1]), av[3], av[2]); return MOD_CONT; } diff --git a/src/protocol/unreal32.c b/src/protocol/unreal32.c index 3564fecd6..aeb35ee88 100644 --- a/src/protocol/unreal32.c +++ b/src/protocol/unreal32.c @@ -216,9 +216,9 @@ class UnrealIRCdProto : public IRCDProto void SendServer(Server *server) { if (Config.Numeric) - send_cmd(NULL, "SERVER %s %d :U0-*-%s %s", server->name, server->hops, Config.Numeric, server->desc); + send_cmd(NULL, "SERVER %s %d :U0-*-%s %s", server->GetName().c_str(), server->GetHops(), Config.Numeric, server->GetDescription().c_str()); else - send_cmd(NULL, "SERVER %s %d :%s", server->name, server->hops, server->desc); + send_cmd(NULL, "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str()); } /* JOIN */ @@ -286,10 +286,10 @@ class UnrealIRCdProto : public IRCDProto void SendConnect() { + Me = new Server(NULL, Config.ServerName, 0, Config.ServerDesc, (Config.Numeric ? Config.Numeric : "")); unreal_cmd_capab(); unreal_cmd_pass(uplink_server->password); - me_server = new_server(NULL, Config.ServerName, Config.ServerDesc, SERVER_ISME, (Config.Numeric ? Config.Numeric : "")); - SendServer(me_server); + SendServer(Me); } /* SVSHOLD - set */ @@ -701,7 +701,7 @@ int anope_event_mode(const char *source, int ac, const char **av) /* This is used to strip the TS from the end of the mode stirng */ int anope_event_gmode(const char *source, int ac, const char **av) { - if (findserver(servlist, source)) + if (Server::Find(source)) --ac; return anope_event_mode(source, ac, av); } @@ -966,16 +966,15 @@ int anope_event_server(const char *source, int ac, const char **av) char *upnumeric; if (!stricmp(av[1], "1")) { - uplink = sstrdup(av[0]); vl = myStrGetToken(av[2], ' ', 0); upnumeric = myStrGetToken(vl, '-', 2); desc = myStrGetTokenRemainder(av[2], ' ', 1); - do_server(source, av[0], av[1], desc, upnumeric); + do_server(source, av[0], atoi(av[1]), desc, upnumeric); delete [] vl; delete [] desc; delete [] upnumeric; } else { - do_server(source, av[0], av[1], av[2], ""); + do_server(source, av[0], atoi(av[1]), av[2], ""); } ircdproto->SendPing(Config.ServerName, av[0]); @@ -1021,12 +1020,10 @@ int anope_event_error(const char *source, int ac, const char **av) int anope_event_sdesc(const char *source, int ac, const char **av) { - Server *s; - s = findserver(servlist, source); + Server *s = Server::Find(source ? source : ""); - if (s) { - s->desc = const_cast<char *>(av[0]); // XXX Unsafe cast -- CyberBotX - } + if (s) + s->SetDescription(av[0]); return MOD_CONT; } diff --git a/src/regchannel.cpp b/src/regchannel.cpp index 8eb4b28f0..d70985f9c 100644 --- a/src/regchannel.cpp +++ b/src/regchannel.cpp @@ -578,7 +578,7 @@ bool ChannelInfo::CheckKick(User *user) /* We don't enforce services restrictions on clients on ulined services * as this will likely lead to kick/rejoin floods. ~ Viper */ - if (is_ulined(user->server->name)) + if (user->server->IsULined()) return false; if (!is_oper(user) && (this->HasFlag(CI_SUSPENDED) || this->HasFlag(CI_FORBIDDEN))) diff --git a/src/servers.c b/src/servers.c deleted file mode 100644 index 0978e8f30..000000000 --- a/src/servers.c +++ /dev/null @@ -1,702 +0,0 @@ -/* Routines to maintain a list of connected servers - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ - -#include "services.h" -#include "modules.h" - -Server *servlist = NULL; -Server *me_server = NULL; /* This are we */ -Server *serv_uplink = NULL; /* This is our uplink */ -Flags<CapabType> Capab; -char *uplink; -char *TS6UPLINK; -char *TS6SID; - -/* For first_server / next_server */ -static Server *server_cur; - -CapabInfo Capab_Info[] = { - {"NOQUIT", CAPAB_NOQUIT}, - {"TSMODE", CAPAB_TSMODE}, - {"UNCONNECT", CAPAB_UNCONNECT}, - {"NICKIP", CAPAB_NICKIP}, - {"SSJOIN", CAPAB_NSJOIN}, - {"ZIP", CAPAB_ZIP}, - {"BURST", CAPAB_BURST}, - {"TS5", CAPAB_TS5}, - {"TS3", CAPAB_TS3}, - {"DKEY", CAPAB_DKEY}, - {"PT4", CAPAB_PT4}, - {"SCS", CAPAB_SCS}, - {"QS", CAPAB_QS}, - {"UID", CAPAB_UID}, - {"KNOCK", CAPAB_KNOCK}, - {"CLIENT", CAPAB_CLIENT}, - {"IPV6", CAPAB_IPV6}, - {"SSJ5", CAPAB_SSJ5}, - {"SN2", CAPAB_SN2}, - {"TOK1", CAPAB_TOKEN}, - {"TOKEN", CAPAB_TOKEN}, - {"VHOST", CAPAB_VHOST}, - {"SSJ3", CAPAB_SSJ3}, - {"SJB64", CAPAB_SJB64}, - {"CHANMODES", CAPAB_CHANMODE}, - {"NICKCHARS", CAPAB_NICKCHARS}, - {"", CAPAB_END} -}; - -/*************************************************************************/ - -/** - * Return the first server in the server struct - * @param flag Server Flag, see services.h - * @return Server Struct - */ -Server *first_server(ServerFlag flag) -{ - server_cur = servlist; - - while (server_cur && !server_cur->HasFlag(flag)) - server_cur = next_server(flag); - return server_cur; -} - -/*************************************************************************/ - -/** - * Return the next server in the server struct - * @param flags Server Flags, see services.h - * @return Server Struct - */ -Server *next_server(ServerFlag flag) -{ - if (!server_cur) - return NULL; - - do { - if (server_cur->links) { - server_cur = server_cur->links; - } else if (server_cur->next) { - server_cur = server_cur->next; - } else { - do { - server_cur = server_cur->uplink; - if (server_cur && server_cur->next) { - server_cur = server_cur->next; - break; - } - } while (server_cur); - } - } while (server_cur && !server_cur->HasFlag(flag)); - - return server_cur; -} - -/*************************************************************************/ - -/** - * This function makes a new Server structure and links it in the right - * places in the linked list if a Server struct to it's uplink if provided. - * It can also be NULL to indicate it's the uplink and should be first in - * the server list. - * @param server_uplink Server struct - * @param name Server Name - * @param desc Server Description - * @param flags Server Flags, see services.h - * @param suid Server Universal ID - * @return Server Struct - */ -Server *new_server(Server * server_uplink, const char *name, const char *desc, - ServerFlag flag, const std::string &suid) -{ - Server *serv; - - Alog(LOG_DEBUG) << "Creating " << name << "(" << suid << ") uplinked to " << (server_uplink ? server_uplink->name : "No uplink"); - serv = new Server; - if (!name) - name = ""; - serv->name = sstrdup(name); - serv->desc = sstrdup(desc); - if (flag != SERVER_START) - serv->SetFlag(flag); - serv->uplink = server_uplink; - if (!suid.empty()) - serv->suid = sstrdup(suid.c_str()); - else - serv->suid = NULL; - - serv->sync = SSYNC_IN_PROGRESS; - serv->links = NULL; - serv->prev = NULL; - - if (!server_uplink) { - serv->hops = 0; - serv->next = servlist; - if (servlist) - servlist->prev = serv; - servlist = serv; - } else { - serv->hops = server_uplink->hops + 1; - serv->next = server_uplink->links; - if (server_uplink->links) - server_uplink->links->prev = serv; - server_uplink->links = serv; - } - - /* Check if this is our uplink server */ - if ((server_uplink == me_server) && flag != SERVER_JUPED) - { - // XXX: Apparantly we set ourselves as serv_uplink before we (really) set the uplink when we recieve SERVER. This is wrong and ugly. - if (serv_uplink != NULL) - { - /* Bring in our pseudo-clients */ - introduce_user(""); - - /* And hybrid needs Global joined in the logchan */ - if (LogChan && ircd->join2msg) { - /* XXX might desync */ - ircdproto->SendJoin(findbot(Config.s_GlobalNoticer), Config.LogChannel, time(NULL)); - } - } - serv_uplink = serv; - serv->SetFlag(SERVER_ISUPLINK); - } - - return serv; -} - -/*************************************************************************/ - -/** - * Remove and free a Server structure. This function is the most complete - * remove treatment a server can get, as it first quits all clients which - * still pretend to be on this server, then it walks through all connected - * servers and disconnects them too. If all mess is cleared, the server - * itself will be too. - * @param Server struct - * @param reason the server quit - * @return void - */ -static void delete_server(Server * serv, const char *quitreason) -{ - Server *s, *snext; - User *u, *unext; - NickAlias *na; - - if (!serv) { - Alog(LOG_DEBUG) << "delete_server() called with NULL arg!"; - return; - } - - Alog(LOG_DEBUG) << "delete_server() called, deleting " << serv->name << "(" << serv->suid << ") uplinked to " - << (serv->uplink ? serv->uplink->name : "NOTHING") << "(" - << (serv->uplink ? serv->uplink->suid : "NOSUIDUPLINK") << ")"; - - if (Capab.HasFlag(CAPAB_NOQUIT) || Capab.HasFlag(CAPAB_QS)) - { - u = firstuser(); - while (u) - { - unext = nextuser(); - if (u->server == serv) - { - if ((na = findnick(u->nick)) && !na->HasFlag(NS_FORBIDDEN) - && (!na->nc->HasFlag(NI_SUSPENDED)) - && (u->IsRecognized() || u->IsIdentified())) { - na->last_seen = time(NULL); - if (na->last_quit) - delete [] na->last_quit; - na->last_quit = (quitreason ? sstrdup(quitreason) : NULL); - } - if (Config.LimitSessions && !is_ulined(u->server->name)) { - del_session(u->host); - } - delete u; - } - u = unext; - } - Alog(LOG_DEBUG) << "delete_server() cleared all users"; - } - - s = serv->links; - while (s) { - snext = s->next; - delete_server(s, quitreason); - s = snext; - } - - Alog(LOG_DEBUG) << "delete_server() cleared all servers"; - - delete [] serv->name; - delete [] serv->desc; - if (serv->prev) - serv->prev->next = serv->next; - if (serv->next) - serv->next->prev = serv->prev; - if (serv->uplink->links == serv) - serv->uplink->links = serv->next; - - Alog(LOG_DEBUG) << "delete_server() completed"; -} - -/*************************************************************************/ - -/** - * Find a server by name, returns NULL if not found - * @param s Server struct - * @param name Server Name - * @return Server struct - */ -Server *findserver(Server * s, const char *name) -{ - Server *sl; - - if (!name || !*name) { - return NULL; - } - - Alog(LOG_DEBUG) << "findserver(" << name << ")"; - - while (s && (stricmp(s->name, name) != 0)) - { - Alog(LOG_DEBUG_3) << "Compared " << s->name << ", not a match"; - if (s->links) - { - sl = findserver(s->links, name); - if (sl) - { - s = sl; - } - else - { - s = s->next; - } - } - else - { - s = s->next; - } - } - - Alog(LOG_DEBUG) << "findserver(" << name << ") -> " << static_cast<void *>(s); - return s; -} - -/*************************************************************************/ - -/** - * Find a server by UID, returns NULL if not found - * @param s Server struct - * @param name Server Name - * @return Server struct - */ -Server *findserver_uid(Server * s, const char *name) -{ - Server *sl; - - if (!name || !*name) { - return NULL; - } - - Alog(LOG_DEBUG) << "findserver_uid(" << name << ")"; - - while (s && s->suid && (stricmp(s->suid, name) != 0)) - { - Alog(LOG_DEBUG_3) << "Compared " << s->suid << ", not a match"; - if (s->links) - { - sl = findserver_uid(s->links, name); - if (sl) - { - s = sl; - } - else - { - s = s->next; - } - } - else - { - s = s->next; - } - } - - Alog(LOG_DEBUG) << "findserver_uid(" << name << ") -> " << static_cast<void *>(s); - return s; -} - -/*************************************************************************/ - -/** - * Find if the server is synced with the network - * @param s Server struct - * @param name Server Name - * @return Not Synced returns -1, Synced returns 1, Error returns 0 - */ -int anope_check_sync(const char *name) -{ - Server *s; - s = findserver(servlist, name); - - if (!s) - return 0; - - if (is_sync(s)) - return 1; - else - return -1; -} - -/*************************************************************************/ - -/** - * Handle adding the server to the Server struct - * @param source Name of the uplink if any - * @param servername Name of the server being linked - * @param hops Number of hops to reach this server - * @param descript Description of the server - * @param numeric Server Numberic/SUID - * @return void - */ -void do_server(const char *source, const char *servername, const char *hops, - const char *descript, const std::string &numeric) -{ - Server *s, *newserver; - - Alog(LOG_DEBUG) << "Server introduced (" << servername << ")" << (*source ? " from " : "") << (*source ? source : ""); - - - if (source[0] == '\0') - s = me_server; - else - s = findserver(servlist, source); - - if (s == NULL) - s = findserver_uid(servlist, source); - - if (s == NULL) - throw CoreException("Recieved a server from a nonexistant uplink?"); - - /* Create a server structure. */ - newserver = new_server(s, servername, descript, SERVER_START, numeric); - - /* Announce services being online. */ - if (Config.GlobalOnCycle && Config.GlobalOnCycleUP) - notice_server(Config.s_GlobalNoticer, newserver, "%s", Config.GlobalOnCycleUP); - - /* Let modules know about the connection */ - FOREACH_MOD(I_OnNewServer, OnNewServer(newserver)); -} - -/*************************************************************************/ - -/** - * Handle removing the server from the Server struct - * @param source Name of the server leaving - * @param ac Number of arguments in av - * @param av Agruments as part of the SQUIT - * @return void - */ -void do_squit(const char *source, int ac, const char **av) -{ - char buf[BUFSIZE]; - Server *s; - - if (ircd->ts6) { - s = findserver_uid(servlist, av[0]); - if (!s) { - s = findserver(servlist, av[0]); - } - } else { - s = findserver(servlist, av[0]); - } - if (!s) - { - Alog() << "SQUIT for nonexistent server (" << av[0] << ")!!"; - return; - } - FOREACH_MOD(I_OnServerQuit, OnServerQuit(s)); - - /* If this is a juped server, send a nice global to inform the online - * opers that we received it. - */ - if (s->HasFlag(SERVER_JUPED)) - { - snprintf(buf, BUFSIZE, "Received SQUIT for juped server %s", - s->name); - ircdproto->SendGlobops(findbot(Config.s_OperServ), buf); - } - - snprintf(buf, sizeof(buf), "%s %s", s->name, - (s->uplink ? s->uplink->name : "")); - - if (s->uplink == me_server && Capab.HasFlag(CAPAB_UNCONNECT)) - { - Alog(LOG_DEBUG) << "Sending UNCONNECT SQUIT for " << s->name; - /* need to fix */ - ircdproto->SendSquit(s->name, buf); - } - - delete_server(s, buf); -} - -/*************************************************************************/ - -/** Handle parsing the CAPAB/PROTOCTL messages - * @param ac Number of args - * @param av Args - */ -void CapabParse(int ac, const char **av) -{ - for (int i = 0; i < ac; ++i) - { - for (unsigned j = 0; !Capab_Info[j].Token.empty(); ++j) - { - if (av[i] == Capab_Info[j].Token) - { - Capab.SetFlag(Capab_Info[j].Flag); - - if (Capab_Info[j].Token == "NICKIP" && !ircd->nickip) - ircd->nickip = 1; - break; - } - } - } -} - -/*************************************************************************/ - -/** - * Search the uline servers array to find out if the server that just set the - * mode is in our uline list - * @param server Server Setting the mode - * @return int 0 if not found, 1 if found - */ -int is_ulined(const char *server) -{ - int j; - - for (j = 0; j < Config.NumUlines; j++) { - if (stricmp(Config.Ulines[j], server) == 0) { - return 1; - } - } - - return 0; -} - -/*************************************************************************/ - -/** - * See if the current server is synced, or has an unknown sync state - * (in which case we pretend it is always synced) - * @param server Server of which we want to know the state - * @return int 0 if not synced, 1 if synced - */ -int is_sync(Server * server) -{ - if (server->sync == SSYNC_DONE) - return 1; - return 0; -} - -/*************************************************************************/ - -/* Finish the syncing process for this server and (optionally) for all - * it's leaves as well - * @param serv Server to finish syncing - * @param sync_links Should all leaves be synced as well? (1: yes, 0: no) - * @return void - */ -void finish_sync(Server * serv, int sync_links) -{ - Server *s; - - if (!serv || is_sync(serv)) - return; - - /* Mark each server as in sync */ - s = serv; - do { - if (!is_sync(s)) - { - Alog(LOG_DEBUG) << "Finishing sync for server " << s->name; - s->sync = SSYNC_DONE; - } - - if (!sync_links) - break; - - if (s->links) { - s = s->links; - } else if (s->next) { - s = s->next; - } else { - do { - s = s->uplink; - if (s == serv) - s = NULL; - if (s == me_server) - s = NULL; - } while (s && !(s->next)); - if (s) - s = s->next; - } - } while (s); - - if (serv == serv_uplink) - { - FOREACH_MOD(I_OnFinishSync, OnFinishSync(serv)); - ircdproto->SendEOB(); - } - - /* Do some general stuff which should only be done once */ - // XXX: this doesn't actually match the description. finish_sync(), depending on the ircd, can be called multiple times - // Perhaps this should be done if serv == serv_uplink? - restore_unsynced_topics(); - Alog() << "Server " << serv->name << " is done syncing"; - - FOREACH_MOD(I_OnServerSync, OnServerSync(s)); - if (serv == serv_uplink) - { - FOREACH_MOD(I_OnUplinkSync, OnUplinkSync()); - } -} - -/*******************************************************************/ - -/* TS6 UID generator common code. - * - * Derived from atheme-services, uid.c (hg 2954:116d46894b4c). - * -nenolod - */ -static int ts6_uid_initted = 0; -static char ts6_new_uid[10]; /* allow for \0 */ -static unsigned int ts6_uid_index = 9; /* last slot in uid buf */ - -void ts6_uid_init() -{ - snprintf(ts6_new_uid, 10, "%sAAAAAA", TS6SID); - ts6_uid_initted = 1; -} - -void ts6_uid_increment(unsigned int slot) -{ - if (slot != strlen(TS6SID)) { - if (ts6_new_uid[slot] == 'Z') - ts6_new_uid[slot] = '0'; - else if (ts6_new_uid[slot] == '9') { - ts6_new_uid[slot] = 'A'; - ts6_uid_increment(slot - 1); - } else - ts6_new_uid[slot]++; - } else { - if (ts6_new_uid[slot] == 'Z') - for (slot = 3; slot < 9; slot++) - ts6_new_uid[slot] = 'A'; - else - ts6_new_uid[slot]++; - } -} - -const char *ts6_uid_retrieve() -{ - if (ircd->ts6 == 0) - { - Alog(LOG_DEBUG) << "ts6_uid_retrieve(): TS6 not supported on this ircd"; - return ""; - } - - if (ts6_uid_initted != 1) - { - throw CoreException("TS6 IRCd and ts6_uid_init() hasn't been called!"); - } - - ts6_uid_increment(ts6_uid_index - 1); - return ts6_new_uid; -} - -/*******************************************************************/ - -/* - * TS6 generator code, provided by DukePyrolator - */ - -static int ts6_sid_initted = 0; -static char ts6_new_sid[4]; - -static void ts6_sid_increment(unsigned pos) -{ - /* - * An SID must be exactly 3 characters long, starts with a digit, - * and the other two characters are A-Z or digits - * The rules for generating an SID go like this... - * --> ABCDEFGHIJKLMNOPQRSTUVWXYZ --> 0123456789 --> WRAP - */ - if (!pos) - { - /* At pos 0, if we hit '9', we've run out of available SIDs, - * reset the SID to the smallest possible value and try again. */ - if (ts6_new_sid[pos] == '9') - { - ts6_new_sid[0] = '0'; - ts6_new_sid[1] = 'A'; - ts6_new_sid[2] = 'A'; - } - else - // But if we haven't, just keep incrementing merrily. - ++ts6_new_sid[0]; - } - else - { - if (ts6_new_sid[pos] == 'Z') - ts6_new_sid[pos] = '0'; - else if (ts6_new_sid[pos] == '9') - { - ts6_new_sid[pos] = 'A'; - ts6_sid_increment(pos - 1); - } - else - ++ts6_new_sid[pos]; - } -} - -const char *ts6_sid_retrieve() -{ - if (!ircd->ts6) - { - Alog(LOG_DEBUG) << "ts6_sid_retrieve(): TS6 not supported on this ircd"; - return ""; - } - - if (!ts6_sid_initted) - { - // Initialize ts6_new_sid with the services server SID - snprintf(ts6_new_sid, 4, "%s", TS6SID); - ts6_sid_initted = 1; - } - while (1) - { - // Check if the new SID is used by a known server - if (!findserver_uid(servlist, ts6_new_sid)) - // return the new SID - return ts6_new_sid; - - // Add one to the last SID - ts6_sid_increment(2); - } - /* not reached */ - return ""; -} - -/* EOF */ diff --git a/src/servers.cpp b/src/servers.cpp new file mode 100644 index 000000000..77876372e --- /dev/null +++ b/src/servers.cpp @@ -0,0 +1,576 @@ +/* Routines to maintain a list of connected servers + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + * + * $Id$ + * + */ + +#include "services.h" +#include "modules.h" + +char *TS6SID = NULL; + +/* Anope */ +Server *Me = NULL; + +CapabInfo Capab_Info[] = { + {"NOQUIT", CAPAB_NOQUIT}, + {"TSMODE", CAPAB_TSMODE}, + {"UNCONNECT", CAPAB_UNCONNECT}, + {"NICKIP", CAPAB_NICKIP}, + {"SSJOIN", CAPAB_NSJOIN}, + {"ZIP", CAPAB_ZIP}, + {"BURST", CAPAB_BURST}, + {"TS5", CAPAB_TS5}, + {"TS3", CAPAB_TS3}, + {"DKEY", CAPAB_DKEY}, + {"PT4", CAPAB_PT4}, + {"SCS", CAPAB_SCS}, + {"QS", CAPAB_QS}, + {"UID", CAPAB_UID}, + {"KNOCK", CAPAB_KNOCK}, + {"CLIENT", CAPAB_CLIENT}, + {"IPV6", CAPAB_IPV6}, + {"SSJ5", CAPAB_SSJ5}, + {"SN2", CAPAB_SN2}, + {"TOK1", CAPAB_TOKEN}, + {"TOKEN", CAPAB_TOKEN}, + {"VHOST", CAPAB_VHOST}, + {"SSJ3", CAPAB_SSJ3}, + {"SJB64", CAPAB_SJB64}, + {"CHANMODES", CAPAB_CHANMODE}, + {"NICKCHARS", CAPAB_NICKCHARS}, + {"", CAPAB_END} +}; + +Flags<CapabType> Capab; + +/** Constructor + * @param uplink The uplink this server is from, is only NULL when creating Me + * @param name The server name + * @param hops Hops from services server + * @param description Server rdescription + * @param sid Server sid/numeric + */ +Server::Server(Server *uplink, const std::string &name, unsigned int hops, const std::string &description, const std::string &sid) : Name(name), Hops(hops), Description(description), SID(sid), UplinkServer(uplink) +{ + Links = NULL; + + SetFlag(SERVER_SYNCING); + + Alog(LOG_DEBUG) << "Creating " << GetName() << " (" << GetSID() << ") uplinked to " << (UplinkServer ? UplinkServer->GetName() : "no uplink"); + + /* Add this server to our uplinks leaf list */ + if (UplinkServer) + UplinkServer->AddLink(this); + + if (Me && UplinkServer && Me == UplinkServer) + { + /* Bring in our pseudo-clients */ + introduce_user(""); + + /* And some IRCds needs Global joined in the logchan */ + if (LogChan && ircd->join2msg) + { + /* XXX might desync */ + ircdproto->SendJoin(findbot(Config.s_GlobalNoticer), Config.LogChannel, time(NULL)); + } + } +} + +/** Destructor + */ +Server::~Server() +{ + Alog(LOG_DEBUG) << "Deleting server " << GetName() << " (" << GetSID() << ") uplinked to " << GetName(); + + if (Capab.HasFlag(CAPAB_NOQUIT) || Capab.HasFlag(CAPAB_QS)) + { + User *nextu; + time_t t = time(NULL); + + for (User *u = firstuser(); u; u = nextu) + { + nextu = nextuser(); + + if (u->server == this) + { + NickAlias *na = findnick(u->nick); + if (na && !na->HasFlag(NS_FORBIDDEN) && (!na->nc->HasFlag(NI_SUSPENDED)) && (u->IsRecognized() || u->IsIdentified())) + { + na->last_seen = t; + if (na->last_quit) + delete [] na->last_quit; + na->last_quit = (!QReason.empty() ? sstrdup(QReason.c_str()) : NULL); + } + + if (Config.LimitSessions && !u->server->IsULined()) + { + del_session(u->host); + } + + delete u; + } + } + + Alog(LOG_DEBUG) << "Finished removing all users for " << GetName(); + } + + if (Links) + { + for (std::list<Server *>::iterator it = Links->begin(); it != Links->end(); ++it) + { + delete *it; + } + } + + delete Links; +} + +/** Delete this server with a reason + * @param reason The reason + */ +void Server::Delete(const std::string &reason) +{ + QReason = reason; + delete this; +} + +/** Get the name for this server + * @return The name + */ +const std::string& Server::GetName() const +{ + return Name; +} + +/** Get the number of hops this server is from services + * @return Number of hops + */ +unsigned int Server::GetHops() const +{ + return Hops; +} + +/** Set the server description + * @param desc The new description + */ +void Server::SetDescription(const std::string& desc) +{ + Description = desc; +} + +/** Get the server description + * @return The server description + */ +const std::string& Server::GetDescription() const +{ + return Description; +} + +/** Get the server numeric/SID + * @return The numeric/SID + */ +const std::string& Server::GetSID() const +{ + return SID; +} + +/** Get the list of links this server has, or NULL if it has none + * @return A list of servers + */ +const std::list<Server*>* Server::GetLinks() const +{ + return Links; +} + +/** Get the uplink server for this server, if this is our uplink will be Me + * @return The servers uplink + */ +Server* Server::GetUplink() const +{ + return UplinkServer; +} + +/** Adds a link to this server + * @param s The linking server + */ +void Server::AddLink(Server *s) +{ + /* This is only used for Me, initially we start services with an uplink of NULL, then + * connect to the server which introduces itself and has us as the uplink, which calls this + */ + if (!UplinkServer) + { + UplinkServer = s; + } + else + { + if (!Links) + { + Links = new std::list<Server *>(); + } + + Links->push_back(s); + } + + Alog() << "Server " << s->GetName() << " introduced from " << GetName(); +} + +/** Delinks a server from this server + * @param s The server + */ +void Server::DelLink(Server *s) +{ + if (!Links) + throw CoreException("Server::DelLink called on " + GetName() + " for " + s->GetName() + " but we have no links?"); + + for (std::list<Server *>::iterator it = Links->begin(); it != Links->end(); ++it) + { + if (*it == s) + { + Links->erase(it); + break; + } + } + + if (Links->empty()) + { + delete Links; + Links = NULL; + } + + Alog() << "Server " << s->GetName() << " quit from " << GetName(); +} + +/** Finish syncing this server and optionally all links to it + * @param SyncLinks True to sync the links for this server too (if any) + */ +void Server::Sync(bool SyncLinks) +{ + if (IsSynced()) + return; + + UnsetFlag(SERVER_SYNCING); + + if (SyncLinks && Links) + { + for (std::list<Server *>::iterator it = Links->begin(); it != Links->end(); ++it) + { + (*it)->Sync(true); + } + } + + if (this == Me->GetUplink()) + { + FOREACH_MOD(I_OnPreUplinkSync, OnPreUplinkSync(this)); + ircdproto->SendEOB(); + } + + Alog() << "Server " << GetName() << " is done syncing"; + + FOREACH_MOD(I_OnServerSync, OnServerSync(this)); + + if (this == Me->GetUplink()) + { + FOREACH_MOD(I_OnUplinkSync, OnUplinkSync(this)); + restore_unsynced_topics(); + } +} + +/** Check if this server is synced + * @return true or false + */ +bool Server::IsSynced() const +{ + return !HasFlag(SERVER_SYNCING); +} + +/** Check if this server is ULined + * @return true or false + */ +bool Server::IsULined() const +{ + for (int j = 0; j < Config.NumUlines; ++j) + if (!stricmp(Config.Ulines[j], GetName().c_str())) + return true; + return false; +} + +/** Find a server + * @param name The name or SID/numeric + * @param s The server list to search for this server on, defaults to our Uplink + * @return The server + */ +Server* Server::Find(const std::string &name, Server *s) +{ + if (!s) + s = Me->GetUplink(); + if (s->GetName() == name || s->GetSID() == name) + return s; + + if (s->GetLinks()) + { + for (std::list<Server *>::const_iterator it = s->GetLinks()->begin(); it != s->GetLinks()->end(); ++it) + { + Server *serv = *it; + + if (serv->GetName() == name || serv->GetSID() == name) + return serv; + Server *server = Server::Find(name, serv); + if (server) + return server; + } + } + + return NULL; +} + +/*************************************************************************/ + +/** + * Handle adding the server to the Server struct + * @param source Name of the uplink if any + * @param servername Name of the server being linked + * @param hops Number of hops to reach this server + * @param descript Description of the server + * @param numeric Server Numberic/SUID + * @return void + */ +void do_server(const std::string &source, const std::string &servername, unsigned int hops, const std::string &descript, const std::string &numeric) +{ + if (source.empty()) + Alog(LOG_DEBUG) << "Server " << servername << " introduced"; + else + Alog(LOG_DEBUG) << "Server introduced (" << servername << ")" << " from " << source; + + Server *s = NULL; + + if (!source.empty()) + { + s = Server::Find(source); + + if (!s) + throw CoreException("Recieved a server from a nonexistant uplink?"); + } + else + s = Me; + + /* Create a server structure. */ + Server *newserver = new Server(s, servername, hops, descript, numeric); + + /* Announce services being online. */ + if (Config.GlobalOnCycle && Config.GlobalOnCycleUP) + notice_server(Config.s_GlobalNoticer, newserver, "%s", Config.GlobalOnCycleUP); + + /* Let modules know about the connection */ + FOREACH_MOD(I_OnNewServer, OnNewServer(newserver)); +} + +/*************************************************************************/ + +/** + * Handle removing the server from the Server struct + * @param source Name of the server leaving + * @param ac Number of arguments in av + * @param av Agruments as part of the SQUIT + * @return void + */ +void do_squit(const char *source, int ac, const char **av) +{ + char buf[BUFSIZE]; + Server *s = Server::Find(av[0]); + + if (!s) + { + Alog() << "SQUIT for nonexistent server (" << av[0] << ")!!"; + return; + } + + FOREACH_MOD(I_OnServerQuit, OnServerQuit(s)); + + /* If this is a juped server, send a nice global to inform the online + * opers that we received it. + */ + if (s->HasFlag(SERVER_JUPED)) + { + snprintf(buf, BUFSIZE, "Received SQUIT for juped server %s", s->GetName().c_str()); + ircdproto->SendGlobops(findbot(Config.s_OperServ), buf); + } + + snprintf(buf, sizeof(buf), "%s %s", s->GetName().c_str(), s->GetUplink()->GetName().c_str()); + + if (s->GetUplink() == Me->GetUplink() && Capab.HasFlag(CAPAB_UNCONNECT)) + { + Alog(LOG_DEBUG) << "Sending UNCONNECT SQUIT for " << s->GetName(); + /* need to fix */ + ircdproto->SendSquit(s->GetName().c_str(), buf); + } + + s->Delete(buf); +} + +/*************************************************************************/ + +/** Handle parsing the CAPAB/PROTOCTL messages + * @param ac Number of args + * @param av Args + */ +void CapabParse(int ac, const char **av) +{ + for (int i = 0; i < ac; ++i) + { + for (unsigned j = 0; !Capab_Info[j].Token.empty(); ++j) + { + if (av[i] == Capab_Info[j].Token) + { + Capab.SetFlag(Capab_Info[j].Flag); + + if (Capab_Info[j].Token == "NICKIP" && !ircd->nickip) + ircd->nickip = 1; + break; + } + } + } +} + +/*************************************************************************/ + +/* TS6 UID generator common code. + * + * Derived from atheme-services, uid.c (hg 2954:116d46894b4c). + * -nenolod + */ +static bool ts6_uid_initted = false; +static char ts6_new_uid[10]; + +static void ts6_uid_increment(unsigned int slot) +{ + if (slot != strlen(TS6SID)) + { + if (ts6_new_uid[slot] == 'Z') + ts6_new_uid[slot] = '0'; + else if (ts6_new_uid[slot] == '9') + { + ts6_new_uid[slot] = 'A'; + ts6_uid_increment(slot - 1); + } + else + ++ts6_new_uid[slot]; + } + else + { + if (ts6_new_uid[slot] == 'Z') + for (slot = 3; slot < 9; slot++) + ts6_new_uid[slot] = 'A'; + else + ++ts6_new_uid[slot]; + } +} + +/** Recieve the next UID in our list + * @return The UID + */ +const char *ts6_uid_retrieve() +{ + if (ircd->ts6 == 0) + { + Alog(LOG_DEBUG) << "ts6_uid_retrieve(): TS6 not supported on this ircd"; + return ""; + } + + if (!ts6_uid_initted) + { + snprintf(ts6_new_uid, 10, "%sAAAAAA", TS6SID); + ts6_uid_initted = true; + } + + ts6_uid_increment(8); + return ts6_new_uid; +} + +/*******************************************************************/ + +/* + * TS6 generator code, provided by DukePyrolator + */ + +static bool ts6_sid_initted = false; +static char ts6_new_sid[4]; + +static void ts6_sid_increment(unsigned pos) +{ + /* + * An SID must be exactly 3 characters long, starts with a digit, + * and the other two characters are A-Z or digits + * The rules for generating an SID go like this... + * --> ABCDEFGHIJKLMNOPQRSTUVWXYZ --> 0123456789 --> WRAP + */ + if (!pos) + { + /* At pos 0, if we hit '9', we've run out of available SIDs, + * reset the SID to the smallest possible value and try again. */ + if (ts6_new_sid[pos] == '9') + { + ts6_new_sid[0] = '0'; + ts6_new_sid[1] = 'A'; + ts6_new_sid[2] = 'A'; + } + else + // But if we haven't, just keep incrementing merrily. + ++ts6_new_sid[0]; + } + else + { + if (ts6_new_sid[pos] == 'Z') + ts6_new_sid[pos] = '0'; + else if (ts6_new_sid[pos] == '9') + { + ts6_new_sid[pos] = 'A'; + ts6_sid_increment(pos - 1); + } + else + ++ts6_new_sid[pos]; + } +} + +/** Return the next SID in our list + * @return The SID + */ +const char *ts6_sid_retrieve() +{ + if (!ircd->ts6) + { + Alog(LOG_DEBUG) << "ts6_sid_retrieve(): TS6 not supported on this ircd"; + return ""; + } + + if (!ts6_sid_initted) + { + // Initialize ts6_new_sid with the services server SID + snprintf(ts6_new_sid, 4, "%s", TS6SID); + ts6_sid_initted = true; + } + + while (1) + { + // Check if the new SID is used by a known server + if (!Server::Find(ts6_new_sid)) + // return the new SID + return ts6_new_sid; + + // Add one to the last SID + ts6_sid_increment(2); + } + /* not reached */ + return ""; +} + +/* EOF */ diff --git a/src/users.c b/src/users.c index e32363259..6e42b7a08 100644 --- a/src/users.c +++ b/src/users.c @@ -231,7 +231,7 @@ User::~User() Alog() << "LOGUSERS: " << this->GetMask() << (ircd->vhost ? " => " : " ") << (ircd->vhost ? this->GetDisplayedHost() : "") - << " (" << srealname << ") left the network (" << this->server->name << ")."; + << " (" << srealname << ") left the network (" << this->server->GetName() << ")."; delete [] srealname; } @@ -551,8 +551,7 @@ void get_user_stats(long *nusers, long *memuse) } if (user->realname) mem += strlen(user->realname) + 1; - if (user->server->name) - mem += strlen(user->server->name) + 1; + mem += user->server->GetName().length() + 1; mem += (sizeof(ChannelContainer) * user->chans.size()); } } @@ -862,6 +861,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const ntoa(addr, ipbuf, sizeof(ipbuf)); } + Server *serv = Server::Find(server); if (Config.LogUsers) { @@ -886,7 +886,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const << (ircd->nickvhost && vhost ? " => " : "") << (ircd->nickvhost && vhost ? vhost : "") << ") (" << logrealname << ") " << (ircd->nickip ? "[" : "") << (ircd->nickip ? ipbuf : "") << (ircd->nickip ? "]" : "") - << " connected to the network (" << server << ")."; + << " connected to the network (" << serv->GetName() << ")."; delete [] logrealname; } @@ -894,7 +894,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const user = new User(nick, uid ? uid : ""); user->SetIdent(username); user->host = sstrdup(host); - user->server = findserver(servlist, server); + user->server = serv; user->realname = sstrdup(realname); user->timestamp = ts; user->my_signon = time(NULL); @@ -925,7 +925,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const if (ircd->szline && ircd->nickip) check_szline(nick, ipbuf); - if (Config.LimitSessions && !is_ulined(server)) + if (Config.LimitSessions && !serv->IsULined()) add_session(nick, host, ipbuf); /* User is no longer connected, return */ @@ -954,8 +954,8 @@ User *do_nick(const char *source, const char *nick, const char *username, const { const char *logrealname = normalizeBuffer(user->realname); Alog() << "LOGUSERS: " << user->nick << " (" << user->GetIdent() << "@" << user->host - << (ircd->vhost ? " => " : "") << (ircd->vhost ? user->GetDisplayedHost() : "") << ") (" - << logrealname << ") " << "changed nick to " << nick << " (" << user->server->name << ")."; + << (ircd->vhost ? " => " : "") << (ircd->vhost ? user->GetDisplayedHost() : "") << ") (" + << logrealname << ") " << "changed nick to " << nick << " (" << user->server->GetName() << ")."; if (logrealname) delete [] logrealname; } @@ -1055,9 +1055,8 @@ void do_quit(const char *source, int ac, const char **av) delete [] na->last_quit; na->last_quit = *av[0] ? sstrdup(av[0]) : NULL; } - if (Config.LimitSessions && !is_ulined(user->server->name)) { + if (Config.LimitSessions && !user->server->IsULined()) del_session(user->host); - } FOREACH_MOD(I_OnUserQuit, OnUserQuit(user, *av[0] ? av[0] : "")); delete user; } @@ -1088,7 +1087,7 @@ void do_kill(const std::string &nick, const std::string &msg) delete [] na->last_quit; na->last_quit = !msg.empty() ? sstrdup(msg.c_str()) : NULL; } - if (Config.LimitSessions && !is_ulined(user->server->name)) { + if (Config.LimitSessions && !user->server->IsULined()) { del_session(user->host); } delete user; |