mirror of
https://github.com/osmarks/ngircd.git
synced 2024-12-12 09:50:29 +00:00
Respect RFC 1459 compatibility mode when announcing channels (no NJOIN).
This commit is contained in:
parent
1d6dcb25c4
commit
ec0b405d9d
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ngIRCd -- The Next Generation IRC Daemon
|
* ngIRCd -- The Next Generation IRC Daemon
|
||||||
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
|
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
#include "portab.h"
|
#include "portab.h"
|
||||||
|
|
||||||
static char UNUSED id[] = "$Id: irc-channel.c,v 1.45 2008/02/24 18:57:38 fw Exp $";
|
|
||||||
|
|
||||||
#include "imp.h"
|
#include "imp.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -122,20 +120,45 @@ join_set_channelmodes(CHANNEL *chan, CLIENT *target, const char *flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
cb_join_forward(CLIENT *To, CLIENT *Prefix, void *Data)
|
||||||
|
{
|
||||||
|
CONN_ID conn;
|
||||||
|
char str[COMMAND_LEN], *ptr = NULL;
|
||||||
|
|
||||||
|
strlcpy(str, (char *)Data, sizeof(str));
|
||||||
|
conn = Client_Conn(To);
|
||||||
|
|
||||||
|
if (Conn_Options(conn) & CONN_RFC1459) {
|
||||||
|
/* RFC 1459 compatibility mode, appended modes are NOT
|
||||||
|
* supported, so strip them off! */
|
||||||
|
ptr = strchr(str, 0x7);
|
||||||
|
if (ptr)
|
||||||
|
*ptr++ = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
IRC_WriteStrClientPrefix(To, Prefix, "JOIN %s", str);
|
||||||
|
if (ptr && *ptr)
|
||||||
|
IRC_WriteStrClientPrefix(To, Prefix, "MODE %s +%s %s", str, ptr,
|
||||||
|
Client_ID(Prefix));
|
||||||
|
} /* cb_join_forward */
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan,
|
join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan,
|
||||||
const char *channame)
|
const char *channame)
|
||||||
{
|
{
|
||||||
char modes[8];
|
char modes[CHANNEL_MODE_LEN], str[COMMAND_LEN];
|
||||||
|
|
||||||
strlcpy(&modes[1], Channel_UserModes(chan, target), sizeof(modes) - 1);
|
strlcpy(&modes[1], Channel_UserModes(chan, target), sizeof(modes) - 1);
|
||||||
|
|
||||||
if (modes[1])
|
if (modes[1])
|
||||||
modes[0] = 0x7;
|
modes[0] = 0x7;
|
||||||
else
|
else
|
||||||
modes[0] = '\0';
|
modes[0] = '\0';
|
||||||
|
|
||||||
/* forward to other servers */
|
/* forward to other servers */
|
||||||
IRC_WriteStrServersPrefix(Client, target, "JOIN :%s%s", channame, modes);
|
snprintf(str, sizeof(str), "%s%s", channame, modes);
|
||||||
|
IRC_WriteStrServersPrefixFlag_CB(Client, target, '\0', cb_join_forward, str);
|
||||||
|
|
||||||
/* tell users in this channel about the new client */
|
/* tell users in this channel about the new client */
|
||||||
IRC_WriteStrChannelPrefix(Client, chan, target, false, "JOIN :%s", channame);
|
IRC_WriteStrChannelPrefix(Client, chan, target, false, "JOIN :%s", channame);
|
||||||
@ -460,7 +483,7 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
|
|||||||
Req->argv[1] );
|
Req->argv[1] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while( pattern )
|
while( pattern )
|
||||||
{
|
{
|
||||||
/* Loop through all the channels */
|
/* Loop through all the channels */
|
||||||
@ -484,14 +507,14 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
|
|||||||
}
|
}
|
||||||
chan = Channel_Next( chan );
|
chan = Channel_Next( chan );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get next name ... */
|
/* Get next name ... */
|
||||||
if( Req->argc > 0 )
|
if( Req->argc > 0 )
|
||||||
pattern = strtok( NULL, "," );
|
pattern = strtok( NULL, "," );
|
||||||
else
|
else
|
||||||
pattern = NULL;
|
pattern = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IRC_WriteStrClient( from, RPL_LISTEND_MSG, Client_ID( from ));
|
return IRC_WriteStrClient( from, RPL_LISTEND_MSG, Client_ID( from ));
|
||||||
} /* IRC_LIST */
|
} /* IRC_LIST */
|
||||||
|
|
||||||
@ -560,7 +583,7 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req )
|
|||||||
}
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inform members of this channel */
|
/* Inform members of this channel */
|
||||||
IRC_WriteStrChannelPrefix( Client, chan, from, false, "MODE %s +%s%s", Req->argv[0], Channel_Modes( chan ), modes_add );
|
IRC_WriteStrChannelPrefix( Client, chan, from, false, "MODE %s +%s%s", Req->argv[0], Channel_Modes( chan ), modes_add );
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,77 @@
|
|||||||
#include "numeric.h"
|
#include "numeric.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Announce a channel and its users in the network.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
Announce_Channel(CLIENT *Client, CHANNEL *Chan)
|
||||||
|
{
|
||||||
|
CL2CHAN *cl2chan;
|
||||||
|
CLIENT *cl;
|
||||||
|
char str[LINE_LEN], *ptr;
|
||||||
|
bool njoin;
|
||||||
|
|
||||||
|
if (Conn_Options(Client_Conn(Client)) & CONN_RFC1459)
|
||||||
|
njoin = false;
|
||||||
|
else
|
||||||
|
njoin = true;
|
||||||
|
|
||||||
|
/* Get all the members of this channel */
|
||||||
|
cl2chan = Channel_FirstMember(Chan);
|
||||||
|
snprintf(str, sizeof(str), "NJOIN %s :", Channel_Name(Chan));
|
||||||
|
while (cl2chan) {
|
||||||
|
cl = Channel_GetClient(cl2chan);
|
||||||
|
assert(cl != NULL);
|
||||||
|
|
||||||
|
if (njoin) {
|
||||||
|
/* RFC 2813: send NJOIN with nick names and modes
|
||||||
|
* (if user is channel operator or has voice) */
|
||||||
|
if (str[strlen(str) - 1] != ':')
|
||||||
|
strlcat(str, ",", sizeof(str));
|
||||||
|
if (strchr(Channel_UserModes(Chan, cl), 'v'))
|
||||||
|
strlcat(str, "+", sizeof(str));
|
||||||
|
if (strchr(Channel_UserModes(Chan, cl), 'o'))
|
||||||
|
strlcat(str, "@", sizeof(str));
|
||||||
|
strlcat(str, Client_ID(cl), sizeof(str));
|
||||||
|
|
||||||
|
/* Send the data if the buffer is "full" */
|
||||||
|
if (strlen(str) > (LINE_LEN - CLIENT_NICK_LEN - 8)) {
|
||||||
|
if (!IRC_WriteStrClient(Client, "%s", str))
|
||||||
|
return DISCONNECTED;
|
||||||
|
snprintf(str, sizeof(str), "NJOIN %s :",
|
||||||
|
Channel_Name(Chan));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* RFC 1459: no NJOIN, send JOIN and MODE */
|
||||||
|
if (!IRC_WriteStrClientPrefix(Client, cl, "JOIN %s",
|
||||||
|
Channel_Name(Chan)))
|
||||||
|
return DISCONNECTED;
|
||||||
|
ptr = Channel_UserModes(Chan, cl);
|
||||||
|
while (*ptr) {
|
||||||
|
if (!IRC_WriteStrClientPrefix(Client, cl,
|
||||||
|
"MODE %s +%c %s",
|
||||||
|
Channel_Name(Chan), ptr[0],
|
||||||
|
Client_ID(cl)))
|
||||||
|
return DISCONNECTED;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cl2chan = Channel_NextMember(Chan, cl2chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Data left in the buffer? */
|
||||||
|
if (str[strlen(str) - 1] != ':') {
|
||||||
|
/* Yes, send it ... */
|
||||||
|
if (!IRC_WriteStrClient(Client, "%s", str))
|
||||||
|
return DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CONNECTED;
|
||||||
|
} /* Announce_Channel */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Announce new server in the network
|
* Announce new server in the network
|
||||||
* @param Client New server
|
* @param Client New server
|
||||||
@ -219,11 +290,9 @@ Send_CHANINFO(CLIENT * Client, CHANNEL * Chan)
|
|||||||
GLOBAL bool
|
GLOBAL bool
|
||||||
IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
|
IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
|
||||||
{
|
{
|
||||||
char str[LINE_LEN];
|
|
||||||
int max_hops, i;
|
int max_hops, i;
|
||||||
CLIENT *c, *cl;
|
CLIENT *c;
|
||||||
CHANNEL *chan;
|
CHANNEL *chan;
|
||||||
CL2CHAN *cl2chan;
|
|
||||||
|
|
||||||
Client_SetType(Client, CLIENT_SERVER);
|
Client_SetType(Client, CLIENT_SERVER);
|
||||||
|
|
||||||
@ -280,39 +349,8 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get all the members of this channel */
|
if (!Announce_Channel(Client, chan))
|
||||||
cl2chan = Channel_FirstMember(chan);
|
return DISCONNECTED;
|
||||||
snprintf(str, sizeof(str), "NJOIN %s :", Channel_Name(chan));
|
|
||||||
while (cl2chan) {
|
|
||||||
cl = Channel_GetClient(cl2chan);
|
|
||||||
assert(cl != NULL);
|
|
||||||
|
|
||||||
/* Nick name, with modes (if applicable) */
|
|
||||||
if (str[strlen(str) - 1] != ':')
|
|
||||||
strlcat(str, ",", sizeof(str));
|
|
||||||
if (strchr(Channel_UserModes(chan, cl), 'v'))
|
|
||||||
strlcat(str, "+", sizeof(str));
|
|
||||||
if (strchr(Channel_UserModes(chan, cl), 'o'))
|
|
||||||
strlcat(str, "@", sizeof(str));
|
|
||||||
strlcat(str, Client_ID(cl), sizeof(str));
|
|
||||||
|
|
||||||
/* Send the data if the buffer is "full" */
|
|
||||||
if (strlen(str) > (LINE_LEN - CLIENT_NICK_LEN - 8)) {
|
|
||||||
if (!IRC_WriteStrClient(Client, "%s", str))
|
|
||||||
return DISCONNECTED;
|
|
||||||
snprintf(str, sizeof(str), "NJOIN %s :",
|
|
||||||
Channel_Name(chan));
|
|
||||||
}
|
|
||||||
|
|
||||||
cl2chan = Channel_NextMember(chan, cl2chan);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Data left in the buffer? */
|
|
||||||
if (str[strlen(str) - 1] != ':') {
|
|
||||||
/* Yes, send it ... */
|
|
||||||
if (!IRC_WriteStrClient(Client, "%s", str))
|
|
||||||
return DISCONNECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get next channel ... */
|
/* Get next channel ... */
|
||||||
chan = Channel_Next(chan);
|
chan = Channel_Next(chan);
|
||||||
|
Loading…
Reference in New Issue
Block a user