Browse Source

xmpp: add ability to connect and disconnect

master
eta 9 months ago
parent
commit
f188141f22
  1. 202
      src/plugins/xmpp/xmpp.c

202
src/plugins/xmpp/xmpp.c

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
* along with WeeChat. If not, see <https://www.gnu.org/licenses/>.
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -29,8 +30,13 @@ @@ -29,8 +30,13 @@
#include "../weechat-plugin.h"
#include "xmpp.h"
/* Interval at which to call the libstrophe event loop */
const long EVENT_LOOP_INTERVAL = 200;
struct t_weechat_plugin *weechat_xmpp_plugin = NULL;
struct t_config_option *opt_jid = NULL;
struct t_config_option *opt_password = NULL;
xmpp_ctx_t *xmpp_ctx = NULL;
xmpp_conn_t *xmpp_conn = NULL;
WEECHAT_PLUGIN_NAME(XMPP_PLUGIN_NAME);
WEECHAT_PLUGIN_DESCRIPTION(N_("Cursed XMPP plugin"));
@ -62,10 +68,159 @@ void strophe_log_handler(void *userdata, xmpp_log_level_t level, const char *are @@ -62,10 +68,159 @@ void strophe_log_handler(void *userdata, xmpp_log_level_t level, const char *are
if (level >= XMPP_LEVEL_WARN) {
prefix = weechat_prefix("error");
}
weechat_printf(NULL, "%sxmpp %s: %s", prefix, area, msg);
weechat_printf(NULL, "%slibstrophe %s: %s", prefix, area, msg);
}
const xmpp_log_t *xmpp_logger = {&strophe_log_handler, NULL};
static const xmpp_log_t xmpp_logger = {&strophe_log_handler, NULL};
int
xmpp_finish () {
if (xmpp_conn) {
xmpp_conn_t *old_conn = xmpp_conn;
xmpp_conn = NULL;
xmpp_conn_release(old_conn);
}
return WEECHAT_RC_OK;
}
const char* stringify_error_type (xmpp_error_type_t err) {
if (!err) {
return "(null)";
}
switch (err) {
case XMPP_SE_BAD_FORMAT:
return "bad-format";
case XMPP_SE_BAD_NS_PREFIX:
return "bad-namespace-prefix";
case XMPP_SE_CONFLICT:
return "conflict";
case XMPP_SE_CONN_TIMEOUT:
return "connection-timeout";
case XMPP_SE_HOST_GONE:
return "host-gone";
case XMPP_SE_HOST_UNKNOWN:
return "host-unknown";
case XMPP_SE_IMPROPER_ADDR:
return "improper-addressing";
case XMPP_SE_INTERNAL_SERVER_ERROR:
return "internal-server-error";
case XMPP_SE_INVALID_FROM:
return "invalid-from";
case XMPP_SE_INVALID_ID:
return "invalid-id";
case XMPP_SE_INVALID_NS:
return "invalid-namespace";
case XMPP_SE_INVALID_XML:
return "invalid-xml";
case XMPP_SE_NOT_AUTHORIZED:
return "not-authorized";
case XMPP_SE_POLICY_VIOLATION:
return "policy-violation";
case XMPP_SE_REMOTE_CONN_FAILED:
return "remote-connection-failed";
case XMPP_SE_RESOURCE_CONSTRAINT:
return "resource-constraint";
case XMPP_SE_RESTRICTED_XML:
return "restricted-xml";
case XMPP_SE_SEE_OTHER_HOST:
return "see-other-host";
case XMPP_SE_SYSTEM_SHUTDOWN:
return "system-shutdown";
case XMPP_SE_UNDEFINED_CONDITION:
return "undefined-condition";
case XMPP_SE_UNSUPPORTED_ENCODING:
return "unsupported-encoding";
case XMPP_SE_UNSUPPORTED_STANZA_TYPE:
return "unsupported-stanza-type";
case XMPP_SE_UNSUPPORTED_VERSION:
return "unsupported-version";
case XMPP_SE_XML_NOT_WELL_FORMED:
return "xml-not-well-formed";
default:
return "internal-server-error";
}
}
void
xmpp_conn_cb (xmpp_conn_t *conn, const xmpp_conn_event_t event, const int error, xmpp_stream_error_t *stream_error, void *userdata) {
switch (event) {
case XMPP_CONN_CONNECT:
weechat_printf(NULL, "xmpp: connected to server");
break;
case XMPP_CONN_RAW_CONNECT:
weechat_printf(NULL, "xmpp: raw stream established");
break;
case XMPP_CONN_DISCONNECT:
case XMPP_CONN_FAIL:
if (error) {
char *error_text = strerror(error);
weechat_printf(NULL, "%sxmpp: connection error: %s", weechat_prefix("error"), error_text);
}
else if (stream_error) {
char* error_text = NULL;
char* error_ty = stringify_error_type(stream_error->type);
if (stream_error->text) {
asprintf(&error_text, "%s (%s)", stream_error->text, error_ty);
}
else {
error_text = error_ty;
}
weechat_printf(NULL, "%sxmpp: connection error: %s", weechat_prefix("error"), error_text);
}
weechat_printf(NULL, "%sxmpp: disconnected from server", weechat_prefix("error"));
xmpp_finish();
break;
}
}
int
xmpp_connect () {
if (xmpp_conn) {
weechat_printf(NULL, "%sxmpp: disconnecting existing connection");
xmpp_finish();
}
xmpp_conn = xmpp_conn_new(xmpp_ctx);
if (!xmpp_conn) {
weechat_printf(NULL, "%sxmpp: creating connection failed", weechat_prefix("error"));
return WEECHAT_RC_ERROR;
}
const char *jid = weechat_config_string(opt_jid);
if (!jid || jid == "") {
weechat_printf(NULL, "%sxmpp: no JID configured", weechat_prefix("error"));
return WEECHAT_RC_ERROR;
}
const char *password = weechat_config_string(opt_password);
if (!password || password == "") {
weechat_printf(NULL, "%sxmpp: no password configured", weechat_prefix("error"));
return WEECHAT_RC_ERROR;
}
xmpp_conn_set_jid(xmpp_conn, jid);
xmpp_conn_set_pass(xmpp_conn, password);
weechat_printf(NULL, "xmpp: connecting to server");
xmpp_connect_client(xmpp_conn, NULL, 0, &xmpp_conn_cb, NULL);
return WEECHAT_RC_OK;
}
int
xmpp_command_connect (const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol) {
return xmpp_connect();
}
int
xmpp_command_disconnect (const void *pointer, void *data,
struct t_gui_buffer *buffer, int argc,
char **argv, char **argv_eol) {
xmpp_finish();
return WEECHAT_RC_OK;
}
int
xmpp_command_eval (const void *pointer, void *data,
@ -112,10 +267,43 @@ void lisp_load(char *file) @@ -112,10 +267,43 @@ void lisp_load(char *file)
}
*/
void weechat_config_init() {
struct t_config_file *file = weechat_config_new("xmpp", NULL, NULL, NULL);
struct t_config_section *sect_account =
weechat_config_new_section(file, "account", 0, 0,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL);
opt_jid =
weechat_config_new_option(file, sect_account, "jid", "string",
"The Jabber ID (JID) of the XMPP account to use.",
NULL, 0, 0, NULL, NULL,
1, NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL);
opt_password =
weechat_config_new_option(file, sect_account, "password", "string",
"The password to authenticate to the XMPP server with.",
NULL, 0, 0, NULL, NULL,
1, NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL);
}
int on_event_loop_timer(const void *xmpp_ctx_ptr, void *data, int remaining_calls) {
xmpp_ctx_t *xmpp_ctx = (xmpp_ctx_t *) xmpp_ctx_ptr;
xmpp_run_once(xmpp_ctx, 0);
return WEECHAT_RC_OK;
}
int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char **argv) {
weechat_plugin = plugin;
weechat_config_init();
xmpp_initialize();
xmpp_ctx = xmpp_ctx_new(NULL, xmpp_logger);
xmpp_ctx = xmpp_ctx_new(NULL, &xmpp_logger);
if (!xmpp_ctx) {
weechat_printf(NULL, "%sxmpp: xmpp_ctx_new failed", weechat_prefix("error"));
return WEECHAT_RC_ERROR;
@ -131,6 +319,14 @@ int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char **argv) @@ -131,6 +319,14 @@ int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char **argv)
cl_boot(0, fake_argv);
weechat_hook_command("cleval", "Evaluate a Common Lisp form", "[form]", "form: a Common Lisp form", "", &xmpp_command_eval, NULL, NULL);
weechat_hook_command("xconnect", "Connect to the XMPP server", "", "", "", &xmpp_command_connect, NULL, NULL);
weechat_hook_command("xdisconnect", "Disconnect from the XMPP server", "", "", "", &xmpp_command_disconnect, NULL, NULL);
struct t_hook *hook = weechat_hook_timer(EVENT_LOOP_INTERVAL, 0, 0, &on_event_loop_timer, xmpp_ctx, NULL);
if (!hook) {
weechat_printf(NULL, "%sxmpp: event loop hook failed", weechat_prefix("error"));
return WEECHAT_RC_ERROR;
}
weechat_printf(NULL, "xmpp: plugin loaded");
return WEECHAT_RC_OK;

Loading…
Cancel
Save