mirror of
				https://github.com/osmarks/ngircd.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	This adds support for sending NOTICEs to a channel.
[also see Bug #70 in ngircd bugzilla]. Based on a patch by Fabian Schlager <fabian.schlager@gmail.com>.
This commit is contained in:
		| @@ -12,8 +12,11 @@ | |||||||
|  |  | ||||||
| ngIRCd HEAD | ngIRCd HEAD | ||||||
|  |  | ||||||
| ngIRCd 0.11.0-pre2 (2008-01-07) |   - allow NOTICEs to be sent to a channel. (Fabian Schlager) | ||||||
|  |  | ||||||
|  | ngIRCd 0.11.0 (2008-01-15) | ||||||
|  |  | ||||||
|  |   ngIRCd 0.11.0-pre2 (2008-01-07) | ||||||
|   - SECURITY: IRC_PART could reference invalid memory, causing |   - SECURITY: IRC_PART could reference invalid memory, causing | ||||||
|     ngircd to crash [from HEAD]. |     ngircd to crash [from HEAD]. | ||||||
|    |    | ||||||
| @@ -735,4 +738,4 @@ ngIRCd 0.0.1, 31.12.2001 | |||||||
|  |  | ||||||
|  |  | ||||||
| --  | --  | ||||||
| $Id: ChangeLog,v 1.334 2008/01/07 23:08:14 alex Exp $ | $Id: ChangeLog,v 1.335 2008/01/15 22:28:15 fw Exp $ | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ | |||||||
|  |  | ||||||
| #include "portab.h" | #include "portab.h" | ||||||
|  |  | ||||||
| static char UNUSED id[] = "$Id: channel.c,v 1.63 2007/06/11 20:06:46 fw Exp $"; | static char UNUSED id[] = "$Id: channel.c,v 1.64 2008/01/15 22:28:14 fw Exp $"; | ||||||
|  |  | ||||||
| #include "imp.h" | #include "imp.h" | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| @@ -695,38 +695,66 @@ Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count) | |||||||
| } /* Channel_SetMaxUsers */ | } /* Channel_SetMaxUsers */ | ||||||
|  |  | ||||||
|  |  | ||||||
| GLOBAL bool | static bool | ||||||
| Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, char *Text ) | Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From) | ||||||
| { | { | ||||||
| 	bool is_member, has_voice, is_op, ok; | 	bool is_member, has_voice, is_op; | ||||||
|  |  | ||||||
| 	/* Okay, target is a channel */ |  | ||||||
| 	is_member = has_voice = is_op = false; | 	is_member = has_voice = is_op = false; | ||||||
| 	if( Channel_IsMemberOf( Chan, From )) |  | ||||||
| 	{ | 	if (Channel_IsMemberOf(Chan, From)) { | ||||||
| 		is_member = true; | 		is_member = true; | ||||||
| 		if( strchr( Channel_UserModes( Chan, From ), 'v' )) has_voice = true; | 		if (strchr(Channel_UserModes(Chan, From), 'v')) | ||||||
| 		if( strchr( Channel_UserModes( Chan, From ), 'o' )) is_op = true; | 			has_voice = true; | ||||||
|  | 		if (strchr(Channel_UserModes(Chan, From), 'o')) | ||||||
|  | 			is_op = true; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* Is the client allowed to write to channel? */ | 	/* | ||||||
| 	ok = true; | 	 * Is the client allowed to write to channel? | ||||||
| 	if( strchr( Channel_Modes( Chan ), 'n' ) && ( ! is_member )) ok = false; | 	 * | ||||||
| 	if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = false; | 	 * If channel mode n set: non-members cannot send to channel. | ||||||
|  | 	 * If channel mode m set: need voice. | ||||||
|  | 	 */ | ||||||
|  | 	if (strchr(Channel_Modes(Chan), 'n') && !is_member) | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
| 	/* Is the client banned? */ | 	if (is_op || has_voice) | ||||||
| 	if( Lists_Check(&Chan->list_bans, From)) | 		return true; | ||||||
| 	{ |  | ||||||
| 		/* Client is banned, but is he channel operator or has voice? */ |  | ||||||
| 		if(( ! has_voice ) && ( ! is_op )) ok = false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if( ! ok ) return IRC_WriteStrClient( From, ERR_CANNOTSENDTOCHAN_MSG, Client_ID( From ), Channel_Name( Chan )); | 	if (strchr(Channel_Modes(Chan), 'm')) | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
| 	/* Send text */ | 	return !Lists_Check(&Chan->list_bans, From); | ||||||
| 	if( Client_Conn( From ) > NONE ) Conn_UpdateIdle( Client_Conn( From )); | } | ||||||
| 	return IRC_WriteStrChannelPrefix( Client, Chan, From, true, "PRIVMSG %s :%s", Channel_Name( Chan ), Text ); |  | ||||||
| } /* Channel_Write */ |  | ||||||
|  | GLOBAL bool | ||||||
|  | Channel_Write(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Text) | ||||||
|  | { | ||||||
|  | 	if (!Can_Send_To_Channel(Chan, From)) | ||||||
|  | 		return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG, Client_ID(From), Channel_Name(Chan)); | ||||||
|  |  | ||||||
|  | 	if (Client_Conn(From) > NONE) | ||||||
|  | 		Conn_UpdateIdle(Client_Conn(From)); | ||||||
|  |  | ||||||
|  | 	return IRC_WriteStrChannelPrefix(Client, Chan, From, true, | ||||||
|  | 			"PRIVMSG %s :%s", Channel_Name(Chan), Text); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | GLOBAL bool | ||||||
|  | Channel_Notice(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Text) | ||||||
|  | { | ||||||
|  | 	if (!Can_Send_To_Channel(Chan, From)) | ||||||
|  | 		return true; /* no error, see RFC 2812 */ | ||||||
|  |  | ||||||
|  | 	if (Client_Conn(From) > NONE) | ||||||
|  | 		Conn_UpdateIdle(Client_Conn(From)); | ||||||
|  |  | ||||||
|  | 	return IRC_WriteStrChannelPrefix(Client, Chan, From, true, | ||||||
|  | 			"NOTICE %s :%s", Channel_Name(Chan), Text); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| GLOBAL CHANNEL * | GLOBAL CHANNEL * | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|  * (at your option) any later version. |  * (at your option) any later version. | ||||||
|  * Please read the file COPYING, README and AUTHORS for more information. |  * Please read the file COPYING, README and AUTHORS for more information. | ||||||
|  * |  * | ||||||
|  * $Id: channel.h,v 1.33 2006/12/07 22:23:39 fw Exp $ |  * $Id: channel.h,v 1.34 2008/01/15 22:28:14 fw Exp $ | ||||||
|  * |  * | ||||||
|  * Channel management (header) |  * Channel management (header) | ||||||
|  */ |  */ | ||||||
| @@ -109,7 +109,8 @@ GLOBAL char *Channel_UserModes PARAMS(( CHANNEL *Chan, CLIENT *Client )); | |||||||
|  |  | ||||||
| GLOBAL bool Channel_IsMemberOf PARAMS(( CHANNEL *Chan, CLIENT *Client )); | GLOBAL bool Channel_IsMemberOf PARAMS(( CHANNEL *Chan, CLIENT *Client )); | ||||||
|  |  | ||||||
| GLOBAL bool Channel_Write PARAMS(( CHANNEL *Chan, CLIENT *From, CLIENT *Client, char *Text )); | GLOBAL bool Channel_Write PARAMS(( CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Text )); | ||||||
|  | GLOBAL bool Channel_Notice PARAMS(( CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Text)); | ||||||
|  |  | ||||||
| GLOBAL CHANNEL *Channel_Create PARAMS(( char *Name )); | GLOBAL CHANNEL *Channel_Create PARAMS(( char *Name )); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ | |||||||
|  |  | ||||||
| #include "portab.h" | #include "portab.h" | ||||||
|  |  | ||||||
| static char UNUSED id[] = "$Id: irc.c,v 1.131 2006/07/23 14:55:40 alex Exp $"; | static char UNUSED id[] = "$Id: irc.c,v 1.132 2008/01/15 22:28:14 fw Exp $"; | ||||||
|  |  | ||||||
| #include "imp.h" | #include "imp.h" | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| @@ -170,6 +170,7 @@ GLOBAL bool | |||||||
| IRC_NOTICE( CLIENT *Client, REQUEST *Req ) | IRC_NOTICE( CLIENT *Client, REQUEST *Req ) | ||||||
| { | { | ||||||
| 	CLIENT *to, *from; | 	CLIENT *to, *from; | ||||||
|  | 	CHANNEL *chan; | ||||||
|  |  | ||||||
| 	assert( Client != NULL ); | 	assert( Client != NULL ); | ||||||
| 	assert( Req != NULL ); | 	assert( Req != NULL ); | ||||||
| @@ -189,7 +190,14 @@ IRC_NOTICE( CLIENT *Client, REQUEST *Req ) | |||||||
| 		/* Okay, Ziel ist ein User */ | 		/* Okay, Ziel ist ein User */ | ||||||
| 		return IRC_WriteStrClientPrefix( to, from, "NOTICE %s :%s", Client_ID( to ), Req->argv[1] ); | 		return IRC_WriteStrClientPrefix( to, from, "NOTICE %s :%s", Client_ID( to ), Req->argv[1] ); | ||||||
| 	} | 	} | ||||||
| 	else return CONNECTED; | 	else | ||||||
|  | 	{ | ||||||
|  | 		chan = Channel_Search(Req->argv[0]); | ||||||
|  | 		if (chan) | ||||||
|  | 			return Channel_Notice(chan, from, Client, Req->argv[1]); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return CONNECTED; | ||||||
| } /* IRC_NOTICE */ | } /* IRC_NOTICE */ | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Florian Westphal
					Florian Westphal