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