1 /*
2 *
3 * php4_rrdtool.c
4 *
5 * PHP interface to RRD Tool. (for php4/zend)
6 *
7 *
8 * Joe Miller, <joeym@ibizcorp.com>, <joeym@inficad.com>
9 * iBIZ Technology Corp, SkyLynx / Inficad Communications
10 * 2/12/2000 & 7/18/2000
11 *
12 *
13 * See README, INSTALL, and USAGE files for more details.
14 *
15 * $Id$
16 *
17 */
19 #include "php.h"
20 #include "rrd.h"
21 #include "php_rrdtool.h"
23 #if HAVE_RRDTOOL
25 function_entry rrdtool_functions[] = {
26 PHP_FE(rrd_error, NULL)
27 PHP_FE(rrd_clear_error, NULL)
28 PHP_FE(rrd_graph, NULL)
29 PHP_FE(rrd_last, NULL)
30 PHP_FE(rrd_fetch, NULL)
31 PHP_FE(rrd_update, NULL)
32 PHP_FE(rrd_create, NULL)
33 {NULL, NULL, NULL}
34 };
36 zend_module_entry rrdtool_module_entry = {
37 #if ZEND_EXTENSION_API_NO >= 220050617
38 STANDARD_MODULE_HEADER_EX, NULL,
39 NULL, /* dependencies */
40 #else
41 STANDARD_MODULE_HEADER,
42 #endif
43 "RRDTool", /* name */
44 rrdtool_functions, /* functions */
45 NULL, /* module_startup_func */
46 NULL, /* module_shutdown_func */
47 NULL, /* request_startup_func */
48 NULL, /* request_shutdown_func */
49 PHP_MINFO(rrdtool), /* info_func */
50 NO_VERSION_YET,
51 STANDARD_MODULE_PROPERTIES
52 };
54 #ifdef COMPILE_DL_RRDTOOL
55 ZEND_GET_MODULE(rrdtool)
56 #endif
58 PHP_MINFO_FUNCTION(rrdtool)
59 {
60 php_info_print_table_start();
61 php_info_print_table_header(2, "rrdtool support", "enabled");
62 php_info_print_table_end();
63 }
65 //PHP_MINIT_FUNCTION(rrdtool)
66 //{
67 // return SUCCESS;
68 //}
71 /* {{{ proto string rrd_error(void)
72 Get the error message set by the last rrd tool function call */
74 PHP_FUNCTION(rrd_error)
75 {
76 char *msg;
78 if ( rrd_test_error() )
79 {
80 msg = rrd_get_error();
82 RETVAL_STRING(msg, 1);
83 rrd_clear_error();
84 }
85 else
86 return;
87 }
88 /* }}} */
92 /* {{{ proto void rrd_clear_error(void)
93 Clear the error set by the last rrd tool function call */
95 PHP_FUNCTION(rrd_clear_error)
96 {
97 if ( rrd_test_error() )
98 rrd_clear_error();
100 return;
101 }
102 /* }}} */
106 /* {{{ proto int rrd_update(string file, string opt)
107 Update an RRD file with values specified */
109 PHP_FUNCTION(rrd_update)
110 {
111 pval *file, *opt;
112 char **argv;
114 if ( rrd_test_error() )
115 rrd_clear_error();
117 if ( ZEND_NUM_ARGS() == 2 &&
118 zend_get_parameters(ht, 2, &file, &opt) == SUCCESS )
119 {
120 convert_to_string(file);
121 convert_to_string(opt);
123 argv = (char **) emalloc(4 * sizeof(char *));
125 argv[0] = "dummy";
126 argv[1] = estrdup("update");
127 argv[2] = estrdup(file->value.str.val);
128 argv[3] = estrdup(opt->value.str.val);
130 optind = 0; opterr = 0;
131 if ( rrd_update(3, &argv[1]) != -1 )
132 {
133 RETVAL_TRUE;
134 }
135 else
136 {
137 RETVAL_FALSE;
138 }
139 efree(argv[1]); efree(argv[2]); efree(argv[3]);
140 efree(argv);
141 }
142 else
143 {
144 WRONG_PARAM_COUNT;
145 }
146 return;
147 }
148 /* }}} */
152 /* {{{ proto int rrd_last(string file)
153 Gets last update time of an RRD file */
155 PHP_FUNCTION(rrd_last)
156 {
157 pval *file;
158 unsigned long retval;
160 char **argv = (char **) emalloc(3 * sizeof(char *));
162 if ( rrd_test_error() )
163 rrd_clear_error();
165 if (zend_get_parameters(ht, 1, &file) == SUCCESS)
166 {
167 convert_to_string(file);
169 argv[0] = "dummy";
170 argv[1] = estrdup("last");
171 argv[2] = estrdup(file->value.str.val);
173 optind = 0; opterr = 0;
174 retval = rrd_last(2, &argv[1]);
176 efree(argv[1]); efree(argv[2]);
177 efree(argv);
178 RETVAL_LONG(retval);
179 }
180 else
181 {
182 WRONG_PARAM_COUNT;
183 }
184 return;
185 }
186 /* }}} */
189 /* {{{ proto int rrd_create(string file, array args_arr, int argc)
190 Create an RRD file with the options passed (passed via array) */
192 PHP_FUNCTION(rrd_create)
193 {
194 pval *file, *args, *p_argc;
195 pval *entry;
196 char **argv;
197 HashTable *args_arr;
198 int argc, i;
200 if ( rrd_test_error() )
201 rrd_clear_error();
203 if ( ZEND_NUM_ARGS() == 3 &&
204 getParameters(ht, 3, &file, &args, &p_argc) == SUCCESS )
205 {
206 if ( args->type != IS_ARRAY )
207 {
208 php_error(E_WARNING, "2nd Variable passed to rrd_create is not an array!\n");
209 RETURN_FALSE;
210 }
212 convert_to_long(p_argc);
213 convert_to_string(file);
215 convert_to_array(args);
216 args_arr = args->value.ht;
217 zend_hash_internal_pointer_reset(args_arr);
219 argc = p_argc->value.lval + 3;
220 argv = (char **) emalloc(argc * sizeof(char *));
222 argv[0] = "dummy";
223 argv[1] = estrdup("create");
224 argv[2] = estrdup(file->value.str.val);
226 for (i = 3; i < argc; i++)
227 {
228 pval **dataptr;
230 if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
231 continue;
233 entry = *dataptr;
235 if ( entry->type != IS_STRING )
236 convert_to_string(entry);
238 argv[i] = estrdup(entry->value.str.val);
240 if ( i < argc )
241 zend_hash_move_forward(args_arr);
242 }
244 optind = 0; opterr = 0;
246 if ( rrd_create(argc-1, &argv[1]) != -1 )
247 {
248 RETVAL_TRUE;
249 }
250 else
251 {
252 RETVAL_FALSE;
253 }
254 for (i = 1; i < argc; i++)
255 efree(argv[i]);
257 efree(argv);
258 }
259 else
260 {
261 WRONG_PARAM_COUNT;
262 }
263 return;
264 }
265 /* }}} */
269 /* {{{ proto mixed rrd_graph(string file, array args_arr, int argc)
270 Creates a graph based on options passed via an array */
272 PHP_FUNCTION(rrd_graph)
273 {
274 pval *file, *args, *p_argc;
275 pval *entry;
276 zval *p_calcpr;
277 HashTable *args_arr;
278 int i, xsize, ysize, argc;
279 double ymin, ymax;
280 char **argv, **calcpr;
283 if ( rrd_test_error() )
284 rrd_clear_error();
286 if ( ZEND_NUM_ARGS() == 3 &&
287 zend_get_parameters(ht, 3, &file, &args, &p_argc) == SUCCESS)
288 {
289 if ( args->type != IS_ARRAY )
290 {
291 php_error(E_WARNING, "2nd Variable passed to rrd_graph is not an array!\n");
292 RETURN_FALSE;
293 }
295 convert_to_long(p_argc);
296 convert_to_string(file);
298 convert_to_array(args);
299 args_arr = args->value.ht;
301 argc = p_argc->value.lval + 3;
302 argv = (char **) emalloc(argc * sizeof(char *));
304 argv[0] = "dummy";
305 argv[1] = estrdup("graph");
306 argv[2] = estrdup(file->value.str.val);
308 for (i = 3; i < argc; i++)
309 {
310 pval **dataptr;
312 if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
313 continue;
315 entry = *dataptr;
317 if ( entry->type != IS_STRING )
318 convert_to_string(entry);
320 argv[i] = estrdup(entry->value.str.val);
322 if ( i < argc )
323 zend_hash_move_forward(args_arr);
324 }
326 optind = 0; opterr = 0;
327 if ( rrd_graph(argc-1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin, &ymax) != -1 )
328 {
329 array_init(return_value);
330 add_assoc_long(return_value, "xsize", xsize);
331 add_assoc_long(return_value, "ysize", ysize);
332 add_assoc_double(return_value, "ymin", ymin);
333 add_assoc_double(return_value, "ymax", ymax);
335 MAKE_STD_ZVAL(p_calcpr);
336 array_init(p_calcpr);
338 if (calcpr)
339 {
340 for (i = 0; calcpr[i]; i++)
341 {
342 add_next_index_string(p_calcpr, calcpr[i], 1);
343 free(calcpr[i]);
344 }
345 free(calcpr);
346 }
347 zend_hash_update(return_value->value.ht, "calcpr", sizeof("calcpr"),
348 (void *)&p_calcpr, sizeof(zval *), NULL);
349 }
350 else
351 {
352 RETVAL_FALSE;
353 }
354 for (i = 1; i < argc; i++)
355 efree(argv[i]);
357 efree(argv);
358 }
359 else
360 {
361 WRONG_PARAM_COUNT;
362 }
363 return;
364 }
365 /* }}} */
369 /* {{{ proto mixed rrd_fetch(string file, array args_arr, int p_argc)
370 Fetch info from an RRD file */
372 PHP_FUNCTION(rrd_fetch)
373 {
374 pval *file, *args, *p_argc;
375 pval *entry;
376 pval *p_start, *p_end, *p_step, *p_ds_cnt;
377 HashTable *args_arr;
378 zval *p_ds_namv, *p_data;
379 int i, argc;
380 time_t start, end;
381 unsigned long step, ds_cnt;
382 char **argv, **ds_namv;
383 rrd_value_t *data, *datap;
385 if ( rrd_test_error() )
386 rrd_clear_error();
388 if ( ZEND_NUM_ARGS() == 3 &&
389 zend_get_parameters(ht, 3, &file, &args, &p_argc) == SUCCESS)
390 {
391 if ( args->type != IS_ARRAY )
392 {
393 php_error(E_WARNING, "2nd Variable passed to rrd_fetch is not an array!\n");
394 RETURN_FALSE;
395 }
397 convert_to_long(p_argc);
398 convert_to_string(file);
400 convert_to_array(args);
401 args_arr = args->value.ht;
403 argc = p_argc->value.lval + 3;
404 argv = (char **) emalloc(argc * sizeof(char *));
406 argv[0] = "dummy";
407 argv[1] = estrdup("fetch");
408 argv[2] = estrdup(file->value.str.val);
410 for (i = 3; i < argc; i++)
411 {
412 pval **dataptr;
414 if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
415 continue;
417 entry = *dataptr;
419 if ( entry->type != IS_STRING )
420 convert_to_string(entry);
422 argv[i] = estrdup(entry->value.str.val);
424 if ( i < argc )
425 zend_hash_move_forward(args_arr);
426 }
428 optind = 0; opterr = 0;
430 if ( rrd_fetch(argc-1, &argv[1], &start,&end,&step,&ds_cnt,&ds_namv,&data) != -1 )
431 {
432 array_init(return_value);
433 add_assoc_long(return_value, "start", start);
434 add_assoc_long(return_value, "end", end);
435 add_assoc_long(return_value, "step", step);
436 add_assoc_long(return_value, "ds_cnt", ds_cnt);
438 MAKE_STD_ZVAL(p_ds_namv);
439 MAKE_STD_ZVAL(p_data);
440 array_init(p_ds_namv);
441 array_init(p_data);
443 if (ds_namv)
444 {
445 for (i = 0; i < ds_cnt; i++)
446 {
447 add_next_index_string(p_ds_namv, ds_namv[i], 1);
448 free(ds_namv[i]);
449 }
450 free(ds_namv);
451 }
453 if (data)
454 {
455 datap = data;
457 for (i = start; i <= end; i += step)
458 add_next_index_double(p_data, *(datap++));
460 free(data);
461 }
463 zend_hash_update(return_value->value.ht, "ds_namv", sizeof("ds_namv"),
464 (void *)&p_ds_namv, sizeof(zval *), NULL);
465 zend_hash_update(return_value->value.ht, "data", sizeof("data"),
466 (void *)&p_data, sizeof(zval *), NULL);
467 }
468 else
469 {
470 RETVAL_FALSE;
471 }
472 for (i = 1; i < argc; i++)
473 efree(argv[i]);
475 efree(argv);
476 }
477 else
478 {
479 WRONG_PARAM_COUNT;
480 }
481 return;
482 }
483 /* }}} */
485 #endif /* HAVE_RRDTOOL */