]> git.itanic.dy.fi Git - rrdd/commitdiff
Parsers: Implement framework for registering and querying parsers
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Mon, 19 Nov 2012 18:43:52 +0000 (20:43 +0200)
committerTimo Kokkonen <timo.t.kokkonen@iki.fi>
Mon, 19 Nov 2012 20:10:01 +0000 (22:10 +0200)
This framework can be used to register parsers and get parsers by a
string name. This allows all need for hard coding string and parser
function names together.

All existing parsers are converted to use the new framework.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
Makefile
built_in_parsers.c [new file with mode: 0644]
built_in_parsers.h [new file with mode: 0644]
config.c
main.c
parser.c
parser.h
rrdtool.c
rrdtool.h
utils.h

index db48947d2952d7fead3e7337693af5d8cf728c37..3a89e912e5378c36b1e22ecef087db64eac77385 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CC=gcc
 LD=ld
 CFLAGS=-Wall -O2 -g
 
 LD=ld
 CFLAGS=-Wall -O2 -g
 
-RRDD_OBJS= main.o process.o rrdtool.o parser.o string.o \
+RRDD_OBJS= main.o process.o rrdtool.o parser.o built_in_parsers.o string.o \
                debug.o config.o onewire_parser.o plugin_manager.o
 
 ALL_OBJS = $(RRDD_OBJS)
                debug.o config.o onewire_parser.o plugin_manager.o
 
 ALL_OBJS = $(RRDD_OBJS)
diff --git a/built_in_parsers.c b/built_in_parsers.c
new file mode 100644 (file)
index 0000000..f3a8c79
--- /dev/null
@@ -0,0 +1,327 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "parser.h"
+#include "process.h"
+#include "string.h"
+#include "debug.h"
+#include "utils.h"
+#include "built_in_parsers.h"
+
+#define STATFILE "/proc/stat"
+
+static int cpu_parser(char *data, const char **p)
+{
+       char buf[1024];
+       char *str = buf;
+       FILE *file = fopen(STATFILE, "r");
+       long long user, nice, sys, idle, wait, irq, softirq;
+
+       if (file == NULL) {
+               pr_err("Failed to open file %s\n", STATFILE);
+               return -1;
+       }
+
+       if (!fgets(buf, 1024, file)) {
+               pr_err("Failed to read file %s\n", STATFILE);
+               fclose(file);
+               return -1;
+       }
+
+       user    = dec_to_longlong(str, &str);
+       nice    = dec_to_longlong(str, &str);
+       sys     = dec_to_longlong(str, &str);
+       idle    = dec_to_longlong(str, &str);
+       wait    = dec_to_longlong(str, &str);
+       irq     = dec_to_longlong(str, &str);
+       softirq = dec_to_longlong(str, &str);
+
+       snprintf(data, RRD_DATA_MAX_LEN, "%lld:%lld:%lld:%lld:%lld:%lld:%lld",
+               user, nice, sys, idle, wait, irq, softirq);
+
+       fclose(file);
+       return 0;
+}
+
+#define MEMFILE "/proc/meminfo"
+
+static int mem_parser(char *data, const char **p)
+{
+       char buf[1024], word[1024];
+       int free = 0, buffered = 0, cache = 0, active = 0, inactive = 0,
+               swapfree = 0, anon = 0, slab = 0, tables = 0, other = 0,
+               swaptotal = 0, total = 0;
+       FILE *file = fopen(MEMFILE, "r");
+
+       if (file == NULL) {
+               pr_err("Failed to open file %s\n", MEMFILE);
+               return -1;
+       }
+
+       while (fgets(buf, 1024, file)) {
+               get_word(buf, 0, word, 1024);
+
+               if (!strcmp(word, "MemFree:")) {
+                       free = dec_to_int(buf, NULL);
+               } else if (!strcmp(word, "MemTotal:")) {
+                       total = dec_to_int(buf, NULL);
+               } else if (!strcmp(word, "Buffers:")) {
+                       buffered = dec_to_int(buf, NULL);
+               } else if (!strcmp(word, "Cached:")) {
+                       cache = dec_to_int(buf, NULL);
+               } else if (!strcmp(word, "Active:")) {
+                       active = dec_to_int(buf, NULL);
+               } else if (!strcmp(word, "Inactive:")) {
+                       inactive = dec_to_int(buf, NULL);
+               } else if (!strcmp(word, "SwapFree:")) {
+                       swapfree = dec_to_int(buf, NULL);
+               } else if (!strcmp(word, "AnonPages:")) {
+                       anon = dec_to_int(buf, NULL);
+               } else if (!strcmp(word, "Slab:")) {
+                       slab = dec_to_int(buf, NULL);
+               } else if (!strcmp(word, "PageTables:")) {
+                       tables = dec_to_int(buf, NULL);
+               } else if (!strcmp(word, "SwapTotal:")) {
+                       swaptotal = dec_to_int(buf, NULL);
+               }
+       }
+       fclose(file);
+
+       other = total - free - buffered - cache - anon - slab - tables;
+
+       snprintf(data, RRD_DATA_MAX_LEN, "%f:%f:%f:%f:%f:%f:%f:%f:%f:%f:%f",
+               free / 1024.0,
+               buffered / 1024.0,
+               cache / 1024.0,
+               active / 1024.0,
+               inactive / 1024.0,
+               swapfree / 1024.0,
+               anon / 1024.0,
+               slab / 1024.0,
+               tables / 1024.0,
+               other / 1024.0,
+               (swaptotal - swapfree) / 1024.0);
+
+       return 0;
+}
+
+int cpu_mem_parser(char *data, const char **p)
+{
+       char cpu[1024], mem[1024];
+
+       cpu_parser(cpu, p);
+       mem_parser(mem, p);
+       snprintf(data, RRD_DATA_MAX_LEN, "%s:%s", cpu, mem);
+
+       return 0;
+}
+
+static int digitemp_parser(char *data, const char **p)
+{
+       const char digitemp_cmd[] = "/usr/bin/digitemp";
+       char *const digitemp_args[] = { "", "-o2", "-a", "-q", 0 };
+       FILE *readf;
+       int pid, ret;
+       float t1 = 0, t2 = 0, t3 = 0;
+       char buf[1024];
+
+       pid = run_piped_stream(digitemp_cmd, digitemp_args, 0, &readf, 0);
+       if (pid < 0) {
+               pr_err("Failed to parse digitemp\n");
+               sprintf(data, "U:U");
+               return -1;
+       }
+
+       ret = fscanf(readf, "%f %f %f", &t1, &t2, &t3);
+
+       if (ret != 3) {
+               pr_err("Failed to parse digitemp output: %m\n");
+               sprintf(data, "U:U");
+               return 1;
+       }
+
+       t2 += 2.16;
+       t3 += -0.44;
+
+       /* Read whatever the process might be still printing out */
+       while (fgets(buf, 1024, readf));
+
+       harvest_zombies(pid);
+       snprintf(data, RRD_DATA_MAX_LEN, "%.2f:%.2f", t3, t2);
+       return 0;
+}
+
+static int digitemp_parser_mod(char *data, const char **p)
+{
+       char buf[1024];
+       int ret;
+
+       ret = digitemp_parser(buf, p);
+       snprintf(data, RRD_DATA_MAX_LEN, "U:%s", buf);
+
+       return ret;
+}
+
+/* Run a command and feed the output from stdout directly to rrdtool */
+static int script_parser(char *rrd_data, const char **parser_data)
+{
+       FILE *readf;
+       int pid, ret;
+       void *tmp = parser_data;
+       char **cmd = tmp;
+
+       pid = run_piped_stream(cmd[0], &cmd[1], NULL, &readf, NULL);
+       ret = fread(rrd_data, 1, RRD_DATA_MAX_LEN, readf);
+
+       pr_info("Read %d bytes :%s\n", ret, rrd_data);
+       fclose(readf);
+
+       harvest_zombies(pid);
+
+       return 0;
+}
+
+struct iface_stats {
+       long long rx_bytes;
+       long long rx_packets;
+       long long tx_bytes;
+       long long tx_packets;
+};
+
+#define PROC_NETDEV    "/proc/net/dev"
+
+static int get_iface_stats(const char *iface, struct iface_stats *stat)
+{
+       FILE *netdev;
+       char buf[1024];
+       char if_name[16];
+       char *str;
+       int error;
+
+       netdev = fopen(PROC_NETDEV, "r");
+
+       if (netdev == NULL) {
+               error = errno;
+               pr_err("Failed to open file %s: %d (%m)\n",
+                       PROC_NETDEV, error);
+               return error;
+       }
+
+       while (fgets(buf, sizeof(buf), netdev)) {
+               get_word(buf, &str, if_name, sizeof(if_name));
+
+               /* Remove the ':' at the end of the if_name */
+               if_name[strlen(if_name) - 1] = 0;
+               if (strncmp(iface, if_name, sizeof(if_name)))
+                       continue;
+
+               stat->rx_bytes          = dec_to_longlong(str, &str);
+               stat->rx_packets        = dec_to_longlong(str, &str);
+               /* errs */                dec_to_longlong(str, &str);
+               /* drop */                dec_to_longlong(str, &str);
+               /* fifo */                dec_to_longlong(str, &str);
+               /* frame */               dec_to_longlong(str, &str);
+               /* compressed */          dec_to_longlong(str, &str);
+               /* multicast */           dec_to_longlong(str, &str);
+               stat->tx_bytes          = dec_to_longlong(str, &str);
+               stat->tx_packets        = dec_to_longlong(str, &str);
+
+               pr_info("rx_b %lld rx_p %lld tx_b %lld tx_p %lld\n",
+                       stat->rx_bytes, stat->rx_packets,
+                       stat->tx_bytes, stat->tx_packets);
+
+               return 0;
+       }
+
+       pr_err("Interface %s not found\n", iface);
+       return -ENODEV;
+}
+
+int netstats_parser(char *rrd_data, const char **parser_data)
+{
+       struct iface_stats stat;
+       const char **iface_name = parser_data;
+       int max_str = RRD_DATA_MAX_LEN;
+       int ret;
+
+       if (!parser_data) {
+               pr_err("No device names specified\n");
+               return -1;
+       }
+
+       while(*iface_name) {
+               pr_info("getting data for iface %s\n", *iface_name);
+               ret = get_iface_stats(*iface_name, &stat);
+
+               if (!ret) {
+                       ret = snprintf(rrd_data, max_str, "%lld:%lld:%lld:%lld",
+                               stat.rx_bytes, stat.rx_packets,
+                               stat.tx_bytes, stat.tx_packets);
+               } else {
+                       ret = snprintf(rrd_data, max_str, "U:U:U:U");
+               }
+
+               max_str -= ret;
+               rrd_data += ret;
+
+               iface_name++;
+               if (!*iface_name)
+                       break;
+
+               ret = snprintf(rrd_data, max_str, ":");
+               max_str -= ret;
+               rrd_data += ret;
+       }
+
+       return 0;
+}
+
+static struct parser_info built_in_parsers[] = {
+       {
+               .name = "cpu",
+               .parse = cpu_parser,
+       },
+       {
+               .name = "mem",
+               .parse = mem_parser,
+       },
+       {
+               .name = "cpu_mem",
+               .parse = cpu_mem_parser,
+       },
+       {
+               .name = "digitemp",
+               .parse = digitemp_parser,
+       },
+       {
+               .name = "digitemp_mod",
+               .parse = digitemp_parser_mod,
+       },
+       {
+               .name = "script",
+               .parse = script_parser,
+       },
+       {
+               .name = "netstats",
+               .parse = netstats_parser,
+       },
+       {
+               .name = "onewire",
+               .parse = onewire_parser,
+       },
+};
+
+int register_built_in_parsers(void)
+{
+       int i, ret;
+
+       for (i = 0; i < ARRAY_SIZE(built_in_parsers); i++) {
+               ret = register_parser(&built_in_parsers[i]);
+
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
diff --git a/built_in_parsers.h b/built_in_parsers.h
new file mode 100644 (file)
index 0000000..76b3a98
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _BUILT_IN_PARSERS_H
+#define _BUILT_IN_PARSERS_H
+
+int register_built_in_parsers(void);
+
+int onewire_parser(char *rrd_data, const char **parser_data);
+
+#endif
index 2e28c3337ab34ac793a9dda2d8e8f3f3a66fb227..939a8c6c0aac6a8c638fa776d95b1621ae30d509 100644 (file)
--- a/config.c
+++ b/config.c
@@ -145,38 +145,6 @@ static int parse_images(config_setting_t *list, struct rrd_database *db)
        return 0;
 }
 
        return 0;
 }
 
-static int (*str_to_parser(const char *str))(char *rrd_data, const char **parser_data)
-{
-       if (!str)
-               return NULL;
-
-       if (!strcmp(str, "cpu"))
-               return cpu_parser;
-
-       if (!strcmp(str, "mem"))
-               return mem_parser;
-
-       if (!strcmp(str, "cpu_mem"))
-               return cpu_mem_parser;
-
-       if (!strcmp(str, "digitemp"))
-               return digitemp_parser;
-
-       if (!strcmp(str, "digitemp_mod"))
-               return digitemp_parser_mod;
-
-       if (!strcmp(str, "script"))
-               return script_parser;
-
-       if (!strcmp(str, "netstats"))
-               return netstats_parser;
-
-       if (!strcmp(str, "onewire"))
-               return onewire_parser;
-
-       return NULL;
-}
-
 static int parse_data_sources(config_setting_t *rrd, struct rrd_database *db)
 {
        config_setting_t *list, *group;
 static int parse_data_sources(config_setting_t *rrd, struct rrd_database *db)
 {
        config_setting_t *list, *group;
@@ -286,7 +254,7 @@ static int parse_database(config_setting_t *rrd, struct rrd_database *db)
 
        /* Parser is not a mandatory parameter */
        config_setting_lookup_string(rrd, "parser", &parser);
 
        /* Parser is not a mandatory parameter */
        config_setting_lookup_string(rrd, "parser", &parser);
-       db->parse = str_to_parser(parser);
+       db->parser = str_to_parser(parser);
 
        list = config_setting_get_member(rrd, "image");
        parse_images(list, db);
 
        list = config_setting_get_member(rrd, "image");
        parse_images(list, db);
diff --git a/main.c b/main.c
index 49adc285414610d5c9ba2962ec52b80871262059..1d26539900810a821f6aff6235e56e89cbb5fc7e 100644 (file)
--- a/main.c
+++ b/main.c
@@ -9,6 +9,7 @@
 #include "debug.h"
 
 #include "config.h"
 #include "debug.h"
 
 #include "config.h"
+#include "built_in_parsers.h"
 
 struct user_options {
        int max_jobs;
 
 struct user_options {
        int max_jobs;
@@ -60,6 +61,7 @@ int main(int argc, char *argv[])
        if (read_args(argc, argv, &opts) < 0)
                return -1;
 
        if (read_args(argc, argv, &opts) < 0)
                return -1;
 
+       register_built_in_parsers();
 
        if (!opts.config_file) {
                pr_err("No database config file given. Nothing to do\n");
 
        if (!opts.config_file) {
                pr_err("No database config file given. Nothing to do\n");
index 887b524e6ad12df4a89c9e69d5cf845650c2bfc9..4a5e5355d5360483a1aef22c42d0604cdd17ccbb 100644 (file)
--- a/parser.c
+++ b/parser.c
-#include <stdlib.h>
-#include <stdio.h>
 #include <string.h>
 
 #include "parser.h"
 #include <string.h>
 
 #include "parser.h"
-#include "process.h"
-#include "string.h"
 #include "debug.h"
 #include "debug.h"
-#include "utils.h"
 
 
-#define STATFILE "/proc/stat"
+static struct parser_info *parser_list;
 
 
-int cpu_parser(char *data, const char **p)
+int register_parser(struct parser_info *info)
 {
 {
-       char buf[1024];
-       char *str = buf;
-       FILE *file = fopen(STATFILE, "r");
-       long long user, nice, sys, idle, wait, irq, softirq;
+       struct parser_info *parser;
 
 
-       if (file == NULL) {
-               pr_err("Failed to open file %s\n", STATFILE);
+       if (!info->name) {
+               pr_err("Unable to register parser without a name\n");
                return -1;
        }
 
                return -1;
        }
 
-       if (!fgets(buf, 1024, file)) {
-               pr_err("Failed to read file %s\n", STATFILE);
-               fclose(file);
-               return -1;
-       }
-
-       user    = dec_to_longlong(str, &str);
-       nice    = dec_to_longlong(str, &str);
-       sys     = dec_to_longlong(str, &str);
-       idle    = dec_to_longlong(str, &str);
-       wait    = dec_to_longlong(str, &str);
-       irq     = dec_to_longlong(str, &str);
-       softirq = dec_to_longlong(str, &str);
-
-       snprintf(data, RRD_DATA_MAX_LEN, "%lld:%lld:%lld:%lld:%lld:%lld:%lld",
-               user, nice, sys, idle, wait, irq, softirq);
-
-       fclose(file);
-       return 0;
-}
-
-#define MEMFILE "/proc/meminfo"
-
-int mem_parser(char *data, const char **p)
-{
-       char buf[1024], word[1024];
-       int free = 0, buffered = 0, cache = 0, active = 0, inactive = 0,
-               swapfree = 0, anon = 0, slab = 0, tables = 0, other = 0,
-               swaptotal = 0, total = 0;
-       FILE *file = fopen(MEMFILE, "r");
+       pr_info("Registering parser %s\n", info->name);
 
 
-       if (file == NULL) {
-               pr_err("Failed to open file %s\n", MEMFILE);
-               return -1;
-       }
-
-       while (fgets(buf, 1024, file)) {
-               get_word(buf, 0, word, 1024);
-               
-               if (!strcmp(word, "MemFree:")) {
-                       free = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "MemTotal:")) {
-                       total = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "Buffers:")) {
-                       buffered = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "Cached:")) {
-                       cache = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "Active:")) {
-                       active = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "Inactive:")) {
-                       inactive = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "SwapFree:")) {
-                       swapfree = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "AnonPages:")) {
-                       anon = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "Slab:")) {
-                       slab = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "PageTables:")) {
-                       tables = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "SwapTotal:")) {
-                       swaptotal = dec_to_int(buf, NULL);
-               }
-       }
-       fclose(file);
-
-       other = total - free - buffered - cache - anon - slab - tables;
-
-       snprintf(data, RRD_DATA_MAX_LEN, "%f:%f:%f:%f:%f:%f:%f:%f:%f:%f:%f",
-               free / 1024.0,
-               buffered / 1024.0,
-               cache / 1024.0,
-               active / 1024.0,
-               inactive / 1024.0,
-               swapfree / 1024.0,
-               anon / 1024.0,
-               slab / 1024.0,
-               tables / 1024.0,
-               other / 1024.0,
-               (swaptotal - swapfree) / 1024.0);
-
-       return 0;
-}
-
-int cpu_mem_parser(char *data, const char **p)
-{
-       char cpu[1024], mem[1024];
-
-       cpu_parser(cpu, p);
-       mem_parser(mem, p);
-       snprintf(data, RRD_DATA_MAX_LEN, "%s:%s", cpu, mem);
-
-       return 0;
-}
-
-int digitemp_parser(char *data, const char **p)
-{
-       const char digitemp_cmd[] = "/usr/bin/digitemp";
-       char *const digitemp_args[] = { "", "-o2", "-a", "-q", 0 };
-       FILE *readf;
-       int pid, ret;
-       float t1 = 0, t2 = 0, t3 = 0;
-       char buf[1024];
-
-       pid = run_piped_stream(digitemp_cmd, digitemp_args, 0, &readf, 0);
-       if (pid < 0) {
-               pr_err("Failed to parse digitemp\n");
-               sprintf(data, "U:U");
-               return -1;
-       }
-
-       ret = fscanf(readf, "%f %f %f", &t1, &t2, &t3);
-
-       if (ret != 3) {
-               pr_err("Failed to parse digitemp output: %m\n");
-               sprintf(data, "U:U");
-               return 1;
+       if (!parser_list) {
+               parser_list = info;
+               return 0;
        }
 
        }
 
-       t2 += 2.16;
-       t3 += -0.44;
-
-       /* Read whatever the process might be still printing out */
-       while (fgets(buf, 1024, readf));
-
-       harvest_zombies(pid);
-       snprintf(data, RRD_DATA_MAX_LEN, "%.2f:%.2f", t3, t2);
-       return 0;
-}
-
-int digitemp_parser_mod(char *data, const char **p)
-{
-       char buf[1024];
-       int ret;
-
-       ret = digitemp_parser(buf, p);
-       snprintf(data, RRD_DATA_MAX_LEN, "U:%s", buf);
-
-       return ret;
-}
-
-/* Run a command and feed the output from stdout directly to rrdtool */
-int script_parser(char *rrd_data, const char **parser_data)
-{
-       FILE *readf;
-       int pid, ret;
-       void *tmp = parser_data;
-       char **cmd = tmp;
+       for (parser = parser_list; parser->next; parser = parser->next)
+               ;
 
 
-       pid = run_piped_stream(cmd[0], &cmd[1], NULL, &readf, NULL);
-       ret = fread(rrd_data, 1, RRD_DATA_MAX_LEN, readf);
-
-       pr_info("Read %d bytes :%s\n", ret, rrd_data);
-       fclose(readf);
-
-       harvest_zombies(pid);
+       parser->next = info;
+       info->next = NULL;
 
        return 0;
 }
 
 
        return 0;
 }
 
-struct iface_stats {
-       long long rx_bytes;
-       long long rx_packets;
-       long long tx_bytes;
-       long long tx_packets;
-};
-
-#define PROC_NETDEV    "/proc/net/dev"
-
-static int get_iface_stats(const char *iface, struct iface_stats *stat)
+struct parser_info *str_to_parser(const char *str)
 {
 {
-       FILE *netdev;
-       char buf[1024];
-       char if_name[16];
-       char *str;
-       int error;
-
-       netdev = fopen(PROC_NETDEV, "r");
+       struct parser_info *parser;
 
 
-       if (netdev == NULL) {
-               error = errno;
-               pr_err("Failed to open file %s: %d (%m)\n",
-                       PROC_NETDEV, error);
-               return error;
+       for (parser = parser_list; parser; parser = parser->next) {
+               if (!strcmp(str, parser->name))
+                       return parser;
        }
 
        }
 
-       while (fgets(buf, sizeof(buf), netdev)) {
-               get_word(buf, &str, if_name, sizeof(if_name));
-
-               /* Remove the ':' at the end of the if_name */
-               if_name[strlen(if_name) - 1] = 0;
-               if (strncmp(iface, if_name, sizeof(if_name)))
-                       continue;
-
-               stat->rx_bytes          = dec_to_longlong(str, &str);
-               stat->rx_packets        = dec_to_longlong(str, &str);
-               /* errs */                dec_to_longlong(str, &str);
-               /* drop */                dec_to_longlong(str, &str);
-               /* fifo */                dec_to_longlong(str, &str);
-               /* frame */               dec_to_longlong(str, &str);
-               /* compressed */          dec_to_longlong(str, &str);
-               /* multicast */           dec_to_longlong(str, &str);
-               stat->tx_bytes          = dec_to_longlong(str, &str);
-               stat->tx_packets        = dec_to_longlong(str, &str);
-
-               pr_info("rx_b %lld rx_p %lld tx_b %lld tx_p %lld\n",
-                       stat->rx_bytes, stat->rx_packets,
-                       stat->tx_bytes, stat->tx_packets);
-
-               return 0;
-       }
-
-       pr_err("Interface %s not found\n", iface);
-       return -ENODEV;
-}
-
-int netstats_parser(char *rrd_data, const char **parser_data)
-{
-       struct iface_stats stat;
-       const char **iface_name = parser_data;
-       int max_str = RRD_DATA_MAX_LEN;
-       int ret;
-
-       if (!parser_data) {
-               pr_err("No device names specified\n");
-               return -1;
-       }
-
-       while(*iface_name) {
-               pr_info("getting data for iface %s\n", *iface_name);
-               ret = get_iface_stats(*iface_name, &stat);
-
-               if (!ret) {
-                       ret = snprintf(rrd_data, max_str, "%lld:%lld:%lld:%lld",
-                               stat.rx_bytes, stat.rx_packets,
-                               stat.tx_bytes, stat.tx_packets);
-               } else {
-                       ret = snprintf(rrd_data, max_str, "U:U:U:U");
-               }
-
-               max_str -= ret;
-               rrd_data += ret;
-
-               iface_name++;
-               if (!*iface_name)
-                       break;
-
-               ret = snprintf(rrd_data, max_str, ":");
-               max_str -= ret;
-               rrd_data += ret;
-       }
-
-       return 0;
+       return NULL;
 }
 }
index 5ec6a8e26340b6d510c6cc8dc2304803fe72ae1b..b5718e018672e35c2c937d8583bfb4ff29778787 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -1,17 +1,17 @@
 #ifndef _PARSER_H
 #define _PARSER_H
 
 #ifndef _PARSER_H
 #define _PARSER_H
 
-#define RRD_DATA_MAX_LEN       4096
+typedef int (parse_fn_t)(char *rrd_data, const char **parser_data);
+
+struct parser_info {
+       struct parser_info *next;
+       const char *name;
+       parse_fn_t *parse;
+};
 
 
-int cpu_parser(char *data, const char **p);
-int mem_parser(char *data, const char **p);
-int cpu_mem_parser(char *data, const char **p);
-int digitemp_parser(char *data, const char **p);
-int digitemp_parser_mod(char *data, const char **p);
-int script_parser(char *rrd_data, const char **parser_data);
-int netstats_parser(char *rrd_data, const char **parser_data);
-int onewire_parser(char *rrd_data, const char **parser_data);
+int register_parser(struct parser_info *info);
+struct parser_info *str_to_parser(const char *str);
 
 
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define RRD_DATA_MAX_LEN       4096
 
 #endif
 
 #endif
index d2fd024a4fd3b2e0443644615503c5e185877ccc..53db261354f4102f41f3bdccf4a77b2ee6ba542a 100644 (file)
--- a/rrdtool.c
+++ b/rrdtool.c
@@ -220,8 +220,8 @@ int rrdtool_update_data(struct rrd_database *rrd)
 
        l = sprintf(data, "N:");
 
 
        l = sprintf(data, "N:");
 
-       if (rrd->parse) {
-               rrd->parse(data + l, rrd->parser_data);
+       if (rrd->parser && rrd->parser->parse) {
+               rrd->parser->parse(data + l, rrd->parser_data);
                data[RRD_DATA_MAX_LEN + 2] = '\0';
 
                pr_info("Data: %s\n", data);
                data[RRD_DATA_MAX_LEN + 2] = '\0';
 
                pr_info("Data: %s\n", data);
index fa1df3708644ca36f8a27e17edc3ce6fd339b528..ae0c507154911fe4293e3b90aa5f24554181d821 100644 (file)
--- a/rrdtool.h
+++ b/rrdtool.h
@@ -37,7 +37,7 @@ struct rrd_database {
        int     interval;       /* Update interval */
 
        /* Parser to aquire data for rrd */
        int     interval;       /* Update interval */
 
        /* Parser to aquire data for rrd */
-       int (*parse)(char *rrd_data, const char **parser_data);
+       struct parser_info *parser;
        const char **parser_data;       /* data to be fed to the parser */
 
        char *const *pre_draw_cmd; /* Command to execute prior drawing images*/
        const char **parser_data;       /* data to be fed to the parser */
 
        char *const *pre_draw_cmd; /* Command to execute prior drawing images*/
diff --git a/utils.h b/utils.h
index c3d639a6a7b41cf6c1b15266502d5adb52a2aa62..3269e7d3bfbe0d5c31db54cf3b16617f79ac614e 100644 (file)
--- a/utils.h
+++ b/utils.h
@@ -3,4 +3,6 @@
 
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 
 
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 
+#define ARRAY_SIZE(a) (sizeof(a) / (sizeof((a)[0])))
+
 #endif
 #endif