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