aboutsummaryrefslogtreecommitdiffstats
path: root/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'protocols')
-rw-r--r--protocols/jabber/conference.c18
-rw-r--r--protocols/jabber/jabber.h1
-rw-r--r--protocols/jabber/s5bytestream.c6
-rw-r--r--protocols/oscar/rxhandlers.c10
-rw-r--r--protocols/purple/purple.c116
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");