📄 m_server.c
字号:
aconf = cptr->serv->conf; if (!aconf->hubmask) { sendto_locfailops("Link %s cancelled, is Non-Hub but introduced Leaf %s", cptr->name, servername); return exit_client(cptr, cptr, cptr, "Non-Hub Link"); } if (match(aconf->hubmask, servername)) { sendto_locfailops("Link %s cancelled, linked in %s, which hub config disallows", cptr->name, servername); return exit_client(cptr, cptr, cptr, "Not matching hub configuration"); } if (aconf->leafmask) { if (match(aconf->leafmask, servername)) { sendto_locfailops("Link %s(%s) cancelled, disallowed by leaf configuration", cptr->name, servername); return exit_client(cptr, cptr, cptr, "Disallowed by leaf configuration"); } } if (aconf->leafdepth && (hop > aconf->leafdepth)) { sendto_locfailops("Link %s(%s) cancelled, too deep depth", cptr->name, servername); return exit_client(cptr, cptr, cptr, "Too deep link depth (leaf)"); } if (numeric) { if ((numeric < 0) || (numeric > 254)) { sendto_locfailops("Link %s(%s) cancelled, numeric '%ld' out of range (should be 0-254)", cptr->name, servername, numeric); return exit_client(cptr, cptr, cptr, "Numeric out of range (0-254)"); } if (numeric_collides(numeric)) { sendto_locfailops("Link %s(%s) cancelled, colliding server numeric", cptr->name, servername); return exit_client(cptr, cptr, cptr, "Colliding server numeric (choose another)"); } } acptr = make_client(cptr, find_server_quick(parv[0])); (void)make_server(acptr); acptr->serv->numeric = numeric; acptr->hopcount = hop; strncpyzt(acptr->name, servername, sizeof(acptr->name)); strncpyzt(acptr->info, info, sizeof(acptr->info)); acptr->serv->up = find_or_add(parv[0]); SetServer(acptr); ircd_log(LOG_SERVER, "SERVER %s", acptr->name); /* Taken from bahamut makes it so all servers behind a U:lined * server are also U:lined, very helpful if HIDE_ULINES is on */ if (IsULine(sptr) || (Find_uline(acptr->name))) acptr->flags |= FLAGS_ULINE; add_server_to_table(acptr); IRCstats.servers++; (void)find_or_add(acptr->name); add_client_to_list(acptr); (void)add_to_client_hash_table(acptr->name, acptr); RunHook(HOOKTYPE_SERVER_CONNECT, acptr); for (i = 0; i <= LastSlot; i++) { if (!(bcptr = local[i]) || !IsServer(bcptr) || bcptr == cptr || IsMe(bcptr)) continue; if (SupportNS(bcptr)) { sendto_one(bcptr, "%c%s %s %s %d %ld :%s", (sptr->serv->numeric ? '@' : ':'), (sptr->serv->numeric ? base64enc(sptr->serv->numeric) : sptr->name), IsToken(bcptr) ? TOK_SERVER : MSG_SERVER, acptr->name, hop + 1, numeric, acptr->info); } else { sendto_one(bcptr, ":%s %s %s %d :%s", parv[0], IsToken(bcptr) ? TOK_SERVER : MSG_SERVER, acptr->name, hop + 1, acptr->info); } } RunHook(HOOKTYPE_POST_SERVER_CONNECT, acptr); return 0;}int m_server_synch(aClient *cptr, long numeric, ConfigItem_link *aconf){ char *inpath = get_client_name(cptr, TRUE); extern MODVAR char serveropts[]; aClient *acptr; int i; char buf[BUFSIZE]; int incoming = IsUnknown(cptr) ? 1 : 0; ircd_log(LOG_SERVER, "SERVER %s", cptr->name); if (cptr->passwd) { MyFree(cptr->passwd); cptr->passwd = NULL; } if (incoming) { /* If this is an incomming connection, then we have just received * their stuff and now send our stuff back. */ send_proto(cptr, aconf); sendto_one(cptr, "PASS :%s", aconf->connpwd); sendto_one(cptr, "SERVER %s 1 :U%d-%s-%i %s", me.name, UnrealProtocol, serveropts, me.serv->numeric, (me.info[0]) ? (me.info) : "IRCers United"); }#ifdef ZIP_LINKS if (aconf->options & CONNECT_ZIP) { if (cptr->proto & PROTO_ZIP) { if (zip_init(cptr, aconf->compression_level ? aconf->compression_level : ZIP_DEFAULT_LEVEL) == -1) { zip_free(cptr); sendto_realops("Unable to setup compressed link for %s", get_client_name(cptr, TRUE)); return exit_client(cptr, cptr, &me, "zip_init() failed"); } SetZipped(cptr); cptr->zip->first = 1; } else { sendto_realops("WARNING: Remote doesnt have link::options::zip set. Compression disabled."); } }#endif#if 0/* Disabled because it may generate false warning when linking with cvs versions between b14 en b15 -- Syzop */ if ((cptr->proto & PROTO_ZIP) && !(aconf->options & CONNECT_ZIP)) {#ifdef ZIP_LINKS sendto_realops("WARNING: Remote requested compressed link, but we don't have link::options::zip set. Compression disabled.");#else sendto_realops("WARNING: Remote requested compressed link, but we don't have zip links support compiled in. Compression disabled.");#endif }#endif /* Set up server structure */ SetServer(cptr); IRCstats.me_servers++; IRCstats.servers++; IRCstats.unknown--;#ifndef NO_FDLIST addto_fdlist(cptr->slot, &serv_fdlist);#endif if ((Find_uline(cptr->name))) cptr->flags |= FLAGS_ULINE; nextping = TStime(); (void)find_or_add(cptr->name);#ifdef USE_SSL if (IsSecure(cptr)) { sendto_serv_butone(&me, ":%s SMO o :(\2link\2) Secure %slink %s -> %s established (%s)", me.name, IsZipped(cptr) ? "ZIP" : "", me.name, inpath, (char *) ssl_get_cipher((SSL *)cptr->ssl)); sendto_realops("(\2link\2) Secure %slink %s -> %s established (%s)", IsZipped(cptr) ? "ZIP" : "", me.name, inpath, (char *) ssl_get_cipher((SSL *)cptr->ssl)); } else#endif { sendto_serv_butone(&me, ":%s SMO o :(\2link\2) %sLink %s -> %s established", me.name, IsZipped(cptr) ? "ZIP" : "", me.name, inpath); sendto_realops("(\2link\2) %sLink %s -> %s established", IsZipped(cptr) ? "ZIP" : "", me.name, inpath); } (void)add_to_client_hash_table(cptr->name, cptr); /* doesnt duplicate cptr->serv if allocted this struct already */ (void)make_server(cptr); cptr->serv->up = me.name; cptr->srvptr = &me; cptr->serv->numeric = numeric; cptr->serv->conf = aconf; if (incoming) { cptr->serv->conf->refcount++; Debug((DEBUG_ERROR, "reference count for %s (%s) is now %d", cptr->name, cptr->serv->conf->servername, cptr->serv->conf->refcount)); } cptr->serv->conf->class->clients++; cptr->class = cptr->serv->conf->class; add_server_to_table(cptr); RunHook(HOOKTYPE_SERVER_CONNECT, cptr); for (i = 0; i <= LastSlot; i++) { if (!(acptr = local[i]) || !IsServer(acptr) || acptr == cptr || IsMe(acptr)) continue; if (SupportNS(acptr)) { sendto_one(acptr, "%c%s %s %s 2 %i :%s", (me.serv->numeric ? '@' : ':'), (me.serv->numeric ? base64enc(me. serv->numeric) : me.name), (IsToken(acptr) ? TOK_SERVER : MSG_SERVER), cptr->name, cptr->serv->numeric, cptr->info); } else { sendto_one(acptr, ":%s %s %s 2 :%s", me.name, (IsToken(acptr) ? TOK_SERVER : MSG_SERVER), cptr->name, cptr->info); } } for (acptr = &me; acptr; acptr = acptr->prev) { /* acptr->from == acptr for acptr == cptr */ if (acptr->from == cptr) continue; if (IsServer(acptr)) { if (SupportNS(cptr)) { /* this has to work. */ numeric = ((aClient *)find_server_quick(acptr-> serv->up))->serv->numeric; sendto_one(cptr, "%c%s %s %s %d %i :%s", (numeric ? '@' : ':'), (numeric ? base64enc(numeric) : acptr->serv->up), IsToken(cptr) ? TOK_SERVER : MSG_SERVER, acptr->name, acptr->hopcount + 1, acptr->serv->numeric, acptr->info); } else sendto_one(cptr, ":%s %s %s %d :%s", acptr->serv->up, (IsToken(cptr) ? TOK_SERVER : MSG_SERVER), acptr->name, acptr->hopcount + 1, acptr->info); /* Also signal to the just-linked server which * servers are fully linked. * Now you might ask yourself "Why don't we just * assume every server you get during link phase * is fully linked?", well.. there's a race condition * if 2 servers link (almost) at the same time, * then you would think the other one is fully linked * while in fact he was not.. -- Syzop. */ if (acptr->serv->flags.synced) { sendto_one(cptr, ":%s %s", acptr->name, (IsToken(cptr) ? TOK_EOS : MSG_EOS));#ifdef DEBUGMODE ircd_log(LOG_ERROR, "[EOSDBG] m_server_synch: sending to uplink '%s' with src %s...", cptr->name, acptr->name);#endif } } } /* Synching nick information */ for (acptr = &me; acptr; acptr = acptr->prev) { /* acptr->from == acptr for acptr == cptr */ if (acptr->from == cptr) continue; if (IsPerson(acptr)) { if (!SupportNICKv2(cptr)) { sendto_one(cptr, "%s %s %d %ld %s %s %s %lu :%s", (IsToken(cptr) ? TOK_NICK : MSG_NICK), acptr->name, acptr->hopcount + 1, acptr->lastnick, acptr->user->username, acptr->user->realhost, acptr->user->server, (unsigned long)acptr->user->servicestamp, acptr->info); send_umode(cptr, acptr, 0, SEND_UMODES, buf); if (IsHidden(acptr) && acptr->user->virthost) sendto_one(cptr, ":%s %s %s", acptr->name, (IsToken(cptr) ? TOK_SETHOST : MSG_SETHOST), acptr->user->virthost); } else { send_umode(NULL, acptr, 0, SEND_UMODES, buf); if (!SupportVHP(cptr)) { if (SupportNS(cptr) && acptr->srvptr->serv->numeric) { sendto_one(cptr, ((cptr->proto & PROTO_SJB64) ? "%s %s %d %B %s %s %b %lu %s %s %s%s%s%s:%s" : "%s %s %d %lu %s %s %b %lu %s %s %s%s%s%s:%s"), (IsToken(cptr) ? TOK_NICK : MSG_NICK), acptr->name, acptr->hopcount + 1, (long)acptr->lastnick, acptr->user->username, acptr->user->realhost, (long)(acptr->srvptr->serv->numeric), (unsigned long)acptr->user->servicestamp, (!buf || *buf == '\0' ? "+" : buf), ((IsHidden(acptr) && (acptr->umodes & UMODE_SETHOST)) ? acptr->user->virthost : "*"), SupportCLK(cptr) ? getcloak(acptr) : "", SupportCLK(cptr) ? " " : "", SupportNICKIP(cptr) ? encode_ip(acptr->user->ip_str) : "", SupportNICKIP(cptr) ? " " : "", acptr->info); } else { sendto_one(cptr, (cptr->proto & PROTO_SJB64 ? "%s %s %d %B %s %s %s %lu %s %s %s%s%s%s:%s" : "%s %s %d %lu %s %s %s %lu %s %s %s%s%s%s:%s"), (IsToken(cptr) ? TOK_NICK : MSG_NICK), acptr->name, acptr->hopcount + 1, (long)acptr->lastnick, acptr->user->username, acptr->user->realhost, acptr->user->server, (unsigned long)acptr->user->servicestamp, (!buf || *buf == '\0' ? "+" : buf), ((IsHidden(acptr) && (acptr->umodes & UMODE_SETHOST)) ? acptr->user->virthost : "*"), SupportCLK(cptr) ? getcloak(acptr) : "", SupportCLK(cptr) ? " " : "", SupportNICKIP(cptr) ? encode_ip(acptr->user->ip_str) : "", SupportNICKIP(cptr) ? " " : "", acptr->info); } } else sendto_one(cptr, "%s %s %d %ld %s %s %s %lu %s %s %s%s:%s", (IsToken(cptr) ? TOK_NICK : MSG_NICK), acptr->name, acptr->hopcount + 1, acptr->lastnick, acptr->user->username, acptr->user->realhost, (SupportNS(cptr) ? (acptr->srvptr->serv->numeric ? base64enc(acptr->srvptr-> serv->numeric) : acptr-> user->server) : acptr->user-> server), (unsigned long)acptr->user->servicestamp, (!buf || *buf == '\0' ? "+" : buf), GetHost(acptr), SupportNICKIP(cptr) ? encode_ip(acptr->user->ip_str) : "", SupportNICKIP(cptr) ? " " : "", acptr->info); } if (acptr->user->away) sendto_one(cptr, ":%s %s :%s", acptr->name, (IsToken(cptr) ? TOK_AWAY : MSG_AWAY), acptr->user->away); if (acptr->user->swhois) if (*acptr->user->swhois != '\0') sendto_one(cptr, "%s %s :%s", (IsToken(cptr) ? TOK_SWHOIS : MSG_SWHOIS), acptr->name, acptr->user->swhois); if (!SupportSJOIN(cptr)) send_user_joins(cptr, acptr); } } /* ** Last, pass all channels plus statuses */ { aChannel *chptr; for (chptr = channel; chptr; chptr = chptr->nextch) { if (!SupportSJOIN(cptr)) send_channel_modes(cptr, chptr); else if (SupportSJOIN(cptr) && !SupportSJ3(cptr)) { send_channel_modes_sjoin(cptr, chptr); } else send_channel_modes_sjoin3(cptr, chptr); if (chptr->topic_time) sendto_one(cptr, (cptr->proto & PROTO_SJB64 ? "%s %s %s %B :%s" : "%s %s %s %lu :%s"), (IsToken(cptr) ? TOK_TOPIC : MSG_TOPIC), chptr->chname, chptr->topic_nick, (long)chptr->topic_time, chptr->topic); } } /* pass on TKLs */ tkl_synch(cptr); /* send out SVSFLINEs */ dcc_sync(cptr); sendto_one(cptr, "%s %i %li %i %s 0 0 0 :%s", (IsToken(cptr) ? TOK_NETINFO : MSG_NETINFO), IRCstats.global_max, TStime(), UnrealProtocol, CLOAK_KEYCRC, ircnetwork); /* Send EOS (End Of Sync) to the just linked server... */ sendto_one(cptr, ":%s %s", me.name, (IsToken(cptr) ? TOK_EOS : MSG_EOS));#ifdef DEBUGMODE ircd_log(LOG_ERROR, "[EOSDBG] m_server_synch: sending to justlinked '%s' with src ME...", cptr->name);#endif RunHook(HOOKTYPE_POST_SERVER_CONNECT, cptr); return 0;}static int send_mode_list(aClient *cptr, char *chname, TS creationtime, Member *top, int mask, char flag){ Member *lp; char *cp, *name; int count = 0, send = 0, sent = 0; cp = modebuf + strlen(modebuf); if (*parabuf) /* mode +l or +k xx */ count = 1; for (lp = top; lp; lp = lp->next) { /* * Okay, since ban's are stored in their own linked * list, we won't even bother to check if CHFL_BAN * is set in the flags. This should work as long * as only ban-lists are feed in with CHFL_BAN mask. * However, we still need to typecast... -Donwulff */ if ((mask == CHFL_BAN) || (mask == CHFL_EXCEPT) || (mask == CHFL_INVEX)) {/* if (!(((Ban *)lp)->flags & mask)) continue; */ name = ((Ban *) lp)->banstr; } else { if (!(lp->flags & mask)) continue; name = lp->cptr->name; } if (strlen(parabuf) + strlen(name) + 11 < (size_t)MODEBUFLEN) { if (*parabuf) (void)strlcat(parabuf, " ", sizeof parabuf); (void)strlcat(parabuf, name, sizeof parabuf); count++; *cp++ = flag; *cp = '\0'; } else if (*parabuf) send = 1; if (count == RESYNCMODES) send = 1; if (send) { /* cptr is always a server! So we send creationtimes */ sendmodeto_one(cptr, me.name, chname, modebuf, parabuf, creationtime); sent = 1; send = 0; *parabuf = '\0'; cp = modebuf; *cp++ = '+'; if (count != RESYNCMODES) { (void)strlcpy(parabuf, name, sizeof parabuf); *cp++ = flag; } count = 0; *cp = '\0'; } } return sent;}/* A little kludge to prevent sending double spaces -- codemastr */static inline void send_channel_mode(aClient *cptr, char *from, aChannel *chptr){ if (*parabuf) sendto_one(cptr, ":%s %s %s %s %s %lu", from, (IsToken(cptr) ? TOK_MODE : MSG_MODE), chptr->chname, modebuf, parabuf, chptr->creationtime); else sendto_one(cptr, ":%s %s %s %s %lu", from, (IsToken(cptr) ? TOK_MODE : MSG_MODE), chptr->chname, modebuf, chptr->creationtime);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -