From 4ef172d60331611ddb4d96ba33266998eb7ae505 Mon Sep 17 00:00:00 2001 From: Alexander Barton Date: Wed, 2 Mar 2005 16:35:10 +0000 Subject: [PATCH] Implemented support for "secret channels" (channel mode "s"). --- ChangeLog | 3 ++- NEWS | 5 +++-- src/ngircd/defines.h | 6 +++--- src/ngircd/irc-channel.c | 14 +++++++++----- src/ngircd/irc-info.c | 38 +++++++++++++++++++++++++++++--------- src/ngircd/irc-mode.c | 3 ++- 6 files changed, 48 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 13929d53..13891598 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ ngIRCd CVSHEAD + - Implemented support for "secret channels" (channel mode "s"). - New configuration option "Mask" for [Operator] sections to limit OPER commands to ussers with a specific IRC mask. Patch from Florian Westphal. - Write "error file" (/tmp/ngircd-XXX.err) only if compiled with debug @@ -588,4 +589,4 @@ ngIRCd 0.0.1, 31.12.2001 -- -$Id: ChangeLog,v 1.262 2005/03/02 16:07:30 alex Exp $ +$Id: ChangeLog,v 1.263 2005/03/02 16:35:10 alex Exp $ diff --git a/NEWS b/NEWS index 4778cd7d..6a49e149 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2004 by Alexander Barton, + (c)2001-2005 Alexander Barton, alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -12,6 +12,7 @@ ngIRCd CVSHEAD + - Implemented support for "secret channels" (channel mode "s"). - New configuration option "Mask" for [Operator] sections to limit OPER commands to ussers with a specific IRC mask. Patch from Florian Westphal. - New configuration variable "PidFile", section "[Global]": if defined, @@ -200,4 +201,4 @@ ngIRCd 0.0.1, 31.12.2001 -- -$Id: NEWS,v 1.69 2005/03/02 16:07:30 alex Exp $ +$Id: NEWS,v 1.70 2005/03/02 16:35:10 alex Exp $ diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h index 12558ef3..7d6ff21d 100644 --- a/src/ngircd/defines.h +++ b/src/ngircd/defines.h @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: defines.h,v 1.49 2005/02/04 14:24:21 alex Exp $ + * $Id: defines.h,v 1.50 2005/03/02 16:35:11 alex Exp $ * * Global defines of ngIRCd. */ @@ -49,7 +49,7 @@ #define CLIENT_FLAGS_LEN 100 /* max. length of client flags */ #define CHANNEL_NAME_LEN 51 /* max. length of a channel name, see. RFC 2812, 1.3 */ -#define CHANNEL_MODE_LEN 8 /* max. length of channel modes */ +#define CHANNEL_MODE_LEN 9 /* max. length of channel modes */ #define CHANNEL_TOPIC_LEN 128 /* max. length of a channel topic */ #define COMMAND_LEN 513 /* max. IRC command length, see. RFC 2812, 3.2 */ @@ -74,7 +74,7 @@ #define RECONNECT_DELAY 3 /* time to delay re-connect attempts (seconds) */ #define USERMODES "aios" /* supported user modes */ -#define CHANMODES "biklImnoPtv" /* supported channel modes */ +#define CHANMODES "biklImnoPstv" /* supported channel modes */ #define CONNECTED TRUE /* internal status codes */ #define DISCONNECTED FALSE diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c index 79be0005..a37fca96 100644 --- a/src/ngircd/irc-channel.c +++ b/src/ngircd/irc-channel.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-channel.c,v 1.27 2004/04/09 20:46:48 alex Exp $"; +static char UNUSED id[] = "$Id: irc-channel.c,v 1.28 2005/03/02 16:35:11 alex Exp $"; #include "imp.h" #include @@ -349,15 +349,19 @@ IRC_LIST( CLIENT *Client, REQUEST *Req ) while( pattern ) { - /* alle Channel durchgehen */ + /* Loop through all the channels */ chan = Channel_First( ); while( chan ) { - /* Passt die Suchmaske auf diesen Channel? */ + /* Check search pattern */ if( Match( pattern, Channel_Name( chan ))) { - /* Treffer! */ - if( ! IRC_WriteStrClient( from, RPL_LIST_MSG, from, Channel_Name( chan ), Channel_MemberCount( chan ), Channel_Topic( chan ))) return DISCONNECTED; + /* Gotcha! */ + if( ! strchr( Channel_Modes( chan ), 's' ) || + Channel_IsMemberOf( chan, from )) + { + if( ! IRC_WriteStrClient( from, RPL_LIST_MSG, from, Channel_Name( chan ), Channel_MemberCount( chan ), Channel_Topic( chan ))) return DISCONNECTED; + } } chan = Channel_Next( chan ); } diff --git a/src/ngircd/irc-info.c b/src/ngircd/irc-info.c index 0d7246f8..3811ea73 100644 --- a/src/ngircd/irc-info.c +++ b/src/ngircd/irc-info.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-info.c,v 1.26 2005/02/09 09:52:58 alex Exp $"; +static char UNUSED id[] = "$Id: irc-info.c,v 1.27 2005/03/02 16:35:11 alex Exp $"; #include "imp.h" #include @@ -543,7 +543,7 @@ IRC_WHO( CLIENT *Client, REQUEST *Req ) BOOLEAN ok, only_ops; CHAR flags[8], *ptr; CL2CHAN *cl2chan; - CHANNEL *chan; + CHANNEL *chan, *cn; CLIENT *c; assert( Client != NULL ); @@ -591,14 +591,25 @@ IRC_WHO( CLIENT *Client, REQUEST *Req ) if( ok && (( ! only_ops ) || ( strchr( Client_Modes( c ), 'o' )))) { - /* Flags zusammenbasteln */ + /* Get flags */ strcpy( flags, "H" ); if( strchr( Client_Modes( c ), 'o' )) strlcat( flags, "*", sizeof( flags )); - /* ausgeben */ + /* Search suitable channel */ cl2chan = Channel_FirstChannelOf( c ); - if( cl2chan ) ptr = Channel_Name( Channel_GetChannel( cl2chan )); - else ptr = "*"; + while( cl2chan ) + { + cn = Channel_GetChannel( cl2chan ); + if( Channel_IsMemberOf( cn, Client ) || + ! strchr( Channel_Modes( cn ), 's' )) + { + ptr = Channel_Name( cn ); + break; + } + cl2chan = Channel_NextChannelOf( c, cl2chan ); + } + if( ! cl2chan ) ptr = "*"; + if( ! IRC_WriteStrClient( Client, RPL_WHOREPLY_MSG, Client_ID( Client ), ptr, Client_User( c ), Client_Hostname( c ), Client_ID( Client_Introducer( c )), Client_ID( c ), flags, Client_Hops( c ), Client_Info( c ))) return DISCONNECTED; } } @@ -663,6 +674,12 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) chan = Channel_GetChannel( cl2chan ); assert( chan != NULL ); + /* next */ + cl2chan = Channel_NextChannelOf( c, cl2chan ); + + /* Secret channel? */ + if( strchr( Channel_Modes( chan ), 's' ) && ! Channel_IsMemberOf( chan, Client )) continue; + /* Concatenate channel names */ if( str[strlen( str ) - 1] != ':' ) strlcat( str, " ", sizeof( str )); if( strchr( Channel_UserModes( chan, c ), 'o' )) strlcat( str, "@", sizeof( str )); @@ -675,9 +692,6 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED; snprintf( str, sizeof( str ), RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c )); } - - /* next */ - cl2chan = Channel_NextChannelOf( c, cl2chan ); } if( str[strlen( str ) - 1] != ':') { @@ -822,6 +836,9 @@ IRC_Send_NAMES( CLIENT *Client, CHANNEL *Chan ) if( Channel_IsMemberOf( Chan, Client )) is_member = TRUE; else is_member = FALSE; + /* Secret channel? */ + if( ! is_member && strchr( Channel_Modes( Chan ), 's' )) return CONNECTED; + /* Alle Mitglieder suchen */ snprintf( str, sizeof( str ), RPL_NAMREPLY_MSG, Client_ID( Client ), "=", Channel_Name( Chan )); cl2chan = Channel_FirstMember( Chan ); @@ -875,6 +892,9 @@ IRC_Send_WHO( CLIENT *Client, CHANNEL *Chan, BOOLEAN OnlyOps ) if( Channel_IsMemberOf( Chan, Client )) is_member = TRUE; else is_member = FALSE; + /* Secret channel? */ + if( ! is_member && strchr( Channel_Modes( Chan ), 's' )) return CONNECTED; + /* Alle Mitglieder suchen */ cl2chan = Channel_FirstMember( Chan ); while( cl2chan ) diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c index bbecca98..368185f6 100644 --- a/src/ngircd/irc-mode.c +++ b/src/ngircd/irc-mode.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-mode.c,v 1.36 2005/02/27 20:09:44 alex Exp $"; +static char UNUSED id[] = "$Id: irc-mode.c,v 1.37 2005/03/02 16:35:11 alex Exp $"; #include "imp.h" #include @@ -362,6 +362,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) case 'i': /* Invite only */ case 'm': /* Moderated */ case 'n': /* Only members can write */ + case 's': /* Secret channel */ case 't': /* Topic locked */ if( modeok ) x[0] = *mode_ptr; else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));