I found useful in some cases to check the running configuration
parameters, particularly when more than one application/virtual host
is running on the same Apache installation. So I extended the
functionalities catered by the undocumented arrays RivetServerConf,
RivetDirConf and RivetUserConf and I got done a first implementation
for an introspection command of Rivet. 

 I named this command '::rivet::inspect', in order to make it distinctively 
different from 'info', since a namespace import from ::rivet into 
the global namespace would clash the 2 command definitions. 

I don't have a special affection to this name, so I'm open to change it. 

My first plan was to make it similar to PHP's phpinfo command, but I admit 
I don't know of a straightforward way to store and return the plethora of 
information (when meaningful to Rivet) that command caters. Anyway the
dictionary value returned by ::rivet::inspect can be extended to 
new values or sections of configuration values.

 ::rivet::inspect has 3 forms:

 1) with no arguments: 

[::rivet::inspect] returns a dictionary with 3
subdictionaries having "server","user" and "dir" respectively for keys.
In this form '::rivet::inspect' returns only the configuration
parameters that were set by the admin or user in the conf files. 
The dictionary works as a way to preserve compatibility
with the existing RivetServerConf,RivetDirConf and RivetUserConf arrays.
These arrays are maintained by Rivet_PropagateServerConfArrays and
Rivet_PropagatePerDirConfArrays functions in mod_rivet.c. Particularly
Rivet_PropagatePerDirConfArrays has a (though small) performance cost as
it gets run at every request.

Example: placing in BeforeScript the line

 array set RivetDirConf [dict get [::rivet::inspect] dir]

would emulate what Rivet_PropagatePerDirConfArrays does, but only when
you need it

Bottom line: those Rivet_Propagate* function in mod_rivet.c can go now
and their arrays created on demand

2) ::rivet::inspect is called in this form:  

::rivet::inspect -all 

a dictionary is returned where each supported configuration keyword
(see below) is a key to a value read from the current configuration
record (as returned by Rivet_GetConf). Script values undefined are
filled with the string "<undef>"

3) ::rivet::inspect is given a single argument matching one of the
configuration keywords. The corresponding value is returned

Example:
 
 [::rivet::inspect UploadMaxSize]
==> 2000000

Supported configuration keywords are "ServerInitScript",
"GlobalInitScript", "ChildInitScript", "ChildExitScript",
"BeforeScript", "AfterScript", "AfterEveryScript",
"AbortScript", "ErrorScript", "UploadMaxSize",
"UploadDirectory", "UploadFilesToVar", "SeparateVirtualInterps",
"HonorHeaderOnlyRequests"
 
This is the patch, including changes to mod_rivet.c to assure propagation
of some server configuration scripts. 

In mod_rivet.c Rivet_UserConf and Rivet_DirConf are now restricted to
accept only configure scripts that are meaningful to them (child process 
initialization and termination are handled at the server scope)

 -- Massimo



Index: src/apache-2/Makefile.am
===================================================================
--- src/apache-2/Makefile.am	(revision 1331892)
+++ src/apache-2/Makefile.am	(working copy)
@@ -37,6 +37,7 @@
 	        mod_rivet.c 				\
 	        TclWebapache.c 				\
 	        rivetCore.c					\
+            rivetConf.c                 \
 	        ../rivetChannel.c 			\
             ../rivetParser.c
 
Index: src/apache-2/mod_rivet.c
===================================================================
--- src/apache-2/mod_rivet.c	(revision 1331892)
+++ src/apache-2/mod_rivet.c	(working copy)
@@ -697,6 +697,10 @@
               rivet_server_conf *base, rivet_server_conf *add )
 {
     FILEDEBUGINFO;
+    new->rivet_child_init_script = add->rivet_child_init_script ?
+        add->rivet_child_init_script : base->rivet_child_init_script;
+    new->rivet_child_exit_script = add->rivet_child_exit_script ?
+        add->rivet_child_exit_script : base->rivet_child_exit_script;
 
     new->rivet_before_script = add->rivet_before_script ?
         add->rivet_before_script : base->rivet_before_script;
@@ -782,8 +786,8 @@
     Tcl_IncrRefCount(rsc->rivet_default_error_script);
 
     /* these are pointers so that they can be passed around...  */
-    rsc->cache_size = apr_pcalloc(p, sizeof(int));
-    rsc->cache_free = apr_pcalloc(p, sizeof(int));
+    rsc->cache_size                 = apr_pcalloc(p, sizeof(int));
+    rsc->cache_free                 = apr_pcalloc(p, sizeof(int));
     *(rsc->cache_size)              = -1;
     *(rsc->cache_free)              = 0;
     rsc->upload_max                 = RIVET_MAX_POST;
@@ -936,7 +940,7 @@
 
     /* Create a global array with information about the server. */
     Rivet_InitServerVariables(interp, p );
-    Rivet_PropagateServerConfArray( interp, rsc );
+//  Rivet_PropagateServerConfArray( interp, rsc );
 
     /* Eval Rivet's init.tcl file to load in the Tcl-level commands. */
 
@@ -962,15 +966,9 @@
 
     /* Loading into the interpreter the commands provided by librivet.so */
 
-   /* It would be nice to have to whole set of Rivet commands
-    * loaded into the interpreter at this stage. Unfortunately
-    * a problem with the dynamic loader of some OS prevents us 
-    * from callingTcl_PkgRequire for 'rivetlib' because Apache segfaults
-    * shortly after the extension library is loaded.
-    * The problem was investigated on Linux and it became clear 
-    * that it's linked to the way Tcl calls dlopen (Bug #3216070)
-    * The problem could be solved in Tcl8.6 
-    */
+    /* Bug #3216070 has been solved with 8.5.10 and commands shipped with
+     * Rivetlib can be mapped at this stage
+     */
 
     if (Tcl_PkgRequire(interp, RIVETLIB_TCL_PACKAGE, "1.2", 1) == NULL)
     {
@@ -1085,12 +1083,14 @@
  *
  * Command Arguments:
  *
+ *  RivetServerConf ServerInitScript <script>
  *  RivetServerConf GlobalInitScript <script>
  *  RivetServerConf ChildInitScript <script>
  *  RivetServerConf ChildExitScript <script>
  *  RivetServerConf BeforeScript <script>
  *  RivetServerConf AfterScript <script>
  *  RivetServerConf ErrorScript <script>
+ *  RivetServerConf AfterEveryScript <script>
  *  RivetServerConf CacheSize <integer>
  *  RivetServerConf UploadDirectory <directory>
  *  RivetServerConf UploadMaxSize <integer>
@@ -1140,6 +1140,7 @@
  *  RivetDirConf BeforeScript <script>
  *  RivetDirConf AfterScript <script>
  *  RivetDirConf ErrorScript <script>
+ *  RivetDirConf AfterEveryScript <script>
  *  RivetDirConf UploadDirectory <directory>
  */
 
@@ -1159,7 +1160,19 @@
     if( STREQU( var, "UploadDirectory" ) ) {
         rdc->upload_dir = val;
     } else {
-        string = Rivet_SetScript( cmd->pool, rdc, var, val );
+        if (STREQU(var,"BeforeScript")      || 
+            STREQU(var,"AfterScript")       || 
+            STREQU(var,"AbortScript")       ||
+            STREQU(var,"AfterEveryScript")  ||
+            STREQU(var,"ErrorScript"))
+        {
+            string = Rivet_SetScript( cmd->pool, rdc, var, val );
+        }
+        else
+        {
+            return apr_pstrcat(cmd->pool, "Rivet configuration error: '",var, 
+                                          "' not valid for RivetDirConf", NULL);
+        }
     }
 
     if (string != NULL) apr_table_set( rdc->rivet_dir_vars, var, string );
@@ -1176,7 +1189,8 @@
  */
 
 static const char *
-Rivet_UserConf( cmd_parms *cmd, void *vrdc, 
+Rivet_UserConf( cmd_parms *cmd, 
+                void *vrdc, 
                 const char *var, 
                 const char *val )
 {
@@ -1192,9 +1206,23 @@
     /* We have modified these scripts. */
     /* This is less than ideal though, because it will get set to 1
      * every time - FIXME. */
+
     rdc->user_scripts_updated = 1;
 
-    string = Rivet_SetScript( cmd->pool, rdc, var, val );
+    if (STREQU(var,"BeforeScript")  || 
+        STREQU(var,"AfterScript")   || 
+        STREQU(var,"AbortScript")   ||
+        STREQU(var,"AfterEveryScript") ||
+        STREQU(var,"ErrorScript"))
+    {
+        string = Rivet_SetScript( cmd->pool, rdc, var, val );
+    }
+    else
+    {
+        return apr_pstrcat(cmd->pool, "Rivet configuration error: '",var, 
+                                      "' not valid for RivetUserConf", NULL);
+    }
+
     /* XXX Need to figure out what to do about setting the table.  */
     if (string != NULL) apr_table_set( rdc->rivet_user_vars, var, string );
     return NULL;
@@ -1824,9 +1852,9 @@
     }
 
 #ifdef USE_APACHE_RSC
-    Rivet_PropagatePerDirConfArrays( interp, rsc );
+//  Rivet_PropagatePerDirConfArrays( interp, rsc );
 #else
-    Rivet_PropagatePerDirConfArrays( interp, rdc );
+//  Rivet_PropagatePerDirConfArrays( interp, rdc );
 #endif
 
     /* Initialize this the first time through and keep it around. */
Index: src/apache-2/mod_rivet.h
===================================================================
--- src/apache-2/mod_rivet.h	(revision 1331892)
+++ src/apache-2/mod_rivet.h	(working copy)
@@ -131,5 +131,14 @@
 #define RIVET_NEW_CONF(p) \
 	(rivet_server_conf *)apr_pcalloc(p, sizeof(rivet_server_conf))
 
+Tcl_Obj* Rivet_BuildConfDictionary ( Tcl_Interp*        interp,
+                                    rivet_server_conf*  rivet_conf);
+
+Tcl_Obj* Rivet_ReadConfParameter (  Tcl_Interp*         interp,
+                                    rivet_server_conf*  rivet_conf,
+                                    Tcl_Obj*            par_name);
+
+Tcl_Obj* Rivet_CurrentConfDict (    Tcl_Interp*           interp,
+                                    rivet_server_conf*    rivet_conf);
 #endif /* MOD_RIVET_H */
 
Index: src/apache-2/rivetConf.c
===================================================================
--- src/apache-2/rivetConf.c	(revision 0)
+++ src/apache-2/rivetConf.c	(revision 0)
@@ -0,0 +1,421 @@
+/*
+ * rivetConf.c - Functions for accessing Rivet configuration variables
+ *
+ * Functions in this file implement core function to be called mainly
+ * by the Rivet_InspectCmd function, which implments command 'inspect'
+ *
+ */
+
+/* Copyright 2002-2004 The Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+/* $Id: */
+
+#include <tcl.h>
+#include <string.h>
+#include <apr_errno.h>
+#include <apr_strings.h>
+#include <apr_tables.h>
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_request.h"
+#include "http_core.h"
+#include "http_main.h"
+#include "util_script.h"
+#include "http_config.h"
+
+#include "mod_rivet.h"
+
+static const char* confDirectives[] = 
+{ 
+                    "ServerInitScript", 
+                    "GlobalInitScript",
+                    "ChildInitScript",
+                    "ChildExitScript",
+                    "BeforeScript",
+                    "AfterScript",
+                    "AfterEveryScript",
+                    "AbortScript",
+                    "ErrorScript",
+                    "UploadMaxSize",
+                    "UploadDirectory",
+                    "UploadFilesToVar",
+                    "SeparateVirtualInterps",
+                    "HonorHeaderOnlyRequests",
+                    NULL 
+};
+
+enum confIndices {
+                    server_init_script,
+                    global_init_script,
+                    child_init_script,
+                    child_exit_script,
+                    before_script,
+                    after_script,
+                    after_every_script,
+                    abort_script,
+                    error_script,
+                    upload_max,
+                    upload_directory,
+                    upload_files_to_var,
+                    separate_virtual_interps,
+                    honor_header_only_requests,
+                    conf_index_terminator 
+                };
+
+/* 
+ * -- Rivet_ReadConfParameter
+ *
+ * This procedure reads a single field named par_name from 
+ * rivet_server_conf structure and returns a Tcl_Obj pointer
+ * containing the field value. See confDirectives for a list
+ * of possible names. If the procedure is queried for a non  
+ * existing field a NULL is returned.
+ *
+ *  Arguments:
+ *
+ *  - interp: pointer to the current Tcl interpreter structure
+ *  - rsc: a pointer to a rivet_server_conf structure
+ *  - par_name: parameter name (as listed in confDirectives)
+ *
+ * Returned value:
+ *
+ *  - A Tcl_Obj pointer to the parameter value. Its refCount is
+ *    set to 1
+ *
+ */
+
+Tcl_Obj*
+Rivet_ReadConfParameter ( Tcl_Interp* interp,
+                          rivet_server_conf* rsc,
+                          Tcl_Obj*    par_name)
+{
+    int parameter_i;
+    Tcl_Obj* par_value;
+
+    if (Tcl_GetIndexFromObj(interp, par_name, confDirectives,
+                "<one of conf directives>", 0, &parameter_i) == TCL_ERROR) {
+        return NULL;
+    }
+
+    switch (parameter_i)
+    {
+        case server_init_script:
+        {
+            par_value = rsc->rivet_server_init_script;
+            break;
+        }
+        case global_init_script:
+        {
+            par_value = rsc->rivet_global_init_script;
+            break;
+        }
+        case child_init_script:
+        {
+            par_value = rsc->rivet_child_init_script;
+            break;
+        }
+        case child_exit_script:
+        {
+            par_value = rsc->rivet_child_exit_script;
+            break;
+        }
+        case before_script:
+        {
+            par_value = rsc->rivet_before_script;
+            break;
+        }
+        case after_script:
+        {
+            par_value = rsc->rivet_after_script;
+            break;
+        }
+        case after_every_script:
+        {
+            par_value = rsc->after_every_script;
+            break;
+        }
+        case abort_script:
+        {
+            par_value = rsc->rivet_abort_script;
+            break;
+        }
+        case error_script:
+        {
+            par_value = rsc->rivet_error_script;
+            break;
+        }
+        case upload_max:
+        {
+            par_value = Tcl_NewIntObj(rsc->upload_max);
+            break;
+        }
+        case upload_directory:
+        {
+            par_value = Tcl_NewStringObj(rsc->upload_dir,-1);
+            break;
+        }
+        case upload_files_to_var:
+        {
+            par_value = Tcl_NewIntObj(rsc->upload_files_to_var);
+            break;
+        }
+        case separate_virtual_interps:
+        {
+            par_value = Tcl_NewIntObj(rsc->separate_virtual_interps);
+            break;
+        }
+        case honor_header_only_requests:
+        {
+            par_value = Tcl_NewIntObj(rsc->honor_header_only_reqs);
+            break;
+        }
+        default:
+        {
+            return NULL;
+        }
+    }
+
+    if (par_value == NULL) 
+    {
+        par_value=Tcl_NewStringObj("<undef>",-1);
+    }
+
+    Tcl_IncrRefCount(par_value);
+
+    return par_value;
+}
+
+/* 
+ * Rivet_ReadConfTable: 
+ * 
+ * This procedure builds a key-value list from an apr table
+ * It called from Rivet_BuildConfDictionary for Rivet configuration
+ * tables but it could work for every apr table
+ *
+ * Arguments:
+ *
+ *  - interp: Tcl_Interp pointer
+ *  - table: an apr_table_t pointer
+ */
+
+Tcl_Obj* Rivet_ReadConfTable (  Tcl_Interp*           interp,
+                                apr_table_t*          table)
+{
+    Tcl_Obj*                key;
+    Tcl_Obj*                val;
+    apr_array_header_t      *arr;
+    apr_table_entry_t       *elts;
+    int                     nelts,i;
+    int                     tcl_status = TCL_OK;
+    Tcl_Obj*                keyval_list = Tcl_NewObj();
+
+    Tcl_IncrRefCount(keyval_list);
+
+    arr   = (apr_array_header_t*) apr_table_elts( table );
+    elts  = (apr_table_entry_t *) arr->elts;
+    nelts = arr->nelts;
+
+/*
+    if (Tcl_IsShared(keyval_list))
+    {
+        fprintf(stderr,"building duplicate keyval_list\n");
+        keyval_list = Tcl_DuplicateObj(keyval_list);
+    }
+ */
+
+    for (i = 0; i < nelts; i++)
+    {
+        key = Tcl_NewStringObj( elts[i].key, -1);
+        val = Tcl_NewStringObj( elts[i].val, -1);
+        Tcl_IncrRefCount(key);
+        Tcl_IncrRefCount(val);
+
+        tcl_status = Tcl_ListObjAppendElement (interp,keyval_list,key);
+        if (tcl_status == TCL_ERROR)
+        {   
+            Tcl_DecrRefCount(keyval_list);
+            Tcl_DecrRefCount(key);
+            Tcl_DecrRefCount(val);
+            return NULL;
+        }
+
+        tcl_status = Tcl_ListObjAppendElement (interp,keyval_list,val);
+        if (tcl_status == TCL_ERROR)
+        {
+            Tcl_DecrRefCount(keyval_list);
+            Tcl_DecrRefCount(key);
+            Tcl_DecrRefCount(val);
+            return NULL;
+        }
+
+        Tcl_DecrRefCount(key);
+        Tcl_DecrRefCount(val);
+    }
+
+    return keyval_list;
+}
+
+
+/*
+ * -- Rivet_BuildConfDictionary
+ * 
+ * Parameters set in the configuration files are collected in three
+ * APR tables by Rivet_ServerConf,Rivet_DirConf and Rivet_UserConf. 
+ *
+ * Arguments:
+ *
+ * - interp: Tcl_Interp pointer
+ * - rivet_conf: pointer to a rivet_server_conf structure as
+ *   returned by Rivet_GetConf
+ *
+ * Returned value:
+ *
+ *  - Tcl dictionary storing the dir/user/server configuration
+ *
+ */
+
+Tcl_Obj* Rivet_BuildConfDictionary ( Tcl_Interp*           interp,
+                                     rivet_server_conf*    rivet_conf)
+{
+    apr_table_t* conf_tables[3];
+    Tcl_Obj*     keyval_list = NULL;
+    Tcl_Obj*     key_list[2];
+    int          it;
+    Tcl_Obj*     conf_dict = Tcl_NewObj();
+
+    static const char* section_names[] = 
+    {
+        "dir",
+        "user",
+        "server"
+    };
+
+    enum
+    {
+        dir_conf_section,
+        user_conf_section,
+        server_conf_section
+    };
+
+    conf_tables[0] = rivet_conf->rivet_dir_vars;
+    conf_tables[1] = rivet_conf->rivet_user_vars;
+    conf_tables[2] = rivet_conf->rivet_server_vars;
+
+    Tcl_IncrRefCount(conf_dict);
+
+    for (it=0; it < 3; it++)
+    {
+        keyval_list = Rivet_ReadConfTable(interp,conf_tables[it]);
+
+        if (keyval_list != NULL)
+        {
+            int       i;
+            Tcl_Obj** objArrayPnt;
+            int       objArrayCnt;
+            Tcl_Obj*  val;
+
+            key_list[0] = Tcl_NewStringObj(section_names[it],-1);
+            Tcl_IncrRefCount(key_list[0]);
+
+            Tcl_ListObjGetElements(interp,keyval_list,&objArrayCnt,&objArrayPnt);
+            for (i=0; i < objArrayCnt; i+=2)
+            {
+                key_list[1] = objArrayPnt[i];
+                val         = objArrayPnt[i+1];
+
+                Tcl_IncrRefCount(key_list[1]);
+                Tcl_IncrRefCount(val);
+
+                Tcl_DictObjPutKeyList(interp,conf_dict,2,key_list,val);
+
+                Tcl_DecrRefCount(key_list[1]);
+                Tcl_DecrRefCount(val);
+            }
+            Tcl_DecrRefCount(key_list[0]);
+            Tcl_DecrRefCount(keyval_list);
+        }
+        else
+        {
+            return NULL;
+        }
+    }
+
+    return conf_dict;
+}
+
+
+/*
+ * Rivet_CurrentConfDict 
+ *
+ * This function is called by Rivet_InspectCmd which implements command
+ * '::rivet::inspect -all'. The function returns a dictionary where every
+ * parameter name (confDirectives) is associated to its value stored in
+ * the rivet_server_conf as returned by Rivet_GetConf
+ *
+ * Arguments:
+ *
+ * - interp: Tcl interpreter pointer
+ * - rivet_conf: a pointer to a rivet_server_conf structure
+ *
+ * Returned value_
+ *
+ * - a Tcl_Obj* pointer to a dictionary. The dictionary object
+ *  refCount is set to 1
+ */
+
+Tcl_Obj* Rivet_CurrentConfDict (    Tcl_Interp*           interp,
+                                    rivet_server_conf*    rivet_conf)
+{
+    Tcl_Obj* dictObj = Tcl_NewObj();
+    Tcl_Obj* par_name; 
+    static const char** p;
+
+    Tcl_IncrRefCount(dictObj);
+
+    for (p = confDirectives; (*p) != NULL; p++)
+    {
+        Tcl_Obj* par_value;
+
+        par_name = Tcl_NewStringObj(*p,-1);
+        Tcl_IncrRefCount(par_name);
+
+        par_value = Rivet_ReadConfParameter(interp,rivet_conf,par_name);
+        if (par_value != NULL)
+        {
+            Tcl_DictObjPut(interp,dictObj,par_name,par_value);
+            Tcl_DecrRefCount(par_value);
+        }
+        else
+        {
+            Tcl_Obj* message = Tcl_NewStringObj("Invalid configuration option: ",-1);
+            
+            Tcl_IncrRefCount(message);
+            Tcl_AppendObjToObj(message,par_name);
+            Tcl_AddErrorInfo(interp, Tcl_GetStringFromObj(message,NULL));
+
+            Tcl_DecrRefCount(message);
+            Tcl_DecrRefCount(par_name);
+            Tcl_DecrRefCount(dictObj);
+            dictObj = NULL;
+            break;
+        }
+        Tcl_DecrRefCount(par_name);
+
+    }
+
+    return dictObj;
+}
Index: src/apache-2/rivetCore.c
===================================================================
--- src/apache-2/rivetCore.c	(revision 1331892)
+++ src/apache-2/rivetCore.c	(working copy)
@@ -1230,6 +1230,84 @@
 /*
  *-----------------------------------------------------------------------------
  *
+ * Rivet_Inspect --
+ *
+ *      Rivet configuration introspection. Command '::rivet::inspect' 
+ *      returns a dictionary of configuration data:
+ *
+ * Results:
+ *      A dictionary or parameter value
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+TCL_CMD_HEADER( Rivet_InspectCmd )
+{
+    rivet_interp_globals*   globals = Tcl_GetAssocData( interp, "rivet", NULL );
+    rivet_server_conf*      rsc = Rivet_GetConf(globals->r); 
+    int                     status = TCL_OK;
+
+    if (objc == 1)
+    {
+        Tcl_Obj* dictObj;
+
+        dictObj = Rivet_BuildConfDictionary(interp,rsc);
+        if (dictObj != NULL) {
+            Tcl_SetObjResult(interp,dictObj);
+            Tcl_DecrRefCount(dictObj);
+        } else {
+            status = TCL_ERROR;
+        }
+    }
+    else if (objc == 2)
+    {
+        Tcl_Obj* par_name = objv[1];
+
+        Tcl_IncrRefCount(par_name);
+        if (STRNEQU(Tcl_GetStringFromObj(par_name,NULL),"-all"))
+        {
+            Tcl_Obj* dictObj;
+
+            dictObj = Rivet_CurrentConfDict(interp,rsc);
+            if (dictObj == NULL)
+            {
+                status = TCL_ERROR;
+            }
+            else
+            {
+                Tcl_SetObjResult(interp,dictObj);            
+                Tcl_DecrRefCount(dictObj);
+            }
+        }
+        else
+        {
+            Tcl_Obj* par_value = NULL;
+
+            par_value = Rivet_ReadConfParameter(interp,rsc,par_name);
+            if (par_value == NULL)
+            {
+                status = TCL_ERROR;
+            }
+            else
+            {
+                Tcl_SetObjResult(interp,par_value);
+                Tcl_DecrRefCount(par_value);
+            }
+        }
+
+        Tcl_DecrRefCount(par_name);
+    }
+    else 
+    {
+        Tcl_WrongNumArgs( interp, 1, objv, "?server | dir | user? ?parameter name?" );
+        status = TCL_ERROR;
+    }
+    return status;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
  * Rivet_LogError --
  *
  *      Log an error from Rivet
@@ -1421,6 +1499,7 @@
     RIVET_OBJ_CMD ("no_body",Rivet_NoBody);
     RIVET_OBJ_CMD ("env",Rivet_EnvCmd);
     RIVET_OBJ_CMD ("apache_log_error",Rivet_LogErrorCmd);
+    RIVET_OBJ_CMD ("inspect",Rivet_InspectCmd);
 
 #ifdef TESTPANIC
     RIVET_OBJ_CMD ("testpanic",TestpanicCmd);

---------------------------------------------------------------------
To unsubscribe, e-mail: rivet-dev-unsubscr...@tcl.apache.org
For additional commands, e-mail: rivet-dev-h...@tcl.apache.org

Reply via email to