diff --git a/inspircd-aux.c b/inspircd-aux.c
deleted file mode 100644
index a844a6f..0000000
--- a/inspircd-aux.c
+++ /dev/null
@@ -1,1634 +0,0 @@
-/*
- * Copyright (c) 2005-2006 Atheme Development Group
- * Rights to this code are documented in doc/LICENSE.
- *
- * The People's Democratic Republic of InspIRCd common (across all protocols) support.
- *
- */
-
-#include "atheme.h"
-#include "uplink.h"
-#include "pmodule.h"
-#include "protocol/inspircd.h"
-
-DECLARE_MODULE_V1("protocol/inspircd-aux", true, _modinit, NULL, PACKAGE_STRING, "Atheme Development Group ");
-
-/* *INDENT-OFF* */
-
-ircd_t InspIRCd = {
- "InspIRCd 1.2+", /* IRCd name */
- "$", /* TLD Prefix, used by Global. */
- true, /* Whether or not we use IRCNet/TS6 UID */
- false, /* Whether or not we use RCOMMAND */
- true, /* Whether or not we support channel owners. */
- true, /* Whether or not we support channel protection. */
- true, /* Whether or not we support halfops. */
- false, /* Whether or not we use P10 */
- true, /* Whether or not we use vHosts. */
- CMODE_OPERONLY | CMODE_PERM | CMODE_IMMUNE, /* Oper-only cmodes */
- CSTATUS_OWNER, /* Integer flag for owner channel flag. */
- CSTATUS_PROTECT, /* Integer flag for protect channel flag. */
- CSTATUS_HALFOP, /* Integer flag for halfops. */
- "+q", /* Mode we set for owner. */
- "+a", /* Mode we set for protect. */
- "+h", /* Mode we set for halfops. */
- PROTOCOL_INSPIRCD, /* Protocol type */
- CMODE_PERM, /* Permanent cmodes */
- CMODE_IMMUNE, /* Oper-immune cmode */
- "beIg", /* Ban-like cmodes */
- 'e', /* Except mchar */
- 'I', /* Invex mchar */
- IRCD_CIDR_BANS | IRCD_HOLDNICK /* Flags */
-};
-
-struct cmode_ inspircd_mode_list[] = {
- { 'i', CMODE_INVITE },
- { 'm', CMODE_MOD },
- { 'n', CMODE_NOEXT },
- { 'p', CMODE_PRIV },
- { 's', CMODE_SEC },
- { 't', CMODE_TOPIC },
- { 'c', CMODE_NOCOLOR },
- { 'M', CMODE_MODREG },
- { 'R', CMODE_REGONLY },
- { 'O', CMODE_OPERONLY },
- { 'S', CMODE_STRIP },
- { 'K', CMODE_NOKNOCK },
- { 'A', CMODE_NOINVITE },
- { 'C', CMODE_NOCTCP },
- { 'N', CMODE_STICKY },
- { 'G', CMODE_CENSOR },
- { 'P', CMODE_PERM },
- { 'B', CMODE_NOCAPS },
- { 'z', CMODE_SSLONLY },
- { 'T', CMODE_NONOTICE },
- { 'u', CMODE_HIDING },
- { 'Q', CMODE_PEACE },
- { 'Y', CMODE_IMMUNE },
- { 'D', CMODE_DELAYJOIN },
- { '\0', 0 }
-};
-
-static bool check_flood(const char *, channel_t *, mychan_t *, user_t *, myuser_t *);
-static bool check_nickflood(const char *, channel_t *, mychan_t *, user_t *, myuser_t *);
-static bool check_jointhrottle(const char *, channel_t *, mychan_t *, user_t *, myuser_t *);
-static bool check_forward(const char *, channel_t *, mychan_t *, user_t *, myuser_t *);
-static bool check_rejoindelay(const char *, channel_t *, mychan_t *, user_t *, myuser_t *);
-static bool check_delaymsg(const char *, channel_t *, mychan_t *, user_t *, myuser_t *);
-
-struct extmode inspircd_ignore_mode_list[] = {
- { 'f', check_flood },
- { 'F', check_nickflood },
- { 'j', check_jointhrottle },
- { 'L', check_forward },
- { 'J', check_rejoindelay },
- { 'd', check_delaymsg },
- { '\0', 0 }
-};
-
-struct cmode_ inspircd_status_mode_list[] = {
- { 'q', CSTATUS_OWNER },
- { 'a', CSTATUS_PROTECT },
- { 'o', CSTATUS_OP },
- { 'h', CSTATUS_HALFOP },
- { 'v', CSTATUS_VOICE },
- { '\0', 0 }
-};
-
-struct cmode_ inspircd_prefix_mode_list[] = {
- { '~', CSTATUS_OWNER },
- { '&', CSTATUS_PROTECT },
- { '@', CSTATUS_OP },
- { '%', CSTATUS_HALFOP },
- { '+', CSTATUS_VOICE },
- { '\0', 0 }
-};
-
-struct cmode_ inspircd_user_mode_list[] = {
- { 'i', UF_INVIS },
- { 'o', UF_IRCOP },
- { 'd', UF_DEAF },
- { '\0', 0 }
-};
-
-/* CAPABilities */
-static bool has_servicesmod = false;
-static bool has_globopsmod = false;
-static bool has_chghostmod = false;
-static bool has_cbanmod = false;
-static bool has_hidechansmod = false;
-static bool has_servprotectmod = false;
-static bool has_svshold = false;
-static bool has_cloakingmod = false;
-static bool has_shun = false;
-static bool has_mlock = false;
-static int has_protocol = 0;
-
-#define PROTOCOL_12BETA 1201 /* we do not support anything older than this */
-#define PROTOCOL_METADATA_TS 1204
-
-/* find a user's server by extracting the SID and looking that up. --nenolod */
-static server_t *sid_find(char *name)
-{
- char sid[4];
- mowgli_strlcpy(sid, name, 4);
- return server_find(sid);
-}
-
-
-/* *INDENT-ON* */
-
-static inline void channel_metadata_sts(channel_t *c, const char *key, const char *value)
-{
- if (has_protocol < PROTOCOL_METADATA_TS)
- {
- sts(":%s METADATA %s %s :%s", ME, c->name, key, value);
- return;
- }
-
- sts(":%s METADATA %s %ld %s :%s", ME, c->name, c->ts, key, value);
-}
-
-static bool check_flood(const char *value, channel_t *c, mychan_t *mc, user_t *u, myuser_t *mu)
-{
- /* +F doesn't support *, so don't bother checking for it -- w00t */
- return check_jointhrottle(value, c, mc, u, mu);
-}
-
-static bool check_nickflood(const char *value, channel_t *c, mychan_t *mc, user_t *u, myuser_t *mu)
-{
- return *value == '*' ? check_jointhrottle(value + 1, c, mc, u, mu) : check_jointhrottle(value, c, mc, u, mu);
-}
-
-static bool check_jointhrottle(const char *value, channel_t *c, mychan_t *mc, user_t *u, myuser_t *mu)
-{
- const char *p, *arg2;
-
- p = value, arg2 = NULL;
- while (*p != '\0')
- {
- if (*p == ':')
- {
- if (arg2 != NULL)
- return false;
- arg2 = p + 1;
- }
- else if (!isdigit(*p))
- return false;
- p++;
- }
- if (arg2 == NULL)
- return false;
- if (p - arg2 > 10 || arg2 - value - 1 > 10 || !atoi(value) || !atoi(arg2))
- return false;
- return true;
-}
-
-static bool check_forward(const char *value, channel_t *c, mychan_t *mc, user_t *u, myuser_t *mu)
-{
- channel_t *target_c;
- mychan_t *target_mc;
-
- if (*value != '#' || strlen(value) > 50)
- return false;
- if (u == NULL && mu == NULL)
- return true;
- target_c = channel_find(value);
- target_mc = MYCHAN_FROM(target_c);
- if (target_c == NULL && target_mc == NULL)
- return false;
- return true;
-}
-
-static bool check_rejoindelay(const char *value, channel_t *c, mychan_t *mc, user_t *u, myuser_t *mu)
-{
- const char *ch = value;
-
- while (*ch)
- {
- if (!isdigit(*ch))
- return false;
- ch++;
- }
-
- /* don't allow mlocking a rejoin delay mode greater than 5 seconds.
- it's extremely rude. --nenolod */
- if (atoi(value) <= 0 || atoi(value) >= 5)
- {
- return false;
- }
- else
- {
- return true;
- }
-}
-
-static bool check_delaymsg(const char *value, channel_t *c, mychan_t *mc, user_t *u, myuser_t *mu)
-{
- const char *ch = value;
-
- while (*ch)
- {
- if (!isdigit(*ch))
- return false;
- ch++;
- }
-
- if (atoi(value) <= 0)
- {
- return false;
- }
- else
- {
- return true;
- }
-}
-
-/* login to our uplink */
-static unsigned int inspircd_server_login(void)
-{
- int ret;
-
- /* Check if we have a numeric set. InspIRCd 1.2 protocol
- * requires it. -nenolod
- */
- if (me.numeric == NULL)
- {
- slog(LG_ERROR, "inspircd_server_login(): inspircd 1.2 requires a unique identifier. set serverinfo::numeric.");
- exit(EXIT_FAILURE);
- }
-
- /* will be determined in CAPAB. */
- ircd->uses_owner = false;
- ircd->uses_protect = false;
- ircd->uses_halfops = false;
-
- ret = sts("SERVER %s %s 0 %s :%s", me.name, curr_uplink->send_pass, me.numeric, me.desc);
- if (ret == 1)
- return 1;
-
- me.bursting = true;
- return 0;
-}
-
-/* introduce a client */
-static void inspircd_introduce_nick(user_t *u)
-{
- /* :penguin.omega.org.za UID 497AAAAAB 1188302517 OperServ 127.0.0.1 127.0.0.1 OperServ +s 127.0.0.1 :Operator Server */
- const char *umode = user_get_umodestr(u);
-
- sts(":%s UID %s %lu %s %s %s %s 0.0.0.0 %lu %s%s%s :%s", me.numeric, u->uid, (unsigned long)u->ts, u->nick, u->host, u->host, u->user, (unsigned long)u->ts, umode, has_hidechansmod ? "I" : "", has_servprotectmod ? "k" : "", u->gecos);
- if (is_ircop(u))
- sts(":%s OPERTYPE Services", u->uid);
-}
-
-static void inspircd_quit_sts(user_t *u, const char *reason)
-{
- sts(":%s QUIT :%s", u->uid, reason);
-}
-
-/* WALLOPS wrapper */
-static void inspircd_wallops_sts(const char *text)
-{
- if (has_globopsmod)
- sts(":%s SNONOTICE g :%s", me.numeric, text);
- else
- sts(":%s SNONOTICE A :%s", me.numeric, text);
-}
-
-/* join a channel */
-static void inspircd_join_sts(channel_t *c, user_t *u, bool isnew, char *modes)
-{
- if (isnew)
- {
- sts(":%s FJOIN %s %lu + :o,%s", me.numeric, c->name, (unsigned long)c->ts, u->uid);
- if (modes[0] && modes[1])
- sts(":%s FMODE %s %lu %s", me.numeric, c->name, (unsigned long)c->ts, modes);
- }
- else
- {
- sts(":%s FJOIN %s %lu + :o,%s", me.numeric, c->name, (unsigned long)c->ts, u->uid);
- }
-}
-
-static void inspircd_chan_lowerts(channel_t *c, user_t *u)
-{
- slog(LG_DEBUG, "inspircd_chan_lowerts(): lowering TS for %s to %lu",
- c->name, (unsigned long)c->ts);
-
- sts(":%s FJOIN %s %lu + :o,%s", me.numeric, c->name, (unsigned long)c->ts, u->uid);
- sts(":%s FMODE %s %lu %s", me.numeric, c->name, (unsigned long)c->ts, channel_modes(c, true));
-}
-
-/* kicks a user from a channel */
-static void inspircd_kick(user_t *source, channel_t *c, user_t *u, const char *reason)
-{
- sts(":%s KICK %s %s :%s", source->uid, c->name, u->uid, reason);
-
- chanuser_delete(c, u);
-}
-
-/* PRIVMSG wrapper */
-static void inspircd_msg(const char *from, const char *target, const char *fmt, ...)
-{
- va_list ap;
- char buf[BUFSIZE];
- user_t *user = user_find(target);
- user_t *from_p = user_find(from);
-
- va_start(ap, fmt);
- vsnprintf(buf, BUFSIZE, fmt, ap);
- va_end(ap);
-
- sts(":%s PRIVMSG %s :%s", from_p->uid, *target != '#' ? user->uid : target, buf);
-}
-
-static void inspircd_msg_global_sts(user_t *from, const char *mask, const char *text)
-{
- sts(":%s PRIVMSG %s%s :%s", from ? from->uid : me.numeric, ircd->tldprefix, mask, text);
-}
-
-/* NOTICE wrapper */
-static void inspircd_notice_user_sts(user_t *from, user_t *target, const char *text)
-{
- sts(":%s NOTICE %s :%s", from ? from->uid : me.numeric, target->uid, text);
-}
-
-static void inspircd_notice_global_sts(user_t *from, const char *mask, const char *text)
-{
- sts(":%s NOTICE %s%s :%s", from ? from->uid : me.numeric, ircd->tldprefix, mask, text);
-}
-
-static void inspircd_notice_channel_sts(user_t *from, channel_t *target, const char *text)
-{
- sts(":%s NOTICE %s :%s", from ? from->uid : me.numeric, target->name, text);
-}
-
-static void inspircd_numeric_sts(server_t *from, int numeric, user_t *target, const char *fmt, ...)
-{
- va_list ap;
- char buf[BUFSIZE];
-
- va_start(ap, fmt);
- vsnprintf(buf, BUFSIZE, fmt, ap);
- va_end(ap);
-
- sts(":%s PUSH %s ::%s %d %s %s", from->sid, target->uid, from->name, numeric, target->nick, buf);
-}
-
-/* KILL wrapper */
-static void inspircd_kill_id_sts(user_t *killer, const char *id, const char *reason)
-{
- if (killer != NULL)
- sts(":%s KILL %s :Killed (%s (%s))", CLIENT_NAME(killer), id, killer->nick, reason);
- else
- sts(":%s KILL %s :Killed (%s (%s))", ME, id, me.name, reason);
-}
-
-/* PART wrapper */
-static void inspircd_part_sts(channel_t *c, user_t *u)
-{
- sts(":%s PART %s :Leaving", u->uid, c->name);
-}
-
-/* server-to-server KLINE wrapper */
-static void inspircd_kline_sts(const char *server, const char *user, const char *host, long duration, const char *reason)
-{
- service_t *svs;
-
- /* :services-dev.chatspike.net ADDLINE G test@test.com Brain 1133994664 0 :You are banned from this network */
- svs = service_find("operserv");
- sts(":%s ADDLINE G %s@%s %s %lu %ld :%s", me.numeric, user, host, svs != NULL ? svs->nick : me.name, (unsigned long)CURRTIME, duration, reason);
-}
-
-/* server-to-server UNKLINE wrapper */
-static void inspircd_unkline_sts(const char *server, const char *user, const char *host)
-{
- service_t *svs;
-
- /* I know this looks wrong, but it's really not. Trust me. --w00t */
- svs = service_find("operserv");
- sts(":%s GLINE %s@%s", svs != NULL ? svs->me->uid : ME, user, host);
-}
-
-/* server-to-server QLINE wrapper */
-static void inspircd_qline_sts(const char *server, const char *name, long duration, const char *reason)
-{
- service_t *svs;
-
- svs = service_find("operserv");
-
- if (*name != '#')
- {
- sts(":%s ADDLINE Q %s %s %lu %ld :%s", me.numeric, name, svs != NULL ? svs->nick : me.name, (unsigned long)CURRTIME, duration, reason);
- return;
- }
-
- if (has_cbanmod)
- sts(":%s CBAN %s %ld :%s", svs != NULL ? svs->me->uid : ME, name, duration, reason);
- else
- slog(LG_INFO, "SQLINE: Could not set SQLINE on \2%s\2 due to m_cban not being loaded in inspircd.", name);
-}
-
-/* server-to-server UNQLINE wrapper */
-static void inspircd_unqline_sts(const char *server, const char *name)
-{
- if (*name != '#')
- {
- sts(":%s QLINE %s", ME, name);
- return;
- }
-
- if (has_cbanmod)
- sts(":%s CBAN %s", ME, name);
- else
- slog(LG_INFO, "SQLINE: Could not remove SQLINE on \2%s\2 due to m_cban not being loaded in inspircd.", name);
-}
-
-/* topic wrapper */
-static void inspircd_topic_sts(channel_t *c, user_t *source, const char *setter, time_t ts, time_t prevts, const char *topic)
-{
- return_if_fail(c != NULL);
-
- /* If possible, try to use FTOPIC
- * Note that because TOPIC does not contain topicTS, it may be
- * off a few seconds on other servers, hence the 60 seconds here.
- * -- jilles */
- /* Restoring old topic */
- if (ts > prevts + 60 || prevts == 0)
- {
- sts(":%s FTOPIC %s %lu %s :%s", source->uid, c->name, (unsigned long)ts, setter, topic);
- return;
- }
- /* Tweaking a topic */
- else if (ts == prevts)
- {
- ts += 60;
- sts(":%s FTOPIC %s %lu %s :%s", source->uid, c->name, (unsigned long)ts, setter, topic);
- c->topicts = ts;
- return;
- }
- sts(":%s TOPIC %s :%s", source->uid, c->name, topic);
- c->topicts = CURRTIME;
-}
-
-/* mode wrapper */
-static void inspircd_mode_sts(char *sender, channel_t *target, char *modes)
-{
- user_t *sender_p;
-
- return_if_fail(sender != NULL);
- return_if_fail(target != NULL);
- return_if_fail(modes != NULL);
-
- sender_p = user_find(sender);
-
- return_if_fail(sender_p != NULL);
-
- sts(":%s FMODE %s %lu %s", sender_p->uid, target->name, (unsigned long)target->ts, modes);
-}
-
-/* ping wrapper */
-static void inspircd_ping_sts(void)
-{
- // XXX this is annoying, uplink_t contains no sid or link to server_t
- server_t *u = server_find(curr_uplink->name);
-
- if (!u)
- return;
-
- sts(":%s PING %s :%s", me.numeric, me.numeric, u->sid);
-}
-
-/* protocol-specific stuff to do on login */
-static void inspircd_on_login(user_t *u, myuser_t *mu, const char *wantedhost)
-{
- sts(":%s METADATA %s accountname :%s", me.numeric, u->uid, entity(mu)->name);
-}
-
-/* protocol-specific stuff to do on logout */
-static bool inspircd_on_logout(user_t *u, const char *account)
-{
- sts(":%s METADATA %s accountname :", me.numeric, u->uid);
- return false;
-}
-
-static void inspircd_jupe(const char *server, const char *reason)
-{
- service_t *svs;
- static char sid[3+1];
- int i;
- server_t *s;
-
- svs = service_find("operserv");
-
- s = server_find(server);
- if (s != NULL)
- {
- /* We need to wait for the RSQUIT to be processed -- jilles */
- sts(":%s RSQUIT :%s", svs != NULL ? svs->me->uid : ME, server);
- s->flags |= SF_JUPE_PENDING;
- return;
- }
-
- /* Remove any previous jupe first */
- sts(":%s SQUIT %s :%s", me.numeric, server, reason);
- /* dirty dirty make up some sid */
- if (sid[0] == '\0')
- mowgli_strlcpy(sid, me.numeric, sizeof sid);
- do
- {
- i = 2;
- for (;;)
- {
- if (sid[i] == 'Z')
- {
- sid[i] = '0';
- i--;
- /* eek, no more sids */
- if (i < 0)
- return;
- continue;
- }
- else if (sid[i] == '9')
- sid[i] = 'A';
- else sid[i]++;
- break;
- }
- } while (server_find(sid));
-
- sts(":%s SERVER %s * 1 %s :%s", me.numeric, server, sid, reason);
-}
-
-static void inspircd_sethost_sts(user_t *source, user_t *target, const char *host)
-{
- if (has_chghostmod)
- {
- sts(":%s CHGHOST %s %s", source->uid, target->uid, host);
-
- if (has_cloakingmod && !irccasecmp(target->host, host))
- sts(":%s SVSMODE %s +x", source->uid, target->uid);
- }
- else
- slog(LG_INFO, "VHOST: Could not set \2%s\2 due to m_chghost not being loaded in inspircd.", host);
-}
-
-static void inspircd_fnc_sts(user_t *source, user_t *u, char *newnick, int type)
-{
- /* svsnick can only be sent by a server */
- sts(":%s SVSNICK %s %s %lu", me.numeric, u->uid, newnick,
- (unsigned long)(CURRTIME - 60));
-}
-
-
-/* invite a user to a channel */
-static void inspircd_invite_sts(user_t *sender, user_t *target, channel_t *channel)
-{
- sts(":%s INVITE %s %s", sender->uid, target->uid, channel->name);
-}
-
-static void inspircd_holdnick_sts(user_t *source, int duration, const char *nick, myuser_t *account)
-{
- service_t *svs;
-
- svs = service_find("operserv");
- if (duration == 0)
- {
- if (has_svshold)
- /* remove SVSHOLD */
- sts(":%s SVSHOLD %s", source->uid, nick);
- else
- sts(":%s QLINE %s", svs != NULL ? svs->me->uid : ME, nick);
- }
- else
- {
- if (has_svshold)
- sts(":%s SVSHOLD %s %d :Registered nickname.", source->uid, nick, duration);
- else
- sts(":%s ADDLINE Q %s %s %lu %d :%s", me.numeric, nick, svs != NULL ? svs->nick : me.name, (unsigned long)CURRTIME, duration, "Nickname Enforcer");
- }
-}
-
-static void inspircd_svslogin_sts(char *target, char *nick, char *user, char *host, char *login)
-{
- user_t *tu = user_find(target);
-
- if(!tu && !ircd->uses_uid)
- return;
-
- sts(":%s METADATA %s accountname :%s", me.numeric, target, login);
-}
-
-static void inspircd_sasl_sts(char *target, char mode, char *data)
-{
- service_t *svs;
- server_t *s = sid_find(target);
-
- return_if_fail(s != NULL);
-
- svs = service_find("saslserv");
- if (svs == NULL)
- return;
-
- sts(":%s ENCAP %s SASL %s %s %c %s", ME, s->sid, svs->me->uid, target, mode, data);
-}
-
-static void inspircd_quarantine_sts(user_t *source, user_t *victim, long duration, const char *reason)
-{
- if (has_shun)
- sts(":%s ADDLINE SHUN *@%s %s %lu %ld :%s", me.numeric, victim->host, source->nick, (unsigned long) CURRTIME, duration, reason);
-}
-
-static void inspircd_mlock_sts(channel_t *c)
-{
- mychan_t *mc = MYCHAN_FROM(c);
-
- if (has_mlock == false)
- return;
-
- if (mc == NULL)
- return;
-
- channel_metadata_sts(c, "mlock", mychan_get_sts_mlock(mc));
-}
-
-static void m_topic(sourceinfo_t *si, int parc, char *parv[])
-{
- channel_t *c = channel_find(parv[0]);
-
- if (!c)
- return;
-
- handle_topic_from(si, c, si->su->nick, time(NULL), parv[1]);
-}
-
-static void m_ftopic(sourceinfo_t *si, int parc, char *parv[])
-{
- channel_t *c = channel_find(parv[0]);
- time_t ts = atol(parv[1]);
-
- if (!c)
- return;
-
- if (c->topic != NULL && c->topicts >= ts)
- {
- slog(LG_DEBUG, "m_ftopic(): ignoring older topic on %s", c->name);
- return;
- }
-
- handle_topic_from(si, c, parv[2], ts, parv[3]);
-}
-
-static void m_ping(sourceinfo_t *si, int parc, char *parv[])
-{
- /* reply to PING's */
- if (parc == 1)
- sts(":%s PONG %s", me.numeric, parv[0]);
- else if (parc == 2)
- sts(":%s PONG %s :%s", me.numeric, parv[1], parv[0]);
-}
-
-static void m_pong(sourceinfo_t *si, int parc, char *parv[])
-{
- server_t *s;
-
- if (!parv[1])
- return;
- s = server_find(parv[0]);
- if (!s || s == me.me)
- {
- TAINT_ON(s = server_find(parv[1]), "inspircd bug #90 causes possible state desync -- upgrade your software");
- if (!s || s == me.me)
- return;
- }
-
- handle_eob(s);
-
- me.uplinkpong = CURRTIME;
-
- /* if pong source isn't origin, this isn't a complete burst. --nenolod */
- if (s != si->s)
- return;
-
- /* -> :test.projectxero.net PONG test.projectxero.net :shrike.malkier.net */
- if (me.bursting)
- {
-#ifdef HAVE_GETTIMEOFDAY
- e_time(burstime, &burstime);
-
- slog(LG_INFO, "m_pong(): finished synching with uplink (%d %s)", (tv2ms(&burstime) > 1000) ? (tv2ms(&burstime) / 1000) : tv2ms(&burstime), (tv2ms(&burstime) > 1000) ? "s" : "ms");
-
- wallops("Finished synchronizing with network in %d %s.", (tv2ms(&burstime) > 1000) ? (tv2ms(&burstime) / 1000) : tv2ms(&burstime), (tv2ms(&burstime) > 1000) ? "s" : "ms");
-#else
- slog(LG_INFO, "m_pong(): finished synching with uplink");
- wallops("Finished synchronizing with network.");
-#endif
-
- me.bursting = false;
- }
-}
-
-static void m_privmsg(sourceinfo_t *si, int parc, char *parv[])
-{
- if (parc != 2)
- return;
-
- handle_message(si, parv[0], false, parv[1]);
-}
-
-static void m_notice(sourceinfo_t *si, int parc, char *parv[])
-{
- if (!me.recvsvr)
- {
- slog(LG_ERROR, "m_notice(): received NOTICE from uplink which is in unregistered state.");
- slog(LG_ERROR, "m_notice(): this probably means that you are linking to a client port instead");
- slog(LG_ERROR, "m_notice(): of a server port on your inspircd server.");
- slog(LG_ERROR, "m_notice(): atheme is giving up now. please correct your configuration and try again.");
- exit(EXIT_FAILURE);
- }
-
- if (parc != 2)
- return;
-
- handle_message(si, parv[0], true, parv[1]);
-}
-
-static void map_a_prefix(char prefix, char* prefixandnick, unsigned int *nlen)
-{
- size_t j, k;
-
- /* does this char match a known prefix? */
- for (j = 0; status_mode_list[j].mode; j++)
- {
- /* yup. add it to the 'final' combination (@%w00t) */
- if (prefix == status_mode_list[j].mode)
- {
- for (k = 0; prefix_mode_list[k].mode; k++)
- {
- if (status_mode_list[j].value == prefix_mode_list[k].value)
- {
- prefixandnick[*nlen] = prefix_mode_list[k].mode;
- (*nlen)++;
- return;
- }
- }
- }
- }
-}
-
-static void m_fjoin(sourceinfo_t *si, int parc, char *parv[])
-{
- /* :08X FJOIN #flaps 1234 +nt vh,0F8XXXXN ,08XGH75C ,001CCCC3 aq,00ABBBB1 */
- channel_t *c;
- unsigned int userc;
- unsigned int i;
- unsigned int nlen;
- bool prefix = true;
- bool keep_new_modes = true;
- char *userv[256];
- char prefixandnick[51];
- time_t ts;
-
- c = channel_find(parv[0]);
- ts = atol(parv[1]);
-
- if (!c)
- {
- slog(LG_DEBUG, "m_fjoin(): new channel: %s", parv[0]);
- c = channel_add(parv[0], ts, si->s);
- return_if_fail(c != NULL);
- }
-
- if (ts < c->ts)
- {
- chanuser_t *cu;
- mowgli_node_t *n;
-
- /* the TS changed. a TS change requires us to do
- * bugger all except update the TS, because in InspIRCd
- * remote servers enforce the TS change - Brain
- *
- * This is no longer the case with 1.1, we need to remove modes etc
- * as well as lowering the channel ts. Do both. -- w00t
- */
- clear_simple_modes(c);
- chanban_clear(c);
-
- /*
- * Also reop services, and remove status from others.
- */
- MOWGLI_ITER_FOREACH(n, c->members.head)
- {
- cu = (chanuser_t *)n->data;
- if (cu->user->server == me.me)
- {
- /* it's a service, reop */
- sts(":%s FMODE %s %lu +o %s", me.numeric, c->name, (unsigned long)ts, cu->user->uid);
- cu->modes = CSTATUS_OP;
- }
- else
- cu->modes = 0;
- }
-
- c->ts = ts;
- hook_call_channel_tschange(c);
- }
- else if (ts > c->ts)
- {
- keep_new_modes = false; /* ignore statuses */
- }
-
- /*
- * ok, here's the difference from 1.0 -> 1.1:
- * 1.0 sent p[3] and up as individual users, prefixed with their 'highest' prefix, @, % or +
- * in 1.1, this is more complex. All prefixes are sent, with the additional caveat that modules
- * can add their own prefixes (dangerous!) - therefore, don't just chanuser_add(), split the prefix
- * out and ignore unknown prefixes (probably the safest option). --w00t
- */
- userc = sjtoken(parv[parc - 1], ' ', userv);
-
- if (keep_new_modes)
- {
- channel_mode(NULL, c, parc - 3, parv + 2);
- }
-
- /* loop over all the users in this fjoin */
- for (i = 0; i < userc; i++)
- {
- nlen = 0;
- prefix = true;
-
- slog(LG_DEBUG, "m_fjoin(): processing user: %s", userv[i]);
-
- /*
- * ok, now look at the chars in the nick.. we have something like "@%,w00t", but need @%w00t.. and
- * we also want to ignore unknown prefixes.. loop through the chars
- */
- for (; *userv[i]; userv[i]++)
- {
- map_a_prefix(*userv[i], prefixandnick, &nlen);
-
- /* it's not a known prefix char, have we reached the end of the prefixes? */
- if (*userv[i] == ',')
- {
- /* yup, skip over the comma */
- userv[i]++;
-
- /* if we're ignoring status (keep_new_modes is false) then just add them to chan here.. */
- if (keep_new_modes == false)
- {
- /* This ignores the @%, and just adds 'w00t' to the chan */
- chanuser_add(c, userv[i]);
- }
- else
- {
- /* else, we do care about their prefixes.. add '@%w00t' to the chan */
- mowgli_strlcpy(prefixandnick + nlen, userv[i], sizeof(prefixandnick) - nlen);
- chanuser_add(c, prefixandnick);
- }
-
- /* added them.. break out of this loop, which will move us to the next user */
- break;
- }
- else
- {
- /* unknown prefix char */
- }
- }
-
- /* go to the next user */
- }
-
- if (c->nummembers == 0 && !(c->modes & ircd->perm_mode))
- channel_delete(c);
-}
-
-static void m_part(sourceinfo_t *si, int parc, char *parv[])
-{
- int chanc;
- char *chanv[256];
- int i;
-
- chanc = sjtoken(parv[0], ',', chanv);
- for (i = 0; i < chanc; i++)
- {
- slog(LG_DEBUG, "m_part(): user left channel: %s -> %s", si->su->nick, chanv[i]);
-
- chanuser_delete(channel_find(chanv[i]), si->su);
- }
-}
-
-static void m_uid(sourceinfo_t *si, int parc, char *parv[])
-{
- user_t *u;
-
- /* 1 2 3 4 5 6 7 8 9* 10* */
- /* -> :751 UID 751AAAAAA 1220196319 Brain brainwave.brainbox.cc netadmin.chatspike.net brain 192.168.1.10 1220196324 +Siosw +ACKNOQcdfgklnoqtx :Craig Edwards */
-
- /*
- * note: you can't rely on realname being p[10], it's actually p[parc - 1].
- * reason being that mode params may exist in p[9]+, or not at all.
- */
- if (parc >= 10)
- {
- slog(LG_DEBUG, "m_uid(): new user on `%s': %s", si->s->name, parv[2]);
-
- /* char *nick, char *user, char *host, char *vhost, char *ip, char *uid, char *gecos, server_t *server, unsigned int ts */
- u = user_add(parv[2], parv[5], parv[3], parv[4], parv[6], parv[0], parv[parc - 1], si->s, atol(parv[1]));
- if (u == NULL)
- return;
- user_mode(u, parv[8]);
-
- /* If server is not yet EOB we will do this later.
- * This avoids useless "please identify" -- jilles */
- if (si->s->flags & SF_EOB)
- handle_nickchange(u);
- }
- else
- {
- int i;
- slog(LG_DEBUG, "m_uid(): got UID with wrong number of params");
-
- for (i = 0; i < parc; i++)
- slog(LG_DEBUG, "m_uid(): parv[%d] = %s", i, parv[i]);
- }
-}
-
-static void m_nick(sourceinfo_t *si, int parc, char *parv[])
-{
- /* if it's only 1 then it's a nickname change, if it's 2, it's a nickname change with a TS */
- if (parc == 1 || parc == 2)
- {
- if (!si->su)
- {
- slog(LG_DEBUG, "m_nick(): server trying to change nick: %s", si->s != NULL ? si->s->name : "");
- return;
- }
-
- slog(LG_DEBUG, "m_nick(): nickname change from `%s': %s", si->su->nick, parv[0]);
-
- if (user_changenick(si->su, parv[0], parc == 2 ? atoi(parv[1]) : CURRTIME))
- return;
-
- /* It could happen that our PING arrived late and the
- * server didn't acknowledge EOB yet even though it is
- * EOB; don't send double notices in that case -- jilles */
- if (si->su->server->flags & SF_EOB)
- handle_nickchange(si->su);
- }
- else
- {
- int i;
- slog(LG_DEBUG, "m_nick(): got NICK with wrong number of params");
-
- for (i = 0; i < parc; i++)
- slog(LG_DEBUG, "m_nick(): parv[%d] = %s", i, parv[i]);
- }
-}
-
-static void m_quit(sourceinfo_t *si, int parc, char *parv[])
-{
- slog(LG_DEBUG, "m_quit(): user leaving: %s", si->su->nick);
-
- /* user_delete() takes care of removing channels and so forth */
- user_delete(si->su, parv[0]);
-}
-
-static void inspircd_user_mode(user_t *u, const char *modes)
-{
- int dir;
- const char *p;
-
- return_if_fail(u != NULL);
-
- user_mode(u, modes);
- dir = 0;
- for (p = modes; *p; ++p)
- switch (*p)
- {
- case '-':
- dir = MTYPE_DEL;
- break;
- case '+':
- dir = MTYPE_ADD;
- break;
- case 'x':
- /* If +x is set then the users vhost is set to their cloaked host
- * Note that -x etc works OK here, InspIRCd is nice enough to tell us
- * everytime a users host changes. - Adam
- */
- if (dir == MTYPE_ADD)
- {
- /* It is possible for the users vhost to not be their cloaked host after +x.
- * This only occurs when a user is introduced after a netmerge with their
- * vhost instead of their cloaked host. - Adam
- */
- if (strcmp(u->vhost, u->chost))
- {
- strshare_unref(u->chost);
- u->chost = strshare_get(u->vhost);
- }
- }
- break;
- }
-}
-
-static void m_saquit(sourceinfo_t *si, int parc, char *parv[])
-{
- user_t *u = user_find(parv[0]);
-
- slog(LG_DEBUG, "m_saquit(): user leaving: %s", parv[0]);
-
- /* user_delete() takes care of removing channels and so forth */
- user_delete(u, parv[1]);
-}
-
-static void m_mode(sourceinfo_t *si, int parc, char *parv[])
-{
- if (*parv[0] == '#')
- channel_mode(NULL, channel_find(parv[0]), parc - 1, &parv[1]);
- else
- inspircd_user_mode(user_find(parv[0]), parv[1]);
-}
-
-static void m_fmode(sourceinfo_t *si, int parc, char *parv[])
-{
- channel_t *c;
- time_t ts;
-
- /* :server.moo FMODE #blarp tshere +ntsklLg keymoo 1337 secks */
- if (*parv[0] == '#')
- {
- c = channel_find(parv[0]);
- if (c == NULL)
- {
- slog(LG_DEBUG, "m_fmode(): nonexistant channel: %s", parv[0]);
- return;
- }
- ts = atoi(parv[1]);
- if (ts > c->ts)
- {
- return;
- }
- else if (ts < c->ts)
- slog(LG_DEBUG, "m_fmode(): %s %s: incoming TS %lu is older than our TS %lu, possible desync", parv[0], parv[2], (unsigned long)ts, (unsigned long)c->ts);
- channel_mode(NULL, c, parc - 2, &parv[2]);
- }
- else
- inspircd_user_mode(user_find(parv[0]), parv[2]);
-}
-
-static void m_kick(sourceinfo_t *si, int parc, char *parv[])
-{
- user_t *u = user_find(parv[1]);
- channel_t *c = channel_find(parv[0]);
-
- /* -> :rakaur KICK #shrike rintaun :test */
- slog(LG_DEBUG, "m_kick(): user was kicked: %s -> %s", parv[1], parv[0]);
-
- if (!u)
- {
- slog(LG_DEBUG, "m_kick(): got kick for nonexistant user %s", parv[1]);
- return;
- }
-
- if (!c)
- {
- slog(LG_DEBUG, "m_kick(): got kick in nonexistant channel: %s", parv[0]);
- return;
- }
-
- if (!chanuser_find(c, u))
- {
- slog(LG_DEBUG, "m_kick(): got kick for %s not in %s", u->nick, c->name);
- return;
- }
-
- chanuser_delete(c, u);
-
- /* if they kicked us, let's rejoin */
- if (is_internal_client(u))
- {
- slog(LG_DEBUG, "m_kick(): %s got kicked from %s; rejoining", u->nick, parv[0]);
- join(parv[0], u->nick);
- }
-}
-
-static void m_kill(sourceinfo_t *si, int parc, char *parv[])
-{
- handle_kill(si, parv[0], parc > 1 ? parv[1] : "");
-}
-
-static void m_squit(sourceinfo_t *si, int parc, char *parv[])
-{
- slog(LG_DEBUG, "m_squit(): server leaving: %s", parv[0]);
- server_delete(parv[0]);
-}
-
-static void m_server(sourceinfo_t *si, int parc, char *parv[])
-{
- server_t *s;
-
- slog(LG_DEBUG, "m_server(): new server: %s", parv[0]);
- if (si->s == NULL)
- {
- sts(":%s BURST", me.numeric);
- sts(":%s VERSION :%s. %s %s",
- me.name, PACKAGE_STRING, me.numeric, get_conf_opts());
- services_init();
- sts(":%s ENDBURST", me.numeric);
- }
- s = handle_server(si, parv[0], parv[3], atoi(parv[2]), parv[4]);
-}
-
-static void m_endburst(sourceinfo_t *si, int parc, char *parv[])
-{
- mowgli_node_t *n;
-
- /* elicit PONG for EOB detection. */
- sts(":%s PING %s %s", me.numeric, me.numeric, si->s->sid);
-
- MOWGLI_ITER_FOREACH(n, si->s->children.head)
- {
- server_t *s = n->data;
-
- sts(":%s PING %s %s", me.numeric, me.numeric, s->sid);
- }
-}
-
-static void m_stats(sourceinfo_t *si, int parc, char *parv[])
-{
- handle_stats(si->su, parv[0][0]);
-}
-
-static void m_motd(sourceinfo_t *si, int parc, char *parv[])
-{
- handle_motd(si->su);
-}
-
-static void m_admin(sourceinfo_t *si, int parc, char *parv[])
-{
- handle_admin(si->su);
-}
-
-static void m_away(sourceinfo_t *si, int parc, char *parv[])
-{
- handle_away(si->su, parc >= 1 ? parv[0] : NULL);
-}
-
-static void m_join(sourceinfo_t *si, int parc, char *parv[])
-{
- channel_t *c;
-
- c = channel_find(parv[0]);
- if (!c)
- {
- slog(LG_DEBUG, "m_join(): new channel: %s (modes lost)", parv[0]);
- c = channel_add(parv[0], parc > 1 ? atol(parv[1]) : CURRTIME, si->su->server);
- return_if_fail(c != NULL);
- channel_mode_va(NULL, c, 1, "+");
- }
- chanuser_add(c, si->su->nick);
-}
-
-static void m_sajoin(sourceinfo_t *si, int parc, char *parv[])
-{
- si->su = user_find(parv[0]);
- if (si->su == NULL)
- return;
- m_join(si, 1, &parv[1]);
-}
-
-static void m_sapart(sourceinfo_t *si, int parc, char *parv[])
-{
- si->su = user_find(parv[0]);
- if (si->su == NULL)
- return;
- m_part(si, 1, &parv[1]);
-}
-
-static void m_sanick(sourceinfo_t *si, int parc, char *parv[])
-{
- si->su = user_find(parv[0]);
- if (si->su == NULL)
- return;
- m_nick(si, 1, &parv[1]);
-}
-
-static void m_svsnick(sourceinfo_t *si, int parc, char *parv[])
-{
- si->su = user_find(parv[0]);
- if (si->su == NULL || si->su->ts != atoi(parv[2]))
- return;
- if (is_internal_client(si->su))
- {
- // we've already killed the colliding user in user_add/user_changenick
- // XXX this could cause a services fight if we get desynced and haven't killed the camper
- sts(":%s NICK %s %lu", si->su->uid, si->su->nick, (unsigned long)si->su->ts);
- }
- else
- {
- m_nick(si, 2, &parv[1]);
- }
-}
-
-static void m_samode(sourceinfo_t *si, int parc, char *parv[])
-{
- /* note that SAMODE is not checked in any way before propagation,
- * and only works on channels, not users */
- channel_mode(NULL, channel_find(parv[0]), parc - 1, &parv[1]);
-}
-
-static void m_error(sourceinfo_t *si, int parc, char *parv[])
-{
- slog(LG_INFO, "m_error(): error from server: %s", parv[0]);
-}
-
-static void m_idle(sourceinfo_t *si, int parc, char *parv[])
-{
- if (parc == 1 && si->su != NULL)
- {
- sts(":%s IDLE %s %lu 0", parv[0], si->su->nick, (unsigned long)CURRTIME);
- }
- else
- {
- slog(LG_INFO, "m_idle(): Received an IDLE response but we didn't WHOIS anybody!");
- }
-}
-
-static void m_opertype(sourceinfo_t *si, int parc, char *parv[])
-{
- /*
- * Hope this works.. InspIRCd OPERTYPE means user is an oper, mark them so
- * Later, we may want to look at saving their OPERTYPE for informational
- * purposes, or not. --w00t
- */
- user_mode(si->su, "+o");
-}
-
-static void m_fhost(sourceinfo_t *si, int parc, char *parv[])
-{
- strshare_unref(si->su->vhost);
- si->su->vhost = strshare_get(parv[0]);
-}
-
-static void m_encap(sourceinfo_t *si, int parc, char *parv[])
-{
- if (!irccasecmp(parv[1], "SASL"))
- {
- /* :08C ENCAP * SASL 08CAAAAAE * S d29vTklOSkFTAGRhdGEgaW4gZmlyc3QgbGluZQ== */
- sasl_message_t smsg;
-
- if (parc < 6)
- return;
-
- smsg.uid = parv[2];
- smsg.mode = *parv[4];
- smsg.buf = parv[5];
- smsg.ext = parc >= 6 ? parv[6] : NULL;
- hook_call_sasl_input(&smsg);
- }
-}
-
-static inline void verify_mlock(channel_t *c, time_t ts, const char *their_mlock)
-{
- const char *mlock_str;
- mychan_t *mc;
-
- mc = MYCHAN_FROM(c);
- if (mc == NULL)
- return;
-
- if (ts != 0 && ts != c->ts)
- return mlock_sts(c);
-
- /* bounce MLOCK change if it doesn't match what we say it is */
- mlock_str = mychan_get_sts_mlock(mc);
- if (strcmp(mlock_str, their_mlock))
- return mlock_sts(c);
-}
-
-/*
- * :