diff options
author | Marius Halden <marius.h@lden.org> | 2016-12-27 14:13:51 +0100 |
---|---|---|
committer | Marius Halden <marius.h@lden.org> | 2016-12-27 14:13:51 +0100 |
commit | d35affbcea87f453fb20c4bb545a10b668eae81b (patch) | |
tree | a6856cc15f6ba10c79d737a61e2773cba12bf558 /protocols | |
parent | 184c46d3507a0ff9fc68a4409f690add96cd183d (diff) | |
parent | 9cdcef077ed523966f508a3721944a16425734cb (diff) |
Merge branch 'master' into patched-master
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/jabber/conference.c | 18 | ||||
-rw-r--r-- | protocols/jabber/jabber.h | 1 | ||||
-rw-r--r-- | protocols/jabber/s5bytestream.c | 6 | ||||
-rw-r--r-- | protocols/oscar/rxhandlers.c | 10 | ||||
-rw-r--r-- | protocols/purple/purple.c | 116 |
5 files changed, 133 insertions, 18 deletions
diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c index 593e4233..75f3100c 100644 --- a/protocols/jabber/conference.c +++ b/protocols/jabber/conference.c @@ -166,6 +166,7 @@ void jabber_chat_free(struct groupchat *c) jabber_buddy_remove_bare(c->ic, jc->name); + g_free(jc->last_sent_message); g_free(jc->my_full_jid); g_free(jc->name); g_free(jc->invite); @@ -187,6 +188,9 @@ int jabber_chat_msg(struct groupchat *c, char *message, int flags) jabber_cache_add(ic, node, jabber_chat_self_message); + g_free(jc->last_sent_message); + jc->last_sent_message = g_strdup(message); + return !jabber_write_packet(ic, node); } @@ -493,10 +497,16 @@ void jabber_chat_pkt_message(struct im_connection *ic, struct jabber_buddy *bud, } else if (chat != NULL && bud == NULL && nick == NULL) { imcb_chat_log(chat, "From conference server: %s", body->text); return; - } else if (jc && jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me && - (jabber_cache_handle_packet(ic, node) == XT_ABORT)) { - /* Self message marked by this bitlbee, don't show it */ - return; + } else if (jc && jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me) { + if (jabber_cache_handle_packet(ic, node) == XT_ABORT) { + /* Self message marked by this bitlbee, don't show it */ + return; + } else if (xt_find_attr(node, "id") == NULL && + g_strcmp0(body->text, jc->last_sent_message) == 0) { + /* Some misbehaving servers (like slack) eat the ids and echo anyway. + * Try to detect those cases by comparing against the last sent message. */ + return; + } } if (bud) { diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index a09bd060..5100b7a9 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -178,6 +178,7 @@ struct jabber_chat { char *my_full_jid; /* Separate copy because of case sensitivity. */ struct jabber_buddy *me; char *invite; + char *last_sent_message; }; struct jabber_transfer { diff --git a/protocols/jabber/s5bytestream.c b/protocols/jabber/s5bytestream.c index 577840f1..9c79de8e 100644 --- a/protocols/jabber/s5bytestream.c +++ b/protocols/jabber/s5bytestream.c @@ -499,7 +499,7 @@ gboolean jabber_bs_recv_handshake(gpointer data, gint fd, b_input_condition cond } case BS_PHASE_REPLY: { - struct socks5_message socks5_reply; + struct socks5_message socks5_reply = {0}; int ret; if (!(ret = jabber_bs_peek(bt, &socks5_reply, sizeof(struct socks5_message)))) { @@ -1045,7 +1045,7 @@ gboolean jabber_bs_send_handshake(gpointer data, gint fd, b_input_condition cond unsigned char ver; unsigned char nmethods; unsigned char method; - } socks5_hello; + } socks5_hello = {0}; if (!(ret = jabber_bs_peek(bt, &socks5_hello, sizeof(socks5_hello)))) { return FALSE; @@ -1090,7 +1090,7 @@ gboolean jabber_bs_send_handshake(gpointer data, gint fd, b_input_condition cond } case BS_PHASE_REQUEST: { - struct socks5_message socks5_connect; + struct socks5_message socks5_connect = {0}; int msgsize = sizeof(struct socks5_message); int ret; diff --git a/protocols/oscar/rxhandlers.c b/protocols/oscar/rxhandlers.c index 6ff106b2..0f1bb3d7 100644 --- a/protocols/oscar/rxhandlers.c +++ b/protocols/oscar/rxhandlers.c @@ -234,14 +234,8 @@ int aim_conn_addhandler(aim_session_t *sess, aim_conn_t *conn, guint16 family, g { struct aim_rxcblist_s *newcb; - if (!conn) { - return -1; - } - - if (checkdisallowed(family, type)) { - g_assert(0); - return -1; - } + g_return_val_if_fail(conn, -1); + g_return_val_if_fail(checkdisallowed(family, type), -1); if (!(newcb = (struct aim_rxcblist_s *) g_new0(struct aim_rxcblist_s, 1))) { return -1; diff --git a/protocols/purple/purple.c b/protocols/purple/purple.c index 2515f07e..fbc5f45e 100644 --- a/protocols/purple/purple.c +++ b/protocols/purple/purple.c @@ -123,6 +123,7 @@ static gboolean purple_account_should_set_nick(account_t *acc) "prpl-hangouts", "prpl-eionrobb-funyahoo-plusplus", "prpl-icq", + "prpl-line", NULL, }; char **p; @@ -303,6 +304,11 @@ static void purple_init(account_t *acc) s = set_add(&acc->set, "gg_sync_contacts", "true", set_eval_bool, acc); } + if (g_strcmp0(prpl->info->id, "prpl-line") == 0) { + s = set_add(&acc->set, "line-auth-token", NULL, NULL, acc); + s->flags |= SET_HIDDEN; + } + /* Go through all away states to figure out if away/status messages are possible. */ pa = purple_account_new(acc->user, prpl_id); @@ -373,6 +379,11 @@ static void purple_sync_settings(account_t *acc, PurpleAccount *pa) if (pi->options & OPT_PROTO_MAIL_CHECK) { purple_account_set_check_mail(pa, set_getbool(&acc->set, "mail_notifications")); } + + if (g_strcmp0(prpl->info->id, "prpl-line") == 0) { + const char *name = "line-auth-token"; + purple_account_set_string(pa, name, set_getstr(&acc->set, name)); + } } static void purple_login(account_t *acc) @@ -776,6 +787,7 @@ struct groupchat *purple_chat_join(struct im_connection *ic, const char *room, c PurpleConversation *conv; struct groupchat *gc; GList *info, *l; + GString *missing_settings = NULL; if (!pi->chat_info || !pi->chat_info_defaults || !(info = pi->chat_info(purple_account_get_connection(pd->account)))) { @@ -801,6 +813,28 @@ struct groupchat *purple_chat_join(struct im_connection *ic, const char *room, c g_hash_table_replace(chat_hash, "password", g_strdup(password)); } else if (strcmp(pce->identifier, "passwd") == 0) { g_hash_table_replace(chat_hash, "passwd", g_strdup(password)); + } else { + char *key, *value; + + key = g_strdup_printf("purple_%s", pce->identifier); + str_reject_chars(key, " -", '_'); + + if ((value = set_getstr(sets, key))) { + /* sync from bitlbee to the prpl */ + g_hash_table_replace(chat_hash, (char *) pce->identifier, g_strdup(value)); + } else if ((value = g_hash_table_lookup(chat_hash, pce->identifier))) { + /* if the bitlbee one was empty, sync from prpl to bitlbee */ + set_setstr(sets, key, value); + } + + g_free(key); + } + + if (pce->required && !g_hash_table_lookup(chat_hash, pce->identifier)) { + if (!missing_settings) { + missing_settings = g_string_sized_new(32); + } + g_string_append_printf(missing_settings, "%s, ", pce->identifier); } g_free(pce); @@ -808,6 +842,17 @@ struct groupchat *purple_chat_join(struct im_connection *ic, const char *room, c g_list_free(info); + if (missing_settings) { + /* remove the ", " from the end */ + g_string_truncate(missing_settings, missing_settings->len - 2); + + imcb_error(ic, "Can't join %s. The following settings are required: %s", room, missing_settings->str); + + g_string_free(missing_settings, TRUE); + g_hash_table_destroy(chat_hash); + return NULL; + } + /* do this before serv_join_chat to handle cases where prplcb_conv_new is called immediately (not async) */ gc = imcb_chat_new(ic, room); @@ -843,6 +888,61 @@ void purple_chat_list(struct im_connection *ic, const char *server) } } +/* handles either prpl->chat_(add|free)_settings depending on the value of 'add' */ +static void purple_chat_update_settings(account_t *acc, set_t **head, gboolean add) +{ + PurplePlugin *prpl = purple_plugins_find_with_id((char *) acc->prpl->data); + PurplePluginProtocolInfo *pi = prpl->info->extra_info; + GList *info, *l; + + if (!pi->chat_info || !pi->chat_info_defaults) { + return; + } + + /* hack / leap of faith: pass a NULL here because we don't have a connection yet. + * i reviewed all the built-in prpls and a bunch of third-party ones and none + * of them seem to need this parameter at all, so... i hope it never crashes */ + info = pi->chat_info(NULL); + + for (l = info; l; l = l->next) { + struct proto_chat_entry *pce = l->data; + char *key; + + if (strcmp(pce->identifier, "handle") == 0 || + strcmp(pce->identifier, "password") == 0 || + strcmp(pce->identifier, "passwd") == 0) { + /* skip these, they are handled above */ + g_free(pce); + continue; + } + + key = g_strdup_printf("purple_%s", pce->identifier); + str_reject_chars(key, " -", '_'); + + if (add) { + set_add(head, key, NULL, NULL, NULL); + } else { + set_del(head, key); + } + + g_free(key); + g_free(pce); + } + + g_list_free(NULL); + g_list_free(info); +} + +static void purple_chat_add_settings(account_t *acc, set_t **head) +{ + purple_chat_update_settings(acc, head, TRUE); +} + +static void purple_chat_free_settings(account_t *acc, set_t **head) +{ + purple_chat_update_settings(acc, head, FALSE); +} + void purple_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *handle); static void purple_ui_init(); @@ -879,7 +979,8 @@ static void prplcb_conn_progress(PurpleConnection *gc, const char *text, size_t static void prplcb_conn_connected(PurpleConnection *gc) { struct im_connection *ic = purple_ic_by_gc(gc); - const char *dn; + struct purple_data *pd = ic->proto_data; + const char *dn, *token; set_t *s; imcb_connected(ic); @@ -893,6 +994,13 @@ static void prplcb_conn_connected(PurpleConnection *gc) // user list needs to be requested for Gadu-Gadu purple_gg_buddylist_import(gc); + /* more awful hacks, because clearly we didn't have enough of those */ + if ((s = set_find(&ic->acc->set, "line-auth-token")) && + (token = purple_account_get_string(pd->account, "line-auth-token", NULL))) { + g_free(s->value); + s->value = g_strdup(token); + } + ic->flags |= OPT_DOES_HTML; } @@ -1703,8 +1811,8 @@ void purple_initmodule() return; } - g_assert((int) B_EV_IO_READ == (int) PURPLE_INPUT_READ); - g_assert((int) B_EV_IO_WRITE == (int) PURPLE_INPUT_WRITE); + g_return_if_fail((int) B_EV_IO_READ == (int) PURPLE_INPUT_READ); + g_return_if_fail((int) B_EV_IO_WRITE == (int) PURPLE_INPUT_WRITE); dir = g_strdup_printf("%s/purple", global.conf->configdir); purple_util_set_user_dir(dir); @@ -1780,6 +1888,8 @@ void purple_initmodule() funcs.chat_leave = purple_chat_leave; funcs.chat_join = purple_chat_join; funcs.chat_list = purple_chat_list; + funcs.chat_add_settings = purple_chat_add_settings; + funcs.chat_free_settings = purple_chat_free_settings; funcs.transfer_request = purple_transfer_request; help = g_string_new("BitlBee libpurple module supports the following IM protocols:\n"); |