diff options
| -rw-r--r-- | irc.h | 6 | ||||
| -rw-r--r-- | irc_channel.c | 50 | ||||
| -rw-r--r-- | irc_commands.c | 4 | ||||
| -rw-r--r-- | irc_im.c | 124 | ||||
| -rw-r--r-- | root_commands.c | 21 | 
5 files changed, 131 insertions, 74 deletions
| @@ -194,12 +194,6 @@ struct irc_control_channel  	struct account *account;  }; -struct irc_groupchat_stub -{ -	struct account *acc; -	char *room; -}; -  extern const struct bee_ui_funcs irc_ui_funcs;  /* irc.c */ diff --git a/irc_channel.c b/irc_channel.c index 64bbd614..bceb067c 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -28,7 +28,8 @@  static char *set_eval_channel_type( set_t *set, char *value );  static gint irc_channel_user_cmp( gconstpointer a_, gconstpointer b_ );  static const struct irc_channel_funcs control_channel_funcs; -static const struct irc_channel_funcs groupchat_stub_funcs; + +extern const struct irc_channel_funcs irc_channel_im_chat_funcs;  irc_channel_t *irc_channel_new( irc_t *irc, const char *name )  { @@ -103,7 +104,7 @@ static char *set_eval_channel_type( set_t *set, char *value )  	if( strcmp( value, "control" ) == 0 )  		new = &control_channel_funcs;  	else if( strcmp( value, "chat" ) == 0 ) -		new = &groupchat_stub_funcs; +		new = &irc_channel_im_chat_funcs;  	else  		return SET_INVALID; @@ -388,48 +389,3 @@ static const struct irc_channel_funcs control_channel_funcs = {  	control_channel_init,  	control_channel_free,  }; - -/* Groupchat stub: Only handles /INVITE at least for now. */ -static gboolean groupchat_stub_invite( irc_channel_t *ic, irc_user_t *iu ) -{ -	bee_user_t *bu = iu->bu; -	 -	if( iu->bu->ic->acc->prpl->chat_with ) -	{ -		ic->flags |= IRC_CHANNEL_CHAT_PICKME; -		iu->bu->ic->acc->prpl->chat_with( bu->ic, bu->handle ); -		ic->flags &= ~IRC_CHANNEL_CHAT_PICKME; -		return TRUE; -	} -	else -	{ -		irc_send_num( ic->irc, 482, "%s :IM protocol does not support room invitations", ic->name ); -		return FALSE; -	} -} - -static gboolean groupchat_stub_join( irc_channel_t *ic ) -{ -	struct irc_groupchat_stub *igs = ic->data; -	 -	if( igs && igs->acc->ic && igs->acc->prpl->chat_join ) -	{ -		ic->flags |= IRC_CHANNEL_CHAT_PICKME; -		igs->acc->prpl->chat_join( igs->acc->ic, igs->room, ic->irc->user->nick, NULL ); -		ic->flags &= ~IRC_CHANNEL_CHAT_PICKME; -		return FALSE; -	} -	else -	{ -		irc_send_num( ic->irc, 403, "%s :Can't join channel, account offline?", ic->name ); -		return FALSE; -	} -} - -static const struct irc_channel_funcs groupchat_stub_funcs = { -	NULL, -	groupchat_stub_join, -	NULL, -	NULL, -	groupchat_stub_invite, -}; diff --git a/irc_commands.c b/irc_commands.c index 24be35e3..ccfc2171 100644 --- a/irc_commands.c +++ b/irc_commands.c @@ -398,9 +398,7 @@ static void irc_cmd_invite( irc_t *irc, char **cmd )  		return;  	} -	if( ic->f->invite ) -		ic->f->invite( ic, iu ); -	else +	if( !ic->f->invite || !ic->f->invite( ic, iu ) )  		irc_send_num( irc, 482, "%s :Can't invite people here", cmd[2] );  } @@ -317,7 +317,7 @@ static const struct irc_user_funcs irc_user_im_funcs = {  /* IM->IRC: Groupchats */ -static const struct irc_channel_funcs irc_channel_im_chat_funcs; +const struct irc_channel_funcs irc_channel_im_chat_funcs;  static gboolean bee_irc_chat_new( bee_t *bee, struct groupchat *c )  { @@ -340,7 +340,7 @@ static gboolean bee_irc_chat_new( bee_t *bee, struct groupchat *c )  	if( l == NULL ) for( i = 0; i <= 999; i ++ )  	{  		char name[16]; -		sprintf( name, "&chat_%03d", i ); +		sprintf( name, "#chat_%03d", i );  		if( ( ic = irc_channel_new( irc, name ) ) )  			break;  	} @@ -350,7 +350,6 @@ static gboolean bee_irc_chat_new( bee_t *bee, struct groupchat *c )  	c->ui_data = ic;  	ic->data = c; -	ic->f = &irc_channel_im_chat_funcs;  	topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title );  	irc_channel_set_topic( ic, topic, irc->root ); @@ -366,7 +365,10 @@ static gboolean bee_irc_chat_free( bee_t *bee, struct groupchat *c )  	if( ic->flags & IRC_CHANNEL_JOINED )  		irc_channel_printf( ic, "Cleaning up channel, bye!" ); -	irc_channel_free( ic ); +	/* irc_channel_free( ic ); */ +	 +	irc_channel_del_user( ic, ic->irc->user ); +	ic->data = NULL;  	return TRUE;  } @@ -467,33 +469,70 @@ static gboolean bee_irc_channel_chat_privmsg( irc_channel_t *ic, const char *msg  {  	struct groupchat *c = ic->data; +	if( c == NULL ) +		return FALSE; +	  	bee_chat_msg( ic->irc->b, c, msg, 0 );  	return TRUE; +} + +static gboolean bee_irc_channel_chat_join( irc_channel_t *ic ) +{ +	char *acc_s, *room; +	account_t *acc; +	if( strcmp( set_getstr( &ic->set, "chat_type" ), "room" ) != 0 ) +		return TRUE; +	 +	if( ( acc_s = set_getstr( &ic->set, "account" ) ) && +	    ( room = set_getstr( &ic->set, "room" ) ) && +	    ( acc = account_get( ic->irc->b, acc_s ) ) && +	    acc->ic && acc->prpl->chat_join ) +	{ +		char *nick; +		 +		if( !( nick = set_getstr( &ic->set, "nick" ) ) ) +			nick = ic->irc->user->nick; +		 +		ic->flags |= IRC_CHANNEL_CHAT_PICKME; +		acc->prpl->chat_join( acc->ic, room, nick, NULL ); +		ic->flags &= ~IRC_CHANNEL_CHAT_PICKME; +		 +		return FALSE; +	} +	else +	{ +		irc_send_num( ic->irc, 403, "%s :Can't join channel, account offline?", ic->name ); +		return FALSE; +	}  }  static gboolean bee_irc_channel_chat_part( irc_channel_t *ic, const char *msg )  {  	struct groupchat *c = ic->data; -	if( c->ic->acc->prpl->chat_leave ) +	if( c && c->ic->acc->prpl->chat_leave )  		c->ic->acc->prpl->chat_leave( c );  	return TRUE; -	  }  static gboolean bee_irc_channel_chat_topic( irc_channel_t *ic, const char *new )  {  	struct groupchat *c = ic->data; -	char *topic = g_strdup( new ); /* TODO: Need more const goodness here, sigh */ +	 +	if( c == NULL ) +		return FALSE;  	if( c->ic->acc->prpl->chat_topic == NULL )  		irc_send_num( ic->irc, 482, "%s :IM network does not support channel topics", ic->name );  	else  	{ +		/* TODO: Need more const goodness here, sigh */ +		char *topic = g_strdup( new );  		c->ic->acc->prpl->chat_topic( c, topic ); +		g_free( topic );  		return TRUE;  	} @@ -503,23 +542,82 @@ static gboolean bee_irc_channel_chat_topic( irc_channel_t *ic, const char *new )  static gboolean bee_irc_channel_chat_invite( irc_channel_t *ic, irc_user_t *iu )  {  	struct groupchat *c = ic->data; +	bee_user_t *bu = iu->bu; +	 +	if( bu == NULL ) +		return FALSE; -	if( iu->bu->ic != c->ic ) -		irc_send_num( ic->irc, 482, "%s :Can't mix different IM networks in one groupchat", ic->name ); -	else if( c->ic->acc->prpl->chat_invite ) -		c->ic->acc->prpl->chat_invite( c, iu->bu->handle, NULL ); +	if( c ) +	{ +		if( iu->bu->ic != c->ic ) +			irc_send_num( ic->irc, 482, "%s :Can't mix different IM networks in one groupchat", ic->name ); +		else if( c->ic->acc->prpl->chat_invite ) +			c->ic->acc->prpl->chat_invite( c, iu->bu->handle, NULL ); +		else +			irc_send_num( ic->irc, 482, "%s :IM protocol does not support room invitations", ic->name ); +	} +	else if( bu->ic->acc->prpl->chat_with && +	         strcmp( set_getstr( &ic->set, "chat_type" ), "groupchat" ) == 0 ) +	{ +		ic->flags |= IRC_CHANNEL_CHAT_PICKME; +		iu->bu->ic->acc->prpl->chat_with( bu->ic, bu->handle ); +		ic->flags &= ~IRC_CHANNEL_CHAT_PICKME; +	}  	else +	{  		irc_send_num( ic->irc, 482, "%s :IM protocol does not support room invitations", ic->name ); +	}  	return TRUE;  } -static const struct irc_channel_funcs irc_channel_im_chat_funcs = { +static char *set_eval_room_account( set_t *set, char *value ); + +static gboolean bee_irc_channel_init( irc_channel_t *ic ) +{ +	set_add( &ic->set, "account", NULL, set_eval_room_account, ic ); +	set_add( &ic->set, "chat_type", "groupchat", NULL, ic ); +	set_add( &ic->set, "nick", NULL, NULL, ic ); +	set_add( &ic->set, "room", NULL, NULL, ic ); +	 +	return TRUE; +} + +static char *set_eval_room_account( set_t *set, char *value ) +{ +	struct irc_channel *ic = set->data; +	account_t *acc; +	 +	if( !( acc = account_get( ic->irc->b, value ) ) ) +		return SET_INVALID; +	else if( !acc->prpl->chat_join ) +	{ +		irc_usermsg( ic->irc, "Named chatrooms not supported on that account." ); +		return SET_INVALID; +	} +	 +	return g_strdup_printf( "%s(%s)", acc->prpl->name, acc->user ); +} + +static gboolean bee_irc_channel_free( irc_channel_t *ic ) +{ +	set_del( &ic->set, "account" ); +	set_del( &ic->set, "chat_type" ); +	set_del( &ic->set, "nick" ); +	set_del( &ic->set, "room" ); +	 +	return TRUE; +} + +const struct irc_channel_funcs irc_channel_im_chat_funcs = {  	bee_irc_channel_chat_privmsg, -	NULL, /* join */ +	bee_irc_channel_chat_join,  	bee_irc_channel_chat_part,  	bee_irc_channel_chat_topic,  	bee_irc_channel_chat_invite, + +	bee_irc_channel_init, +	bee_irc_channel_free,  }; diff --git a/root_commands.c b/root_commands.c index cf1c169c..7c54e272 100644 --- a/root_commands.c +++ b/root_commands.c @@ -979,6 +979,11 @@ static void cmd_chat( irc_t *irc, char **cmd )  			irc_usermsg( irc, "Invalid account" );  			return;  		} +		else if( !acc->prpl->chat_join ) +		{ +			irc_usermsg( irc, "Named chatrooms not supported on that account." ); +			return; +		}  		if( cmd[4] == NULL )  		{ @@ -998,13 +1003,19 @@ static void cmd_chat( irc_t *irc, char **cmd )  			channel = s;  		} -		if( ( ic = irc_channel_new( irc, channel ) ) ) +		if( ( ic = irc_channel_new( irc, channel ) ) && +		    set_setstr( &ic->set, "chat_type", "room" ) && +		    set_setstr( &ic->set, "account", cmd[2] ) && +		    set_setstr( &ic->set, "room", cmd[3] ) ) +		{ +			irc_usermsg( irc, "Chatroom successfully added." ); +		} +		else  		{ -			struct irc_groupchat_stub *igs; +			if( ic ) +				irc_channel_free( ic ); -			ic->data = igs = g_new0( struct irc_groupchat_stub, 1 ); -			igs->acc = acc; -			igs->room = g_strdup( cmd[3] ); +			irc_usermsg( irc, "Could not add chatroom." );  		}  	}  	/* | 
