/* * * php4_rrdtool.c * * PHP interface to RRD Tool. (for php4/zend) * * * Joe Miller, , * iBIZ Technology Corp, SkyLynx / Inficad Communications * 2/12/2000 & 7/18/2000 * * * See README, INSTALL, and USAGE files for more details. * * $Id: rrdtool.c,v 1.1.1.1 2002/02/26 10:21:20 oetiker Exp $ * */ #include "php.h" #include "rrd.h" #include "php_rrdtool.h" #if HAVE_RRDTOOL function_entry rrdtool_functions[] = { PHP_FE(rrd_error, NULL) PHP_FE(rrd_clear_error, NULL) PHP_FE(rrd_graph, NULL) PHP_FE(rrd_last, NULL) PHP_FE(rrd_fetch, NULL) PHP_FE(rrd_update, NULL) PHP_FE(rrd_create, NULL) {NULL, NULL, NULL} }; zend_module_entry rrdtool_module_entry = { "RRDTool", rrdtool_functions, NULL, NULL, NULL, NULL, PHP_MINFO(rrdtool), STANDARD_MODULE_PROPERTIES, }; #ifdef COMPILE_DL_RRDTOOL ZEND_GET_MODULE(rrdtool) #endif PHP_MINFO_FUNCTION(rrdtool) { php_info_print_table_start(); php_info_print_table_header(2, "rrdtool support", "enabled"); php_info_print_table_end(); } //PHP_MINIT_FUNCTION(rrdtool) //{ // return SUCCESS; //} /* {{{ proto string rrd_error(void) Get the error message set by the last rrd tool function call */ PHP_FUNCTION(rrd_error) { char *msg; if ( rrd_test_error() ) { msg = rrd_get_error(); RETVAL_STRING(msg, 1); rrd_clear_error(); } else return; } /* }}} */ /* {{{ proto void rrd_clear_error(void) Clear the error set by the last rrd tool function call */ PHP_FUNCTION(rrd_clear_error) { if ( rrd_test_error() ) rrd_clear_error(); return; } /* }}} */ /* {{{ proto int rrd_update(string file, string opt) Update an RRD file with values specified */ PHP_FUNCTION(rrd_update) { pval *file, *opt; char **argv; if ( rrd_test_error() ) rrd_clear_error(); if ( ZEND_NUM_ARGS() == 2 && zend_get_parameters(ht, 2, &file, &opt) == SUCCESS ) { convert_to_string(file); convert_to_string(opt); argv = (char **) emalloc(4 * sizeof(char *)); argv[0] = "dummy"; argv[1] = estrdup("update"); argv[2] = estrdup(file->value.str.val); argv[3] = estrdup(opt->value.str.val); optind = 0; opterr = 0; if ( rrd_update(3, &argv[1]) != -1 ) { RETVAL_TRUE; } else { RETVAL_FALSE; } efree(argv[1]); efree(argv[2]); efree(argv[3]); efree(argv); } else { WRONG_PARAM_COUNT; } return; } /* }}} */ /* {{{ proto int rrd_last(string file) Gets last update time of an RRD file */ PHP_FUNCTION(rrd_last) { pval *file; unsigned long retval; char **argv = (char **) emalloc(3 * sizeof(char *)); if ( rrd_test_error() ) rrd_clear_error(); if (zend_get_parameters(ht, 1, &file) == SUCCESS) { convert_to_string(file); argv[0] = "dummy"; argv[1] = estrdup("last"); argv[2] = estrdup(file->value.str.val); optind = 0; opterr = 0; retval = rrd_last(2, &argv[1]); efree(argv[1]); efree(argv[2]); efree(argv); RETVAL_LONG(retval); } else { WRONG_PARAM_COUNT; } return; } /* }}} */ /* {{{ proto int rrd_create(string file, array args_arr, int argc) Create an RRD file with the options passed (passed via array) */ PHP_FUNCTION(rrd_create) { pval *file, *args, *p_argc; pval *entry; char **argv; HashTable *args_arr; int argc, i; if ( rrd_test_error() ) rrd_clear_error(); if ( ZEND_NUM_ARGS() == 3 && getParameters(ht, 3, &file, &args, &p_argc) == SUCCESS ) { if ( args->type != IS_ARRAY ) { php_error(E_WARNING, "2nd Variable passed to rrd_create is not an array!\n"); RETURN_FALSE; } convert_to_long(p_argc); convert_to_string(file); convert_to_array(args); args_arr = args->value.ht; zend_hash_internal_pointer_reset(args_arr); argc = p_argc->value.lval + 3; argv = (char **) emalloc(argc * sizeof(char *)); argv[0] = "dummy"; argv[1] = estrdup("create"); argv[2] = estrdup(file->value.str.val); for (i = 3; i < argc; i++) { pval **dataptr; if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE ) continue; entry = *dataptr; if ( entry->type != IS_STRING ) convert_to_string(entry); argv[i] = estrdup(entry->value.str.val); if ( i < argc ) zend_hash_move_forward(args_arr); } optind = 0; opterr = 0; if ( rrd_create(argc-1, &argv[1]) != -1 ) { RETVAL_TRUE; } else { RETVAL_FALSE; } for (i = 1; i < argc; i++) efree(argv[i]); efree(argv); } else { WRONG_PARAM_COUNT; } return; } /* }}} */ /* {{{ proto mixed rrd_graph(string file, array args_arr, int argc) Creates a graph based on options passed via an array */ PHP_FUNCTION(rrd_graph) { pval *file, *args, *p_argc; pval *entry; zval *p_calcpr; HashTable *args_arr; int i, xsize, ysize, argc; char **argv, **calcpr; if ( rrd_test_error() ) rrd_clear_error(); if ( ZEND_NUM_ARGS() == 3 && zend_get_parameters(ht, 3, &file, &args, &p_argc) == SUCCESS) { if ( args->type != IS_ARRAY ) { php_error(E_WARNING, "2nd Variable passed to rrd_graph is not an array!\n"); RETURN_FALSE; } convert_to_long(p_argc); convert_to_string(file); convert_to_array(args); args_arr = args->value.ht; argc = p_argc->value.lval + 3; argv = (char **) emalloc(argc * sizeof(char *)); argv[0] = "dummy"; argv[1] = estrdup("graph"); argv[2] = estrdup(file->value.str.val); for (i = 3; i < argc; i++) { pval **dataptr; if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE ) continue; entry = *dataptr; if ( entry->type != IS_STRING ) convert_to_string(entry); argv[i] = estrdup(entry->value.str.val); if ( i < argc ) zend_hash_move_forward(args_arr); } optind = 0; opterr = 0; if ( rrd_graph(argc-1, &argv[1], &calcpr, &xsize, &ysize) != -1 ) { array_init(return_value); add_assoc_long(return_value, "xsize", xsize); add_assoc_long(return_value, "ysize", ysize); MAKE_STD_ZVAL(p_calcpr); array_init(p_calcpr); if (calcpr) { for (i = 0; calcpr[i]; i++) { add_next_index_string(p_calcpr, calcpr[i], 1); free(calcpr[i]); } free(calcpr); } zend_hash_update(return_value->value.ht, "calcpr", sizeof("calcpr"), (void *)&p_calcpr, sizeof(zval *), NULL); } else { RETVAL_FALSE; } for (i = 1; i < argc; i++) efree(argv[i]); efree(argv); } else { WRONG_PARAM_COUNT; } return; } /* }}} */ /* {{{ proto mixed rrd_fetch(string file, array args_arr, int p_argc) Fetch info from an RRD file */ PHP_FUNCTION(rrd_fetch) { pval *file, *args, *p_argc; pval *entry; pval *p_start, *p_end, *p_step, *p_ds_cnt; HashTable *args_arr; zval *p_ds_namv, *p_data; int i, argc; time_t start, end; unsigned long step, ds_cnt; char **argv, **ds_namv; rrd_value_t *data, *datap; if ( rrd_test_error() ) rrd_clear_error(); if ( ZEND_NUM_ARGS() == 3 && zend_get_parameters(ht, 3, &file, &args, &p_argc) == SUCCESS) { if ( args->type != IS_ARRAY ) { php_error(E_WARNING, "2nd Variable passed to rrd_fetch is not an array!\n"); RETURN_FALSE; } convert_to_long(p_argc); convert_to_string(file); convert_to_array(args); args_arr = args->value.ht; argc = p_argc->value.lval + 3; argv = (char **) emalloc(argc * sizeof(char *)); argv[0] = "dummy"; argv[1] = estrdup("fetch"); argv[2] = estrdup(file->value.str.val); for (i = 3; i < argc; i++) { pval **dataptr; if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE ) continue; entry = *dataptr; if ( entry->type != IS_STRING ) convert_to_string(entry); argv[i] = estrdup(entry->value.str.val); if ( i < argc ) zend_hash_move_forward(args_arr); } optind = 0; opterr = 0; if ( rrd_fetch(argc-1, &argv[1], &start,&end,&step,&ds_cnt,&ds_namv,&data) != -1 ) { array_init(return_value); add_assoc_long(return_value, "start", start); add_assoc_long(return_value, "end", end); add_assoc_long(return_value, "step", step); add_assoc_long(return_value, "ds_cnt", ds_cnt); MAKE_STD_ZVAL(p_ds_namv); MAKE_STD_ZVAL(p_data); array_init(p_ds_namv); array_init(p_data); if (ds_namv) { for (i = 0; i < ds_cnt; i++) { add_next_index_string(p_ds_namv, ds_namv[i], 1); free(ds_namv[i]); } free(ds_namv); } if (data) { datap = data; for (i = start; i <= end; i += step) add_next_index_double(p_data, *(datap++)); free(data); } zend_hash_update(return_value->value.ht, "ds_namv", sizeof("ds_namv"), (void *)&p_ds_namv, sizeof(zval *), NULL); zend_hash_update(return_value->value.ht, "data", sizeof("data"), (void *)&p_data, sizeof(zval *), NULL); } else { RETVAL_FALSE; } for (i = 1; i < argc; i++) efree(argv[i]); efree(argv); } else { WRONG_PARAM_COUNT; } return; } /* }}} */ #endif /* HAVE_RRDTOOL */