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 "RRDTool",
38 rrdtool_functions,
39 NULL,
40 NULL,
41 NULL,
42 NULL,
43 PHP_MINFO(rrdtool),
44 STANDARD_MODULE_PROPERTIES,
45 };
47 #ifdef COMPILE_DL_RRDTOOL
48 ZEND_GET_MODULE(rrdtool)
49 #endif
51 PHP_MINFO_FUNCTION(rrdtool)
52 {
53 php_info_print_table_start();
54 php_info_print_table_header(2, "rrdtool support", "enabled");
55 php_info_print_table_end();
56 }
58 //PHP_MINIT_FUNCTION(rrdtool)
59 //{
60 // return SUCCESS;
61 //}
64 /* {{{ proto string rrd_error(void)
65 Get the error message set by the last rrd tool function call */
67 PHP_FUNCTION(rrd_error)
68 {
69 char *msg;
71 if ( rrd_test_error() )
72 {
73 msg = rrd_get_error();
75 RETVAL_STRING(msg, 1);
76 rrd_clear_error();
77 }
78 else
79 return;
80 }
81 /* }}} */
85 /* {{{ proto void rrd_clear_error(void)
86 Clear the error set by the last rrd tool function call */
88 PHP_FUNCTION(rrd_clear_error)
89 {
90 if ( rrd_test_error() )
91 rrd_clear_error();
93 return;
94 }
95 /* }}} */
99 /* {{{ proto int rrd_update(string file, string opt)
100 Update an RRD file with values specified */
102 PHP_FUNCTION(rrd_update)
103 {
104 pval *file, *opt;
105 char **argv;
107 if ( rrd_test_error() )
108 rrd_clear_error();
110 if ( ZEND_NUM_ARGS() == 2 &&
111 zend_get_parameters(ht, 2, &file, &opt) == SUCCESS )
112 {
113 convert_to_string(file);
114 convert_to_string(opt);
116 argv = (char **) emalloc(4 * sizeof(char *));
118 argv[0] = "dummy";
119 argv[1] = estrdup("update");
120 argv[2] = estrdup(file->value.str.val);
121 argv[3] = estrdup(opt->value.str.val);
123 optind = 0; opterr = 0;
124 if ( rrd_update(3, &argv[1]) != -1 )
125 {
126 RETVAL_TRUE;
127 }
128 else
129 {
130 RETVAL_FALSE;
131 }
132 efree(argv[1]); efree(argv[2]); efree(argv[3]);
133 efree(argv);
134 }
135 else
136 {
137 WRONG_PARAM_COUNT;
138 }
139 return;
140 }
141 /* }}} */
145 /* {{{ proto int rrd_last(string file)
146 Gets last update time of an RRD file */
148 PHP_FUNCTION(rrd_last)
149 {
150 pval *file;
151 unsigned long retval;
153 char **argv = (char **) emalloc(3 * sizeof(char *));
155 if ( rrd_test_error() )
156 rrd_clear_error();
158 if (zend_get_parameters(ht, 1, &file) == SUCCESS)
159 {
160 convert_to_string(file);
162 argv[0] = "dummy";
163 argv[1] = estrdup("last");
164 argv[2] = estrdup(file->value.str.val);
166 optind = 0; opterr = 0;
167 retval = rrd_last(2, &argv[1]);
169 efree(argv[1]); efree(argv[2]);
170 efree(argv);
171 RETVAL_LONG(retval);
172 }
173 else
174 {
175 WRONG_PARAM_COUNT;
176 }
177 return;
178 }
179 /* }}} */
182 /* {{{ proto int rrd_create(string file, array args_arr, int argc)
183 Create an RRD file with the options passed (passed via array) */
185 PHP_FUNCTION(rrd_create)
186 {
187 pval *file, *args, *p_argc;
188 pval *entry;
189 char **argv;
190 HashTable *args_arr;
191 int argc, i;
193 if ( rrd_test_error() )
194 rrd_clear_error();
196 if ( ZEND_NUM_ARGS() == 3 &&
197 getParameters(ht, 3, &file, &args, &p_argc) == SUCCESS )
198 {
199 if ( args->type != IS_ARRAY )
200 {
201 php_error(E_WARNING, "2nd Variable passed to rrd_create is not an array!\n");
202 RETURN_FALSE;
203 }
205 convert_to_long(p_argc);
206 convert_to_string(file);
208 convert_to_array(args);
209 args_arr = args->value.ht;
210 zend_hash_internal_pointer_reset(args_arr);
212 argc = p_argc->value.lval + 3;
213 argv = (char **) emalloc(argc * sizeof(char *));
215 argv[0] = "dummy";
216 argv[1] = estrdup("create");
217 argv[2] = estrdup(file->value.str.val);
219 for (i = 3; i < argc; i++)
220 {
221 pval **dataptr;
223 if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
224 continue;
226 entry = *dataptr;
228 if ( entry->type != IS_STRING )
229 convert_to_string(entry);
231 argv[i] = estrdup(entry->value.str.val);
233 if ( i < argc )
234 zend_hash_move_forward(args_arr);
235 }
237 optind = 0; opterr = 0;
239 if ( rrd_create(argc-1, &argv[1]) != -1 )
240 {
241 RETVAL_TRUE;
242 }
243 else
244 {
245 RETVAL_FALSE;
246 }
247 for (i = 1; i < argc; i++)
248 efree(argv[i]);
250 efree(argv);
251 }
252 else
253 {
254 WRONG_PARAM_COUNT;
255 }
256 return;
257 }
258 /* }}} */
262 /* {{{ proto mixed rrd_graph(string file, array args_arr, int argc)
263 Creates a graph based on options passed via an array */
265 PHP_FUNCTION(rrd_graph)
266 {
267 pval *file, *args, *p_argc;
268 pval *entry;
269 zval *p_calcpr;
270 HashTable *args_arr;
271 int i, xsize, ysize, argc;
272 char **argv, **calcpr;
275 if ( rrd_test_error() )
276 rrd_clear_error();
278 if ( ZEND_NUM_ARGS() == 3 &&
279 zend_get_parameters(ht, 3, &file, &args, &p_argc) == SUCCESS)
280 {
281 if ( args->type != IS_ARRAY )
282 {
283 php_error(E_WARNING, "2nd Variable passed to rrd_graph is not an array!\n");
284 RETURN_FALSE;
285 }
287 convert_to_long(p_argc);
288 convert_to_string(file);
290 convert_to_array(args);
291 args_arr = args->value.ht;
293 argc = p_argc->value.lval + 3;
294 argv = (char **) emalloc(argc * sizeof(char *));
296 argv[0] = "dummy";
297 argv[1] = estrdup("graph");
298 argv[2] = estrdup(file->value.str.val);
300 for (i = 3; i < argc; i++)
301 {
302 pval **dataptr;
304 if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
305 continue;
307 entry = *dataptr;
309 if ( entry->type != IS_STRING )
310 convert_to_string(entry);
312 argv[i] = estrdup(entry->value.str.val);
314 if ( i < argc )
315 zend_hash_move_forward(args_arr);
316 }
318 optind = 0; opterr = 0;
319 if ( rrd_graph(argc-1, &argv[1], &calcpr, &xsize, &ysize) != -1 )
320 {
321 array_init(return_value);
322 add_assoc_long(return_value, "xsize", xsize);
323 add_assoc_long(return_value, "ysize", ysize);
325 MAKE_STD_ZVAL(p_calcpr);
326 array_init(p_calcpr);
328 if (calcpr)
329 {
330 for (i = 0; calcpr[i]; i++)
331 {
332 add_next_index_string(p_calcpr, calcpr[i], 1);
333 free(calcpr[i]);
334 }
335 free(calcpr);
336 }
337 zend_hash_update(return_value->value.ht, "calcpr", sizeof("calcpr"),
338 (void *)&p_calcpr, sizeof(zval *), NULL);
339 }
340 else
341 {
342 RETVAL_FALSE;
343 }
344 for (i = 1; i < argc; i++)
345 efree(argv[i]);
347 efree(argv);
348 }
349 else
350 {
351 WRONG_PARAM_COUNT;
352 }
353 return;
354 }
355 /* }}} */
359 /* {{{ proto mixed rrd_fetch(string file, array args_arr, int p_argc)
360 Fetch info from an RRD file */
362 PHP_FUNCTION(rrd_fetch)
363 {
364 pval *file, *args, *p_argc;
365 pval *entry;
366 pval *p_start, *p_end, *p_step, *p_ds_cnt;
367 HashTable *args_arr;
368 zval *p_ds_namv, *p_data;
369 int i, argc;
370 time_t start, end;
371 unsigned long step, ds_cnt;
372 char **argv, **ds_namv;
373 rrd_value_t *data, *datap;
375 if ( rrd_test_error() )
376 rrd_clear_error();
378 if ( ZEND_NUM_ARGS() == 3 &&
379 zend_get_parameters(ht, 3, &file, &args, &p_argc) == SUCCESS)
380 {
381 if ( args->type != IS_ARRAY )
382 {
383 php_error(E_WARNING, "2nd Variable passed to rrd_fetch is not an array!\n");
384 RETURN_FALSE;
385 }
387 convert_to_long(p_argc);
388 convert_to_string(file);
390 convert_to_array(args);
391 args_arr = args->value.ht;
393 argc = p_argc->value.lval + 3;
394 argv = (char **) emalloc(argc * sizeof(char *));
396 argv[0] = "dummy";
397 argv[1] = estrdup("fetch");
398 argv[2] = estrdup(file->value.str.val);
400 for (i = 3; i < argc; i++)
401 {
402 pval **dataptr;
404 if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
405 continue;
407 entry = *dataptr;
409 if ( entry->type != IS_STRING )
410 convert_to_string(entry);
412 argv[i] = estrdup(entry->value.str.val);
414 if ( i < argc )
415 zend_hash_move_forward(args_arr);
416 }
418 optind = 0; opterr = 0;
420 if ( rrd_fetch(argc-1, &argv[1], &start,&end,&step,&ds_cnt,&ds_namv,&data) != -1 )
421 {
422 array_init(return_value);
423 add_assoc_long(return_value, "start", start);
424 add_assoc_long(return_value, "end", end);
425 add_assoc_long(return_value, "step", step);
426 add_assoc_long(return_value, "ds_cnt", ds_cnt);
428 MAKE_STD_ZVAL(p_ds_namv);
429 MAKE_STD_ZVAL(p_data);
430 array_init(p_ds_namv);
431 array_init(p_data);
433 if (ds_namv)
434 {
435 for (i = 0; i < ds_cnt; i++)
436 {
437 add_next_index_string(p_ds_namv, ds_namv[i], 1);
438 free(ds_namv[i]);
439 }
440 free(ds_namv);
441 }
443 if (data)
444 {
445 datap = data;
447 for (i = start; i <= end; i += step)
448 add_next_index_double(p_data, *(datap++));
450 free(data);
451 }
453 zend_hash_update(return_value->value.ht, "ds_namv", sizeof("ds_namv"),
454 (void *)&p_ds_namv, sizeof(zval *), NULL);
455 zend_hash_update(return_value->value.ht, "data", sizeof("data"),
456 (void *)&p_data, sizeof(zval *), NULL);
457 }
458 else
459 {
460 RETVAL_FALSE;
461 }
462 for (i = 1; i < argc; i++)
463 efree(argv[i]);
465 efree(argv);
466 }
467 else
468 {
469 WRONG_PARAM_COUNT;
470 }
471 return;
472 }
473 /* }}} */
475 #endif /* HAVE_RRDTOOL */