]> git.itanic.dy.fi Git - rrdd/blob - rrdtool.c
parser: Define maximum length for the rrd data
[rrdd] / rrdtool.c
1 #include <time.h>
2
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <unistd.h>
6 #include <string.h>
7
8 #include "rrdtool.h"
9 #include "process.h"
10 #include "parser.h"
11
12 #define MAX_ARGS        512
13 #define ARGSTR_LEN      32768
14
15 #define RRDTOOL_CMD "/usr/bin/rrdtool"
16
17 /*
18  * Add new argument to a argument list
19  *
20  * args         pointer list to arguments
21  * argcnt       argument counter
22  * argstr       array where the actual arguments are stored
23  * idx          index in the argstr where the new argument will be appended
24  */
25 #define add_arg(args, argcnt, argstr, idx, fmt, arg...) \
26         args[argcnt] = argstr + idx;                    \
27         idx += sprintf(argstr + idx, fmt, ##arg);       \
28         argcnt++;                                       \
29         argstr[++idx] = 0
30
31 int rrdtool_draw_image(struct rrd_image *image)
32 {
33         char cmd[] = RRDTOOL_CMD;
34 //      char cmd[] = "echo";
35         char *args[512], argstr[ARGSTR_LEN];
36         int idx = 0, argcnt = 0, i,j;
37         char timestamp[256];
38         char tmp[256];
39         time_t t = time(0);
40
41         strftime(tmp, 256, "%d.%m.%Y %T (%Z) ", localtime(&t));
42         for (i = 0, j = 0; j < 256;) {
43                 if (tmp[i] == ':') {
44                         timestamp[j++] = '\\';
45                 }
46                 timestamp[j++] = tmp[i++];
47                 if (!tmp[i])
48                         break;
49         }
50         timestamp[j] = 0;
51
52
53         add_arg(args, argcnt, argstr, idx, " ");
54         add_arg(args, argcnt, argstr, idx, "graph");
55         add_arg(args, argcnt, argstr, idx, "%s", image->image_filename);
56
57         add_arg(args, argcnt, argstr, idx, "--start");
58         add_arg(args, argcnt, argstr, idx, "%s", image->timestart);
59         add_arg(args, argcnt, argstr, idx, "--end");
60         add_arg(args, argcnt, argstr, idx, "%s", image->timeend);
61         add_arg(args, argcnt, argstr, idx, "--width");
62         add_arg(args, argcnt, argstr, idx, "%d", image->width);
63         add_arg(args, argcnt, argstr, idx, "--height");
64         add_arg(args, argcnt, argstr, idx, "%d", image->height);
65         add_arg(args, argcnt, argstr, idx, "--imgformat");
66         add_arg(args, argcnt, argstr, idx, "%s", image->imageformat);
67
68         for (i = 0; image->options[i]; i++) {
69                 add_arg(args, argcnt, argstr, idx, "%s", image->options[i]);
70         }
71
72         for (i = 0; image->text[i]; i++) {
73                 args[argcnt++] = image->text[i];
74         }
75
76         add_arg(args, argcnt, argstr, idx, "COMMENT:Last update %s\\c", timestamp);
77
78         args[argcnt] = 0;
79
80         run(cmd, args);
81
82         return 0;
83 }
84
85 int rrdtool_draw_images(struct rrd_image **image)
86 {
87         int i;
88         for (i = 0; image[i]; i++)
89                 rrdtool_draw_image(image[i]);
90
91         return 0;
92 }
93
94 int rrdtool_update_data(struct rrd_database *rrd)
95 {
96         char data[RRD_DATA_MAX_LEN];
97         char cmd[] = RRDTOOL_CMD;
98 //      char cmd[] = "echo";
99         char *cmdline[] = {
100                 "",
101                 "update",
102                 rrd->filename,
103                 data,
104                 0
105         };
106         int l;
107
108         rrd->last_update = time(0);
109         if (do_fork())
110                 return 0;
111
112         l = sprintf(data, "N:");
113
114         if (rrd->parse) {
115                 rrd->parse(data + l, rrd->parser_data);
116                 run(cmd, cmdline);
117         }
118
119         if (rrd->images)
120                 rrdtool_draw_images(rrd->images);
121
122         while (harvest_zombies(0));
123         exit(0);
124 }
125
126 static int database_exists(struct rrd_database *db)
127 {
128         struct stat s;
129
130         /* If the filename exists, stat will return zero */
131         if (db->filename)
132                 return !stat(db->filename, &s);
133
134         return 1;
135 }
136
137 static int create_database(struct rrd_database *db)
138 {
139         char cmd[] = RRDTOOL_CMD;
140 //      char cmd[] = "echo";
141         char *args[512], argstr[ARGSTR_LEN];
142         int idx = 0, argcnt = 0;
143         int child, i;
144
145         if (!db->sources || !db->archives) {
146                 printf("Cannot create db \"%s\", insufficient source data\n",
147                         db->filename);
148                 return -1;
149         }
150
151         add_arg(args, argcnt, argstr, idx, " ");
152         add_arg(args, argcnt, argstr, idx, "create");
153         add_arg(args, argcnt, argstr, idx, "%s", db->filename);
154         add_arg(args, argcnt, argstr, idx, "--step");
155         add_arg(args, argcnt, argstr, idx, "%d", db->interval);
156
157         for (i = 0; db->sources[i].type; i++) {
158                 add_arg(args, argcnt, argstr, idx, "DS:%s:%s:%d:%f:%f",
159                         db->sources[i].name,
160                         db->sources[i].type,
161                         db->sources[i].heartbeat,
162                         db->sources[i].min,
163                         db->sources[i].max);
164         }
165
166         for (i = 0; db->archives[i].type; i++) {
167                 add_arg(args, argcnt, argstr, idx, "RRA:%s:%f:%d:%d",
168                         db->archives[i].type,
169                         db->archives[i].xff,
170                         db->archives[i].steps,
171                         db->archives[i].rows);
172         }
173
174         child = run(cmd, args);
175
176         harvest_zombies(child);
177
178         return 0;
179 }
180
181 int rrdtool_check_databases(struct rrd_database *dbs[])
182 {
183         struct rrd_database *db;
184         int i;
185
186         for (i = 0, db = dbs[i]; db; i++, db = dbs[i]) {
187                 if (database_exists(db)) {
188                         printf("database %s found\n", db->filename);
189                         continue;
190                 }
191                 printf("Database %s missing, creating\n", db->filename);
192                 create_database(db);
193         }
194         printf("All done\n");
195
196         return 0;
197 }