Code

lets have just a single rrdtool extension annd not two ...
[rrdtool-all.git] / contrib / php4 / rrdtool.c
1 /*
2  *
3  * php_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  *       Jeffrey Wheat <jeff@cetlink.net> - 10/01/2002
13  *          - Fixed to build with php-4.2.3
14  *
15  * See README, INSTALL, and USAGE files for more details.
16  *
17  * $Id$
18  *
19  */
21 /* PHP Includes */
22 #include "php.h"
23 #include "php_logos.h"
24 #include "ext/standard/info.h"
25 #include "SAPI.h"
27 /* rrdtool includes */
28 #include "php_rrdtool.h"
29 #include "rrdtool_logo.h"
30 #include <rrd.h>
32 #ifdef HAVE_CONFIG_H
33 #include "php_config.h"
34 #endif
36 #if HAVE_RRDTOOL
38 /* If you declare any globals in php_rrdtool.h uncomment this:
39 ZEND_DECLARE_MODULE_GLOBALS(rrdtool)
40  */
42 function_entry rrdtool_functions[] = {
43         PHP_FE(rrd_graph, NULL)
44         PHP_FE(rrd_fetch, NULL)
45         PHP_FE(rrd_error, NULL)
46         PHP_FE(rrd_clear_error, NULL)
47         PHP_FE(rrd_update, NULL)
48         PHP_FE(rrd_last, NULL)
49         PHP_FE(rrd_create, NULL)
50         PHP_FE(rrdtool_info, NULL)
51         PHP_FE(rrdtool_logo_guid, NULL)
52         {NULL, NULL, NULL}
53 };
55 zend_module_entry rrdtool_module_entry = {
56 #if ZEND_EXTENSION_API_NO >= 220050617
57         STANDARD_MODULE_HEADER_EX, NULL,
58         NULL, /* dependencies */
59 #else
60         STANDARD_MODULE_HEADER,
61 #endif
62         "rrdtool", /* name */
63         rrdtool_functions, /* functions */
64         PHP_MINIT(rrdtool), /* module_startup_func */
65         PHP_MSHUTDOWN(rrdtool), /* module_shutdown_func */
66         NULL, /* request_startup_func */
67         NULL, /* request_shutdown_func */
68         PHP_MINFO(rrdtool), /* info_func */
69         NO_VERSION_YET,
70         STANDARD_MODULE_PROPERTIES
71 };
73 #ifdef COMPILE_DL_RRDTOOL
74 ZEND_GET_MODULE(rrdtool)
75 #endif
77 #ifdef COMPILE_DL_RRDTOOL
78 #define PHP_RRD_VERSION_STRING "1.2.x extension"
79 #else
80 #define PHP_RRD_VERSION_STRING "1.2.x bundled"
81 #endif
83 /* {{{ PHP_MINIT_FUNCTION */
84 PHP_MINIT_FUNCTION(rrdtool)
85 {
86         php_register_info_logo(RRDTOOL_LOGO_GUID   , "image/gif", rrdtool_logo   , sizeof(rrdtool_logo));
87         
88         return SUCCESS;
89 }
90 /* }}} */
92 /* {{{ PHP_MSHUTDOWN_FUNCTION */
93 PHP_MSHUTDOWN_FUNCTION(rrdtool)
94 {
95         php_unregister_info_logo(RRDTOOL_LOGO_GUID);
96         
97         return SUCCESS;
98 }
99 /* }}} */
101 /* {{{ PHP_MINFO_FUNCTION */
102 PHP_MINFO_FUNCTION(rrdtool)
104         php_info_print_box_start(1);
105         PUTS("<a href=\"http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/\" target=\"rrdtool\"><img border=\"0\" src=\"");
106         if (SG(request_info).request_uri) {
107                 PUTS(SG(request_info).request_uri);
108         }
109         PUTS("?="RRDTOOL_LOGO_GUID"\" alt=\"ClamAV logo\" /></a>\n");
110         php_printf("<h1 class=\"p\">rrdtool Version %s</h1>\n", PHP_RRD_VERSION_STRING);
111         php_info_print_box_end();
112         php_info_print_table_start();
113         php_info_print_table_row(2, "rrdtool support", "enabled");
114         php_info_print_table_end();
116 /* }}} */
118 /* {{{ proto mixed rrd_graph(string file, array args_arr, int argc)
119         Creates a graph based on options passed via an array */
120 PHP_FUNCTION(rrd_graph)
122         pval *file, *args, *p_argc;
123         pval *entry;
124         zval *p_calcpr;
125         HashTable *args_arr;
126         int i, xsize, ysize, argc;
127         double ymin, ymax;
128         char **argv, **calcpr;
129     
131         if ( rrd_test_error() )
132                 rrd_clear_error();
133     
134         if ( (ZEND_NUM_ARGS() >= 3 && ZEND_NUM_ARGS() <= 6) &&
135                 zend_get_parameters(ht, 3, &file, &args, &p_argc) == SUCCESS)
136         {
137                 if ( args->type != IS_ARRAY )
138                 { 
139                         php_error(E_WARNING, "2nd Variable passed to rrd_graph is not an array!\n");
140                         RETURN_FALSE;
141                 }
142         
143                 convert_to_long(p_argc);
144                 convert_to_string(file);
146                 convert_to_array(args);
147                 args_arr = args->value.ht;
149                 argc = p_argc->value.lval + 3;
150                 argv = (char **) emalloc(argc * sizeof(char *));
151  
152                 argv[0] = "dummy";
153                 argv[1] = estrdup("graph");
154                 argv[2] = estrdup(file->value.str.val);
156                 for (i = 3; i < argc; i++) 
157                 {
158                         pval **dataptr;
160                         if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
161                                 continue;
163                         entry = *dataptr;
165                         if ( entry->type != IS_STRING )
166                                 convert_to_string(entry);
168                         argv[i] = estrdup(entry->value.str.val);
170                         if ( i < argc )
171                                 zend_hash_move_forward(args_arr);
172                 }
173    
174                 optind = 0; opterr = 0; 
175                 if ( rrd_graph(argc-1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin, &ymax) != -1 )
176                 {
177                         array_init(return_value);
178                         add_assoc_long(return_value, "xsize", xsize);
179                         add_assoc_long(return_value, "ysize", ysize);
180                         add_assoc_double(return_value, "ymin", ymin);
181                         add_assoc_double(return_value, "ymax", ymax);
183                         MAKE_STD_ZVAL(p_calcpr);
184                         array_init(p_calcpr);
185     
186                         if (calcpr)
187                         {
188                                 for (i = 0; calcpr[i]; i++)
189                                 {
190                                         add_next_index_string(p_calcpr, calcpr[i], 1);
191                                         free(calcpr[i]);
192                                 }
193                                 free(calcpr);
194                         }
195                         zend_hash_update(return_value->value.ht, "calcpr", sizeof("calcpr"), 
196                                                         (void *)&p_calcpr, sizeof(zval *), NULL);
197                 }
198                 else
199                 {
200                         RETVAL_FALSE;
201                 }
202                 for (i = 1; i < argc; i++)
203                         efree(argv[i]);
205                 efree(argv);
206         }
207         else
208         { 
209                 WRONG_PARAM_COUNT;
210         }
211         return;
213 /* }}} */
215 /* {{{ proto mixed rrd_fetch(string file, array args_arr, int p_argc)
216         Fetch info from an RRD file */
217 PHP_FUNCTION(rrd_fetch)
219         pval *file, *args, *p_argc;
220         pval *entry;
221         pval *p_start, *p_end, *p_step, *p_ds_cnt;
222         HashTable *args_arr;
223         zval *p_ds_namv, *p_data;
224         int i, j, argc;
225         time_t start, end;
226         unsigned long step, ds_cnt;
227         char **argv, **ds_namv; 
228         rrd_value_t *data, *datap;
229     
230         if ( rrd_test_error() )
231                 rrd_clear_error();
232     
233         if ( ZEND_NUM_ARGS() == 3 && 
234                  zend_get_parameters(ht, 3, &file, &args, &p_argc) == SUCCESS)
235         {
236                 if ( args->type != IS_ARRAY )
237                 { 
238                         php_error(E_WARNING, "2nd Variable passed to rrd_fetch is not an array!\n");
239                         RETURN_FALSE;
240                 }
241         
242                 convert_to_long(p_argc);
243                 convert_to_string(file);
245                 convert_to_array(args);
246                 args_arr = args->value.ht;
248                 argc = p_argc->value.lval + 3;
249                 argv = (char **) emalloc(argc * sizeof(char *));
250  
251                 argv[0] = "dummy";
252                 argv[1] = estrdup("fetch");
253                 argv[2] = estrdup(file->value.str.val);
255                 for (i = 3; i < argc; i++) 
256                 {
257                         pval **dataptr;
259                         if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
260                                 continue;
262                         entry = *dataptr;
264                         if ( entry->type != IS_STRING )
265                                 convert_to_string(entry);
267                         argv[i] = estrdup(entry->value.str.val);
269                         if ( i < argc )
270                                 zend_hash_move_forward(args_arr);
271                 }
272   
273                 optind = 0; opterr = 0; 
275                 if ( rrd_fetch(argc-1, &argv[1], &start,&end,&step,&ds_cnt,&ds_namv,&data) != -1 )
276                 {
277                         array_init(return_value);
278                         add_assoc_long(return_value, "start", start);
279                         add_assoc_long(return_value, "end", end);
280                         add_assoc_long(return_value, "step", step);
281                         add_assoc_long(return_value, "ds_cnt", ds_cnt);
283                         MAKE_STD_ZVAL(p_ds_namv);
284                         MAKE_STD_ZVAL(p_data);
285                         array_init(p_ds_namv);
286                         array_init(p_data);
287    
288                         if (ds_namv)
289                         {
290                                 for (i = 0; i < ds_cnt; i++)
291                                 {
292                                         add_next_index_string(p_ds_namv, ds_namv[i], 1);
293                                         free(ds_namv[i]);
294                                 }
295                                 free(ds_namv);
296                         }
298                         if (data)
299                         {
300                                 datap = data;
301  
302                                 for (i = start; i <= end; i += step)
303                                         for (j = 0; j < ds_cnt; j++)
304                                                 add_next_index_double(p_data, *(datap++));
305  
306                                 free(data);
307                         }
309                         zend_hash_update(return_value->value.ht, "ds_namv", sizeof("ds_namv"), 
310                                                         (void *)&p_ds_namv, sizeof(zval *), NULL);
311                         zend_hash_update(return_value->value.ht, "data", sizeof("data"), 
312                                                         (void *)&p_data, sizeof(zval *), NULL);
313                 }
314                 else
315                 {
316                         RETVAL_FALSE;
317                 }
318                 for (i = 1; i < argc; i++)
319                         efree(argv[i]);
321                 efree(argv);
322         }
323         else
324         { 
325                 WRONG_PARAM_COUNT;
326         }
327         return;
329 /* }}} */
331 /* {{{ proto string rrd_error(void)
332         Get the error message set by the last rrd tool function call */
333 PHP_FUNCTION(rrd_error)
335         char *msg;
337         if ( rrd_test_error() )
338         {
339                 msg = rrd_get_error();        
341                 RETVAL_STRING(msg, 1);
342                 rrd_clear_error();
343         }
344         else
345                 return;
347 /* }}} */
349 /* {{{ proto void rrd_clear_error(void)
350         Clear the error set by the last rrd tool function call */
351 PHP_FUNCTION(rrd_clear_error)
353         if ( rrd_test_error() )
354                 rrd_clear_error();
356         return;
358 /* }}} */
360 /* {{{ proto int rrd_update(string file, string opt) 
361         Update an RRD file with values specified */
362 PHP_FUNCTION(rrd_update)
364         pval *file, *opt;
365         char **argv;
367         if ( rrd_test_error() )
368                 rrd_clear_error();
370         if ( ZEND_NUM_ARGS() == 2 && 
371                  zend_get_parameters(ht, 2, &file, &opt) == SUCCESS )
372         {
373                 convert_to_string(file);
374                 convert_to_string(opt);
376                 argv = (char **) emalloc(4 * sizeof(char *));
378                 argv[0] = "dummy";
379                 argv[1] = estrdup("update");
380                 argv[2] = estrdup(file->value.str.val);
381                 argv[3] = estrdup(opt->value.str.val);
383                 optind = 0; opterr = 0;
384                 if ( rrd_update(3, &argv[1]) != -1 )
385                 {
386                         RETVAL_TRUE;
387                 }
388                 else
389                 {
390                         RETVAL_FALSE;
391                 }
392                 efree(argv[1]); efree(argv[2]); efree(argv[3]);
393                 efree(argv);
394         }
395         else
396         {
397                 WRONG_PARAM_COUNT;
398         }
399         return;
401 /* }}} */
403 /* {{{ proto int rrd_last(string file)
404         Gets last update time of an RRD file */
405 PHP_FUNCTION(rrd_last)
407         pval *file;
408         unsigned long retval;
410         char **argv = (char **) emalloc(3 * sizeof(char *));
411     
412         if ( rrd_test_error() )
413                 rrd_clear_error();
414     
415         if (zend_get_parameters(ht, 1, &file) == SUCCESS)
416         {
417                 convert_to_string(file);
419                 argv[0] = "dummy";
420                 argv[1] = estrdup("last");
421                 argv[2] = estrdup(file->value.str.val);
423                 optind = 0; opterr = 0;
424                 retval = rrd_last(2, &argv[1]);
426                 efree(argv[1]);  efree(argv[2]);
427                 efree(argv);
428                 RETVAL_LONG(retval);
429         }
430         else
431         {
432                 WRONG_PARAM_COUNT;
433         }
434         return;
436 /* }}} */
438 /* {{{ proto int rrd_create(string file, array args_arr, int argc)
439         Create an RRD file with the options passed (passed via array) */ 
440 PHP_FUNCTION(rrd_create)
442         pval *file, *args, *p_argc;
443         pval *entry;
444         char **argv;
445         HashTable *args_arr;
446         int argc, i;
448         if ( rrd_test_error() )
449                 rrd_clear_error();
451         if ( ZEND_NUM_ARGS() == 3 && 
452                 getParameters(ht, 3, &file, &args, &p_argc) == SUCCESS )
453         {
454                 if ( args->type != IS_ARRAY )
455                 { 
456                         php_error(E_WARNING, "2nd Variable passed to rrd_create is not an array!\n");
457                         RETURN_FALSE;
458                 }
460                 convert_to_long(p_argc);
461                 convert_to_string(file);
462                 
463                 convert_to_array(args);
464                 args_arr = args->value.ht;
465                 zend_hash_internal_pointer_reset(args_arr);
467                 argc = p_argc->value.lval + 3;
468                 argv = (char **) emalloc(argc * sizeof(char *));
470                 argv[0] = "dummy";
471                 argv[1] = estrdup("create");
472                 argv[2] = estrdup(file->value.str.val);
474                 for (i = 3; i < argc; i++) 
475                 {
476                         pval **dataptr;
478                         if ( zend_hash_get_current_data(args_arr, (void *) &dataptr) == FAILURE )
479                                 continue;
481                         entry = *dataptr;
483                         if ( entry->type != IS_STRING )
484                                 convert_to_string(entry);
486                         argv[i] = estrdup(entry->value.str.val);
488                         if ( i < argc )
489                                 zend_hash_move_forward(args_arr);
490                 }
491   
492                 optind = 0;  opterr = 0;
494                 if ( rrd_create(argc-1, &argv[1]) != -1 )
495                 {
496                         RETVAL_TRUE;
497                 }
498                 else
499                 {
500                         RETVAL_FALSE;
501                 }
502                 for (i = 1; i < argc; i++)
503                         efree(argv[i]);
505                 efree(argv);
506         }
507         else
508         {
509             WRONG_PARAM_COUNT;
510         }
511         return;
513 /* }}} */
515 PHP_FUNCTION(rrdtool_info)
518         if (ZEND_NUM_ARGS()!=0) {
519                 ZEND_WRONG_PARAM_COUNT();
520                 RETURN_FALSE;
521         }
523         PUTS("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"DTD/xhtml1-transitional.dtd\">\n");
524         PUTS("<html>");
525         PUTS("<head>\n");
526         PUTS("<style type=\"text/css\"><!--");
527         PUTS("body {background-color: #ffffff; color: #000000;}");
528         PUTS("body, td, th, h1, h2 {font-family: sans-serif;}");
529         PUTS("pre {margin: 0px; font-family: monospace;}");
530         PUTS("a:link {color: #000099; text-decoration: none; background-color: #ffffff;}");
531         PUTS("a:hover {text-decoration: underline;}");
532         PUTS("table {border-collapse: collapse;}");
533         PUTS(".center {text-align: center;}");
534         PUTS(".center table { margin-left: auto; margin-right: auto; text-align: left;}");
535         PUTS(".center th { text-align: center !important; }");
536         PUTS("td, th { border: 1px solid #000000; font-size: 75%; vertical-align: baseline;}");
537         PUTS("h1 {font-size: 150%;}");
538         PUTS("h2 {font-size: 125%;}");
539         PUTS(".p {text-align: left;}");
540         PUTS(".e {background-color: #ccccff; font-weight: bold; color: #000000;}");
541         PUTS(".h {background-color: #9999cc; font-weight: bold; color: #000000;}");
542         PUTS(".v {background-color: #cccccc; color: #000000;}");
543         PUTS("i {color: #666666; background-color: #cccccc;}");
544         PUTS("img {float: right; border: 0px;}");
545         PUTS("hr {width: 600px; background-color: #cccccc; border: 0px; height: 1px; color: #000000;}");
546         PUTS("//--></style>");
547         PUTS("<title>rrdtool_info()</title>");
548         PUTS("</head>\n");
549         PUTS("<body><div class=\"center\">\n");
551         php_info_print_box_start(1);
552         PUTS("<a href=\"http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/\" target=\"rrdtool\"><img border=\"0\" src=\"");
553         if (SG(request_info).request_uri) {
554                 PUTS(SG(request_info).request_uri);
555         }
556         PUTS("?="RRDTOOL_LOGO_GUID"\" alt=\"ClamAV logo\" /></a>\n");
557         php_printf("<h1 class=\"p\">rrdtool Version %s</h1>\n", PHP_RRD_VERSION_STRING);
558         php_info_print_box_end();
559         php_info_print_table_start();
560         php_info_print_table_row(2, "System", PHP_UNAME );
561         php_info_print_table_row(2, "Build Date", __DATE__ " " __TIME__ );
562         php_info_print_table_row(2, "rrdtool Support","Enabled");
563         php_info_print_table_end();
565         PUTS("<h2>RRDTOOL Copyright</h2>\n");
566         php_info_print_box_start(0);
567         PUTS("COPYRIGHT STATEMENT FOLLOWS THIS LINE</p>\n<blockquote>\n");
568         PUTS("<p>Portions copyright 2005 by Dale Walsh (buildsmart@daleenterprise.com).</p>\n");
569         PUTS("<p>Portions relating to rrdtool 1999, 2000, 2001, 2002, 2003, 2004, 2005 by Tobias Oetiker.</p>\n");
570         php_info_print_box_end();
571         PUTS("<h2>RRDTOOL License</h2>\n");
572         php_info_print_box_start(0);
573         PUTS("<p><b>Permission has been granted to copy, distribute and modify rrd in any context without fee, including a commercial application, provided that this notice is present in user-accessible supporting documentation. </b></p>");
574         PUTS("<p>This does not affect your ownership of the derived work itself, and the intent is to assure proper credit for the authors of rrdtool, not to interfere with your productive use of rrdtool. If you have questions, ask. \"Derived works\" ");
575         PUTS("includes all programs that utilize the library. Credit must be given in user-accessible documentation.</p>\n");
576         PUTS("<p><b>This software is provided \"AS IS.\"</b> The copyright holders disclaim all warranties, either express or implied, including but not limited to implied warranties of merchantability and fitness for a particular purpose, ");
577         PUTS("with respect to this code and accompanying documentation.</p>\n");
578         php_info_print_box_end();
579         PUTS("<h2>Special Thanks</h2>\n");
580         php_info_print_box_start(0);
581         PUTS("<p>Perl by Larry Wall");
582         PUTS("<p>gd library by Thomas Boutell");
583         PUTS("<p>gifcode from David Koblas");
584         PUTS("<p>libpng by Glenn Randers-Pehrson / Andreas Eric Dilger / Guy Eric Schalnat");
585         PUTS("<p>cgilib by Martin Schulze");
586         PUTS("<p>zlib by Jean-loup Gailly and Mark Adler");
587         PUTS("<p>Portions relating to php4 and php5 bindings, Dale Walsh (buildsmart@daleenterprise.com)");
588         php_info_print_box_end();
590         PUTS("</div></body></html>");
592 /* }}} */
594 PHP_FUNCTION(rrdtool_logo_guid)
596         if (ZEND_NUM_ARGS() != 0) {
597                 WRONG_PARAM_COUNT;
598         }
600         RETURN_STRINGL(RRDTOOL_LOGO_GUID, sizeof(RRDTOOL_LOGO_GUID)-1, 1);
602 /* }}} */
604 #endif  /* HAVE_RRDTOOL */
606 /*
607  * Local variables:
608  * tab-width: 4
609  * c-basic-offset: 4
610  * End:
611  * vim600: noet sw=4 ts=4 fdm=marker
612  * vim<600: noet sw=4 ts=4
613  */