1 /**
2 * collection4 - common.c
3 * Copyright (C) 2010 Florian octo Forster
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
19 *
20 * Authors:
21 * Florian octo Forster <ff at octo.it>
22 **/
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <stdint.h>
27 #include <inttypes.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <errno.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <dirent.h>
35 #include <assert.h>
36 #include <math.h>
38 #include <rrd.h>
40 #include "common.h"
41 #include "graph_list.h"
42 #include "utils_cgi.h"
44 #include <fcgiapp.h>
45 #include <fcgi_stdio.h>
47 size_t c_strlcat (char *dst, const char *src, size_t size) /* {{{ */
48 {
49 size_t retval;
50 size_t dst_len;
51 size_t src_len;
53 dst_len = strlen (dst);
54 src_len = strlen (src);
55 retval = dst_len + src_len;
57 if ((dst_len + 1) >= size)
58 return (retval);
60 dst += dst_len;
61 size -= dst_len;
62 assert (size >= 2);
64 /* Result will be truncated. */
65 if (src_len >= size)
66 src_len = size - 1;
68 memcpy (dst, src, src_len);
69 dst[src_len] = 0;
71 return (retval);
72 } /* }}} size_t c_strlcat */
74 int ds_list_from_rrd_file (char *file, /* {{{ */
75 size_t *ret_dses_num, char ***ret_dses)
76 {
77 char *rrd_argv[] = { "info", file, NULL };
78 int rrd_argc = (sizeof (rrd_argv) / sizeof (rrd_argv[0])) - 1;
80 rrd_info_t *info;
81 rrd_info_t *ptr;
83 char **dses = NULL;
84 size_t dses_num = 0;
86 info = rrd_info (rrd_argc, rrd_argv);
87 if (info == NULL)
88 {
89 printf ("%s: rrd_info (%s) failed.\n", __func__, file);
90 return (-1);
91 }
93 for (ptr = info; ptr != NULL; ptr = ptr->next)
94 {
95 size_t keylen;
96 size_t dslen;
97 char *ds;
98 char **tmp;
100 if (strncmp ("ds[", ptr->key, strlen ("ds[")) != 0)
101 continue;
103 keylen = strlen (ptr->key);
104 if (keylen < strlen ("ds[?].type"))
105 continue;
107 dslen = keylen - strlen ("ds[].type");
108 assert (dslen >= 1);
110 if (strcmp ("].type", ptr->key + (strlen ("ds[") + dslen)) != 0)
111 continue;
113 ds = malloc (dslen + 1);
114 if (ds == NULL)
115 continue;
117 memcpy (ds, ptr->key + strlen ("ds["), dslen);
118 ds[dslen] = 0;
120 tmp = realloc (dses, sizeof (*dses) * (dses_num + 1));
121 if (tmp == NULL)
122 {
123 free (ds);
124 continue;
125 }
126 dses = tmp;
128 dses[dses_num] = ds;
129 dses_num++;
130 }
132 rrd_info_free (info);
134 if (dses_num < 1)
135 {
136 assert (dses == NULL);
137 return (ENOENT);
138 }
140 *ret_dses_num = dses_num;
141 *ret_dses = dses;
143 return (0);
144 } /* }}} int ds_list_from_rrd_file */
146 static int hsv_to_rgb (double *hsv, double *rgb) /* {{{ */
147 {
148 double c = hsv[2] * hsv[1];
149 double h = hsv[0] / 60.0;
150 double x = c * (1.0 - fabs (fmod (h, 2.0) - 1));
151 double m = hsv[2] - c;
153 rgb[0] = 0.0;
154 rgb[1] = 0.0;
155 rgb[2] = 0.0;
157 if ((0.0 <= h) && (h < 1.0)) { rgb[0] = 1.0; rgb[1] = x; rgb[2] = 0.0; }
158 else if ((1.0 <= h) && (h < 2.0)) { rgb[0] = x; rgb[1] = 1.0; rgb[2] = 0.0; }
159 else if ((2.0 <= h) && (h < 3.0)) { rgb[0] = 0.0; rgb[1] = 1.0; rgb[2] = x; }
160 else if ((3.0 <= h) && (h < 4.0)) { rgb[0] = 0.0; rgb[1] = x; rgb[2] = 1.0; }
161 else if ((4.0 <= h) && (h < 5.0)) { rgb[0] = x; rgb[1] = 0.0; rgb[2] = 1.0; }
162 else if ((5.0 <= h) && (h < 6.0)) { rgb[0] = 1.0; rgb[1] = 0.0; rgb[2] = x; }
164 rgb[0] += m;
165 rgb[1] += m;
166 rgb[2] += m;
168 return (0);
169 } /* }}} int hsv_to_rgb */
171 static uint32_t rgb_to_uint32 (double *rgb) /* {{{ */
172 {
173 uint8_t r;
174 uint8_t g;
175 uint8_t b;
177 r = (uint8_t) (255.0 * rgb[0]);
178 g = (uint8_t) (255.0 * rgb[1]);
179 b = (uint8_t) (255.0 * rgb[2]);
181 return ((((uint32_t) r) << 16)
182 | (((uint32_t) g) << 8)
183 | ((uint32_t) b));
184 } /* }}} uint32_t rgb_to_uint32 */
186 static int uint32_to_rgb (uint32_t color, double *rgb) /* {{{ */
187 {
188 uint8_t r;
189 uint8_t g;
190 uint8_t b;
192 r = (uint8_t) ((color >> 16) & 0x00ff);
193 g = (uint8_t) ((color >> 8) & 0x00ff);
194 b = (uint8_t) ((color >> 0) & 0x00ff);
196 rgb[0] = ((double) r) / 255.0;
197 rgb[1] = ((double) g) / 255.0;
198 rgb[2] = ((double) b) / 255.0;
200 return (0);
201 } /* }}} int uint32_to_rgb */
203 uint32_t get_random_color (void) /* {{{ */
204 {
205 double hsv[3] = { 0.0, 1.0, 1.0 };
206 double rgb[3] = { 0.0, 0.0, 0.0 };
208 hsv[0] = 360.0 * ((double) rand ()) / (((double) RAND_MAX) + 1.0);
210 hsv_to_rgb (hsv, rgb);
212 return (rgb_to_uint32 (rgb));
213 } /* }}} uint32_t get_random_color */
215 uint32_t fade_color (uint32_t color) /* {{{ */
216 {
217 double rgb[3];
219 uint32_to_rgb (color, rgb);
220 rgb[0] = 1.0 - ((1.0 - rgb[0]) * 0.1);
221 rgb[1] = 1.0 - ((1.0 - rgb[1]) * 0.1);
222 rgb[2] = 1.0 - ((1.0 - rgb[2]) * 0.1);
224 return (rgb_to_uint32 (rgb));
225 } /* }}} uint32_t fade_color */
227 int print_debug (const char *format, ...) /* {{{ */
228 {
229 static _Bool have_header = 0;
231 va_list ap;
232 int status;
234 if (!have_header)
235 {
236 printf ("Content-Type: text/plain\n\n");
237 have_header = 1;
238 }
240 va_start (ap, format);
241 status = vprintf (format, ap);
242 va_end (ap);
244 return (status);
245 } /* }}} int print_debug */
247 char *strtolower (char *str) /* {{{ */
248 {
249 unsigned int i;
251 if (str == NULL)
252 return (NULL);
254 for (i = 0; str[i] != 0; i++)
255 str[i] = (char) tolower ((int) str[i]);
257 return (str);
258 } /* }}} char *strtolower */
260 char *strtolower_copy (const char *str) /* {{{ */
261 {
262 if (str == NULL)
263 return (NULL);
265 return (strtolower (strdup (str)));
266 } /* }}} char *strtolower_copy */
268 int get_time_args (long *ret_begin, long *ret_end, /* {{{ */
269 long *ret_now)
270 {
271 const char *begin_str;
272 const char *end_str;
273 long now;
274 long begin;
275 long end;
276 char *endptr;
277 long tmp;
279 if ((ret_begin == NULL) || (ret_end == NULL))
280 return (EINVAL);
282 begin_str = param ("begin");
283 end_str = param ("end");
285 now = (long) time (NULL);
286 if (ret_now != NULL)
287 *ret_now = now;
288 *ret_begin = now - 86400;
289 *ret_end = now;
291 if (begin_str != NULL)
292 {
293 endptr = NULL;
294 errno = 0;
295 tmp = strtol (begin_str, &endptr, /* base = */ 0);
296 if ((endptr == begin_str) || (errno != 0))
297 return (-1);
298 if (tmp <= 0)
299 begin = now + tmp;
300 else
301 begin = tmp;
302 }
303 else /* if (begin_str == NULL) */
304 {
305 begin = now - 86400;
306 }
308 if (end_str != NULL)
309 {
310 endptr = NULL;
311 errno = 0;
312 tmp = strtol (end_str, &endptr, /* base = */ 0);
313 if ((endptr == end_str) || (errno != 0))
314 return (-1);
315 end = tmp;
316 if (tmp <= 0)
317 end = now + tmp;
318 else
319 end = tmp;
320 }
321 else /* if (end_str == NULL) */
322 {
323 end = now;
324 }
326 if (begin == end)
327 return (-1);
329 if (begin > end)
330 {
331 tmp = begin;
332 begin = end;
333 end = tmp;
334 }
336 *ret_begin = begin;
337 *ret_end = end;
339 return (0);
340 } /* }}} int get_time_args */
342 /* vim: set sw=2 sts=2 et fdm=marker : */