aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Halden <marius.h@lden.org>2016-12-27 14:13:51 +0100
committerMarius Halden <marius.h@lden.org>2016-12-27 14:13:51 +0100
commitd35affbcea87f453fb20c4bb545a10b668eae81b (patch)
treea6856cc15f6ba10c79d737a61e2773cba12bf558
parent184c46d3507a0ff9fc68a4409f690add96cd183d (diff)
parent9cdcef077ed523966f508a3721944a16425734cb (diff)
Merge branch 'master' into patched-master
-rw-r--r--debian/bitlbee-common.config8
-rw-r--r--debian/bitlbee-common.postinst4
-rw-r--r--debian/control2
-rw-r--r--doc/user-guide/commands.xml6
-rw-r--r--lib/ftutil.c2
-rw-r--r--nick.c2
-rw-r--r--otr.c2
-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
-rw-r--r--root_commands.c4
-rw-r--r--set.c2
-rw-r--r--storage.c2
15 files changed, 148 insertions, 37 deletions
diff --git a/debian/bitlbee-common.config b/debian/bitlbee-common.config
index c2437b54..927f646f 100644
--- a/debian/bitlbee-common.config
+++ b/debian/bitlbee-common.config
@@ -12,13 +12,7 @@ if [ -n "$BITLBEE_PORT" ]; then
else
db_get bitlbee/serveport
if [ "$RET" = "stillhavetoask" ]; then
- listens=$(netstat -ltn | awk '{print $4}')
- for port in 6667 6666 6668 6669; do
- if [ $(expr "$listens " : ".*:$port\s") = "0" ]; then
- break
- fi
- done
- db_set bitlbee/serveport $port;
+ db_set bitlbee/serveport 6667;
fi
fi
diff --git a/debian/bitlbee-common.postinst b/debian/bitlbee-common.postinst
index e0e371d8..477bdee4 100644
--- a/debian/bitlbee-common.postinst
+++ b/debian/bitlbee-common.postinst
@@ -70,10 +70,10 @@ fi
## If we're upgrading, we'll probably skip this next part
if [ -d $CONFDIR ] && chown -R bitlbee: $CONFDIR; then
echo 'BitlBee (probably) already installed, skipping user/configdir installation'
- exit 0
+else
+ adduser --system --group --disabled-login --disabled-password --home /var/lib/bitlbee/ bitlbee
fi
-adduser --system --group --disabled-login --disabled-password --home /var/lib/bitlbee/ bitlbee
chmod 700 /var/lib/bitlbee/
## Can't do this in packaging phase: Don't know the UID yet. Access to
diff --git a/debian/control b/debian/control
index d83f089e..9dac2ef8 100644
--- a/debian/control
+++ b/debian/control
@@ -38,7 +38,7 @@ Description: IRC to other chat networks gateway (using libpurple)
Package: bitlbee-common
Architecture: all
-Depends: ${misc:Depends}, net-tools, adduser
+Depends: ${misc:Depends}, adduser
Replaces: bitlbee
Description: IRC to other chat networks gateway (common files/docs)
This program can be used as an IRC server which forwards everything you
diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml
index 7190f024..91e02ff2 100644
--- a/doc/user-guide/commands.xml
+++ b/doc/user-guide/commands.xml
@@ -276,7 +276,11 @@
<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>, using the number in the index column after a "!" as a shortcut.
+ List existing named chatrooms provided by an account. Chats from this list can be referenced from <emphasis>chat add</emphasis> by using the number in the index column after a "!" as a shortcut.
+ </para>
+
+ <para>
+ The server parameter is optional and currently only used by jabber.
</para>
</description>
diff --git a/lib/ftutil.c b/lib/ftutil.c
index 7606890f..3c79ba1f 100644
--- a/lib/ftutil.c
+++ b/lib/ftutil.c
@@ -41,7 +41,7 @@ int ft_listen(struct sockaddr_storage *saddr_ptr, char *host, char *port, int co
int fd, gret, saddrlen;
struct addrinfo hints, *rp;
socklen_t ssize = sizeof(struct sockaddr_storage);
- struct sockaddr_storage saddrs, *saddr = &saddrs;
+ struct sockaddr_storage saddrs = {0}, *saddr = &saddrs;
static char errmsg[1024];
char *ftlisten = global.conf->ft_listen;
diff --git a/nick.c b/nick.c
index f782aea2..68cdabd3 100644
--- a/nick.c
+++ b/nick.c
@@ -292,7 +292,7 @@ void nick_del(bee_user_t *bu)
void nick_strip(irc_t *irc, char *nick)
{
int len = 0;
- gboolean nick_underscores = set_getbool(&irc->b->set, "nick_underscores");
+ gboolean nick_underscores = irc ? set_getbool(&irc->b->set, "nick_underscores") : FALSE;
if (irc && (irc->status & IRC_UTF8_NICKS)) {
gunichar c;
diff --git a/otr.c b/otr.c
index d2c1a2f2..2a2385ce 100644
--- a/otr.c
+++ b/otr.c
@@ -1513,7 +1513,7 @@ struct im_connection *check_imc(void *opdata, const char *accountname,
break;
}
}
- assert(l != NULL); /* a match should always be found */
+ g_return_val_if_fail(l, NULL);
if (!l) {
return NULL;
}
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");
diff --git a/root_commands.c b/root_commands.c
index edc17855..9ffd3818 100644
--- a/root_commands.c
+++ b/root_commands.c
@@ -1425,9 +1425,7 @@ static void cmd_chat(irc_t *irc, char **cmd)
}
} 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.");
- cmd_channel(irc, cmd);
+ irc_rootmsg(irc, "Unknown command: chat %s. Did you mean \002channel %s\002?", cmd[1], cmd[1]);
} else {
irc_rootmsg(irc,
"Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat",
diff --git a/set.c b/set.c
index 8727209f..ff2470b6 100644
--- a/set.c
+++ b/set.c
@@ -166,7 +166,7 @@ int set_setstr(set_t **head, const char *key, char *value)
/* If there's a default setting and it's equal to what we're trying to
set, stick with s->value = NULL. Otherwise, remember the setting. */
- if (!s->def || (strcmp(nv, s->def) != 0)) {
+ if (!s->def || (g_strcmp0(nv, s->def) != 0)) {
s->value = g_strdup(nv);
}
diff --git a/storage.c b/storage.c
index f1ea32a2..9e16c9e2 100644
--- a/storage.c
+++ b/storage.c
@@ -107,7 +107,7 @@ GList *storage_init(const char *primary, char **migrate)
register_storage_backend(&storage_xml);
storage = storage_init_single(primary);
- if (storage == NULL && storage->save == NULL) {
+ if (storage == NULL || storage->save == NULL) {
return NULL;
}