diff options
-rw-r--r-- | bitlbee.h | 1 | ||||
-rw-r--r-- | debian/changelog | 11 | ||||
-rw-r--r-- | debian/control | 16 | ||||
-rwxr-xr-x | debian/rules | 2 | ||||
-rw-r--r-- | doc/user-guide/commands.xml | 12 | ||||
-rw-r--r-- | protocols/bee.h | 10 | ||||
-rw-r--r-- | protocols/bee_chat.c | 5 | ||||
-rw-r--r-- | protocols/nogaim.h | 8 | ||||
-rw-r--r-- | protocols/purple/bpurple.h | 7 | ||||
-rw-r--r-- | protocols/purple/purple.c | 124 | ||||
-rw-r--r-- | root_commands.c | 80 |
11 files changed, 259 insertions, 17 deletions
@@ -172,6 +172,7 @@ void root_command_string(irc_t *irc, char *command); void root_command(irc_t *irc, char *command[]); gboolean root_command_add(const char *command, int params, void (*func)(irc_t *, char **args), int flags); gboolean cmd_identify_finish(gpointer data, gint fd, b_input_condition cond); +void cmd_chat_list_finish(struct im_connection *ic); gboolean bitlbee_shutdown(gpointer data, gint fd, b_input_condition cond); char *set_eval_root_nick(set_t *set, char *new_nick); diff --git a/debian/changelog b/debian/changelog index 8e423588..e40fefdc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,17 @@ -bitlbee (3.4.2-1) UNRELEASED; urgency=medium +bitlbee (3.4.2-1) unstable; urgency=medium + [ Jelmer Vernooij ] * Make the build reproducible by not encoding ARCH / CPU defines in the binary. * Fix Vcs-* control headers after migration to Git. + * Don't start synopsis with an article. + * Bump standards version to 3.9.8 (no changes). + * Use dh_prep rather than deprecated 'dh_clean -k'. - -- Jelmer Vernooij <jelmer@debian.org> Sun, 15 May 2016 17:15:13 +0000 + [ Wilmer van der Gaast ] + * New upstream release. + + -- Wilmer van der Gaast <wilmer@gaast.net> Sun, 12 Jun 2016 22:31:18 +0100 bitlbee (3.4.1-1) unstable; urgency=medium diff --git a/debian/control b/debian/control index d5283d6e..9da8ce9d 100644 --- a/debian/control +++ b/debian/control @@ -2,8 +2,8 @@ Source: bitlbee Section: net Priority: optional Maintainer: Wilmer van der Gaast <wilmer@gaast.net> -Uploaders: Jelmer Vernooij <jelmer@debian.org> -Standards-Version: 3.9.5 +Uploaders: Jelmer Vernooij <jelmer@debian.org> +Standards-Version: 3.9.8 Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls28-dev | libgnutls-dev | gnutls-dev, po-debconf, libpurple-dev, libotr5-dev, debhelper (>= 6.0.7~) Homepage: http://www.bitlbee.org/ Vcs-Git: https://github.com/bitlbee/bitlbee @@ -14,7 +14,7 @@ Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends}, debianutils (>= 1.16), bitlbee-common (= ${source:Version}) Conflicts: bitlbee-libpurple Replaces: bitlbee-libpurple -Description: An IRC to other chat networks gateway (default version) +Description: IRC to other chat networks gateway (default version) This program can be used as an IRC server which forwards everything you say to people on other chat networks: Jabber (which includes Google Talk and Facebook Chat), ICQ, AIM, MSN, Yahoo! and Twitter/Identica/Status.net. @@ -24,7 +24,7 @@ Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends}, debianutils (>= 1.16), bitlbee-common (= ${source:Version}) Conflicts: bitlbee Replaces: bitlbee -Description: An IRC to other chat networks gateway (using libpurple) +Description: IRC to other chat networks gateway (using libpurple) This program can be used as an IRC server which forwards everything you say to people on other chat networks: Jabber (which includes Google Talk and Facebook Chat), ICQ, AIM, MSN, Yahoo! and Twitter/Identica/Status.net. @@ -40,7 +40,7 @@ Package: bitlbee-common Architecture: all Depends: ${misc:Depends}, net-tools, adduser Replaces: bitlbee -Description: An IRC to other chat networks gateway (common files/docs) +Description: IRC to other chat networks gateway (common files/docs) This program can be used as an IRC server which forwards everything you say to people on other chat networks: Jabber (which includes Google Talk and Facebook Chat), ICQ, AIM, MSN, Yahoo! and Twitter/Identica/Status.net. @@ -51,7 +51,7 @@ Description: An IRC to other chat networks gateway (common files/docs) Package: bitlbee-dev Architecture: all Depends: ${misc:Depends}, bitlbee (>= ${source:Version}) | bitlbee-libpurple (>= ${source:Version}), bitlbee (<< ${source:Version}.1~) | bitlbee-libpurple (<< ${source:Version}.1~), bitlbee-common (= ${source:Version}) -Description: An IRC to other chat networks gateway (dev files) +Description: IRC to other chat networks gateway (dev files) This program can be used as an IRC server which forwards everything you say to people on other chat networks: Jabber (which includes Google Talk and Facebook Chat), ICQ, AIM, MSN, Yahoo! and Twitter/Identica/Status.net. @@ -61,7 +61,7 @@ Description: An IRC to other chat networks gateway (dev files) Package: bitlbee-plugin-otr Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends}, bitlbee (= ${binary:Version}) | bitlbee-libpurple (= ${binary:Version}), bitlbee-common (= ${source:Version}) -Description: An IRC to other chat networks gateway (OTR plugin) +Description: IRC to other chat networks gateway (OTR plugin) This program can be used as an IRC server which forwards everything you say to people on other chat networks: Jabber (which includes Google Talk and Facebook Chat), ICQ, AIM, MSN, Yahoo! and Twitter/Identica/Status.net. @@ -73,7 +73,7 @@ Package: bitlbee-plugin-skype Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends}, bitlbee (= ${binary:Version}) | bitlbee-libpurple (= ${binary:Version}), bitlbee-common (= ${source:Version}) Recommends: skyped -Description: An IRC to other chat networks gateway (Skype plugin) +Description: IRC to other chat networks gateway (Skype plugin) This program can be used as an IRC server which forwards everything you say to people on other chat networks: Jabber (which includes Google Talk and Facebook Chat), ICQ, AIM, MSN, Yahoo! and Twitter/Identica/Status.net. diff --git a/debian/rules b/debian/rules index e0ffb898..febb1922 100755 --- a/debian/rules +++ b/debian/rules @@ -71,7 +71,7 @@ clean: install: build dh_testdir dh_testroot - dh_clean -k + dh_prep dh_installdirs $(MAKE) -C debian/build-native install-bin DESTDIR=`pwd`/debian/bitlbee diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml index 56beba54..53979b13 100644 --- a/doc/user-guide/commands.xml +++ b/doc/user-guide/commands.xml @@ -263,7 +263,7 @@ </description> <bitlbee-command name="add"> - <syntax>chat add <account id> <room> [<channel>]</syntax> + <syntax>chat add <account id> <room|!index> [<channel>]</syntax> <description> <para> @@ -281,6 +281,16 @@ </bitlbee-command> + <bitlbee-command name="list"> + <syntax>chat list <account id> [<server>]</syntax> + + <description> + <para> + List existing chatrooms provided by an account. BitlBee needs this to propogate an internal list of chats. The existing chat can then be added with <emphasis>chat add</emphasis>. + </para> + </description> + </bitlbee-command> + <bitlbee-command name="with"> <syntax>chat with <nickname></syntax> diff --git a/protocols/bee.h b/protocols/bee.h index d22e4d85..8e665ac8 100644 --- a/protocols/bee.h +++ b/protocols/bee.h @@ -83,6 +83,14 @@ typedef struct bee_user { void *data; /* Can be used by the IM module. */ } bee_user_t; +typedef struct bee_chat_info { + char *title; + char *topic; + + /* If less than zero, the user count is ignored when displaying */ + int userc; +} bee_chat_info_t; + /* This one's mostly used so save space and make it easier (cheaper) to compare groups of contacts, etc. */ typedef struct bee_group { @@ -184,4 +192,6 @@ G_MODULE_EXPORT int bee_chat_msg(bee_t *bee, struct groupchat *c, const char *ms 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); +G_MODULE_EXPORT void bee_chat_list_finish(struct im_connection *ic); + #endif /* __BEE_H__ */ diff --git a/protocols/bee_chat.c b/protocols/bee_chat.c index 2fcb0396..76ed7f85 100644 --- a/protocols/bee_chat.c +++ b/protocols/bee_chat.c @@ -273,3 +273,8 @@ void imcb_chat_invite(struct im_connection *ic, const char *name, const char *wh ic->bee->ui->chat_invite(ic->bee, bu, name, msg); } } + +void bee_chat_list_finish(struct im_connection *ic) +{ + cmd_chat_list_finish(ic); +} diff --git a/protocols/nogaim.h b/protocols/nogaim.h index e5569313..b2ae2cae 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -95,6 +95,7 @@ struct im_connection { bee_t *bee; GSList *groupchats; + GSList *chatlist; }; struct groupchat { @@ -262,6 +263,13 @@ struct prpl { /* If null, equivalent to handle_cmp( ic->acc->user, who ) */ gboolean (* handle_is_self) (struct im_connection *, const char *who); + /* This sets/updates the im_connection->chatlist field with a + * bee_chat_info_t GSList. This function should ensure the + * bee_chat_list_finish() function gets called at some point + * after the chat list is completely updated. + */ + void (*chat_list) (struct im_connection *, const char *server); + /* Some placeholders so eventually older plugins may cooperate with newer BitlBees. */ void *resv1; void *resv2; diff --git a/protocols/purple/bpurple.h b/protocols/purple/bpurple.h index 39677b86..c7b3a59c 100644 --- a/protocols/purple/bpurple.h +++ b/protocols/purple/bpurple.h @@ -14,4 +14,11 @@ struct purple_data guint next_request_id; }; +struct purple_roomlist_data +{ + GSList *chats; + gint topic; + gint userc; +}; + #endif /* !BPURPLE_H */ diff --git a/protocols/purple/purple.c b/protocols/purple/purple.c index 6ea2d7d8..bee45607 100644 --- a/protocols/purple/purple.c +++ b/protocols/purple/purple.c @@ -353,6 +353,21 @@ static void purple_login(account_t *acc) } } +static void purple_chatlist_free(struct im_connection *ic) +{ + bee_chat_info_t *ci; + GSList *l = ic->chatlist; + + while (l) { + ci = l->data; + l = g_slist_delete_link(l, l); + + g_free(ci->title); + g_free(ci->topic); + g_free(ci); + } +} + static void purple_logout(struct im_connection *ic) { struct purple_data *pd = ic->proto_data; @@ -368,6 +383,7 @@ static void purple_logout(struct im_connection *ic) purple_account_set_enabled(pd->account, "BitlBee", FALSE); purple_connections = g_slist_remove(purple_connections, ic); purple_accounts_remove(pd->account); + purple_chatlist_free(ic); g_hash_table_destroy(pd->input_requests); g_free(pd); } @@ -731,6 +747,13 @@ struct groupchat *purple_chat_join(struct im_connection *ic, const char *room, c return imcb_chat_new(ic, room); } +void purple_chat_list(struct im_connection *ic, const char *server) +{ + struct purple_data *pd = ic->proto_data; + + purple_roomlist_get_list(pd->account->gc); +} + void purple_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *handle); static void purple_ui_init(); @@ -1266,6 +1289,105 @@ static PurplePrivacyUiOps bee_privacy_uiops = prplcb_privacy_deny_removed, /* deny_removed */ }; +static void prplcb_roomlist_create(PurpleRoomlist *list) +{ + struct purple_roomlist_data *rld; + + list->ui_data = rld = g_new0(struct purple_roomlist_data, 1); + rld->topic = -1; + rld->userc = -1; +} + +static void prplcb_roomlist_set_fields(PurpleRoomlist *list, GList *fields) +{ + GList *l; + guint i; + PurpleRoomlistField *field; + struct purple_roomlist_data *rld = list->ui_data; + + for (i = 0, l = fields; l; i++, l = l->next) { + field = l->data; + + if ((g_strcasecmp(field->name, "description") == 0) || + (g_strcasecmp(field->name, "topic") == 0)) { + if (field->type == PURPLE_ROOMLIST_FIELD_STRING) { + rld->topic = i; + } + } else if (g_strcasecmp(field->name, "users") == 0) { + if (field->type == PURPLE_ROOMLIST_FIELD_INT) { + rld->userc = i; + } + } + } +} + +static void prplcb_roomlist_add_room(PurpleRoomlist *list, PurpleRoomlistRoom *room) +{ + bee_chat_info_t *ci; + const char *title; + const char *topic; + GList *fields; + gpointer data; + struct purple_roomlist_data *rld = list->ui_data; + + fields = purple_roomlist_room_get_fields(room); + title = purple_roomlist_room_get_name(room); + + if (rld->topic >= 0) { + topic = g_list_nth_data(fields, rld->topic); + } else { + topic = NULL; + } + + ci = g_new(bee_chat_info_t, 1); + ci->title = g_strdup(title); + ci->topic = g_strdup(topic); + rld->chats = g_slist_prepend(rld->chats, ci); + + if (rld->userc >= 0) { + data = g_list_nth_data(fields, rld->userc); + ci->userc = GPOINTER_TO_INT(data); + } else { + ci->userc = -1; + } +} + +static void prplcb_roomlist_in_progress(PurpleRoomlist *list, gboolean in_progress) +{ + struct im_connection *ic; + struct purple_roomlist_data *rld = list->ui_data; + + if (in_progress) { + return; + } + + ic = purple_ic_by_pa(list->account); + purple_chatlist_free(ic); + + ic->chatlist = g_slist_reverse(rld->chats); + rld->chats = NULL; + + bee_chat_list_finish(ic); + purple_roomlist_unref(list); +} + +static void prplcb_roomlist_destroy(PurpleRoomlist *list) +{ + /* bee_chat_list_finish() frees rld->chats */ + g_free(list->ui_data); + list->ui_data = NULL; +} + +static PurpleRoomlistUiOps bee_roomlist_uiops = +{ + NULL, /* show_with_account */ + prplcb_roomlist_create, /* create */ + prplcb_roomlist_set_fields, /* set_fields */ + prplcb_roomlist_add_room, /* add_room */ + prplcb_roomlist_in_progress, /* in_progress */ + prplcb_roomlist_destroy, /* destroy */ +}; + static void prplcb_debug_print(PurpleDebugLevel level, const char *category, const char *arg_s) { fprintf(stderr, "DEBUG %s: %s", category, arg_s); @@ -1430,6 +1552,7 @@ static void purple_ui_init() purple_conversations_set_ui_ops(&bee_conv_uiops); purple_request_set_ui_ops(&bee_request_uiops); purple_privacy_set_ui_ops(&bee_privacy_uiops); + purple_roomlist_set_ui_ops(&bee_roomlist_uiops); purple_notify_set_ui_ops(&bee_notify_uiops); purple_accounts_set_ui_ops(&bee_account_uiops); purple_xfers_set_ui_ops(&bee_xfer_uiops); @@ -1517,6 +1640,7 @@ void purple_initmodule() funcs.chat_kick = purple_chat_kick; funcs.chat_leave = purple_chat_leave; funcs.chat_join = purple_chat_join; + funcs.chat_list = purple_chat_list; funcs.transfer_request = purple_transfer_request; help = g_string_new("BitlBee libpurple module supports the following IM protocols:\n"); diff --git a/root_commands.c b/root_commands.c index 9acc30f0..86133244 100644 --- a/root_commands.c +++ b/root_commands.c @@ -1217,8 +1217,10 @@ static void cmd_chat(irc_t *irc, char **cmd) account_t *acc; if (g_strcasecmp(cmd[1], "add") == 0) { - char *channel, *s; + bee_chat_info_t *ci; + char *channel, *room, *s; struct irc_channel *ic; + guint i; MIN_ARGS(3); @@ -1230,8 +1232,22 @@ static void cmd_chat(irc_t *irc, char **cmd) return; } + if (cmd[3][0] == '!') { + i = g_ascii_strtoull(cmd[3] + 1, NULL, 10); + ci = g_slist_nth_data(acc->ic->chatlist, i - 1); + + if (ci == NULL) { + irc_rootmsg(irc, "Invalid chatroom index"); + return; + } + + room = ci->title; + } else { + room = cmd[3]; + } + if (cmd[4] == NULL) { - channel = g_strdup(cmd[3]); + channel = g_strdup(room); if ((s = strchr(channel, '@'))) { *s = 0; } @@ -1251,7 +1267,7 @@ static void cmd_chat(irc_t *irc, char **cmd) set_setstr(&ic->set, "type", "chat") && set_setstr(&ic->set, "chat_type", "room") && set_setstr(&ic->set, "account", cmd[2]) && - set_setstr(&ic->set, "room", cmd[3])) { + set_setstr(&ic->set, "room", room)) { irc_rootmsg(irc, "Chatroom successfully added."); } else { if (ic) { @@ -1261,6 +1277,18 @@ static void cmd_chat(irc_t *irc, char **cmd) irc_rootmsg(irc, "Could not add chatroom."); } g_free(channel); + } else if (g_strcasecmp(cmd[1], "list") == 0) { + MIN_ARGS(2); + + if (!(acc = account_get(irc->b, cmd[2]))) { + irc_rootmsg(irc, "Invalid account"); + return; + } else if (!acc->prpl->chat_list) { + irc_rootmsg(irc, "Existing chatrooms not supported on that account."); + return; + } + + acc->prpl->chat_list(acc->ic, cmd[3]); } else if (g_strcasecmp(cmd[1], "with") == 0) { irc_user_t *iu; @@ -1275,8 +1303,7 @@ static void cmd_chat(irc_t *irc, char **cmd) } else { irc_rootmsg(irc, "Can't open a groupchat with %s.", cmd[2]); } - } else if (g_strcasecmp(cmd[1], "list") == 0 || - g_strcasecmp(cmd[1], "set") == 0 || + } else if (g_strcasecmp(cmd[1], "set") == 0 || g_strcasecmp(cmd[1], "del") == 0) { irc_rootmsg(irc, "Warning: The \002chat\002 command was mostly replaced with the \002channel\002 command."); @@ -1288,6 +1315,49 @@ static void cmd_chat(irc_t *irc, char **cmd) } } +void cmd_chat_list_finish(struct im_connection *ic) +{ + account_t *acc = ic->acc; + bee_chat_info_t *ci; + char *hformat, *iformat, *topic; + GSList *l; + GString *userc; + guint i = 0; + irc_t *irc = ic->bee->ui_data; + + if (ic->chatlist == NULL) { + irc_rootmsg(irc, "No existing chatrooms"); + return; + } + + if (strchr(irc->umode, 'b') != NULL) { + hformat = "%s\t%s\t%s\t%s"; + iformat = "%u\t%s\t%s\t%s"; + } else { + hformat = "%s %-20s %s %s"; + iformat = "%5u %-20.20s %5s %s"; + } + + irc_rootmsg(irc, hformat, "Index", "Title", "Users", "Topic"); + userc = g_string_new(NULL); + + for (l = ic->chatlist; l; l = l->next) { + ci = l->data; + topic = ci->topic ? ci->topic : ""; + + if (ci->userc >= 0) { + g_string_printf(userc, "%d", ci->userc); + } else { + g_string_assign(userc, "-"); + } + + irc_rootmsg(irc, iformat, ++i, ci->title, userc->str, topic); + } + + irc_rootmsg(irc, "%u %s chatrooms", i, acc->tag); + g_string_free(userc, TRUE); +} + static void cmd_group(irc_t *irc, char **cmd) { GSList *l; |