new configfile.[ch] & logging.[ch]

This commit is contained in:
Olaf Rempel 2007-03-31 22:15:00 +02:00
parent 576960f682
commit 042b7ce9a0
12 changed files with 329 additions and 332 deletions

View File

@ -28,59 +28,130 @@
#include <arpa/inet.h>
#include "configfile.h"
#include "helper.h"
#include "list.h"
#include "logging.h"
#define BUFSIZE 1024
struct conf_section {
struct list_head list;
struct list_head tupel_list;
const char *name;
};
struct conf_tupel {
struct list_head list;
const char *option;
const char *parameter;
};
static LIST_HEAD(config_list);
static struct conf_section * config_add_section(char *name)
static struct conf_section * config_add_section(const char *name)
{
struct conf_section *section;
if (!name)
section = malloc(sizeof(struct conf_section) + strlen(name));
if (section == NULL)
return NULL;
section = malloc(sizeof(struct conf_section));
if (section) {
INIT_LIST_HEAD(&section->list);
INIT_LIST_HEAD(&section->tupel);
INIT_LIST_HEAD(&section->list);
INIT_LIST_HEAD(&section->tupel_list);
strncpy(section->name, name, sizeof(section->name));
list_add_tail(&section->list, &config_list);
section->name = strdup(name);
if (section->name == NULL) {
free(section);
return NULL;
}
list_add_tail(&section->list, &config_list);
return section;
}
static int config_add_tupel(struct conf_section *section, char *option, char *parameter)
static int config_add_tupel(struct conf_section *section, const char *option, const char *parameter)
{
struct conf_tupel *tupel;
if (!section || !option || !parameter)
return 0;
if (!(tupel = malloc(sizeof(struct conf_tupel))))
return 0;
struct conf_tupel *tupel = malloc(sizeof(struct conf_tupel));
if (tupel == NULL)
return -1;
INIT_LIST_HEAD(&tupel->list);
tupel->option = strdup(option);
tupel->parameter = strdup(parameter);
list_add_tail(&tupel->list, &section->tupel);
return 1;
if (tupel->option == NULL || tupel->parameter == NULL) {
free(tupel);
return -1;
}
list_add_tail(&tupel->list, &section->tupel_list);
return 0;
}
static void config_free(void)
int config_parse(const char *config)
{
FILE *fz = fopen(config, "r");
if (fz == NULL) {
log_print(LOG_ERROR, "config_parse(): %s", config);
return -1;
}
char *line = malloc(BUFSIZE);
if (line == NULL) {
log_print(LOG_ERROR, "config_parse(): out of memory");
fclose(fz);
return -1;
}
int linenum = 0;
struct conf_section *section = NULL;
while (fgets(line, BUFSIZE, fz) != NULL) {
linenum++;
if (line[0] == '#' || line[0] <= ' ') {
continue;
} else if (line[0] == '[') {
char *tok = strtok(line +1, " ]\n");
if (tok == NULL || (section = config_add_section(tok)) == NULL) {
log_print(LOG_WARN, "config_parse(): invalid section in row %d", linenum);
free(line);
fclose(fz);
return -1;
}
continue;
} else if (section == NULL) {
log_print(LOG_WARN, "config_parse(): missing section in row %d", linenum);
free(line);
fclose(fz);
return -1;
}
char *tok = strtok(line, " \n");
if (tok != NULL) {
char *tok2;
while ((tok2 = strtok(NULL, " \n"))) {
if (config_add_tupel(section, tok, tok2) != 0)
log_print(LOG_WARN, "config_parse(): invalid row %d", linenum);
}
}
}
fclose(fz);
free(line);
return 0;
}
void config_free(void)
{
struct conf_section *section, *section_tmp;
struct conf_tupel *tupel, *tupel_tmp;
list_for_each_entry_safe(section, section_tmp, &config_list, list) {
list_for_each_entry_safe(tupel, tupel_tmp, &section->tupel, list) {
list_for_each_entry_safe(tupel, tupel_tmp, &section->tupel_list, list) {
list_del(&tupel->list);
free(tupel->option);
free(tupel->parameter);
free((char *)tupel->option);
free((char *)tupel->parameter);
free(tupel);
}
list_del(&section->list);
@ -88,66 +159,7 @@ static void config_free(void)
}
}
int config_parse(char *config)
{
struct conf_section *section = NULL;
FILE *fz;
int i = 0, ret = 1;
char *row, *tok, *tok2;
if (!config)
return 0;
if (!(row = malloc(1024)))
return 0;
if (!(fz = fopen(config, "r"))) {
log_print(LOG_ERROR, "config_parse(): %s", config);
return 0;
}
while (fgets(row, 1024, fz)) {
i++;
if (row[0] == '#' || row[0] <= ' ') {
continue;
} else if (row[0] == '[') {
tok = strtok(row +1, " ]\n");
section = config_add_section(tok);
if (!section) {
log_print(LOG_WARN, "config_parse(): invalid section in row %d", i);
ret = 0;
break;
}
continue;
} else if (!section) {
log_print(LOG_WARN, "config_parse(): missing section in row %d", i);
ret = 0;
break;
}
if ((tok = strtok(row, " \n"))) {
while ((tok2 = strtok(NULL, " \n"))) {
if (!config_add_tupel(section, tok, tok2))
log_print(LOG_WARN, "config_parse(): invalid row %d", i);
}
}
}
fclose(fz);
free(row);
if (atexit(config_free) != 0) {
log_print(LOG_ERROR, "config_parse(): atexit()");
return 0;
}
return ret;
}
struct conf_section * config_get_section(char *name)
static struct conf_section * config_get_section(const char *name)
{
struct conf_section *section;
@ -158,51 +170,48 @@ struct conf_section * config_get_section(char *name)
return NULL;
}
char * config_get_parameter(struct conf_section *section, char *option)
const char * config_get_string(const char *section_str, const char *option, const char *def)
{
struct conf_tupel *tupel;
list_for_each_entry(tupel, &section->tupel, list) {
if (!strcmp(tupel->option, option))
return tupel->parameter;
struct conf_section *section = config_get_section(section_str);
if (section != NULL) {
struct conf_tupel *tupel;
list_for_each_entry(tupel, &section->tupel_list, list) {
if (!strcmp(tupel->option, option))
return tupel->parameter;
}
}
return NULL;
}
char * config_get_string(char *section, char *option, char *def)
{
struct conf_section *tmp;
char *ret;
tmp = config_get_section(section);
if (tmp && (ret = config_get_parameter(tmp, option)))
return ret;
if (def != NULL)
log_print(LOG_WARN, "config [%s:%s] not found, using default: '%s'",
section_str, option, def);
return def;
}
int config_get_int(char *section, char *option, int def)
int config_get_int(const char *section, const char *option, int def)
{
char *ret;
ret = config_get_string(section, option, NULL);
return ret ? atoi(ret) : def;
const char *ret = config_get_string(section, option, NULL);
if (ret == NULL) {
log_print(LOG_WARN, "config [%s:%s] not found, using default: '%d'",
section, option, def);
return def;
}
return atoi(ret);
}
int config_get_saddr(char *section, char *option, struct sockaddr_in *sa)
int config_get_strings(const char *section_str, const char *option,
int (*callback)(const char *value, void *privdata),
void *privdata)
{
char *ret, *part[2];
ret = config_get_string(section, option, NULL);
if (ret == NULL)
struct conf_section *section = config_get_section(section_str);
if (section == NULL)
return -1;
if (strsplit(ret, ":", part, 2) != 2)
return -1;
sa->sin_family = AF_INET;
sa->sin_port = htons(atoi(part[1]));
inet_aton(part[0], &sa->sin_addr);
return 0;
int cnt = 0;
struct conf_tupel *tupel;
list_for_each_entry(tupel, &section->tupel_list, list) {
if (!strcmp(tupel->option, option))
if (callback(tupel->parameter, privdata) == 0)
cnt++;
}
return cnt;
}

View File

@ -1,27 +1,15 @@
#ifndef _CONFIG_H_
#define _CONFIG_H_
#include <netinet/in.h>
int config_parse(const char *config);
void config_free(void);
#include "list.h"
const char * config_get_string(const char *section_str, const char *option, const char *def);
struct conf_section {
struct list_head list;
char name[32];
struct list_head tupel;
};
int config_get_int(const char *section, const char *option, int def);
struct conf_tupel {
struct list_head list;
char *option;
char *parameter;
};
int config_parse(char *config);
struct conf_section * config_get_section(char *name);
char * config_get_parameter(struct conf_section *section, char *option);
char * config_get_string(char *section, char *option, char *def);
int config_get_int(char *section, char *option, int def);
int config_get_saddr(char *section, char *option, struct sockaddr_in *sa);
int config_get_strings(const char *section_str, const char *option,
int (*callback)(const char *value, void *privdata),
void *privdata);
#endif /* _CONFIG_H_ */

View File

@ -29,75 +29,74 @@
#define BUFSIZE 8192
static FILE *log_fd = NULL;
static int log_prio = LOG_EVERYTIME;
static char *buffer = NULL;
void log_print(int prio, const char *fmt, ...)
int log_print(int prio, const char *fmt, ...)
{
va_list az;
int len;
int len = 0, retval;
if (prio < log_prio)
return 0;
if (buffer == NULL) {
buffer = malloc(BUFSIZE);
if (buffer == NULL) {
fprintf(stderr, "log_print: out of memory\nBailing out!\n");
exit(-1);
fprintf(stderr, "log_print(): out of memory\n");
return -1;
}
}
if (log_fd != NULL) {
time_t tzgr;
time(&tzgr);
len += strftime(buffer, BUFSIZE, "%b %d %H:%M:%S :", localtime(&tzgr));
}
va_start(az, fmt);
len = vsnprintf(buffer, BUFSIZE, fmt, az);
len += vsnprintf(buffer + len, BUFSIZE - len, fmt, az);
va_end(az);
if (len < 0 || len >= BUFSIZE) {
log_print(LOG_ERROR, "log_print: arguments too long");
errno = 0;
return;
return log_print(LOG_ERROR, "log_print: arguments too long");
}
if (errno) {
strncpy(buffer + len, ": ", BUFSIZE - len);
len += 2;
strncpy(buffer + len, strerror(errno), BUFSIZE - len);
len += snprintf(buffer + len, BUFSIZE - len, ": %s", strerror(errno));
errno = 0;
}
if (log_fd) {
char tbuf[64];
time_t tzgr;
time(&tzgr);
strftime(tbuf, sizeof(tbuf), "%b %d %H:%M:%S :", localtime(&tzgr));
fprintf(log_fd, "%s %s\n", tbuf, buffer);
fflush(log_fd);
} else {
fprintf(stderr, "%s\n", buffer);
}
errno = 0;
retval = fprintf((log_fd ? log_fd : stderr), "%s\n", buffer);
fflush(log_fd);
return retval;
}
static void log_close(void)
void log_close(void)
{
if (buffer)
free(buffer);
fclose(log_fd);
if (log_fd)
fclose(log_fd);
}
int log_init(char *logfile)
int log_init(const char *logfile)
{
if (log_fd != NULL)
log_close();
log_fd = fopen(logfile, "a");
if (log_fd == NULL) {
log_print(LOG_ERROR, "log_open('%s'): %s", logfile);
return 0;
fprintf(stderr, "log_init(): can not open logfile");
return -1;
}
if (atexit(log_close) != 0) {
log_print(LOG_ERROR, "log_open(): atexit()");
return 0;
}
log_print(LOG_EVERYTIME, "==========================");
return 1;
return 0;
}
void log_setprio(int prio)
{
log_prio = prio;
}

View File

@ -10,7 +10,10 @@
#define LOG_EVERYTIME 0
int log_init(char *logfile);
void log_print(int prio, const char *fmt, ... );
int log_init(const char *logfile);
void log_close(void);
void log_setprio(int prio);
int log_print(int prio, const char *fmt, ... );
#endif /* _LOGGING_H_ */

View File

@ -24,7 +24,7 @@ static int fwd_sock;
static char *tx_buf, *rx_buf;
static int tx_pos;
int net_submit(char *hostname, char *plugin, char *filename, int ds_id, char *data)
int net_submit(const char *hostname, char *plugin, char *filename, int ds_id, char *data)
{
int size = snprintf(tx_buf + tx_pos, BUFSIZE - tx_pos, "%s:%s:%s:%d %s\n",
hostname, plugin, filename, ds_id, data);
@ -76,9 +76,27 @@ int net_receive(int socket)
return 0;
}
static int net_config_get_saddr(char *section, char *option, struct sockaddr_in *sa)
{
char *part[2];
const char *ret = config_get_string(section, option, NULL);
if (ret == NULL)
return -1;
if (strsplit(ret, ":", part, 2) != 2)
return -1;
sa->sin_family = AF_INET;
sa->sin_port = htons(atoi(part[1]));
inet_aton(part[0], &sa->sin_addr);
return 0;
}
int net_init_cli()
{
int ret = config_get_saddr("global", "forward", &fwd_sa);
int ret = net_config_get_saddr("global", "forward", &fwd_sa);
if (ret < 0)
return -1;
@ -104,7 +122,7 @@ int net_init_srv()
{
struct sockaddr_in sa_srv;
int ret = config_get_saddr("global", "listen", &sa_srv);
int ret = net_config_get_saddr("global", "listen", &sa_srv);
if (ret < 0)
return -1;

View File

@ -7,7 +7,7 @@ int net_init_srv();
int net_init_cli();
int net_receive(int sock);
int net_submit(char *hostname, char *plugin, char *filename, int ds_id, char *data);
int net_submit(const char *hostname, char *plugin, char *filename, int ds_id, char *data);
int net_submit_flush();
#endif /* _NETWORK_H_ */

View File

@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <curl/curl.h>
@ -118,6 +119,74 @@ static int probe(void)
return 0;
}
static int init_cb(const char *parameter, void *privdata)
{
char *part[4];
int ret = strsplit(parameter, ",", part, 4);
if (ret < 2) {
log_print(LOG_ERROR, "p_apache: parse error (1)");
return -1;
}
struct server_entry *entry = malloc(sizeof(struct server_entry));
if (entry == NULL) {
log_print(LOG_ERROR, "p_apache: out of memory");
return -1;
}
// reference config mem
entry->name = part[0];
entry->handle = curl_easy_init();
if (entry->handle == NULL) {
free(entry);
return -1;
}
ret = curl_easy_setopt(entry->handle, CURLOPT_URL, part[1]);
if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
curl_easy_cleanup(entry->handle);
free(entry);
return -1;
}
if (part[2] != NULL && part[3] != NULL) {
*(part[3] -1) = ':';
log_print(LOG_INFO, "p_apache: auth: '%s'", part[2]);
ret = curl_easy_setopt(entry->handle, CURLOPT_USERPWD, part[2]);
if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
curl_easy_cleanup(entry->handle);
free(entry);
return -1;
}
}
ret = curl_easy_setopt(entry->handle, CURLOPT_WRITEFUNCTION, &curl_callback);
if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
curl_easy_cleanup(entry->handle);
free(entry);
return -1;
}
ret = curl_easy_setopt(entry->handle, CURLOPT_WRITEDATA, entry);
if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
curl_easy_cleanup(entry->handle);
free(entry);
return -1;
}
log_print(LOG_INFO, "p_apache: added server '%s'", entry->name);
list_add_tail(&entry->list, &server_list);
return 0;
}
static int init(void)
{
rx_buf = malloc(BUFSIZE);
@ -126,82 +195,7 @@ static int init(void)
return -1;
}
struct conf_section *section;
section = config_get_section("p_apache");
if (section == NULL) {
log_print(LOG_ERROR, "p_apache: no config section found");
free(rx_buf);
return -1;
}
struct conf_tupel *tupel;
list_for_each_entry(tupel, &section->tupel, list) {
if (strcmp(tupel->option, "server"))
continue;
char *part[4];
int ret = strsplit(tupel->parameter, ",", part, 4);
if (ret < 2) {
log_print(LOG_ERROR, "p_apache: parse error (1)");
continue;
}
struct server_entry *entry = malloc(sizeof(struct server_entry));
if (entry == NULL) {
log_print(LOG_ERROR, "p_apache: out of memory");
continue;
}
// reference config mem
entry->name = part[0];
entry->handle = curl_easy_init();
if (entry->handle == NULL) {
free(entry);
continue;
}
ret = curl_easy_setopt(entry->handle, CURLOPT_URL, part[1]);
if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
curl_easy_cleanup(entry->handle);
free(entry);
continue;
}
if (part[2] != NULL && part[3] != NULL) {
*(part[3] -1) = ':';
log_print(LOG_INFO, "p_apache: auth: '%s'", part[2]);
ret = curl_easy_setopt(entry->handle, CURLOPT_USERPWD, part[2]);
if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
curl_easy_cleanup(entry->handle);
free(entry);
continue;
}
}
ret = curl_easy_setopt(entry->handle, CURLOPT_WRITEFUNCTION, &curl_callback);
if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
curl_easy_cleanup(entry->handle);
free(entry);
continue;
}
ret = curl_easy_setopt(entry->handle, CURLOPT_WRITEDATA, entry);
if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
curl_easy_cleanup(entry->handle);
free(entry);
continue;
}
log_print(LOG_INFO, "p_apache: added server '%s'", entry->name);
list_add_tail(&entry->list, &server_list);
}
config_get_strings("p_apache", "server", init_cb, NULL);
return 0;
}

View File

@ -148,44 +148,37 @@ static int probe(void)
return 0;
}
static int init(void)
static int init_cb(const char *parameter, void *privdata)
{
struct conf_section *section;
section = config_get_section("p_mysql");
if (section == NULL) {
log_print(LOG_ERROR, "p_mysql: no config section found");
char *part[4];
int ret = strsplit(parameter, ",", part, 4);
if (ret != 4) {
log_print(LOG_ERROR, "p_mysql: parse error");
return -1;
}
struct conf_tupel *tupel;
list_for_each_entry(tupel, &section->tupel, list) {
if (strcmp(tupel->option, "server"))
continue;
void *mysql = init_connection(part[1], part[2], part[3]);
if (mysql == NULL)
return -1;
char *part[4];
int ret = strsplit(tupel->parameter, ",", part, 4);
if (ret != 4) {
log_print(LOG_ERROR, "p_mysql: parse error");
continue;
}
void *mysql = init_connection(part[1], part[2], part[3]);
if (mysql == NULL)
continue;
struct server_entry *entry = malloc(sizeof(struct server_entry));
if (entry == NULL) {
log_print(LOG_ERROR, "p_mysql: out of memory");
close_connection(mysql);
continue;
}
entry->name = part[0];
entry->mysql = mysql;
log_print(LOG_DEBUG, "p_mysql: added server '%s'", entry->name);
list_add_tail(&entry->list, &server_list);
struct server_entry *entry = malloc(sizeof(struct server_entry));
if (entry == NULL) {
log_print(LOG_ERROR, "p_mysql: out of memory");
close_connection(mysql);
return -1;
}
entry->name = part[0];
entry->mysql = mysql;
log_print(LOG_DEBUG, "p_mysql: added server '%s'", entry->name);
list_add_tail(&entry->list, &server_list);
return 0;
}
static int init(void)
{
config_get_strings("p_mysql", "server", init_cb, NULL);
return 0;
}

View File

@ -39,10 +39,10 @@ static LIST_HEAD(plugin_list);
static int plugin_flags;
static int plugin_load(char *filename)
static int plugin_init_cb(const char *filename, void *privdata)
{
struct sammler_plugin *plugin = NULL;
static char *plugin_dir;
static const char *plugin_dir;
char *buffer;
void *tmp;
@ -95,16 +95,7 @@ static int plugin_load(char *filename)
void plugin_init(int flags)
{
struct conf_section *section;
section = config_get_section("global");
if (section == NULL)
return;
struct conf_tupel *tupel;
list_for_each_entry(tupel, &section->tupel, list)
if (!strcmp(tupel->option, "plugin"))
plugin_load(tupel->parameter);
config_get_strings("global", "plugin", plugin_init_cb, NULL);
plugin_flags = flags;
}
@ -139,7 +130,7 @@ struct sammler_plugin * plugin_lookup(char *name)
int probe_submit(struct sammler_plugin *plugin, char *filename, int ds_id, const char *fmt, ... )
{
static char *hostname = NULL;
static const char *hostname = NULL;
va_list az;
char *buffer;

View File

@ -42,33 +42,35 @@
#define BUFSIZE 1024
static int append_rra_config(char *buffer, int size, int *pos)
struct rra_cb_data {
char *buffer;
int size;
int *pos;
};
static int append_rra_config_cb(const char *parameter, void *privdata)
{
struct conf_section *section;
struct conf_tupel *tupel;
struct rra_cb_data *data = (struct rra_cb_data *)privdata;
int len, rra_cnt = 0;
section = config_get_section("global");
if (section == NULL) {
log_print(LOG_ERROR, "append_ds_config: conf-section 'global' not found");
int len = snprintf(data->buffer + *(data->pos), data->size - *(data->pos), "%s ", parameter);
if (len < 0 || len >= data->size - *(data->pos)) {
log_print(LOG_ERROR, "append_rra_config_cb: arguments too long");
return -1;
}
list_for_each_entry(tupel, &section->tupel, list) {
if (strcmp(tupel->option, "rra"))
continue;
*(data->pos) += len;
return 0;
}
len = snprintf(buffer + *pos, size - *pos, "%s ", tupel->parameter);
if (len < 0 || len >= size - *pos) {
log_print(LOG_ERROR, "append_ds_config: arguments too long");
return -1;
}
static int append_rra_config(char *buffer, int size, int *pos)
{
struct rra_cb_data data = {
.buffer = buffer,
.size = size,
.pos = pos,
};
*pos += len;
rra_cnt++;
}
return rra_cnt;
return config_get_strings("global", "rra", append_rra_config_cb, &data);
}
static int do_rrd(int mode, char *cmd)
@ -226,10 +228,10 @@ static int create_parent_dirs(char *filename)
return 0;
}
int rrd_submit(char *hostname, char *plugin, char *filename, int ds_id, char *data)
int rrd_submit(const char *hostname, char *plugin, char *filename, int ds_id, char *data)
{
struct stat statbuf;
static char *rrd_dir = NULL;
static const char *rrd_dir = NULL;
char *fullfile;
int len;

View File

@ -2,7 +2,7 @@
#define _RRDTOOL_H_
#ifdef WITH_RRD
int rrd_submit(char *hostname, char *plugin, char *filename, int ds_id, char *data);
int rrd_submit(const char *hostname, char *plugin, char *filename, int ds_id, char *data);
#else
#define rrd_submit(hostname, plugin, filename, ds_id, data)
#endif

View File

@ -79,21 +79,21 @@ int main(int argc, char *argv[])
} while (code != -1);
/* parse config file */
if (!config_parse(config))
if (config_parse(config))
exit(-1);
/* check logfile */
char *logfile = config_get_string("global", "logfile", DEFAULT_LOGFILE);
const char *logfile = config_get_string("global", "logfile", DEFAULT_LOGFILE);
if (logfile != NULL && debug == 0) {
/* start logging */
if (!log_init(logfile))
if (log_init(logfile))
exit(-1);
/* zum daemon mutieren */
daemon(-1, 0);
}
char *hostname = config_get_string("global", "hostname", "localhost");
const char *hostname = config_get_string("global", "hostname", "localhost");
log_print(LOG_EVERYTIME, "sammler (pid:%d) started on host '%s'", getpid(), hostname);
fd_set fdsel, fdcpy;
@ -107,7 +107,7 @@ int main(int argc, char *argv[])
if (net_init_cli() != -1)
probe_flags |= PLUGIN_NET;
char *fwd_only = config_get_string("global", "forward_only", NULL);
const char *fwd_only = config_get_string("global", "forward_only", NULL);
if (fwd_only == NULL || strncmp(fwd_only, "true", 4))
probe_flags |= PLUGIN_RRD;