internal changes

This commit is contained in:
Olaf Rempel 2010-06-12 12:30:12 +02:00
parent 9ff2ebbffa
commit d38cbcc0c6
16 changed files with 496 additions and 125 deletions

View File

@ -17,9 +17,9 @@ WWW_OWNER = www-data
# ############################ # ############################
SRC := configfile.c event.c helper.c logging.c network.c pidfile.c plugins.c probe.c SRC := configfile.c event.c helper.c linebuffer.c logging.c network.c pidfile.c
SRC += sammler.c signals.c sockaddr.c SRC += plugins.c probe.c sammler.c signals.c sockaddr.c
CFLAGS := -O2 -Wall -MMD -fno-stack-protector -I. CFLAGS := -O2 -Wall -Wno-unused-result -MMD -fno-stack-protector -I.
LDFLAGS := -ldl -rdynamic LDFLAGS := -ldl -rdynamic
# ############################ # ############################

View File

@ -1,5 +1,5 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 07/2007 by Olaf Rempel * * Copyright (C) 03/2010 by Olaf Rempel *
* razzor@kopf-tisch.de * * razzor@kopf-tisch.de *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
@ -20,6 +20,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <ctype.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -126,10 +127,10 @@ int config_parse(const char *config)
return -1; return -1;
} }
char *tok = strtok(line, " \n"); char *tmp, *tok = strtok_r(line, " \t\n", &tmp);
if (tok != NULL) { if (tok != NULL) {
char *tok2; char *tok2;
while ((tok2 = strtok(NULL, " \n"))) { while ((tok2 = strtok_r(NULL, " \n", &tmp))) {
if (config_add_tupel(section, tok, tok2) != 0) if (config_add_tupel(section, tok, tok2) != 0)
log_print(LOG_WARN, "config_parse(): invalid row %d", linenum); log_print(LOG_WARN, "config_parse(): invalid row %d", linenum);
} }
@ -186,15 +187,29 @@ const char * config_get_string(const char *section_str, const char *option, cons
return def; return def;
} }
int config_get_int(const char *section, const char *option, int def) int config_get_int(const char *section, const char *option, int *value, int def)
{ {
const char *ret = config_get_string(section, option, NULL); const char *ret = config_get_string(section, option, NULL);
if (ret == NULL) { if (ret == NULL) {
log_print(LOG_WARN, "config [%s:%s] not found, using default: '%d'", log_print(LOG_WARN, "config [%s:%s] not found, using default: '%d'",
section, option, def); section, option, def);
return def;
*value = def;
return -1;
} }
return atoi(ret);
char *tmp;
*value = strtol(ret, &tmp, 0);
if (*tmp != '\0' && !isspace(*tmp)) {
log_print(LOG_WARN, "config [%s:%s] not an integer: '%s', using default '%d'",
section, option, ret, def);
*value = def;
return -1;
}
return 0;
} }
int config_get_strings(const char *section_str, const char *option, int config_get_strings(const char *section_str, const char *option,
@ -214,3 +229,65 @@ int config_get_strings(const char *section_str, const char *option,
} }
return cnt; return cnt;
} }
struct strtoken * strtokenize(const char *input, const char *delim, int maxfields)
{
struct strtoken *tokens = malloc(sizeof(struct strtoken) +
maxfields * sizeof(char *) +
strlen(input));
if (tokens == NULL)
return NULL;
char *ptr = (char *)&tokens->field[maxfields];
strcpy(ptr, input);
int i;
char *tmp;
tokens->count = 0;
for (i = 0; i < maxfields; i++) {
tokens->field[i] = strtok_r(ptr, delim, &tmp);
ptr = NULL;
if (tokens->field[i] != NULL)
tokens->count++;
}
return tokens;
}
struct strtoken * config_get_strtoken(const char *section, const char *option, const char *delim, int maxfields)
{
const char *ret = config_get_string(section, option, NULL);
if (ret == NULL) {
log_print(LOG_WARN, "config [%s:%s] not found", section, option);
return NULL;
}
return strtokenize(ret, delim, maxfields);
}
int config_get_strtokens(const char *section_str, const char *option, const char *delim, int maxfields,
int (*callback)(struct strtoken *data, void *privdata),
void *privdata)
{
struct conf_section *section = config_get_section(section_str);
if (section == NULL)
return -1;
int cnt = 0;
struct conf_tupel *tupel;
list_for_each_entry(tupel, &section->tupel_list, list) {
if (!strcmp(tupel->option, option)) {
struct strtoken *tokens = strtokenize(tupel->parameter, delim, maxfields);
if (tokens != NULL) {
if (callback(tokens, privdata) == 0)
cnt++;
free(tokens);
}
}
}
return cnt;
}

View File

@ -6,10 +6,23 @@ void config_free(void);
const char * config_get_string(const char *section_str, const char *option, const char *def); const char * config_get_string(const char *section_str, const char *option, const char *def);
int config_get_int(const char *section, const char *option, int def); int config_get_int(const char *section, const char *option, int *value, int def);
int config_get_strings(const char *section_str, const char *option, int config_get_strings(const char *section_str, const char *option,
int (*callback)(const char *value, void *privdata), int (*callback)(const char *value, void *privdata),
void *privdata); void *privdata);
struct strtoken {
int count;
char *field[0];
};
struct strtoken * strtokenize(const char *input, const char *delim, int maxfields);
struct strtoken * config_get_strtoken(const char *section_str, const char *option, const char *delim, int maxfields);
int config_get_strtokens(const char *section_str, const char *option, const char *delim, int maxfields,
int (*callback)(struct strtoken *tokens, void *privdata),
void *privdata);
#endif /* _CONFIG_H_ */ #endif /* _CONFIG_H_ */

33
event.c
View File

@ -1,5 +1,5 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 07/2007 by Olaf Rempel * * Copyright (C) 03/2010 by Olaf Rempel *
* razzor@kopf-tisch.de * * razzor@kopf-tisch.de *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
@ -20,6 +20,7 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
@ -30,7 +31,6 @@
static LIST_HEAD(event_fd_list); static LIST_HEAD(event_fd_list);
static LIST_HEAD(event_timeout_list); static LIST_HEAD(event_timeout_list);
static int leave_loop;
struct event_fd { struct event_fd {
struct list_head list; struct list_head list;
@ -199,12 +199,7 @@ void event_remove_timeout(struct event_timeout *entry)
entry->flags |= EVENT_DELETE; entry->flags |= EVENT_DELETE;
} }
void event_loop_break(void) int event_loop(int (*callback)(void *privdata), void *privdata)
{
leave_loop = 1;
}
int event_loop(void)
{ {
fd_set *fdsets = malloc(sizeof(fd_set) * 2); fd_set *fdsets = malloc(sizeof(fd_set) * 2);
if (fdsets == NULL) { if (fdsets == NULL) {
@ -212,8 +207,7 @@ int event_loop(void)
return -1; return -1;
} }
leave_loop = 0; while (1) {
while (!leave_loop) {
struct timeval timeout, *timeout_p = NULL; struct timeval timeout, *timeout_p = NULL;
if (!list_empty(&event_timeout_list)) { if (!list_empty(&event_timeout_list)) {
struct timeval now; struct timeval now;
@ -284,13 +278,20 @@ int event_loop(void)
maxfd = (entry->fd > maxfd) ? entry->fd : maxfd; maxfd = (entry->fd > maxfd) ? entry->fd : maxfd;
} }
/* exit loop if callback returns true */
if (callback != NULL && callback(privdata) != 0)
break;
int i = select(maxfd +1, readfds, writefds, NULL, timeout_p); int i = select(maxfd +1, readfds, writefds, NULL, timeout_p);
if (i <= 0) { if (i < 0 && errno == EINTR) {
/* On error, -1 is returned, and errno is set errno = 0;
* appropriately; the sets and timeout become continue;
* undefined, so do not rely on their contents
* after an error. } else if (i < 0) {
*/ log_print(LOG_ERROR, "event_loop(): select():");
continue;
} else if (i == 0) {
continue; continue;
} }

View File

@ -37,7 +37,6 @@ struct event_timeout * event_add_timeout(
void event_remove_timeout(struct event_timeout *entry); void event_remove_timeout(struct event_timeout *entry);
void event_loop_break(void); int event_loop(int (*callback)(void *privdata), void *privdata);
int event_loop(void);
#endif /* _EVENT_H_ */ #endif /* _EVENT_H_ */

239
linebuffer.c Normal file
View File

@ -0,0 +1,239 @@
/***************************************************************************
* Copyright (C) 03/2010 by Olaf Rempel *
* razzor@kopf-tisch.de *
* *
* 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; version 2 of the License *
* *
* 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, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include "linebuffer.h"
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
struct lbuf {
size_t size;
size_t pos;
char *token;
char data[0];
};
/*
* creates linebuffer with given size
*/
struct lbuf * lbuf_create(size_t size)
{
struct lbuf *buf = malloc(sizeof(struct lbuf) + size);
if (buf == NULL)
return NULL;
buf->size = size;
buf->pos = 0;
return buf;
}
/*
* frees the linebuffer and all data in it
*/
void lbuf_free(struct lbuf *buf)
{
free(buf);
}
/*
* clears the linebuffer
* - returns the datasize it was holding
*/
int lbuf_clear(struct lbuf *buf)
{
int oldpos = buf->pos;
buf->pos = 0;
return oldpos;
}
/*
* get pointer to internal data
* - returns pointer to datasize
*/
char * lbuf_getdata(struct lbuf *buf, size_t *len)
{
if (len != NULL)
*len = buf->pos;
return buf->data;
}
/*
* appends data to the buffer
* - returns the number of bytes copied
*/
int lbuf_append(struct lbuf *buf, const char *src, size_t size)
{
int len = MIN(buf->size - buf->pos, size);
memcpy(buf->data + buf->pos, src, len);
buf->pos += len;
return len;
}
/*
* reads as much data as it can get from a FD
* - returns the number of bytes read, or -1 on error
*/
int lbuf_readfd(struct lbuf *buf, int fd)
{
int len = read(fd, buf->data + buf->pos, buf->size - buf->pos);
if (len <= 0)
return -1;
buf->pos += len;
return len;
}
/*
* parses as much data as it can get from a FD
* parses means: backspaces remove one byte from the end of the buffer
* - returns 0 on success, or -1 on error
*/
int lbuf_parsefd(struct lbuf *buf, int fd)
{
char tmp[32];
int len = read(fd, tmp, sizeof(tmp));
if (len <= 0)
return -1;
int i;
for (i = 0; i < len; i++) {
/* "understand" backspace */
if (tmp[i] == 0x08 && buf->pos > 0) {
buf->pos--;
/* copy */
} else if (tmp[i] >= ' ' || tmp[i] == '\n') {
*(buf->data + buf->pos++) = tmp[i];
}
if (buf->pos > buf->size)
return -1;
}
/* TODO: return bytes appended to buffer? */
return 0;
}
/*
* writes as much data as it can to a FD
* - returns the number of bytes written, or -1 on error
*/
int lbuf_writefd(struct lbuf *buf, int fd)
{
int len = write(fd, buf->data, buf->pos);
if (len <= 0)
return -1;
/* handle partial writes */
if (len != buf->pos)
memmove(buf->data, buf->data + len, buf->pos - len);
buf->pos -= len;
return len;
}
/*
* append va_list to buffer
* - returns number ob bytes appended, or -1 on error
*/
int lbuf_vprintf(struct lbuf *buf, const char *fmt, va_list az)
{
int len = vsnprintf(buf->data + buf->pos, buf->size - buf->pos, fmt, az);
if (len < 0 || len >= (buf->size - buf->pos))
return -1;
buf->pos += len;
return len;
}
/*
* printf into buffer
* - returns number of bytes appended, or -1 on error
*/
int lbuf_printf(struct lbuf *buf, const char *fmt, ...)
{
va_list az;
va_start(az, fmt);
int ret = lbuf_vprintf(buf, fmt, az);
va_end(az);
return ret;
}
/*
* get next non-empty token
* - returns pointer to next token
* - returns NULL if no delimter is found in buffer
*/
char * lbuf_gettok(struct lbuf *buf, const char *delim)
{
char *start = buf->data;
char *end = buf->data + buf->pos;
int dlen = strlen(delim);
while (1) {
buf->token = NULL;
/* find first delimiter in buffer */
int i;
for (i = 0; i < dlen; i++) {
char *tok = memchr(start, delim[i], end - start);
if (tok != NULL && (tok < buf->token || buf->token == NULL))
buf->token = tok;
}
/* nothing found */
if (buf->token == NULL)
return NULL;
/* delimter found on start pos -> skip empty token */
if (buf->token == start) {
start++;
if (start >= end)
return NULL;
} else {
/* non-empty token found, exit */
break;
}
}
/* overwrite token, return start ptr */
*(buf->token) = '\0';
return start;
}
/*
* release previous fetched line
* - returns number of remaining bytes in buffer
*/
int lbuf_freetok(struct lbuf *buf)
{
if (buf->token != NULL) {
buf->pos -= (buf->token - buf->data) +1;
memmove(buf->data, buf->token +1, buf->pos);
buf->token = NULL;
}
return buf->pos;
}

27
linebuffer.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef _LINEBUFFER_H_
#define _LINEBUFFER_H_
#include <stdarg.h>
/* hide details */
struct lbuf;
struct lbuf * lbuf_create(size_t size);
void lbuf_free(struct lbuf *buf);
int lbuf_clear(struct lbuf *buf);
int lbuf_readfd(struct lbuf *buf, int fd);
int lbuf_parsefd(struct lbuf *buf, int fd);
int lbuf_writefd(struct lbuf *buf, int fd);
char * lbuf_getdata(struct lbuf *buf, size_t *len);
int lbuf_append(struct lbuf *buf, const char *src, size_t size);
int lbuf_vprintf(struct lbuf *buf, const char *fmt, va_list ap);
int lbuf_printf(struct lbuf *buf, const char *fmt, ...);
char * lbuf_gettok(struct lbuf *buf, const char *delim);
int lbuf_freetok(struct lbuf *buf);
#endif /* _LINEBUFFER_H_ */

View File

@ -44,6 +44,8 @@ pid_t pidfile_check(const char *filename, int remove_stale)
int len = read(fd, buf, sizeof(buf) -1); int len = read(fd, buf, sizeof(buf) -1);
buf[len] = '\0'; buf[len] = '\0';
close(fd);
char *tmp; char *tmp;
pid_t pid = strtol(buf, &tmp, 10); pid_t pid = strtol(buf, &tmp, 10);
if (len == 0 || tmp == buf) if (len == 0 || tmp == buf)

View File

@ -26,6 +26,7 @@
#include "configfile.h" #include "configfile.h"
#include "helper.h" #include "helper.h"
#include "linebuffer.h"
#include "list.h" #include "list.h"
#include "logging.h" #include "logging.h"
#include "plugins.h" #include "plugins.h"
@ -57,8 +58,7 @@ struct stats {
uint64_t idle_workers; uint64_t idle_workers;
}; };
static char *rx_buf; static struct lbuf * rxbuf;
static int rx_pos;
static const char * get_ds(int ds_id) static const char * get_ds(int ds_id)
{ {
@ -69,13 +69,8 @@ static size_t curl_callback(void *buffer, size_t size, size_t nmemb, void *userp
{ {
size_t realsize = size * nmemb; size_t realsize = size * nmemb;
// discard data lbuf_append(rxbuf, buffer, realsize);
if (rx_pos + realsize >= BUFSIZE)
return realsize;
memcpy(rx_buf + rx_pos, buffer, realsize);
rx_pos += realsize;
return realsize; return realsize;
} }
@ -83,14 +78,19 @@ static int probe(void)
{ {
struct server_entry *entry; struct server_entry *entry;
list_for_each_entry(entry, &server_list, list) { list_for_each_entry(entry, &server_list, list) {
rx_pos = 0; lbuf_clear(rxbuf);
curl_easy_perform(entry->handle);
int ret = curl_easy_perform(entry->handle);
if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
continue;
}
struct stats stats; struct stats stats;
memset(&stats, 0, sizeof(stats)); memset(&stats, 0, sizeof(stats));
char *line, *tmp = rx_buf, *tmp2; char *line;
while ((line = strtok_r(tmp, "\r\n", &tmp2))) { while ((line = lbuf_gettok(rxbuf, "\r\n")) != NULL) {
char *part[2]; char *part[2];
strsplit(line, ":", part, 2); strsplit(line, ":", part, 2);
@ -106,7 +106,7 @@ static int probe(void)
else if (!strcmp(part[0], "IdleWorkers") || !strcmp(part[0], "IdleServers")) else if (!strcmp(part[0], "IdleWorkers") || !strcmp(part[0], "IdleServers"))
stats.idle_workers = atoll(part[1]); stats.idle_workers = atoll(part[1]);
tmp = NULL; lbuf_freetok(rxbuf);
} }
char filename[32]; char filename[32];
@ -121,12 +121,10 @@ static int probe(void)
return 0; return 0;
} }
static int init_cb(const char *parameter, void *privdata) static int init_cb(struct strtoken *tokens, void *privdata)
{ {
char *part[4]; if (tokens->count < 2) {
int ret = strsplit(parameter, ",", part, 4); log_print(LOG_ERROR, "p_apache: parse error");
if (ret < 2) {
log_print(LOG_ERROR, "p_apache: parse error (1)");
return -1; return -1;
} }
@ -136,8 +134,7 @@ static int init_cb(const char *parameter, void *privdata)
return -1; return -1;
} }
// reference config mem entry->name = strdup(tokens->field[0]);
entry->name = part[0];
entry->handle = curl_easy_init(); entry->handle = curl_easy_init();
if (entry->handle == NULL) { if (entry->handle == NULL) {
@ -145,7 +142,8 @@ static int init_cb(const char *parameter, void *privdata)
return -1; return -1;
} }
ret = curl_easy_setopt(entry->handle, CURLOPT_URL, part[1]); /* set URL */
int ret = curl_easy_setopt(entry->handle, CURLOPT_URL, tokens->field[1]);
if (ret != 0) { if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret)); log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
curl_easy_cleanup(entry->handle); curl_easy_cleanup(entry->handle);
@ -153,12 +151,13 @@ static int init_cb(const char *parameter, void *privdata)
return -1; return -1;
} }
if (part[2] != NULL && part[3] != NULL) { if (tokens->field[2] != NULL && tokens->field[3] != NULL) {
*(part[3] -1) = ':'; *(tokens->field[3] -1) = ':';
log_print(LOG_INFO, "p_apache: auth: '%s'", part[2]); log_print(LOG_INFO, "p_apache: auth: '%s'", tokens->field[2]);
ret = curl_easy_setopt(entry->handle, CURLOPT_USERPWD, part[2]); /* set username:password */
ret = curl_easy_setopt(entry->handle, CURLOPT_USERPWD, tokens->field[2]);
if (ret != 0) { if (ret != 0) {
log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret)); log_print(LOG_ERROR, "p_apache: %s", curl_easy_strerror(ret));
curl_easy_cleanup(entry->handle); curl_easy_cleanup(entry->handle);
@ -191,13 +190,13 @@ static int init_cb(const char *parameter, void *privdata)
static int init(void) static int init(void)
{ {
rx_buf = malloc(BUFSIZE); rxbuf = lbuf_create(BUFSIZE);
if (rx_buf == NULL) { if (rxbuf == NULL) {
log_print(LOG_ERROR, "p_apache: out of memory"); log_print(LOG_ERROR, "p_apache: out of memory");
return -1; return -1;
} }
config_get_strings("p_apache", "server", init_cb, NULL); config_get_strtokens("p_apache", "server", ",", 4, init_cb, NULL);
return 0; return 0;
} }
@ -206,10 +205,11 @@ static int fini(void)
struct server_entry *entry, *tmp; struct server_entry *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &server_list, list) { list_for_each_entry_safe(entry, tmp, &server_list, list) {
curl_easy_cleanup(entry->handle); curl_easy_cleanup(entry->handle);
free(entry->name);
free(entry); free(entry);
} }
free(rx_buf); lbuf_free(rxbuf);
return 0; return 0;
} }

View File

@ -75,11 +75,9 @@ static int probe(void)
return 0; return 0;
} }
static int init_cb(const char *parameter, void *privdata) static int init_cb(struct strtoken *tokens, void *privdata)
{ {
char *part[2]; if (tokens->count != 2) {
int ret = strsplit(parameter, ",", part, 2);
if (ret != 2) {
log_print(LOG_ERROR, "p_hwmon: parse error"); log_print(LOG_ERROR, "p_hwmon: parse error");
return -1; return -1;
} }
@ -90,8 +88,8 @@ static int init_cb(const char *parameter, void *privdata)
return -1; return -1;
} }
entry->name = part[0]; entry->name = strdup(tokens->field[0]);
entry->path = part[1]; entry->path = strdup(tokens->field[1]);
log_print(LOG_DEBUG, "p_hwmon: added sensor '%s' (%s)", entry->name, entry->path); log_print(LOG_DEBUG, "p_hwmon: added sensor '%s' (%s)", entry->name, entry->path);
list_add_tail(&entry->list, &hwmon_list); list_add_tail(&entry->list, &hwmon_list);
@ -101,15 +99,18 @@ static int init_cb(const char *parameter, void *privdata)
static int init(void) static int init(void)
{ {
config_get_strings("p_hwmon", "temp", init_cb, NULL); config_get_strtokens("p_hwmon", "temp", ",", 2, init_cb, NULL);
return 0; return 0;
} }
static int fini(void) static int fini(void)
{ {
struct hwmon_entry *entry, *tmp; struct hwmon_entry *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &hwmon_list, list) list_for_each_entry_safe(entry, tmp, &hwmon_list, list) {
free(entry->name);
free(entry->path);
free(entry); free(entry);
}
return 0; return 0;
} }

View File

@ -150,18 +150,17 @@ static int probe(void)
return 0; return 0;
} }
static int init_cb(const char *parameter, void *privdata) static int init_cb(struct strtoken *tokens, void *privdata)
{ {
char *part[4]; if (tokens->count != 4) {
int ret = strsplit(parameter, ",", part, 4);
if (ret != 4) {
log_print(LOG_ERROR, "p_mysql: parse error"); log_print(LOG_ERROR, "p_mysql: parse error");
return -1; return -1;
} }
void *mysql = init_connection(part[1], part[2], part[3]); void *mysql = init_connection(tokens->field[1], tokens->field[2], tokens->field[3]);
if (mysql == NULL) if (mysql == NULL) {
return -1; return -1;
}
struct server_entry *entry = malloc(sizeof(struct server_entry)); struct server_entry *entry = malloc(sizeof(struct server_entry));
if (entry == NULL) { if (entry == NULL) {
@ -170,7 +169,7 @@ static int init_cb(const char *parameter, void *privdata)
return -1; return -1;
} }
entry->name = part[0]; entry->name = strdup(tokens->field[0]);
entry->mysql = mysql; entry->mysql = mysql;
log_print(LOG_DEBUG, "p_mysql: added server '%s'", entry->name); log_print(LOG_DEBUG, "p_mysql: added server '%s'", entry->name);
@ -180,7 +179,7 @@ static int init_cb(const char *parameter, void *privdata)
static int init(void) static int init(void)
{ {
config_get_strings("p_mysql", "server", init_cb, NULL); config_get_strtokens("p_mysql", "server", ",", 4, init_cb, NULL);
return 0; return 0;
} }
@ -189,6 +188,7 @@ static int fini(void)
struct server_entry *entry, *tmp; struct server_entry *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &server_list, list) { list_for_each_entry_safe(entry, tmp, &server_list, list) {
close_connection(entry->mysql); close_connection(entry->mysql);
free(entry->name);
free(entry); free(entry);
} }
return 0; return 0;

View File

@ -151,11 +151,9 @@ static int probe(void)
return 0; return 0;
} }
static int init_cb(const char *parameter, void *privdata) static int init_cb(struct strtoken *tokens, void *privdata)
{ {
char *part[2]; if (tokens->count != 2) {
int ret = strsplit((char *)parameter, ",", part, 2);
if (ret < 2) {
log_print(LOG_ERROR, "p_ts2: parse error"); log_print(LOG_ERROR, "p_ts2: parse error");
return -1; return -1;
} }
@ -166,11 +164,11 @@ static int init_cb(const char *parameter, void *privdata)
return -1; return -1;
} }
entry->name = strdup(part[0]); entry->name = strdup(tokens->field[0]);
entry->errors = 0; entry->errors = 0;
if (parse_sockaddr((char *)part[1], &entry->sa) < 0) { if (parse_sockaddr(tokens->field[1], &entry->sa) < 0) {
log_print(LOG_ERROR, "p_ts2: invalid address: <%s>", part[1]); log_print(LOG_ERROR, "p_ts2: invalid address: <%s>", tokens->field[1]);
free(entry->name); free(entry->name);
free(entry); free(entry);
return -1; return -1;
@ -189,7 +187,7 @@ static int init(void)
return -1; return -1;
} }
config_get_strings("p_ts2", "server", init_cb, NULL); config_get_strtokens("p_ts2", "server", ",", 2, init_cb, NULL);
return 0; return 0;
} }

View File

@ -28,6 +28,7 @@
#include "configfile.h" #include "configfile.h"
#include "helper.h" #include "helper.h"
#include "linebuffer.h"
#include "list.h" #include "list.h"
#include "logging.h" #include "logging.h"
#include "plugins.h" #include "plugins.h"
@ -38,12 +39,6 @@
#define ARGVSIZE 1024 #define ARGVSIZE 1024
#define BUFSIZE 1024 #define BUFSIZE 1024
struct rra_cb_data {
char *buffer;
int size;
int *pos;
};
static const char *rrd_dir; static const char *rrd_dir;
int sammler_rrd_init(void) int sammler_rrd_init(void)
@ -54,20 +49,19 @@ int sammler_rrd_init(void)
static int append_rra_config(const char *parameter, void *privdata) static int append_rra_config(const char *parameter, void *privdata)
{ {
struct rra_cb_data *data = (struct rra_cb_data *)privdata; struct lbuf *buffer = (struct lbuf *)privdata;
int len = snprintf(data->buffer + *(data->pos), data->size - *(data->pos), "%s ", parameter); lbuf_printf(buffer, "%s ", parameter);
if (len < 0 || len >= data->size - *(data->pos)) {
log_print(LOG_ERROR, "append_rra_config_cb: arguments too long");
return -1;
}
*(data->pos) += len;
return 0; return 0;
} }
static int do_rrd(int (*rrd_func)(int, char **), char *cmd) static int do_rrd(int (*rrd_func)(int, char **), struct lbuf *buffer)
{ {
size_t len;
char *cmd = lbuf_getdata(buffer, &len);
if (len < ARGVSIZE -1)
cmd[len] = '\0';
char *argv[ARGCMAX]; char *argv[ARGCMAX];
int argc = strsplit(cmd, " \t\n", argv, ARGCMAX -1); int argc = strsplit(cmd, " \t\n", argv, ARGCMAX -1);
argv[argc] = NULL; argv[argc] = NULL;
@ -81,7 +75,6 @@ static int do_rrd(int (*rrd_func)(int, char **), char *cmd)
log_print(LOG_ERROR, "rrd_func failed: %s: %s", argv[1], rrd_get_error()); log_print(LOG_ERROR, "rrd_func failed: %s: %s", argv[1], rrd_get_error());
} }
free(cmd);
return retval; return retval;
} }
@ -99,51 +92,48 @@ static int rrd_create_file(const char *filename, const char *pluginname, int ds_
return -1; return -1;
} }
char *buffer = malloc(ARGVSIZE); struct lbuf *buffer = lbuf_create(ARGVSIZE);
if (buffer == NULL) { if (buffer == NULL) {
log_print(LOG_ERROR, "rrd_create_file: out of memory"); log_print(LOG_ERROR, "rrd_create_file: out of memory");
return -1; return -1;
} }
int step = plugin->interval; int ret = lbuf_printf(buffer, "create %s -s %d %s ", filename, plugin->interval, ds_def);
int pos = snprintf(buffer, ARGVSIZE, "create %s -s %d %s ", filename, step, ds_def); if (ret == -1) {
if (pos < 0 || pos >= ARGVSIZE) {
log_print(LOG_ERROR, "rrd_create_file: arguments too long"); log_print(LOG_ERROR, "rrd_create_file: arguments too long");
free(buffer); lbuf_free(buffer);
return -1; return -1;
} }
struct rra_cb_data data = { ret = config_get_strings("global", "rra", append_rra_config, buffer);
.buffer = buffer, if (ret <= 0) {
.size = ARGVSIZE, lbuf_free(buffer);
.pos = &pos,
};
int cnt = config_get_strings("global", "rra", append_rra_config, &data);
if (cnt <= 0) {
free(buffer);
return -1; return -1;
} }
return do_rrd(&rrd_create, buffer); ret = do_rrd(&rrd_create, buffer);
lbuf_free(buffer);
return ret;
} }
static int rrd_update_file(const char *filename, const char *values) static int rrd_update_file(const char *filename, const char *values)
{ {
char *buffer = malloc(ARGVSIZE); struct lbuf *buffer = lbuf_create(ARGVSIZE);
if (buffer == NULL) { if (buffer == NULL) {
log_print(LOG_ERROR, "append_ds_config: out of memory"); log_print(LOG_ERROR, "append_ds_config: out of memory");
return -1; return -1;
} }
int pos = snprintf(buffer, ARGVSIZE, "update %s N:%s", filename, values); int ret = lbuf_printf(buffer, "update %s N:%s", filename, values);
if (pos < 0 || pos >= ARGVSIZE) { if (ret == -1) {
log_print(LOG_ERROR, "rrd_update_file: arguments too long"); log_print(LOG_ERROR, "rrd_update_file: arguments too long");
free(buffer); lbuf_free(buffer);
return -1; return -1;
} }
return do_rrd(&rrd_update, buffer); ret = do_rrd(&rrd_update, buffer);
lbuf_free(buffer);
return ret;
} }
static int check_create_dir(const char *dir) static int check_create_dir(const char *dir)

View File

@ -1,5 +1,5 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 06/2006 by Olaf Rempel * * Copyright (C) 03/2010 by Olaf Rempel *
* razzor@kopf-tisch.de * * razzor@kopf-tisch.de *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
@ -48,6 +48,25 @@ static struct option opts[] = {
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
static int restart_var;
static void trigger_restart(void *privdata)
{
int *restart = (int *)privdata;
*restart = 1;
}
static int check_restart(void *privdata)
{
int *restart = (int *)privdata;
if (*restart == 1) {
*restart = 0;
return 1;
}
return 0;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *config = DEFAULT_CONFIG; char *config = DEFAULT_CONFIG;
@ -102,7 +121,10 @@ int main(int argc, char *argv[])
exit(1); exit(1);
/* zum daemon mutieren */ /* zum daemon mutieren */
daemon(-1, 0); if (daemon(-1, 0) < 0) {
log_print(LOG_ERROR, "failed to daemonize");
exit(1);
}
/* create pidfile */ /* create pidfile */
if (pidfile_create(pidfile) < 0) { if (pidfile_create(pidfile) < 0) {
@ -112,7 +134,7 @@ int main(int argc, char *argv[])
} }
signal_init(); signal_init();
signal_set_callback(SIGHUP, event_loop_break); signal_add_callback(SIGHUP, trigger_restart, (void *)&restart_var);
log_print(LOG_EVERYTIME, "sammler started (pid:%d)", getpid()); log_print(LOG_EVERYTIME, "sammler started (pid:%d)", getpid());
@ -130,7 +152,7 @@ int main(int argc, char *argv[])
break; break;
/* exited on restart / SIGUSR1 */ /* exited on restart / SIGUSR1 */
event_loop(); event_loop(check_restart, (void *)&restart_var);
plugin_close(); plugin_close();

View File

@ -32,7 +32,8 @@ struct signal_entry {
int signum; int signum;
int deleted; int deleted;
void (*callback)(void); void (*callback)(void *privdata);
void *privdata;
}; };
static LIST_HEAD(callback_list); static LIST_HEAD(callback_list);
@ -76,7 +77,7 @@ int signal_remove_callback(int signum, int type)
return 0; return 0;
} }
int signal_set_callback(int signum, void (*callback)(void)) int signal_add_callback(int signum, void (*callback)(void *privdata), void *privdata)
{ {
struct signal_entry *entry = malloc(sizeof(struct signal_entry)); struct signal_entry *entry = malloc(sizeof(struct signal_entry));
if (entry == NULL) { if (entry == NULL) {
@ -87,6 +88,7 @@ int signal_set_callback(int signum, void (*callback)(void))
entry->signum = signum; entry->signum = signum;
entry->deleted = 0; entry->deleted = 0;
entry->callback = callback; entry->callback = callback;
entry->privdata = privdata;
list_add_tail(&entry->list, &callback_list); list_add_tail(&entry->list, &callback_list);
struct sigaction sig_action = { struct sigaction sig_action = {
@ -121,7 +123,7 @@ static int sig_event(int fd, void *privdata)
} }
if (search->signum == signum) if (search->signum == signum)
search->callback(); search->callback(search->privdata);
} }
return 0; return 0;

View File

@ -5,7 +5,7 @@
#define SIG_IGNORE 0x01 #define SIG_IGNORE 0x01
int signal_remove_callback(int signum, int type); int signal_remove_callback(int signum, int type);
int signal_set_callback(int signum, void (*callback)(void)); int signal_add_callback(int signum, void (*callback)(void *privdata), void *privdata);
int signal_init(void); int signal_init(void);