⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclrrd.c

📁 rrdtool
💻 C
📖 第 1 页 / 共 2 页
字号:
    argv2 = getopt_init(argc, argv);    if (rrd_fetch(argc, argv2, &start, &end, &step,		  &ds_cnt, &ds_namv, &data) != -1) {        datai = data;        listPtr = Tcl_GetObjResult(interp);        for (j = start; j <= end; j += step) {            for (ii = 0; ii < ds_cnt; ii++) {		sprintf(s, "%.2f", *(datai++));                Tcl_ListObjAppendElement(interp, listPtr,					 Tcl_NewStringObj(s, -1));            }        }        for (i=0; i<ds_cnt; i++) free(ds_namv[i]);        free(ds_namv);        free(data);    }    getopt_cleanup(argc, argv2);    if (rrd_test_error()) {	Tcl_AppendResult(interp, "RRD Error: ",			 rrd_get_error(), (char *) NULL);        rrd_clear_error();	return TCL_ERROR;    }    return TCL_OK;}static intRrd_Graph(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[]){    Tcl_Channel channel;    int mode, fd2;    ClientData fd1;    FILE *stream = NULL;    char **calcpr = NULL;    int rc, xsize, ysize;    double ymin, ymax;    char dimensions[50];    char **argv2;    CONST84 char *save;        /*     * If the "filename" is a Tcl fileID, then arrange for rrd_graph() to write to     * that file descriptor.  Will this work with windoze?  I have no idea.     */    if ((channel = Tcl_GetChannel(interp, argv[1], &mode)) != NULL) {	/*	 * It >is< a Tcl fileID	 */	if (!(mode & TCL_WRITABLE)) {	    Tcl_AppendResult(interp, "channel \"", argv[1],		"\" wasn't opened for writing", (char *) NULL);	    return TCL_ERROR;	}	/*	 * Must flush channel to make sure any buffered data is written before	 * rrd_graph() writes to the stream	 */	if (Tcl_Flush(channel) != TCL_OK) {	    Tcl_AppendResult(interp, "flush failed for \"", argv[1], "\": ",		strerror(Tcl_GetErrno()), (char *) NULL);	    return TCL_ERROR;	}	if (Tcl_GetChannelHandle(channel, TCL_WRITABLE, &fd1) != TCL_OK) {	    Tcl_AppendResult(interp, "cannot get file descriptor associated with \"",		argv[1], "\"", (char *) NULL);	    return TCL_ERROR;	}	/*	 * Must dup() file descriptor so we can fclose(stream), otherwise the fclose()	 * would close Tcl's file descriptor	 */	if ((fd2 = dup((int)fd1)) == -1) {	    Tcl_AppendResult(interp, "dup() failed for file descriptor associated with \"",		argv[1], "\": ", strerror(errno), (char *) NULL);	    return TCL_ERROR;	}	/*	 * rrd_graph() wants a FILE*	 */	if ((stream = fdopen(fd2, "wb")) == NULL) {	    Tcl_AppendResult(interp, "fdopen() failed for file descriptor associated with \"",		argv[1], "\": ", strerror(errno), (char *) NULL);	    close(fd2);		/* plug potential file descriptor leak */	    return TCL_ERROR;	}	save = argv[1];	argv[1] = "-";	argv2 = getopt_init(argc, argv);	argv[1] = save;    } else {	Tcl_ResetResult(interp);	/* clear error from Tcl_GetChannel() */	argv2 = getopt_init(argc, argv);    }    rc = rrd_graph(argc, argv2, &calcpr, &xsize, &ysize, stream, &ymin, &ymax);    getopt_cleanup(argc, argv2);    if (stream != NULL)	fclose(stream);		/* plug potential malloc & file descriptor leak */    if (rc != -1) {        sprintf(dimensions, "%d %d", xsize, ysize);        Tcl_AppendResult(interp, dimensions, (char *) NULL);        if (calcpr) {#if 0	    int i;	                for(i = 0; calcpr[i]; i++){                printf("%s\n", calcpr[i]);                free(calcpr[i]);            } #endif            free(calcpr);        }    }    if (rrd_test_error()) {	Tcl_AppendResult(interp, "RRD Error: ",			 rrd_get_error(), (char *) NULL);        rrd_clear_error();	return TCL_ERROR;    }    return TCL_OK;}static intRrd_Tune(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[]){    char **argv2;        argv2 = getopt_init(argc, argv);    rrd_tune(argc, argv2);    getopt_cleanup(argc, argv2);    if (rrd_test_error()) {	Tcl_AppendResult(interp, "RRD Error: ",			 rrd_get_error(), (char *) NULL);        rrd_clear_error();	return TCL_ERROR;    }    return TCL_OK;}static intRrd_Resize(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[]){    char **argv2;        argv2 = getopt_init(argc, argv);    rrd_resize(argc, argv2);    getopt_cleanup(argc, argv2);    if (rrd_test_error()) {	Tcl_AppendResult(interp, "RRD Error: ",			 rrd_get_error(), (char *) NULL);        rrd_clear_error();	return TCL_ERROR;    }    return TCL_OK;}static intRrd_Restore(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[]){    char **argv2;        argv2 = getopt_init(argc, argv);    rrd_restore(argc, argv2);    getopt_cleanup(argc, argv2);    if (rrd_test_error()) {	Tcl_AppendResult(interp, "RRD Error: ",			 rrd_get_error(), (char *) NULL);        rrd_clear_error();	return TCL_ERROR;    }    return TCL_OK;}/* * The following structure defines the commands in the Rrd extension. */typedef struct {    char *name;			/* Name of the command. */    Tcl_CmdProc *proc;		/* Procedure for command. */    int hide;			/* Hide if safe interpreter */} CmdInfo;static CmdInfo rrdCmds[] = {    { "Rrd::create",	Rrd_Create,	1 }, /* Thread-safe version */    { "Rrd::dump",	Rrd_Dump,	0 }, /* Thread-safe version */    { "Rrd::last",	Rrd_Last,	0 }, /* Thread-safe version */    { "Rrd::update",	Rrd_Update,	1 }, /* Thread-safe version */    { "Rrd::fetch",	Rrd_Fetch,	0 },    { "Rrd::graph",	Rrd_Graph,	1 }, /* Due to RRD's API, a safe						interpreter cannot create						a graph since it writes to					        a filename supplied by the					        caller */    { "Rrd::tune",	Rrd_Tune,	1 },    { "Rrd::resize",	Rrd_Resize,	1 },    { "Rrd::restore",	Rrd_Restore,	1 },    { (char *) NULL,	(Tcl_CmdProc *) NULL, 0	}};static intinit(Tcl_Interp *interp, int safe){     CmdInfo *cmdInfoPtr;    Tcl_CmdInfo info;    if ( Tcl_InitStubs(interp,TCL_VERSION,0) == NULL )	return TCL_ERROR;    if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 1) == NULL) {        return TCL_ERROR;    }    /*     * Why a global array?  In keeping with the Rrd:: namespace, why     * not simply create a normal variable Rrd::version and set it?     */    Tcl_SetVar2(interp, "rrd", "version", VERSION, TCL_GLOBAL_ONLY);    for (cmdInfoPtr = rrdCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {	/*	 * Check if the command already exists and return an error	 * to ensure we detect name clashes while loading the Rrd	 * extension.	 */	if (Tcl_GetCommandInfo(interp, cmdInfoPtr->name, &info)) {	    Tcl_AppendResult(interp, "command \"", cmdInfoPtr->name,			     "\" already exists", (char *) NULL);	    return TCL_ERROR;	}	if (safe && cmdInfoPtr->hide) {#if 0	    /*	     * Turns out the one cannot hide a command in a namespace	     * due to a limitation of Tcl, one can only hide global	     * commands.  Thus, if we created the commands without	     * the Rrd:: namespace in a safe interpreter, then the	     * "unsafe" commands could be hidden -- which would allow	     * an owning interpreter either un-hiding them or doing	     * an "interp invokehidden".  If the Rrd:: namespace is	     * used, then it's still possible for the owning interpreter	     * to fake out the missing commands:	     *	     *   # Make all Rrd::* commands available in master interperter	     *   package require Rrd	     *   set safe [interp create -safe]	     *   # Make safe Rrd::* commands available in safe interperter	     *   interp invokehidden $safe -global load ./tclrrd1.2.11.so	     *   # Provide the safe interpreter with the missing commands	     *   $safe alias Rrd::update do_update $safe	     *   proc do_update {which_interp $args} {	     *     # Do some checking maybe...	     *       :	     *     return [eval Rrd::update $args]	     *   }	     *	     * Our solution for now is to just not create the "unsafe"	     * commands in a safe interpreter.	     */	    if (Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name) != TCL_OK)		return TCL_ERROR;#endif	}	else	    Tcl_CreateCommand(interp, cmdInfoPtr->name, cmdInfoPtr->proc,		          (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);    }    if (Tcl_PkgProvide(interp, "Rrd", VERSION) != TCL_OK) {	return TCL_ERROR;    }    return TCL_OK;}intTclrrd_Init(Tcl_Interp *interp){   return init(interp, 0);}/* * See the comments above and note how few commands are considered "safe"... * Using rrdtool in a safe interpreter has very limited functionality.  It's * tempting to just return TCL_ERROR and forget about it. */intTclrrd_SafeInit(Tcl_Interp *interp){   return init(interp, 1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -