2 * tclrrd.c -- A TCL interpreter extension to access the RRD library.
4 * Copyright (c) 1999,2000 Frank Strauss, Technical University of Braunschweig.
6 * See the file "COPYING" for information on usage and redistribution
7 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
17 #include <rrd_format.h>
21 extern int __getopt_initialized;
25 * some rrd_XXX() functions might modify the argv strings passed to it.
26 * Furthermore, they use getopt() without initializing getopt's optind
27 * variable themselves. Hence, we need to do some preparation before
28 * calling the rrd library functions.
30 static char ** getopt_init(argc, argv)
39 argv2 = calloc(argc, sizeof(char *));
40 for (i = 0; i < argc; i++) {
41 argv2[i] = strdup(argv[i]);
46 static void getopt_cleanup(argc, argv2)
52 for (i = 0; i < argc; i++) {
61 Rrd_Create(clientData, interp, argc, argv)
62 ClientData clientData;
69 argv2 = getopt_init(argc, argv);
70 rrd_create(argc, argv2);
71 getopt_cleanup(argc, argv2);
73 if (rrd_test_error()) {
74 Tcl_AppendResult(interp, "RRD Error: ",
75 rrd_get_error(), (char *) NULL);
86 Rrd_Dump(clientData, interp, argc, argv)
87 ClientData clientData;
94 argv2 = getopt_init(argc, argv);
95 rrd_dump(argc, argv2);
96 getopt_cleanup(argv, argv2);
98 /* NOTE: rrd_dump() writes to stdout. No interaction with TCL. */
100 if (rrd_test_error()) {
101 Tcl_AppendResult(interp, "RRD Error: ",
102 rrd_get_error(), (char *) NULL);
113 Rrd_Last(clientData, interp, argc, argv)
114 ClientData clientData;
122 argv2 = getopt_init(argc, argv);
123 t = rrd_last(argc, argv2);
124 getopt_cleanup(argv, argv2);
127 if (rrd_test_error()) {
128 Tcl_AppendResult(interp, "RRD Error: ",
129 rrd_get_error(), (char *) NULL);
134 Tcl_SetIntObj(Tcl_GetObjResult(interp), t);
142 Rrd_Update(clientData, interp, argc, argv)
143 ClientData clientData;
150 argv2 = getopt_init(argc, argv);
151 rrd_update(argc, argv2);
152 getopt_cleanup(argv, argv2);
154 if (rrd_test_error()) {
155 Tcl_AppendResult(interp, "RRD Error: ",
156 rrd_get_error(), (char *) NULL);
167 Rrd_Fetch(clientData, interp, argc, argv)
168 ClientData clientData;
174 unsigned long step, ds_cnt, i, ii;
175 rrd_value_t *data, *datai;
181 argv2 = getopt_init(argc, argv);
182 if (rrd_fetch(argc, argv2, &start, &end, &step,
183 &ds_cnt, &ds_namv, &data) != -1) {
185 listPtr = Tcl_GetObjResult(interp);
186 for (i = start; i <= end; i += step) {
187 for (ii = 0; ii < ds_cnt; ii++) {
188 sprintf(s, "%.2f", *(datai++));
189 Tcl_ListObjAppendElement(interp, listPtr,
190 Tcl_NewStringObj(s, -1));
193 for (i=0; i<ds_cnt; i++) free(ds_namv[i]);
197 getopt_cleanup(argv, argv2);
199 if (rrd_test_error()) {
200 Tcl_AppendResult(interp, "RRD Error: ",
201 rrd_get_error(), (char *) NULL);
212 Rrd_Graph(clientData, interp, argc, argv)
213 ClientData clientData;
225 argv2 = getopt_init(argc, argv);
226 if (rrd_graph(argc, argv2, &calcpr, &xsize, &ysize) != -1 ) {
227 listPtr = Tcl_GetObjResult(interp);
228 Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(xsize));
229 Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(ysize));
234 for(i = 0; calcpr[i]; i++){
235 printf("%s\n", calcpr[i]);
242 getopt_cleanup(argv, argv2);
244 if (rrd_test_error()) {
245 Tcl_AppendResult(interp, "RRD Error: ",
246 rrd_get_error(), (char *) NULL);
257 Rrd_Tune(clientData, interp, argc, argv)
258 ClientData clientData;
265 argv2 = getopt_init(argc, argv);
266 rrd_tune(argc, argv2);
267 getopt_cleanup(argv, argv2);
269 if (rrd_test_error()) {
270 Tcl_AppendResult(interp, "RRD Error: ",
271 rrd_get_error(), (char *) NULL);
282 Rrd_Resize(clientData, interp, argc, argv)
283 ClientData clientData;
290 argv2 = getopt_init(argc, argv);
291 rrd_resize(argc, argv2);
292 getopt_cleanup(argv, argv2);
294 if (rrd_test_error()) {
295 Tcl_AppendResult(interp, "RRD Error: ",
296 rrd_get_error(), (char *) NULL);
307 Rrd_Restore(clientData, interp, argc, argv)
308 ClientData clientData;
315 argv2 = getopt_init(argc, argv);
316 rrd_restore(argc, argv2);
317 getopt_cleanup(argv, argv2);
319 if (rrd_test_error()) {
320 Tcl_AppendResult(interp, "RRD Error: ",
321 rrd_get_error(), (char *) NULL);
332 * The following structure defines the commands in the Rrd extension.
336 char *name; /* Name of the command. */
337 Tcl_CmdProc *proc; /* Procedure for command. */
340 static CmdInfo rrdCmds[] = {
341 { "Rrd::create", Rrd_Create },
342 { "Rrd::dump", Rrd_Dump },
343 { "Rrd::last", Rrd_Last },
344 { "Rrd::update", Rrd_Update },
345 { "Rrd::fetch", Rrd_Fetch },
346 { "Rrd::graph", Rrd_Graph },
347 { "Rrd::tune", Rrd_Tune },
348 { "Rrd::resize", Rrd_Resize },
349 { "Rrd::restore", Rrd_Restore },
350 { (char *) NULL, (Tcl_CmdProc *) NULL }
356 Tclrrd_Init(interp, safe)
363 if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 1) == NULL) {
367 Tcl_SetVar2(interp, "rrd", "version", VERSION, TCL_GLOBAL_ONLY);
369 for (cmdInfoPtr = rrdCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
371 * Check if the command already exists and return an error
372 * to ensure we detect name clashes while loading the Rrd
375 if (Tcl_GetCommandInfo(interp, cmdInfoPtr->name, &info)) {
376 Tcl_AppendResult(interp, "command \"", cmdInfoPtr->name,
377 "\" already exists", (char *) NULL);
380 Tcl_CreateCommand(interp, cmdInfoPtr->name, cmdInfoPtr->proc,
381 (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
384 if (Tcl_PkgProvide(interp, "Rrd", VERSION) != TCL_OK) {