---
include/send.h | 1 +
include/struct.h | 2 +-
src/channel.c | 41 +++++++++++++++++++++++++++++++++--------
src/send.c | 29 +++++++++++++++++++++++++++++
4 files changed, 64 insertions(+), 9 deletions(-)
diff --git a/include/send.h b/include/send.h
index a96adda..eab3766 100644
--- a/include/send.h
+++ b/include/send.h
@@ -75,6 +75,7 @@ extern void sendto_realops(char *pattern, ...) ATTRIBUTE_PRINTF(1, 2);
extern void sendto_non_noquit_servs_butone(aClient *one, char *pattern, ...) ATTRIBUTE_PRINTF(2, 3);
extern void sendto_serv_butone(aClient *one, char *pattern, ...) ATTRIBUTE_PRINTF(2, 3);
extern void sendto_serv_butone_nickipstr(aClient *one, int flag, char *pattern, ...) ATTRIBUTE_PRINTF(3, 4);
+extern void sendto_capab_serv_butone(aClient *one, int include, int exclude, char *pattern, ...) ATTRIBUTE_PRINTF(4, 5);
extern void sendto_serv_butone_super(aClient *one, int flag, char *pattern, ...) ATTRIBUTE_PRINTF(3, 4);
extern void sendto_wallops_butone(aClient *one, aClient *from,
char *pattern, ...) ATTRIBUTE_PRINTF(3, 4);
diff --git a/include/struct.h b/include/struct.h
index ee705cb..b9c9c87 100644
--- a/include/struct.h
+++ b/include/struct.h
@@ -1212,7 +1212,7 @@ struct Channel
Mode mode;
char chname[CHANNELLEN+1];
char topic[TOPICLEN + 1];
- char topic_nick[NICKLEN + 1];
+ char topic_nick[NICKLEN + 1 + USERLEN + 1 + HOSTLEN + 1];
time_t topic_time;
int users;
chanMember* members;
diff --git a/src/channel.c b/src/channel.c
index 40c14ae..c55ae2b 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -3329,14 +3329,32 @@ void send_topic_burst(aClient *cptr)
{
aChannel *chptr;
aClient *acptr;
+ char *tmpptr; /* Temporary pointer to remove the user@host part from tnick for non-NICKIPSTR servers */
+ char tnick[NICKLEN + 1]; /* chptr->topic_nick without the user@host part for non-NICKIPSTR servers */
+ int len; /* tnick's length */
if (!(confopts & FLAGS_SERVHUB) || !(cptr->serv->uflags & ULF_NOBTOPIC))
for (chptr = channel; chptr; chptr = chptr->nextch)
{
if(chptr->topic[0] != '\0')
- sendto_one(cptr, ":%s TOPIC %s %s %ld :%s", me.name, chptr->chname,
- chptr->topic_nick, (long)chptr->topic_time,
- chptr->topic);
+ {
+ if(cptr->capabilities & CAPAB_NICKIPSTR)
+ sendto_one(cptr, ":%s TOPIC %s %s %ld :%s", me.name, chptr->chname,
+ chptr->topic_nick, (long)chptr->topic_time,
+ chptr->topic);
+ else
+ {
+ /* This is a non-NICKIPSTR server, we need to remove the user@host part before we send it */
+ tmpptr = chptr->topic_nick;
+ len = 0;
+ while(*tmpptr && *tmpptr!='!')
+ tnick[len++] = *(tmpptr++);
+ tnick[len] = '\0';
+ sendto_one(cptr, ":%s TOPIC %s %s %ld :%s", me.name, chptr->chname,
+ tnick, (long)chptr->topic_time,
+ chptr->topic);
+ }
+ }
}
if (!(confopts & FLAGS_SERVHUB) || !(cptr->serv->uflags & ULF_NOBAWAY))
@@ -3357,7 +3375,8 @@ void send_topic_burst(aClient *cptr)
int m_topic(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
aChannel *chptr = NullChn;
- char *topic = NULL, *name, *tnick = sptr->name;
+ char *topic = NULL, *name, *tnick;
+ char *tmpptr; /* Temporary pointer to remove the user@host part from tnick for non-NICKIPSTR servers */
time_t ts = timeofday;
int member;
@@ -3427,6 +3446,7 @@ int m_topic(aClient *cptr, aClient *sptr, int parc, char *parv[])
chptr->chname);
return 0;
}
+ tnick = make_nick_user_host(sptr->name, sptr->user->username, sptr->user->host);
}
else
{
@@ -3437,6 +3457,7 @@ int m_topic(aClient *cptr, aClient *sptr, int parc, char *parv[])
tnick = parv[2];
ts = atoi(parv[3]);
}
+ else tnick = sptr->name;
/* ignore old topics during burst/race */
if (!IsULine(sptr) && chptr->topic[0] && chptr->topic_time >= ts)
@@ -3451,10 +3472,14 @@ int m_topic(aClient *cptr, aClient *sptr, int parc, char *parv[])
* sends with the topic, so I changed everything to work like that.
* -wd */
- sendto_serv_butone(cptr, ":%s TOPIC %s %s %lu :%s", parv[0],
- chptr->chname, chptr->topic_nick,
- (unsigned long)chptr->topic_time,
- chptr->topic);
+ sendto_capab_serv_butone(cptr, CAPAB_NICKIPSTR, 0, ":%s TOPIC %s %s %lu :%s", parv[0],
+ chptr->chname, chptr->topic_nick,
+ (unsigned long)chptr->topic_time, chptr->topic);
+ if((tmpptr = strchr(tnick, '!')))
+ *tmpptr = '\0'; /* Remove the user@host part before we send it to non-NICKIPSTR servers */
+ sendto_capab_serv_butone(cptr, 0, CAPAB_NICKIPSTR, ":%s TOPIC %s %s %lu :%s", parv[0],
+ chptr->chname, chptr->topic_nick,
+ (unsigned long)chptr->topic_time, chptr->topic);
sendto_channel_butserv_me(chptr, sptr, ":%s TOPIC %s :%s", parv[0],
chptr->chname, chptr->topic);
diff --git a/src/send.c b/src/send.c
index 00fcab0..96fde71 100644
--- a/src/send.c
+++ b/src/send.c
@@ -792,6 +792,35 @@ void sendto_serv_butone_nickipstr(aClient *one, int flag, char *pattern, ...)
return;
}
+/* sendto_capab_serv_butone - Send a message to all servers with "include" capab and without "exclude" capab */
+void sendto_capab_serv_butone(aClient *one, int include, int exclude, char *pattern, ...)
+{
+ aClient *cptr;
+ int k = 0;
+ fdlist send_fdlist;
+ va_list vl;
+ DLink *lp;
+
+ va_start(vl, pattern);
+ for(lp = server_list; lp; lp = lp->next)
+ {
+ cptr = lp->value.cptr;
+
+ if ((one==cptr) ||
+ (include && !(cptr->capabilities & include)) ||
+ (exclude && (cptr->capabilities & exclude)))
+ continue;
+
+ send_fdlist.entry[++k] = cptr->fd;
+ }
+ send_fdlist.last_entry = k;
+ if (k)
+ vsendto_fdlist(&send_fdlist, pattern, vl);
+ va_end(vl);
+
+ return;
+}
+
/*
* sendto_server_butone
*
--
1.7.1.1