Make sure the event handlers initialize and register themselves.

This commit is contained in:
Wilco Baan Hofman 2012-08-06 01:11:03 +02:00
parent fb4832fb88
commit 3fb1474113
11 changed files with 221 additions and 154 deletions

150
config.c
View file

@ -15,6 +15,11 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* TODO:
* - Have each event protocol definition get its own configuration directives
*/
#include "includes.h" #include "includes.h"
/* My global state */ /* My global state */
@ -23,6 +28,10 @@ const char *process_name = NULL;
struct rsa_public_key *public_key = NULL; struct rsa_public_key *public_key = NULL;
struct rsa_private_key *private_key = NULL; struct rsa_private_key *private_key = NULL;
configuration *get_modifiable_conf(void) {
return conf;
}
const configuration *get_conf(void) { const configuration *get_conf(void) {
return conf; return conf;
} }
@ -51,100 +60,107 @@ STATUS set_rsa_keys(struct rsa_public_key *pub, struct rsa_private_key *priv) {
return ST_OK; return ST_OK;
} }
STATUS read_rsa_keys(void) {
int res;
FILE *file;
uint8_t buf[1024];
struct rsa_private_key *priv;
struct rsa_public_key *pub;
uint8_t *buffer = NULL;
size_t n, size=0;
priv = talloc(conf, struct rsa_private_key);
pub = talloc(conf, struct rsa_public_key);
rsa_public_key_init (pub);
rsa_private_key_init (priv);
file = fopen(conf->rsa_key_file, "r");
if (file == NULL) {
DEBUG(0, "Can't open configured rsa key file: %s", conf->rsa_key_file);
exit(ST_CONFIGURATION_ERROR);
}
while (1) {
n = fread(&buf, 1, 1024, file);
buffer = talloc_realloc(conf, buffer, uint8_t, size + n);
memcpy(buffer + size, buf, n);
size += n;
if (n < 1024)
break;
}
fclose(file);
res = rsa_keypair_from_sexp(pub, priv, 0, size, buffer);
conf->public_key = pub;
conf->private_key = priv;
return res;
}
STATUS read_configuration_file(TALLOC_CTX *mem_ctx) STATUS read_configuration_file(TALLOC_CTX *mem_ctx)
{ {
GError *error = NULL; GError *error = NULL;
GKeyFile *keyfile = g_key_file_new (); char *buf, *ptr;
if (!g_key_file_load_from_file (keyfile, CONFIGFILE, 0, &error)) {
g_error (error->message);
return ST_CONFIGURATION_ERROR;
}
conf = talloc(mem_ctx, configuration); conf = talloc(mem_ctx, configuration);
NO_MEM_RETURN(conf); NO_MEM_RETURN(conf);
conf->database_host = g_key_file_get_string(keyfile, "database", conf->keyfile = g_key_file_new ();
"host", &error);
if (error) { if (!g_key_file_load_from_file (conf->keyfile, CONFIGFILE, 0, &error)) {
fprintf(stderr, "No database host supplied in the configuration.\n"); g_error (error->message);
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; return ST_CONFIGURATION_ERROR;
} }
conf->log_file = g_key_file_get_string(keyfile, "siahsd", "log file", &error); buf = g_key_file_get_string(conf->keyfile, "siahsd", "event handlers", &error);
if (error) { if (error) {
fprintf(stderr, "No log file supplied in the configuration.\n"); fprintf(stderr, "No log file supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR; return ST_CONFIGURATION_ERROR;
} }
conf->log_level = g_key_file_get_integer(keyfile, "siahsd", "log level", &error);
DEBUG(0, "%s\n", buf);
/* Initialize the required event handler backends */
ptr = strtok(buf, " ");
if (ptr != NULL) {
do {
DEBUG(0, "%s\n", ptr);
if (strcmp(ptr, "database") == 0) {
database_init();
} else if (strcmp(ptr, "jsonbot") == 0) {
jsonbot_init();
}
} while((ptr = strtok(NULL, " ")) != NULL);
}
conf->log_file = g_key_file_get_string(conf->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(conf->keyfile, "siahsd", "log level", &error);
if (error) { if (error) {
fprintf(stderr, "No log level supplied in the configuration.\n"); fprintf(stderr, "No log level supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR; return ST_CONFIGURATION_ERROR;
} }
conf->pid_file = g_key_file_get_string(keyfile, "siahsd", "pid file", &error); conf->pid_file = g_key_file_get_string(conf->keyfile, "siahsd", "pid file", &error);
if (error) { if (error) {
fprintf(stderr, "No pid file supplied in the configuration.\n"); fprintf(stderr, "No pid file supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR; return ST_CONFIGURATION_ERROR;
} }
conf->jsonbot_address = g_key_file_get_string(keyfile, "jsonbot", "address", &error);
if (error) { conf->foreground = g_key_file_get_boolean(conf->keyfile, "siahsd", "foreground", &error);
fprintf(stderr, "No jsonbot address supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->jsonbot_port = g_key_file_get_integer(keyfile, "jsonbot", "port", &error);
if (error) {
fprintf(stderr, "No jsonbot port supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->jsonbot_aeskey = g_key_file_get_string(keyfile, "jsonbot", "aes key", &error);
if (error) {
fprintf(stderr, "No jsonbot aes key supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->jsonbot_password = g_key_file_get_string(keyfile, "jsonbot", "password", &error);
if (error) {
fprintf(stderr, "No jsonbot password supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->jsonbot_privmsg_to = g_key_file_get_string(keyfile, "jsonbot", "privmsg to", &error);
if (error) {
fprintf(stderr, "No jsonbot privsmg to supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->foreground = g_key_file_get_boolean(keyfile, "siahsd", "foreground", &error);
if (error) { if (error) {
conf->foreground = false; conf->foreground = false;
} }
/* Optional parameters are protocol-specific */
conf->siahs_port = g_key_file_get_integer(keyfile, "siahs", "port", &error);
conf->secip_port = g_key_file_get_integer(keyfile, "secip", "port", &error);
conf->rsa_key_file = g_key_file_get_string(keyfile, "secip", "rsa key file", &error);
/* Optional parameters are protocol-specific */
/* FIXME Warn the user when these aren't configured */
conf->siahs_port = g_key_file_get_integer(conf->keyfile, "siahs", "port", &error);
conf->secip_port = g_key_file_get_integer(conf->keyfile, "secip", "port", &error);
conf->rsa_key_file = g_key_file_get_string(conf->keyfile, "secip", "rsa key file", &error);
return ST_OK; return ST_OK;
} }

View file

@ -18,30 +18,49 @@
#define CONFIGFILE "/etc/siahsd.conf" #define CONFIGFILE "/etc/siahsd.conf"
typedef STATUS (*event_function)(TALLOC_CTX *mem_ctx, const char *prom, const char *code, const char *description);
typedef struct { typedef struct {
/* Global configuration */
char *log_file;
gint log_level;
gboolean foreground;
char *pid_file; /* FIXME Apparently the same for siahs and secip.. for now */
/* Alphatronics SIA-HS configuration */
gint siahs_port;
/* Vebon SecIP configuration */
gint secip_port;
char *rsa_key_file;
/* Database client configuration */
char *database_host; char *database_host;
char *database_username; char *database_username;
char *database_password; char *database_password;
char *database_name; char *database_name;
char *database_driver; char *database_driver;
gint siahs_port;
char *log_file; /* JSONbot client configuration */
gint log_level;
gboolean foreground;
char *pid_file;
gint secip_port;
char *rsa_key_file;
char *jsonbot_address; char *jsonbot_address;
gint jsonbot_port; gint jsonbot_port;
char *jsonbot_aeskey; char *jsonbot_aeskey;
char *jsonbot_password; char *jsonbot_password;
char *jsonbot_privmsg_to; char *jsonbot_privmsg_to;
/* Global configuration based state */
GKeyFile *keyfile;
uint8_t event_handler_cnt;
event_function *event_handlers;
struct rsa_public_key *public_key;
struct rsa_private_key *private_key;
} configuration; } configuration;
const configuration *get_conf(void); const configuration *get_conf(void);
STATUS get_rsa_keys(struct rsa_public_key **pub, struct rsa_private_key **priv); configuration *get_modifiable_conf(void);
STATUS set_rsa_keys(struct rsa_public_key *pub, struct rsa_private_key *priv);
STATUS read_rsa_keys(void);
const char *get_process_name(void); const char *get_process_name(void);
STATUS set_process_name(const char *name); STATUS set_process_name(const char *name);

View file

@ -18,6 +18,8 @@
#include "includes.h" #include "includes.h"
static dbi_conn conn;
/* /*
* talloc_quoted_string escapes quotes in a string and encapsulates it in quotes. * talloc_quoted_string escapes quotes in a string and encapsulates it in quotes.
* It returns a pointer to talloc'ed memory, the quoted string. * It returns a pointer to talloc'ed memory, the quoted string.
@ -45,7 +47,7 @@ static char *talloc_quoted_string(TALLOC_CTX *mem_ctx, const char *string) {
return ret; return ret;
} }
STATUS log_event_to_database(TALLOC_CTX *mem_ctx, dbi_conn conn, const char *prom, const char *code, const char *description) { STATUS log_event_to_database(TALLOC_CTX *mem_ctx, const char *prom, const char *code, const char *description) {
char *quoted_prom; char *quoted_prom;
char *quoted_code; char *quoted_code;
char *quoted_long_code; char *quoted_long_code;
@ -73,22 +75,60 @@ STATUS log_event_to_database(TALLOC_CTX *mem_ctx, dbi_conn conn, const char *pro
return ST_OK; return ST_OK;
} }
STATUS connect_to_database(dbi_conn *conn)
STATUS database_init(void)
{ {
const configuration *conf = get_conf(); configuration *conf = get_modifiable_conf();
GError *error = NULL;
conf->database_host = g_key_file_get_string(conf->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(conf->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(conf->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(conf->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(conf->keyfile, "database",
"password", &error);
if (error) {
fprintf(stderr, "No database password supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->event_handlers = talloc_realloc(conf, conf->event_handlers, event_function, conf->event_handler_cnt+1);
conf->event_handlers[conf->event_handler_cnt] = log_event_to_database;
conf->event_handler_cnt++;
DEBUG(1, "Connecting to %s database %s at %s as user %s", conf->database_driver, DEBUG(1, "Connecting to %s database %s at %s as user %s", conf->database_driver,
conf->database_name, conf->database_host, conf->database_username); conf->database_name, conf->database_host, conf->database_username);
dbi_initialize(NULL); dbi_initialize(NULL);
*conn = dbi_conn_new(conf->database_driver); conn = dbi_conn_new(conf->database_driver);
dbi_conn_set_option(*conn, "host", conf->database_host); dbi_conn_set_option(conn, "host", conf->database_host);
dbi_conn_set_option(*conn, "username", conf->database_username); dbi_conn_set_option(conn, "username", conf->database_username);
dbi_conn_set_option(*conn, "password", conf->database_password); dbi_conn_set_option(conn, "password", conf->database_password);
dbi_conn_set_option(*conn, "dbname", conf->database_name); dbi_conn_set_option(conn, "dbname", conf->database_name);
dbi_conn_set_option(*conn, "encoding", "UTF-8"); dbi_conn_set_option(conn, "encoding", "UTF-8");
if (dbi_conn_connect(*conn) < 0) { if (dbi_conn_connect(conn) < 0) {
DEBUG(0, "Could not connect to the database"); DEBUG(0, "Could not connect to the database");
return ST_DATABASE_FAILURE; return ST_DATABASE_FAILURE;
} }

View file

@ -16,5 +16,5 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
STATUS log_event_to_database(TALLOC_CTX *mem_ctx, dbi_conn conn, const char *prom, const char *code, const char *description); STATUS log_event_to_database(TALLOC_CTX *mem_ctx, const char *prom, const char *code, const char *description);
STATUS connect_to_database(dbi_conn *conn); STATUS database_init(void);

View file

@ -21,7 +21,7 @@
#include <nettle/aes.h> #include <nettle/aes.h>
STATUS jsonbot_notify(TALLOC_CTX *mem_ctx, dbi_conn conn, const char *prom, const char *code, const char *description) STATUS jsonbot_notify(TALLOC_CTX *mem_ctx, const char *prom, const char *code, const char *description)
{ {
int sockfd; int sockfd;
struct sockaddr_in servaddr; struct sockaddr_in servaddr;
@ -77,3 +77,40 @@ STATUS jsonbot_notify(TALLOC_CTX *mem_ctx, dbi_conn conn, const char *prom, cons
return ST_OK; return ST_OK;
} }
STATUS jsonbot_init(void) {
GError *error = NULL;
configuration *conf = get_modifiable_conf();
conf->jsonbot_address = g_key_file_get_string(conf->keyfile, "jsonbot", "address", &error);
if (error) {
fprintf(stderr, "No jsonbot address supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->jsonbot_port = g_key_file_get_integer(conf->keyfile, "jsonbot", "port", &error);
if (error) {
fprintf(stderr, "No jsonbot port supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->jsonbot_aeskey = g_key_file_get_string(conf->keyfile, "jsonbot", "aes key", &error);
if (error) {
fprintf(stderr, "No jsonbot aes key supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->jsonbot_password = g_key_file_get_string(conf->keyfile, "jsonbot", "password", &error);
if (error) {
fprintf(stderr, "No jsonbot password supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->jsonbot_privmsg_to = g_key_file_get_string(conf->keyfile, "jsonbot", "privmsg to", &error);
if (error) {
fprintf(stderr, "No jsonbot privsmg to supplied in the configuration.\n");
return ST_CONFIGURATION_ERROR;
}
conf->event_handlers = talloc_realloc(conf, conf->event_handlers, event_function, conf->event_handler_cnt+1);
conf->event_handlers[conf->event_handler_cnt] = jsonbot_notify;
conf->event_handler_cnt++;
return ST_OK;
}

View file

@ -18,4 +18,5 @@
*/ */
STATUS jsonbot_notify(TALLOC_CTX *mem_ctx, dbi_conn conn, const char *prom, const char *code, const char *description); STATUS jsonbot_notify(TALLOC_CTX *mem_ctx, const char *prom, const char *code, const char *description);
STATUS jsonbot_init(void);

View file

@ -18,55 +18,15 @@
#include "includes.h" #include "includes.h"
#include "build/ndr_secip.h" #include "build/ndr_secip.h"
static int read_rsa_keys(void) {
int res;
FILE *file;
uint8_t buf[1024];
struct rsa_private_key *priv;
struct rsa_public_key *pub;
const configuration *conf = get_conf();
uint8_t *buffer = NULL;
size_t n, size=0;
priv = talloc(conf, struct rsa_private_key); static STATUS send_ppk_com(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct secip_packet *pkt) {
pub = talloc(conf, struct rsa_public_key);
rsa_public_key_init (pub);
rsa_private_key_init (priv);
file = fopen(conf->rsa_key_file, "r");
if (file == NULL) {
DEBUG(0, "Can't open configured rsa key file: %s", conf->rsa_key_file);
exit(ST_CONFIGURATION_ERROR);
}
while (1) {
n = fread(&buf, 1, 1024, file);
buffer = talloc_realloc(conf, buffer, uint8_t, size + n);
memcpy(buffer + size, buf, n);
size += n;
if (n < 1024)
break;
}
fclose(file);
res = rsa_keypair_from_sexp(pub, priv, 0, size, buffer);
set_rsa_keys(pub, priv);
return res;
}
STATUS send_ppk_com(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct secip_packet *pkt) {
struct secip_setup_packet *setup_pkt; struct secip_setup_packet *setup_pkt;
struct secip_out_packet *ppk_com; struct secip_out_packet *ppk_com;
DATA_BLOB raw_pkt, raw_setup_pkt; DATA_BLOB raw_pkt, raw_setup_pkt;
enum ndr_err_code ndr_err; enum ndr_err_code ndr_err;
size_t n; size_t n;
struct rsa_private_key *priv;
struct rsa_public_key *pub;
size_t count; size_t count;
const configuration *conf = get_conf();
setup_pkt = talloc_zero(mem_ctx, struct secip_setup_packet); setup_pkt = talloc_zero(mem_ctx, struct secip_setup_packet);
@ -78,9 +38,7 @@ STATUS send_ppk_com(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, stru
memcpy(ppk_com->device_id, "MyFirstAlarm[TM]", strlen("MyFirstAlarm[TM]")); memcpy(ppk_com->device_id, "MyFirstAlarm[TM]", strlen("MyFirstAlarm[TM]"));
ppk_com->msg.ppk_com.session_id = 0; ppk_com->msg.ppk_com.session_id = 0;
get_rsa_keys(&pub, &priv); mpz_export(&ppk_com->msg.ppk_com.rsa_key, &count, 1, 4, 1, 0, conf->public_key->n);
mpz_export(&ppk_com->msg.ppk_com.rsa_key, &count, 1, 4, 1, 0, pub->n);
DEBUG(0, "RSA Words written: %u", count); DEBUG(0, "RSA Words written: %u", count);
printf("%s\n", ndr_print_struct_string(pkt,(ndr_print_fn_t)ndr_print_secip_out_packet, "ppk_com packet", ppk_com)); printf("%s\n", ndr_print_struct_string(pkt,(ndr_print_fn_t)ndr_print_secip_out_packet, "ppk_com packet", ppk_com));
@ -116,7 +74,6 @@ int main (int argc, char **argv) {
struct sockaddr_in server; struct sockaddr_in server;
struct sockaddr_in from; struct sockaddr_in from;
TALLOC_CTX *mem_ctx; TALLOC_CTX *mem_ctx;
dbi_conn conn;
STATUS rv; STATUS rv;
FILE *pidfile; FILE *pidfile;
pid_t pid; pid_t pid;
@ -176,11 +133,6 @@ int main (int argc, char **argv) {
DEBUG(0, "Started %s and waiting for SecIP packets on port %d", DEBUG(0, "Started %s and waiting for SecIP packets on port %d",
get_process_name(), conf->secip_port); get_process_name(), conf->secip_port);
/* Open a connection to the database */
rv = connect_to_database(&conn);
if (rv != ST_OK)
return rv;
/* /*
* Wait for packets * Wait for packets
*/ */

View file

@ -34,12 +34,14 @@
* and writes the event to the database. * and writes the event to the database.
* It returns nothing. * It returns nothing.
*/ */
STATUS parse_message(TALLOC_CTX *mem_ctx, dbi_conn conn, struct siahs_packet *pkt) { STATUS parse_message(TALLOC_CTX *mem_ctx, struct siahs_packet *pkt) {
char *message = talloc_strdup(mem_ctx, pkt->message + strlen("MESSAGE ")); char *message = talloc_strdup(mem_ctx, pkt->message + strlen("MESSAGE "));
char *ptr = message; char *ptr = message;
char *prom = ptr; char *prom = ptr;
char *pkt_prom; char *pkt_prom;
char *code; char *code;
const configuration *conf = get_conf();
uint8_t i;
NO_MEM_RETURN(message); NO_MEM_RETURN(message);
@ -75,8 +77,10 @@ STATUS parse_message(TALLOC_CTX *mem_ctx, dbi_conn conn, struct siahs_packet *pk
return ST_OK; return ST_OK;
} }
log_event_to_database(message, conn, prom, code, ptr); /* Dispatch all configured event handlers */
jsonbot_notify(message, conn, prom, code, ptr); for (i = 0; conf->event_handlers[i] != NULL; i++) {
conf->event_handlers[i](message, prom, code, ptr);
}
talloc_free(message); talloc_free(message);
@ -156,7 +160,6 @@ int main(int argc, char **argv) {
struct sockaddr_in server; struct sockaddr_in server;
struct sockaddr_in from; struct sockaddr_in from;
TALLOC_CTX *mem_ctx; TALLOC_CTX *mem_ctx;
dbi_conn conn;
STATUS rv; STATUS rv;
FILE *pidfile; FILE *pidfile;
pid_t pid; pid_t pid;
@ -216,11 +219,6 @@ int main(int argc, char **argv) {
DEBUG(0, "Started %s and waiting for SIA-HS packets on port %d", DEBUG(0, "Started %s and waiting for SIA-HS packets on port %d",
get_process_name(), conf->siahs_port); get_process_name(), conf->siahs_port);
/* Open a connection to the database */
rv = connect_to_database(&conn);
if (rv != ST_OK)
return rv;
/* /*
* Wait for packets * Wait for packets
*/ */
@ -306,7 +304,7 @@ int main(int argc, char **argv) {
} else if (strncmp(pkt->message, "MESSAGE ", strlen("MESSAGE ")) == 0) { } else if (strncmp(pkt->message, "MESSAGE ", strlen("MESSAGE ")) == 0) {
send_reply(pkt, sock, from, pkt, "ACKNOWLEDGE MESSAGE"); send_reply(pkt, sock, from, pkt, "ACKNOWLEDGE MESSAGE");
parse_message(pkt, conn, pkt); parse_message(pkt, pkt);
} else { } else {
DEBUG(0, "Could not parse this message:\n" DEBUG(0, "Could not parse this message:\n"

View file

@ -3,6 +3,7 @@ pid file = /var/run/siahsd.pid
log file = /var/log/siahsd/siahsd.log log file = /var/log/siahsd/siahsd.log
log level = 3 log level = 3
foreground = 1 foreground = 1
event handlers = database jsonbot
[database] [database]
driver = mysql driver = mysql

View file

@ -33,9 +33,12 @@ STATUS debug(int loglevel, const char *location, const char *function, ...)
} }
logfile = fopen(conf->log_file, "a"); logfile = fopen(conf->log_file, "a");
if (logfile == NULL && conf->foreground) { if (logfile == NULL) {
if (conf->foreground) {
fprintf(stderr, "Error opening log file: %s\n", strerror(errno)); fprintf(stderr, "Error opening log file: %s\n", strerror(errno));
} }
return ST_GENERAL_FAILURE;
}
time(&rawtime); time(&rawtime);
timeinfo = localtime(&rawtime); timeinfo = localtime(&rawtime);

View file

@ -90,7 +90,7 @@ def configure(conf):
def build(bld): def build(bld):
bld.stlib(source="database.c", target="database", use='glib-2.0') bld.stlib(source="database.c", target="database", use='glib-2.0')
bld.stlib(source="status.c", target="status", use='glib-2.0') bld.stlib(source="status.c", target="status", use='glib-2.0')
bld.stlib(source="config.c", target="config", use='glib-2.0') bld.stlib(source="config.c", target="config", use='glib-2.0 database jsonbot')
bld.stlib(source="sia.c", target="sia", use='glib-2.0') bld.stlib(source="sia.c", target="sia", use='glib-2.0')
bld.stlib(source="jsonbot.c", target="jsonbot", use='glib-2.0') bld.stlib(source="jsonbot.c", target="jsonbot", use='glib-2.0')