*/
#include "stdinc.h"
-#include "tools.h"
#include "send.h"
#include "channel.h"
#include "client.h"
#include "common.h"
#include "config.h"
#include "ircd.h"
-#include "irc_string.h"
+#include "match.h"
#include "s_conf.h"
#include "msg.h"
#include "modules.h"
#include "s_serv.h"
static int ms_tb(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int ms_etb(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
struct Message tb_msgtab = {
"TB", 0, 0, 0, MFLG_SLOW,
{mg_unreg, mg_ignore, mg_ignore, {ms_tb, 4}, mg_ignore, mg_ignore}
};
-mapi_clist_av1 tb_clist[] = { &tb_msgtab, NULL };
+struct Message etb_msgtab = {
+ "ETB", 0, 0, 0, MFLG_SLOW,
+ {mg_unreg, mg_ignore, {ms_etb, 5}, {ms_etb, 5}, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 tb_clist[] = { &tb_msgtab, &etb_msgtab, NULL };
DECLARE_MODULE_AV1(tb, NULL, NULL, tb_clist, NULL, NULL, "$Revision: 1349 $");
/* m_tb()
use_id(source_p), chptr->chname, (long) chptr->topic_time,
ConfigChannel.burst_topicwho ? chptr->topic_info : "",
ConfigChannel.burst_topicwho ? " " : "", chptr->topic);
- sendto_server(client_p, chptr, CAP_TB, CAP_TS6,
- ":%s TB %s %ld %s%s:%s",
- source_p->name, chptr->chname, (long) chptr->topic_time,
- ConfigChannel.burst_topicwho ? chptr->topic_info : "",
- ConfigChannel.burst_topicwho ? " " : "", chptr->topic);
+ }
+
+ return 0;
+}
+
+/* ms_etb()
+ *
+ * parv[1] - channel ts
+ * parv[2] - channel
+ * parv[3] - topic ts
+ * parv[4] - topicwho
+ * parv[5] - topic
+ */
+static int
+ms_etb(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+ struct Channel *chptr;
+ const char *newtopic;
+ const char *newtopicwho;
+ time_t channelts, newtopicts;
+ struct Client *fakesource_p, *source_server_p;
+ int textchange, can_use_tb, member;
+
+ channelts = atol(parv[1]);
+ chptr = find_channel(parv[2]);
+
+ if(chptr == NULL)
+ return 0;
+
+ newtopicts = atol(parv[3]);
+
+ /* Hide connecting server on netburst -- jilles */
+ if (IsServer(source_p) && ConfigServerHide.flatten_links &&
+ !HasSentEob(source_p))
+ fakesource_p = &me;
+ else
+ fakesource_p = source_p;
+
+ newtopicwho = parv[4];
+ newtopic = parv[parc - 1];
+
+ if(chptr->topic == NULL || chptr->channelts > channelts ||
+ (chptr->channelts == channelts && chptr->topic_time < newtopicts))
+ {
+ textchange = chptr->topic == NULL || strcmp(chptr->topic, newtopic);
+ can_use_tb = textchange && !EmptyString(newtopic) &&
+ (chptr->topic == NULL || chptr->topic_time > newtopicts);
+
+ set_channel_topic(chptr, newtopic, newtopicwho, newtopicts);
+ newtopic = chptr->topic ? chptr->topic : "";
+ if (chptr->topic_info)
+ newtopicwho = chptr->topic_info;
+
+ /* Do not send a textually identical topic to clients,
+ * but do propagate the new topicts/topicwho to servers.
+ */
+ if(textchange)
+ {
+ if (IsPerson(fakesource_p))
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s!%s@%s TOPIC %s :%s",
+ fakesource_p->name,
+ fakesource_p->username,
+ fakesource_p->host,
+ chptr->chname,
+ newtopic);
+ else
+ sendto_channel_local(ALL_MEMBERS, chptr,
+ ":%s TOPIC %s :%s",
+ fakesource_p->name,
+ chptr->chname, newtopic);
+ }
+ /* Propagate channelts as given, because an older channelts
+ * forces any change.
+ */
+ sendto_server(client_p, chptr, CAP_EOPMOD|CAP_TS6, NOCAPS,
+ ":%s ETB %ld %s %ld %s :%s",
+ use_id(source_p), (long)channelts, chptr->chname,
+ (long)newtopicts, newtopicwho, newtopic);
+ source_server_p = IsServer(source_p) ? source_p : source_p->servptr;
+ if (can_use_tb)
+ sendto_server(client_p, chptr, CAP_TB|CAP_TS6, CAP_EOPMOD,
+ ":%s TB %s %ld %s :%s",
+ use_id(source_server_p),
+ chptr->chname, (long)newtopicts,
+ newtopicwho, newtopic);
+ else if (IsPerson(source_p) && textchange)
+ {
+ member = IsMember(source_p, chptr);
+ if (!member)
+ sendto_server(client_p, chptr, CAP_TS6, CAP_EOPMOD,
+ ":%s SJOIN %ld %s + :@%s",
+ use_id(source_server_p),
+ (long)chptr->channelts,
+ chptr->chname, use_id(source_p));
+ if (EmptyString(newtopic) ||
+ newtopicts >= rb_current_time() - 60)
+ sendto_server(client_p, chptr, CAP_TS6, CAP_EOPMOD,
+ ":%s TOPIC %s :%s",
+ use_id(source_p),
+ chptr->chname, newtopic);
+ else
+ {
+ sendto_server(client_p, chptr, CAP_TS6, CAP_EOPMOD,
+ ":%s TOPIC %s :%s",
+ use_id(source_p),
+ chptr->chname, "");
+ sendto_server(client_p, chptr, CAP_TB|CAP_TS6, CAP_EOPMOD,
+ ":%s TB %s %ld %s :%s",
+ use_id(source_server_p),
+ chptr->chname, (long)newtopicts,
+ newtopicwho, newtopic);
+ }
+ if (!member)
+ sendto_server(client_p, chptr, CAP_TS6, CAP_EOPMOD,
+ ":%s PART %s :Topic set for %s",
+ use_id(source_p),
+ chptr->chname, newtopicwho);
+ }
+ else if (textchange)
+ {
+ /* Should not send :server ETB if not all servers
+ * support EOPMOD.
+ */
+ sendto_server(client_p, chptr, CAP_TS6, CAP_EOPMOD,
+ ":%s NOTICE %s :*** Notice -- Dropping topic change for %s",
+ me.id, chptr->chname, chptr->chname);
+ }
}
return 0;