weechat-xmpp/connection.c

198 lines
5.9 KiB
C
Raw Normal View History

2021-06-26 14:17:00 +00:00
// This Source Code Form is subject to the terms of the Mozilla Public
// License, version 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <stdlib.h>
#include <string.h>
#include <strophe.h>
#include <weechat/weechat-plugin.h>
2021-06-28 01:17:02 +00:00
#include "plugin.h"
#include "config.h"
2021-06-30 08:54:59 +00:00
#include "account.h"
2021-07-01 22:08:12 +00:00
#include "user.h"
2021-06-30 08:54:59 +00:00
#include "channel.h"
2021-06-28 01:17:02 +00:00
#include "connection.h"
2021-06-26 14:17:00 +00:00
2021-06-30 06:26:06 +00:00
void connection__init()
2021-06-26 14:17:00 +00:00
{
xmpp_initialize();
2021-06-27 22:51:05 +00:00
}
2021-06-26 14:17:00 +00:00
2021-06-28 01:00:49 +00:00
int version_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
{
xmpp_stanza_t *reply, *query, *name, *version, *text;
const char *ns;
2021-06-30 08:54:59 +00:00
struct t_account *account = (struct t_account *)userdata;
const char *weechat_name = "weechat";
const char *weechat_version = weechat_info_get("version", NULL);
2021-06-28 01:00:49 +00:00
weechat_printf(NULL, "Received version request from %s", xmpp_stanza_get_from(stanza));
reply = xmpp_stanza_reply(stanza);
xmpp_stanza_set_type(reply, "result");
2021-06-30 08:54:59 +00:00
query = xmpp_stanza_new(account->context);
2021-06-28 01:00:49 +00:00
xmpp_stanza_set_name(query, "query");
ns = xmpp_stanza_get_ns(xmpp_stanza_get_children(stanza));
if (ns) {
xmpp_stanza_set_ns(query, ns);
}
2021-06-30 08:54:59 +00:00
name = xmpp_stanza_new(account->context);
2021-06-28 01:00:49 +00:00
xmpp_stanza_set_name(name, "name");
xmpp_stanza_add_child(query, name);
xmpp_stanza_release(name);
2021-06-30 08:54:59 +00:00
text = xmpp_stanza_new(account->context);
xmpp_stanza_set_text(text, weechat_name);
2021-06-28 01:00:49 +00:00
xmpp_stanza_add_child(name, text);
xmpp_stanza_release(text);
2021-06-30 08:54:59 +00:00
version = xmpp_stanza_new(account->context);
2021-06-28 01:00:49 +00:00
xmpp_stanza_set_name(version, "version");
2021-06-30 08:54:59 +00:00
xmpp_stanza_add_child(query, weechat_version);
2021-06-28 01:00:49 +00:00
xmpp_stanza_release(version);
2021-06-30 08:54:59 +00:00
text = xmpp_stanza_new(account->context);
xmpp_stanza_set_text(text, version);
2021-06-28 01:00:49 +00:00
xmpp_stanza_add_child(version, text);
xmpp_stanza_release(text);
xmpp_stanza_add_child(reply, query);
xmpp_stanza_release(query);
xmpp_send(conn, reply);
xmpp_stanza_release(reply);
2021-06-30 08:54:59 +00:00
if (version)
free (version);
2021-06-28 01:00:49 +00:00
return 1;
}
int message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
{
2021-06-30 08:54:59 +00:00
struct t_account *account = (struct t_account *)userdata;
2021-06-30 22:31:20 +00:00
xmpp_stanza_t *body, *reply, *to;
const char *type, *from, *from_bare;
2021-06-28 01:00:49 +00:00
char *intext, *replytext;
body = xmpp_stanza_get_child_by_name(stanza, "body");
if (body == NULL)
return 1;
type = xmpp_stanza_get_type(stanza);
if (type != NULL && strcmp(type, "error") == 0)
return 1;
2021-06-30 08:54:59 +00:00
from = xmpp_stanza_get_from(stanza);
2021-07-01 21:08:50 +00:00
if (from == NULL)
return 1;
2021-06-30 22:31:20 +00:00
from_bare = xmpp_jid_bare(account->context, from);
to = xmpp_stanza_get_to(stanza);
2021-06-28 01:00:49 +00:00
intext = xmpp_stanza_get_text(body);
2021-07-01 21:08:50 +00:00
if (intext == NULL)
intext = strdup("");
2021-06-28 01:00:49 +00:00
2021-06-30 22:31:20 +00:00
struct t_channel *channel = channel__search(account, from_bare);
2021-06-30 08:54:59 +00:00
if (!channel)
2021-06-30 22:31:20 +00:00
channel = channel__new(account, CHANNEL_TYPE_PM, from_bare, from_bare);
2021-06-30 08:54:59 +00:00
2021-07-01 20:37:43 +00:00
if (weechat_strcasecmp(type, "groupchat") == 0)
{
from = weechat_strcasecmp(channel->name,
xmpp_jid_bare(account->context,
from)) == 0
? xmpp_jid_resource(account->context, from)
: from;
}
2021-07-01 02:07:18 +00:00
if (strcmp(to, channel->id) == 0)
2021-07-01 22:08:12 +00:00
weechat_printf(channel->buffer, "%s[to %s]: %s",
user__as_prefix_raw(account->context, from),
to, intext);
2021-07-01 21:08:50 +00:00
else if (weechat_string_match(intext, "/me *", 0))
2021-07-01 22:08:12 +00:00
weechat_printf(channel->buffer, "%s%s %s",
weechat_prefix("action"), from, intext+4);
2021-07-01 02:07:18 +00:00
else
2021-07-01 22:08:12 +00:00
weechat_printf(channel->buffer, "%s%s",
user__as_prefix_raw(account->context, from),
intext);
2021-06-28 01:00:49 +00:00
2021-06-30 08:54:59 +00:00
xmpp_free(account->context, intext);
2021-06-28 01:00:49 +00:00
return 1;
}
2021-06-30 06:26:06 +00:00
void connection__handler(xmpp_conn_t *conn, xmpp_conn_event_t status,
2021-06-30 08:54:59 +00:00
int error, xmpp_stream_error_t *stream_error,
void *userdata)
2021-06-27 22:51:05 +00:00
{
2021-06-30 08:54:59 +00:00
struct t_account *account = (struct t_account *)userdata;
2021-06-28 01:00:49 +00:00
(void)error;
(void)stream_error;
if (status == XMPP_CONN_CONNECT) {
xmpp_stanza_t *pres;
2021-07-01 02:07:18 +00:00
//weechat_printf(account->buffer, "DEBUG: connected");
2021-06-28 01:00:49 +00:00
xmpp_handler_add(conn, version_handler, "jabber:iq:version", "iq", NULL,
2021-06-30 08:54:59 +00:00
account);
xmpp_handler_add(conn, message_handler, NULL, "message", NULL, account);
2021-06-28 01:00:49 +00:00
/* Send initial <presence/> so that we appear online to contacts */
2021-06-30 08:54:59 +00:00
pres = xmpp_presence_new(account->context);
2021-06-28 01:00:49 +00:00
xmpp_send(conn, pres);
xmpp_stanza_release(pres);
} else {
2021-07-01 02:07:18 +00:00
//weechat_printf(account->buffer, "DEBUG: disconnected");
2021-06-30 08:54:59 +00:00
//xmpp_stop(account->context);
2021-06-28 01:00:49 +00:00
}
2021-06-26 14:17:00 +00:00
}
2021-06-30 08:54:59 +00:00
int connection__connect(struct t_account *account, xmpp_conn_t **connection,
const char* jid, const char* password, int tls)
2021-06-26 14:17:00 +00:00
{
2021-06-30 08:54:59 +00:00
*connection = xmpp_conn_new(account->context);
2021-06-30 06:26:06 +00:00
xmpp_conn_set_jid(*connection, jid);
xmpp_conn_set_pass(*connection, password);
2021-06-26 14:17:00 +00:00
2021-06-30 06:26:06 +00:00
auto flags = xmpp_conn_get_flags(*connection);
switch (tls)
{
case 0:
flags |= XMPP_CONN_FLAG_DISABLE_TLS;
break;
case 1:
break;
case 2:
flags |= XMPP_CONN_FLAG_TRUST_TLS;
break;
default:
break;
}
xmpp_conn_set_flags(*connection, flags);
2021-06-26 14:17:00 +00:00
2021-06-30 08:54:59 +00:00
if (xmpp_connect_client(*connection, NULL, 0, &connection__handler, account)
2021-06-30 06:26:06 +00:00
!= XMPP_EOK)
{
weechat_printf(
NULL,
_("%s%s: error connecting to %s"),
weechat_prefix("error"), WEECHAT_XMPP_PLUGIN_NAME,
jid);
return 0;
}
2021-06-26 14:17:00 +00:00
2021-06-30 06:26:06 +00:00
return 1;
2021-06-28 01:00:49 +00:00
}
2021-06-30 06:26:06 +00:00
void connection__process(xmpp_ctx_t *context, xmpp_conn_t *connection,
const unsigned long timeout)
2021-06-28 01:00:49 +00:00
{
2021-06-30 06:26:06 +00:00
if (connection)
2021-06-28 01:00:49 +00:00
{
2021-06-30 06:26:06 +00:00
xmpp_run_once(context ? context : xmpp_conn_get_context(connection),
timeout);
2021-06-28 01:00:49 +00:00
}
2021-06-26 14:17:00 +00:00
}