From 1972b32b6012f22b765f5c2e1248af2550715d23 Mon Sep 17 00:00:00 2001 From: Wilco Baan Hofman Date: Wed, 1 Aug 2012 03:29:01 +0200 Subject: [PATCH] Refactor code so that other protocols can be added with minimal duplicate code. --- Makefile | 22 +++- config.c | 114 +++++++++++++++++++++ config.h | 40 ++++++++ database.c | 98 ++++++++++++++++++ database.h | 20 ++++ includes.h | 44 ++++++++ sia.c | 4 +- sia.h | 4 +- siahs.h | 2 +- siahsd.c | 237 ++----------------------------------------- status.c | 75 ++++++++++++++ siahsd.h => status.h | 16 +-- 12 files changed, 428 insertions(+), 248 deletions(-) create mode 100644 config.c create mode 100644 config.h create mode 100644 database.c create mode 100644 database.h create mode 100644 includes.h create mode 100644 status.c rename siahsd.h => status.h (84%) diff --git a/Makefile b/Makefile index c3ba41d..68f513d 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,20 @@ CC := gcc # Enable for debug -CFLAGS := -g -ggdb -std=c99 -Wall -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wdeclaration-after-statement -Werror-implicit-function-declaration -Wstrict-prototypes -Werror +CFLAGS := -g -ggdb -std=c99 -Wall -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wdeclaration-after-statement -Werror-implicit-function-declaration -Wstrict-prototypes -INCLUDES := -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include +INCLUDES := -I/usr/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/samba-4.0 siahsd_LIB := -ltalloc -ldbi -lglib-2.0 -siahsd_OBJ := sia.o siahsd.o +siahsd_OBJ := sia.o status.o database.o config.o siahsd.o -OBJ := $(siahsd_OBJ) +secipd_LIB := -ltalloc -ldbi -lglib-2.0 -lndr +secipd_OBJ := sia.o status.o database.o config.o ndr_secip.o secipd.o -binaries := siahsd + +OBJ := $(siahsd_OBJ) $(secipd_OBJ) + +binaries := siahsd secipd all: $(binaries) @@ -23,6 +27,10 @@ distclean: clean rm -f tags +secipd: $(secipd_OBJ) + @echo Linking $@ + @$(CC) $(secipd_OBJ) $(secipd_LIB) -o secipd + siahsd: $(siahsd_OBJ) @echo Linking $@ @$(CC) $(siahsd_OBJ) $(siahsd_LIB) -o siahsd @@ -30,6 +38,10 @@ siahsd: $(siahsd_OBJ) ctags: ctags `find -name \*.[ch]` +idl: + pidl/pidl --ndr-parser=ndr_secip.c secip.idl + pidl/pidl --header=secip.h secip.idl + %.o: %.c @echo Compiling $*.c @$(CC) -c $(CFLAGS) $(INCLUDES) -o $*.o $< diff --git a/config.c b/config.c new file mode 100644 index 0000000..434e092 --- /dev/null +++ b/config.c @@ -0,0 +1,114 @@ +/* + SIA-HS Alarm Monitoring Service + Copyright (C) Wilco Baan Hofman 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#include "includes.h" + +/* My global state */ +configuration *conf = NULL; +const char *process_name = NULL; + + +configuration *get_conf(void) { + return conf; +} + +const char *get_process_name(void) { + return process_name; +} + +STATUS set_process_name(const char *name) { + process_name = name; + return ST_OK; +} + +STATUS read_configuration_file(TALLOC_CTX *mem_ctx) +{ + GError *error = NULL; + GKeyFile *keyfile = g_key_file_new (); + + if (!g_key_file_load_from_file (keyfile, CONFIGFILE, 0, &error)) { + g_error (error->message); + return ST_CONFIGURATION_ERROR; + } + + conf = talloc(mem_ctx, configuration); + NO_MEM_RETURN(conf); + + conf->database_host = g_key_file_get_string(keyfile, "database", + "host", &error); + if (error) { + fprintf(stderr, "No database host supplied in the configuration.\n"); + return ST_CONFIGURATION_ERROR; + } + conf->database_name = g_key_file_get_string(keyfile, "database", + "name", &error); + if (error) { + fprintf(stderr, "No database name supplied in the configuration.\n"); + return ST_CONFIGURATION_ERROR; + } + conf->database_driver = g_key_file_get_string(keyfile, "database", + "driver", &error); + if (error) { + fprintf(stderr, "No database driver supplied in the configuration.\n"); + return ST_CONFIGURATION_ERROR; + } + conf->database_username = g_key_file_get_string(keyfile, "database", + "username", &error); + if (error) { + fprintf(stderr, "No database username supplied in the configuration.\n"); + return ST_CONFIGURATION_ERROR; + } + conf->database_password = g_key_file_get_string(keyfile, "database", + "password", &error); + if (error) { + fprintf(stderr, "No database password supplied in the configuration.\n"); + return ST_CONFIGURATION_ERROR; + } + + conf->siahs_port = g_key_file_get_integer(keyfile, "siahs", "port", &error); + if (error) { + fprintf(stderr, "No SIA-HS port supplied in the configuration.\n"); + return ST_CONFIGURATION_ERROR; + } + conf->log_file = g_key_file_get_string(keyfile, "siahsd", "log file", &error); + if (error) { + fprintf(stderr, "No log file supplied in the configuration.\n"); + return ST_CONFIGURATION_ERROR; + } + conf->log_level = g_key_file_get_integer(keyfile, "siahsd", "log level", &error); + if (error) { + fprintf(stderr, "No log level supplied in the configuration.\n"); + return ST_CONFIGURATION_ERROR; + } + conf->pid_file = g_key_file_get_string(keyfile, "siahsd", "pid file", &error); + if (error) { + fprintf(stderr, "No pid file supplied in the configuration.\n"); + return ST_CONFIGURATION_ERROR; + } + conf->foreground = g_key_file_get_boolean(keyfile, "siahsd", "foreground", &error); + if (error) { + conf->foreground = false; + } + conf->secip_port = g_key_file_get_integer(keyfile, "secip", "port", &error); + if (error) { + fprintf(stderr, "No SecIP port supplied in the configuration.\n"); + return ST_CONFIGURATION_ERROR; + } + + return ST_OK; +} + diff --git a/config.h b/config.h new file mode 100644 index 0000000..4a0e569 --- /dev/null +++ b/config.h @@ -0,0 +1,40 @@ +/* + SIA-HS Alarm Monitoring Service + Copyright (C) Wilco Baan Hofman 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#define CONFIGFILE "/etc/siahsd.conf" + +typedef struct { + char *database_host; + char *database_username; + char *database_password; + char *database_name; + char *database_driver; + gint siahs_port; + char *log_file; + gint log_level; + gboolean foreground; + char *pid_file; + gint secip_port; +} configuration; + + +configuration *get_conf(void); +const char *get_process_name(void); + +STATUS set_process_name(const char *name); +STATUS read_configuration_file(TALLOC_CTX *mem_ctx); diff --git a/database.c b/database.c new file mode 100644 index 0000000..942f994 --- /dev/null +++ b/database.c @@ -0,0 +1,98 @@ +/* + SIA-HS Alarm Monitoring Service + Copyright (C) Wilco Baan Hofman 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#include "includes.h" + + +/* + * talloc_quoted_string escapes quotes in a string and encapsulates it in quotes. + * It returns a pointer to talloc'ed memory, the quoted string. + */ +static char *talloc_quoted_string(TALLOC_CTX *mem_ctx, const char *string) { + /* Allocate twice the string length, to be safe and not having to realloc all the time */ + char *ret = talloc_zero_array(mem_ctx, char, strlen(string) * 2 + 1); + size_t i, j; + + NO_MEM_RETURN_RV(ret, NULL); + + ret[0] = '\''; + + for (i = 0, j = 1; i < strlen(string); i++, j++) { + if (string[i] == '\'' || string[i] == '\\') { + ret[j] = '\''; + ret[++j] = string[i]; + } else { + ret[j] = string[i]; + } + } + ret[j] = '\''; + ret[++j] = '\0'; + + return ret; +} + +STATUS log_event_to_database(TALLOC_CTX *mem_ctx, dbi_conn conn, const char *prom, const char *code, const char *description) { + char *quoted_prom; + char *quoted_code; + char *quoted_long_code; + char *quoted_description; + + quoted_prom = talloc_quoted_string(mem_ctx, prom); + NO_MEM_RETURN(quoted_prom); + quoted_code = talloc_quoted_string(mem_ctx, code); + NO_MEM_RETURN(quoted_code); + quoted_long_code = talloc_quoted_string(mem_ctx, sia_code_str(code)); + NO_MEM_RETURN(quoted_long_code); + quoted_description = talloc_quoted_string(mem_ctx, description); + NO_MEM_RETURN(quoted_description); + + DEBUG(3, "Storing event: %s %s %s -- %s: %s\n", prom, code, description, sia_code_str(code), sia_code_desc(code)); + + dbi_conn_queryf(conn, "INSERT INTO events (timestamp, prom, code, long_code, description) VALUES (NOW(), %s, %s, %s, %s)\n", + quoted_prom, quoted_code, quoted_long_code, quoted_description); + + talloc_free(quoted_prom); + talloc_free(quoted_code); + talloc_free(quoted_long_code); + talloc_free(quoted_description); + + return ST_OK; +} + +STATUS connect_to_database(dbi_conn *conn) +{ + configuration *conf = get_conf(); + + DEBUG(1, "Connecting to %s database %s at %s as user %s", conf->database_driver, + conf->database_name, conf->database_host, conf->database_username); + + dbi_initialize(NULL); + *conn = dbi_conn_new(conf->database_driver); + dbi_conn_set_option(*conn, "host", conf->database_host); + dbi_conn_set_option(*conn, "username", conf->database_username); + dbi_conn_set_option(*conn, "password", conf->database_password); + dbi_conn_set_option(*conn, "dbname", conf->database_name); + dbi_conn_set_option(*conn, "encoding", "UTF-8"); + + if (dbi_conn_connect(*conn) < 0) { + DEBUG(0, "Could not connect to the database"); + return ST_DATABASE_FAILURE; + } + + return ST_OK; +} + diff --git a/database.h b/database.h new file mode 100644 index 0000000..9daf99d --- /dev/null +++ b/database.h @@ -0,0 +1,20 @@ +/* + SIA-HS Alarm Monitoring Service + Copyright (C) Wilco Baan Hofman 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +STATUS log_event_to_database(TALLOC_CTX *mem_ctx, dbi_conn conn, const char *prom, const char *code, const char *description); +STATUS connect_to_database(dbi_conn *conn); diff --git a/includes.h b/includes.h new file mode 100644 index 0000000..0478d0c --- /dev/null +++ b/includes.h @@ -0,0 +1,44 @@ +/* + SIA-HS Alarm Monitoring Service + Copyright (C) Wilco Baan Hofman 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Libs */ +#include +#include +#include + +/* Private */ +#include "status.h" +#include "talloc.h" +#include "sia.h" +#include "config.h" +#include "database.h" diff --git a/sia.c b/sia.c index ee8c39d..a54a5ba 100644 --- a/sia.c +++ b/sia.c @@ -638,7 +638,7 @@ const struct { -const char *sia_code_str(char *code) { +const char *sia_code_str(const char *code) { uint16_t i; for (i = 0; sia_codes[i].code != NULL; i++) { @@ -650,7 +650,7 @@ const char *sia_code_str(char *code) { return NULL; } -const char *sia_code_desc(char *code) { +const char *sia_code_desc(const char *code) { uint16_t i; for (i = 0; sia_codes[i].code != NULL; i++) { diff --git a/sia.h b/sia.h index d3e54a0..67d9946 100644 --- a/sia.h +++ b/sia.h @@ -15,6 +15,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -const char *sia_code_str(char *code); -const char *sia_code_desc(char *code); +const char *sia_code_str(const char *code); +const char *sia_code_desc(const char *code); diff --git a/siahs.h b/siahs.h index feac845..6ba8b7b 100644 --- a/siahs.h +++ b/siahs.h @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -struct packet { +struct siahs_packet { uint32_t len; char unknown1; /* 0x01 */ char unknown2; /* 0x01 */ diff --git a/siahsd.c b/siahsd.c index 506c8ab..cc12445 100644 --- a/siahsd.c +++ b/siahsd.c @@ -15,34 +15,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* Libs */ -#include -#include -#include - -/* Private */ -#include "siahsd.h" +#include "includes.h" #include "siahs.h" -#include "sia.h" #define MY_DEVICE "RCIPv2.4" -#define CONFIGFILE "/etc/siahsd.conf" /* TODO: * - Add event connection to jsonbot @@ -51,107 +28,17 @@ */ -/* My global state */ -configuration *conf = NULL; -const char *process_name = NULL; - -STATUS debug(int loglevel, const char *location, const char *function, ...) -{ - va_list ap; - static char timebuf[100]; /* Static because this should not be reallocated - in case of out of memory errors */ - time_t rawtime; - struct tm *timeinfo; - size_t s; - FILE *logfile; - - if (loglevel > conf->log_level) { - return ST_OK; - } - - logfile = fopen(conf->log_file, "a"); - if (logfile == NULL && conf->foreground) { - fprintf(stderr, "Error opening log file: %s\n", strerror(errno)); - } - - time(&rawtime); - timeinfo = localtime(&rawtime); - - s = strftime(timebuf, sizeof(timebuf), "%c", timeinfo); - if (s == 0) { - const char *text = "Failed to get proper strftime formatted date\n"; - if (conf->foreground) { - fprintf(stderr, text); - } - fprintf(logfile, text); - return ST_GENERAL_FAILURE; - } - - fprintf(logfile, "%s: %s(%d): Log level %d, at %s in function %s():\n", - timebuf, process_name, getpid(), loglevel, location, function); - if (conf->foreground) - fprintf(stderr, "%s: %s(%d): Log level %d, at %s in function %s():\n", - timebuf, process_name, getpid(), loglevel, location, function); - - va_start(ap, function); - vfprintf(logfile, va_arg(ap, char *), ap); - va_end(ap); - fputc('\n', logfile); - - if (conf->foreground) { - va_start(ap, function); - vfprintf(stderr, va_arg(ap, char *), ap); - va_end(ap); - fputc('\n', stderr); - } - - fclose(logfile); - - return ST_OK; -} - -/* - * talloc_quoted_string escapes quotes in a string and encapsulates it in quotes. - * It returns a pointer to talloc'ed memory, the quoted string. - */ -char *talloc_quoted_string(TALLOC_CTX *mem_ctx, const char *string) { - /* Allocate twice the string length, to be safe and not having to realloc all the time */ - char *ret = talloc_zero_array(mem_ctx, char, strlen(string) * 2 + 1); - size_t i, j; - - NO_MEM_RETURN_RV(ret, NULL); - - ret[0] = '\''; - - for (i = 0, j = 1; i < strlen(string); i++, j++) { - if (string[i] == '\'' || string[i] == '\\') { - ret[j] = '\''; - ret[++j] = string[i]; - } else { - ret[j] = string[i]; - } - } - ret[j] = '\''; - ret[++j] = '\0'; - - return ret; -} - /* * parse_message parses the string portion of the SIA-HS message * and writes the event to the database. * It returns nothing. */ -STATUS parse_message(TALLOC_CTX *mem_ctx, dbi_conn conn, struct packet *pkt) { +STATUS parse_message(TALLOC_CTX *mem_ctx, dbi_conn conn, struct siahs_packet *pkt) { char *message = talloc_strdup(mem_ctx, pkt->message + strlen("MESSAGE ")); char *ptr = message; char *prom = ptr; char *pkt_prom; char *code; - char *quoted_prom; - char *quoted_code; - char *quoted_long_code; - char *quoted_description; NO_MEM_RETURN(message); @@ -187,19 +74,7 @@ STATUS parse_message(TALLOC_CTX *mem_ctx, dbi_conn conn, struct packet *pkt) { return ST_ASSERTION_FAILED; } - quoted_prom = talloc_quoted_string(message, prom); - NO_MEM_RETURN(quoted_prom); - quoted_code = talloc_quoted_string(message, code); - NO_MEM_RETURN(quoted_code); - quoted_long_code = talloc_quoted_string(message, sia_code_str(code)); - NO_MEM_RETURN(quoted_long_code); - quoted_description = talloc_quoted_string(message, ptr); - NO_MEM_RETURN(quoted_description); - - fprintf(stderr, "%s %s %s -- %s: %s\n", prom, code, ptr, sia_code_str(code), sia_code_desc(code)); - - dbi_conn_queryf(conn, "INSERT INTO events (timestamp, prom, code, long_code, description) VALUES (NOW(), %s, %s, %s, %s)\n", - quoted_prom, quoted_code, quoted_long_code, quoted_description); + log_event_to_database(message, conn, prom, code, ptr); talloc_free(message); @@ -213,7 +88,7 @@ STATUS parse_message(TALLOC_CTX *mem_ctx, dbi_conn conn, struct packet *pkt) { * and a string with the reply message. * It returns nothing. */ -STATUS send_reply(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct packet *pkt, const char *string) { +STATUS send_reply(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct siahs_packet *pkt, const char *string) { int n; uint8_t *reply; int i; @@ -272,99 +147,6 @@ STATUS send_reply(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct return ST_OK; } -STATUS read_configuration_file(TALLOC_CTX *mem_ctx) -{ - GError *error = NULL; - GKeyFile *keyfile = g_key_file_new (); - - if (!g_key_file_load_from_file (keyfile, CONFIGFILE, 0, &error)) { - g_error (error->message); - return ST_CONFIGURATION_ERROR; - } - - conf = talloc(mem_ctx, configuration); - NO_MEM_RETURN(conf); - - conf->database_host = g_key_file_get_string(keyfile, "database", - "host", &error); - if (error) { - fprintf(stderr, "No database host supplied in the configuration.\n"); - return ST_CONFIGURATION_ERROR; - } - conf->database_name = g_key_file_get_string(keyfile, "database", - "name", &error); - if (error) { - fprintf(stderr, "No database name supplied in the configuration.\n"); - return ST_CONFIGURATION_ERROR; - } - conf->database_driver = g_key_file_get_string(keyfile, "database", - "driver", &error); - if (error) { - fprintf(stderr, "No database driver supplied in the configuration.\n"); - return ST_CONFIGURATION_ERROR; - } - conf->database_username = g_key_file_get_string(keyfile, "database", - "username", &error); - if (error) { - fprintf(stderr, "No database username supplied in the configuration.\n"); - return ST_CONFIGURATION_ERROR; - } - conf->database_password = g_key_file_get_string(keyfile, "database", - "password", &error); - if (error) { - fprintf(stderr, "No database password supplied in the configuration.\n"); - return ST_CONFIGURATION_ERROR; - } - - conf->siahs_port = g_key_file_get_integer(keyfile, "siahs", "port", &error); - if (error) { - fprintf(stderr, "No SIA-HS port supplied in the configuration.\n"); - return ST_CONFIGURATION_ERROR; - } - conf->log_file = g_key_file_get_string(keyfile, "siahsd", "log file", &error); - if (error) { - fprintf(stderr, "No log file supplied in the configuration.\n"); - return ST_CONFIGURATION_ERROR; - } - conf->log_level = g_key_file_get_integer(keyfile, "siahsd", "log level", &error); - if (error) { - fprintf(stderr, "No log level supplied in the configuration.\n"); - return ST_CONFIGURATION_ERROR; - } - conf->pid_file = g_key_file_get_string(keyfile, "siahsd", "pid file", &error); - if (error) { - fprintf(stderr, "No pid file supplied in the configuration.\n"); - return ST_CONFIGURATION_ERROR; - } - conf->foreground = g_key_file_get_boolean(keyfile, "siahsd", "foreground", &error); - if (error) { - conf->foreground = false; - } - - return ST_OK; -} - -STATUS connect_to_database(dbi_conn *conn) -{ - DEBUG(1, "Connecting to %s database %s at %s as user %s", conf->database_driver, - conf->database_name, conf->database_host, conf->database_username); - - dbi_initialize(NULL); - *conn = dbi_conn_new(conf->database_driver); - dbi_conn_set_option(*conn, "host", conf->database_host); - dbi_conn_set_option(*conn, "username", conf->database_username); - dbi_conn_set_option(*conn, "password", conf->database_password); - dbi_conn_set_option(*conn, "dbname", conf->database_name); - dbi_conn_set_option(*conn, "encoding", "UTF-8"); - - if (dbi_conn_connect(*conn) < 0) { - DEBUG(0, "Could not connect to the database"); - return ST_DATABASE_FAILURE; - } - - return ST_OK; -} - int main(int argc, char **argv) { int sock, n, i; @@ -376,8 +158,9 @@ int main(int argc, char **argv) { STATUS rv; FILE *pidfile; pid_t pid; + configuration *conf; - process_name = argv[0]; + set_process_name(argv[0]); /* Initialize a memory context */ mem_ctx = talloc_init("siahsd"); @@ -388,6 +171,8 @@ int main(int argc, char **argv) { if (rv != ST_OK) return rv; + conf = get_conf(); + /* Daemonize if we're not supposed to run in foreground mode */ if (!conf->foreground) { fclose(stdin); @@ -427,7 +212,7 @@ int main(int argc, char **argv) { DEBUG(0, "Started %s and waiting for SIA-HS packets on port %d", - process_name, conf->siahs_port); + get_process_name(), conf->siahs_port); /* Open a connection to the database */ rv = connect_to_database(&conn); @@ -441,12 +226,12 @@ int main(int argc, char **argv) { fromlen = sizeof(struct sockaddr_in); while (1) { uint16_t src_port; - struct packet *pkt; + struct siahs_packet *pkt; uint8_t *decoded; char buf[1024]; /* Purposefully static length */ char *reply_message; - pkt = talloc_zero(mem_ctx, struct packet); + pkt = talloc_zero(mem_ctx, struct siahs_packet); NO_MEM_RETURN(pkt); diff --git a/status.c b/status.c new file mode 100644 index 0000000..d8ad571 --- /dev/null +++ b/status.c @@ -0,0 +1,75 @@ +/* + SIA-HS Alarm Monitoring Service + Copyright (C) Wilco Baan Hofman 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#include "includes.h" + +STATUS debug(int loglevel, const char *location, const char *function, ...) +{ + va_list ap; + static char timebuf[100]; /* Static because this should not be reallocated + in case of out of memory errors */ + time_t rawtime; + struct tm *timeinfo; + size_t s; + FILE *logfile; + configuration *conf = get_conf(); + + if (loglevel > conf->log_level) { + return ST_OK; + } + + logfile = fopen(conf->log_file, "a"); + if (logfile == NULL && conf->foreground) { + fprintf(stderr, "Error opening log file: %s\n", strerror(errno)); + } + + time(&rawtime); + timeinfo = localtime(&rawtime); + + s = strftime(timebuf, sizeof(timebuf), "%c", timeinfo); + if (s == 0) { + const char *text = "Failed to get proper strftime formatted date\n"; + if (conf->foreground) { + fprintf(stderr, text); + } + fprintf(logfile, text); + return ST_GENERAL_FAILURE; + } + + fprintf(logfile, "%s: %s(%d): Log level %d, at %s in function %s():\n", + timebuf, get_process_name(), getpid(), loglevel, location, function); + if (conf->foreground) + fprintf(stderr, "%s: %s(%d): Log level %d, at %s in function %s():\n", + timebuf, get_process_name(), getpid(), loglevel, location, function); + + va_start(ap, function); + vfprintf(logfile, va_arg(ap, char *), ap); + va_end(ap); + fputc('\n', logfile); + + if (conf->foreground) { + va_start(ap, function); + vfprintf(stderr, va_arg(ap, char *), ap); + va_end(ap); + fputc('\n', stderr); + } + + fclose(logfile); + + return ST_OK; +} + diff --git a/siahsd.h b/status.h similarity index 84% rename from siahsd.h rename to status.h index 7cf549a..ab6cedb 100644 --- a/siahsd.h +++ b/status.h @@ -15,21 +15,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -typedef struct { - char *database_host; - char *database_username; - char *database_password; - char *database_name; - char *database_driver; - gint siahs_port; - char *log_file; - gint log_level; - gboolean foreground; - char *pid_file; -} configuration; #define DEBUG(level, args...) debug(level, __location__, __FUNCTION__, args) + typedef enum { ST_OK = 0, ST_GENERAL_FAILURE = 1, @@ -48,3 +37,6 @@ typedef enum { #define NO_MEM_RETURN(ptr) {if (ptr == NULL) { DEBUG(0, "Out of memory"); return ST_OUT_OF_MEMORY; }} #define NO_MEM_RETURN_RV(ptr, rv) {if (ptr == NULL) { DEBUG(0, "Out of memory"); return rv; }} + + +STATUS debug(int loglevel, const char *location, const char *function, ...);