]> git.itanic.dy.fi Git - rrdd/blob - onewire_parser.c
onewire_parser: Convert to a plugin
[rrdd] / onewire_parser.c
1 #include <stdio.h>
2 #include <ownetapi.h>
3
4 #include "parser.h"
5 #include "debug.h"
6 #include "string.h"
7 #include "utils.h"
8 #include "plugin.h"
9
10 static int parse_opts(const char *str, char *ow_path, size_t pathlen, double *offset)
11 {
12         char *endptr;
13         const char *start_str = str;
14         const char offset_str[] = "offset=";
15
16         if (!offset)
17                 return 0;
18
19         /*
20          * Skip the onewire path entry. Options begin after the first
21          * white space
22          */
23         for (; *str; str++)
24                 if (isspace(*str))
25                         break;
26
27         /* Copy the onewire path without options */
28         strncpy(ow_path, start_str, pathlen);
29         ow_path[str - start_str] = '\0';
30
31         /* Get the next non-space, which is where the argument begins */
32         for (; *str; str++)
33                 if (!isspace(*str))
34                         break;
35
36         if (strncmp(str, offset_str, sizeof(offset_str) - 1))
37                 return 0;
38         str += sizeof(offset_str) - 1;
39
40         *offset = strtod(str, &endptr);
41
42         if (str != endptr)
43                 return 1;
44
45         return 0;
46 }
47
48 static int onewire_parser(char *rrd_data, const char **parser_data)
49 {
50         OWNET_HANDLE h;
51         const char *server_addr;
52         char buf[24], *tmp;
53         int i = 1, ret;
54         int max_str = RRD_DATA_MAX_LEN;
55
56         if (!parser_data) {
57                 pr_err("No parser data available\n");
58                 return -1;
59         }
60
61         server_addr = parser_data[0];
62
63         if (!server_addr) {
64                 pr_err("Server address not specified\n");
65                 return -1;
66         }
67
68         h = OWNET_init(server_addr);
69         if (h < 0) {
70                 pr_err("Failed to connect to server %s\n", server_addr);
71                 return -1;
72         }
73
74         while (parser_data[i]) {
75                 double offset = 0, data;
76                 char *endptr;
77                 char ow_path[1024];
78
79                 if (!strcmp("U", parser_data[i])) {
80 undefined:
81                         ret = snprintf(rrd_data, max_str, "U");
82                         max_str -= ret;
83                         rrd_data += ret;
84                         goto next;
85                 }
86
87                 parse_opts(parser_data[i], ow_path, sizeof(ow_path), &offset);
88
89                 pr_info("Reading data for entry %s with offset of %.2f\n",
90                         ow_path, offset);
91                 ret = OWNET_read(h, ow_path, &tmp);
92                 if (ret < 0) {
93                         pr_err("Failed to read entry %s\n", parser_data[i]);
94                         goto undefined;
95                 }
96
97                 /* The data from OWNET_read appears to not be NULL terminated */
98                 memcpy(buf, tmp, MIN(ret, sizeof(buf) -1));
99                 free(tmp);
100                 buf[ret] = 0;
101
102                 data = strtod(buf, &endptr);
103
104                 if (endptr == buf) {
105                         pr_err("Failed to parse data %s\n", buf);
106                         goto undefined;
107                 }
108
109                 data += offset;
110
111                 ret = snprintf(rrd_data, max_str, "%f", data);
112                 max_str -= ret;
113                 rrd_data += ret;
114
115 next:
116                 i++;
117                 if (!parser_data[i])
118                         break;
119
120                 ret = snprintf(rrd_data, max_str, ":");
121                 max_str -= ret;
122                 rrd_data += ret;
123         }
124         rrd_data = 0;
125
126         OWNET_finish();
127         return 0;
128 }
129
130 static struct parser_info onewire_parser_info = {
131         .name = "onewire",
132         .parse = onewire_parser,
133 };
134
135 static int init_onewire_parser(void)
136 {
137         return register_parser(&onewire_parser_info);
138 }
139
140 struct plugin_info plugin_info = {
141         .name = "onewire_parser",
142         .init = init_onewire_parser,
143 };