aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--irc.h1
-rw-r--r--irc_im.c58
-rw-r--r--irc_send.c8
-rw-r--r--protocols/bee.h2
-rw-r--r--protocols/bee_chat.c8
-rw-r--r--protocols/jabber/message.c16
6 files changed, 86 insertions, 7 deletions
diff --git a/irc.h b/irc.h
index 58ca19c9..36667662 100644
--- a/irc.h
+++ b/irc.h
@@ -281,6 +281,7 @@ void irc_send_msg_f( irc_user_t *iu, const char *type, const char *dst, const ch
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 );
+void irc_send_invite( irc_user_t *iu, irc_channel_t *ic );
/* irc_user.c */
irc_user_t *irc_user_new( irc_t *irc, const char *nick );
diff --git a/irc_im.c b/irc_im.c
index 7ed2922e..6ddcb432 100644
--- a/irc_im.c
+++ b/irc_im.c
@@ -612,6 +612,63 @@ static gboolean bee_irc_chat_name_hint( bee_t *bee, struct groupchat *c, const c
return TRUE;
}
+static gboolean bee_irc_chat_invite( bee_t *bee, bee_user_t *bu, const char *name, const char *msg )
+{
+ char *channel, *s;
+ irc_t *irc = bee->ui_data;
+ irc_user_t *iu = bu->ui_data;
+ irc_channel_t *chan;
+
+ if( strchr( CTYPES, name[0] ) )
+ channel = g_strdup( name );
+ else
+ channel = g_strdup_printf( "#%s", name );
+
+ if( ( s = strchr( channel, '@' ) ) )
+ *s = '\0';
+
+ if( strlen( channel ) > MAX_NICK_LENGTH )
+ {
+ /* If the channel name is very long (like those insane GTalk
+ UUID names), try if we can use the inviter's nick. */
+ s = g_strdup_printf( "#%s", iu->nick );
+ if( irc_channel_by_name( irc, s ) == NULL )
+ {
+ g_free( channel );
+ channel = s;
+ }
+ }
+
+ if( ( chan = irc_channel_new( irc, channel ) ) &&
+ set_setstr( &chan->set, "type", "chat" ) &&
+ set_setstr( &chan->set, "chat_type", "room" ) &&
+ set_setstr( &chan->set, "account", bu->ic->acc->tag ) &&
+ set_setstr( &chan->set, "room", (char*) name ) )
+ {
+ /* I'm assuming that if the user didn't "chat add" the room
+ himself but got invited, it's temporary, so make this a
+ temporary mapping that is removed as soon as we /PART. */
+ chan->flags |= IRC_CHANNEL_TEMP;
+ }
+ else
+ {
+ irc_channel_free( chan );
+ chan = NULL;
+ }
+ g_free( channel );
+
+ irc_send_msg_f( iu, "PRIVMSG", irc->user->nick, "<< \002BitlBee\002 - Invitation to chatroom %s >>", name );
+ if( msg )
+ irc_send_msg( iu, "PRIVMSG", irc->user->nick, msg, NULL );
+ if( chan )
+ {
+ irc_send_msg_f( iu, "PRIVMSG", irc->user->nick, "To join the room, just /join %s", chan->name );
+ irc_send_invite( iu, chan );
+ }
+
+ return TRUE;
+}
+
/* IRC->IM */
static gboolean bee_irc_channel_chat_privmsg_cb( gpointer data, gint fd, b_input_condition cond );
@@ -908,6 +965,7 @@ const struct bee_ui_funcs irc_ui_funcs = {
bee_irc_chat_remove_user,
bee_irc_chat_topic,
bee_irc_chat_name_hint,
+ bee_irc_chat_invite,
bee_irc_ft_in_start,
bee_irc_ft_out_start,
diff --git a/irc_send.c b/irc_send.c
index 5f4dc350..76b54dd1 100644
--- a/irc_send.c
+++ b/irc_send.c
@@ -397,3 +397,11 @@ void irc_send_channel_user_mode_diff( irc_channel_t *ic, irc_user_t *iu,
if( *changes )
irc_write( ic->irc, ":%s MODE %s %s", from, ic->name, changes );
}
+
+void irc_send_invite( irc_user_t *iu, irc_channel_t *ic )
+{
+ irc_t *irc = iu->irc;
+
+ irc_write( iu->irc, ":%s!%s@%s INVITE %s :%s",
+ iu->nick, iu->user, iu->host, irc->user->nick, ic->name );
+}
diff --git a/protocols/bee.h b/protocols/bee.h
index 2fd3562e..b99c8de7 100644
--- a/protocols/bee.h
+++ b/protocols/bee.h
@@ -122,6 +122,7 @@ typedef struct bee_ui_funcs
gboolean (*chat_remove_user)( bee_t *bee, struct groupchat *c, bee_user_t *bu );
gboolean (*chat_topic)( bee_t *bee, struct groupchat *c, const char *new, bee_user_t *bu );
gboolean (*chat_name_hint)( bee_t *bee, struct groupchat *c, const char *name );
+ gboolean (*chat_invite)( bee_t *bee, bee_user_t *bu, const char *name, const char *msg );
struct file_transfer* (*ft_in_start)( bee_t *bee, bee_user_t *bu, const char *file_name, size_t file_size );
gboolean (*ft_out_start)( struct im_connection *ic, struct file_transfer *ft );
@@ -174,5 +175,6 @@ G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *c, const char *handl
G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *c, const char *handle, const char *reason );
G_MODULE_EXPORT int bee_chat_msg( bee_t *bee, struct groupchat *c, const char *msg, int flags );
G_MODULE_EXPORT struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const char *title );
+G_MODULE_EXPORT void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg );
#endif /* __BEE_H__ */
diff --git a/protocols/bee_chat.c b/protocols/bee_chat.c
index 3be6f189..0314cae5 100644
--- a/protocols/bee_chat.c
+++ b/protocols/bee_chat.c
@@ -232,3 +232,11 @@ struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const
return NULL;
}
+
+void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg )
+{
+ bee_user_t *bu = bee_user_by_handle( ic->bee, ic, who );
+
+ if( bu && ic->bee->ui->chat_invite )
+ ic->bee->ui->chat_invite( ic->bee, bu, name, msg );
+}
diff --git a/protocols/jabber/message.c b/protocols/jabber/message.c
index ce5017fb..6e40e521 100644
--- a/protocols/jabber/message.c
+++ b/protocols/jabber/message.c
@@ -30,7 +30,7 @@ xt_status jabber_pkt_message( struct xt_node *node, gpointer data )
char *type = xt_find_attr( node, "type" );
struct xt_node *body = xt_find_node( node->children, "body" ), *c;
struct jabber_buddy *bud = NULL;
- char *s;
+ char *s, *room = NULL, *reason = NULL;
if( !from )
return XT_HANDLED; /* Consider this packet corrupted. */
@@ -51,19 +51,19 @@ xt_status jabber_pkt_message( struct xt_node *node, gpointer data )
for( c = node->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
{
- char *ns = xt_find_attr( c, "xmlns" ), *room;
- struct xt_node *inv, *reason;
+ char *ns = xt_find_attr( c, "xmlns" );
+ struct xt_node *inv;
if( ns && strcmp( ns, XMLNS_MUC_USER ) == 0 &&
( inv = xt_find_node( c->children, "invite" ) ) )
{
+ /* This is an invitation. Set some vars which
+ will be passed to imcb_chat_invite() below. */
room = from;
if( ( from = xt_find_attr( inv, "from" ) ) == NULL )
from = room;
-
- g_string_append_printf( fullmsg, "<< \002BitlBee\002 - Invitation to chatroom %s >>\n", room );
- if( ( reason = xt_find_node( inv->children, "reason" ) ) && reason->text_len > 0 )
- g_string_append( fullmsg, reason->text );
+ if( ( inv = xt_find_node( inv->children, "reason" ) ) && inv->text_len > 0 )
+ reason = inv->text;
}
}
@@ -103,6 +103,8 @@ xt_status jabber_pkt_message( struct xt_node *node, gpointer data )
if( fullmsg->len > 0 )
imcb_buddy_msg( ic, from, fullmsg->str,
0, jabber_get_timestamp( node ) );
+ if( room )
+ imcb_chat_invite( ic, room, from, reason );
g_string_free( fullmsg, TRUE );