aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-05-03 00:44:33 +0100
committerWilmer van der Gaast <wilmer@gaast.net>2010-05-03 00:44:33 +0100
commite54112f152c375df81a21181f755ced5f57165bc (patch)
treeeebdf4bd47b9e7fe81bb5ac109ac0d4928b3240d
parentbce78c8e6b9363175943a1b10df76fdbd87ba0c8 (diff)
Put a channel userlist in irc_channel_user elements so we can save flags
(i.e. modes).
-rw-r--r--irc.h15
-rw-r--r--irc_channel.c43
-rw-r--r--irc_send.c7
3 files changed, 56 insertions, 9 deletions
diff --git a/irc.h b/irc.h
index 3a1a3520..0d233844 100644
--- a/irc.h
+++ b/irc.h
@@ -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 )
{
diff --git a/irc_send.c b/irc_send.c
index 0d9aba48..a1df68b2 100644
--- a/irc_send.c
+++ b/irc_send.c
@@ -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,