diff --git a/Makefile b/Makefile index 94bb22e..dcc399f 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ INSTALL ?= /usr/bin/install SRCS=xmpp.c \ xmpp-config.c \ + xmpp-connection.c \ OLDSRCS=slack.c \ slack-api.c \ diff --git a/slack-api.c b/slack-api.c deleted file mode 100644 index fc86b4a..0000000 --- a/slack-api.c +++ /dev/null @@ -1,291 +0,0 @@ -// 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 -#include -#include -#include - -#include "weechat-plugin.h" -#include "slack.h" -#include "slack-workspace.h" -#include "slack-api.h" -#include "api/slack-api-hello.h" -#include "api/slack-api-error.h" -#include "api/slack-api-message.h" -#include "api/slack-api-user-typing.h" - -struct stringcase -{ - const char *string; - int (*func)(struct t_slack_workspace *workspace, - json_object *message); -}; - -static struct stringcase cases[] = -{ { "hello", &slack_api_hello } -, { "error", &slack_api_error } -, { "message", &slack_api_message } -, { "user_typing", &slack_api_user_typing } -}; - -static int stringcase_cmp(const void *p1, const void *p2) -{ - return strcasecmp(((struct stringcase*)p1)->string, ((struct stringcase*)p2)->string); -} - -void slack_api_init() -{ - size_t case_count = sizeof(cases) / sizeof(cases[0]); - qsort(cases, case_count, sizeof(struct stringcase), stringcase_cmp); - - slack_api_message_init(); -} - -static int callback_ws(struct lws* wsi, enum lws_callback_reasons reason, - void *user, void* in, size_t len) -{ - struct t_slack_workspace *workspace = (struct t_slack_workspace *)user; - - (void) wsi; - - switch (reason) - { - /* because we are protocols[0] ... */ - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - weechat_printf( - workspace->buffer, - _("%s%s: error connecting to slack: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - in ? (char *)in : "(null)"); - workspace->client_wsi = NULL; - break; - - case LWS_CALLBACK_CLIENT_ESTABLISHED: - weechat_printf( - workspace->buffer, - _("%s%s: waiting for hello..."), - weechat_prefix("network"), SLACK_PLUGIN_NAME); - break; - - /* data is never chunked */ - case LWS_CALLBACK_CLIENT_RECEIVE: - weechat_printf( - workspace->buffer, - _("%s%s: received data: %s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, - (const char *)in); - { - int data_size; - char *json_string; - json_object *response, *type; - struct t_json_chunk *new_chunk, *last_chunk, *chunk_ptr; - - new_chunk = malloc(sizeof(*new_chunk)); - new_chunk->data = malloc(((int)len) + 1); - new_chunk->data[0] = '\0'; - new_chunk->next = NULL; - - strncat(new_chunk->data, in, (int)len); - - if (workspace->json_chunks) - { - for (last_chunk = workspace->json_chunks; last_chunk->next; - last_chunk = last_chunk->next); - last_chunk->next = new_chunk; - } - else - { - workspace->json_chunks = new_chunk; - } - - data_size = 0; - for (chunk_ptr = workspace->json_chunks; chunk_ptr; chunk_ptr = chunk_ptr->next) - { - data_size += strlen(chunk_ptr->data); - } - - json_string = malloc(data_size + 1); - json_string[0] = '\0'; - - for (chunk_ptr = workspace->json_chunks; chunk_ptr; chunk_ptr = chunk_ptr->next) - { - strcat(json_string, chunk_ptr->data); - } - - response = json_tokener_parse(json_string); - if (response) - { - for (chunk_ptr = workspace->json_chunks; chunk_ptr; workspace->json_chunks = chunk_ptr) - { - chunk_ptr = chunk_ptr->next; - free(workspace->json_chunks->data); - free(workspace->json_chunks); - } - - type = json_object_object_get(response, "type"); - if (!type) - { - weechat_printf( - workspace->buffer, - _("%s%s: unexpected data received from websocket: closing"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - - slack_workspace_disconnect(workspace, 0); - - json_object_put(response); - free(json_string); - return -1; - } - - if (!slack_api_route_message(workspace, - json_object_get_string(type), response)) - { - weechat_printf( - workspace->buffer, - _("%s%s: error while handling message: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - json_string); - weechat_printf( - workspace->buffer, - _("%s%s: closing connection."), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - - slack_workspace_disconnect(workspace, 0); - - json_object_put(response); - free(json_string); - return -1; - } - - json_object_put(response); - free(json_string); - } - else - { - free(json_string); - } - } - return 0; /* don't passthru */ - - case LWS_CALLBACK_CLIENT_WRITEABLE: - weechat_printf( - workspace->buffer, - _("%s%s: websocket is writeable"), - weechat_prefix("network"), SLACK_PLUGIN_NAME); - break; - - case LWS_CALLBACK_CLOSED: - workspace->client_wsi = NULL; - workspace->disconnected = 1; - /* start reconnect timer */ - break; - - default: - break; - } - - return lws_callback_http_dummy(wsi, reason, user, in, len); -} - -static const struct lws_protocols protocols[] = { - { - "default", - callback_ws, - 0, - 0, - }, - { NULL, NULL, 0, 0 } -}; - -void slack_api_connect(struct t_slack_workspace *workspace) -{ - struct lws_context_creation_info ctxinfo; - struct lws_client_connect_info ccinfo; - const char *url_protocol, *url_path; - char path[512]; - - memset(&ctxinfo, 0, sizeof(ctxinfo)); - memset(&ccinfo, 0, sizeof(ccinfo)); - - ccinfo.port = 443; - - if (lws_parse_uri(workspace->ws_url, - &url_protocol, &ccinfo.address, - &ccinfo.port, &url_path)) - { - weechat_printf( - workspace->buffer, - _("%s%s: error connecting to slack: bad websocket uri"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return; - } - - path[0] = '/'; - strncpy(path + 1, url_path, sizeof(path) - 2); - path[sizeof(path) - 1] = '\0'; - - ccinfo.path = path; - - ctxinfo.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - ctxinfo.port = CONTEXT_PORT_NO_LISTEN; - ctxinfo.protocols = protocols; - ctxinfo.uid = -1; - ctxinfo.gid = -1; - - workspace->context = lws_create_context(&ctxinfo); - if (!workspace->context) - { - weechat_printf( - workspace->buffer, - _("%s%s: error connecting to slack: lws init failed"), - weechat_prefix("error"), SLACK_PLUGIN_NAME); - return; - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: connecting to %s://%s:%d%s"), - weechat_prefix("network"), SLACK_PLUGIN_NAME, - url_protocol, ccinfo.address, ccinfo.port, path); - } - - ccinfo.context = workspace->context; - ccinfo.ssl_connection = LCCSCF_USE_SSL; - ccinfo.host = ccinfo.address; - ccinfo.origin = ccinfo.address; - ccinfo.ietf_version_or_minus_one = -1; - ccinfo.protocol = protocols[0].name; - ccinfo.pwsi = &workspace->client_wsi; - ccinfo.userdata = workspace; - - lws_client_connect_via_info(&ccinfo); -} - -int slack_api_route_message(struct t_slack_workspace *workspace, - const char *type, json_object *message) -{ - struct stringcase key; - key.string = type; - - size_t case_count = sizeof(cases) / sizeof(cases[0]); - void *entry_ptr = bsearch(&key, cases, case_count, - sizeof(struct stringcase), stringcase_cmp); - - if (entry_ptr) - { - struct stringcase *entry = (struct stringcase *)entry_ptr; - return (*entry->func)(workspace, message); - } - else - { - weechat_printf( - workspace->buffer, - _("%s%s: got unhandled message of type: %s"), - weechat_prefix("error"), SLACK_PLUGIN_NAME, - type); - return 1; - } -} diff --git a/slack-api.h b/slack-api.h deleted file mode 100644 index 723b3b9..0000000 --- a/slack-api.h +++ /dev/null @@ -1,15 +0,0 @@ -// 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/. - -#ifndef _SLACK_API_H_ -#define _SLACK_API_H_ - -void slack_api_init(); - -void slack_api_connect(struct t_slack_workspace *workspace); - -int slack_api_route_message(struct t_slack_workspace *workspace, - const char *type, json_object *message); - -#endif /*SLACK_API_H*/ diff --git a/xmpp-connection.c b/xmpp-connection.c new file mode 100644 index 0000000..47152f1 --- /dev/null +++ b/xmpp-connection.c @@ -0,0 +1,146 @@ +// 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 +#include +#include +#include +#include + +#include "xmpp.h" +#include "xmpp-config.h" +#include "xmpp-connection.h" +//#include "api/xmpp-api-hello.h" +//#include "api/xmpp-api-error.h" +//#include "api/xmpp-api-message.h" +//#include "api/xmpp-api-user-typing.h" + +xmpp_ctx_t *xmpp_context = NULL; + +xmpp_conn_t *xmpp_connection = NULL; + +void xmpp_log_emit_weechat(void *const userdata, const xmpp_log_level_t level, const char *const area, const char *const msg) +{ + (void) userdata; + time_t date = time(NULL); + const char *timestamp = weechat_util_get_time_string(&date); + + weechat_printf( + NULL, + _("%s%s %d | %s: %s - %s"), + weechat_prefix("error"), XMPP_PLUGIN_NAME, + level, timestamp, area, msg); +} + +xmpp_log_t xmpp_logger = { + &xmpp_log_emit_weechat, + NULL +}; + +void xmpp_connection_init() +{ + + xmpp_initialize(); + xmpp_context = xmpp_ctx_new(NULL, &xmpp_logger); + xmpp_connection = xmpp_conn_new(xmpp_context); + xmpp_conn_set_jid(xmpp_connection, + weechat_config_string(xmpp_config_serverdef_jid)); + xmpp_conn_set_pass(xmpp_connection, + weechat_config_string(xmpp_config_serverdef_password)); + //size_t case_count = sizeof(cases) / sizeof(cases[0]); + //qsort(cases, case_count, sizeof(struct stringcase), stringcase_cmp); + + //xmpp_api_message_init(); +} + +void xmpp_connection_connect(xmpp_conn_t *connection) +{ + //struct lws_context_creation_info ctxinfo; + //struct lws_client_connect_info ccinfo; + //const char *url_protocol, *url_path; + //char path[512]; + + //memset(&ctxinfo, 0, sizeof(ctxinfo)); + //memset(&ccinfo, 0, sizeof(ccinfo)); + + //ccinfo.port = 443; + + //if (lws_parse_uri(workspace->ws_url, + // &url_protocol, &ccinfo.address, + // &ccinfo.port, &url_path)) + //{ + // weechat_printf( + // workspace->buffer, + // _("%s%s: error connecting to xmpp: bad websocket uri"), + // weechat_prefix("error"), XMPP_PLUGIN_NAME); + // return; + //} + + //path[0] = '/'; + //strncpy(path + 1, url_path, sizeof(path) - 2); + //path[sizeof(path) - 1] = '\0'; + + //ccinfo.path = path; + + //ctxinfo.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; + //ctxinfo.port = CONTEXT_PORT_NO_LISTEN; + //ctxinfo.protocols = protocols; + //ctxinfo.uid = -1; + //ctxinfo.gid = -1; + + //workspace->context = lws_create_context(&ctxinfo); + //if (!workspace->context) + //{ + // weechat_printf( + // workspace->buffer, + // _("%s%s: error connecting to xmpp: lws init failed"), + // weechat_prefix("error"), XMPP_PLUGIN_NAME); + // return; + //} + //else + //{ + // weechat_printf( + // workspace->buffer, + // _("%s%s: connecting to %s://%s:%d%s"), + // weechat_prefix("network"), XMPP_PLUGIN_NAME, + // url_protocol, ccinfo.address, ccinfo.port, path); + //} + + //ccinfo.context = workspace->context; + //ccinfo.ssl_connection = LCCSCF_USE_SSL; + //ccinfo.host = ccinfo.address; + //ccinfo.origin = ccinfo.address; + //ccinfo.ietf_version_or_minus_one = -1; + //ccinfo.protocol = protocols[0].name; + //ccinfo.pwsi = &workspace->client_wsi; + //ccinfo.userdata = workspace; + + //lws_client_connect_via_info(&ccinfo); +} + +int xmpp_connection_route_message(xmpp_conn_t *workspace, + const char *type, json_object *message) +{ + //struct stringcase key; + //key.string = type; + + //size_t case_count = sizeof(cases) / sizeof(cases[0]); + //void *entry_ptr = bsearch(&key, cases, case_count, + // sizeof(struct stringcase), stringcase_cmp); + + //if (entry_ptr) + //{ + // struct stringcase *entry = (struct stringcase *)entry_ptr; + // return (*entry->func)(workspace, message); + //} + //else + //{ + // weechat_printf( + // workspace->buffer, + // _("%s%s: got unhandled message of type: %s"), + // weechat_prefix("error"), XMPP_PLUGIN_NAME, + // type); + return 1; + //} +} diff --git a/xmpp-connection.h b/xmpp-connection.h new file mode 100644 index 0000000..f6e7979 --- /dev/null +++ b/xmpp-connection.h @@ -0,0 +1,19 @@ +// 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/. + +#ifndef _XMPP_CONNECTION_H_ +#define _XMPP_CONNECTION_H_ + +extern xmpp_ctx_t *xmpp_context; + +extern xmpp_conn_t *xmpp_connection; + +void xmpp_connection_init(); + +void xmpp_connection_connect(xmpp_conn_t *connection); + +int xmpp_connection_route_message(xmpp_conn_t *connection, + const char *type, json_object *message); + +#endif /*XMPP_CONNECTION_H*/ diff --git a/xmpp.c b/xmpp.c index 7e5974e..c489c66 100644 --- a/xmpp.c +++ b/xmpp.c @@ -11,9 +11,9 @@ #include "xmpp.h" #include "xmpp-config.h" +#include "xmpp-connection.h" //#include "slack-command.h" //#include "slack-workspace.h" -//#include "slack-api.h" //#include "slack-buffer.h" //#include "slack-completion.h" @@ -31,28 +31,6 @@ struct t_hook *xmpp_hook_timer = NULL; struct t_gui_bar_item *xmpp_typing_bar_item = NULL; -xmpp_ctx_t *xmpp_context = NULL; - -xmpp_conn_t *xmpp_connection = NULL; - -void xmpp_log_emit_weechat(void *const userdata, const xmpp_log_level_t level, const char *const area, const char *const msg) -{ - (void) userdata; - time_t date = time(NULL); - const char *timestamp = weechat_util_get_time_string(&date); - - weechat_printf( - NULL, - _("%s%s %d | %s: %s - %s"), - weechat_prefix("error"), XMPP_PLUGIN_NAME, - level, timestamp, area, msg); -} - -xmpp_log_t xmpp_logger = { - &xmpp_log_emit_weechat, - NULL -}; - int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[]) { (void) argc; @@ -65,18 +43,10 @@ int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[]) xmpp_config_read(); - xmpp_initialize(); - xmpp_context = xmpp_ctx_new(NULL, &xmpp_logger); - xmpp_connection = xmpp_conn_new(xmpp_context); - xmpp_conn_set_jid(xmpp_connection, - weechat_config_string(xmpp_config_serverdef_jid)); - xmpp_conn_set_pass(xmpp_connection, - weechat_config_string(xmpp_config_serverdef_password)); + xmpp_connection_init(); //xmpp_command_init(); - //xmpp_api_init(); - //xmpp_completion_init(); //xmpp_hook_timer = weechat_hook_timer(0.1 * 1000, 0, 0,