rem: argv[0], " sectionname", NULL);
add: (char*)argv[0], " sectionname", NULL);
context: static Tcl_CmdProc SectionCmd;static Tcl_CmdProc ParamCmd;static Ns_Set     *GetSection(char *section, int create);static char       *ConfigGet(char *section, char *key, int exact);/* *---------------------------------------------------------------------- * * Ns_ConfigGetValue -- * *	Return a config file value for a given key  * * Results: *	ASCIIZ ptr to a value  * * Side effects: *	None.  * *---------------------------------------------------------------------- */char *Ns_ConfigGetValue(char *section, char *key){    return ConfigGet(section, key, 0);}/* *---------------------------------------------------------------------- * * Ns_ConfigGetValueExact -- * *	Case-sensitive version of Ns_ConfigGetValue  * * Results: *	See Ns_ConfigGetValue  * * Side effects: *	None.  * *---------------------------------------------------------------------- */char *Ns_ConfigGetValueExact(char *section, char *key){    return ConfigGet(section, key, 1);}/* *---------------------------------------------------------------------- * * Ns_ConfigGetInt -- * *	Fetch integer config values  * * Results: *	S_TRUE if it found an integer value; otherwise, it returns  *	NS_FALSE and sets the value to 0  * * Side effects: *	The integer value is returned by reference  * *---------------------------------------------------------------------- */intNs_ConfigGetInt(char *section, char *key, int *valuePtr){    char           *s;    s = Ns_ConfigGetValue(section, key);    if (s == NULL || sscanf(s, "%d", valuePtr) != 1) {        return NS_FALSE;    }    return NS_TRUE;}/* *---------------------------------------------------------------------- * * Ns_ConfigGetInt64 -- * *	Like Ns_ConfigGetInt, but with INT64 data instead of  *	system-native int types.  * * Results: *	See Ns_ConfigGetInt  * * Side effects: *	See Ns_ConfigGetInt  * *---------------------------------------------------------------------- */intNs_ConfigGetInt64(char *section, char *key, INT64 *valuePtr){    char           *s;    s = Ns_ConfigGetValue(section, key);    if (s == NULL || sscanf(s, NS_INT_64_FORMAT_STRING, valuePtr) != 1) {        return NS_FALSE;    }    return NS_TRUE;}/* *---------------------------------------------------------------------- * * Ns_ConfigGetBool -- * *	Get a boolean config value. There are many ways to represent  *	a boolean value.  * * Results: *	NS_TRUE/NS_FALSE * * Side effects: *	The boolean value is returned by reference  * *---------------------------------------------------------------------- */intNs_ConfigGetBool(char *section, char *key, int *valuePtr){    char           *s;    s = Ns_ConfigGetValue(section, key);    if (s == NULL) {        return NS_FALSE;    }    if (STREQ(s, "1") ||	STRIEQ(s, "y") ||	STRIEQ(s, "yes") ||	STRIEQ(s, "on") ||	STRIEQ(s, "t") ||	STRIEQ(s, "true")) {        *valuePtr = 1;    } else if (STREQ(s, "0") ||	STRIEQ(s, "n") ||	STRIEQ(s, "no") ||	STRIEQ(s, "off") ||	STRIEQ(s, "f") ||	STRIEQ(s, "false")) {        *valuePtr = 0;    } else if (sscanf(s, "%d", valuePtr) != 1) {        return NS_FALSE;    }    return NS_TRUE;}/* *---------------------------------------------------------------------- * * Ns_ConfigGetPath -- * *	Get the full name of a config file section if it exists.  * * Results: *	A pointer to an ASCIIZ string of the full path name, or NULL  *	if that path is not in the config file.  * * Side effects: *	None.  * *---------------------------------------------------------------------- */char *Ns_ConfigGetPath(char *server, char *module, ...){    va_list         ap;    char           *s;    Ns_DString      ds;    Ns_Set         *set;    Ns_DStringInit(&ds);    Ns_DStringAppend(&ds, "ns");    if (server != NULL) {        Ns_DStringVarAppend(&ds, "/server/", server, NULL);    }    if (module != NULL) {        Ns_DStringVarAppend(&ds, "/module/", module, NULL);    }    va_start(ap, module);    while ((s = va_arg(ap, char *)) != NULL) {        Ns_DStringAppend(&ds, "/");        while (*s != '\0' && ISSLASH(*s)) {            ++s;        }        Ns_DStringAppend(&ds, s);        while (ISSLASH(ds.string[ds.length - 1])) {            ds.string[--ds.length] = '\0';        }    }    va_end(ap);    set = Ns_ConfigGetSection(ds.string);    Ns_DStringFree(&ds);    return (set ? Ns_SetName(set) : NULL);}/* *---------------------------------------------------------------------- * * Ns_ConfigGetSections -- * *	Return a malloc'ed, NULL-terminated array of sets, each  *	corresponding to a config section  * * Results: *	An array of sets  * * Side effects: *	The result is malloc'ed memory  * *---------------------------------------------------------------------- */Ns_Set **Ns_ConfigGetSections(void){    Ns_Set        **sets;    Tcl_HashEntry  *hPtr;    Tcl_HashSearch  search;    int     	    n;        n = nsconf.sections.numEntries + 1;    sets = ns_malloc(sizeof(Ns_Set *) * n);    n = 0;    hPtr = Tcl_FirstHashEntry(&nsconf.sections, &search);    while (hPtr != NULL) {    	sets[n++] = Tcl_GetHashValue(hPtr);    	hPtr = Tcl_NextHashEntry(&search);    }    sets[n] = NULL;    return sets;}/* *---------------------------------------------------------------------- * * Ns_ConfigGetSection -- * *	Return the Ns_Set of a config section called section.  * * Results: *	An Ns_Set, containing the section's parameters  * * Side effects: *	None.  * *---------------------------------------------------------------------- */Ns_Set *Ns_ConfigGetSection(char *section){    return (section ? GetSection(section, 0) : NULL);}/* *---------------------------------------------------------------------- * * NsConfigRead -- * *	Read a config file at startup. * * Results: *  	Pointer to the config buffer of an ns_malloc'ed string. * * Side Effects: *	Server aborts if file cannot be read for any reason. * *--------------------------------------------------------------------- */char *NsConfigRead(char *file){    struct stat st;    int fd;    char *buf;    off_t n;    if (stat(file, &st) != 0) {	Ns_Fatal("config: stat(%s) failed: %s", file, strerror(errno));    }    if (S_ISREG(st.st_mode) == 0) {	Ns_Fatal("config: not regular file: %s", file);    }    fd = open(file, O_RDONLY);    if (fd < 0) {	Ns_Fatal("config: open(%s) failed: %s", file, strerror(errno));    }    n = st.st_size;    buf = ns_malloc(n + 1);    n = read(fd, buf, n);    if (n < 0) {	Ns_Fatal("config: read(%s) failed: %s", file, strerror(errno));    }    buf[n] = '\0';    close(fd);    return buf;}/* *---------------------------------------------------------------------- * * NsConfigEval -- * *	Eval config script in a startup Tcl interp.  * * Results: *  	None. * * Side Effects: *      Various variables in the configInterp will be set as well as *      the sundry configuration hashes * *--------------------------------------------------------------------- */voidNsConfigEval(char *config, int argc, char **argv, int optind){    char buf[20];    Tcl_Interp *interp;    Ns_Set     *set;    int i;    /*     * Create an interp with a few config-related commands.     */    set = NULL;    interp = Ns_TclCreateInterp();    Tcl_CreateCommand(interp, "ns_section", SectionCmd, &set, NULL);    Tcl_CreateCommand(interp, "ns_param", ParamCmd, &set, NULL);    for (i = 0; argv[i] != NULL; ++i) {	Tcl_SetVar(interp, "argv", argv[i], TCL_APPEND_VALUE|TCL_LIST_ELEMENT|TCL_GLOBAL_ONLY);    }    sprintf(buf, "%d", argc);    Tcl_SetVar(interp, "argc", buf, TCL_GLOBAL_ONLY);    sprintf(buf, "%d", optind);    Tcl_SetVar(interp, "optind", buf, TCL_GLOBAL_ONLY);    if (Tcl_Eval(interp, config) != TCL_OK) {	Ns_TclLogError(interp);	Ns_Fatal("config error");    }    Tcl_DeleteInterp(interp);}/* *---------------------------------------------------------------------- * * ConfigGet -- * *	Return the value for key in the config section.  * * Results: *	Pointer to value, or NULL  * * Side effects: *	None.  * *---------------------------------------------------------------------- */static char *ConfigGet(char *section, char *key, int exact){    Ns_Set         *set;    int             i;    char           *s;    s = NULL;    if (section != NULL && key != NULL) {        set = Ns_ConfigGetSection(section);        if (set != NULL) {	    if (exact) {            	i = Ns_SetFind(set, key);	    } else {            	i = Ns_SetIFind(set, key);	    }            if (i >= 0) {                s = Ns_SetValue(set, i);            }        }    }    return s;}/* *---------------------------------------------------------------------- * * ParamCmd -- * *	Add a single nsd.ini parameter; this command may only be run  *	from within an ns_section.  * * Results: *	Standard Tcl Result  * * Side effects: *	A tcl variable will be created with the name  *	ns_cfgdata(section,key), and a set entry will be added for  *	the current section.  * *---------------------------------------------------------------------- */static intParamCmd(ClientData arg, Tcl_Interp *interp, int argc, char **argv){    Ns_Set *set;    if (argc != 3) {	Tcl_AppendResult(interp, "wrong # args: should be \"",		argv[0], " key value", NULL);	return TCL_ERROR;    }    set = *((Ns_Set **) arg);    if (set == NULL) {	Tcl_AppendResult(interp, argv[0],			 " not preceded by an ns_section command.", NULL);	return TCL_ERROR;    }    Ns_SetPut(set, argv[1], argv[2]);    return TCL_OK;}/* *---------------------------------------------------------------------- * * SectionCmd -- * *	This creates a new config section and sets a shared variable *	to point at a newly-allocated set for holding config data. *	ns_param stores config data in the set. * * Results: *	Standard tcl result.  * * Side effects: *	Section set is created (if necessary). * *---------------------------------------------------------------------- */static intSectionCmd(ClientData arg, Tcl_Interp *interp, int argc, char **argv){    Ns_Set  **set;    if (argc != 2) {	Tcl_AppendResult(interp, "wrong # args: should be \"",			 argv[0], " sectionname", NULL);	return TCL_ERROR;    }    set = (Ns_Set **) arg;    *set = GetSection(argv[1], 1);    return TCL_OK;}