aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjgeboski <jgeboski@gmail.com>2015-01-28 18:40:47 -0500
committerjgeboski <jgeboski@gmail.com>2015-01-29 14:24:17 -0500
commit7821ee89fef7bae353b06fc4c23f3ab23093e5cc (patch)
treef406d02909d53bd8023a3653018ce9d95e38aea6
parent7b8238d0c9f409deaa15147bc76fc77101cb52c3 (diff)
irc_commands: implemented KICK support
With similar commands being supported, such as INVITE, the KICK command should be supported as well. The key motivation behind supporting KICK is having for having a way to remove users from group chats. As of now, there is no way for a bitlbee user to remove a user from a group chat. With no current KICK implementation, it made using this command a prime candidate for the UI side of this implementation. In addition, the KICK command has been supported in the control channel as well. This is to keep the INVITE/KICK pair consistent.
-rw-r--r--irc.h1
-rw-r--r--irc_channel.c19
-rw-r--r--irc_commands.c25
-rw-r--r--irc_im.c18
-rw-r--r--protocols/nogaim.h5
5 files changed, 68 insertions, 0 deletions
diff --git a/irc.h b/irc.h
index 8bb27427..64a3e808 100644
--- a/irc.h
+++ b/irc.h
@@ -187,6 +187,7 @@ struct irc_channel_funcs
gboolean (*part)( irc_channel_t *ic, const char *msg );
gboolean (*topic)( irc_channel_t *ic, const char *new_topic );
gboolean (*invite)( irc_channel_t *ic, irc_user_t *iu );
+ void (*kick)( irc_channel_t *ic, irc_user_t *iu, const char *msg );
gboolean (*_init)( irc_channel_t *ic );
gboolean (*_free)( irc_channel_t *ic );
diff --git a/irc_channel.c b/irc_channel.c
index b8763ce3..4fe0fad4 100644
--- a/irc_channel.c
+++ b/irc_channel.c
@@ -625,6 +625,24 @@ static gboolean control_channel_invite( irc_channel_t *ic, irc_user_t *iu )
return TRUE;
}
+static void control_channel_kick( irc_channel_t *ic, irc_user_t *iu, const char *msg )
+{
+ struct irc_control_channel *icc = ic->data;
+ bee_user_t *bu = iu->bu;
+
+ if( bu == NULL )
+ return;
+
+ if( icc->type != IRC_CC_TYPE_GROUP )
+ {
+ irc_send_num( ic->irc, 482, "%s :Kicks are only possible to fill_by=group channels", ic->name );
+ return;
+ }
+
+ bu->ic->acc->prpl->remove_buddy( bu->ic, bu->handle,
+ icc->group ? icc->group->name : NULL );
+}
+
static char *set_eval_by_account( set_t *set, char *value );
static char *set_eval_fill_by( set_t *set, char *value );
static char *set_eval_by_group( set_t *set, char *value );
@@ -843,6 +861,7 @@ static const struct irc_channel_funcs control_channel_funcs = {
NULL,
NULL,
control_channel_invite,
+ control_channel_kick,
control_channel_init,
control_channel_free,
diff --git a/irc_commands.c b/irc_commands.c
index 6be756ff..f438193c 100644
--- a/irc_commands.c
+++ b/irc_commands.c
@@ -499,6 +499,30 @@ static void irc_cmd_invite( irc_t *irc, char **cmd )
irc_send_num( irc, 341, "%s %s", iu->nick, ic->name );
}
+static void irc_cmd_kick( irc_t *irc, char **cmd )
+{
+ irc_channel_t *ic;
+ irc_user_t *iu;
+
+ if( ( iu = irc_user_by_name( irc, cmd[2] ) ) == NULL )
+ {
+ irc_send_num( irc, 401, "%s :No such nick", cmd[2] );
+ return;
+ }
+ else if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL )
+ {
+ irc_send_num( irc, 403, "%s :No such channel", cmd[1] );
+ return;
+ }
+ else if( !ic->f->kick )
+ {
+ irc_send_num( irc, 482, "%s :Can't kick people here", cmd[1] );
+ return;
+ }
+
+ ic->f->kick( ic, iu, cmd[3] ? cmd[3] : NULL );
+}
+
static void irc_cmd_userhost( irc_t *irc, char **cmd )
{
int i;
@@ -745,6 +769,7 @@ static const command_t irc_commands[] = {
{ "ison", 1, irc_cmd_ison, IRC_CMD_LOGGED_IN },
{ "watch", 1, irc_cmd_watch, IRC_CMD_LOGGED_IN },
{ "invite", 2, irc_cmd_invite, IRC_CMD_LOGGED_IN },
+ { "kick", 2, irc_cmd_kick, IRC_CMD_LOGGED_IN },
{ "topic", 1, irc_cmd_topic, IRC_CMD_LOGGED_IN },
{ "oper", 2, irc_cmd_oper, IRC_CMD_LOGGED_IN },
{ "list", 0, irc_cmd_list, IRC_CMD_LOGGED_IN },
diff --git a/irc_im.c b/irc_im.c
index 9f4fd83c..810d82be 100644
--- a/irc_im.c
+++ b/irc_im.c
@@ -971,6 +971,23 @@ static gboolean bee_irc_channel_chat_invite( irc_channel_t *ic, irc_user_t *iu )
return TRUE;
}
+static void bee_irc_channel_chat_kick( irc_channel_t *ic, irc_user_t *iu, const char *msg )
+{
+ struct groupchat *c = ic->data;
+ bee_user_t *bu = iu->bu;
+
+ if( ( c == NULL ) || ( bu == NULL ) )
+ return;
+
+ if( !c->ic->acc->prpl->chat_kick )
+ {
+ irc_send_num( ic->irc, 482, "%s :IM protocol does not support room kicking", ic->name );
+ return;
+ }
+
+ c->ic->acc->prpl->chat_kick( c, iu->bu->handle, msg );
+}
+
static char *set_eval_room_account( set_t *set, char *value );
static char *set_eval_chat_type( set_t *set, char *value );
@@ -1055,6 +1072,7 @@ const struct irc_channel_funcs irc_channel_im_chat_funcs = {
bee_irc_channel_chat_part,
bee_irc_channel_chat_topic,
bee_irc_channel_chat_invite,
+ bee_irc_channel_chat_kick,
bee_irc_channel_init,
bee_irc_channel_free,
diff --git a/protocols/nogaim.h b/protocols/nogaim.h
index d1711cde..a726b174 100644
--- a/protocols/nogaim.h
+++ b/protocols/nogaim.h
@@ -212,6 +212,11 @@ struct prpl {
* - 'message' is a handle to invite
*/
void (* chat_invite) (struct groupchat *, char *who, char *message);
+ /* This is called when the user uses the /kick IRC command.
+ * - 'who' is a handle to kick
+ * - 'message' is a kick message or NULL
+ */
+ void (* chat_kick) (struct groupchat *, char *who, const char *message);
/* This is called when the user uses the /part IRC command in a group
* chat. You just should tell the user about it, nothing more. */
void (* chat_leave) (struct groupchat *);