<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://panoptic.com/mediawiki/aolserver/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Caveman</id>
	<title>AOLserver Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://panoptic.com/mediawiki/aolserver/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Caveman"/>
	<link rel="alternate" type="text/html" href="https://panoptic.com/wiki/aolserver/Special:Contributions/Caveman"/>
	<updated>2026-06-09T05:45:45Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Akhassin&amp;diff=5461</id>
		<title>User talk:Akhassin</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Akhassin&amp;diff=5461"/>
		<updated>2009-10-13T16:01:47Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Thanks for the recent updates! --[[User:Caveman|Caveman]] 12:01, 13 October 2009 (EDT)&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Writing_your_first_C_module&amp;diff=5413</id>
		<title>Writing your first C module</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Writing_your_first_C_module&amp;diff=5413"/>
		<updated>2009-10-08T20:00:37Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The AOLServer C API is very easy to develop towards. This short tutorial takes you through construction of an &amp;quot;nshello&amp;quot; module that provides a &amp;quot;ns_hello&amp;quot; function.&lt;br /&gt;
&lt;br /&gt;
NOTE: This has been updated for aolserver4.5 (ns.mak) --[[User:Caveman|Caveman]] 15:49, 8 October 2009 (EDT)&lt;br /&gt;
&lt;br /&gt;
Step 0: Requirements&lt;br /&gt;
&lt;br /&gt;
You need (at least) ns.h and ns.mak.&lt;br /&gt;
&lt;br /&gt;
On Debian, simply:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apt-get install aolserver4-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step 1: Write your module code, &amp;quot;nshello.c&amp;quot; (this can be any name you like):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Get the data types and constants you will need later on,&lt;br /&gt;
 * such as Tcl_Interp and NS_OK.&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;quot;ns.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Each module asserts its version via the required Ns_ModuleVersion variable&lt;br /&gt;
 */&lt;br /&gt;
int Ns_ModuleVersion = 1;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Declare that this module will implement this initialization method.&lt;br /&gt;
 */&lt;br /&gt;
int Ns_ModuleInit(char *hServer, char *hModule);&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * This can be named whatever you like, it is used during module initialisation&lt;br /&gt;
 * to contain specific initialisation steps for the Tcl interpreter itself,&lt;br /&gt;
 * such as registering commands like &amp;quot;ns_hello&amp;quot;.&lt;br /&gt;
 */&lt;br /&gt;
static int HelloInterpInit(Tcl_Interp *interp, void *context);&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Declare a C function that will be bound to the &amp;quot;ns_hello&amp;quot; Tcl command. It can be&lt;br /&gt;
 * named whatever you like as well.&lt;br /&gt;
 */&lt;br /&gt;
static int HelloCmd(ClientData context, Tcl_Interp *interp, int argc, char **argv);&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Implement the Ns_ModuleInit function we declared we would implement earlier.&lt;br /&gt;
 * This is called by the server right after the module is loaded. Here, you&lt;br /&gt;
 * can read configuration data, initialise internal data, and of course&lt;br /&gt;
 * register any Tcl commands.&lt;br /&gt;
 */&lt;br /&gt;
int Ns_ModuleInit(char *hServer, char *hModule)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Invoke the server's Tcl interpreter initialisation and pass&lt;br /&gt;
     * it the callback we defined to our own interpreter initialisation.&lt;br /&gt;
     */&lt;br /&gt;
    return (Ns_TclInitInterps(hServer, HelloInterpInit, NULL));&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Implement the interpreter initialisation we declared and passed&lt;br /&gt;
 * during module init. Use Tcl_CreateCommand to register&lt;br /&gt;
 * the command &amp;quot;ns_hello&amp;quot;, passing a callback to &amp;quot;HelloCmd&amp;quot; which&lt;br /&gt;
 * we declared earlier.&lt;br /&gt;
 */&lt;br /&gt;
static int HelloInterpInit(Tcl_Interp *interp, void *context)&lt;br /&gt;
{&lt;br /&gt;
    Tcl_CreateCommand(interp, &amp;quot;ns_hello&amp;quot;, HelloCmd, NULL, NULL);&lt;br /&gt;
&lt;br /&gt;
    return NS_OK;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Append &amp;quot;hello&amp;quot; and then all arguments to the result.&lt;br /&gt;
 */&lt;br /&gt;
static int HelloCmd(ClientData context, Tcl_Interp *interp, int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    int i;&lt;br /&gt;
&lt;br /&gt;
    Tcl_AppendResult(interp, &amp;quot;hello&amp;quot;, NULL);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; argc; i++)&lt;br /&gt;
    {&lt;br /&gt;
           Tcl_AppendResult(interp, &amp;quot; &amp;quot;, NULL);&lt;br /&gt;
           Tcl_AppendResult(interp, argv[i], NULL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return NS_OK;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's it. That's an entire module.&lt;br /&gt;
&lt;br /&gt;
Step 2: Build your module.&lt;br /&gt;
&lt;br /&gt;
AOLServer includes a meta-Makefile '''Makefile.module''' that simplifies the construction of module makefiles. Simply define a few values in your owm Makefile, then include this meta-Makefile.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Module name&lt;br /&gt;
#&lt;br /&gt;
MOD      =  nshello&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Objects to build&lt;br /&gt;
# .o will be matched to .c files&lt;br /&gt;
#&lt;br /&gt;
OBJS     =  nshello.o&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Header files in THIS directory&lt;br /&gt;
#&lt;br /&gt;
HDRS     =&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Extra libraries&lt;br /&gt;
#&lt;br /&gt;
MODLIBS  =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Compiler flags&lt;br /&gt;
#&lt;br /&gt;
CFLAGS   =&lt;br /&gt;
&lt;br /&gt;
include  /usr/share/aolserver4/ns.mk&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done. Now you can build your module with 'make'.&lt;br /&gt;
&lt;br /&gt;
You should now have a nifty &amp;quot;nshello.so&amp;quot; shared object library sitting around. Copy &amp;quot;nshello.so&amp;quot; to /usr/lib/aolserver4/bin (or where you keep your server modules).&lt;br /&gt;
&lt;br /&gt;
Step 3: Tell aolserver to load the module (/etc/aolserver4/aolserver4.tcl):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_section &amp;quot;ns/server/${servername}/modules&amp;quot;&lt;br /&gt;
ns_param   nshello            nshello.so&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done. Restart aolserver and check the log file for errors.&lt;br /&gt;
&lt;br /&gt;
Step 4: Use the function &amp;quot;ns_hello&amp;quot; in an ADP script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%&lt;br /&gt;
ns_adp_puts [ns_hello &amp;quot;AOLServer module&amp;quot; &amp;quot;world!&amp;quot;]&lt;br /&gt;
%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whoa! You get a strange result: hello ns_hello AOLServer module world!&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;quot;ns_hello&amp;quot; in there? That's because argv[0] is actually the name of the function used to call your interpreter! So, keep that in mind and happy AOLServer module hacking!&lt;br /&gt;
&lt;br /&gt;
'''Continued Topics'''&lt;br /&gt;
&lt;br /&gt;
Calling Tcl from within your module (i.e. call ns_rand from your module).&lt;br /&gt;
&lt;br /&gt;
Reading configuration sections during initialisation.&lt;br /&gt;
&lt;br /&gt;
Linking to other C libraries in the build process (e.g. linking with libpng).&lt;br /&gt;
&lt;br /&gt;
[[Embedding a new programming language as a module]].&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Module_inclusion&amp;diff=5412</id>
		<title>Talk:Module inclusion</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Module_inclusion&amp;diff=5412"/>
		<updated>2009-10-08T19:53:24Z</updated>

		<summary type="html">&lt;p&gt;Caveman: added log snippet which adds no real information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I'm having trouble using something which worked in aolserver4 with aolserver4.5 -- for example my 'writing your first C module' article:&lt;br /&gt;
&lt;br /&gt;
http://panoptic.com/wiki/aolserver/Writing_your_first_C_module&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[08/Oct/2009:19:46:30][26013.18446744072300399344][-main-] Notice: modload: loading '/usr/lib/aolserver4/bin/nsperm.so'&lt;br /&gt;
[08/Oct/2009:19:46:30][26013.18446744072300399344][-main-] Notice: modload: loading '/usr/lib/aolserver4/bin/nstokyo.so'&lt;br /&gt;
[08/Oct/2009:19:46:30][26013.18446744072300399344][-main-] Warning: modload: could not load /usr/lib/aolserver4/bin/nstokyo.so: libnstokyo.so: cannot open shared object file: No such file or directory&lt;br /&gt;
[08/Oct/2009:19:46:30][26013.18446744072300399344][-main-] Fatal: modload: failed to load module 'nstokyo.so'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ends up with the nshello.so module being attempted loaded but searching for libnshello.so as well, which fails -- has the C module build and deployment changed? --[[User:Caveman|Caveman]] 15:41, 8 October 2009 (EDT)&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Writing_your_first_C_module&amp;diff=5411</id>
		<title>Writing your first C module</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Writing_your_first_C_module&amp;diff=5411"/>
		<updated>2009-10-08T19:49:42Z</updated>

		<summary type="html">&lt;p&gt;Caveman: corrected to use aolserver4.5 ns.mk&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The AOLServer C API is very easy to develop towards. This short tutorial takes you through construction of an &amp;quot;nshello&amp;quot; module that provides a &amp;quot;ns_hello&amp;quot; function.&lt;br /&gt;
&lt;br /&gt;
NOTE: This has been updated for aolserver4.5 (ns.mk) --[[User:Caveman|Caveman]] 15:49, 8 October 2009 (EDT)&lt;br /&gt;
&lt;br /&gt;
Step 0: Requirements&lt;br /&gt;
&lt;br /&gt;
You need (at least) ns.h and Makefile.module.&lt;br /&gt;
&lt;br /&gt;
On Debian, simply:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apt-get install aolserver4-dev&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Step 1: Write your module code, &amp;quot;nshello.c&amp;quot; (this can be any name you like):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Get the data types and constants you will need later on,&lt;br /&gt;
 * such as Tcl_Interp and NS_OK.&lt;br /&gt;
 */&lt;br /&gt;
#include &amp;quot;ns.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Each module asserts its version via the required Ns_ModuleVersion variable&lt;br /&gt;
 */&lt;br /&gt;
int Ns_ModuleVersion = 1;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Declare that this module will implement this initialization method.&lt;br /&gt;
 */&lt;br /&gt;
int Ns_ModuleInit(char *hServer, char *hModule);&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * This can be named whatever you like, it is used during module initialisation&lt;br /&gt;
 * to contain specific initialisation steps for the Tcl interpreter itself,&lt;br /&gt;
 * such as registering commands like &amp;quot;ns_hello&amp;quot;.&lt;br /&gt;
 */&lt;br /&gt;
static int HelloInterpInit(Tcl_Interp *interp, void *context);&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Declare a C function that will be bound to the &amp;quot;ns_hello&amp;quot; Tcl command. It can be&lt;br /&gt;
 * named whatever you like as well.&lt;br /&gt;
 */&lt;br /&gt;
static int HelloCmd(ClientData context, Tcl_Interp *interp, int argc, char **argv);&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Implement the Ns_ModuleInit function we declared we would implement earlier.&lt;br /&gt;
 * This is called by the server right after the module is loaded. Here, you&lt;br /&gt;
 * can read configuration data, initialise internal data, and of course&lt;br /&gt;
 * register any Tcl commands.&lt;br /&gt;
 */&lt;br /&gt;
int Ns_ModuleInit(char *hServer, char *hModule)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     * Invoke the server's Tcl interpreter initialisation and pass&lt;br /&gt;
     * it the callback we defined to our own interpreter initialisation.&lt;br /&gt;
     */&lt;br /&gt;
    return (Ns_TclInitInterps(hServer, HelloInterpInit, NULL));&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Implement the interpreter initialisation we declared and passed&lt;br /&gt;
 * during module init. Use Tcl_CreateCommand to register&lt;br /&gt;
 * the command &amp;quot;ns_hello&amp;quot;, passing a callback to &amp;quot;HelloCmd&amp;quot; which&lt;br /&gt;
 * we declared earlier.&lt;br /&gt;
 */&lt;br /&gt;
static int HelloInterpInit(Tcl_Interp *interp, void *context)&lt;br /&gt;
{&lt;br /&gt;
    Tcl_CreateCommand(interp, &amp;quot;ns_hello&amp;quot;, HelloCmd, NULL, NULL);&lt;br /&gt;
&lt;br /&gt;
    return NS_OK;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Append &amp;quot;hello&amp;quot; and then all arguments to the result.&lt;br /&gt;
 */&lt;br /&gt;
static int HelloCmd(ClientData context, Tcl_Interp *interp, int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    int i;&lt;br /&gt;
&lt;br /&gt;
    Tcl_AppendResult(interp, &amp;quot;hello&amp;quot;, NULL);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; argc; i++)&lt;br /&gt;
    {&lt;br /&gt;
           Tcl_AppendResult(interp, &amp;quot; &amp;quot;, NULL);&lt;br /&gt;
           Tcl_AppendResult(interp, argv[i], NULL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return NS_OK;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's it. That's an entire module.&lt;br /&gt;
&lt;br /&gt;
Step 2: Build your module.&lt;br /&gt;
&lt;br /&gt;
AOLServer includes a meta-Makefile '''Makefile.module''' that simplifies the construction of module makefiles. Simply define a few values in your owm Makefile, then include this meta-Makefile.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Module name&lt;br /&gt;
#&lt;br /&gt;
MOD      =  nshello&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Objects to build&lt;br /&gt;
# .o will be matched to .c files&lt;br /&gt;
#&lt;br /&gt;
OBJS     =  nshello.o&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Header files in THIS directory&lt;br /&gt;
#&lt;br /&gt;
HDRS     =&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Extra libraries&lt;br /&gt;
#&lt;br /&gt;
MODLIBS  =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Compiler flags&lt;br /&gt;
#&lt;br /&gt;
CFLAGS   =&lt;br /&gt;
&lt;br /&gt;
include  /usr/share/aolserver4/ns.mk&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done. Now you can build your module with 'make'.&lt;br /&gt;
&lt;br /&gt;
You should now have a nifty &amp;quot;nshello.so&amp;quot; shared object library sitting around. Copy &amp;quot;nshello.so&amp;quot; to /usr/lib/aolserver4/bin (or where you keep your server modules).&lt;br /&gt;
&lt;br /&gt;
Step 3: Tell aolserver to load the module (/etc/aolserver4/aolserver4.tcl):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_section &amp;quot;ns/server/${servername}/modules&amp;quot;&lt;br /&gt;
ns_param   nshello            nshello.so&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Done. Restart aolserver and check the log file for errors.&lt;br /&gt;
&lt;br /&gt;
Step 4: Use the function &amp;quot;ns_hello&amp;quot; in an ADP script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;%&lt;br /&gt;
ns_adp_puts [ns_hello &amp;quot;AOLServer module&amp;quot; &amp;quot;world!&amp;quot;]&lt;br /&gt;
%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whoa! You get a strange result: hello ns_hello AOLServer module world!&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;quot;ns_hello&amp;quot; in there? That's because argv[0] is actually the name of the function used to call your interpreter! So, keep that in mind and happy AOLServer module hacking!&lt;br /&gt;
&lt;br /&gt;
'''Continued Topics'''&lt;br /&gt;
&lt;br /&gt;
Calling Tcl from within your module (i.e. call ns_rand from your module).&lt;br /&gt;
&lt;br /&gt;
Reading configuration sections during initialisation.&lt;br /&gt;
&lt;br /&gt;
Linking to other C libraries in the build process (e.g. linking with libpng).&lt;br /&gt;
&lt;br /&gt;
[[Embedding a new programming language as a module]].&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Module_inclusion&amp;diff=5410</id>
		<title>Talk:Module inclusion</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Module_inclusion&amp;diff=5410"/>
		<updated>2009-10-08T19:41:13Z</updated>

		<summary type="html">&lt;p&gt;Caveman: added query about 4.0 to 4.5 changes in C modules&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I'm having trouble using something which worked in aolserver4 with aolserver4.5 -- for example my 'writing your first C module' article:&lt;br /&gt;
&lt;br /&gt;
http://panoptic.com/wiki/aolserver/Writing_your_first_C_module&lt;br /&gt;
&lt;br /&gt;
Ends up with the nshello.so module being attempted loaded but searching for libnshello.so as well, which fails -- has the C module build and deployment changed? --[[User:Caveman|Caveman]] 15:41, 8 October 2009 (EDT)&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Akhassin&amp;diff=5409</id>
		<title>User talk:Akhassin</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Akhassin&amp;diff=5409"/>
		<updated>2009-10-08T18:56:38Z</updated>

		<summary type="html">&lt;p&gt;Caveman: simple 'thanks' for recent updates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Thanks for the recent updates!&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_schedule_daily&amp;diff=5408</id>
		<title>Ns schedule daily</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_schedule_daily&amp;diff=5408"/>
		<updated>2009-10-08T18:55:04Z</updated>

		<summary type="html">&lt;p&gt;Caveman: removed SPAM link to research papers site&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Man page: http://aolserver.com/docs/tcl/ns_schedule_daily.html&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''NAME'''&lt;br /&gt;
&lt;br /&gt;
: ns_schedule_daily - Schedule a script to run daily at a certain time&lt;br /&gt;
&lt;br /&gt;
'''SYNOPSIS'''&lt;br /&gt;
&lt;br /&gt;
: '''ns_schedule_daily''' ''?-once? ?-thread? hour minute script''&lt;br /&gt;
&lt;br /&gt;
'''DESCRIPTION'''&lt;br /&gt;
&lt;br /&gt;
: This command schedules a ''script'' to be run at a certain ''hour'' and ''minute'' of the day.  Returns the ID of the newly scheduled script.  If ''-once'' is specified, then the script is run once and then unscheduled, otherwise it will continue to run every day at that time.  If ''-thread'' is specified, then the script will be run in its own thread, otherwise it will run in the scheduler's thread.  If the script is long-running, this may interfere with the running of other scheduled scripts, so long-running scripts should be run in their own threads.&lt;br /&gt;
&lt;br /&gt;
: '''NOTE:''' ''hour'' and ''minute'' are specified in local time.  Beware of Daylight Savings Time shifts affecting the time of day when the script will execute.&lt;br /&gt;
&lt;br /&gt;
'''EXAMPLES'''&lt;br /&gt;
&lt;br /&gt;
    % set id [[ns_schedule_daily -once 5 35 { ns_log notice &amp;quot;It is now 5:35 AM.&amp;quot; }]]&lt;br /&gt;
    123&lt;br /&gt;
&lt;br /&gt;
    % ns_unschedule_proc $id&lt;br /&gt;
&lt;br /&gt;
'''SEE ALSO'''&lt;br /&gt;
&lt;br /&gt;
: [[ns_after]], [[ns_info]] scheduled, [[ns_pause]], [[ns_resume]], [[ns_schedule_proc]], [[ns_schedule_weekly]], [[ns_unschedule_proc]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category:Documentation]] - [[Category:Core Tcl API]]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Wiki&amp;diff=5407</id>
		<title>AOLserver Wiki</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Wiki&amp;diff=5407"/>
		<updated>2009-10-08T18:53:46Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* AOLserver Resources: */ removed 'sample essays' SPAM link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''[http://www.aolserver.com AOLserver] is a high performance web server with a powerful customization API.  The AOLserver Wiki is a comprehensive resource for all things AOLserver.'''&lt;br /&gt;
&lt;br /&gt;
If you're new to [[wiki]]'s, then [[Welcome, New Visitors]]!  Before you start editing, you may want to read over the [[Formatting Rules]].  To find pages grouped by category, [[Special:Categories|start here]].&lt;br /&gt;
&lt;br /&gt;
== Topics of Conversation ==&lt;br /&gt;
&lt;br /&gt;
* [[What is AOLserver]]?&lt;br /&gt;
* What [[Web Applications for AOLserver]] would you like to see? &lt;br /&gt;
* What [[AOLserver Bugs and Problems]] are you experiencing? &lt;br /&gt;
* What features does AOLserver need? Add them to the [[AOLserver Wishlist]]. &lt;br /&gt;
&lt;br /&gt;
* [[What's new in 4.5]] -- New features in version 4.5 of AOLserver.  This is the current major release of AOLserver.&lt;br /&gt;
&lt;br /&gt;
== AOLserver Resources: ==&lt;br /&gt;
&lt;br /&gt;
* [[Downloads]] -- Access to various AOLserver files and resources.&lt;br /&gt;
* [[Modules]] -- Complete list of '''over 70''' AOLserver extension modules and other [[AOLserver Contributed Software]].&lt;br /&gt;
* [[Toolkits]] -- Everything you need to build a complete website, fast.&lt;br /&gt;
* [[Languages]] -- Build websites in a varierty of different programming languages.&lt;br /&gt;
* [[Documentation]] -- Tcl and C API references, tutorials and guides.&lt;br /&gt;
* [[FAQ]] -- Frequently Asked Questions about AOLserver.&lt;br /&gt;
* [[AOLserver Improvement Proposals]]&lt;br /&gt;
* The [[AOLserver Cookbook]] -- A collection of questions, and code examples to answer them.&lt;br /&gt;
* [[AOLserver Packages]] -- Binary distributions of AOLserver in popular package management formats.&lt;br /&gt;
* [[Useful Links]]&lt;br /&gt;
* [http://panoptic.com/wiki/aolserver/Special:Recentchanges?feed=rss RSS 2.0 syndication] of this wiki's recent changes.&lt;br /&gt;
&lt;br /&gt;
== Developers' Guide (A Work In Progress) ==&lt;br /&gt;
&lt;br /&gt;
* [[AOLserver Developer's Guide]] -- A growing, community generated guide on how to develop, deploy and maintain applications using AOLserver including discussions of internals, troubleshooting, debugging, testing and tuning.&lt;br /&gt;
&lt;br /&gt;
== AOLserver Community ==&lt;br /&gt;
&lt;br /&gt;
* The AOLserver project [[Roadmap]], as well as the planned [[Features]] and changes.&lt;br /&gt;
* The [[People]] who work on and contribute to AOLserver, organized into [[Project Teams]].&lt;br /&gt;
* Come join us in our [http://www.aolserver.com/chat/ online chat], or just read the [http://panoptic.com/aolserver/chat/ chat logs].  You can participate on the chat either via IRC (irc.freenode.net:6667 #aolserver) or via AIM.&lt;br /&gt;
* There's also an [http://www.livejournal.com/community/aolserver/ AOLserver LiveJournal community].&lt;br /&gt;
* [[Sites That Run On AOLserver]]&lt;br /&gt;
* The [[OpenACS]] Project.&lt;br /&gt;
* The [[ProjectOpen]] Project (project management based on [[OpenACS]])&lt;br /&gt;
* [[AOLserver User Groups]]&lt;br /&gt;
* [[AOLserver Jobs]]&lt;br /&gt;
&lt;br /&gt;
== AOLserver Core Developers ==&lt;br /&gt;
&lt;br /&gt;
* [[Vision Statement]]&lt;br /&gt;
* [[CVS Commit Guidelines]]&lt;br /&gt;
* [http://www.aolserver.com/docs/devel/tech/standards.html AOLserver Engineering Standards Manual]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Wiki&amp;diff=5406</id>
		<title>AOLserver Wiki</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_Wiki&amp;diff=5406"/>
		<updated>2009-10-08T18:51:36Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* AOLserver Resources: */ removed 'research papers' SPAM link from Al&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''[http://www.aolserver.com AOLserver] is a high performance web server with a powerful customization API.  The AOLserver Wiki is a comprehensive resource for all things AOLserver.'''&lt;br /&gt;
&lt;br /&gt;
If you're new to [[wiki]]'s, then [[Welcome, New Visitors]]!  Before you start editing, you may want to read over the [[Formatting Rules]].  To find pages grouped by category, [[Special:Categories|start here]].&lt;br /&gt;
&lt;br /&gt;
== Topics of Conversation ==&lt;br /&gt;
&lt;br /&gt;
* [[What is AOLserver]]?&lt;br /&gt;
* What [[Web Applications for AOLserver]] would you like to see? &lt;br /&gt;
* What [[AOLserver Bugs and Problems]] are you experiencing? &lt;br /&gt;
* What features does AOLserver need? Add them to the [[AOLserver Wishlist]]. &lt;br /&gt;
&lt;br /&gt;
* [[What's new in 4.5]] -- New features in version 4.5 of AOLserver.  This is the current major release of AOLserver.&lt;br /&gt;
&lt;br /&gt;
== AOLserver Resources: ==&lt;br /&gt;
&lt;br /&gt;
* [[Downloads]] -- Access to various AOLserver files and resources.&lt;br /&gt;
* [[Modules]] -- Complete list of '''over 70''' AOLserver extension modules and other [[AOLserver Contributed Software]].&lt;br /&gt;
* [[Toolkits]] -- Everything you need to build a complete website, fast.&lt;br /&gt;
* [[Languages]] -- Build websites in a varierty of different programming languages.&lt;br /&gt;
* [[Documentation]] -- Tcl and C API references, tutorials and guides.&lt;br /&gt;
* [[FAQ]] -- Frequently Asked Questions about AOLserver.&lt;br /&gt;
* [[AOLserver Improvement Proposals]]&lt;br /&gt;
* The [[AOLserver Cookbook]] -- A collection of questions, and code examples to answer them.&lt;br /&gt;
* [[AOLserver Packages]] -- Binary distributions of AOLserver in popular package management formats.&lt;br /&gt;
* [[Useful Links]]-sample [http://www.bestessays.co.uk Essays]&lt;br /&gt;
* [http://panoptic.com/wiki/aolserver/Special:Recentchanges?feed=rss RSS 2.0 syndication] of this wiki's recent changes.&lt;br /&gt;
&lt;br /&gt;
== Developers' Guide (A Work In Progress) ==&lt;br /&gt;
&lt;br /&gt;
* [[AOLserver Developer's Guide]] -- A growing, community generated guide on how to develop, deploy and maintain applications using AOLserver including discussions of internals, troubleshooting, debugging, testing and tuning.&lt;br /&gt;
&lt;br /&gt;
== AOLserver Community ==&lt;br /&gt;
&lt;br /&gt;
* The AOLserver project [[Roadmap]], as well as the planned [[Features]] and changes.&lt;br /&gt;
* The [[People]] who work on and contribute to AOLserver, organized into [[Project Teams]].&lt;br /&gt;
* Come join us in our [http://www.aolserver.com/chat/ online chat], or just read the [http://panoptic.com/aolserver/chat/ chat logs].  You can participate on the chat either via IRC (irc.freenode.net:6667 #aolserver) or via AIM.&lt;br /&gt;
* There's also an [http://www.livejournal.com/community/aolserver/ AOLserver LiveJournal community].&lt;br /&gt;
* [[Sites That Run On AOLserver]]&lt;br /&gt;
* The [[OpenACS]] Project.&lt;br /&gt;
* The [[ProjectOpen]] Project (project management based on [[OpenACS]])&lt;br /&gt;
* [[AOLserver User Groups]]&lt;br /&gt;
* [[AOLserver Jobs]]&lt;br /&gt;
&lt;br /&gt;
== AOLserver Core Developers ==&lt;br /&gt;
&lt;br /&gt;
* [[Vision Statement]]&lt;br /&gt;
* [[CVS Commit Guidelines]]&lt;br /&gt;
* [http://www.aolserver.com/docs/devel/tech/standards.html AOLserver Engineering Standards Manual]&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=5405</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=5405"/>
		<updated>2009-10-08T18:45:59Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* AJAX/JSON support in AOLserver */  removed spammer link to &amp;quot;buy term papers&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {::sha1::hmac [lindex $args 1] [lindex $args 0]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;64&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
[http://philip.greenspun.com/doc/ philip.greenspun.com/doc/]&lt;br /&gt;
&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline data-pipeline]&lt;br /&gt;
&lt;br /&gt;
== AJAX/JSON support in AOLserver ==&lt;br /&gt;
&lt;br /&gt;
# HTTP request hits AOLserver, returns HTML including JavaScript with AJAX (or JSON-RPC, whatever) features.&lt;br /&gt;
# Client interacts with rendered HTML application, resulting in AJAX calls to AOLserver.&lt;br /&gt;
# AOLserver handles the AJAX calls and responds.&lt;br /&gt;
# Client potentially modified by result of AJAX call without reload.&lt;br /&gt;
&lt;br /&gt;
Use cases:&lt;br /&gt;
# Rate something and store the rating without reload of page.&lt;br /&gt;
# Stateful drag and drop of tiles (shopping cart, wish list).&lt;br /&gt;
# Background saving of application state (e.g. word processor, calendar, etc) without page reload.&lt;br /&gt;
# Reload portions of the view (e.g. portlet) without reloading the whole page. E.g. stock tickers, chat windows, log viewers, etc.&lt;br /&gt;
# Add/remove item from cart statefully without reload of page.&lt;br /&gt;
# Recalculate shopping cart prices/totals without reload of page.&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
# Allows &amp;quot;Web 2.0&amp;quot; sites such as Digg and Gmail to be run on massively scalable AOLserver platform.&lt;br /&gt;
# It's an itch. We scratch these things.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.writely.com/ writely -- the web word processor]&lt;br /&gt;
* [http://www.digg.com/spy digg spy -- show console data e.g. log, recent searches, monitoring, stocks, etc]&lt;br /&gt;
* [http://www.kiko.com/ kiko -- online calendar]&lt;br /&gt;
* [http://mail.google.com/ google mail]&lt;br /&gt;
* [http://maps.google.com/ google maps]&lt;br /&gt;
* [http://www.crockford.com/javascript/ javascript link collection]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/AJAX wikipedia article on AJAX]&lt;br /&gt;
* [http://rajshekhar.net/blog/archives/85-Rasmus-30-second-AJAX-Tutorial.html 30 second intro to AJAX]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=5404</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=5404"/>
		<updated>2009-10-08T18:45:24Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* useful links */  removed spammer links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {::sha1::hmac [lindex $args 1] [lindex $args 0]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;64&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
[http://philip.greenspun.com/doc/ philip.greenspun.com/doc/]&lt;br /&gt;
&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline data-pipeline]&lt;br /&gt;
&lt;br /&gt;
== AJAX/JSON support in AOLserver ==&lt;br /&gt;
&lt;br /&gt;
# HTTP request hits AOLserver, returns HTML including JavaScript with AJAX (or JSON-RPC, whatever) features.&lt;br /&gt;
# Client interacts with rendered HTML application, resulting in AJAX calls to AOLserver.&lt;br /&gt;
# AOLserver handles the AJAX calls and responds.&lt;br /&gt;
# Client potentially modified by result of AJAX call without reload.&lt;br /&gt;
&lt;br /&gt;
Use cases:&lt;br /&gt;
# Rate something and store the rating without reload of page.&lt;br /&gt;
# Stateful drag and drop of tiles (shopping cart, wish list).&lt;br /&gt;
# Background saving of application state (e.g. word processor, calendar, etc) without page reload.&lt;br /&gt;
# Reload portions of the view (e.g. portlet) without reloading the whole page. E.g. stock tickers, chat windows, log viewers, etc.&lt;br /&gt;
# Add/remove item from cart statefully without reload of page.&lt;br /&gt;
# Recalculate shopping cart prices/totals without reload of page.&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
# Allows &amp;quot;Web 2.0&amp;quot; sites such as Digg and Gmail to be run on massively scalable AOLserver platform.&lt;br /&gt;
# It's an itch. We scratch these things.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.term-paper-research.com/ buy term papers]&lt;br /&gt;
* [http://www.writely.com/ writely -- the web word processor]&lt;br /&gt;
* [http://www.digg.com/spy digg spy -- show console data e.g. log, recent searches, monitoring, stocks, etc]&lt;br /&gt;
* [http://www.kiko.com/ kiko -- online calendar]&lt;br /&gt;
* [http://mail.google.com/ google mail]&lt;br /&gt;
* [http://maps.google.com/ google maps]&lt;br /&gt;
* [http://www.crockford.com/javascript/ javascript link collection]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/AJAX wikipedia article on AJAX]&lt;br /&gt;
* [http://rajshekhar.net/blog/archives/85-Rasmus-30-second-AJAX-Tutorial.html 30 second intro to AJAX]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_library&amp;diff=4684</id>
		<title>Ns library</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_library&amp;diff=4684"/>
		<updated>2006-01-11T21:52:00Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Man page: http://aolserver.com/docs/tcl/ns_library.html&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''NAME'''&lt;br /&gt;
&lt;br /&gt;
: ns_library - Get the paths to the private and shared Tcl libraries&lt;br /&gt;
&lt;br /&gt;
'''SYNOPSIS'''&lt;br /&gt;
&lt;br /&gt;
: '''ns_library''' ''library ?module?''&lt;br /&gt;
&lt;br /&gt;
'''DESCRIPTION'''&lt;br /&gt;
 &lt;br /&gt;
: This command returns the path to the private and shared Tcl libraries, optionally specifying a ''module'' as well.&lt;br /&gt;
''library'' must either be &amp;quot;private&amp;quot; or &amp;quot;shared&amp;quot;.  The private library is the same as what's returned from [[ns_info]] '''tcllib''' as defined in the config .tcl at server start-up.  The shared library is relative to the path specified by [[ns_info]] '''home''', in the &amp;quot;modules/tcl&amp;quot; subdirectory.&lt;br /&gt;
&lt;br /&gt;
: The optional ''module'' is simply concatenated to the path returned from '''ns_library'''.&lt;br /&gt;
&lt;br /&gt;
'''EXAMPLES'''&lt;br /&gt;
&lt;br /&gt;
    % ns_library shared&lt;br /&gt;
    /home/aolserver/modules/tcl&lt;br /&gt;
&lt;br /&gt;
    % file join [ns_info home] modules tcl&lt;br /&gt;
    /home/aolserver/modules/tcl&lt;br /&gt;
&lt;br /&gt;
    % ns_library private exampleModule&lt;br /&gt;
    /home/aolserver/servers/exampleServer/tcl/exampleModule&lt;br /&gt;
&lt;br /&gt;
    % file join [ns_info tcllib] exampleModule&lt;br /&gt;
    /home/aolserver/servers/exampleServer/tcl/exampleModule&lt;br /&gt;
&lt;br /&gt;
'''SEE ALSO'''&lt;br /&gt;
&lt;br /&gt;
: [[ns_info]] '''home''', [[ns_info]] '''tcllib'''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category Documentation]] - [[Category Core Tcl API]]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ns_register_proc&amp;diff=4683</id>
		<title>Talk:Ns register proc</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ns_register_proc&amp;diff=4683"/>
		<updated>2006-01-11T21:31:14Z</updated>

		<summary type="html">&lt;p&gt;Caveman: getting modules to reload&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== getting modules to reload ==&lt;br /&gt;
&lt;br /&gt;
Using stock install of Debian's AOLserver package, I am trying to figure out how to get my modules to automatically reload (or even manually) without having to restart the entire server. Is this possible? If so, how?&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
I have a module &amp;quot;mymod.tcl&amp;quot; in &amp;quot;/usr/lib/aolserver4/servers/main/modules/tcl&amp;quot;. I want to change a small bit of behavior in the module, say, correcting a typographical error. In order to get this change to be read by the server, I have to stop and then start the server. This is not desired.&lt;br /&gt;
&lt;br /&gt;
--[[User:Caveman|Caveman]] 16:31, 11 January 2006 (EST)&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4658</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4658"/>
		<updated>2006-01-01T16:05:27Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* AJAX/JSON support in AOLserver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {::sha1::hmac [lindex $args 1] [lindex $args 0]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;64&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
[http://philip.greenspun.com/doc/ philip.greenspun.com/doc/]&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline data-pipeline]&lt;br /&gt;
&lt;br /&gt;
== AJAX/JSON support in AOLserver ==&lt;br /&gt;
&lt;br /&gt;
# HTTP request hits AOLserver, returns HTML including JavaScript with AJAX (or JSON-RPC, whatever) features.&lt;br /&gt;
# Client interacts with rendered HTML application, resulting in AJAX calls to AOLserver.&lt;br /&gt;
# AOLserver handles the AJAX calls and responds.&lt;br /&gt;
# Client potentially modified by result of AJAX call without reload.&lt;br /&gt;
&lt;br /&gt;
Use cases:&lt;br /&gt;
# Rate something and store the rating without reload of page.&lt;br /&gt;
# Stateful drag and drop of tiles (shopping cart, wish list).&lt;br /&gt;
# Background saving of application state (e.g. word processor, calendar, etc) without page reload.&lt;br /&gt;
# Reload portions of the view (e.g. portlet) without reloading the whole page. E.g. stock tickers, chat windows, log viewers, etc.&lt;br /&gt;
# Add/remove item from cart statefully without reload of page.&lt;br /&gt;
# Recalculate shopping cart prices/totals without reload of page.&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
# Allows &amp;quot;Web 2.0&amp;quot; sites such as Digg and Gmail to be run on massively scalable AOLserver platform.&lt;br /&gt;
# It's an itch. We scratch these things.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.writely.com/ writely -- the web word processor]&lt;br /&gt;
* [http://www.digg.com/spy digg spy -- show console data e.g. log, recent searches, monitoring, stocks, etc]&lt;br /&gt;
* [http://www.kiko.com/ kiko -- online calendar]&lt;br /&gt;
* [http://mail.google.com/ google mail]&lt;br /&gt;
* [http://maps.google.com/ google maps]&lt;br /&gt;
* [http://www.crockford.com/javascript/ javascript link collection]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/AJAX wikipedia article on AJAX]&lt;br /&gt;
* [http://rajshekhar.net/blog/archives/85-Rasmus-30-second-AJAX-Tutorial.html 30 second intro to AJAX]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4654</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4654"/>
		<updated>2005-12-25T22:17:37Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* AJAX/JSON support in AOLserver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {::sha1::hmac [lindex $args 1] [lindex $args 0]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;64&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
[http://philip.greenspun.com/doc/ philip.greenspun.com/doc/]&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline data-pipeline]&lt;br /&gt;
&lt;br /&gt;
== AJAX/JSON support in AOLserver ==&lt;br /&gt;
&lt;br /&gt;
# HTTP request hits AOLserver, returns HTML including JavaScript with AJAX (or JSON-RPC, whatever) features.&lt;br /&gt;
# Client interacts with rendered HTML application, resulting in AJAX calls to AOLserver.&lt;br /&gt;
# AOLserver handles the AJAX calls and responds.&lt;br /&gt;
# Client potentially modified by result of AJAX call without reload.&lt;br /&gt;
&lt;br /&gt;
Use cases:&lt;br /&gt;
# Rate something and store the rating without reload of page.&lt;br /&gt;
# Stateful drag and drop of tiles (shopping cart, wish list).&lt;br /&gt;
# Background saving of application state (e.g. word processor, calendar, etc) without page reload.&lt;br /&gt;
# Reload portions of the view (e.g. portlet) without reloading the whole page. E.g. stock tickers, chat windows, log viewers, etc.&lt;br /&gt;
# Add/remove item from cart statefully without reload of page.&lt;br /&gt;
# Recalculate shopping cart prices/totals without reload of page.&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
# Allows &amp;quot;Web 2.0&amp;quot; sites such as Digg and Gmail to be run on massively scalable AOLserver platform.&lt;br /&gt;
# It's an itch. We scratch these things.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.writely.com/ writely -- the web word processor]&lt;br /&gt;
* [http://www.digg.com/spy digg spy -- show console data e.g. log, recent searches, monitoring, stocks, etc]&lt;br /&gt;
* [http://www.kiko.com/ kiko -- online calendar]&lt;br /&gt;
* [http://mail.google.com/ google mail]&lt;br /&gt;
* [http://maps.google.com/ google maps]&lt;br /&gt;
* [http://www.crockford.com/javascript/ javascript link collection]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/AJAX wikipedia article on AJAX]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4653</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4653"/>
		<updated>2005-12-25T22:16:41Z</updated>

		<summary type="html">&lt;p&gt;Caveman: AJAX/JSON support in AOLserver&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {::sha1::hmac [lindex $args 1] [lindex $args 0]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;64&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
[http://philip.greenspun.com/doc/ philip.greenspun.com/doc/]&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline data-pipeline]&lt;br /&gt;
&lt;br /&gt;
== AJAX/JSON support in AOLserver ==&lt;br /&gt;
&lt;br /&gt;
1. HTTP request hits AOLserver, returns HTML including JavaScript with AJAX (or JSON-RPC, whatever) features.&lt;br /&gt;
2. Client interacts with rendered HTML application, resulting in AJAX calls to AOLserver.&lt;br /&gt;
3. AOLserver handles the AJAX calls and responds.&lt;br /&gt;
4. Client potentially modified by result of AJAX call without reload.&lt;br /&gt;
&lt;br /&gt;
Use cases:&lt;br /&gt;
1. Rate something and store the rating without reload of page.&lt;br /&gt;
2. Stateful drag and drop of tiles (shopping cart, wish list).&lt;br /&gt;
3. Background saving of application state (e.g. word processor, calendar, etc) without page reload.&lt;br /&gt;
4. Reload portions of the view (e.g. portlet) without reloading the whole page. E.g. stock tickers, chat windows, log viewers, etc.&lt;br /&gt;
5. Add/remove item from cart statefully without reload of page.&lt;br /&gt;
6. Recalculate shopping cart prices/totals without reload of page.&lt;br /&gt;
&lt;br /&gt;
Benefits:&lt;br /&gt;
1. Allows &amp;quot;Web 2.0&amp;quot; sites such as Digg and Gmail to be run on massively scalable AOLserver platform.&lt;br /&gt;
2. It's an itch. We scratch these things.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
[http://www.writely.com/ writely -- the web word processor]&lt;br /&gt;
[http://www.digg.com/spy digg spy -- show console data e.g. log, recent searches, monitoring, stocks, etc]&lt;br /&gt;
[http://www.kiko.com/ kiko -- online calendar]&lt;br /&gt;
[http://mail.google.com/ google mail]&lt;br /&gt;
[http://maps.google.com/ google maps]&lt;br /&gt;
[http://www.crockford.com/javascript/ javascript link collection]&lt;br /&gt;
[http://en.wikipedia.org/wiki/AJAX wikipedia article on AJAX]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User:Caveman&amp;diff=4652</id>
		<title>User:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User:Caveman&amp;diff=4652"/>
		<updated>2005-12-25T22:06:07Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[mailto:sam@caveman.org Samuel Montgomery-Blinn]&lt;br /&gt;
&lt;br /&gt;
An off-and-on hobbyist user of Aolserver from 3.x days. Never been an OpenACS fan, hope that doesn't get me into trouble someday. My Aolserver runs on Debian 3.1 using the aolserver4-* binary packages, so I thank the maintainers for their time and effort.&lt;br /&gt;
&lt;br /&gt;
'''Current primary AOLserver interest:'''&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Web 2.0&amp;quot; buzzword tinkering with AOLserver: AJAX primarily. Atom/RSS, &amp;quot;Web Services&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
'''Current seconday AOLserver interests:'''&lt;br /&gt;
&lt;br /&gt;
Best Practices on cookie management and session management with AOLServer&lt;br /&gt;
&lt;br /&gt;
Best Pratcices for identity management and authorization model AOLServer&lt;br /&gt;
&lt;br /&gt;
Tinkering with a standardised phpinfo() alike command: [http://caveman.org/info/]&lt;br /&gt;
&lt;br /&gt;
Blogging/discussion software, especially usefully multi-user.&lt;br /&gt;
&lt;br /&gt;
SVG graphics generation.&lt;br /&gt;
&lt;br /&gt;
Application model and management.&lt;br /&gt;
&lt;br /&gt;
nsdbeans data layer (similar to Java's EJB, or Python's SQLObject).&lt;br /&gt;
&lt;br /&gt;
SOAP conversation with directi's reseller server [http://manage.directi.com/kb/servlet/KBServlet/cat106.html]&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Current 'real' work:'''&lt;br /&gt;
&lt;br /&gt;
A lot of JACL/TCL scripting in the test automation world for &amp;quot;nameless big software company&amp;quot;. WebSphere includes a JACL administrative shell that is quite useful for scripting all kinds of configuration and test activity for J2EE applications.&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4644</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4644"/>
		<updated>2005-12-14T22:57:19Z</updated>

		<summary type="html">&lt;p&gt;Caveman: corrected use of ns_dbquotevalue&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {::sha1::hmac [lindex $args 1] [lindex $args 0]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;64&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name=[ns_dbquotevalue [lindex $args 0]]}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
[http://philip.greenspun.com/doc/ philip.greenspun.com/doc/]&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline data-pipeline]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4643</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4643"/>
		<updated>2005-12-14T21:53:13Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {::sha1::hmac [lindex $args 1] [lindex $args 0]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;64&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
[http://philip.greenspun.com/doc/ philip.greenspun.com/doc/]&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline data-pipeline]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4642</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4642"/>
		<updated>2005-12-14T20:26:11Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* cleaned up old conversations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {ns_sha1 [ns_md5 [lindex $args 0]] [lindex $args 1]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;8&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
[http://philip.greenspun.com/doc/ philip.greenspun.com/doc/]&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline data-pipeline]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4641</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4641"/>
		<updated>2005-12-14T20:20:52Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* useful links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, and welcome to the wiki!  If you don't mind me asking, what's your full name (or do you want to remain anonymous)?  Are you also subscribed to the [http://aolserver.com/lists.php AOLSERVER mailing list]?  Some of us also hang out on [http://aolserver.com/chat/ IRC and chat] (you can also access the chat via AIM, but most folks use IRC).&lt;br /&gt;
&lt;br /&gt;
If you have any questions or concerns, don't hesitate to contact me.  Thanks! ''-- [[User:Dossy|Dossy]] 07:13, 3 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Why does it seem like you're avoiding Tcl?  Your recent wiki edits have been focused around other languages in AOLserver other than Tcl, like Lua, PHP and Ruby.  Why?  You will really never get the kind of performance out of Perl, PHP or Ruby as you will Tcl, because Tcl is suitable for embedding in a multi-threaded application where Perl, PHP and Ruby aren't.  (I don't know enough about Lua to say one way or the other.)  So, if you still want to use those other languages, then you probably don't care about performance at the high end, in which case, you probably don't need to use AOLserver, either.  In the small, any web server will be more than adequate on modern hardware to serve a few hundred pages here and there.  It's when you start getting into the few hundred per second arena where AOLserver has the opportunity to shine. ''-- [[User:Dossy|Dossy]] 07:46, 10 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
* Not at all -- I'm looking at other languages simply from the point of view of seeing how AOLServer modules are built at all. It has been a while since I did any heavy lifting with C, and I felt that tinkering with the module code would be a good refresher. Just scratching an itch. I use TCL heavily every day at work, and have no real knowledge of Lua either, it just seemed an opportune target to use when examining the general AOLServer module layer. --[[User:Caveman|Caveman]] 12:23, 12 December 2005 (EST) &lt;br /&gt;
&lt;br /&gt;
** Okay, cool.  FYI, &amp;quot;AOLserver&amp;quot; is capitalized just like that, not &amp;quot;AOLServer&amp;quot; -- I'm picking nits, but the consistency is important to me.  Thanks.  :-) ''-- [[User:Dossy|Dossy]] 12:41, 12 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
*** Ack. I've been doing that on a ton of pages -- my mistake, I will try to use the correct capitalisation. --[[User:Caveman|Caveman]] 12:43, 12 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {ns_sha1 [ns_md5 [lindex $args 0]] [lindex $args 1]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;8&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
[http://philip.greenspun.com/doc/ philip.greenspun.com/doc/]&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline data-pipeline]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4640</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4640"/>
		<updated>2005-12-14T20:20:28Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* useful links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, and welcome to the wiki!  If you don't mind me asking, what's your full name (or do you want to remain anonymous)?  Are you also subscribed to the [http://aolserver.com/lists.php AOLSERVER mailing list]?  Some of us also hang out on [http://aolserver.com/chat/ IRC and chat] (you can also access the chat via AIM, but most folks use IRC).&lt;br /&gt;
&lt;br /&gt;
If you have any questions or concerns, don't hesitate to contact me.  Thanks! ''-- [[User:Dossy|Dossy]] 07:13, 3 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Why does it seem like you're avoiding Tcl?  Your recent wiki edits have been focused around other languages in AOLserver other than Tcl, like Lua, PHP and Ruby.  Why?  You will really never get the kind of performance out of Perl, PHP or Ruby as you will Tcl, because Tcl is suitable for embedding in a multi-threaded application where Perl, PHP and Ruby aren't.  (I don't know enough about Lua to say one way or the other.)  So, if you still want to use those other languages, then you probably don't care about performance at the high end, in which case, you probably don't need to use AOLserver, either.  In the small, any web server will be more than adequate on modern hardware to serve a few hundred pages here and there.  It's when you start getting into the few hundred per second arena where AOLserver has the opportunity to shine. ''-- [[User:Dossy|Dossy]] 07:46, 10 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
* Not at all -- I'm looking at other languages simply from the point of view of seeing how AOLServer modules are built at all. It has been a while since I did any heavy lifting with C, and I felt that tinkering with the module code would be a good refresher. Just scratching an itch. I use TCL heavily every day at work, and have no real knowledge of Lua either, it just seemed an opportune target to use when examining the general AOLServer module layer. --[[User:Caveman|Caveman]] 12:23, 12 December 2005 (EST) &lt;br /&gt;
&lt;br /&gt;
** Okay, cool.  FYI, &amp;quot;AOLserver&amp;quot; is capitalized just like that, not &amp;quot;AOLServer&amp;quot; -- I'm picking nits, but the consistency is important to me.  Thanks.  :-) ''-- [[User:Dossy|Dossy]] 12:41, 12 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
*** Ack. I've been doing that on a ton of pages -- my mistake, I will try to use the correct capitalisation. --[[User:Caveman|Caveman]] 12:43, 12 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {ns_sha1 [ns_md5 [lindex $args 0]] [lindex $args 1]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;8&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
[http://philip.greenspun.com/doc/ philip.greenspun.com/doc/]&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline philip.greenspun.com/doc/data-pipeline]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4639</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4639"/>
		<updated>2005-12-14T20:19:51Z</updated>

		<summary type="html">&lt;p&gt;Caveman: useful links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, and welcome to the wiki!  If you don't mind me asking, what's your full name (or do you want to remain anonymous)?  Are you also subscribed to the [http://aolserver.com/lists.php AOLSERVER mailing list]?  Some of us also hang out on [http://aolserver.com/chat/ IRC and chat] (you can also access the chat via AIM, but most folks use IRC).&lt;br /&gt;
&lt;br /&gt;
If you have any questions or concerns, don't hesitate to contact me.  Thanks! ''-- [[User:Dossy|Dossy]] 07:13, 3 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Why does it seem like you're avoiding Tcl?  Your recent wiki edits have been focused around other languages in AOLserver other than Tcl, like Lua, PHP and Ruby.  Why?  You will really never get the kind of performance out of Perl, PHP or Ruby as you will Tcl, because Tcl is suitable for embedding in a multi-threaded application where Perl, PHP and Ruby aren't.  (I don't know enough about Lua to say one way or the other.)  So, if you still want to use those other languages, then you probably don't care about performance at the high end, in which case, you probably don't need to use AOLserver, either.  In the small, any web server will be more than adequate on modern hardware to serve a few hundred pages here and there.  It's when you start getting into the few hundred per second arena where AOLserver has the opportunity to shine. ''-- [[User:Dossy|Dossy]] 07:46, 10 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
* Not at all -- I'm looking at other languages simply from the point of view of seeing how AOLServer modules are built at all. It has been a while since I did any heavy lifting with C, and I felt that tinkering with the module code would be a good refresher. Just scratching an itch. I use TCL heavily every day at work, and have no real knowledge of Lua either, it just seemed an opportune target to use when examining the general AOLServer module layer. --[[User:Caveman|Caveman]] 12:23, 12 December 2005 (EST) &lt;br /&gt;
&lt;br /&gt;
** Okay, cool.  FYI, &amp;quot;AOLserver&amp;quot; is capitalized just like that, not &amp;quot;AOLServer&amp;quot; -- I'm picking nits, but the consistency is important to me.  Thanks.  :-) ''-- [[User:Dossy|Dossy]] 12:41, 12 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
*** Ack. I've been doing that on a ton of pages -- my mistake, I will try to use the correct capitalisation. --[[User:Caveman|Caveman]] 12:43, 12 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {ns_sha1 [ns_md5 [lindex $args 0]] [lindex $args 1]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;8&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;br /&gt;
&lt;br /&gt;
== useful links ==&lt;br /&gt;
&lt;br /&gt;
[http://philip.greenspun.com/doc/data-pipeline]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User:Caveman&amp;diff=4638</id>
		<title>User:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User:Caveman&amp;diff=4638"/>
		<updated>2005-12-14T20:15:58Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[mailto:sam@caveman.org Samuel Montgomery-Blinn]&lt;br /&gt;
&lt;br /&gt;
An off-and-on hobbyist user of Aolserver from 3.x days. Never been an OpenACS fan, hope that doesn't get me into trouble someday. My Aolserver runs on Debian 3.1 using the aolserver4-* binary packages, so I thank the maintainers for their time and effort.&lt;br /&gt;
&lt;br /&gt;
'''Current interests:'''&lt;br /&gt;
&lt;br /&gt;
Best Practices on cookie management and session management with AOLServer&lt;br /&gt;
&lt;br /&gt;
Best Pratcices for identity management and authorization model AOLServer&lt;br /&gt;
&lt;br /&gt;
Tinkering with a standardised phpinfo() alike command: [http://caveman.org/info/]&lt;br /&gt;
&lt;br /&gt;
Blogging/discussion software, especially usefully multi-user.&lt;br /&gt;
&lt;br /&gt;
SVG graphics generation.&lt;br /&gt;
&lt;br /&gt;
Application model and management.&lt;br /&gt;
&lt;br /&gt;
nsdbeans data layer (similar to Java's EJB, or Python's SQLObject).&lt;br /&gt;
&lt;br /&gt;
SOAP conversation with directi's reseller server [http://manage.directi.com/kb/servlet/KBServlet/cat106.html]&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
'''Current 'real' work:'''&lt;br /&gt;
&lt;br /&gt;
A lot of JACL/TCL scripting in the test automation world for &amp;quot;nameless big software company&amp;quot;. WebSphere includes a JACL administrative shell that is quite useful for scripting all kinds of configuration and test activity for J2EE applications.&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4637</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4637"/>
		<updated>2005-12-14T20:15:36Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, and welcome to the wiki!  If you don't mind me asking, what's your full name (or do you want to remain anonymous)?  Are you also subscribed to the [http://aolserver.com/lists.php AOLSERVER mailing list]?  Some of us also hang out on [http://aolserver.com/chat/ IRC and chat] (you can also access the chat via AIM, but most folks use IRC).&lt;br /&gt;
&lt;br /&gt;
If you have any questions or concerns, don't hesitate to contact me.  Thanks! ''-- [[User:Dossy|Dossy]] 07:13, 3 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Why does it seem like you're avoiding Tcl?  Your recent wiki edits have been focused around other languages in AOLserver other than Tcl, like Lua, PHP and Ruby.  Why?  You will really never get the kind of performance out of Perl, PHP or Ruby as you will Tcl, because Tcl is suitable for embedding in a multi-threaded application where Perl, PHP and Ruby aren't.  (I don't know enough about Lua to say one way or the other.)  So, if you still want to use those other languages, then you probably don't care about performance at the high end, in which case, you probably don't need to use AOLserver, either.  In the small, any web server will be more than adequate on modern hardware to serve a few hundred pages here and there.  It's when you start getting into the few hundred per second arena where AOLserver has the opportunity to shine. ''-- [[User:Dossy|Dossy]] 07:46, 10 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
* Not at all -- I'm looking at other languages simply from the point of view of seeing how AOLServer modules are built at all. It has been a while since I did any heavy lifting with C, and I felt that tinkering with the module code would be a good refresher. Just scratching an itch. I use TCL heavily every day at work, and have no real knowledge of Lua either, it just seemed an opportune target to use when examining the general AOLServer module layer. --[[User:Caveman|Caveman]] 12:23, 12 December 2005 (EST) &lt;br /&gt;
&lt;br /&gt;
** Okay, cool.  FYI, &amp;quot;AOLserver&amp;quot; is capitalized just like that, not &amp;quot;AOLServer&amp;quot; -- I'm picking nits, but the consistency is important to me.  Thanks.  :-) ''-- [[User:Dossy|Dossy]] 12:41, 12 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
*** Ack. I've been doing that on a ton of pages -- my mistake, I will try to use the correct capitalisation. --[[User:Caveman|Caveman]] 12:43, 12 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {ns_sha1 [ns_md5 [lindex $args 0]] [lindex $args 1]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;8&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Frequently_Asked_Questions&amp;diff=4636</id>
		<title>Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Frequently_Asked_Questions&amp;diff=4636"/>
		<updated>2005-12-14T19:45:20Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* changed should no longer be necessary to stronger language for package require example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Frequently Asked Questions'''&lt;br /&gt;
&lt;br /&gt;
(Please add new questions at the very bottom  of the list.  Thanks.)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''What is AOLserver?'''&lt;br /&gt;
&lt;br /&gt;
AOLserver is America Online's Open Source web server.  AOLserver is the backbone of the largest and busiest production environments in the world.&lt;br /&gt;
&lt;br /&gt;
AOLserver is a multithreaded, Tcl-enabled, massively-scalable and extensible web server tuned for large scale, dynamic web sites. AOLserver also includes complete database integration and a dynamic page scripting language.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''What is the latest version of AOLserver?'''&lt;br /&gt;
* The latest stable 3.4.x version is 3.4.2 released 18 September 2001.&lt;br /&gt;
* The latest stable 3.5.x version is 3.5.11 released 17 October 2003.&lt;br /&gt;
* The latest stable 4.0.x version is 4.0.10 released 18 January 2005.&lt;br /&gt;
* Current development (CVS HEAD) is 4.1.0a.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Where can I get AOLserver?'''&lt;br /&gt;
&lt;br /&gt;
The AOLserver project is hosted at [http://sourceforge.net/ SourceForge], and file releases are available for [[download]] in the [http://sourceforge.net/project/showfiles.php?group_id=3152 AOLserver Project Filelist].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''What platforms does AOLserver support?'''&lt;br /&gt;
&lt;br /&gt;
'''AOLserver''' is known to compile and run on the following platforms:&lt;br /&gt;
* Linux 2.2 (i386), 2.4 and 2.6&lt;br /&gt;
* Windows 95/98/NT/2K/XP (i386) (partially supported, see #6)&lt;br /&gt;
* FreeBSD 3.4 (i386)&lt;br /&gt;
* OpenBSD 2.5 (i386)&lt;br /&gt;
* UnixWare 7.x (i386)&lt;br /&gt;
* DEC Tru64 &amp;amp; OSF/1 4.0 (alpha)&lt;br /&gt;
* Solaris 2.x (sparc), Solaris 2.10 (x86)&lt;br /&gt;
* HP/UX 10 &amp;amp; 11 (hppa)&lt;br /&gt;
* Irix 6.x (mips)&lt;br /&gt;
* Apple MacOS X 10.3 (ppc), 10.4 (ppc)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How is AOLserver licensed and distributed?'''&lt;br /&gt;
&lt;br /&gt;
Via the [[AOLserver Public License]], viewable at http://aolserver.com/license/.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How does AOLserver performance compare to other major servers?'''&lt;br /&gt;
&lt;br /&gt;
[[Brady Wetherington]] says:  On Unix, AOLserver can generate many, many dynamic pages very quickly and reliably. It also has some special code paths designed to speed up processing of static pages (fastpath), though I don't use that very much, personally.  Along with the database connection pools, it's definitely one of the highest-performance web-based database systems I've used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''How is it different from Apache HTTP Server?'''&lt;br /&gt;
&lt;br /&gt;
The current Apache HTTP Server&lt;br /&gt;
* is part of / a project of the Apache Software Foundation. The process of development and decision making is working for years and accepted by all participants&lt;br /&gt;
* allows to run applications in a process-pre-forking or multi-threaded environment by design&lt;br /&gt;
* is the leading webserver, so it is widely known, accepted and supported&lt;br /&gt;
* is itself a subproject accompanied by lots of well known other projects and frameworks (like Ant, Jakarta, Struts...)&lt;br /&gt;
&lt;br /&gt;
In contrast AOLserver&lt;br /&gt;
* can do lots of use cases that are done with Apache modules with a few lines of TCL code (via registered filters and procs)&lt;br /&gt;
* is bound to its multi-threaded architecture that has its own disadvantages, depending on what you want to do&lt;br /&gt;
&lt;br /&gt;
'''How is it different from &amp;lt;insert other webserver&amp;gt;?'''&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Where is AOLserver appropriate?  Where is it not?'''&lt;br /&gt;
&lt;br /&gt;
It is not appropriate...&lt;br /&gt;
* when you want to do virtual hosting for multiple customers.  For static content, AOLserver is fine - you're just serving static content.  For dynamic, server-side functionality, to get the level of privilege separation necessary, you'd have to run a separate nsd per customer to ensure that one customer can't access the content/data of another's.  There are apparently some folks out there who have set up AOLserver just this way and are doing just this.&lt;br /&gt;
* when the code you want to use is not thread-safe (and you are not able to change that)&lt;br /&gt;
* when your main application makes heavy use of cgi-tools or other scripting languages like PHP or Phython (in general: where currently no active dedicated maintainer for corresponding modules is known)&lt;br /&gt;
* when you need backup of a large world wide community that uses tools, modules and code you can find and read in every single computer magazine. AOLserver and TCL are niche products, which only means they are not sexy to the broad audience, but are used intensively by a sophisticated, intelligent minority&lt;br /&gt;
* when you know you would need more than one day to convince your customer to use it (in other words: if you use technology the first time don't let your most important customer be the beta tester)&lt;br /&gt;
&lt;br /&gt;
It is appropriate...&lt;br /&gt;
* when you want to make maximum use of your machines hardware ressources: AOLserver is a highly configurable beast that allows you to run big websites&lt;br /&gt;
* when you plan to run a website that makes heavy use of one or more databases (using pooled connections)&lt;br /&gt;
* when you want to cache lots or all of your static files (.html,.gif,.css.,.js ...) in your servers memory (via modules fastpath and nscache)&lt;br /&gt;
* when you like the good feeling of running and coding your apps on a well-tested multi-threaded server architecture. The server never has been a process-forking one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The idea here is if you know your requirements and your scope is fairly stable and you feel comfortable you can predict the future, and if all signs point to the app. remaining small-to-medium in usage/traffic, then pick whatever platform or technology you like the best -- it really won't make a difference.  But, if you think that it's a very real possibility you'll need&lt;br /&gt;
to scale up capacity to meet growing demand/traffic, possibly indefinitely, then yes, the hidden cost of re-architecting or migrating to a different technology can be a killer when you have to use the words &amp;quot;sunk cost&amp;quot; to describe the originally developed system.  In that case, you may be better off starting with implementing with AOLserver, as its performance &amp;quot;ceiling&amp;quot; so to speak is higher than other technologies.  (TODO: Benchmarks demonstrating this empirically?)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How do I get started with AOLserver?'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;need to link to a newbie guide HOWTO&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How can I learn more about AOLserver?'''&lt;br /&gt;
&lt;br /&gt;
Start by reading the [[Documentation]], which is still a work-in-progress.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''&amp;quot;package require&amp;quot; doesn't work!  What's wrong?'''&lt;br /&gt;
&lt;br /&gt;
Here's the relevant portion of a message [[Dossy Shiobara]] sent to the AOLserver mailing list back on 16 June 2000:&lt;br /&gt;
&lt;br /&gt;
  set tcl_library [file join $tcl_pkgPath tcl${tcl_version}]&lt;br /&gt;
  source [file join $tcl_library init.tcl]&lt;br /&gt;
&lt;br /&gt;
  package require works like a charm after that :-)&lt;br /&gt;
&lt;br /&gt;
There you have it.  Perhaps, some day, this won't be a necessary step.  But, in the meantime ...&lt;br /&gt;
&lt;br /&gt;
''As of AOLserver 4.0 and perhaps even a late version of 3.5.x, this step is no longer necessary.''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''&amp;quot;ns_set update [ns_conn outputheaders $conn] Content-Type {application/x-tcl}&amp;quot; does not work in .adp files as I wish.  The server always returns two copies of the Content-Type header, one as application/x-tcl, another as text/html and clients(galeon, tcl http package) always use the second.  How do I remove the second Content-Type?'''&lt;br /&gt;
&lt;br /&gt;
Good question -- this is really a bug that needs to be fixed in the server code itself.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How can I get Tclet scripts served from AOLserver to run inside the Tcl Plugin?'''&lt;br /&gt;
&lt;br /&gt;
Someone asks: ''I have an aolserver for OpenACS.  I installed Tcl Plugin which works well with classic Tclets on Tcl Plugin Home Pages.  But with Aolserver, it doesn't work.... Do you know the answer of this?''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How can I compile AOLserver on HP-UX, both 10.20 and 11.x?'''&lt;br /&gt;
&lt;br /&gt;
[[Dossy]]: Good question.  If I had easy access to HP-UX machines, I'd try it myself.  AOLserver 4.x should hopefully build on HP-UX without any changes, but I'm only guessing.&lt;br /&gt;
&lt;br /&gt;
HPUX doesn't implement a lot of BSD/POSIX IPC functions, or so I hear.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''I'm getting an error compiling AOLserver about POLLIN, POLLOUT and POLLPRI being redefined.  What's wrong?'''&lt;br /&gt;
&lt;br /&gt;
AOLserver requires that the &amp;quot;configure&amp;quot; script be run using the GNU C (gcc) compiler.  Try running the configure script like this:&lt;br /&gt;
&lt;br /&gt;
    $ CC=gcc ./configure --args...&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Does AOLserver support HTTP Keep-Alive?  I'm sending a HTTP/1.1 request via httperf and AOLserver isn't doing Keep-Alive like Apache does!  What's wrong?'''&lt;br /&gt;
&lt;br /&gt;
Actually, nothing is wrong. You just need to tell httperf to include the headers that tell AOLserver to expect multiple requests per connection. Add '--add_header &amp;quot;Connection: Keep-Alive\n&amp;quot;' to your httperf request. &lt;br /&gt;
&lt;br /&gt;
The issue is that Apache and AOLserver chose opposite default behaviors when interpretting [http://www.ietf.org/rfc/rfc2068.txt RFC 2068 section 8.1.2.1]:&lt;br /&gt;
&lt;br /&gt;
   An HTTP/1.1 server MAY assume that a HTTP/1.1 client intends to&lt;br /&gt;
   maintain a persistent connection unless a Connection header including&lt;br /&gt;
   the connection-token &amp;quot;close&amp;quot; was sent in the request. If the server&lt;br /&gt;
   chooses to close the connection immediately after sending the&lt;br /&gt;
   response, it SHOULD send a Connection header including the&lt;br /&gt;
   connection-token close.&lt;br /&gt;
&lt;br /&gt;
   An HTTP/1.1 client MAY expect a connection to remain open, but would&lt;br /&gt;
   decide to keep it open based on whether the response from a server&lt;br /&gt;
   contains a Connection header with the connection-token close. In case&lt;br /&gt;
   the client does not want to maintain a connection for more than that&lt;br /&gt;
   request, it SHOULD send a Connection header including the&lt;br /&gt;
   connection-token close.&lt;br /&gt;
&lt;br /&gt;
The key here is &amp;quot;MAY&amp;quot; -- AOLserver (currently, as of 4.0.10) chooses not to assume a Keep-Alive connection unless the client explicitly requests it by sending &amp;quot;Connection: Keep-Alive&amp;quot; in the HTTP request header.  This may change in the future (HTTP/1.1 requests default to Keep-Alive unless the client explicitly sends &amp;quot;Connection: close&amp;quot; -- apparently this is how Apache works).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category Documentation]]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Frequently_Asked_Questions&amp;diff=4635</id>
		<title>Frequently Asked Questions</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Frequently_Asked_Questions&amp;diff=4635"/>
		<updated>2005-12-14T19:43:43Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* fixed brackets in code sample for package require */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Frequently Asked Questions'''&lt;br /&gt;
&lt;br /&gt;
(Please add new questions at the very bottom  of the list.  Thanks.)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''What is AOLserver?'''&lt;br /&gt;
&lt;br /&gt;
AOLserver is America Online's Open Source web server.  AOLserver is the backbone of the largest and busiest production environments in the world.&lt;br /&gt;
&lt;br /&gt;
AOLserver is a multithreaded, Tcl-enabled, massively-scalable and extensible web server tuned for large scale, dynamic web sites. AOLserver also includes complete database integration and a dynamic page scripting language.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''What is the latest version of AOLserver?'''&lt;br /&gt;
* The latest stable 3.4.x version is 3.4.2 released 18 September 2001.&lt;br /&gt;
* The latest stable 3.5.x version is 3.5.11 released 17 October 2003.&lt;br /&gt;
* The latest stable 4.0.x version is 4.0.10 released 18 January 2005.&lt;br /&gt;
* Current development (CVS HEAD) is 4.1.0a.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Where can I get AOLserver?'''&lt;br /&gt;
&lt;br /&gt;
The AOLserver project is hosted at [http://sourceforge.net/ SourceForge], and file releases are available for [[download]] in the [http://sourceforge.net/project/showfiles.php?group_id=3152 AOLserver Project Filelist].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''What platforms does AOLserver support?'''&lt;br /&gt;
&lt;br /&gt;
'''AOLserver''' is known to compile and run on the following platforms:&lt;br /&gt;
* Linux 2.2 (i386), 2.4 and 2.6&lt;br /&gt;
* Windows 95/98/NT/2K/XP (i386) (partially supported, see #6)&lt;br /&gt;
* FreeBSD 3.4 (i386)&lt;br /&gt;
* OpenBSD 2.5 (i386)&lt;br /&gt;
* UnixWare 7.x (i386)&lt;br /&gt;
* DEC Tru64 &amp;amp; OSF/1 4.0 (alpha)&lt;br /&gt;
* Solaris 2.x (sparc), Solaris 2.10 (x86)&lt;br /&gt;
* HP/UX 10 &amp;amp; 11 (hppa)&lt;br /&gt;
* Irix 6.x (mips)&lt;br /&gt;
* Apple MacOS X 10.3 (ppc), 10.4 (ppc)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How is AOLserver licensed and distributed?'''&lt;br /&gt;
&lt;br /&gt;
Via the [[AOLserver Public License]], viewable at http://aolserver.com/license/.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How does AOLserver performance compare to other major servers?'''&lt;br /&gt;
&lt;br /&gt;
[[Brady Wetherington]] says:  On Unix, AOLserver can generate many, many dynamic pages very quickly and reliably. It also has some special code paths designed to speed up processing of static pages (fastpath), though I don't use that very much, personally.  Along with the database connection pools, it's definitely one of the highest-performance web-based database systems I've used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''How is it different from Apache HTTP Server?'''&lt;br /&gt;
&lt;br /&gt;
The current Apache HTTP Server&lt;br /&gt;
* is part of / a project of the Apache Software Foundation. The process of development and decision making is working for years and accepted by all participants&lt;br /&gt;
* allows to run applications in a process-pre-forking or multi-threaded environment by design&lt;br /&gt;
* is the leading webserver, so it is widely known, accepted and supported&lt;br /&gt;
* is itself a subproject accompanied by lots of well known other projects and frameworks (like Ant, Jakarta, Struts...)&lt;br /&gt;
&lt;br /&gt;
In contrast AOLserver&lt;br /&gt;
* can do lots of use cases that are done with Apache modules with a few lines of TCL code (via registered filters and procs)&lt;br /&gt;
* is bound to its multi-threaded architecture that has its own disadvantages, depending on what you want to do&lt;br /&gt;
&lt;br /&gt;
'''How is it different from &amp;lt;insert other webserver&amp;gt;?'''&lt;br /&gt;
&lt;br /&gt;
???&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Where is AOLserver appropriate?  Where is it not?'''&lt;br /&gt;
&lt;br /&gt;
It is not appropriate...&lt;br /&gt;
* when you want to do virtual hosting for multiple customers.  For static content, AOLserver is fine - you're just serving static content.  For dynamic, server-side functionality, to get the level of privilege separation necessary, you'd have to run a separate nsd per customer to ensure that one customer can't access the content/data of another's.  There are apparently some folks out there who have set up AOLserver just this way and are doing just this.&lt;br /&gt;
* when the code you want to use is not thread-safe (and you are not able to change that)&lt;br /&gt;
* when your main application makes heavy use of cgi-tools or other scripting languages like PHP or Phython (in general: where currently no active dedicated maintainer for corresponding modules is known)&lt;br /&gt;
* when you need backup of a large world wide community that uses tools, modules and code you can find and read in every single computer magazine. AOLserver and TCL are niche products, which only means they are not sexy to the broad audience, but are used intensively by a sophisticated, intelligent minority&lt;br /&gt;
* when you know you would need more than one day to convince your customer to use it (in other words: if you use technology the first time don't let your most important customer be the beta tester)&lt;br /&gt;
&lt;br /&gt;
It is appropriate...&lt;br /&gt;
* when you want to make maximum use of your machines hardware ressources: AOLserver is a highly configurable beast that allows you to run big websites&lt;br /&gt;
* when you plan to run a website that makes heavy use of one or more databases (using pooled connections)&lt;br /&gt;
* when you want to cache lots or all of your static files (.html,.gif,.css.,.js ...) in your servers memory (via modules fastpath and nscache)&lt;br /&gt;
* when you like the good feeling of running and coding your apps on a well-tested multi-threaded server architecture. The server never has been a process-forking one.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The idea here is if you know your requirements and your scope is fairly stable and you feel comfortable you can predict the future, and if all signs point to the app. remaining small-to-medium in usage/traffic, then pick whatever platform or technology you like the best -- it really won't make a difference.  But, if you think that it's a very real possibility you'll need&lt;br /&gt;
to scale up capacity to meet growing demand/traffic, possibly indefinitely, then yes, the hidden cost of re-architecting or migrating to a different technology can be a killer when you have to use the words &amp;quot;sunk cost&amp;quot; to describe the originally developed system.  In that case, you may be better off starting with implementing with AOLserver, as its performance &amp;quot;ceiling&amp;quot; so to speak is higher than other technologies.  (TODO: Benchmarks demonstrating this empirically?)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How do I get started with AOLserver?'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;need to link to a newbie guide HOWTO&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How can I learn more about AOLserver?'''&lt;br /&gt;
&lt;br /&gt;
Start by reading the [[Documentation]], which is still a work-in-progress.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''&amp;quot;package require&amp;quot; doesn't work!  What's wrong?'''&lt;br /&gt;
&lt;br /&gt;
Here's the relevant portion of a message [[Dossy Shiobara]] sent to the AOLserver mailing list back on 16 June 2000:&lt;br /&gt;
&lt;br /&gt;
  set tcl_library [file join $tcl_pkgPath tcl${tcl_version}]&lt;br /&gt;
  source [file join $tcl_library init.tcl]&lt;br /&gt;
&lt;br /&gt;
  package require works like a charm after that :-)&lt;br /&gt;
&lt;br /&gt;
There you have it.  Perhaps, some day, this won't be a necessary step.  But, in the meantime ...&lt;br /&gt;
&lt;br /&gt;
''As of AOLserver 4.0 and perhaps even a late version of 3.5.x, this step should no longer be necessary.''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''&amp;quot;ns_set update [ns_conn outputheaders $conn] Content-Type {application/x-tcl}&amp;quot; does not work in .adp files as I wish.  The server always returns two copies of the Content-Type header, one as application/x-tcl, another as text/html and clients(galeon, tcl http package) always use the second.  How do I remove the second Content-Type?'''&lt;br /&gt;
&lt;br /&gt;
Good question -- this is really a bug that needs to be fixed in the server code itself.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How can I get Tclet scripts served from AOLserver to run inside the Tcl Plugin?'''&lt;br /&gt;
&lt;br /&gt;
Someone asks: ''I have an aolserver for OpenACS.  I installed Tcl Plugin which works well with classic Tclets on Tcl Plugin Home Pages.  But with Aolserver, it doesn't work.... Do you know the answer of this?''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''How can I compile AOLserver on HP-UX, both 10.20 and 11.x?'''&lt;br /&gt;
&lt;br /&gt;
[[Dossy]]: Good question.  If I had easy access to HP-UX machines, I'd try it myself.  AOLserver 4.x should hopefully build on HP-UX without any changes, but I'm only guessing.&lt;br /&gt;
&lt;br /&gt;
HPUX doesn't implement a lot of BSD/POSIX IPC functions, or so I hear.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''I'm getting an error compiling AOLserver about POLLIN, POLLOUT and POLLPRI being redefined.  What's wrong?'''&lt;br /&gt;
&lt;br /&gt;
AOLserver requires that the &amp;quot;configure&amp;quot; script be run using the GNU C (gcc) compiler.  Try running the configure script like this:&lt;br /&gt;
&lt;br /&gt;
    $ CC=gcc ./configure --args...&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''Does AOLserver support HTTP Keep-Alive?  I'm sending a HTTP/1.1 request via httperf and AOLserver isn't doing Keep-Alive like Apache does!  What's wrong?'''&lt;br /&gt;
&lt;br /&gt;
Actually, nothing is wrong. You just need to tell httperf to include the headers that tell AOLserver to expect multiple requests per connection. Add '--add_header &amp;quot;Connection: Keep-Alive\n&amp;quot;' to your httperf request. &lt;br /&gt;
&lt;br /&gt;
The issue is that Apache and AOLserver chose opposite default behaviors when interpretting [http://www.ietf.org/rfc/rfc2068.txt RFC 2068 section 8.1.2.1]:&lt;br /&gt;
&lt;br /&gt;
   An HTTP/1.1 server MAY assume that a HTTP/1.1 client intends to&lt;br /&gt;
   maintain a persistent connection unless a Connection header including&lt;br /&gt;
   the connection-token &amp;quot;close&amp;quot; was sent in the request. If the server&lt;br /&gt;
   chooses to close the connection immediately after sending the&lt;br /&gt;
   response, it SHOULD send a Connection header including the&lt;br /&gt;
   connection-token close.&lt;br /&gt;
&lt;br /&gt;
   An HTTP/1.1 client MAY expect a connection to remain open, but would&lt;br /&gt;
   decide to keep it open based on whether the response from a server&lt;br /&gt;
   contains a Connection header with the connection-token close. In case&lt;br /&gt;
   the client does not want to maintain a connection for more than that&lt;br /&gt;
   request, it SHOULD send a Connection header including the&lt;br /&gt;
   connection-token close.&lt;br /&gt;
&lt;br /&gt;
The key here is &amp;quot;MAY&amp;quot; -- AOLserver (currently, as of 4.0.10) chooses not to assume a Keep-Alive connection unless the client explicitly requests it by sending &amp;quot;Connection: Keep-Alive&amp;quot; in the HTTP request header.  This may change in the future (HTTP/1.1 requests default to Keep-Alive unless the client explicitly sends &amp;quot;Connection: close&amp;quot; -- apparently this is how Apache works).&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category Documentation]]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_job&amp;diff=4634</id>
		<title>Ns job</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_job&amp;diff=4634"/>
		<updated>2005-12-14T14:44:22Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* removed spam */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{manpage|ns_job}}&lt;br /&gt;
&lt;br /&gt;
'''NAME'''&lt;br /&gt;
&lt;br /&gt;
: ns_job - Implement job queues and thread pools for evaluating Tcl scripts&lt;br /&gt;
&lt;br /&gt;
'''SYNOPSIS'''&lt;br /&gt;
&lt;br /&gt;
: '''ns_job''' ''option ?arg arg ...?''&lt;br /&gt;
&lt;br /&gt;
'''DESCRIPTION'''&lt;br /&gt;
&lt;br /&gt;
: '''ns_job''' manages a thread pool and a set of named &amp;quot;queues&amp;quot;. Queues have a max number of threads and when the current number of running thread reaches &amp;quot;max&amp;quot; then jobs are queued.  New threads are created when there are less than maxthread number of idle threads.&lt;br /&gt;
&lt;br /&gt;
: This command provides a means for queueing Tcl scripts for evaluation by a pool of threads.  The legal ''option''s (which may be abbreviated) are:&lt;br /&gt;
* '''ns_job create''' ''?-desc description? queueId ?maxthreads?''&lt;br /&gt;
&lt;br /&gt;
: Create a new job queue called ''queueId''. If ''maxthreads'' is not specified, then the default of 4 is used.&lt;br /&gt;
* '''ns_job queue''' ''?-detached?'' queueId script&lt;br /&gt;
&lt;br /&gt;
: Add a new job to the queue. If there are less than maxthreads current running then the job will be started. If there are maxthreads currently running then this new job will be queued.&lt;br /&gt;
&lt;br /&gt;
: If ''-detached'', then the job will be claned up when it completes; no wait will be necessary.&lt;br /&gt;
&lt;br /&gt;
: The new job's ID is returned.&lt;br /&gt;
* '''ns_job wait''' ''?-timeout seconds:microseconds?'' queueId jobId&lt;br /&gt;
&lt;br /&gt;
: Wait for the specified queued or running job to finish.  '''ns_job wait''' returns the results of the script.&lt;br /&gt;
&lt;br /&gt;
: An error is thrown if the specified timeout period is reached.&lt;br /&gt;
* '''ns_job waitany''' ''?-timeout seconds:microseconds?'' queueId&lt;br /&gt;
&lt;br /&gt;
: Wait for any job on the queue complete.&lt;br /&gt;
&lt;br /&gt;
: An error is thrown if the specified timeout period is reached.&lt;br /&gt;
* '''ns_job cancel''' queueId jobId&lt;br /&gt;
&lt;br /&gt;
: Remove the specified job from the queue. If the job is currently running, then the job will be removed from the queue when it completes.&lt;br /&gt;
&lt;br /&gt;
: 1 (true) is returned if the job is currently running and can not be cancelled.&lt;br /&gt;
* '''ns_job delete''' queueId&lt;br /&gt;
&lt;br /&gt;
: Request that the specified queue be deleted. The queue will only be deleted when all jobs are removed.&lt;br /&gt;
* '''ns_job jobs''' queueId&lt;br /&gt;
&lt;br /&gt;
: Return a list of the job IDs.&lt;br /&gt;
* '''ns_job queues'''&lt;br /&gt;
&lt;br /&gt;
: Returns a list of the queue IDs.&lt;br /&gt;
* '''ns_job threadlist'''&lt;br /&gt;
&lt;br /&gt;
: Returns a list of the thread pool's fields.&lt;br /&gt;
&lt;br /&gt;
: '''maxthreads''' - Max number of threads for all the queues in the thread pool.&lt;br /&gt;
&lt;br /&gt;
: '''numthreads''' - Number of allocated threads.&lt;br /&gt;
&lt;br /&gt;
: '''numidle''' - Number of currently idle threads.&lt;br /&gt;
&lt;br /&gt;
: '''req stop''' - The thread pools is being stopped. This probably means that the server is shutting down.&lt;br /&gt;
* '''ns_job queuelist'''&lt;br /&gt;
&lt;br /&gt;
: Returns a list of the queues. A queue has the following fields:&lt;br /&gt;
&lt;br /&gt;
: '''name''' - Name of the queue.&lt;br /&gt;
&lt;br /&gt;
: '''desc''' - Description of the queue.&lt;br /&gt;
&lt;br /&gt;
: '''maxthreads''' - Max number of threads to run for this queue.&lt;br /&gt;
&lt;br /&gt;
: '''numrunning''' - Number of currently running jobs in this queue.&lt;br /&gt;
&lt;br /&gt;
: '''REQ delete''' - Someone requested this queue be deleted. Queue will not be deleted until all the jobs on the queue are removed.&lt;br /&gt;
* '''ns_job joblist''' queueId&lt;br /&gt;
&lt;br /&gt;
: Returns a list the jobs in the specified queue. A job has the following fields:&lt;br /&gt;
&lt;br /&gt;
: '''id''' - Job's ID&lt;br /&gt;
&lt;br /&gt;
: '''state''' - The state of the job.  The return values are as follows:&lt;br /&gt;
&lt;br /&gt;
: scheduled - The job is scheduled to run.&lt;br /&gt;
&lt;br /&gt;
: running - The job is currently running.&lt;br /&gt;
&lt;br /&gt;
: done - The job has completed.&lt;br /&gt;
&lt;br /&gt;
: '''results''' - If the job has completed, then this field will contain the results. If the job is running or scheduled to run, then this will contain the script.&lt;br /&gt;
 &lt;br /&gt;
: '''code''' - When the job is done, this will contain the return code. Return codes are ''TCL_OK'', ''TCL_ERROR'', ''TCL_RETURN'', ''TCL_BREAK'', ''TCL_CONTINUE''.&lt;br /&gt;
&lt;br /&gt;
: '''type''' - The type of job.  A job's return value is ''nondetached'' or ''detached''.&lt;br /&gt;
&lt;br /&gt;
: '''req''' - The job is required.   Return values are ''none'', ''wait'', ''cancel''.&lt;br /&gt;
* '''ns_job genid'''&lt;br /&gt;
&lt;br /&gt;
: Generate a new unique ID. This new ID can be used as the queue ID without conflicting with any other queue ID.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''EXAMPLES'''&lt;br /&gt;
&lt;br /&gt;
'''SEE ALSO'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Core Tcl API]]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Web_Applications_for_AOLserver&amp;diff=4632</id>
		<title>Talk:Web Applications for AOLserver</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Web_Applications_for_AOLserver&amp;diff=4632"/>
		<updated>2005-12-13T17:44:21Z</updated>

		<summary type="html">&lt;p&gt;Caveman: AJAX discussion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Before we can willy-nilly go off and implement one or more of these things, shouldn't there be some common model of application, user, role, etc, that should be defined so that there is at least the potential of some or all of the applications being able to co-exist? For example, to-do list, calendar, web-mail, if they all used a common model there would be the potential to tie them all in together (e.g. OSSWEB).&lt;br /&gt;
&lt;br /&gt;
== AJAX discussion ==&lt;br /&gt;
&lt;br /&gt;
Has much been done in the area of AJAX implementations using AOLserver? Yes, it is another one of those buzz words full of promise, etc, and also full of drawbacks that people don't like to talk about. Yet it would be interesting to see what kind of performance AOLserver can do serving thousands of pages with thousands more AJAX requests. I would guess very good. The requests can probably be parsed by hand using ns_xml, but perhaps we could provide even simpler hooks for applications to use.&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4631</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4631"/>
		<updated>2005-12-13T14:56:29Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, and welcome to the wiki!  If you don't mind me asking, what's your full name (or do you want to remain anonymous)?  Are you also subscribed to the [http://aolserver.com/lists.php AOLSERVER mailing list]?  Some of us also hang out on [http://aolserver.com/chat/ IRC and chat] (you can also access the chat via AIM, but most folks use IRC).&lt;br /&gt;
&lt;br /&gt;
If you have any questions or concerns, don't hesitate to contact me.  Thanks! ''-- [[User:Dossy|Dossy]] 07:13, 3 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Why does it seem like you're avoiding Tcl?  Your recent wiki edits have been focused around other languages in AOLserver other than Tcl, like Lua, PHP and Ruby.  Why?  You will really never get the kind of performance out of Perl, PHP or Ruby as you will Tcl, because Tcl is suitable for embedding in a multi-threaded application where Perl, PHP and Ruby aren't.  (I don't know enough about Lua to say one way or the other.)  So, if you still want to use those other languages, then you probably don't care about performance at the high end, in which case, you probably don't need to use AOLserver, either.  In the small, any web server will be more than adequate on modern hardware to serve a few hundred pages here and there.  It's when you start getting into the few hundred per second arena where AOLserver has the opportunity to shine. ''-- [[User:Dossy|Dossy]] 07:46, 10 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
* Not at all -- I'm looking at other languages simply from the point of view of seeing how AOLServer modules are built at all. It has been a while since I did any heavy lifting with C, and I felt that tinkering with the module code would be a good refresher. Just scratching an itch. I use TCL heavily every day at work, and have no real knowledge of Lua either, it just seemed an opportune target to use when examining the general AOLServer module layer. --[[Caveman]] 12:23, 12 December 2005 (EST) &lt;br /&gt;
&lt;br /&gt;
** Okay, cool.  FYI, &amp;quot;AOLserver&amp;quot; is capitalized just like that, not &amp;quot;AOLServer&amp;quot; -- I'm picking nits, but the consistency is important to me.  Thanks.  :-) ''-- [[User:Dossy|Dossy]] 12:41, 12 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
*** Ack. I've been doing that on a ton of pages -- my mistake, I will try to use the correct capitalisation. --[[User:Caveman|Caveman]] 12:43, 12 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {ns_sha1 [ns_md5 [lindex $args 0]] [lindex $args 1]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;8&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   e.g. &amp;quot;transform the password&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   e.g. &amp;quot;generate the next id from sequence&amp;quot;&lt;br /&gt;
#     ns_set update $nssData &amp;quot;id&amp;quot; [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4630</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4630"/>
		<updated>2005-12-13T14:54:22Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, and welcome to the wiki!  If you don't mind me asking, what's your full name (or do you want to remain anonymous)?  Are you also subscribed to the [http://aolserver.com/lists.php AOLSERVER mailing list]?  Some of us also hang out on [http://aolserver.com/chat/ IRC and chat] (you can also access the chat via AIM, but most folks use IRC).&lt;br /&gt;
&lt;br /&gt;
If you have any questions or concerns, don't hesitate to contact me.  Thanks! ''-- [[User:Dossy|Dossy]] 07:13, 3 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Why does it seem like you're avoiding Tcl?  Your recent wiki edits have been focused around other languages in AOLserver other than Tcl, like Lua, PHP and Ruby.  Why?  You will really never get the kind of performance out of Perl, PHP or Ruby as you will Tcl, because Tcl is suitable for embedding in a multi-threaded application where Perl, PHP and Ruby aren't.  (I don't know enough about Lua to say one way or the other.)  So, if you still want to use those other languages, then you probably don't care about performance at the high end, in which case, you probably don't need to use AOLserver, either.  In the small, any web server will be more than adequate on modern hardware to serve a few hundred pages here and there.  It's when you start getting into the few hundred per second arena where AOLserver has the opportunity to shine. ''-- [[User:Dossy|Dossy]] 07:46, 10 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
* Not at all -- I'm looking at other languages simply from the point of view of seeing how AOLServer modules are built at all. It has been a while since I did any heavy lifting with C, and I felt that tinkering with the module code would be a good refresher. Just scratching an itch. I use TCL heavily every day at work, and have no real knowledge of Lua either, it just seemed an opportune target to use when examining the general AOLServer module layer. --[[Caveman]] 12:23, 12 December 2005 (EST) &lt;br /&gt;
&lt;br /&gt;
** Okay, cool.  FYI, &amp;quot;AOLserver&amp;quot; is capitalized just like that, not &amp;quot;AOLServer&amp;quot; -- I'm picking nits, but the consistency is important to me.  Thanks.  :-) ''-- [[User:Dossy|Dossy]] 12:41, 12 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
*** Ack. I've been doing that on a ton of pages -- my mistake, I will try to use the correct capitalisation. --[[User:Caveman|Caveman]] 12:43, 12 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {ns_sha1 [ns_md5 [lindex $args 0]] [lindex $args 1]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;8&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use? What about multiple authentication realms?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   ns_set put $nssData &amp;quot;id&amp;quot; [nso_sequence next $sName]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4629</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4629"/>
		<updated>2005-12-13T14:53:11Z</updated>

		<summary type="html">&lt;p&gt;Caveman: towards a data and authentication layer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, and welcome to the wiki!  If you don't mind me asking, what's your full name (or do you want to remain anonymous)?  Are you also subscribed to the [http://aolserver.com/lists.php AOLSERVER mailing list]?  Some of us also hang out on [http://aolserver.com/chat/ IRC and chat] (you can also access the chat via AIM, but most folks use IRC).&lt;br /&gt;
&lt;br /&gt;
If you have any questions or concerns, don't hesitate to contact me.  Thanks! ''-- [[User:Dossy|Dossy]] 07:13, 3 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Why does it seem like you're avoiding Tcl?  Your recent wiki edits have been focused around other languages in AOLserver other than Tcl, like Lua, PHP and Ruby.  Why?  You will really never get the kind of performance out of Perl, PHP or Ruby as you will Tcl, because Tcl is suitable for embedding in a multi-threaded application where Perl, PHP and Ruby aren't.  (I don't know enough about Lua to say one way or the other.)  So, if you still want to use those other languages, then you probably don't care about performance at the high end, in which case, you probably don't need to use AOLserver, either.  In the small, any web server will be more than adequate on modern hardware to serve a few hundred pages here and there.  It's when you start getting into the few hundred per second arena where AOLserver has the opportunity to shine. ''-- [[User:Dossy|Dossy]] 07:46, 10 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
* Not at all -- I'm looking at other languages simply from the point of view of seeing how AOLServer modules are built at all. It has been a while since I did any heavy lifting with C, and I felt that tinkering with the module code would be a good refresher. Just scratching an itch. I use TCL heavily every day at work, and have no real knowledge of Lua either, it just seemed an opportune target to use when examining the general AOLServer module layer. --[[Caveman]] 12:23, 12 December 2005 (EST) &lt;br /&gt;
&lt;br /&gt;
** Okay, cool.  FYI, &amp;quot;AOLserver&amp;quot; is capitalized just like that, not &amp;quot;AOLServer&amp;quot; -- I'm picking nits, but the consistency is important to me.  Thanks.  :-) ''-- [[User:Dossy|Dossy]] 12:41, 12 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
*** Ack. I've been doing that on a ton of pages -- my mistake, I will try to use the correct capitalisation. --[[User:Caveman|Caveman]] 12:43, 12 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
== towards a data and authentication layer ==&lt;br /&gt;
&lt;br /&gt;
It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:&lt;br /&gt;
# authentication (password check)&lt;br /&gt;
# sequences&lt;br /&gt;
# data layer&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Authentication/Authorization config (nsz):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;/security/password/expression&amp;quot;&lt;br /&gt;
# {ns_sha1 [ns_md5 [lindex $args 0]] [lindex $args 1]}&lt;br /&gt;
# config: &amp;quot;/security/password/query&amp;quot;&lt;br /&gt;
# {select password, salt from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
# config: &amp;quot;/security/salt/length&amp;quot; &amp;quot;8&amp;quot;&lt;br /&gt;
# config: &amp;quot;/security/salt/dictionary&amp;quot; &amp;quot;0123456789abcdefghijkl...&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Basically the &amp;quot;expression&amp;quot; is used in a function, '''nsz_password''' to format a given clear-text password (varargs &amp;quot;args&amp;quot; to allow additional arguments to the function). The first argument is always the password.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;query&amp;quot; is executed as part of password-based authentication. The form handler reaches '''nsz_auth &amp;quot;myname&amp;quot; &amp;quot;mypassword&amp;quot;''' and the query is executed using the input list &amp;quot;myname&amp;quot;. All row data beyond the first column, which must always be the password, is appended to the input password &amp;quot;mypassword&amp;quot; to produce the hash/salted/hash input &amp;quot;xpassword&amp;quot;. This input &amp;quot;xpassword&amp;quot; is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;correctpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;correctpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;&lt;br /&gt;
# Return value matches query&lt;br /&gt;
# nsz_auth returns &amp;quot;sam&amp;quot;&lt;br /&gt;
&lt;br /&gt;
nsz_auth &amp;quot;sam&amp;quot; &amp;quot;badpassword&amp;quot;&lt;br /&gt;
# Query returns &amp;quot;sadf8vcx8vxasd7f7...&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot;&lt;br /&gt;
# Expression eval for input passes &amp;quot;badpassword&amp;quot;,&amp;quot;asduf7z6dfa...&amp;quot; and returns &amp;quot;yyzkfosd232cx7c...&amp;quot;&lt;br /&gt;
# Return value does not match query&lt;br /&gt;
# nsz_auth raises error &amp;quot;bad password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nsz/security/password/expression&amp;quot;&lt;br /&gt;
# {lindex $args 0}&lt;br /&gt;
# config: &amp;quot;nsz/security/password/query&amp;quot;&lt;br /&gt;
# {select password from users where name='[ns_dbquoteval [lindex $args 0]]'}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.&lt;br /&gt;
&lt;br /&gt;
Function '''nsz_salt''' can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.&lt;br /&gt;
&lt;br /&gt;
'''Question:''' How to make &amp;quot;users&amp;quot; table configurable? What about configuring which database pool to use?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the &amp;quot;name&amp;quot; and &amp;quot;value&amp;quot; of the sequence.&lt;br /&gt;
&lt;br /&gt;
Config:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/poolname&amp;quot; (default by default)&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/size&amp;quot; &amp;quot;100&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/retry&amp;quot; &amp;quot;5&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/table&amp;quot; &amp;quot;sequences_table&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/name&amp;quot; &amp;quot;name_field&amp;quot;&lt;br /&gt;
# config: &amp;quot;nso/sequence/default/value&amp;quot; &amp;quot;value_field&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sequence defaults could be over-written per-sequence in similar fashion.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set nextId [nso_sequence next &amp;quot;my_seq_name&amp;quot;]&lt;br /&gt;
# returns 53 or error if fail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function '''nso_sequence''' would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# select value_field from sequences_table where name_field='my_seq_name'&lt;br /&gt;
# result is 125, attempt to claim 100 values&lt;br /&gt;
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would be retried up to ''5'' times.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Data layer notes:&lt;br /&gt;
&lt;br /&gt;
Config would map names like &amp;quot;users&amp;quot; to database pools and table names. Default would be default database pool and identity table name.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# set nssValues [ns_set create]&lt;br /&gt;
# ns_set update $nssValues &amp;quot;name&amp;quot; &amp;quot;sam&amp;quot;&lt;br /&gt;
# ns_set update $nssValues &amp;quot;password&amp;quot; &amp;quot;mypassword&amp;quot;&lt;br /&gt;
# ns_set put $nssValues &amp;quot;mail&amp;quot; &amp;quot;sam@caveman.org&amp;quot;&lt;br /&gt;
# set nssUserKey [nso_row create &amp;quot;users&amp;quot; $nssValues]&lt;br /&gt;
# set nssNewValues [ns_set create]&lt;br /&gt;
# ns_set put $nssNewValues &amp;quot;mail&amp;quot; &amp;quot;samuelmb@gmail.com&amp;quot;&lt;br /&gt;
# nso_row update &amp;quot;users&amp;quot; $nssUserKey $nssNewValues&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using ns_set instead of a model type-checking &amp;quot;nso_set&amp;quot; at least for now for simplicity and it would be the simple case.&lt;br /&gt;
&lt;br /&gt;
Additional config allows for data transforms:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# multi stage of filters and expressions:&lt;br /&gt;
#&lt;br /&gt;
# stage 0: accept-data-filter&lt;br /&gt;
#   e.g. &amp;quot;require a password is not null&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require this integer be above zero&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;require id not be set&amp;quot;&lt;br /&gt;
#   e.g. &amp;quot;generate a salt&amp;quot;&lt;br /&gt;
#&lt;br /&gt;
# stage 1: transform-data-filter&lt;br /&gt;
# config: expressions to apply to row:&lt;br /&gt;
#   ns_set update $nssData &amp;quot;salt&amp;quot; [nsz_salt]&lt;br /&gt;
#   ns_set update $nssData &amp;quot;password&amp;quot; [nsz_password [ns_set get $nssData &amp;quot;password&amp;quot;] [ns_set get $nssData &amp;quot;salt&amp;quot;]]&lt;br /&gt;
#   ns_set put $nssData &amp;quot;id&amp;quot; [nso_sequence next $sName]&lt;br /&gt;
#&lt;br /&gt;
# stage 2: veto-data-filter?&lt;br /&gt;
#&lt;br /&gt;
# allow multiple &amp;quot;inheritance&amp;quot; of data rules? or just defining rules that&lt;br /&gt;
# can be referenced by multiple tables?&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''very draft state''&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_dbquotevalue&amp;diff=4626</id>
		<title>Ns dbquotevalue</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_dbquotevalue&amp;diff=4626"/>
		<updated>2005-12-13T14:14:50Z</updated>

		<summary type="html">&lt;p&gt;Caveman: fixed double bracket (double single quote not fixed)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Man page: http://aolserver.com/docs/tcl/ns_dbquotevalue.html&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''NAME'''&lt;br /&gt;
&lt;br /&gt;
: ns_dbquotevalue - Prepare a value string for inclusion in an SQL statement.&lt;br /&gt;
&lt;br /&gt;
'''SYNOPSIS'''&lt;br /&gt;
&lt;br /&gt;
: '''ns_dbquotevalue''' ''value ?type?''&lt;br /&gt;
&lt;br /&gt;
'''DESCRIPTION'''&lt;br /&gt;
&lt;br /&gt;
: This command prepares the string ''value'' for inclusion in an SQL statement.  If ''value'' is &amp;quot;&amp;quot;, ns_dbquotevalue will return the string &amp;quot;NULL&amp;quot;.  If ''value'' is not &amp;quot;&amp;quot;, the returned value depends on ''type''.  If ''type'' is one of: bigint, bit, decimal, double, float, int, integer, numeric, real, smallint, or tinyint, then ''value'' will be returned without modification.  When ''type'' is any other string, or if ''type'' is omitted, ''value'' will be surrounded by single quotes, and any single quotes that it contains will be escaped by translation into two single quotes.&lt;br /&gt;
&lt;br /&gt;
'''EXAMPLES'''&lt;br /&gt;
&lt;br /&gt;
    % ns_dbquotevalue &amp;quot;&amp;quot;&lt;br /&gt;
    NULL&lt;br /&gt;
&lt;br /&gt;
    % ns_dbquotevalue 45.3 float&lt;br /&gt;
    45.3&lt;br /&gt;
&lt;br /&gt;
    % ns_dbquotevalue &amp;quot;John's Car&amp;quot;&lt;br /&gt;
    'John''s Car'&lt;br /&gt;
&lt;br /&gt;
    % set company &amp;quot;John's Cheese Factory&amp;quot;&lt;br /&gt;
    % ns_db dml $db &amp;quot;INSERT INTO companies (name) VALUES ([ns_dbquotevalue $company])&amp;quot;&lt;br /&gt;
&lt;br /&gt;
'''SEE ALSO'''&lt;br /&gt;
&lt;br /&gt;
: [[ns_dbquotename]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category Documentation]] - [[Category Core Tcl API]]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ns_dbquotevalue&amp;diff=4625</id>
		<title>Talk:Ns dbquotevalue</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ns_dbquotevalue&amp;diff=4625"/>
		<updated>2005-12-13T14:14:24Z</updated>

		<summary type="html">&lt;p&gt;Caveman: double single quotes in examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== double single quotes in examples ==&lt;br /&gt;
&lt;br /&gt;
there are errors in the examples: the double single quote is being hijacked by the wiki and turning the text into italic instead of showing the double single quote.&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_set&amp;diff=4621</id>
		<title>Ns set</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Ns_set&amp;diff=4621"/>
		<updated>2005-12-13T04:04:11Z</updated>

		<summary type="html">&lt;p&gt;Caveman: cleaned up double-brackets in code samples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Man page: http://aolserver.com/docs/tcl/ns_set.html&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
'''NAME'''&lt;br /&gt;
&lt;br /&gt;
: ns_set - Manipulate sets of key-value pairs&lt;br /&gt;
&lt;br /&gt;
'''SYNOPSIS'''&lt;br /&gt;
&lt;br /&gt;
: '''ns_set''' ''option ?arg arg ...?''&lt;br /&gt;
&lt;br /&gt;
'''DESCRIPTION'''&lt;br /&gt;
&lt;br /&gt;
: This command is used to manipulate sets of key-value pairs or &amp;quot;fields&amp;quot;.  The fields in the set are ordered by number.  The field numbers start at zero and increase by one, up to the total number of fields.  An '''ns_set''' is actually a multiset - in other words, the same key can appear multiple times in the same set.  This data structure is particularly useful for things like HTTP headers which have this same property.&lt;br /&gt;
&lt;br /&gt;
: The legal ''option''s (which may be abbreviated) are:&lt;br /&gt;
* '''ns_set array''' ''setId''&lt;br /&gt;
&lt;br /&gt;
: Returns the contents of the ''setId'' in a string representation similar to Tcl's '''array get''' format.  This is useful for converting an '''ns_set''' to an '''array''' or for iterating over the key-value pairs with '''foreach'''.  Since '''ns_set'''s can contain the same key multiple times, converting an '''ns_set''' to an '''array''' can result in an array that is not exactly the same as the original '''ns_set''' as keys in an array are unique.&lt;br /&gt;
* '''ns_set cleanup'''&lt;br /&gt;
&lt;br /&gt;
: Frees all sets in the current interp.&lt;br /&gt;
* '''ns_set copy''' ''?-persist? setId''&lt;br /&gt;
&lt;br /&gt;
: Returns a new set that has the same name and contents as the set referenced in ''setId''.  If ''-persist'' is specified, the new set will not be freed when the current transaction ends, and you can free it later with '''ns_set free'''.  If ''-persist'' is not specified, the new set is automatically freed when the transaction ends.&lt;br /&gt;
* '''ns_set cput''' ''setId key value''&lt;br /&gt;
&lt;br /&gt;
: Appends a new field to the set with ''key'' and ''value'', if the field does not already exist in the set.  If the field already exists in the set, the set is unchanged.  Returns the field number of the new field, or the field number of the existing field if it already exists in the set.&lt;br /&gt;
* '''ns_set create''' ''?-persist? ?name? ?key? ?value? ...''&lt;br /&gt;
* '''ns_set new''' ''?-persist? ?name? ?key? ?value? ...''&lt;br /&gt;
&lt;br /&gt;
: Allocates memory for a new set and returns the setId for the new set.  If ''-persist'' is specified, the new set will not be freed when the current transaction ends, and you can free it later with '''ns_set free'''.  If ''-persist'' is not specified, the new set is automatically freed when the transaction ends.&lt;br /&gt;
* '''ns_set delete''' ''setId fieldNumber''&lt;br /&gt;
&lt;br /&gt;
: Deletes the field in the set at field number ''fieldNumber''.&lt;br /&gt;
* '''ns_set delkey''' ''setId key''&lt;br /&gt;
&lt;br /&gt;
: Removes the first field in the set whose key is ''key''.  Note that there could be multiple fields in the set with this key; this command only removes the first occurrence.&lt;br /&gt;
* '''ns_set find''' ''setId key''&lt;br /&gt;
&lt;br /&gt;
: Returns the index of the first field in the specified ''setId'' whose ''key'' matches the specified key.  Indexing starts at zero.  If no matching fields are found, '''ns_set find''' returns -1.&lt;br /&gt;
* '''ns_set free''' ''setId''&lt;br /&gt;
&lt;br /&gt;
: Frees the specified set.  Sets must be explicitly freed with '''ns_set free''' if the ''-persist'' option was used when creating the set.  Otherwise, sets are automatically freed when the transaction ends.&lt;br /&gt;
* '''ns_set get''' ''setId key''&lt;br /&gt;
&lt;br /&gt;
: Returns the first value associated with ''key''.  If ''key'' isn't in the set, an empty string is returned.&lt;br /&gt;
* '''ns_set icput''' ''setId key value''&lt;br /&gt;
&lt;br /&gt;
: Case-insensitive counterpart of '''ns_set cput'''.&lt;br /&gt;
* '''ns_set idelkey''' ''setId key''&lt;br /&gt;
&lt;br /&gt;
: Case-insensitive counterpart of '''ns_set delkey'''.&lt;br /&gt;
* '''ns_set ifind''' ''setId key''&lt;br /&gt;
&lt;br /&gt;
: Case-insensitive counterpart of '''ns_set find'''.&lt;br /&gt;
* '''ns_set iget''' ''setId key''&lt;br /&gt;
&lt;br /&gt;
: Case-insensitive counterpart of '''ns_set get'''.&lt;br /&gt;
* '''ns_set isnull''' ''setId fieldNumber''&lt;br /&gt;
&lt;br /&gt;
: Returns 1 if the value of the field specified by ''fieldNumber'' is null and 0 if it is not.  Note that an empty string is not the same as a null.  '''ns_set isnull''' will return 0 if the value is an empty string.&lt;br /&gt;
* '''ns_set iunique''' ''setId key''&lt;br /&gt;
&lt;br /&gt;
: Case-insensitive counterpart of '''ns_set unique'''.&lt;br /&gt;
* '''ns_set key''' ''setId fieldNumber''&lt;br /&gt;
&lt;br /&gt;
: Returns the key for the field numbered ''fieldNumber''.  This command is useful when looping through all the key-value pairs in the set in order.&lt;br /&gt;
* '''ns_set list''' ''?-shared?''&lt;br /&gt;
&lt;br /&gt;
: Returns the list of all non-persistent '''ns_set'''s.  If ''-shared'' is specified, this command returns only the list of persistent '''ns_set'''s.&lt;br /&gt;
* '''ns_set merge''' ''high low''&lt;br /&gt;
&lt;br /&gt;
: Merges two sets.  Any fields in the ''low'' set are appended to the ''high'' set if a field with the same key name does not already exist in the ''high'' set.&lt;br /&gt;
* '''ns_set move''' ''to from''&lt;br /&gt;
&lt;br /&gt;
: Moves all fields from the ''from'' set to the end of the ''to'' set, leaving the ''from'' set a valid, empty set.&lt;br /&gt;
* '''ns_set name''' ''setId''&lt;br /&gt;
&lt;br /&gt;
: Returns the name of the set.  Returns an empty string if no name has been set.&lt;br /&gt;
* '''ns_set print''' ''setId''&lt;br /&gt;
&lt;br /&gt;
: Prints the specified set to stderr which should go to the server log.  This is useful for debugging, but '''ns_set array''' may be more useful in actual code.&lt;br /&gt;
* '''ns_set put''' ''setId key value''&lt;br /&gt;
&lt;br /&gt;
: Appends a new field to the set with ''key'' and ''value''.  Note that the field is appended so if a previous field has the same key as the new field, the previous field will be returned by '''ns_set get'''.  The field number of the new field is returned.&lt;br /&gt;
* '''ns_set size''' ''setId''&lt;br /&gt;
&lt;br /&gt;
: Returns the number of fields in the set.&lt;br /&gt;
* '''ns_set split''' ''?-persist? setId ?splitChar?''&lt;br /&gt;
&lt;br /&gt;
: Splits one set into multiple sets based on the ''splitChar'' as described below and returns a Tcl list of IDs for the newly-allocated sets.  It assumes that the keys in the source ''setId'' contain a specific character (''splitChar'') that can be used to separate the name of a new set and the key in the new set.  The default ''splitChar'' is a period &amp;quot;.&amp;quot;.&lt;br /&gt;
* '''ns_set truncate''' ''setId fieldNumber''&lt;br /&gt;
&lt;br /&gt;
: Removes any fields with index ''fieldNumber'' or greater and frees any memory allocated for them.&lt;br /&gt;
* '''ns_set unique''' ''setId key''&lt;br /&gt;
&lt;br /&gt;
: Returns 1 if the specified key is unique in the specified set and 0 if it is not.  For example, a web browser could send multiple &amp;quot;Accept:&amp;quot; headers which would end up in the header set for the connection.  '''ns_set unique''' would return 0 for the &amp;quot;Accept:&amp;quot; key, because there are multiple fields with the key &amp;quot;Accept:&amp;quot;.  The test for uniqueness is performed case-sensitively.&lt;br /&gt;
* '''ns_set update''' ''setId key value''&lt;br /&gt;
&lt;br /&gt;
: Updates the first field in the specified set whose key is ''key'' and replaces its value with ''value''.  This is equivalent to '''ns_set delkey''' followed by '''ns_set put''' if there is only one field with the key of ''key''.&lt;br /&gt;
* '''ns_set value''' ''setId fieldNumber''&lt;br /&gt;
&lt;br /&gt;
: Returns the value of the set at field number ''fieldNumber''.  This command is useful when looping through all the key-value pairs in the set.&lt;br /&gt;
&lt;br /&gt;
'''EXAMPLES'''&lt;br /&gt;
&lt;br /&gt;
    % set mySet [ns_set create mySetName a b c d e f A Joe B John C Jeff]&lt;br /&gt;
    d0&lt;br /&gt;
&lt;br /&gt;
    % ns_set size $mySet&lt;br /&gt;
    6&lt;br /&gt;
&lt;br /&gt;
    % ns_set name $mySet&lt;br /&gt;
    mySetName&lt;br /&gt;
&lt;br /&gt;
    % ns_set array $mySet&lt;br /&gt;
    a b c d e f A Joe B John C Jeff&lt;br /&gt;
&lt;br /&gt;
    % ns_set get $mySet A&lt;br /&gt;
    Joe&lt;br /&gt;
&lt;br /&gt;
    % ns_set iget $mySet a&lt;br /&gt;
    b&lt;br /&gt;
&lt;br /&gt;
    % ns_set unique $mySet a&lt;br /&gt;
    1&lt;br /&gt;
&lt;br /&gt;
    % ns_set iunique $mySet a&lt;br /&gt;
    0&lt;br /&gt;
&lt;br /&gt;
    % ns_set truncate $mySet 3&lt;br /&gt;
   &lt;br /&gt;
    % ns_set print $mySet&lt;br /&gt;
    mySetName:&lt;br /&gt;
            a = b&lt;br /&gt;
            c = d&lt;br /&gt;
            e = f&lt;br /&gt;
&lt;br /&gt;
    % ns_set update $mySet c &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
    2&lt;br /&gt;
&lt;br /&gt;
    % ns_set print $mySet&lt;br /&gt;
    mySetName:&lt;br /&gt;
            a = b&lt;br /&gt;
            e = f&lt;br /&gt;
            c = Hello World!&lt;br /&gt;
&lt;br /&gt;
    % ns_set find $mySet c&lt;br /&gt;
    2&lt;br /&gt;
&lt;br /&gt;
    % ns_set find $mySet nokey&lt;br /&gt;
    -1&lt;br /&gt;
&lt;br /&gt;
    % ns_set delete $mySet 0&lt;br /&gt;
&lt;br /&gt;
    % ns_set array $mySet&lt;br /&gt;
    e f c {Hello World!}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    % set anotherSet [ns_set create]&lt;br /&gt;
    d1&lt;br /&gt;
&lt;br /&gt;
    % ns_set list&lt;br /&gt;
    d0 d1&lt;br /&gt;
&lt;br /&gt;
    % ns_set put $anotherSet dog.food &amp;quot;Yummy dog food!&amp;quot;&lt;br /&gt;
    0&lt;br /&gt;
&lt;br /&gt;
    % ns_set put $anotherSet cat.food &amp;quot;Yummy cat food!&amp;quot;&lt;br /&gt;
    1&lt;br /&gt;
&lt;br /&gt;
    % ns_set print $anotherSet&lt;br /&gt;
    &amp;lt;Unamed set&amp;gt;:&lt;br /&gt;
            dog.food = Yummy dog food!&lt;br /&gt;
            cat.food = Yummy cat food!&lt;br /&gt;
&lt;br /&gt;
    % set newSets [ns_set split $anotherSet]&lt;br /&gt;
    d2 d3&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    % foreach s $newSets { ns_set print $s }&lt;br /&gt;
    dog:&lt;br /&gt;
            food = Yummy dog food!&lt;br /&gt;
    cat:&lt;br /&gt;
            food = Yummy cat food!&lt;br /&gt;
&lt;br /&gt;
    % ns_set key $anotherSet 0&lt;br /&gt;
    dog.food&lt;br /&gt;
&lt;br /&gt;
    % ns_set value $anotherSet 1&lt;br /&gt;
    Yummy cat food!&lt;br /&gt;
&lt;br /&gt;
    % ns_set move $mySet $anotherSet&lt;br /&gt;
    d0&lt;br /&gt;
&lt;br /&gt;
    % ns_set array $mySet&lt;br /&gt;
    e f c {Hello World!} dog.food {Yummy dog food!} cat.food {Yummy cat food!}&lt;br /&gt;
&lt;br /&gt;
    % ns_set array $anotherSet&lt;br /&gt;
&lt;br /&gt;
    % set thirdSet [ns_set new]&lt;br /&gt;
    d4&lt;br /&gt;
&lt;br /&gt;
    % ns_set move $thirdSet $mySet&lt;br /&gt;
    d4&lt;br /&gt;
&lt;br /&gt;
    % ns_set array $thirdSet&lt;br /&gt;
    e f c {Hello World!} dog.food {Yummy dog food!} cat.food {Yummy cat food!}&lt;br /&gt;
&lt;br /&gt;
    % array set testArray [ns_set array $thirdSet]&lt;br /&gt;
&lt;br /&gt;
'''NOTES'''&lt;br /&gt;
&lt;br /&gt;
: The ns_set command currently reports that it accepts two additional subcommands, idelete and purge.  These are both noops (idelete may be a mistake as delete is already case-irrelevant).&lt;br /&gt;
&lt;br /&gt;
: NULL values, distinct from the empty string, are useful when representing a database row as an ns_set.  Currently, it is difficult to get a NULL value in an ns_set through the TCL API.  You may get a NULL value in the set created by [[ns_parsequery]] or by omitting the last value when seeding the ns_set in the create/new subcommand, etc.  It is possible to create NULL-valued fields through the C API.&lt;br /&gt;
&lt;br /&gt;
: ns_set is intended for relatively ''small'' amounts of data.  (Keys are found by a ''linear'' search through the whole underlying C array.)  If you stuff very large amounts of data into an ns_set, performance will be very poor - use a Tcl Array instead for that.&lt;br /&gt;
&lt;br /&gt;
'''SEE ALSO'''&lt;br /&gt;
&lt;br /&gt;
: [[ns_findset]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[Category Documentation]] - [[Category Core Tcl API]]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_4_on_Debian&amp;diff=4611</id>
		<title>AOLserver 4 on Debian</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=AOLserver_4_on_Debian&amp;diff=4611"/>
		<updated>2005-12-12T17:54:55Z</updated>

		<summary type="html">&lt;p&gt;Caveman: corrected capitalisation use of AOLserver&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Some quick and easy steps to getting AOLserver 4 up and running on Debian 3.1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# install aolserver4&lt;br /&gt;
apt-get install aolserver4&lt;br /&gt;
&lt;br /&gt;
# optional: to get ns.h and makefiles to build your own custom C or C++ modules&lt;br /&gt;
apt-get install aolserver4-dev&lt;br /&gt;
&lt;br /&gt;
# optional: to get some potentially useful documentation, should you choose to read it&lt;br /&gt;
apt-get install aolserver4-doc&lt;br /&gt;
&lt;br /&gt;
# optional: module: Tcl API for AOLserver Caches&lt;br /&gt;
apt-get install aolserver4-nscache&lt;br /&gt;
&lt;br /&gt;
# optional: module that implements IMAP4 interface&lt;br /&gt;
apt-get install aolserver4-nsimap&lt;br /&gt;
&lt;br /&gt;
# optional: module for LDAP&lt;br /&gt;
apt-get install aolserver4-nsldap&lt;br /&gt;
&lt;br /&gt;
# optional: module: module for SSL mode -- beta module for OpenSSL&lt;br /&gt;
apt-get install aolserver4-nsopenssl&lt;br /&gt;
&lt;br /&gt;
# optional: module: Postgres connector &lt;br /&gt;
apt-get install aolserver4-nspostgres&lt;br /&gt;
&lt;br /&gt;
# optional: module: performs SHA1 hashes -- warning, the SHA1 hash it provides is not to spec&lt;br /&gt;
apt-get install aolserver4-nssha1&lt;br /&gt;
&lt;br /&gt;
# optional: Module for XML support&lt;br /&gt;
apt-get install aolserver4-nsxml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installing the package(s) you want:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/etc/init.d/aolserver4 start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And you are running AOLserver. Congratulations. To make changes to your configuration file, visit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/etc/aolserver4/aolserver4.tcl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To view your server log, visit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/var/log/aolserver4/aolserver4.log&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[PostgreSQL on Debian]]&lt;br /&gt;
* [[Configuring AOLserver 4 and PostgreSQL on Debian]]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=PostgreSQL_on_Debian&amp;diff=4610</id>
		<title>PostgreSQL on Debian</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=PostgreSQL_on_Debian&amp;diff=4610"/>
		<updated>2005-12-12T17:46:11Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;While not always a part of an AOLserver installation, the fact that AOLserver is known almost foremost for its ability to support massively concurrent accesses to its database pools imply that it would be helpful to have such a database installed.&lt;br /&gt;
&lt;br /&gt;
Some quick and easy steps to getting Postgresql up and running on Debian 3.1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# install postgresql&lt;br /&gt;
apt-get install postgresql&lt;br /&gt;
&lt;br /&gt;
# optional: to get some potentially useful documentation, should you choose to read it&lt;br /&gt;
apt-get install postgresql-doc&lt;br /&gt;
&lt;br /&gt;
# optional: if you think you might be up for some postgresql hacking sometime&lt;br /&gt;
apt-get install postgresql-dev&lt;br /&gt;
&lt;br /&gt;
# optional: useful contributed software includes some cryptographic hash functions&lt;br /&gt;
apt-get install postgresql-contrib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installing the package(s) you want:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/etc/init.d/postgresql start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And you are running Postgresql. Congratulations. To make changes to your configuration files, visit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/etc/postgresql/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Recommended'''&lt;br /&gt;
&lt;br /&gt;
While everyone has their own preferences for how to administer and customize their database installation, there are at least a couple of post-install steps that come in very handy:&lt;br /&gt;
&lt;br /&gt;
* [http://www.debian-administration.org/articles/208] details importing the useful pgcrypto functions from postgresql-contrib into your template database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root @ box # su postgres&lt;br /&gt;
postgres @ box $ psql template1 &amp;lt; /usr/share/postgresql/contrib/pgcrypto.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://dev.panopticsearch.com/postgres_microhowto.html] details setting a database password for the postgres user, and setting up socket connection permissions (which allows, among other things, AOLserver to connect to the database):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    postgres @ box $ psql template1&lt;br /&gt;
    Welcome to psql, the PostgreSQL interactive terminal.&lt;br /&gt;
&lt;br /&gt;
    Type:  \copyright for distribution terms&lt;br /&gt;
           \h for help with SQL commands&lt;br /&gt;
           \? for help on internal slash commands&lt;br /&gt;
           \g or terminate with semicolon to execute query&lt;br /&gt;
           \q to quit&lt;br /&gt;
&lt;br /&gt;
    template1=#&lt;br /&gt;
&lt;br /&gt;
# Set a password for the database-user postgres (while being logged into the database (e.g. template1)).&lt;br /&gt;
&lt;br /&gt;
    template1=# ALTER USER postgres WITH PASSWORD 'topsecret';&lt;br /&gt;
    ALTER USER&lt;br /&gt;
    template1=#&lt;br /&gt;
&lt;br /&gt;
# Log out of the database (\q):&lt;br /&gt;
&lt;br /&gt;
    template1=# \q&lt;br /&gt;
    postgres @ box $&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[AOLserver 4 on Debian]]&lt;br /&gt;
* [[Configuring AOLserver 4 and PostgreSQL on Debian]]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=PostgreSQL_on_Debian&amp;diff=4609</id>
		<title>PostgreSQL on Debian</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=PostgreSQL_on_Debian&amp;diff=4609"/>
		<updated>2005-12-12T17:45:51Z</updated>

		<summary type="html">&lt;p&gt;Caveman: corrected capitalisation use of AOLserver&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;While not always a part of an AOLserver installation, the fact that AOLserver is known almost foremost for its ability to support massively concurrent accesses to its database pools imply that it would be helpful to have such a database installed.&lt;br /&gt;
&lt;br /&gt;
Some quick and easy steps to getting Postgresql up and running on Debian 3.1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# install postgresql&lt;br /&gt;
apt-get install postgresql&lt;br /&gt;
&lt;br /&gt;
# optional: to get some potentially useful documentation, should you choose to read it&lt;br /&gt;
apt-get install postgresql-doc&lt;br /&gt;
&lt;br /&gt;
# optional: if you think you might be up for some postgresql hacking sometime&lt;br /&gt;
apt-get install postgresql-dev&lt;br /&gt;
&lt;br /&gt;
# optional: useful contributed software includes some cryptographic hash functions&lt;br /&gt;
apt-get install postgresql-contrib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installing the package(s) you want:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/etc/init.d/postgresql start&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And you are running Postgresql. Congratulations. To make changes to your configuration files, visit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/etc/postgresql/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Recommended'''&lt;br /&gt;
&lt;br /&gt;
While everyone has their own preferences for how to administer and customize their database installation, there are at least a couple of post-install steps that come in very handy:&lt;br /&gt;
&lt;br /&gt;
* [http://www.debian-administration.org/articles/208] details importing the useful pgcrypto functions from postgresql-contrib into your template database:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root @ box # su postgres&lt;br /&gt;
postgres @ box $ psql template1 &amp;lt; /usr/share/postgresql/contrib/pgcrypto.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [http://dev.panopticsearch.com/postgres_microhowto.html] details setting a database password for the postgres user, and setting up socket connection permissions (which allows, among other things, AOLServer to connect to the database):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    postgres @ box $ psql template1&lt;br /&gt;
    Welcome to psql, the PostgreSQL interactive terminal.&lt;br /&gt;
&lt;br /&gt;
    Type:  \copyright for distribution terms&lt;br /&gt;
           \h for help with SQL commands&lt;br /&gt;
           \? for help on internal slash commands&lt;br /&gt;
           \g or terminate with semicolon to execute query&lt;br /&gt;
           \q to quit&lt;br /&gt;
&lt;br /&gt;
    template1=#&lt;br /&gt;
&lt;br /&gt;
# Set a password for the database-user postgres (while being logged into the database (e.g. template1)).&lt;br /&gt;
&lt;br /&gt;
    template1=# ALTER USER postgres WITH PASSWORD 'topsecret';&lt;br /&gt;
    ALTER USER&lt;br /&gt;
    template1=#&lt;br /&gt;
&lt;br /&gt;
# Log out of the database (\q):&lt;br /&gt;
&lt;br /&gt;
    template1=# \q&lt;br /&gt;
    postgres @ box $&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[AOLserver 4 on Debian]]&lt;br /&gt;
* [[Configuring AOLserver 4 and PostgreSQL on Debian]]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4608</id>
		<title>Talk:How to set up PHP under AOLserver</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4608"/>
		<updated>2005-12-12T17:44:31Z</updated>

		<summary type="html">&lt;p&gt;Caveman: corrected capitalisation use of AOLserver&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I cannot get php-5.1.1 to build with Debian 3.1 package of aolserver4 and aolserver4-dev (which is built with --prefix=/usr/lib/aolserver4):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ./configure --with-aolserver=/usr/lib/aolserver4&lt;br /&gt;
loading cache ./config.cache&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Configuring SAPI modules&lt;br /&gt;
checking for AOLserver support... /usr/lib/aolserver4&lt;br /&gt;
configure: error: Please specify the path to the source distribution of AOLserver using --with-aolserver-src=DIR&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''I only ever tested this against PHP 4.3.7 -- I don't know what is required to make it work with PHP 5.1.1.  If you figure it out, please update the page.  -- [[User:Dossy|Dossy]] 12:05, 7 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
** I opened a PHP bug issue for this: [http://bugs.php.net/bug.php?id=35605] --[[User:Caveman|Caveman]] 14:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
*** This may be an issue more with the way Debian 3.1 installs AOLserver 4 than anything else. The &amp;quot;proper&amp;quot; PHP configure command should be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/path/to/installed/aolserver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Debian 3.1 configures AOLServer with a prefix of &amp;quot;/usr/lib/aolserver4&amp;quot;. However, using this as the &amp;quot;/path/to/installed/aolserver&amp;quot; results in the same error and a request for &amp;quot;--with-aolserver-src&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
**** I configured and installed aolserver4 from source into &amp;quot;/home/sam/aolserver&amp;quot;. PHP configure finally completed successfully. However, PHP compile still failed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/bin/sh /home/sam/downloads/php.net/php-5.1.1/libtool --silent --preserve-dup-deps --mode=compile /home/sam/downloads/php.net/php-5.1.1/meta_ccld  -Isapi/aolserver/ -I/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/ -DPHP_ATOM_INC -I/home/sam/downloads/php.net/php-5.1.1/include -I/home/sam/downloads/php.net/php-5.1.1/main -I/home/sam/downloads/php.net/php-5.1.1 -I/home/sam/aolserver/include -I/usr/include/libxml2 -I/home/sam/downloads/php.net/php-5.1.1/ext/date/lib -I/home/sam/downloads/php.net/php-5.1.1/TSRM -I/home/sam/downloads/php.net/php-5.1.1/Zend  -D_REENTRANT  -g -O2 -pthread -DZTS  -prefer-non-pic -c /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c -o sapi/aolserver/aolserver.lo&lt;br /&gt;
In file included from /home/sam/aolserver/include/ns.h:62,&lt;br /&gt;
                 from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:125:17: tcl.h: No such file or directory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was obviously an error finding &amp;quot;tcl.h&amp;quot;. I manually edited the PHP &amp;quot;Makefile&amp;quot; and set:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXTRA_INCLUDES = -I/usr/include/tcl8.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allowed PHP compilation to complete. The module loaded successfully and PHP scripts work as expected (see [http://caveman.org/phpinfo/ phpinfo output]). --[[User:Caveman|Caveman]] 19:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
With trial and error, I was able to configure and compile against the Debian 3.1 packages as installed by default:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/usr&lt;br /&gt;
make &amp;quot;EXTRA_INCLUDES=-I/usr/include/tcl8.4 -I/usr/include/aolserver4&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== extending PHP to take advantage of AOLServer ==&lt;br /&gt;
&lt;br /&gt;
http://aolserver.org/docs/devel/c/api/c-ch3.htm#37064&lt;br /&gt;
&lt;br /&gt;
proposal: write a PHP extension to provide PHP functions to access AOLserver database pools (and perhaps other important features like shared memory).&lt;br /&gt;
&lt;br /&gt;
In other words, provide PHP functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_db_gethandle&lt;br /&gt;
ns_db_select&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so on. It should be nearly trivial to do this, and give PHP on AOLserver a very powerful advantage over PHP on Apache.&lt;br /&gt;
&lt;br /&gt;
[http://www.webtechniques.com/archives/2001/01/junk/ Extending PHP By Sterling Hughes]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1/ext$ ./ext_skel --extname=nsdb&lt;br /&gt;
Creating directory nsdb&lt;br /&gt;
Creating basic files: config.m4 config.w32 .cvsignore nsdb.c php_nsdb.h CREDITS EXPERIMENTAL tests/001.phpt nsdb.php [done].&lt;br /&gt;
&lt;br /&gt;
To use your new extension, you will have to execute the following steps:&lt;br /&gt;
&lt;br /&gt;
1.  $ cd ..&lt;br /&gt;
2.  $ vi ext/nsdb/config.m4&lt;br /&gt;
3.  $ ./buildconf&lt;br /&gt;
4.  $ ./configure --[with|enable]-nsdb&lt;br /&gt;
5.  $ make&lt;br /&gt;
6.  $ ./php -f ext/nsdb/nsdb.php&lt;br /&gt;
7.  $ vi ext/nsdb/nsdb.c&lt;br /&gt;
8.  $ make&lt;br /&gt;
&lt;br /&gt;
Repeat steps 3-6 until you are satisfied with ext/nsdb/config.m4 and&lt;br /&gt;
step 6 confirms that your module is compiled into PHP. Then, start writing&lt;br /&gt;
code and repeat the last two steps as often as necessary.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4607</id>
		<title>User talk:Caveman</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Caveman&amp;diff=4607"/>
		<updated>2005-12-12T17:43:03Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, and welcome to the wiki!  If you don't mind me asking, what's your full name (or do you want to remain anonymous)?  Are you also subscribed to the [http://aolserver.com/lists.php AOLSERVER mailing list]?  Some of us also hang out on [http://aolserver.com/chat/ IRC and chat] (you can also access the chat via AIM, but most folks use IRC).&lt;br /&gt;
&lt;br /&gt;
If you have any questions or concerns, don't hesitate to contact me.  Thanks! ''-- [[User:Dossy|Dossy]] 07:13, 3 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Why does it seem like you're avoiding Tcl?  Your recent wiki edits have been focused around other languages in AOLserver other than Tcl, like Lua, PHP and Ruby.  Why?  You will really never get the kind of performance out of Perl, PHP or Ruby as you will Tcl, because Tcl is suitable for embedding in a multi-threaded application where Perl, PHP and Ruby aren't.  (I don't know enough about Lua to say one way or the other.)  So, if you still want to use those other languages, then you probably don't care about performance at the high end, in which case, you probably don't need to use AOLserver, either.  In the small, any web server will be more than adequate on modern hardware to serve a few hundred pages here and there.  It's when you start getting into the few hundred per second arena where AOLserver has the opportunity to shine. ''-- [[User:Dossy|Dossy]] 07:46, 10 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
* Not at all -- I'm looking at other languages simply from the point of view of seeing how AOLServer modules are built at all. It has been a while since I did any heavy lifting with C, and I felt that tinkering with the module code would be a good refresher. Just scratching an itch. I use TCL heavily every day at work, and have no real knowledge of Lua either, it just seemed an opportune target to use when examining the general AOLServer module layer. --[[Caveman]] 12:23, 12 December 2005 (EST) &lt;br /&gt;
&lt;br /&gt;
** Okay, cool.  FYI, &amp;quot;AOLserver&amp;quot; is capitalized just like that, not &amp;quot;AOLServer&amp;quot; -- I'm picking nits, but the consistency is important to me.  Thanks.  :-) ''-- [[User:Dossy|Dossy]] 12:41, 12 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
*** Ack. I've been doing that on a ton of pages -- my mistake, I will try to use the correct capitalisation. --[[User:Caveman|Caveman]] 12:43, 12 December 2005 (EST)&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Dossy&amp;diff=4604</id>
		<title>User talk:Dossy</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=User_talk:Dossy&amp;diff=4604"/>
		<updated>2005-12-12T17:23:28Z</updated>

		<summary type="html">&lt;p&gt;Caveman: re: avoiding TCL&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== re: avoiding TCL ==&lt;br /&gt;
&lt;br /&gt;
Not at all -- I'm looking at other languages simply from the point of view of seeing how AOLServer modules are built at all. It has been a while since I did any heavy lifting with C, and I felt that tinkering with the module code would be a good refresher. Just scratching an itch. I use TCL heavily every day at work, and have no real knowledge of Lua either, it just seemed an opportune target to use when examining the general AOLServer module layer. --[[User:Caveman|Caveman]] 12:23, 12 December 2005 (EST)&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Embedding_a_new_programming_language_as_a_module&amp;diff=4581</id>
		<title>Talk:Embedding a new programming language as a module</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Embedding_a_new_programming_language_as_a_module&amp;diff=4581"/>
		<updated>2005-12-09T16:09:38Z</updated>

		<summary type="html">&lt;p&gt;Caveman: apache mod_lua link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Do you think any examples like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Ns_Log(Debug, &amp;quot;opening lua state&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Would be useful here?&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
What about proper termination:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Ns_RegisterShutdown(MyLuaCleanup, ...);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Also eventually the reader may need to learn about &amp;lt;pre&amp;gt;Ns_ConfigGetValue&amp;lt;/pre&amp;gt; to complete more complex tasks.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
I honestly don't know how to go about building or configuring a &amp;quot;.lua&amp;quot; extension handler. The full-fledged example I would look at (PyWX) is a great example of a C++ module, but it's a bit difficult for me to translate what's going on in PyWX to what I should do for Lua with a C module. I might be able to work out the extension handler portion, but getting Lua's &amp;quot;print&amp;quot; to output correctly might be tricky. -- --[[User:Caveman|Caveman]] 08:42, 6 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
== apache mod_lua link ==&lt;br /&gt;
&lt;br /&gt;
There is an Apache &amp;quot;mod_lua&amp;quot; on Sourceforge that could be useful for a &amp;quot;real&amp;quot; nslua module developer:&lt;br /&gt;
&lt;br /&gt;
[http://sourceforge.net/projects/modlua/]&lt;br /&gt;
&lt;br /&gt;
[http://cvs.sourceforge.net/viewcvs.py/modlua/modlua/mod_lua.c?rev=1.3&amp;amp;view=auto]&lt;br /&gt;
&lt;br /&gt;
--[[User:Caveman|Caveman]] 11:09, 9 December 2005 (EST)&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ruby&amp;diff=4580</id>
		<title>Talk:Ruby</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ruby&amp;diff=4580"/>
		<updated>2005-12-09T15:28:45Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* Ruby on Rails on AOLServer? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ruby on Rails on AOLServer? ==&lt;br /&gt;
&lt;br /&gt;
Any thoughts or ideas on whether [http://www.rubyonrails.org Ruby on Rails] would work with the nsruby module? --[[User:Caveman|Caveman]] 10:28, 9 December 2005 (EST)&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ruby&amp;diff=4579</id>
		<title>Talk:Ruby</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:Ruby&amp;diff=4579"/>
		<updated>2005-12-09T15:28:31Z</updated>

		<summary type="html">&lt;p&gt;Caveman: Ruby on Rails on AOLServer?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ruby on Rails on AOLServer? ==&lt;br /&gt;
&lt;br /&gt;
Any thoughts or ideas on whether [http://www.rubyonrails.org Ruby on Rails] would work with the nsruby module?&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4578</id>
		<title>Talk:How to set up PHP under AOLserver</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4578"/>
		<updated>2005-12-09T02:33:49Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* extending PHP to take advantage of AOLServer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I cannot get php-5.1.1 to build with Debian 3.1 package of aolserver4 and aolserver4-dev (which is built with --prefix=/usr/lib/aolserver4):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ./configure --with-aolserver=/usr/lib/aolserver4&lt;br /&gt;
loading cache ./config.cache&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Configuring SAPI modules&lt;br /&gt;
checking for AOLserver support... /usr/lib/aolserver4&lt;br /&gt;
configure: error: Please specify the path to the source distribution of AOLserver using --with-aolserver-src=DIR&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''I only ever tested this against PHP 4.3.7 -- I don't know what is required to make it work with PHP 5.1.1.  If you figure it out, please update the page.  -- [[User:Dossy|Dossy]] 12:05, 7 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
** I opened a PHP bug issue for this: [http://bugs.php.net/bug.php?id=35605] --[[User:Caveman|Caveman]] 14:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
*** This may be an issue more with the way Debian 3.1 installs AOLServer 4 than anything else. The &amp;quot;proper&amp;quot; PHP configure command should be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/path/to/installed/aolserver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Debian 3.1 configures AOLServer with a prefix of &amp;quot;/usr/lib/aolserver4&amp;quot;. However, using this as the &amp;quot;/path/to/installed/aolserver&amp;quot; results in the same error and a request for &amp;quot;--with-aolserver-src&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
**** I configured and installed aolserver4 from source into &amp;quot;/home/sam/aolserver&amp;quot;. PHP configure finally completed successfully. However, PHP compile still failed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/bin/sh /home/sam/downloads/php.net/php-5.1.1/libtool --silent --preserve-dup-deps --mode=compile /home/sam/downloads/php.net/php-5.1.1/meta_ccld  -Isapi/aolserver/ -I/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/ -DPHP_ATOM_INC -I/home/sam/downloads/php.net/php-5.1.1/include -I/home/sam/downloads/php.net/php-5.1.1/main -I/home/sam/downloads/php.net/php-5.1.1 -I/home/sam/aolserver/include -I/usr/include/libxml2 -I/home/sam/downloads/php.net/php-5.1.1/ext/date/lib -I/home/sam/downloads/php.net/php-5.1.1/TSRM -I/home/sam/downloads/php.net/php-5.1.1/Zend  -D_REENTRANT  -g -O2 -pthread -DZTS  -prefer-non-pic -c /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c -o sapi/aolserver/aolserver.lo&lt;br /&gt;
In file included from /home/sam/aolserver/include/ns.h:62,&lt;br /&gt;
                 from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:125:17: tcl.h: No such file or directory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was obviously an error finding &amp;quot;tcl.h&amp;quot;. I manually edited the PHP &amp;quot;Makefile&amp;quot; and set:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXTRA_INCLUDES = -I/usr/include/tcl8.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allowed PHP compilation to complete. The module loaded successfully and PHP scripts work as expected (see [http://caveman.org/phpinfo/ phpinfo output]). --[[User:Caveman|Caveman]] 19:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
With trial and error, I was able to configure and compile against the Debian 3.1 packages as installed by default:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/usr&lt;br /&gt;
make &amp;quot;EXTRA_INCLUDES=-I/usr/include/tcl8.4 -I/usr/include/aolserver4&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== extending PHP to take advantage of AOLServer ==&lt;br /&gt;
&lt;br /&gt;
http://aolserver.org/docs/devel/c/api/c-ch3.htm#37064&lt;br /&gt;
&lt;br /&gt;
proposal: write a PHP extension to provide PHP functions to access AOLServer database pools (and perhaps other important features like shared memory).&lt;br /&gt;
&lt;br /&gt;
In other words, provide PHP functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_db_gethandle&lt;br /&gt;
ns_db_select&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so on. It should be nearly trivial to do this, and give PHP on AOLServer a very powerful advantage over PHP on Apache.&lt;br /&gt;
&lt;br /&gt;
[http://www.webtechniques.com/archives/2001/01/junk/ Extending PHP By Sterling Hughes]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1/ext$ ./ext_skel --extname=nsdb&lt;br /&gt;
Creating directory nsdb&lt;br /&gt;
Creating basic files: config.m4 config.w32 .cvsignore nsdb.c php_nsdb.h CREDITS EXPERIMENTAL tests/001.phpt nsdb.php [done].&lt;br /&gt;
&lt;br /&gt;
To use your new extension, you will have to execute the following steps:&lt;br /&gt;
&lt;br /&gt;
1.  $ cd ..&lt;br /&gt;
2.  $ vi ext/nsdb/config.m4&lt;br /&gt;
3.  $ ./buildconf&lt;br /&gt;
4.  $ ./configure --[with|enable]-nsdb&lt;br /&gt;
5.  $ make&lt;br /&gt;
6.  $ ./php -f ext/nsdb/nsdb.php&lt;br /&gt;
7.  $ vi ext/nsdb/nsdb.c&lt;br /&gt;
8.  $ make&lt;br /&gt;
&lt;br /&gt;
Repeat steps 3-6 until you are satisfied with ext/nsdb/config.m4 and&lt;br /&gt;
step 6 confirms that your module is compiled into PHP. Then, start writing&lt;br /&gt;
code and repeat the last two steps as often as necessary.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4577</id>
		<title>Talk:How to set up PHP under AOLserver</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4577"/>
		<updated>2005-12-09T02:21:41Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* extending PHP to take advantage of AOLServer */  added link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I cannot get php-5.1.1 to build with Debian 3.1 package of aolserver4 and aolserver4-dev (which is built with --prefix=/usr/lib/aolserver4):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ./configure --with-aolserver=/usr/lib/aolserver4&lt;br /&gt;
loading cache ./config.cache&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Configuring SAPI modules&lt;br /&gt;
checking for AOLserver support... /usr/lib/aolserver4&lt;br /&gt;
configure: error: Please specify the path to the source distribution of AOLserver using --with-aolserver-src=DIR&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''I only ever tested this against PHP 4.3.7 -- I don't know what is required to make it work with PHP 5.1.1.  If you figure it out, please update the page.  -- [[User:Dossy|Dossy]] 12:05, 7 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
** I opened a PHP bug issue for this: [http://bugs.php.net/bug.php?id=35605] --[[User:Caveman|Caveman]] 14:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
*** This may be an issue more with the way Debian 3.1 installs AOLServer 4 than anything else. The &amp;quot;proper&amp;quot; PHP configure command should be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/path/to/installed/aolserver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Debian 3.1 configures AOLServer with a prefix of &amp;quot;/usr/lib/aolserver4&amp;quot;. However, using this as the &amp;quot;/path/to/installed/aolserver&amp;quot; results in the same error and a request for &amp;quot;--with-aolserver-src&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
**** I configured and installed aolserver4 from source into &amp;quot;/home/sam/aolserver&amp;quot;. PHP configure finally completed successfully. However, PHP compile still failed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/bin/sh /home/sam/downloads/php.net/php-5.1.1/libtool --silent --preserve-dup-deps --mode=compile /home/sam/downloads/php.net/php-5.1.1/meta_ccld  -Isapi/aolserver/ -I/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/ -DPHP_ATOM_INC -I/home/sam/downloads/php.net/php-5.1.1/include -I/home/sam/downloads/php.net/php-5.1.1/main -I/home/sam/downloads/php.net/php-5.1.1 -I/home/sam/aolserver/include -I/usr/include/libxml2 -I/home/sam/downloads/php.net/php-5.1.1/ext/date/lib -I/home/sam/downloads/php.net/php-5.1.1/TSRM -I/home/sam/downloads/php.net/php-5.1.1/Zend  -D_REENTRANT  -g -O2 -pthread -DZTS  -prefer-non-pic -c /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c -o sapi/aolserver/aolserver.lo&lt;br /&gt;
In file included from /home/sam/aolserver/include/ns.h:62,&lt;br /&gt;
                 from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:125:17: tcl.h: No such file or directory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was obviously an error finding &amp;quot;tcl.h&amp;quot;. I manually edited the PHP &amp;quot;Makefile&amp;quot; and set:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXTRA_INCLUDES = -I/usr/include/tcl8.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allowed PHP compilation to complete. The module loaded successfully and PHP scripts work as expected (see [http://caveman.org/phpinfo/ phpinfo output]). --[[User:Caveman|Caveman]] 19:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
With trial and error, I was able to configure and compile against the Debian 3.1 packages as installed by default:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/usr&lt;br /&gt;
make &amp;quot;EXTRA_INCLUDES=-I/usr/include/tcl8.4 -I/usr/include/aolserver4&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== extending PHP to take advantage of AOLServer ==&lt;br /&gt;
&lt;br /&gt;
http://aolserver.org/docs/devel/c/api/c-ch3.htm#37064&lt;br /&gt;
&lt;br /&gt;
proposal: write a PHP extension to provide PHP functions to access AOLServer database pools (and perhaps other important features like shared memory).&lt;br /&gt;
&lt;br /&gt;
In other words, provide PHP functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_db_gethandle&lt;br /&gt;
ns_db_select&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so on. It should be nearly trivial to do this, and give PHP on AOLServer a very powerful advantage over PHP on Apache.&lt;br /&gt;
&lt;br /&gt;
[http://www.webtechniques.com/archives/2001/01/junk/ Extending PHP By Sterling Hughes]&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4576</id>
		<title>Talk:How to set up PHP under AOLserver</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4576"/>
		<updated>2005-12-09T02:11:43Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I cannot get php-5.1.1 to build with Debian 3.1 package of aolserver4 and aolserver4-dev (which is built with --prefix=/usr/lib/aolserver4):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ./configure --with-aolserver=/usr/lib/aolserver4&lt;br /&gt;
loading cache ./config.cache&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Configuring SAPI modules&lt;br /&gt;
checking for AOLserver support... /usr/lib/aolserver4&lt;br /&gt;
configure: error: Please specify the path to the source distribution of AOLserver using --with-aolserver-src=DIR&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''I only ever tested this against PHP 4.3.7 -- I don't know what is required to make it work with PHP 5.1.1.  If you figure it out, please update the page.  -- [[User:Dossy|Dossy]] 12:05, 7 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
** I opened a PHP bug issue for this: [http://bugs.php.net/bug.php?id=35605] --[[User:Caveman|Caveman]] 14:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
*** This may be an issue more with the way Debian 3.1 installs AOLServer 4 than anything else. The &amp;quot;proper&amp;quot; PHP configure command should be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/path/to/installed/aolserver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Debian 3.1 configures AOLServer with a prefix of &amp;quot;/usr/lib/aolserver4&amp;quot;. However, using this as the &amp;quot;/path/to/installed/aolserver&amp;quot; results in the same error and a request for &amp;quot;--with-aolserver-src&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
**** I configured and installed aolserver4 from source into &amp;quot;/home/sam/aolserver&amp;quot;. PHP configure finally completed successfully. However, PHP compile still failed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/bin/sh /home/sam/downloads/php.net/php-5.1.1/libtool --silent --preserve-dup-deps --mode=compile /home/sam/downloads/php.net/php-5.1.1/meta_ccld  -Isapi/aolserver/ -I/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/ -DPHP_ATOM_INC -I/home/sam/downloads/php.net/php-5.1.1/include -I/home/sam/downloads/php.net/php-5.1.1/main -I/home/sam/downloads/php.net/php-5.1.1 -I/home/sam/aolserver/include -I/usr/include/libxml2 -I/home/sam/downloads/php.net/php-5.1.1/ext/date/lib -I/home/sam/downloads/php.net/php-5.1.1/TSRM -I/home/sam/downloads/php.net/php-5.1.1/Zend  -D_REENTRANT  -g -O2 -pthread -DZTS  -prefer-non-pic -c /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c -o sapi/aolserver/aolserver.lo&lt;br /&gt;
In file included from /home/sam/aolserver/include/ns.h:62,&lt;br /&gt;
                 from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:125:17: tcl.h: No such file or directory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was obviously an error finding &amp;quot;tcl.h&amp;quot;. I manually edited the PHP &amp;quot;Makefile&amp;quot; and set:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXTRA_INCLUDES = -I/usr/include/tcl8.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allowed PHP compilation to complete. The module loaded successfully and PHP scripts work as expected (see [http://caveman.org/phpinfo/ phpinfo output]). --[[User:Caveman|Caveman]] 19:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
With trial and error, I was able to configure and compile against the Debian 3.1 packages as installed by default:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/usr&lt;br /&gt;
make &amp;quot;EXTRA_INCLUDES=-I/usr/include/tcl8.4 -I/usr/include/aolserver4&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== extending PHP to take advantage of AOLServer ==&lt;br /&gt;
&lt;br /&gt;
http://aolserver.org/docs/devel/c/api/c-ch3.htm#37064&lt;br /&gt;
&lt;br /&gt;
proposal: write a PHP extension to provide PHP functions to access AOLServer database pools (and perhaps other important features like shared memory).&lt;br /&gt;
&lt;br /&gt;
In other words, provide PHP functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_db_gethandle&lt;br /&gt;
ns_db_select&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so on. It should be nearly trivial to do this, and give PHP on AOLServer a very powerful advantage over PHP on Apache.&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4575</id>
		<title>Talk:How to set up PHP under AOLserver</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4575"/>
		<updated>2005-12-09T02:05:25Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I've downloaded the aolserver src both directly and via the Debian source package, but cannot get php-5.1.1 to build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ./configure --with-aolserver --with-aolserver-src=/home/sam/downloads/aolserver.org/aolserver-4.0.10&lt;br /&gt;
aolserver-4.0.10             aolserver-4.0.10-src.tar.gz&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ./configure --with-aolserver --with-aolserver-src=/home/sam/downloads/aolserver.org/aolserver-4.0.10 --enable-shared&lt;br /&gt;
loading cache ./config.cache&lt;br /&gt;
checking for Cygwin environment... no&lt;br /&gt;
checking for mingw32 environment... no&lt;br /&gt;
checking for egrep... grep -E&lt;br /&gt;
checking for a sed that does not truncate output... /bin/sed&lt;br /&gt;
checking host system type... i686-pc-linux-gnu&lt;br /&gt;
checking target system type... i686-pc-linux-gnu&lt;br /&gt;
checking for gcc... gcc&lt;br /&gt;
checking whether the C compiler (gcc  ) works... yes&lt;br /&gt;
checking whether the C compiler (gcc  ) is a cross-compiler... no&lt;br /&gt;
checking whether we are using GNU C... yes&lt;br /&gt;
checking whether gcc accepts -g... yes&lt;br /&gt;
checking whether gcc and cc understand -c and -o together... yes&lt;br /&gt;
checking how to run the C preprocessor... gcc -E&lt;br /&gt;
checking for AIX... no&lt;br /&gt;
checking whether ln -s works... yes&lt;br /&gt;
checking if compiler supports -R... no&lt;br /&gt;
checking if compiler supports -Wl,-rpath,... yes&lt;br /&gt;
checking for re2c... re2c&lt;br /&gt;
checking for re2c version... invalid&lt;br /&gt;
configure: warning: You will need re2c 0.98 or later if you want to regenerate PHP parsers.&lt;br /&gt;
checking for gawk... gawk&lt;br /&gt;
checking for bison... bison -y&lt;br /&gt;
checking for bison version... 1.875 (ok)&lt;br /&gt;
checking for flex... flex&lt;br /&gt;
checking for yywrap in -lfl... yes&lt;br /&gt;
checking lex output file root... lex.yy&lt;br /&gt;
checking whether yytext is a pointer... yes&lt;br /&gt;
checking for working const... yes&lt;br /&gt;
checking for flex version... invalid&lt;br /&gt;
configure: warning: flex versions supported for regeneration of the Zend/PHP parsers: 2.5.4  (found: 2.5.31).&lt;br /&gt;
checking whether to force non-PIC code in shared modules... yes&lt;br /&gt;
checking for pthreads_cflags... -pthread&lt;br /&gt;
checking for pthreads_lib...&lt;br /&gt;
&lt;br /&gt;
Configuring SAPI modules&lt;br /&gt;
checking for AOLserver support... yes&lt;br /&gt;
configure: error: Please specify the path to the source distribution of AOLserver using --with-aolserver-src=DIR&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ls /home/sam/downloads/aolserver.org/aolserver-4.0.10&lt;br /&gt;
ChangeLog   configure     index.html     nscgi  nsext   nssock             tcl&lt;br /&gt;
Makefile    configure.in  ini2tcl.tcl    nscp   nslog   nsssl              tcl2ini.tcl&lt;br /&gt;
README      doc           install-sh     nsd    nspd    nsthread           tests&lt;br /&gt;
aclocal.m4  include       license.terms  nsdb   nsperm  sample-config.tcl  win32&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perhaps I am simply an idiot (would not be the first time) but something &amp;quot;no longer works&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* ''I only ever tested this against PHP 4.3.7 -- I don't know what is required to make it work with PHP 5.1.1.  If you figure it out, please update the page.  -- [[User:Dossy|Dossy]] 12:05, 7 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
** I opened a PHP bug issue for this: [http://bugs.php.net/bug.php?id=35605] --[[User:Caveman|Caveman]] 14:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
*** This may be an issue more with the way Debian 3.1 installs AOLServer 4 than anything else. The &amp;quot;proper&amp;quot; PHP configure command should be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/path/to/installed/aolserver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Debian 3.1 configures AOLServer with a prefix of &amp;quot;/usr/lib/aolserver4&amp;quot;. However, using this as the &amp;quot;/path/to/installed/aolserver&amp;quot; results in the same error and a request for &amp;quot;--with-aolserver-src&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
**** I configured and installed aolserver4 from source into &amp;quot;/home/sam/aolserver&amp;quot;. PHP configure finally completed successfully. However, PHP compile still failed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/bin/sh /home/sam/downloads/php.net/php-5.1.1/libtool --silent --preserve-dup-deps --mode=compile /home/sam/downloads/php.net/php-5.1.1/meta_ccld  -Isapi/aolserver/ -I/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/ -DPHP_ATOM_INC -I/home/sam/downloads/php.net/php-5.1.1/include -I/home/sam/downloads/php.net/php-5.1.1/main -I/home/sam/downloads/php.net/php-5.1.1 -I/home/sam/aolserver/include -I/usr/include/libxml2 -I/home/sam/downloads/php.net/php-5.1.1/ext/date/lib -I/home/sam/downloads/php.net/php-5.1.1/TSRM -I/home/sam/downloads/php.net/php-5.1.1/Zend  -D_REENTRANT  -g -O2 -pthread -DZTS  -prefer-non-pic -c /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c -o sapi/aolserver/aolserver.lo&lt;br /&gt;
In file included from /home/sam/aolserver/include/ns.h:62,&lt;br /&gt;
                 from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:125:17: tcl.h: No such file or directory&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was obviously an error finding &amp;quot;tcl.h&amp;quot;. I manually edited the PHP &amp;quot;Makefile&amp;quot; and set:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXTRA_INCLUDES = -I/usr/include/tcl8.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allowed PHP compilation to complete. The module loaded successfully and PHP scripts work as expected (see [http://caveman.org/phpinfo/ phpinfo output]). --[[User:Caveman|Caveman]] 19:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
With trial and error, I was able to configure and compile against the Debian 3.1 packages as installed by default:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/usr&lt;br /&gt;
make &amp;quot;EXTRA_INCLUDES=-I/usr/include/tcl8.4 -I/usr/include/aolserver4&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== extending PHP to take advantage of AOLServer ==&lt;br /&gt;
&lt;br /&gt;
http://aolserver.org/docs/devel/c/api/c-ch3.htm#37064&lt;br /&gt;
&lt;br /&gt;
proposal: write a PHP extension to provide PHP functions to access AOLServer database pools (and perhaps other important features like shared memory).&lt;br /&gt;
&lt;br /&gt;
In other words, provide PHP functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_db_gethandle&lt;br /&gt;
ns_db_select&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so on. It should be nearly trivial to do this, and give PHP on AOLServer a very powerful advantage over PHP on Apache.&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4574</id>
		<title>Talk:How to set up PHP under AOLserver</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4574"/>
		<updated>2005-12-09T02:04:37Z</updated>

		<summary type="html">&lt;p&gt;Caveman: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I've downloaded the aolserver src both directly and via the Debian source package, but cannot get php-5.1.1 to build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ./configure --with-aolserver --with-aolserver-src=/home/sam/downloads/aolserver.org/aolserver-4.0.10&lt;br /&gt;
aolserver-4.0.10             aolserver-4.0.10-src.tar.gz&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ./configure --with-aolserver --with-aolserver-src=/home/sam/downloads/aolserver.org/aolserver-4.0.10 --enable-shared&lt;br /&gt;
loading cache ./config.cache&lt;br /&gt;
checking for Cygwin environment... no&lt;br /&gt;
checking for mingw32 environment... no&lt;br /&gt;
checking for egrep... grep -E&lt;br /&gt;
checking for a sed that does not truncate output... /bin/sed&lt;br /&gt;
checking host system type... i686-pc-linux-gnu&lt;br /&gt;
checking target system type... i686-pc-linux-gnu&lt;br /&gt;
checking for gcc... gcc&lt;br /&gt;
checking whether the C compiler (gcc  ) works... yes&lt;br /&gt;
checking whether the C compiler (gcc  ) is a cross-compiler... no&lt;br /&gt;
checking whether we are using GNU C... yes&lt;br /&gt;
checking whether gcc accepts -g... yes&lt;br /&gt;
checking whether gcc and cc understand -c and -o together... yes&lt;br /&gt;
checking how to run the C preprocessor... gcc -E&lt;br /&gt;
checking for AIX... no&lt;br /&gt;
checking whether ln -s works... yes&lt;br /&gt;
checking if compiler supports -R... no&lt;br /&gt;
checking if compiler supports -Wl,-rpath,... yes&lt;br /&gt;
checking for re2c... re2c&lt;br /&gt;
checking for re2c version... invalid&lt;br /&gt;
configure: warning: You will need re2c 0.98 or later if you want to regenerate PHP parsers.&lt;br /&gt;
checking for gawk... gawk&lt;br /&gt;
checking for bison... bison -y&lt;br /&gt;
checking for bison version... 1.875 (ok)&lt;br /&gt;
checking for flex... flex&lt;br /&gt;
checking for yywrap in -lfl... yes&lt;br /&gt;
checking lex output file root... lex.yy&lt;br /&gt;
checking whether yytext is a pointer... yes&lt;br /&gt;
checking for working const... yes&lt;br /&gt;
checking for flex version... invalid&lt;br /&gt;
configure: warning: flex versions supported for regeneration of the Zend/PHP parsers: 2.5.4  (found: 2.5.31).&lt;br /&gt;
checking whether to force non-PIC code in shared modules... yes&lt;br /&gt;
checking for pthreads_cflags... -pthread&lt;br /&gt;
checking for pthreads_lib...&lt;br /&gt;
&lt;br /&gt;
Configuring SAPI modules&lt;br /&gt;
checking for AOLserver support... yes&lt;br /&gt;
configure: error: Please specify the path to the source distribution of AOLserver using --with-aolserver-src=DIR&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ls /home/sam/downloads/aolserver.org/aolserver-4.0.10&lt;br /&gt;
ChangeLog   configure     index.html     nscgi  nsext   nssock             tcl&lt;br /&gt;
Makefile    configure.in  ini2tcl.tcl    nscp   nslog   nsssl              tcl2ini.tcl&lt;br /&gt;
README      doc           install-sh     nsd    nspd    nsthread           tests&lt;br /&gt;
aclocal.m4  include       license.terms  nsdb   nsperm  sample-config.tcl  win32&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perhaps I am simply an idiot (would not be the first time) but something &amp;quot;no longer works&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* ''I only ever tested this against PHP 4.3.7 -- I don't know what is required to make it work with PHP 5.1.1.  If you figure it out, please update the page.  -- [[User:Dossy|Dossy]] 12:05, 7 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
** I opened a PHP bug issue for this: [http://bugs.php.net/bug.php?id=35605] --[[User:Caveman|Caveman]] 14:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
*** This may be an issue more with the way Debian 3.1 installs AOLServer 4 than anything else. The &amp;quot;proper&amp;quot; PHP configure command should be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/path/to/installed/aolserver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Debian 3.1 configures AOLServer with a prefix of &amp;quot;/usr/lib/aolserver4&amp;quot;. However, using this as the &amp;quot;/path/to/installed/aolserver&amp;quot; results in the same error and a request for &amp;quot;--with-aolserver-src&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
**** I configured and installed aolserver4 from source into &amp;quot;/home/sam/aolserver&amp;quot;. PHP configure finally completed successfully. However, PHP compile still failed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/bin/sh /home/sam/downloads/php.net/php-5.1.1/libtool --silent --preserve-dup-deps --mode=compile /home/sam/downloads/php.net/php-5.1.1/meta_ccld  -Isapi/aolserver/ -I/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/ -DPHP_ATOM_INC -I/home/sam/downloads/php.net/php-5.1.1/include -I/home/sam/downloads/php.net/php-5.1.1/main -I/home/sam/downloads/php.net/php-5.1.1 -I/home/sam/aolserver/include -I/usr/include/libxml2 -I/home/sam/downloads/php.net/php-5.1.1/ext/date/lib -I/home/sam/downloads/php.net/php-5.1.1/TSRM -I/home/sam/downloads/php.net/php-5.1.1/Zend  -D_REENTRANT  -g -O2 -pthread -DZTS  -prefer-non-pic -c /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c -o sapi/aolserver/aolserver.lo&lt;br /&gt;
In file included from /home/sam/aolserver/include/ns.h:62,&lt;br /&gt;
                 from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:125:17: tcl.h: No such file or directory&lt;br /&gt;
In file included from /home/sam/aolserver/include/ns.h:62,&lt;br /&gt;
                 from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:178: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:215: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:294: error: syntax error before '*' token&lt;br /&gt;
In file included from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/ns.h:275: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:276: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:277: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:284: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:287: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:442: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:446: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:455: error: syntax error before &amp;quot;Ns_CacheSearch&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:455: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:507: error: syntax error before &amp;quot;Ns_CacheSearch&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:508: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:545: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:546: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:571: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:575: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:576: error: syntax error before &amp;quot;Tcl_Channel&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:580: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:581: error: syntax error before &amp;quot;Tcl_Channel&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:585: error: syntax error before &amp;quot;Tcl_Encoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:586: error: syntax error before &amp;quot;Ns_ConnGetEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:586: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:587: error: syntax error before &amp;quot;Tcl_Encoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:588: error: syntax error before &amp;quot;Ns_ConnGetUrlEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:588: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:617: error: syntax error before &amp;quot;Tcl_Encoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:629: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:630: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:631: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:643: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:644: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:645: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:646: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:647: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:648: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:649: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:649: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:650: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:672: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:764: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:765: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:771: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:772: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:778: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:780: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:782: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:784: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:850: error: syntax error before &amp;quot;Ns_GetEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:850: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:851: error: syntax error before &amp;quot;Ns_GetFileEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:851: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:852: error: syntax error before &amp;quot;Ns_GetTypeEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:852: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:853: error: syntax error before &amp;quot;Ns_GetCharsetEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:853: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:892: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:893: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:894: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:895: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:896: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:904: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:916: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:932: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:966: error: syntax error before &amp;quot;Tcl_Channel&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1095: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1102: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1104: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1111: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1112: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1115: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1116: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1117: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1117: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1118: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1119: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1119: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1120: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1122: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1123: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1133: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1134: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1135: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1136: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1136: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1143: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1144: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1145: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1146: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1152: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1162: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1168: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1170: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1172: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1174: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1181: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1182: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1221: error: syntax error before '*' token&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c: In function `php_ns_request_ctor':&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:428: error: `Tcl_DString' undeclared (first use in this function)&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:428: error: (Each undeclared identifier is reported only once&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:428: error: for each function it appears in.)&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:428: error: syntax error before &amp;quot;ds&amp;quot;&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:438: error: `ds' undeclared (first use in this function)&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:442: warning: passing arg 1 of `strlen' makes pointer from integer without a cast&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:442: warning: passing arg 2 of `memcpy' makes pointer from integer without a cast&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:442: warning: passing arg 1 of `__strdup' makes pointer from integer without a cast&lt;br /&gt;
make: *** [sapi/aolserver/aolserver.lo] Error 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was obviously an error finding &amp;quot;tcl.h&amp;quot;. I manually edited the PHP &amp;quot;Makefile&amp;quot; and set:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXTRA_INCLUDES = -I/usr/include/tcl8.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allowed PHP compilation to complete. The module loaded successfully and PHP scripts work as expected (see [http://caveman.org/phpinfo/ phpinfo output]). --[[User:Caveman|Caveman]] 19:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
With trial and error, I was able to configure and compile against the Debian 3.1 packages as installed by default:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/usr&lt;br /&gt;
make &amp;quot;EXTRA_INCLUDES=-I/usr/include/tcl8.4 -I/usr/include/aolserver4&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== extending PHP to take advantage of AOLServer ==&lt;br /&gt;
&lt;br /&gt;
http://aolserver.org/docs/devel/c/api/c-ch3.htm#37064&lt;br /&gt;
&lt;br /&gt;
proposal: write a PHP extension to provide PHP functions to access AOLServer database pools (and perhaps other important features like shared memory).&lt;br /&gt;
&lt;br /&gt;
In other words, provide PHP functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_db_gethandle&lt;br /&gt;
ns_db_select&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so on. It should be nearly trivial to do this, and give PHP on AOLServer a very powerful advantage over PHP on Apache.&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
	<entry>
		<id>https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4573</id>
		<title>Talk:How to set up PHP under AOLserver</title>
		<link rel="alternate" type="text/html" href="https://panoptic.com/mediawiki/aolserver/index.php?title=Talk:How_to_set_up_PHP_under_AOLserver&amp;diff=4573"/>
		<updated>2005-12-09T00:09:35Z</updated>

		<summary type="html">&lt;p&gt;Caveman: /* link to phpinfo output */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I've downloaded the aolserver src both directly and via the Debian source package, but cannot get php-5.1.1 to build:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ./configure --with-aolserver --with-aolserver-src=/home/sam/downloads/aolserver.org/aolserver-4.0.10&lt;br /&gt;
aolserver-4.0.10             aolserver-4.0.10-src.tar.gz&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ./configure --with-aolserver --with-aolserver-src=/home/sam/downloads/aolserver.org/aolserver-4.0.10 --enable-shared&lt;br /&gt;
loading cache ./config.cache&lt;br /&gt;
checking for Cygwin environment... no&lt;br /&gt;
checking for mingw32 environment... no&lt;br /&gt;
checking for egrep... grep -E&lt;br /&gt;
checking for a sed that does not truncate output... /bin/sed&lt;br /&gt;
checking host system type... i686-pc-linux-gnu&lt;br /&gt;
checking target system type... i686-pc-linux-gnu&lt;br /&gt;
checking for gcc... gcc&lt;br /&gt;
checking whether the C compiler (gcc  ) works... yes&lt;br /&gt;
checking whether the C compiler (gcc  ) is a cross-compiler... no&lt;br /&gt;
checking whether we are using GNU C... yes&lt;br /&gt;
checking whether gcc accepts -g... yes&lt;br /&gt;
checking whether gcc and cc understand -c and -o together... yes&lt;br /&gt;
checking how to run the C preprocessor... gcc -E&lt;br /&gt;
checking for AIX... no&lt;br /&gt;
checking whether ln -s works... yes&lt;br /&gt;
checking if compiler supports -R... no&lt;br /&gt;
checking if compiler supports -Wl,-rpath,... yes&lt;br /&gt;
checking for re2c... re2c&lt;br /&gt;
checking for re2c version... invalid&lt;br /&gt;
configure: warning: You will need re2c 0.98 or later if you want to regenerate PHP parsers.&lt;br /&gt;
checking for gawk... gawk&lt;br /&gt;
checking for bison... bison -y&lt;br /&gt;
checking for bison version... 1.875 (ok)&lt;br /&gt;
checking for flex... flex&lt;br /&gt;
checking for yywrap in -lfl... yes&lt;br /&gt;
checking lex output file root... lex.yy&lt;br /&gt;
checking whether yytext is a pointer... yes&lt;br /&gt;
checking for working const... yes&lt;br /&gt;
checking for flex version... invalid&lt;br /&gt;
configure: warning: flex versions supported for regeneration of the Zend/PHP parsers: 2.5.4  (found: 2.5.31).&lt;br /&gt;
checking whether to force non-PIC code in shared modules... yes&lt;br /&gt;
checking for pthreads_cflags... -pthread&lt;br /&gt;
checking for pthreads_lib...&lt;br /&gt;
&lt;br /&gt;
Configuring SAPI modules&lt;br /&gt;
checking for AOLserver support... yes&lt;br /&gt;
configure: error: Please specify the path to the source distribution of AOLserver using --with-aolserver-src=DIR&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$ ls /home/sam/downloads/aolserver.org/aolserver-4.0.10&lt;br /&gt;
ChangeLog   configure     index.html     nscgi  nsext   nssock             tcl&lt;br /&gt;
Makefile    configure.in  ini2tcl.tcl    nscp   nslog   nsssl              tcl2ini.tcl&lt;br /&gt;
README      doc           install-sh     nsd    nspd    nsthread           tests&lt;br /&gt;
aclocal.m4  include       license.terms  nsdb   nsperm  sample-config.tcl  win32&lt;br /&gt;
sam@caveman:~/downloads/php.net/php-5.1.1$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Perhaps I am simply an idiot (would not be the first time) but something &amp;quot;no longer works&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* ''I only ever tested this against PHP 4.3.7 -- I don't know what is required to make it work with PHP 5.1.1.  If you figure it out, please update the page.  -- [[User:Dossy|Dossy]] 12:05, 7 December 2005 (EST)''&lt;br /&gt;
&lt;br /&gt;
** I opened a PHP bug issue for this: [http://bugs.php.net/bug.php?id=35605] --[[User:Caveman|Caveman]] 14:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
*** This may be an issue more with the way Debian 3.1 installs AOLServer 4 than anything else. The &amp;quot;proper&amp;quot; PHP configure command should be:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
./configure --with-aolserver=/path/to/installed/aolserver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Debian 3.1 configures AOLServer with a prefix of &amp;quot;/usr/lib/aolserver4&amp;quot;. However, using this as the &amp;quot;/path/to/installed/aolserver&amp;quot; results in the same error and a request for &amp;quot;--with-aolserver-src&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
**** I configured and installed aolserver4 from source into &amp;quot;/home/sam/aolserver&amp;quot;. PHP configure finally completed successfully. However, PHP compile still failed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/bin/sh /home/sam/downloads/php.net/php-5.1.1/libtool --silent --preserve-dup-deps --mode=compile /home/sam/downloads/php.net/php-5.1.1/meta_ccld  -Isapi/aolserver/ -I/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/ -DPHP_ATOM_INC -I/home/sam/downloads/php.net/php-5.1.1/include -I/home/sam/downloads/php.net/php-5.1.1/main -I/home/sam/downloads/php.net/php-5.1.1 -I/home/sam/aolserver/include -I/usr/include/libxml2 -I/home/sam/downloads/php.net/php-5.1.1/ext/date/lib -I/home/sam/downloads/php.net/php-5.1.1/TSRM -I/home/sam/downloads/php.net/php-5.1.1/Zend  -D_REENTRANT  -g -O2 -pthread -DZTS  -prefer-non-pic -c /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c -o sapi/aolserver/aolserver.lo&lt;br /&gt;
In file included from /home/sam/aolserver/include/ns.h:62,&lt;br /&gt;
                 from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:125:17: tcl.h: No such file or directory&lt;br /&gt;
In file included from /home/sam/aolserver/include/ns.h:62,&lt;br /&gt;
                 from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:178: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:215: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/nsthread.h:294: error: syntax error before '*' token&lt;br /&gt;
In file included from /home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:49:&lt;br /&gt;
/home/sam/aolserver/include/ns.h:275: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:276: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:277: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:284: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:287: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:442: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:446: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:455: error: syntax error before &amp;quot;Ns_CacheSearch&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:455: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:507: error: syntax error before &amp;quot;Ns_CacheSearch&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:508: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:545: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:546: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:571: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:575: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:576: error: syntax error before &amp;quot;Tcl_Channel&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:580: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:581: error: syntax error before &amp;quot;Tcl_Channel&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:585: error: syntax error before &amp;quot;Tcl_Encoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:586: error: syntax error before &amp;quot;Ns_ConnGetEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:586: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:587: error: syntax error before &amp;quot;Tcl_Encoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:588: error: syntax error before &amp;quot;Ns_ConnGetUrlEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:588: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:617: error: syntax error before &amp;quot;Tcl_Encoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:629: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:630: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:631: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:643: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:644: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:645: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:646: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:647: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:648: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:649: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:649: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:650: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:672: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:764: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:765: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:771: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:772: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:778: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:780: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:782: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:784: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:850: error: syntax error before &amp;quot;Ns_GetEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:850: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:851: error: syntax error before &amp;quot;Ns_GetFileEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:851: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:852: error: syntax error before &amp;quot;Ns_GetTypeEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:852: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:853: error: syntax error before &amp;quot;Ns_GetCharsetEncoding&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:853: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:892: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:893: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:894: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:895: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:896: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:904: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:916: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:932: error: syntax error before &amp;quot;Tcl_DString&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:966: error: syntax error before &amp;quot;Tcl_Channel&amp;quot;&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1095: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1102: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1104: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1111: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1112: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1115: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1116: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1117: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1117: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1118: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1119: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1119: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1120: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1122: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1123: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1133: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1134: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1135: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1136: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1136: warning: data definition has no type or storage class&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1143: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1144: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1145: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1146: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1152: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1162: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1168: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1170: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1172: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1174: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1181: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1182: error: syntax error before '*' token&lt;br /&gt;
/home/sam/aolserver/include/ns.h:1221: error: syntax error before '*' token&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c: In function `php_ns_request_ctor':&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:428: error: `Tcl_DString' undeclared (first use in this function)&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:428: error: (Each undeclared identifier is reported only once&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:428: error: for each function it appears in.)&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:428: error: syntax error before &amp;quot;ds&amp;quot;&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:438: error: `ds' undeclared (first use in this function)&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:442: warning: passing arg 1 of `strlen' makes pointer from integer without a cast&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:442: warning: passing arg 2 of `memcpy' makes pointer from integer without a cast&lt;br /&gt;
/home/sam/downloads/php.net/php-5.1.1/sapi/aolserver/aolserver.c:442: warning: passing arg 1 of `__strdup' makes pointer from integer without a cast&lt;br /&gt;
make: *** [sapi/aolserver/aolserver.lo] Error 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This was obviously an error finding &amp;quot;tcl.h&amp;quot;. I manually edited the PHP &amp;quot;Makefile&amp;quot; and set:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXTRA_INCLUDES = -I/usr/include/tcl8.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allowed PHP compilation to complete. The module loaded successfully and PHP scripts work as expected (see [http://caveman.org/phpinfo/ phpinfo output]). --[[User:Caveman|Caveman]] 19:05, 8 December 2005 (EST)&lt;br /&gt;
&lt;br /&gt;
== extending PHP to take advantage of AOLServer ==&lt;br /&gt;
&lt;br /&gt;
http://aolserver.org/docs/devel/c/api/c-ch3.htm#37064&lt;br /&gt;
&lt;br /&gt;
proposal: write a PHP extension to provide PHP functions to access AOLServer database pools (and perhaps other important features like shared memory).&lt;br /&gt;
&lt;br /&gt;
In other words, provide PHP functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ns_db_gethandle&lt;br /&gt;
ns_db_select&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so on. It should be nearly trivial to do this, and give PHP on AOLServer a very powerful advantage over PHP on Apache.&lt;/div&gt;</summary>
		<author><name>Caveman</name></author>
		
	</entry>
</feed>