diff options
| -rw-r--r-- | irc.h | 15 | ||||
| -rw-r--r-- | irc_channel.c | 43 | ||||
| -rw-r--r-- | irc_send.c | 7 | 
3 files changed, 56 insertions, 9 deletions
| @@ -152,6 +152,19 @@ struct irc_channel_funcs  	gboolean (*privmsg)( irc_channel_t *iu, const char *msg );  }; +typedef enum +{ +	IRC_CHANNEL_USER_OP = 1, +	IRC_CHANNEL_USER_HALFOP = 2, +	IRC_CHANNEL_USER_VOICE = 4, +} irc_channel_user_flags_t; + +typedef struct irc_channel_user +{ +	irc_user_t *iu; +	int flags; +} irc_channel_user_t; +  extern const struct bee_ui_funcs irc_ui_funcs;  /* irc.c */ @@ -180,7 +193,7 @@ irc_channel_t *irc_channel_by_name( irc_t *irc, const char *name );  int irc_channel_free( irc_channel_t *ic );  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 ); -gboolean irc_channel_has_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 );  gboolean irc_channel_name_ok( const char *name ); diff --git a/irc_channel.c b/irc_channel.c index 60c2e422..17ea64d3 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -25,6 +25,7 @@  #include "bitlbee.h" +static gint irc_channel_user_cmp( gconstpointer a_, gconstpointer b_ );  static const struct irc_channel_funcs control_channel_funcs;  irc_channel_t *irc_channel_new( irc_t *irc, const char *name ) @@ -70,7 +71,11 @@ int irc_channel_free( irc_channel_t *ic )  		irc_channel_del_user( ic, irc->user );  	irc->channels = g_slist_remove( irc->channels, ic ); -	g_slist_free( ic->users ); +	while( ic->users ) +	{ +		g_free( ic->users->data ); +		ic->users = g_slist_remove( ic->users, ic->users->data ); +	}  	g_free( ic->name );  	g_free( ic->topic ); @@ -81,10 +86,15 @@ int irc_channel_free( irc_channel_t *ic )  int irc_channel_add_user( irc_channel_t *ic, irc_user_t *iu )  { +	irc_channel_user_t *icu; +	  	if( irc_channel_has_user( ic, iu ) )  		return 0; -	ic->users = g_slist_insert_sorted( ic->users, iu, irc_user_cmp ); +	icu = g_new0( irc_channel_user_t, 1 ); +	icu->iu = iu; +	 +	ic->users = g_slist_insert_sorted( ic->users, icu, irc_channel_user_cmp );  	if( iu == ic->irc->user || ic->flags & IRC_CHANNEL_JOINED )  	{ @@ -97,10 +107,13 @@ 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 )  { -	if( !irc_channel_has_user( ic, iu ) ) +	irc_channel_user_t *icu; +	 +	if( !( icu = irc_channel_has_user( ic, iu ) ) )  		return 0; -	ic->users = g_slist_remove( ic->users, iu ); +	ic->users = g_slist_remove( ic->users, icu ); +	g_free( icu );  	if( ic->flags & IRC_CHANNEL_JOINED )  		irc_send_part( ic, iu, "" ); @@ -111,10 +124,19 @@ int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu )  	return 1;  } -/* Currently a fairly stupid one-liner but I fear it's going to get worse. :-) */ -gboolean irc_channel_has_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 )  { -	return g_slist_find( ic->users, iu ) != NULL; +	GSList *l; +	 +	for( l = ic->users; l; l = l->next ) +	{ +		irc_channel_user_t *icu = l->data; +		 +		if( icu->iu == iu ) +			return icu; +	} +	 +	return NULL;  }  int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_t *iu ) @@ -141,6 +163,13 @@ gboolean irc_channel_name_ok( const char *name )  	return strchr( CTYPES, name[0] ) != NULL && nick_ok( name + 1 );  } +static gint irc_channel_user_cmp( gconstpointer a_, gconstpointer b_ ) +{ +	const irc_channel_user_t *a = a_, *b = b_; +	 +	return irc_user_cmp( a->iu, b->iu ); +} +  /* Channel-type dependent functions, for control channels: */  static gboolean control_channel_privmsg( irc_channel_t *ic, const char *msg )  { @@ -162,7 +162,8 @@ void irc_send_names( irc_channel_t *ic )  	   channel is invalid, just give an empty reply. */  	for( l = ic->users; l; l = l->next )  	{ -		irc_user_t *iu = l->data; +		irc_channel_user_t *icu = l->data; +		irc_user_t *iu = icu->iu;  		if( strlen( namelist ) + strlen( iu->nick ) > sizeof( namelist ) - 4 )  		{ @@ -242,9 +243,13 @@ void irc_send_whois( irc_user_t *iu )  void irc_send_who( irc_t *irc, GSList *l, const char *channel )  { +	gboolean is_channel = strcmp( channel, "**" ) != 0; +	  	while( l )  	{  		irc_user_t *iu = l->data; +		if( is_channel ) +			iu = ((irc_channel_user_t*)iu)->iu;  		/* TODO(wilmer): Restore away/channel information here */  		irc_send_num( irc, 352, "%s %s %s %s %s %c :0 %s",  		              channel ? : "*", iu->user, iu->host, irc->root->host, | 
