/** * Introduce a new user or service client to a remote server. * * @param To The remote server to inform. * @param Prefix Prefix for the generated commands. * @param data CLIENT structure of the new client. */ static void cb_introduceClient(CLIENT *To, CLIENT *Prefix, void *data) { CLIENT *c = (CLIENT *)data; (void)Client_Announce(To, Prefix, c); } /* cb_introduceClient */
/** * Handle ENDOFMOTD (376) numeric and login remote server. * The peer is either an IRC server (no IRC+ protocol), or we got the * ENDOFMOTD numeric from an IRC+ server. We have to register the new server. */ GLOBAL bool IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req) { int max_hops, i; CLIENT *c; CHANNEL *chan; Client_SetType(Client, CLIENT_SERVER); Log(LOG_NOTICE | LOG_snotice, "Server \"%s\" registered (connection %d, 1 hop - direct link).", Client_ID(Client), Client_Conn(Client)); /* Get highest hop count */ max_hops = 0; c = Client_First(); while (c) { if (Client_Hops(c) > max_hops) max_hops = Client_Hops(c); c = Client_Next(c); } /* Inform the new server about all other servers, and announce the * new server to all the already registered ones. Important: we have * to do this "in order" and can't introduce servers of which the * "toplevel server" isn't known already. */ for (i = 0; i < (max_hops + 1); i++) { for (c = Client_First(); c != NULL; c = Client_Next(c)) { if (Client_Type(c) != CLIENT_SERVER) continue; /* not a server */ if (Client_Hops(c) != i) continue; /* not actual "nesting level" */ if (c == Client || c == Client_ThisServer()) continue; /* that's us or the peer! */ if (!Announce_Server(Client, c)) return DISCONNECTED; } } /* Announce all the users to the new server */ c = Client_First(); while (c) { if (Client_Type(c) == CLIENT_USER || Client_Type(c) == CLIENT_SERVICE) { if (!Client_Announce(Client, Client_ThisServer(), c)) return DISCONNECTED; } c = Client_Next(c); } /* Announce all channels to the new server */ chan = Channel_First(); while (chan) { if (Channel_IsLocal(chan)) { chan = Channel_Next(chan); continue; } #ifdef IRCPLUS /* Send CHANINFO if the peer supports it */ if (Client_HasFlag(Client, 'C')) { if (!Send_CHANINFO(Client, chan)) return DISCONNECTED; } #endif if (!Announce_Channel(Client, chan)) return DISCONNECTED; /* Get next channel ... */ chan = Channel_Next(chan); } #ifdef IRCPLUS if (Client_HasFlag(Client, 'L')) { LogDebug("Synchronizing INVITE- and BAN-lists ..."); if (!Synchronize_Lists(Client)) return DISCONNECTED; } #endif if (!IRC_WriteStrClient(Client, "PING :%s", Client_ID(Client_ThisServer()))) return DISCONNECTED; return CONNECTED; } /* IRC_Num_ENDOFMOTD */