diff options
| -rw-r--r-- | irc.c | 4 | ||||
| -rw-r--r-- | irc.h | 3 | ||||
| -rw-r--r-- | irc_channel.c | 16 | ||||
| -rw-r--r-- | irc_im.c | 4 | ||||
| -rw-r--r-- | irc_send.c | 61 | 
5 files changed, 81 insertions, 7 deletions
| @@ -639,6 +639,10 @@ int irc_check_login( irc_t *irc )  			irc_channel_set_topic( ic, CONTROL_TOPIC, irc->root );  			irc_channel_add_user( ic, irc->user ); +			if( strcmp( set_getstr( &irc->b->set, "ops" ), "both" ) == 0 || +			    strcmp( set_getstr( &irc->b->set, "ops" ), "user" ) == 0 ) +				irc_channel_user_set_mode( ic, irc->user, IRC_CHANNEL_USER_OP ); +			  			irc->last_root_cmd = g_strdup( ROOT_CHAN );  			irc_send_msg( irc->root, "PRIVMSG", ROOT_CHAN, @@ -195,6 +195,7 @@ int irc_channel_add_user( irc_channel_t *ic, irc_user_t *iu );  int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu );  irc_channel_user_t *irc_channel_has_user( irc_channel_t *ic, irc_user_t *iu );  int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_t *who ); +void irc_channel_user_set_mode( irc_channel_t *ic, irc_user_t *iu, irc_channel_user_flags_t flags );  gboolean irc_channel_name_ok( const char *name );  /* irc_commands.c */ @@ -215,6 +216,8 @@ void irc_send_msg( irc_user_t *iu, const char *type, const char *dst, const char  void irc_send_msg_raw( irc_user_t *iu, const char *type, const char *dst, const char *msg );  void irc_send_msg_f( irc_user_t *iu, const char *type, const char *dst, const char *format, ... ) G_GNUC_PRINTF( 4, 5 );  void irc_send_nick( irc_user_t *iu, const char *new ); +void irc_send_channel_user_mode_diff( irc_channel_t *ic, irc_user_t *iu, +                                      irc_channel_user_flags_t old, irc_channel_user_flags_t new );  /* irc_user.c */  irc_user_t *irc_user_new( irc_t *irc, const char *nick ); diff --git a/irc_channel.c b/irc_channel.c index 17ea64d3..fd79ba71 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -42,6 +42,9 @@ irc_channel_t *irc_channel_new( irc_t *irc, const char *name )  	strcpy( ic->mode, CMODE );  	irc_channel_add_user( ic, irc->root ); +	if( strcmp( set_getstr( &irc->b->set, "ops" ), "both" ) == 0 || +	    strcmp( set_getstr( &irc->b->set, "ops" ), "root" ) == 0 ) +		irc_channel_user_set_mode( ic, irc->root, IRC_CHANNEL_USER_OP );  	irc->channels = g_slist_prepend( irc->channels, ic ); @@ -158,6 +161,19 @@ int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_  	return 1;  } +void irc_channel_user_set_mode( irc_channel_t *ic, irc_user_t *iu, irc_channel_user_flags_t flags ) +{ +	irc_channel_user_t *icu = irc_channel_has_user( ic, iu ); +	 +	if( icu->flags == flags ) +		return; +	 +	if( ic->flags & IRC_CHANNEL_JOINED ) +		irc_send_channel_user_mode_diff( ic, iu, icu->flags, flags ); +	 +	icu->flags = flags; +} +  gboolean irc_channel_name_ok( const char *name )  {  	return strchr( CTYPES, name[0] ) != NULL && nick_ok( name + 1 ); @@ -91,6 +91,10 @@ static gboolean bee_irc_user_status( bee_t *bee, bee_user_t *bu, bee_user_t *old  				              iu->host, (int) time( NULL ), "logged online" );  			irc_channel_add_user( ic, iu ); +			 +			if( set_getbool( &bee->set, "away_devoice" ) ) +				irc_channel_user_set_mode( ic, iu, ( bu->flags & BEE_USER_AWAY ) ? +				                           0 : IRC_CHANNEL_USER_VOICE );  		}  		else  		{ @@ -156,7 +156,6 @@ void irc_send_names( irc_channel_t *ic )  {  	GSList *l;  	char namelist[385] = ""; -	//char *ops = set_getstr( &ic->irc->b->set, "ops" );  	/* RFCs say there is no error reply allowed on NAMES, so when the  	   channel is invalid, just give an empty reply. */ @@ -171,13 +170,12 @@ void irc_send_names( irc_channel_t *ic )  			*namelist = 0;  		} -		/* -		if( u->ic && !u->away && set_getbool( &irc->set, "away_devoice" ) ) -			strcat( namelist, "+" ); -		else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) || -		         ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ) +		if( icu->flags & IRC_CHANNEL_USER_OP )  			strcat( namelist, "@" ); -		*/ +		else if( icu->flags & IRC_CHANNEL_USER_HALFOP ) +			strcat( namelist, "%" ); +		else if( icu->flags & IRC_CHANNEL_USER_VOICE ) +			strcat( namelist, "+" );  		strcat( namelist, iu->nick );  		strcat( namelist, " " ); @@ -326,3 +324,52 @@ void irc_send_nick( irc_user_t *iu, const char *new )  	irc_write( iu->irc, ":%s!%s@%s NICK %s",  	           iu->nick, iu->user, iu->host, new );  } + +/* Send an update of a user's mode inside a channel, compared to what it was. */ +void irc_send_channel_user_mode_diff( irc_channel_t *ic, irc_user_t *iu, +	irc_channel_user_flags_t old, irc_channel_user_flags_t new ) +{ +	char changes[3*(5+strlen(iu->nick))]; +	char from[strlen(ic->irc->root->nick)+strlen(ic->irc->root->user)+strlen(ic->irc->root->host)+3]; +	int n; +	 +	*changes = '\0'; n = 0; +	if( ( old & IRC_CHANNEL_USER_OP ) != ( new & IRC_CHANNEL_USER_OP ) ) +	{ +		n ++; +		if( new & IRC_CHANNEL_USER_OP ) +			strcat( changes, "+o" ); +		else +			strcat( changes, "-o" ); +	} +	if( ( old & IRC_CHANNEL_USER_HALFOP ) != ( new & IRC_CHANNEL_USER_HALFOP ) ) +	{ +		n ++; +		if( new & IRC_CHANNEL_USER_HALFOP ) +			strcat( changes, "+h" ); +		else +			strcat( changes, "-h" ); +	} +	if( ( old & IRC_CHANNEL_USER_VOICE ) != ( new & IRC_CHANNEL_USER_VOICE ) ) +	{ +		n ++; +		if( new & IRC_CHANNEL_USER_VOICE ) +			strcat( changes, "+v" ); +		else +			strcat( changes, "-v" ); +	} +	while( n ) +	{ +		strcat( changes, " " ); +		strcat( changes, iu->nick ); +		n --; +	} +	 +	if( set_getbool( &ic->irc->b->set, "simulate_netsplit" ) ) +		g_snprintf( from, sizeof( from ), "%s", ic->irc->root->host ); +	else +		g_snprintf( from, sizeof( from ), "%s!%s@%s", ic->irc->root->nick, +		            ic->irc->root->user, ic->irc->root->host ); +	 +	irc_write( ic->irc, ":%s MODE %s %s", from, ic->name, changes ); +} | 
