mirror of
https://github.com/Theldus/alertik.git
synced 2024-11-24 17:03:37 +01:00
Rework string manipulation & minor improvements on webhook events
This commit is contained in:
parent
db437fb6e3
commit
11079f41c1
2
Makefile
2
Makefile
@ -8,7 +8,7 @@ CFLAGS += -Wall -Wextra
|
|||||||
LDLIBS += -pthread -lcurl
|
LDLIBS += -pthread -lcurl
|
||||||
STRIP = strip
|
STRIP = strip
|
||||||
VERSION = v0.1
|
VERSION = v0.1
|
||||||
OBJS = alertik.o events.o env_events.o notifiers.o log.o syslog.o
|
OBJS = alertik.o events.o env_events.o notifiers.o log.o syslog.o str.o
|
||||||
|
|
||||||
ifeq ($(LOG_FILE),yes)
|
ifeq ($(LOG_FILE),yes)
|
||||||
CFLAGS += -DUSE_FILE_AS_LOG
|
CFLAGS += -DUSE_FILE_AS_LOG
|
||||||
|
95
env_events.c
95
env_events.c
@ -15,6 +15,7 @@
|
|||||||
#include "env_events.h"
|
#include "env_events.h"
|
||||||
#include "alertik.h"
|
#include "alertik.h"
|
||||||
#include "notifiers.h"
|
#include "notifiers.h"
|
||||||
|
#include "str.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Environment events
|
* Environment events
|
||||||
@ -105,30 +106,10 @@ get_event_idx(int ev_num, char *str, const char *const *str_list, int size)
|
|||||||
panic("String parameter (%s) invalid for %s\n", env, str);
|
panic("String parameter (%s) invalid for %s\n", env, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Appends a character to the destination buffer if there is space.
|
|
||||||
*
|
|
||||||
* @param dst Pointer to the destination buffer.
|
|
||||||
* @param dst_end End of the destination buffer.
|
|
||||||
* @param c Character to append.
|
|
||||||
*
|
|
||||||
* @return Returns 1 if the character was appended, 0 otherwise.
|
|
||||||
*/
|
|
||||||
static int append_dst(char **dst, const char *dst_end, char c) {
|
|
||||||
char *d = *dst;
|
|
||||||
if (d < dst_end) {
|
|
||||||
*d = c;
|
|
||||||
*dst = ++d;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles match replacement in the event mask message.
|
* @brief Handles match replacement in the event mask message.
|
||||||
*
|
*
|
||||||
* @param dst Pointer to the destination buffer.
|
* @param notif_message Pointer to the append buffer.
|
||||||
* @param dst_e End of the destination buffer.
|
|
||||||
* @param c_msk Pointer to the current position in the mask message.
|
* @param c_msk Pointer to the current position in the mask message.
|
||||||
* @param e_msk End of the mask message.
|
* @param e_msk End of the mask message.
|
||||||
* @param pmatch Array of regex matches.
|
* @param pmatch Array of regex matches.
|
||||||
@ -138,7 +119,7 @@ static int append_dst(char **dst, const char *dst_end, char c) {
|
|||||||
* @return Returns 1 if the replacement was handled, 0 otherwise.
|
* @return Returns 1 if the replacement was handled, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
static int handle_match_replacement(
|
static int handle_match_replacement(
|
||||||
char **dst, char *dst_e,
|
struct str_ab *notif_message,
|
||||||
const char **c_msk, const char *e_msk,
|
const char **c_msk, const char *e_msk,
|
||||||
regmatch_t *pmatch,
|
regmatch_t *pmatch,
|
||||||
struct env_event *env,
|
struct env_event *env,
|
||||||
@ -172,10 +153,8 @@ static int handle_match_replacement(
|
|||||||
off = pmatch[match].rm_so;
|
off = pmatch[match].rm_so;
|
||||||
len = pmatch[match].rm_eo - off;
|
len = pmatch[match].rm_eo - off;
|
||||||
|
|
||||||
for (regoff_t i = 0; i < len; i++) {
|
if (ab_append_str(notif_message, log_ev->msg + off, len) < 0)
|
||||||
if ( !append_dst(dst, dst_e, log_ev->msg[off + i]) )
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -192,22 +171,19 @@ static int handle_match_replacement(
|
|||||||
*
|
*
|
||||||
* @return Returns the pointer to the end of the masked message.
|
* @return Returns the pointer to the end of the masked message.
|
||||||
*/
|
*/
|
||||||
static char*
|
static int
|
||||||
create_masked_message(struct env_event *env, regmatch_t *pmatch,
|
create_masked_message(struct env_event *env, regmatch_t *pmatch,
|
||||||
struct log_event *log_ev, char *buf, size_t buf_size)
|
struct log_event *log_ev, struct str_ab *notif_message)
|
||||||
{
|
{
|
||||||
char *dst, *dst_e;
|
|
||||||
const char *c_msk, *e_msk;
|
const char *c_msk, *e_msk;
|
||||||
|
|
||||||
c_msk = env->ev_mask_msg;
|
c_msk = env->ev_mask_msg;
|
||||||
e_msk = c_msk + strlen(c_msk);
|
e_msk = c_msk + strlen(c_msk);
|
||||||
dst = buf;
|
|
||||||
dst_e = dst + buf_size;
|
|
||||||
|
|
||||||
for (; *c_msk != '\0'; c_msk++)
|
for (; *c_msk != '\0'; c_msk++)
|
||||||
{
|
{
|
||||||
if (*c_msk != '@') {
|
if (*c_msk != '@') {
|
||||||
if (!append_dst(&dst, dst_e, *c_msk))
|
if (ab_append_chr(notif_message, *c_msk) < 0)
|
||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -220,7 +196,7 @@ create_masked_message(struct env_event *env, regmatch_t *pmatch,
|
|||||||
* If next is also '@',escape it.
|
* If next is also '@',escape it.
|
||||||
*/
|
*/
|
||||||
if (c_msk[1] == '@') {
|
if (c_msk[1] == '@') {
|
||||||
if (!append_dst(&dst, dst_e, *c_msk))
|
if (ab_append_chr(notif_message, *c_msk) < 0)
|
||||||
break;
|
break;
|
||||||
else {
|
else {
|
||||||
c_msk++;
|
c_msk++;
|
||||||
@ -240,14 +216,16 @@ create_masked_message(struct env_event *env, regmatch_t *pmatch,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
c_msk++;
|
c_msk++;
|
||||||
if (!handle_match_replacement(&dst, dst_e, &c_msk, e_msk,
|
if (!handle_match_replacement(notif_message, &c_msk, e_msk,
|
||||||
pmatch, env, log_ev))
|
pmatch, env, log_ev))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dst;
|
|
||||||
|
/* If we could parse the entire mask. */
|
||||||
|
return (*c_msk == '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,10 +240,10 @@ static int handle_regex(struct log_event *ev, int idx_env)
|
|||||||
{
|
{
|
||||||
char time_str[32] = {0};
|
char time_str[32] = {0};
|
||||||
regmatch_t pmatch[MAX_MATCHES] = {0};
|
regmatch_t pmatch[MAX_MATCHES] = {0};
|
||||||
char notification_message[2048] = {0};
|
struct str_ab notif_message;
|
||||||
|
|
||||||
|
int ret;
|
||||||
int notif_idx;
|
int notif_idx;
|
||||||
char *notif_p;
|
|
||||||
struct env_event *env_ev;
|
struct env_event *env_ev;
|
||||||
|
|
||||||
env_ev = &env_events[idx_env];
|
env_ev = &env_events[idx_env];
|
||||||
@ -280,34 +258,35 @@ static int handle_regex(struct log_event *ev, int idx_env)
|
|||||||
log_msg("> amnt sub expr: %zu\n", env_ev->regex.re_nsub);
|
log_msg("> amnt sub expr: %zu\n", env_ev->regex.re_nsub);
|
||||||
log_msg("> notifier : %s\n", notifiers_str[notif_idx]);
|
log_msg("> notifier : %s\n", notifiers_str[notif_idx]);
|
||||||
|
|
||||||
notif_p = notification_message;
|
ab_init(¬if_message);
|
||||||
|
|
||||||
/* Check if there are any subexpressions, if not, just format
|
/* Check if there are any subexpressions, if not, just format
|
||||||
* the message.
|
* the message.
|
||||||
*/
|
*/
|
||||||
if (env_ev->regex.re_nsub) {
|
if (env_ev->regex.re_nsub) {
|
||||||
notif_p = create_masked_message(env_ev, pmatch, ev,
|
if (!create_masked_message(env_ev, pmatch, ev, ¬if_message)) {
|
||||||
notification_message, sizeof(notification_message) - 1);
|
log_msg("Unable to create masked message!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(
|
if (ab_append_fmt(¬if_message, ", at: %s",
|
||||||
notif_p,
|
get_formatted_time(ev->timestamp, time_str)))
|
||||||
(notification_message + sizeof(notification_message)) - notif_p,
|
{
|
||||||
", at: %s",
|
return 0;
|
||||||
get_formatted_time(ev->timestamp, time_str)
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
snprintf(
|
ret = ab_append_fmt(¬if_message,
|
||||||
notification_message,
|
|
||||||
sizeof(notification_message) - 1,
|
|
||||||
"%s, at: %s",
|
"%s, at: %s",
|
||||||
env_ev->ev_mask_msg,
|
env_ev->ev_mask_msg,
|
||||||
get_formatted_time(ev->timestamp, time_str)
|
get_formatted_time(ev->timestamp, time_str));
|
||||||
);
|
|
||||||
|
if (ret)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notifiers[notif_idx].send_notification(notification_message) < 0) {
|
if (notifiers[notif_idx].send_notification(notif_message.buff) < 0) {
|
||||||
log_msg("unable to send the notification through %s\n",
|
log_msg("unable to send the notification through %s\n",
|
||||||
notifiers_str[notif_idx]);
|
notifiers_str[notif_idx]);
|
||||||
}
|
}
|
||||||
@ -325,10 +304,11 @@ static int handle_regex(struct log_event *ev, int idx_env)
|
|||||||
*/
|
*/
|
||||||
static int handle_substr(struct log_event *ev, int idx_env)
|
static int handle_substr(struct log_event *ev, int idx_env)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
int notif_idx;
|
int notif_idx;
|
||||||
char time_str[32] = {0};
|
char time_str[32] = {0};
|
||||||
struct env_event *env_ev;
|
struct env_event *env_ev;
|
||||||
char notification_message[2048] = {0};
|
struct str_ab notif_message;
|
||||||
|
|
||||||
env_ev = &env_events[idx_env];
|
env_ev = &env_events[idx_env];
|
||||||
notif_idx = env_ev->ev_notifier_idx;
|
notif_idx = env_ev->ev_notifier_idx;
|
||||||
@ -340,16 +320,19 @@ static int handle_substr(struct log_event *ev, int idx_env)
|
|||||||
log_msg("> type: substr, match: (%s), notifier: %s\n",
|
log_msg("> type: substr, match: (%s), notifier: %s\n",
|
||||||
env_ev->ev_match_str, notifiers_str[notif_idx]);
|
env_ev->ev_match_str, notifiers_str[notif_idx]);
|
||||||
|
|
||||||
|
ab_init(¬if_message);
|
||||||
|
|
||||||
/* Format the message. */
|
/* Format the message. */
|
||||||
snprintf(
|
ret = ab_append_fmt(¬if_message,
|
||||||
notification_message,
|
|
||||||
sizeof notification_message - 1,
|
|
||||||
"%s, at: %s",
|
"%s, at: %s",
|
||||||
env_ev->ev_mask_msg,
|
env_ev->ev_mask_msg,
|
||||||
get_formatted_time(ev->timestamp, time_str)
|
get_formatted_time(ev->timestamp, time_str)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (notifiers[notif_idx].send_notification(notification_message) < 0) {
|
if (ret)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (notifiers[notif_idx].send_notification(notif_message.buff) < 0) {
|
||||||
log_msg("unable to send the notification through %s\n",
|
log_msg("unable to send the notification through %s\n",
|
||||||
notifiers_str[notif_idx]);
|
notifiers_str[notif_idx]);
|
||||||
}
|
}
|
||||||
|
15
events.c
15
events.c
@ -12,6 +12,7 @@
|
|||||||
#include "alertik.h"
|
#include "alertik.h"
|
||||||
#include "notifiers.h"
|
#include "notifiers.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "str.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Static events
|
* Static events
|
||||||
@ -252,18 +253,19 @@ static void handle_wifi_login_attempts(struct log_event *ev, int idx_env)
|
|||||||
char time_str[32] = {0};
|
char time_str[32] = {0};
|
||||||
char mac_addr[32] = {0};
|
char mac_addr[32] = {0};
|
||||||
char wifi_iface[32] = {0};
|
char wifi_iface[32] = {0};
|
||||||
char notification_message[2048] = {0};
|
struct str_ab notif_message;
|
||||||
int notif_idx;
|
int notif_idx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
log_msg("> Login attempt detected!\n");
|
log_msg("> Login attempt detected!\n");
|
||||||
|
|
||||||
if (parse_login_attempt_msg(ev->msg, wifi_iface, mac_addr) < 0)
|
if (parse_login_attempt_msg(ev->msg, wifi_iface, mac_addr) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ab_init(¬if_message);
|
||||||
|
|
||||||
/* Send our notification. */
|
/* Send our notification. */
|
||||||
snprintf(
|
ret = ab_append_fmt(¬if_message,
|
||||||
notification_message,
|
|
||||||
sizeof notification_message - 1,
|
|
||||||
"There is someone trying to connect "
|
"There is someone trying to connect "
|
||||||
"to your WiFi: %s, with the mac-address: %s, at:%s",
|
"to your WiFi: %s, with the mac-address: %s, at:%s",
|
||||||
wifi_iface,
|
wifi_iface,
|
||||||
@ -271,10 +273,13 @@ static void handle_wifi_login_attempts(struct log_event *ev, int idx_env)
|
|||||||
get_formatted_time(ev->timestamp, time_str)
|
get_formatted_time(ev->timestamp, time_str)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
|
||||||
log_msg("> Retrieved info, MAC: (%s), Interface: (%s)\n", mac_addr, wifi_iface);
|
log_msg("> Retrieved info, MAC: (%s), Interface: (%s)\n", mac_addr, wifi_iface);
|
||||||
|
|
||||||
notif_idx = static_events[idx_env].ev_notifier_idx;
|
notif_idx = static_events[idx_env].ev_notifier_idx;
|
||||||
if (notifiers[notif_idx].send_notification(notification_message) < 0) {
|
if (notifiers[notif_idx].send_notification(notif_message.buff) < 0) {
|
||||||
log_msg("unable to send the notification!\n");
|
log_msg("unable to send the notification!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
82
notifiers.c
82
notifiers.c
@ -11,6 +11,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "notifiers.h"
|
#include "notifiers.h"
|
||||||
#include "alertik.h"
|
#include "alertik.h"
|
||||||
|
#include "str.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notification handling/notifiers
|
* Notification handling/notifiers
|
||||||
@ -69,7 +70,12 @@ static int setopts_get_curl(CURL *hnd, const char *url)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @brief Cleanup all resources used by libcurl, including the handler,
|
||||||
|
* curl_slist and escape'd chars.
|
||||||
*
|
*
|
||||||
|
* @param hnd curl handler
|
||||||
|
* @param escape Escape string if any (leave NULL if there's none).
|
||||||
|
* @param slist String list if any (leave NULL if there's none).
|
||||||
*/
|
*/
|
||||||
static void do_curl_cleanup(CURL *hnd, char *escape, struct curl_slist *slist)
|
static void do_curl_cleanup(CURL *hnd, char *escape, struct curl_slist *slist)
|
||||||
{
|
{
|
||||||
@ -80,10 +86,18 @@ static void do_curl_cleanup(CURL *hnd, char *escape, struct curl_slist *slist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @brief Finally sends a curl request, check its return code
|
||||||
|
* and then cleanup the resources allocated.
|
||||||
*
|
*
|
||||||
|
* @param hnd curl handler
|
||||||
|
* @param escape Escape string if any (leave NULL if there's none).
|
||||||
|
* @param slist String list if any (leave NULL if there's none).
|
||||||
|
*
|
||||||
|
* @return Returns CURLE_OK if success, !CURLE_OK if error.
|
||||||
*/
|
*/
|
||||||
static CURLcode do_curl(CURL *hnd, char *escape, struct curl_slist *slist)
|
static CURLcode do_curl(CURL *hnd, char *escape, struct curl_slist *slist)
|
||||||
{
|
{
|
||||||
|
long response_code = 0;
|
||||||
CURLcode ret_curl = !CURLE_OK;
|
CURLcode ret_curl = !CURLE_OK;
|
||||||
|
|
||||||
#ifndef DISABLE_NOTIFICATIONS
|
#ifndef DISABLE_NOTIFICATIONS
|
||||||
@ -91,8 +105,14 @@ static CURLcode do_curl(CURL *hnd, char *escape, struct curl_slist *slist)
|
|||||||
if (ret_curl != CURLE_OK) {
|
if (ret_curl != CURLE_OK) {
|
||||||
log_msg("> Unable to send request!\n");
|
log_msg("> Unable to send request!\n");
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
}
|
||||||
log_msg("> Done!\n");
|
else {
|
||||||
|
curl_easy_getinfo(hnd, CURLINFO_RESPONSE_CODE, &response_code);
|
||||||
|
log_msg("> Done!\n", response_code);
|
||||||
|
if (response_code != 200) {
|
||||||
|
log_msg("(Info: Response code != 200 (%ld), your message might "
|
||||||
|
"not be correctly sent!)\n", response_code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -143,36 +163,48 @@ static int setopts_post_json_curl(CURL *hnd, const char *url,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @brief Sends a generic webhook POST request with JSON payload in the
|
||||||
|
* format {"text": "text here"}.
|
||||||
*
|
*
|
||||||
|
* @param url Target webhook URL.
|
||||||
|
* @param text Text to be sent in the json payload.
|
||||||
|
*
|
||||||
|
* @return Returns CURLE_OK if success, 1 if error.
|
||||||
*/
|
*/
|
||||||
static int send_generic_webhook(const char *url, const char *text)
|
static int send_generic_webhook(const char *url, const char *text)
|
||||||
{
|
{
|
||||||
CURL *hnd = NULL;
|
CURL *hnd = NULL;
|
||||||
struct curl_slist *s = NULL;
|
struct curl_slist *s = NULL;
|
||||||
char payload_data[4096] = {0};
|
struct str_ab payload_data;
|
||||||
|
const char *t;
|
||||||
|
|
||||||
if (!(hnd = curl_easy_init())) {
|
if (!(hnd = curl_easy_init())) {
|
||||||
log_msg("Failed to initialize libcurl!\n");
|
log_msg("Failed to initialize libcurl!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(
|
ab_init(&payload_data);
|
||||||
payload_data,
|
ab_append_str(&payload_data, "{\"text\":\"", 9);
|
||||||
sizeof payload_data - 1,
|
|
||||||
"{\"text\":\"%s\"}",
|
|
||||||
text
|
|
||||||
);
|
|
||||||
|
|
||||||
|
/* Append the payload data text while escaping double
|
||||||
|
* quotes.
|
||||||
|
*/
|
||||||
|
for (t = text; *t != '\0'; t++) {
|
||||||
|
if (*t != '"') {
|
||||||
|
if (ab_append_chr(&payload_data, *t) < 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (ab_append_str(&payload_data, "\\\"", 2) < 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
/* End the string. */
|
||||||
TODO:
|
if (ab_append_str(&payload_data, "\"}", 2) < 0)
|
||||||
- escape "" in the payload, otherwise it will silently
|
return 1;
|
||||||
escape from the {"text": }
|
|
||||||
- think about the return code from the request and
|
|
||||||
emmit some message if not 200
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (setopts_post_json_curl(hnd, url, payload_data, &s))
|
if (setopts_post_json_curl(hnd, url, payload_data.buff, &s))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
log_msg("> Sending notification!\n");
|
log_msg("> Sending notification!\n");
|
||||||
@ -209,9 +241,10 @@ void setup_telegram(void)
|
|||||||
|
|
||||||
static int send_telegram_notification(const char *msg)
|
static int send_telegram_notification(const char *msg)
|
||||||
{
|
{
|
||||||
char full_request_url[4096] = {0};
|
struct str_ab full_request_url;
|
||||||
char *escaped_msg = NULL;
|
char *escaped_msg = NULL;
|
||||||
CURL *hnd = NULL;
|
CURL *hnd = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!(hnd = curl_easy_init())) {
|
if (!(hnd = curl_easy_init())) {
|
||||||
log_msg("Failed to initialize libcurl!\n");
|
log_msg("Failed to initialize libcurl!\n");
|
||||||
@ -224,13 +257,16 @@ static int send_telegram_notification(const char *msg)
|
|||||||
do_curl_cleanup(hnd, escaped_msg, NULL);
|
do_curl_cleanup(hnd, escaped_msg, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(
|
ab_init(&full_request_url);
|
||||||
full_request_url,
|
|
||||||
sizeof full_request_url - 1,
|
ret = ab_append_fmt(&full_request_url,
|
||||||
"https://api.telegram.org/bot%s/sendMessage?chat_id=%s&text=%s",
|
"https://api.telegram.org/bot%s/sendMessage?chat_id=%s&text=%s",
|
||||||
telegram_bot_token, telegram_chat_id, escaped_msg);
|
telegram_bot_token, telegram_chat_id, escaped_msg);
|
||||||
|
|
||||||
setopts_get_curl(hnd, full_request_url);
|
if (ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
setopts_get_curl(hnd, full_request_url.buff);
|
||||||
log_msg("> Sending notification!\n");
|
log_msg("> Sending notification!\n");
|
||||||
return do_curl(hnd, escaped_msg, NULL);
|
return do_curl(hnd, escaped_msg, NULL);
|
||||||
}
|
}
|
||||||
@ -250,7 +286,7 @@ void setup_slack(void)
|
|||||||
|
|
||||||
slack_webhook_url = getenv("SLACK_WEBHOOK_URL");
|
slack_webhook_url = getenv("SLACK_WEBHOOK_URL");
|
||||||
if (!slack_webhook_url) {
|
if (!slack_webhook_url) {
|
||||||
panic("Unable to find env vars for, please check if you have set\n"
|
panic("Unable to find env vars for Slack, please check if you have set "
|
||||||
"the SLACK_WEBHOOK_URL!!\n");
|
"the SLACK_WEBHOOK_URL!!\n");
|
||||||
}
|
}
|
||||||
setup = 1;
|
setup = 1;
|
||||||
|
244
str.c
Normal file
244
str.c
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/*
|
||||||
|
* Alertik: a tiny 'syslog' server & notification tool for Mikrotik routers.
|
||||||
|
* This is free and unencumbered software released into the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* String/append buffer implementation based on Aqua:
|
||||||
|
* https://gist.github.com/Theldus/09ed2205aa5ba15cdf4571b71cd1c8fc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "str.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
/* Malloc is only used if AB_USE_MALLOC is defined. */
|
||||||
|
#ifdef AB_USE_MALLOC
|
||||||
|
#if defined(AB_CALLOC) && defined(AB_REALLOC) && defined(AB_FREE)
|
||||||
|
# define AB_USE_STDLIB
|
||||||
|
#elif !defined(AB_CALLOC) && !defined(AB_REALLOC) && !defined(AB_FREE)
|
||||||
|
# define AB_USE_STDLIB
|
||||||
|
#else
|
||||||
|
#error "For custom memory allocators, you should define all three routines!"
|
||||||
|
#error "Please define: AB_CALLOC, AB_REALLOC and AB_FREE!"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AB_CALLOC
|
||||||
|
#define AB_CALLOC(nmemb,sz) calloc((nmemb),(sz))
|
||||||
|
#define AB_REALLOC(p,newsz) realloc((p),(newsz))
|
||||||
|
#define AB_FREE(p) free((p))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AB_USE_STDLIB
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
/* BUFFER ROUTINES */
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
#ifdef AB_USE_MALLOC
|
||||||
|
/**
|
||||||
|
* @brief Rounds up to the next power of two.
|
||||||
|
*
|
||||||
|
* @param target Target number to be rounded.
|
||||||
|
*
|
||||||
|
* @return Returns the next power of two.
|
||||||
|
*/
|
||||||
|
static size_t next_power(size_t target)
|
||||||
|
{
|
||||||
|
target--;
|
||||||
|
target |= target >> 1;
|
||||||
|
target |= target >> 2;
|
||||||
|
target |= target >> 4;
|
||||||
|
target |= target >> 8;
|
||||||
|
target |= target >> 16;
|
||||||
|
target++;
|
||||||
|
return (target);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if the new size fits in the append buffer, if not,
|
||||||
|
* reallocates the buffer size by @p incr bytes.
|
||||||
|
*
|
||||||
|
* If the macro AB_USE_MALLOC is not defined (default), this only
|
||||||
|
* checks if the new size fits the buffer.
|
||||||
|
*
|
||||||
|
* @param sh Aqua highlight context.
|
||||||
|
* @param incr Size (in bytes) to be incremented.
|
||||||
|
*
|
||||||
|
* @return Returns 0 if success, -1 otherwise.
|
||||||
|
*
|
||||||
|
* @note The new size is the next power of two, that is capable
|
||||||
|
* to hold the required buffer size.
|
||||||
|
*/
|
||||||
|
static int increase_buff(struct str_ab *sh, size_t incr)
|
||||||
|
{
|
||||||
|
#ifndef AB_USE_MALLOC
|
||||||
|
if (sh->pos + incr >= MAX_LINE) {
|
||||||
|
log_msg("(increase buffer) Unable to fit appended message!\n");
|
||||||
|
log_msg("(static storage) incr: %zu, buff_len: %zu, pos: %zu\n",
|
||||||
|
incr, sh->pos, sh->buff_len);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
char *new;
|
||||||
|
size_t new_size;
|
||||||
|
if (sh->pos + incr >= sh->buff_len)
|
||||||
|
{
|
||||||
|
new_size = next_power(sh->buff_len + incr);
|
||||||
|
new = AB_REALLOC(sh->buff, new_size);
|
||||||
|
if (new == NULL)
|
||||||
|
{
|
||||||
|
AB_FREE(sh->buff);
|
||||||
|
sh->buff = NULL;
|
||||||
|
|
||||||
|
log_msg("(increase buffer) Unable to fit appended message!\n");
|
||||||
|
log_msg("(realloc storage) incr: %zu, buff_len: %zu, pos: %zu\n",
|
||||||
|
incr, sh->pos, sh->buff_len);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
sh->buff_len = new_size;
|
||||||
|
sh->buff = new;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the append buffer context.
|
||||||
|
*
|
||||||
|
* @param ab Append buffer structure.
|
||||||
|
*
|
||||||
|
* @return Returns 0 if success, -1 otherwise.
|
||||||
|
*/
|
||||||
|
int ab_init(struct str_ab *ab)
|
||||||
|
{
|
||||||
|
if (!ab)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
memset(ab, 0, sizeof(*ab));
|
||||||
|
|
||||||
|
#ifndef AB_USE_MALLOC
|
||||||
|
ab->buff_len = MAX_LINE;
|
||||||
|
#else
|
||||||
|
ab->buff = AB_CALLOC(MAX_LINE, 1);
|
||||||
|
if (!ab->buff)
|
||||||
|
return (-1);
|
||||||
|
ab->buff_len = MAX_LINE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Append a given char @p c into the buffer.
|
||||||
|
*
|
||||||
|
* @param sh Aqua highlight context.
|
||||||
|
* @param c Char to be appended.
|
||||||
|
*
|
||||||
|
* @return Returns 0 if success, -1 otherwise.
|
||||||
|
*/
|
||||||
|
int ab_append_chr(struct str_ab *sh, char c)
|
||||||
|
{
|
||||||
|
if (increase_buff(sh, 2) < 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
sh->buff[sh->pos + 0] = c;
|
||||||
|
sh->buff[sh->pos + 1] = '\0';
|
||||||
|
sh->pos++;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Appends a given string pointed by @p s of size @p len
|
||||||
|
* into the current buffer.
|
||||||
|
*
|
||||||
|
* If @p len is 0, the string is assumed to be null-terminated
|
||||||
|
* and its length is obtained.
|
||||||
|
*
|
||||||
|
* @param ab Append buffer context.
|
||||||
|
* @param s String to be append into the buffer.
|
||||||
|
* @param len String size, if 0, it's length is obtained.
|
||||||
|
*
|
||||||
|
* @return Returns 0 if success, -1 otherwise.
|
||||||
|
*/
|
||||||
|
int ab_append_str(struct str_ab *ab, const char *s, size_t len)
|
||||||
|
{
|
||||||
|
if (!len)
|
||||||
|
len = strlen(s);
|
||||||
|
|
||||||
|
if (increase_buff(ab, len + 1) < 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
memcpy(ab->buff + ab->pos, s, len);
|
||||||
|
ab->pos += len;
|
||||||
|
ab->buff[ab->pos] = '\0';
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Appends a given formatted string pointed by @p fmt.
|
||||||
|
*
|
||||||
|
* @param ab Append buffer context.
|
||||||
|
* @param fmt Formatted string to be appended.
|
||||||
|
*
|
||||||
|
* @return Returns 0 if success, -1 otherwise.
|
||||||
|
*/
|
||||||
|
int ab_append_fmt(struct str_ab *ab, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int str_len, ab_len, orig_ab_pos;
|
||||||
|
char *buff_st;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
buff_st = ab->buff + ab->pos;
|
||||||
|
ab_len = ab->buff_len - ab->pos;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
str_len = vsnprintf(buff_st, ab_len, fmt, ap);
|
||||||
|
if (str_len < 0) {
|
||||||
|
log_msg("Unable to fit appended message!\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
/* If it fits, just happily returns. */
|
||||||
|
if (str_len + 1 <= ab_len) {
|
||||||
|
ab->pos += str_len;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, adjust current pos and try to increase buffer. */
|
||||||
|
else {
|
||||||
|
orig_ab_pos = ab->pos;
|
||||||
|
|
||||||
|
/* temporarily advance our buffer
|
||||||
|
* to trick our increase buffer. */
|
||||||
|
ab->pos = ab->buff_len;
|
||||||
|
|
||||||
|
if (increase_buff(ab, (str_len + 1) - ab_len))
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
ab->pos = orig_ab_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
buff_st = ab->buff + ab->pos;
|
||||||
|
ab_len = ab->buff_len - ab->pos;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
str_len = vsnprintf(buff_st, ab_len, fmt, ap);
|
||||||
|
if (str_len < 0 || (str_len + 1) > ab_len) {
|
||||||
|
log_msg("Unable to fit appended message!\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
ab->pos += str_len;
|
||||||
|
return (0);
|
||||||
|
}
|
39
str.h
Normal file
39
str.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Alertik: a tiny 'syslog' server & notification tool for Mikrotik routers.
|
||||||
|
* This is free and unencumbered software released into the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STR_H
|
||||||
|
#define STR_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable to disable malloc support and enable dinamically
|
||||||
|
* allocated buffer.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
#define AB_USE_MALLOC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Maximum highlighted line len, when built without malloc. */
|
||||||
|
#define MAX_LINE 4096
|
||||||
|
|
||||||
|
/* Append buffer. */
|
||||||
|
struct str_ab
|
||||||
|
{
|
||||||
|
#ifndef AB_USE_MALLOC
|
||||||
|
char buff[MAX_LINE + 1];
|
||||||
|
#else
|
||||||
|
char *buff;
|
||||||
|
#endif
|
||||||
|
size_t buff_len;
|
||||||
|
size_t pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int ab_init(struct str_ab *ab);
|
||||||
|
extern int ab_append_chr(struct str_ab *sh, char c);
|
||||||
|
extern int ab_append_str(struct str_ab *ab, const char *s, size_t len);
|
||||||
|
extern int ab_append_fmt(struct str_ab *ab, const char *fmt, ...);
|
||||||
|
|
||||||
|
#endif /* STR_H. */
|
Loading…
Reference in New Issue
Block a user