# HG changeset patch # User David Demelier # Date 1612901751 -3600 # Node ID e4fc051e2d947ee70e74154719da5c4f7925fd39 # Parent 3afd375f308bcfb898318376cca216c6a11436c8 irccd: add brand new Irccd.Hook API diff -r 3afd375f308b -r e4fc051e2d94 CHANGES.md --- a/CHANGES.md Tue Feb 09 21:34:00 2021 +0100 +++ b/CHANGES.md Tue Feb 09 21:15:51 2021 +0100 @@ -35,6 +35,7 @@ javascript API: - Brand new Irccd.Rule API to inspect and manage rules. +- Brand new Irccd.Hook API to inspect and manage hooks. irccd 3.1.1 2021-01-04 ---------------------- diff -r 3afd375f308b -r e4fc051e2d94 irccd/CMakeLists.txt --- a/irccd/CMakeLists.txt Tue Feb 09 21:34:00 2021 +0100 +++ b/irccd/CMakeLists.txt Tue Feb 09 21:15:51 2021 +0100 @@ -39,6 +39,8 @@ ${irccd_SOURCE_DIR}/jsapi-directory.h ${irccd_SOURCE_DIR}/jsapi-file.c ${irccd_SOURCE_DIR}/jsapi-file.h + ${irccd_SOURCE_DIR}/jsapi-hook.c + ${irccd_SOURCE_DIR}/jsapi-hook.h ${irccd_SOURCE_DIR}/jsapi-irccd.c ${irccd_SOURCE_DIR}/jsapi-irccd.h ${irccd_SOURCE_DIR}/jsapi-logger.c diff -r 3afd375f308b -r e4fc051e2d94 irccd/js-plugin.c --- a/irccd/js-plugin.c Tue Feb 09 21:34:00 2021 +0100 +++ b/irccd/js-plugin.c Tue Feb 09 21:15:51 2021 +0100 @@ -35,6 +35,7 @@ #include "jsapi-chrono.h" #include "jsapi-directory.h" #include "jsapi-file.h" +#include "jsapi-hook.h" #include "jsapi-irccd.h" #include "jsapi-logger.h" #include "jsapi-plugin.h" @@ -452,6 +453,7 @@ jsapi_chrono_load(js->ctx); jsapi_directory_load(js->ctx); jsapi_file_load(js->ctx); + jsapi_hook_load(js->ctx); jsapi_logger_load(js->ctx); jsapi_plugin_load(js->ctx, &js->plugin); jsapi_rule_load(js->ctx); diff -r 3afd375f308b -r e4fc051e2d94 irccd/jsapi-chrono.c --- a/irccd/jsapi-chrono.c Tue Feb 09 21:34:00 2021 +0100 +++ b/irccd/jsapi-chrono.c Tue Feb 09 21:15:51 2021 +0100 @@ -16,6 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include @@ -107,6 +108,8 @@ void jsapi_chrono_load(duk_context *ctx) { + assert(ctx); + duk_get_global_string(ctx, "Irccd"); duk_push_c_function(ctx, Chrono_constructor, 0); duk_push_object(ctx); diff -r 3afd375f308b -r e4fc051e2d94 irccd/jsapi-hook.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/irccd/jsapi-hook.c Tue Feb 09 21:15:51 2021 +0100 @@ -0,0 +1,85 @@ +/* + * jsapi-hook.c -- Irccd.Hook API + * + * Copyright (c) 2013-2021 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include "jsapi-hook.h" + +static int +Hook_add(duk_context *ctx) +{ + const char *name = duk_require_string(ctx, 0); + const char *path = duk_require_string(ctx, 1); + + if (irc_bot_hook_get(name)) + return duk_error(ctx, DUK_ERR_ERROR, "hook %s already exists", name); + + irc_bot_hook_add(irc_hook_new(name, path)); + + return 0; +} + +static int +Hook_list(duk_context *ctx) +{ + struct irc_hook *h; + size_t i = 0; + + duk_push_array(ctx); + + LIST_FOREACH(h, &irc.hooks, link) { + duk_push_object(ctx); + duk_push_string(ctx, h->name); + duk_put_prop_string(ctx, -2, "name"); + duk_push_string(ctx, h->path); + duk_put_prop_string(ctx, -2, "path"); + duk_put_prop_index(ctx, -2, i++); + } + + return 1; +} + +static int +Hook_remove(duk_context *ctx) +{ + irc_bot_hook_remove(duk_require_string(ctx, 0)); + + return 0; +} + +static const duk_function_list_entry functions[] = { + { "add", Hook_add, 2 }, + { "list", Hook_list, 0 }, + { "remove", Hook_remove, 1 }, + { NULL, NULL, 0 } +}; + +void +jsapi_hook_load(duk_context *ctx) +{ + assert(ctx); + + duk_get_global_string(ctx, "Irccd"); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, functions); + duk_put_prop_string(ctx, -2, "Hook"); + duk_pop(ctx); +} diff -r 3afd375f308b -r e4fc051e2d94 irccd/jsapi-hook.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/irccd/jsapi-hook.h Tue Feb 09 21:15:51 2021 +0100 @@ -0,0 +1,27 @@ +/* + * jsapi-hook.h -- Irccd.Hook API + * + * Copyright (c) 2013-2021 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_JSAPI_HOOK_H +#define IRCCD_JSAPI_HOOK_H + +#include + +void +jsapi_hook_load(duk_context *); + +#endif /* !IRCCD_JSAPI_HOOK_H */ diff -r 3afd375f308b -r e4fc051e2d94 irccd/jsapi-irccd.c --- a/irccd/jsapi-irccd.c Tue Feb 09 21:34:00 2021 +0100 +++ b/irccd/jsapi-irccd.c Tue Feb 09 21:15:51 2021 +0100 @@ -16,6 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include @@ -295,6 +296,8 @@ void jsapi_load(duk_context *ctx) { + assert(ctx); + /* Irccd (global object) */ duk_push_object(ctx); diff -r 3afd375f308b -r e4fc051e2d94 irccd/jsapi-logger.c --- a/irccd/jsapi-logger.c Tue Feb 09 21:34:00 2021 +0100 +++ b/irccd/jsapi-logger.c Tue Feb 09 21:15:51 2021 +0100 @@ -16,6 +16,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #include #include @@ -66,6 +68,8 @@ void jsapi_logger_load(duk_context *ctx) { + assert(ctx); + duk_get_global_string(ctx, "Irccd"); duk_push_object(ctx); duk_put_function_list(ctx, -1, functions); diff -r 3afd375f308b -r e4fc051e2d94 irccd/jsapi-plugin.c --- a/irccd/jsapi-plugin.c Tue Feb 09 21:34:00 2021 +0100 +++ b/irccd/jsapi-plugin.c Tue Feb 09 21:15:51 2021 +0100 @@ -16,6 +16,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #include #include @@ -214,6 +216,9 @@ void jsapi_plugin_load(duk_context *ctx, struct irc_plugin *p) { + assert(ctx); + assert(p); + /* Store plugin. */ duk_push_pointer(ctx, p); duk_put_global_string(ctx, SIGNATURE); @@ -247,6 +252,8 @@ struct irc_plugin * jsapi_plugin_self(duk_context *ctx) { + assert(ctx); + struct irc_plugin *p; duk_get_global_string(ctx, SIGNATURE); diff -r 3afd375f308b -r e4fc051e2d94 irccd/jsapi-rule.c --- a/irccd/jsapi-rule.c Tue Feb 09 21:34:00 2021 +0100 +++ b/irccd/jsapi-rule.c Tue Feb 09 21:15:51 2021 +0100 @@ -18,6 +18,7 @@ #include +#include #include #include @@ -153,6 +154,8 @@ void jsapi_rule_load(duk_context *ctx) { + assert(ctx); + duk_get_global_string(ctx, "Irccd"); duk_push_object(ctx); duk_put_number_list(ctx, -1, actions); diff -r 3afd375f308b -r e4fc051e2d94 irccd/jsapi-system.c --- a/irccd/jsapi-system.c Tue Feb 09 21:34:00 2021 +0100 +++ b/irccd/jsapi-system.c Tue Feb 09 21:15:51 2021 +0100 @@ -16,6 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include @@ -229,6 +230,8 @@ void jsapi_system_raise(duk_context *ctx) { + assert(ctx); + duk_get_global_string(ctx, "Irccd"); duk_get_prop_string(ctx, -1, "SystemError"); duk_remove(ctx, -2); @@ -242,6 +245,8 @@ void jsapi_system_load(duk_context *ctx) { + assert(ctx); + duk_get_global_string(ctx, "Irccd"); duk_push_object(ctx); duk_put_function_list(ctx, -1, functions); diff -r 3afd375f308b -r e4fc051e2d94 irccd/jsapi-timer.c --- a/irccd/jsapi-timer.c Tue Feb 09 21:34:00 2021 +0100 +++ b/irccd/jsapi-timer.c Tue Feb 09 21:15:51 2021 +0100 @@ -16,6 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include @@ -308,6 +309,8 @@ void jsapi_timer_load(duk_context *ctx) { + assert(ctx); + duk_get_global_string(ctx, "Irccd"); duk_push_c_function(ctx, Timer_constructor, 3); duk_put_number_list(ctx, -1, constants); diff -r 3afd375f308b -r e4fc051e2d94 irccd/jsapi-unicode.c --- a/irccd/jsapi-unicode.c Tue Feb 09 21:34:00 2021 +0100 +++ b/irccd/jsapi-unicode.c Tue Feb 09 21:15:51 2021 +0100 @@ -16,6 +16,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #include "jsapi-unicode.h" #include "unicode.h" @@ -80,6 +82,8 @@ void jsapi_unicode_load(duk_context *ctx) { + assert(ctx); + duk_get_global_string(ctx, "Irccd"); duk_push_object(ctx); duk_put_function_list(ctx, -1, functions); diff -r 3afd375f308b -r e4fc051e2d94 lib/irccd/hook.c --- a/lib/irccd/hook.c Tue Feb 09 21:34:00 2021 +0100 +++ b/lib/irccd/hook.c Tue Feb 09 21:15:51 2021 +0100 @@ -129,6 +129,9 @@ void irc_hook_invoke(struct irc_hook *h, const struct irc_event *ev) { + assert(h); + assert(ev); + char **args; pid_t child; @@ -142,6 +145,7 @@ case 0: execv(h->path, args); irc_log_warn("hook %s: %s", h->name, strerror(errno)); + exit(1); break; default: /* We wait for signal handler using SIGCHLD. */ @@ -154,5 +158,7 @@ void irc_hook_finish(struct irc_hook *h) { + assert(h); + free(h); } diff -r 3afd375f308b -r e4fc051e2d94 lib/irccd/server.c --- a/lib/irccd/server.c Tue Feb 09 21:34:00 2021 +0100 +++ b/lib/irccd/server.c Tue Feb 09 21:15:51 2021 +0100 @@ -42,6 +42,25 @@ #define DELAY 30 /* Seconds to wait before reconnecting. */ #define TIMEOUT 1800 /* Seconds before marking a server as dead. */ +static inline const char * +statename(enum irc_server_state st) +{ + switch (st) { + case IRC_SERVER_STATE_NONE: + return "none"; + case IRC_SERVER_STATE_DISCONNECTED: + return "disconnected"; + case IRC_SERVER_STATE_CONNECTING: + return "connecting"; + case IRC_SERVER_STATE_CONNECTED: + return "connected"; + case IRC_SERVER_STATE_WAITING: + return "waiting"; + default: + return "unknown"; + } +} + static inline void clear_channels(struct irc_server *s, int free) { @@ -181,10 +200,15 @@ clear_server(s); if (s->flags & IRC_SERVER_FLAGS_AUTO_RECO) { + irc_log_debug("server %s: state %s -> %s", s->name, + statename(s->state), statename(IRC_SERVER_STATE_WAITING)); irc_log_info("server %s: waiting %u seconds before reconnecting", s->name, DELAY); s->state = IRC_SERVER_STATE_WAITING; - } else + } else { + irc_log_debug("server %s: state %s -> %s", s->name, + statename(s->state), statename(IRC_SERVER_STATE_DISCONNECTED)); s->state = IRC_SERVER_STATE_DISCONNECTED; + } /* Time point when we lose signal from the server. */ s->lost_tp = time(NULL); @@ -201,6 +225,8 @@ LIST_FOREACH(ch, &s->channels, link) irc_server_join(s, ch->name, ch->password); + irc_log_debug("server %s: state %s -> %s", s->name, + statename(s->state), statename(IRC_SERVER_STATE_CONNECTED)); s->state = IRC_SERVER_STATE_CONNECTED; ev->type = IRC_EVENT_CONNECT; @@ -589,6 +615,9 @@ static void auth(struct irc_server *s) { + irc_log_debug("server %s: state %s -> %s", s->name, + statename(s->state), statename(IRC_SERVER_STATE_CONNECTED)); + s->state = IRC_SERVER_STATE_CONNECTED; if (s->ident.password[0]) @@ -645,8 +674,11 @@ if (irc_conn_connect(&s->conn) < 0) fail(s); - else + else { + irc_log_debug("server %s: state %s -> %s", s->name, + statename(s->state), statename(IRC_SERVER_STATE_CONNECTING)); s->state = IRC_SERVER_STATE_CONNECTING; + } /* * Assume the last time we received a message was now, so that @@ -661,6 +693,8 @@ { assert(s); + irc_log_debug("server %s: state %s -> %s", s->name, + statename(s->state), statename(IRC_SERVER_STATE_DISCONNECTED)); s->state = IRC_SERVER_STATE_DISCONNECTED; clear_channels(s, 0); @@ -691,8 +725,10 @@ if (difftime(time(NULL), s->last_tp) >= TIMEOUT) { irc_log_warn("server %s: no message in more than %u seconds", s->name, TIMEOUT); fail(s); - } else if (irc_conn_flush(&s->conn, pfd) < 0) + } else if (irc_conn_flush(&s->conn, pfd) < 0) { + irc_log_warn("server %s: %s", s->name, strerror(errno)); return fail(s); + } break; case IRC_SERVER_STATE_CONNECTING: /* @@ -722,6 +758,8 @@ * something else. */ if (s->state == IRC_SERVER_STATE_DISCONNECTED) { + irc_log_debug("server %s: state %s -> %s", s->name, + statename(s->state), statename(IRC_SERVER_STATE_NONE)); handle_disconnect(s, ev); s->state = IRC_SERVER_STATE_NONE; return 1;