Index: main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/Makefile.in
===================================================================
--- main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/Makefile.in	(revision 28886)
+++ main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/Makefile.in	(revision 28886)
@@ -0,0 +1,379 @@
+###########################################################################
+#
+# Makefile -- runtime-src/src/recpt
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+RUNTIME_DIR = $(GSDL_DIR)/runtime-src
+
+GSDLOS = @gsdlos@
+GSDLARCH = @gsdlarch@
+
+INDEXERS_DIR = $(COMMON_DIR)/indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+RUNTIME_PACKAGES_DIR = $(RUNTIME_DIR)/packages
+COLSERVR_DIR = $(RUNTIME_DIR)/src/colservr
+PROTOCOL_DIR = $(RUNTIME_DIR)/src/protocol
+Z3950_DIR = $(RUNTIME_DIR)/src/z3950
+
+
+ENABLE_ACCENTFOLD = @ENABLE_ACCENTFOLD@
+ifeq ($(ENABLE_ACCENTFOLD), 1)
+ACCENTFOLD_LIBS = $(INDEXERS_DIR)/packages/unac/libunac.a $(COMMON_PACKAGES_DIR)/iconv/lib/libiconv.a
+else
+ACCENTFOLD_LIBS = 
+endif
+
+ENABLE_MG = @ENABLE_MG@
+ifeq ($(ENABLE_MG), 1)
+MG_INDEXERS_LIBS = $(INDEXERS_DIR)/mg/src/text/libmgtext.a \
+	$(INDEXERS_DIR)/mg/lib/libmglib.a
+MG_INCLUDES = -I$(INDEXERS_DIR)/mg -I$(INDEXERS_DIR)/mg/lib
+else
+MG_INDEXERS_LIBS =
+MG_INCLUDES =
+endif
+
+ENABLE_MGPP = @ENABLE_MGPP@
+ifeq ($(ENABLE_MGPP), 1)
+MGPP_SOURCES = phindaction.cpp
+MGPP_OBJECTS = phindaction.o
+MGPP_INDEXERS_LIBS = $(INDEXERS_DIR)/mgpp/text/libmgpptext.a \
+	$(INDEXERS_DIR)/mgpp/lib/libmgpplib.a
+MGPP_INCLUDES = -I$(INDEXERS_DIR)/mgpp/text -I$(INDEXERS_DIR)/mgpp/lib
+else
+MGPP_SOURCES =
+MGPP_OBJECTS =
+MGPP_INDEXERS_LIBS =
+MGPP_INCLUDES =
+endif
+
+USE_FASTCGI = @USE_FASTCGI@
+ifeq ($(USE_FASTCGI), 1)
+FASTCGI_DEFS = -DUSE_FASTCGI
+FASTCGI_INCLUDES = -I$(RUNTIME_PACKAGES_DIR)/fcgi/include
+FASTCGI_LIBS = $(RUNTIME_PACKAGES_DIR)/fcgi/libfcgi/libfcgi.a
+else
+FASTCGI_DEFS =
+FASTCGI_INCLUDES =
+FASTCGI_LIBS = 
+endif
+
+USE_GDBM = @USE_GDBM@
+ifeq ($(USE_GDBM), 1)
+GDBM_DEFINES = -DUSE_GDBM
+GDBM_INCLUDES = -I$(COMMON_PACKAGES_DIR)/gdbm/include
+GDBM_LIBS = $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a
+else
+GDBM_DEFINES = 
+GDBM_INCLUDES = 
+GDBM_LIBS = 
+endif
+
+USE_JDBM = @USE_JDBM@
+ifeq ($(USE_JDBM), 1)
+JDBM_DEFINES = -DUSE_JDBM
+else
+JDBM_DEFINES = 
+endif
+
+USE_SQLITE = @USE_SQLITE@
+ifeq ($(USE_SQLITE), 1)
+SQLITE_DEFINES = -DUSE_SQLITE
+SQLITE_LIBS = $(COMMON_PACKAGES_DIR)/sqlite/lib/libsqlite3.a -ldl -lpthread
+SQL_SOURCES = sqlqueryaction.cpp
+SQL_OBJECTS = sqlqueryaction.o
+else
+SQLITE_DEFINES =
+SQLITE_LIBS = 
+SQL_SOURCES =
+SQL_OBJECTS =
+endif
+
+USE_RSS = @USE_RSS@
+ifeq ($(USE_RSS), 1)
+RSS_DEFINES = -DUSE_RSS
+RSS_SOURCES = rssaction.cpp
+RSS_OBJECTS = rssaction.o
+else
+RSS_DEFINES =
+RSS_SOURCES =
+RSS_OBJECTS =
+endif
+
+
+USE_Z3950 = @USE_Z3950@
+ifeq ($(USE_Z3950), 1)
+Z3950_DEFS = -DUSE_Z3950
+Z3950_INCLUDES = -I$(Z3950_DIR)
+Z3950_LIBS = $(Z3950_DIR)/gsdlz3950.a $(RUNTIME_PACKAGES_DIR)/yaz/lib/libyaz.a
+else
+Z3950_DEFS =
+Z3950_INCLUDES = 
+Z3950_LIBS = 
+endif
+
+USE_APACHE_HTTPD=@USE_APACHE_HTTPD@
+#ifeq ($(USE_APACHE_HTTPD), 1)
+ifeq ($(USE_APACHE_HTTPD), "IGNORE_FOR_NOW")
+APACHE_OBJS = string_pool.o mod_gsdl.o
+
+APACHE_INSTDIR=$(GSDL_DIR)/apache-httpd/$(GSDLOS)
+APACHE_SRCLIBDIR=../../packages/apache-httpd/httpd-2.2.11/srclib
+
+APXS_CFLAGS=-I$(APACHE_INSTDIR)/include \
+  -I$(APACHE_SRCLIBDIR)/apr/include -I$(APACHE_SRCLIBDIR)/apr-util/include
+
+APXS_LDFLAGS= -L$(APACHE_INSTDIR)/lib \
+  -L$(APACHE_SRCLIBDIR)/apr/include -L$(APACHE_SRCLIBDIR)/apr-util/include
+
+APACHE_MODULE = mod_gsdl.so
+else
+APACHE_OBJS =
+APACHE_MODULE =
+endif
+
+# security is on by default
+# need to add special flag for compilation, that turns on experimental features: -std=gnu++0x
+USE_SECURITY = @USE_SECURITY@
+ifeq ($(USE_SECURITY), 1)
+SECURITY_INSTALLED = $(RUNTIME_PACKAGES_DIR)/security/installed
+SECURITY_INCLUDES = -I$(SECURITY_INSTALLED)/include -I$(SECURITY_INSTALLED)/include/esapi
+SECURITY_LIBS = -L $(SECURITY_INSTALLED)/lib -lesapi-c++ -lcryptopp
+SECURITY_DEFINES = -DUSE_SECURITY
+SECURITY_SOURCES = esapitools.cpp
+SECURITY_OBJECTS = esapitools.o
+SECURITY_CXXFLAGS = -std=gnu++0x
+else
+SECURITY_INSTALLED =
+SECURITY_INCLUDES =
+SECURITY_LIBS =
+SECURITY_DEFINES =
+SECURITY_SOURCES =
+SECURITY_OBJECTS =
+SECURITY_CXXFLAGS =
+endif
+
+
+# Extension support
+EXT_DEFINES =
+EXT_INCLUDES =
+EXT_LDFLAGS =
+EXT_LIBS =
+
+
+
+AR = ar
+CC = @CC@
+CFLAGS=@CFLAGS@ @ARCH_DEP_FLAGS@
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ $(SECURITY_CXXFLAGS) @ARCH_DEP_FLAGS@
+DEFS = @DEFS@ -DNZDL -DQUIET -DSHORT_SUFFIX -DPARADOCNUM -DHAVE_CONFIG_H $(FASTCGI_DEFS) $(RSS_DEFINES) $(GDBM_DEFINES) $(JDBM_DEFINES) $(SQLITE_DEFINES) $(Z3950_DEFS) $(EXT_DEFINES)
+INCLUDES = -I. -I$(GSDL_DIR) -I$(COMMON_DIR)/src/lib \
+        -I$(COLSERVR_DIR) -I$(PROTOCOL_DIR) \
+	$(MG_INCLUDES) $(MGPP_INCLUDES) \
+	$(SECURITY_INCLUDES) \
+        -I$(COMMON_PACKAGES_DIR)/expat/include $(FASTCGI_INCLUDES) $(GDBM_INCLUDES) $(Z3950_INCLUDES) $(EXT_INCLUDES)
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @ARCH_DEP_FLAGS@ $(EXT_LDFLAGS)
+LIBS = @LIBS@ $(GDBM_LIBS) \
+	$(COMMON_PACKAGES_DIR)/expat/lib/libexpat.a \
+	$(SECURITY_LIBS) \
+	$(ACCENTFOLD_LIBS) $(FASTCGI_LIBS) $(SQLITE_LIBS) $(Z3950_LIBS) $(EXT_LIBS)
+RANLIB = @RANLIB@
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+SOURCES = \
+	action.cpp \
+	argdb.cpp \
+	authenaction.cpp \
+	browseaction.cpp \
+	browseactiontools.cpp \
+	browserclass.cpp \
+	browsetoolsclass.cpp \
+	cgiargs.cpp \
+	cgiutils.cpp \
+	cgiwrapper.cpp \
+	collectoraction.cpp \
+	configaction.cpp \
+        converter.cpp \
+	datelistbrowserclass.cpp \
+	depositoraction.cpp \
+	documentaction.cpp \
+	dynamicclassifieraction.cpp \
+	extlinkaction.cpp \
+	formattools.cpp \
+	formatconverter.cpp \
+	gtiaction.cpp \
+	highlighttext.cpp \
+	historydb.cpp \
+	hlistbrowserclass.cpp \
+	htmlbrowserclass.cpp \
+	htmlutils.cpp \
+	invbrowserclass.cpp \
+	librarymain.cpp \
+	maincfg.cpp \
+	pageaction.cpp \
+	pagedbrowserclass.cpp \
+	$(MGPP_SOURCES) \
+	phindbrowserclass.cpp \
+	pingaction.cpp \
+	ispersistentaction.cpp \
+	basequeryaction.cpp \
+	queryaction.cpp \
+	$(SECURITY_SOURCES) \
+	$(SQL_SOURCES) \
+	querytools.cpp \
+	receptionist.cpp \
+	$(RSS_SOURCES) \
+	statusaction.cpp \
+	securitytools.cpp \
+	summarise.cpp \
+	tipaction.cpp \
+	userdb.cpp \
+	usersaction.cpp \
+	vlistbrowserclass.cpp \
+	wizardaction.cpp
+
+OBJECTS = \
+	action.o \
+	argdb.o \
+	authenaction.o \
+	browseaction.o \
+	browseactiontools.o \
+	browserclass.o \
+	browsetoolsclass.o \
+	cgiargs.o \
+	cgiutils.o \
+	cgiwrapper.o \
+	collectoraction.o \
+	configaction.o \
+        converter.o \
+	datelistbrowserclass.o \
+	depositoraction.o \
+	documentaction.o \
+	dynamicclassifieraction.o \
+	extlinkaction.o \
+	formattools.o \
+	gtiaction.o \
+	highlighttext.o \
+	historydb.o \
+	hlistbrowserclass.o \
+	htmlbrowserclass.o \
+	htmlutils.o \
+	invbrowserclass.o \
+	librarymain.o \
+	maincfg.o \
+	pageaction.o \
+	pagedbrowserclass.o \
+	$(MGPP_OBJECTS) \
+	phindbrowserclass.o \
+	pingaction.o \
+	ispersistentaction.o \
+	basequeryaction.o \
+	queryaction.o \
+	$(SECURITY_OBJECTS) \
+	$(SQL_OBJECTS) \
+	querytools.o \
+	receptionist.o \
+	$(RSS_OBJECTS) \
+	statusaction.o \
+	securitytools.o \
+	summarise.o \
+	tipaction.o \
+	userdb.o \
+	usersaction.o \
+	vlistbrowserclass.o \
+	wizardaction.o 
+
+CONVERTER_OBJECTS = \
+	cgiargs.o \
+	cgiutils.o \
+	formattools.o \
+	formatconverter.o \
+	summarise.o
+
+LIBRARY = gsdlrecpt.a
+
+GSDL_LIBS = \
+	$(PROTOCOL_DIR)/gsdlprotocol.a \
+	$(COLSERVR_DIR)/gsdlcolservr.a \
+	$(MG_INDEXERS_LIBS) \
+	$(MGPP_INDEXERS_LIBS) \
+	$(COMMON_DIR)/src/lib/gsdllib.a
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(GSDL_LIBS)
+
+EXECUTABLE = library.cgi
+
+
+# Default target: make both gsdlrecpt.a and the library executable
+all: $(LIBRARY) $(EXECUTABLE) $(APACHE_MODULE) formatconverter
+
+formatconverter: $(CONVERTER_OBJECTS)
+	$(CXXLINK) $(CONVERTER_OBJECTS) $(COMMON_DIR)/src/lib/gsdllib.a $(PROTOCOL_DIR)/gsdlprotocol.a $(COLSERVR_DIR)/gsdlcolservr.a
+
+gsdlrecpt.a: $(OBJECTS)
+	rm -f $(LIBRARY)
+	$(AR) cru $(LIBRARY) $(OBJECTS)
+	$(RANLIB) $(LIBRARY)
+
+$(EXECUTABLE): $(EXECUTABLE_OBJECTS) $(GSDL_LIBS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+mod_gsdl.o: mod_gsdl.cpp
+	$(CXX) -c  $(CXXFLAGS) $(DEFS) $(INCLUDES) -D_APACHE_MOD=2 -fPIC $(APXS_CFLAGS) -Wall -o $@ $< 
+
+mod_gsdl.so: $(APACHE_OBJS) $(LIBRARY)
+	$(CXX) -fPIC -shared -o $@ $(APACHE_OBJS) $(LIBRARY) $(GSDL_LIBS) $(LIBS)
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+install: $(EXECUTABLE)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/cgi-bin/$(GSDLOS)$(GSDLARCH)
+#ifeq ($(USE_APACHE_HTTPD), 1)
+ifeq ($(USE_APACHE_HTTPD), "IGNORE_FOR_NOW")
+	$(GSDL_DIR)/apache-httpd/$(GSDLOS)/bin/apxs  -i -n gsdl mod_gsdl.so
+endif
+
+clean:
+	rm -f $(OBJECTS) $(LIBRARY) $(EXECUTABLE) $(APACHE_MODULE) $(APACHE_OBJS)
+
+distclean:
+	rm -f $(OBJECTS) $(LIBRARY) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/TestMainWin32.cpp
===================================================================
--- main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/TestMainWin32.cpp	(revision 28886)
+++ main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/TestMainWin32.cpp	(revision 28886)
@@ -0,0 +1,142 @@
+/**
+* OWASP Enterprise Security API (ESAPI)
+*
+* This file is part of the Open Web Application Security Project (OWASP)
+* Enterprise Security API (ESAPI) project. For details, please see
+* http://www.owasp.org/index.php/ESAPI.
+*
+* Copyright (c) 2011 - The OWASP Foundation
+*
+* @author Kevin Wall, kevin.w.wall@gmail.com
+* @author Jeffrey Walton, noloader@gmail.com
+*
+*/
+
+/////////////////////////////////////////////////////////////
+// Used by Windows. For Linux, Boost::Test provides main() //
+/////////////////////////////////////////////////////////////
+
+#include "EsapiCommon.h"
+using esapi::String;
+using esapi::StringArray;
+using esapi::StringStream;
+using esapi::NarrowString;
+using esapi::WideString;
+
+#include "errors/IllegalArgumentException.h"
+using esapi::IllegalArgumentException;
+
+#include "errors/EncryptionException.h"
+using esapi::EncryptionException;
+
+#include "errors/NoSuchAlgorithmException.h"
+using esapi::NoSuchAlgorithmException;
+
+#include "crypto/SecureRandom.h"
+using esapi::SecureRandom;
+
+#include "crypto/RandomPool.h"
+using esapi::RandomPool;
+
+#include "crypto/KeyGenerator.h"
+using esapi::KeyGenerator;
+
+#include "crypto/PlainText.h"
+using esapi::PlainText;
+
+#include "crypto/CipherText.h"
+using esapi::CipherText;
+
+#include "crypto/SecretKey.h"
+using esapi::SecretKey;
+
+#include "crypto/MessageDigest.h"
+using esapi::MessageDigest;
+
+#include "util/SecureArray.h"
+using esapi::SecureByteArray;
+using esapi::SecureIntArray;
+
+#include "util/SecureString.h"
+using esapi::SecureString;
+
+#include "DummyConfiguration.h"
+using esapi::DummyConfiguration;
+
+#include "reference/DefaultEncryptor.h"
+using esapi::DefaultEncryptor;
+
+#include "util/TextConvert.h"
+using esapi::TextConvert;
+
+#include "util/AlgorithmName.h"
+using esapi::AlgorithmName;
+
+#include "crypto/Cipher.h"
+using esapi::Cipher;
+
+#include "codecs/HTMLEntityCodec.h"
+using esapi::HTMLEntityCodec;
+
+#include <iostream>
+using std::cerr;
+using std::cout;
+using std::endl;
+
+#include <string>
+using std::string;
+
+#include <cstddef>
+#include <memory>
+#include <string>
+
+static const WideString wide = L"\u9aa8";
+static const NarrowString narrow("\xe9\xaa\xa8");
+
+int main(int, char**)
+{
+  // Positive test - uses the overload which takes a 'Char' character
+  HTMLEntityCodec codec;
+
+  struct KnownAnswer
+  {
+    int ch;
+    NarrowString str;
+  };
+
+  // First and last 4 from entity table
+  const KnownAnswer tests[] = {
+    //{ 34, "&quot;" },
+    //{ 38, "&amp;" },
+    //{ 60, "&lt;" },
+    //{ 62, "&gt;" },
+
+    { 252, "&uuml;" },
+    { 253, "&yacute;" },
+    { 254, "&thorn;" },
+    { 255, "&yuml;" }
+  };
+
+  StringArray immune;
+
+  for( unsigned int i = 0; i < COUNTOF(tests); i++ )
+  {
+    const NarrowString utf8 = TextConvert::WideToNarrow(WideString(1,tests[i].ch));
+    const NarrowString encoded = codec.encodeCharacter( immune, utf8 );
+    const NarrowString expected = tests[i].str;
+
+    StringStream oss;
+    oss << "Failed to encode character. Expected ";
+    oss << "'" << expected << "', got ";
+    oss << "'" << encoded << "'";
+
+    if(!(encoded == expected)) {
+      cout << oss.str() << endl;
+    } else {
+      cout << "** WORKED: " << oss.str() << endl;
+    }
+
+  }
+
+	return 0;
+}
Index: main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/configure.in
===================================================================
--- main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/configure.in	(revision 28886)
+++ main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/configure.in	(revision 28886)
@@ -0,0 +1,624 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl Use autoconf-2.59 or later... it might not work anymore with
+dnl the older 2.1x versions - jrm21 12/2004
+AC_INIT()
+AC_CONFIG_HEADER(config.h)
+
+PACKAGE=gsdl
+VERSION=2.x-svn
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+
+dnl
+dnl Set use of fast cgi
+dnl
+USE_FASTCGI=0
+if test USE_FASTCGI = 1; then
+AC_DEFINE(USE_FASTCGI)
+AC_SUBST(USE_FASTCGI)
+fi
+
+dnl
+dnl Set use of langaction
+dnl
+dnl USE_LANGACTION=0
+if test USE_LANGACTION = 1; then
+AC_DEFINE(USE_LANGACTION)
+AC_SUBST(USE_LANGACTION)
+fi
+
+dnl
+dnl Set use of corba
+dnl
+AC_ARG_ENABLE(corba, [  --enable-corba          Enable CORBA support], USE_CORBA=$enableval, USE_CORBA=no)
+if test $USE_CORBA = "yes" -o $USE_CORBA = "1" ; then
+  USE_CORBA=1
+  AC_DEFINE(USE_CORBA,[])
+else
+  USE_CORBA=0
+fi
+AC_SUBST(USE_CORBA)
+
+AC_ARG_WITH(micodir, [  --with-micodir          Use installed MICO directory], MICO_DIR=$withval, MICO_DIR="default")
+AC_DEFINE_UNQUOTED(MICO_DIR, "$MICO_DIR")
+AC_SUBST(MICO_DIR)
+
+dnl
+dnl Disable all Java compilation
+dnl
+AC_ARG_ENABLE(java, [  --disable-java          Disable Java compilation], ENABLE_JAVA=$enableval, ENABLE_JAVA=yes)
+if test $ENABLE_JAVA = "yes" -o $ENABLE_JAVA = "1" ; then
+  ENABLE_JAVA=1
+  if test "x$JAVA_HOME" != "x" ; then
+    echo "Detected JAVA_HOME is set, however this will not be used during compilation"
+    echo "To control the version of 'javac' and 'java' set environment variables JAVAC"
+    echo "and JAVA respectively"
+    export JAVA_HOME=
+  fi
+else
+  ENABLE_JAVA=0
+fi
+AC_SUBST(ENABLE_JAVA)
+
+dnl
+dnl Set use of z39.50
+dnl
+AC_ARG_ENABLE(z3950, [  --enable-z3950          Enable Z39.50 client support], USE_Z3950=$enableval, USE_Z3950=no)
+if test $USE_Z3950 = "yes" -o $USE_Z3950 = "1" ; then
+  USE_Z3950=1
+  AC_DEFINE(USE_Z3950,[])
+else
+  USE_Z3950=0
+fi
+AC_SUBST(USE_Z3950)
+
+dnl
+dnl Set use of yaz - now compiled by default even when z3950 support not required
+dnl
+AC_ARG_ENABLE(yaz, [  --disable-yaz           Disable YAZ compilation], USE_YAZ=$enableval, USE_YAZ=yes)
+if test $USE_YAZ = "yes" -o $USE_YAZ = "1" ; then
+  USE_YAZ=1
+  AC_DEFINE(USE_YAZ,[])
+else
+  USE_YAZ=0
+fi
+AC_SUBST(USE_YAZ)
+
+dnl
+dnl Set use of wvware (enabled by default)
+dnl
+AC_ARG_ENABLE(wvware, [  --disable-wvware          Disable wvWare compilation], USE_WVWARE=$enableval, USE_WVWARE=yes)
+if test $USE_WVWARE = "yes" -o $USE_WVWARE = "1" ; then
+  USE_WVWARE=1
+  AC_DEFINE(USE_WVWARE,[])
+else
+  USE_WVWARE=0
+fi
+AC_SUBST(USE_WVWARE)
+
+dnl
+dnl Set use of JDBM (enabled by default)
+dnl
+AC_ARG_ENABLE(jdbm, [  --disable-jdbm          Disable JDBM compilation], USE_JDBM=$enableval, USE_JDBM=yes)
+if test $ENABLE_JAVA = "1" -a \( $USE_JDBM = "yes" -o $USE_JDBM = "1" \) ; then
+  USE_JDBM=1
+  AC_DEFINE(USE_JDBM,[])
+else
+  USE_JDBM=0
+fi
+AC_SUBST(USE_JDBM)
+
+dnl
+dnl Set use of GDBM (enabled by default)
+dnl
+AC_ARG_ENABLE(gdbm, [  --disable-gdbm          Disable GDBM compilation], USE_GDBM=$enableval, USE_GDBM=yes)
+if test $USE_GDBM = "yes" -o $USE_GDBM = "1" ; then
+  USE_GDBM=1
+  AC_DEFINE(USE_GDBM,[])
+else
+  USE_GDBM=0
+fi
+AC_SUBST(USE_GDBM)
+
+dnl
+dnl Set use of SECURITY package (enabled by default)
+dnl
+AC_ARG_ENABLE(security, [  --disable-security        Disable SECURITY compilation], USE_SECURITY=$enableval, USE_SECURITY=yes)
+if test $USE_SECURITY = "yes" -o $USE_SECURITY = "1" ; then
+  USE_SECURITY=1
+  AC_DEFINE(USE_SECURITY,[])
+else
+  USE_SECURITY=0
+fi
+AC_SUBST(USE_SECURITY)
+
+dnl 
+dnl disable compilation of accent folding stuff for mgpp (and one day mg)
+dnl
+AC_ARG_ENABLE(accentfold, [  --disable-accentfold    Disable Accent Folding for MGPP], ENABLE_ACCENTFOLD=$enableval, ENABLE_ACCENTFOLD=yes)
+if test $ENABLE_ACCENTFOLD = "yes" -o $ENABLE_ACCENTFOLD = "1" ; then
+  ENABLE_ACCENTFOLD=1
+  AC_DEFINE(ENABLE_ACCENTFOLD,[])
+else
+  ENABLE_ACCENTFOLD=0
+fi
+AC_SUBST(ENABLE_ACCENTFOLD)
+
+dnl
+dnl Set use of SQLite (enabled by default)
+dnl
+AC_ARG_ENABLE(sqlite, [  --disable-sqlite        Disable SQLite support], USE_SQLITE=$enableval, USE_SQLITE=yes)
+if test $USE_SQLITE = "yes" -o $USE_SQLITE = "1" ; then
+  USE_SQLITE=1
+  AC_DEFINE(USE_SQLITE,[])
+else
+  USE_SQLITE=0
+fi
+AC_SUBST(USE_SQLITE)
+
+dnl
+dnl Set use of RSS (enabled by default)
+dnl
+AC_ARG_ENABLE(rss, [  --disable-rss        Disable RSS support], USE_RSS=$enableval, USE_RSS=yes)
+if test $USE_RSS = "yes" -o $USE_RSS = "1" ; then
+  USE_RSS=1
+  AC_DEFINE(USE_RSS,[])
+else
+  USE_RSS=0
+fi
+AC_SUBST(USE_RSS)
+
+
+dnl
+dnl Set use of Apache httpd (disabled by default)
+dnl
+if test -d runtime-src; then
+   AC_ARG_ENABLE(apache-httpd, [  --enable-apache-httpd   Enable Apache httpd support], USE_APACHE_HTTPD=$enableval, USE_APACHE_HTTPD=no)
+   if test $USE_APACHE_HTTPD = "yes" -o $USE_APACHE_HTTPD = "1" ; then
+     USE_APACHE_HTTPD=1
+     AC_DEFINE(USE_APACHE_HTTPD,[])
+   else
+     USE_APACHE_HTTPD=0
+   fi
+   AC_SUBST(USE_APACHE_HTTPD)
+fi
+
+dnl
+dnl Set compilation of JNI parts of MG and MGPP indexers (disabled by default, which is GS2's default behaviour)
+dnl
+AC_ARG_ENABLE(jni, [  --enable-jni            Enable JNI compilation], ENABLE_JNI=$enableval, ENABLE_JNI=no)
+if test $ENABLE_JAVA = "1" -a \( $ENABLE_JNI = "yes" -o $ENABLE_JNI = "1" \) ; then
+  ENABLE_JNI=1
+  AC_DEFINE(ENABLE_JNI,[])
+else
+  ENABLE_JNI=0
+fi
+AC_SUBST(ENABLE_JNI)
+
+dnl
+dnl Set compilation of MG (enabled by default)
+dnl
+AC_ARG_ENABLE(mg, [  --disable-mg            Disable MG compilation], ENABLE_MG=$enableval, ENABLE_MG=yes)
+if test $ENABLE_MG = "yes" -o $ENABLE_MG = "1" ; then
+  ENABLE_MG=1
+  AC_DEFINE(ENABLE_MG,[])
+ else
+  ENABLE_MG=0
+ fi
+AC_SUBST(ENABLE_MG)
+
+
+dnl
+dnl Set compilation of MGPP (enabled by default)
+dnl
+AC_ARG_ENABLE(mgpp, [  --disable-mgpp          Disable MGPP compilation], ENABLE_MGPP=$enableval, ENABLE_MGPP=yes)
+if test $ENABLE_MGPP = "yes" -o $ENABLE_MGPP = "1" ; then
+  ENABLE_MGPP=1
+  AC_DEFINE(ENABLE_MGPP,[])
+else
+  ENABLE_MGPP=0
+fi
+AC_SUBST(ENABLE_MGPP)
+
+dnl
+dnl Set compilation of lucene (enabled by default)
+dnl
+AC_ARG_ENABLE(lucene, [  --disable-lucene        Disable Lucene compilation], ENABLE_LUCENE=$enableval, ENABLE_LUCENE=yes)
+if test $ENABLE_JAVA = "1" -a \( $ENABLE_LUCENE = "yes" -o $ENABLE_LUCENE = "1" \) ; then
+  ENABLE_LUCENE=1
+  AC_DEFINE(ENABLE_LUCENE,[])
+else
+  ENABLE_LUCENE=0
+fi
+AC_SUBST(ENABLE_LUCENE)
+
+
+dnl
+dnl Set compilation and/or sourcing of gnome-lib extension (disabled by default)
+dnl
+AC_ARG_ENABLE(gnome-lib-ext, [  --enable-gnome-lib-ext  Enable the gnome-lib extension], ENABLE_GNOMELIB_EXT=1, ENABLE_GNOMELIB_EXT=0)
+if test -d ext/gnome-lib ; then
+   AC_DEFINE(ENABLE_GNOMELIB_EXT, $ENABLE_GNOMELIB_EXT)
+elif test -f ext/gnome-lib-minimal/devel.bash ; then
+   AC_DEFINE(ENABLE_GNOMELIB_EXT, $ENABLE_GNOMELIB_EXT)
+else
+   # Running `svn` returns 127 if no svn is installed. It returns 1 if svn is installed, 
+   # since it suggests running svn --help. It returns 0 if running `svn --version`
+
+   if test $ENABLE_GNOMELIB_EXT = 1; then
+      svn --version
+      result=$?
+      if test $result = 0; then
+      	 cd ext
+	 svn co http://svn.greenstone.org/gs2-extensions/gnome-lib/trunk/src gnome-lib
+	 cd ..
+	 AC_DEFINE(ENABLE_GNOMELIB_EXT, 1)
+      else
+         echo "**** WARNING: No gnome-lib or gnome-lib-minimal(/devel.bash) in gs2build/ext folder. Unable to check out gnome-lib. Disabling gnome-lib-ext."
+	 AC_DEFINE(ENABLE_GNOMELIB_EXT, 0)
+      fi
+   fi
+fi
+AC_SUBST(ENABLE_GNOMELIB_EXT)
+
+
+dnl Checks for programs.
+LDFLAGS=$LDFLAGS
+AC_SUBST(LDFLAGS)
+dnl only set CFLAGS if not already set in environment
+if test -z "$CFLAGS"; then
+CFLAGS=-O2
+fi
+AC_SUBST(CFLAGS)
+
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_AWK
+AC_PROG_YACC
+dnl get $target_cpu, $target_vendor, and $target_os
+dnl (as well as host_*)
+AC_CANONICAL_SYSTEM
+dnl do we actually want this? It adds a prefix based on host, system etc
+dnl AC_ARG_PROGRAM
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+AC_MSG_CHECKING(to see if architecture is 64-bit)
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  AC_MSG_RESULT(yes)
+  if test -z "$ARCH_DEP_FLAGS" ; then
+    ARCH_DEP_FLAGS=-fPIC
+  fi
+else
+  AC_MSG_RESULT(no)
+  if test -z "$ARCH_DEP_FLAGS" ; then
+    ARCH_DEP_FLAGS=
+  fi
+fi
+
+export ARCH_DEP_FLAGS
+AC_SUBST(ARCH_DEP_FLAGS)
+
+
+#moved CORBA MICO directory test to get version of MICO
+if test $USE_CORBA = 1; then
+
+if test $MICO_DIR = "default"; then
+#do something
+MICO_INC="-I packages/mico/mico/include"
+else
+#build the micotest program
+MICO_INC= ""
+if test $MICO_DIR != yes; then
+MICO_INC="-I $MICO_DIR"
+fi
+fi
+
+#get MICO_VER value
+sh -c "$CC -c micotest.cpp -o micotest.o $MICO_INC 2>&1" > /dev/null
+sh -c "$CC -o micotest micotest.o -lstdc++ 2>&1" > /dev/null
+MICO_VER=`./micotest` || MICO_VER=2.3.5
+sh -c "rm micotest"
+sh -c "rm micotest.o"
+
+#do test of MICO_VER
+if test MICO_VER != 0; then
+AC_DEFINE(MICO_VER)
+AC_SUBST(MICO_VER)
+fi
+#end USE_CORBA test
+fi
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_AIX
+AC_ISC_POSIX
+AC_MINIX
+fp_C_PROTOTYPES
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl --- This should be in the stdc checking -----------------
+if test "$ac_cv_prog_cc_stdc" = '-Xc'; then
+dnl The Pyramids running SMP_DC.OSx on MIPS r3000 chips with
+dnl /usr/opt/cc3.11/bin/cc treat -Xc as full ANSI mode - no POSIX or
+dnl XOPEN extensions (like popen).
+dnl Unfortunately -D_{XOPEN,POSIX}_SOURCE can't provide all that mg
+dnl needs. So drop back to -Xa
+AC_TRY_COMPILE(
+[#include <stdio.h>
+], [ FILE *rubbish = popen("yes", "r"); ],,
+[CC="`echo $CC | sed 's/-Xc/-Xa/'`"    ac_cv_prog_cc_stdc='-Xa'])
+fi
+dnl ----------------------
+
+
+dnl Checks for libraries.
+dnl check for -lg:
+AC_HAVE_LIBRARY(g)
+dnl check for -lm:
+AC_HAVE_LIBRARY(m)
+dnl check for -lcrypt:
+AC_HAVE_LIBRARY(crypt)
+#if test $ENABLE_ACCENTFOLD = 1; then
+#AC_HAVE_LIBRARY(iconv)
+#fi
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h limits.h sys/time.h unistd.h crypt.h string.h memory.h sys/procfs.h sys/stat.h)
+AC_EGREP_HEADER(fread, stdio.h, AC_DEFINE(HAVE_FREAD_DECL))
+AC_EGREP_HEADER(fgetc, stdio.h, AC_DEFINE(HAVE_FGETC_DECL))
+AC_EGREP_HEADER(pr_brksize, sys/procfs.h, AC_DEFINE(HAVE_PR_BRKSIZE))
+
+dnl Checks for library functions.
+AC_FUNC_ALLOCA
+AC_PROG_GCC_TRADITIONAL
+AC_TYPE_SIGNAL
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(ftime select strftime strtol getrusage times mallinfo setbuffer getpagesize strerror)
+AC_REPLACE_FUNCS(ftruncate strstr strcasecmp)
+
+dnl see if gettext is in libc. (try the textdomain() function).
+AC_CHECK_FUNC(textdomain, AC_DEFINE(ENABLE_NLS ,1) )
+
+# *** Custom checking (based on GNU tar configure.in) ***
+# ---------------------------------------------------------------------------
+AC_MSG_CHECKING(for HP-UX needing gmalloc)
+if test "`(uname -s) 2> /dev/null`" = 'HP-UX'; then
+  AC_MSG_RESULT(yes)
+  AC_LIBOBJ([gmalloc])
+  AC_DEFINE(HAVE_VALLOC)
+else
+  AC_MSG_RESULT(no)
+  AC_CHECK_FUNCS(valloc)
+fi
+
+# we cannot generate static libraries under Darwin
+AC_MSG_CHECKING(for Apple MacOS X/Darwin)
+if test "`(uname -s) 2> /dev/null`" = 'Darwin'; then
+  AC_MSG_RESULT(yes)
+  STATIC=""
+else
+  AC_MSG_RESULT(no)
+  STATIC="-static "
+fi
+AC_SUBST(STATIC)
+
+fp_WITH_DMALLOC
+fp_WITH_REGEX
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc])
+  AC_LIBOBJ([error])
+fi
+
+
+# ---------------------------------------------------------------------------
+
+dnl
+dnl Switch into C++
+dnl
+AC_LANG_CPLUSPLUS
+
+dnl
+dnl Now check that Perl is actually around, and can be found
+dnl
+AC_MSG_CHECKING(that Perl 5 is available)
+success="no"
+pl_path="$PATH"
+IFS="${IFS=   }"; pl_save_ifs="$IFS"; IFS=":"
+for pl_dir in $pl_path; do
+  test -z "$pl_dir" && pl_dir=.
+  if test -x $pl_dir/perl; then
+    success="yes"
+    break
+  fi
+done
+IFS="$pl_save_ifs"
+
+dnl
+dnl Perl actually can be run; now we see if it is version 5 by
+dnl running a sample script (which returns a "clean" version number
+dnl and then tests the result using expr.  If perl errors in some
+dnl way (eg. broken Perl executable, missing script), we set a failure
+dnl value ("0") and then proceed as best we can
+dnl
+if test $success = "yes"; then
+try=`perl configtest.pl` || try="0"
+try=`expr $try \> 5.000`
+if test $try = "1"; then
+AC_MSG_RESULT("yes")
+else
+success="no"
+fi
+fi
+
+if test $success = "no"; then
+AC_MSG_RESULT("no")
+AC_MSG_ERROR("Perl 5 not available - cannot install")
+fi
+
+dnl
+dnl Check if the STL library has any known faults;
+dnl In GCC 2.7.2.x series, some STL library headers are missing
+dnl a file called "new" which is referred to by other headers
+dnl (eg. vector/vector.h); if this applies, then all use of the
+dnl STL will cause a compile fail, so we'd better let the user
+dnl know now, before things really go wrong!
+dnl
+success=no
+AC_MSG_CHECKING("whether STL library has known faults")
+
+dnl - first shot, try simple good old vector on its own
+AC_TRY_COMPILE(
+[#include <vector>
+], 
+[],
+success=yes,
+)
+
+dnl - try using the .h equivalent
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <vector.h>
+], 
+[],
+success="yes",
+)
+fi
+
+dnl - now try for the objectspace headers
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <ospace\\std\\vector>
+], 
+[],
+success="yes",
+)
+fi
+
+if test $success = yes; then
+AC_MSG_RESULT("no")
+else
+AC_MSG_RESULT("yes")
+AC_MSG_ERROR("STL Broken - Obtain newer version of GNU C Compiler")
+fi
+
+gsdlos=`uname | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+# check for running bash under cygwin
+ if test "`echo $gsdlos | sed 's/cygwin//'`" != "$gsdlos" ;
+ then
+  gsdlos=windows
+ fi
+AC_SUBST(gsdlos)
+
+# check for endianness
+AC_C_BIGENDIAN
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc.o])
+  AC_LIBOBJ([error])
+fi
+
+# ---------------------------------------------------------------------------
+
+dnl
+dnl Locate all children of the modules folder
+dnl
+moduleDirs=""
+MODULEDIRS=""
+if test -d modules ; then
+  for x in `find modules -mindepth 1 -maxdepth 2`; do
+    if test -d "$x"; then
+      d="$x/Makefile.in"
+      if test -e "$d"; then
+  dnl      echo $d
+        moduleDirs="$moduleDirs $x/Makefile"
+        MODULEDIRS="$MODULEDIRS $x"
+      fi
+    fi
+  done
+  echo "Making $moduleDirs in modules directory"
+  AC_SUBST(MODULEDIRS)
+fi
+
+
+#----------------------------------------------------------------------------
+# GS2 uses this configure to set up gnome-lib env, GS3 uses the one in gs2build/build-src
+# For gnome-lib-minimal need to source its ./devel.bash before wvware can even be configured
+# For a gnome-lib that's already compiled, don't need to its source ./devel.bash to configure wvware
+# If a gnome-lib is not yet compiled, we compile it first with CASCADE-MAKE.sh
+# Need to make sure that the gnome-lib-minimal is not the cut-down gnome-lib-minimal (which contains
+# only the linux/lib subfolder) that's included with linux and mac binaries, because we can't compile 
+# wvware with the cut-down one, only run wvware with it. The test for the cut-down version is that 
+# it does not contain devel.bash.
+
+if test -f ext/gnome-lib-minimal/devel.bash; then
+   echo "*** gnome-lib (minimal) detected. Sourcing the gnomelib env for configuring wvware..."
+   cd ext/gnome-lib-minimal
+   source ./devel.bash
+   cd ../..
+elif test -d ext/gnome-lib; then
+  if test -d ext/gnome-lib/$gsdlos; then
+    echo "*** gnome-lib already compiled up in ext/gnome-lib/$gsdlos"
+    echo "*** Sourcing the gnomelib env for configuring wvware for GS2 (although it's not necessary)..."
+    cd ext/gnome-lib
+    source ./devel.bash
+    cd ../..
+  else
+    echo "*** Compiling up gnome-lib..."
+    cd ext/gnome-lib
+    ./CASCADE-MAKE.sh
+    gnomestatus=$?
+    if test $gnomestatus != 0; then
+       echo "****************************************"
+       echo "@@@ Failed to compile up gnomelib successfully"
+       echo "****************************************"
+       exit -1
+    fi
+    cd ../..
+  fi 
+fi
+
+# ---------------------------------------------------------------------------
+dnl for Darwin, as our packages don't (yet) correctly guess our system type.
+dnl not needed any more?
+dnl ac_configure_args="$ac_configure_args --build=$build --target=$target"
+
+# indexers needs a bindir option to get the binaries into the right place
+gsdlprefix=`pwd`
+ac_configure_args="$ac_configure_args --bindir=$gsdlprefix/bin/$gsdlos --libdir=$gsdlprefix/lib/$gsdlos"
+AC_CONFIG_SUBDIRS(common-src)
+AC_CONFIG_SUBDIRS(build-src)
+
+# the list of folders in the src folder
+srclist="common-src/Makefile \
+         build-src/Makefile"
+
+if test -d runtime-src; then
+   AC_CONFIG_SUBDIRS(runtime-src)
+   srclist="$srclist \
+         runtime-src/Makefile"
+fi
+
+AC_OUTPUT(Makefile $srclist $moduleDirs)
+
+
Index: main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/runtime-src/configure.in
===================================================================
--- main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/runtime-src/configure.in	(revision 28886)
+++ main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/runtime-src/configure.in	(revision 28886)
@@ -0,0 +1,516 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl Use autoconf-2.59 or later... it might not work anymore with
+dnl the older 2.1x versions - jrm21 12/2004
+AC_INIT()
+AC_CONFIG_HEADER(config.h)
+
+
+
+PACKAGE=gsdl
+VERSION=2.x-svn
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+dnl
+dnl Set use of fast cgi
+dnl
+USE_FASTCGI=0
+if test USE_FASTCGI = 1; then
+AC_DEFINE(USE_FASTCGI)
+AC_SUBST(USE_FASTCGI)
+fi
+
+dnl
+dnl Set use of langaction
+dnl
+dnl USE_LANGACTION=0
+if test USE_LANGACTION = 1; then
+AC_DEFINE(USE_LANGACTION)
+AC_SUBST(USE_LANGACTION)
+fi
+
+dnl
+dnl Set use of corba
+dnl
+AC_ARG_ENABLE(corba, [  --enable-corba          Enable CORBA support], USE_CORBA=$enableval, USE_CORBA=no)
+if test $USE_CORBA = "yes" -o $USE_CORBA = "1" ; then
+  USE_CORBA=1
+  AC_DEFINE(USE_CORBA,[])
+else
+  USE_CORBA=0
+fi
+AC_SUBST(USE_CORBA)
+
+AC_ARG_WITH(micodir, [  --with-micodir          Use installed MICO directory], MICO_DIR=$withval, MICO_DIR="default")
+AC_DEFINE_UNQUOTED(MICO_DIR, "$MICO_DIR")
+AC_SUBST(MICO_DIR)
+
+dnl
+dnl Set use of z39.50
+dnl
+AC_ARG_ENABLE(z3950, [  --enable-z3950          Enable Z39.50 client support], USE_Z3950=$enableval, USE_Z3950=no)
+if test $USE_Z3950 = "yes" -o $USE_Z3950 = "1" ; then
+  USE_Z3950=1
+  AC_DEFINE(USE_Z3950,[])
+else
+  USE_Z3950=0
+fi
+AC_SUBST(USE_Z3950)
+
+dnl
+dnl Set use of yaz - now compiled by default even when z3950 support not required
+dnl
+AC_ARG_ENABLE(yaz, [  --disable-yaz           Disable YAZ compilation], USE_YAZ=$enableval, USE_YAZ=yes)
+if test $USE_YAZ = "yes" -o $USE_YAZ = "1" ; then
+  USE_YAZ=1
+  AC_DEFINE(USE_YAZ,[])
+else
+  USE_YAZ=0
+fi
+AC_SUBST(USE_YAZ)
+
+dnl
+dnl Disable all Java compilation
+dnl
+AC_ARG_ENABLE(java, [  --disable-java          Disable Java compilation], ENABLE_JAVA=$enableval, ENABLE_JAVA=yes)
+if test $ENABLE_JAVA = "yes" -o $ENABLE_JAVA = "1" ; then
+  ENABLE_JAVA=1
+  if test "x$JAVA_HOME" != "x" ; then
+    echo "Detected JAVA_HOME is set, however this will not be used during compilation"
+    echo "To control the version of 'javac' and 'java' set environment variables JAVAC"
+    echo "and JAVA respectively"
+    export JAVA_HOME=
+  fi
+else
+  ENABLE_JAVA=0
+fi
+AC_SUBST(ENABLE_JAVA)
+
+dnl
+dnl Set use of JDBM (enabled by default)
+dnl
+AC_ARG_ENABLE(jdbm, [  --disable-jdbm        Disable JDBM compilation], USE_JDBM=$enableval, USE_JDBM=yes)
+if test $ENABLE_JAVA = "1" -a \( $USE_JDBM = "yes" -o $USE_JDBM = "1" \) ; then
+  USE_JDBM=1
+  AC_DEFINE(USE_JDBM,[])
+else
+  USE_JDBM=0
+fi
+AC_SUBST(USE_JDBM)
+
+dnl
+dnl Set use of GDBM (enabled by default)
+dnl
+AC_ARG_ENABLE(gdbm, [  --disable-gdbm        Disable GDBM compilation], USE_GDBM=$enableval, USE_GDBM=yes)
+if test $USE_GDBM = "yes" -o $USE_GDBM = "1" ; then
+  USE_GDBM=1
+  AC_DEFINE(USE_GDBM,[])
+else
+  USE_GDBM=0
+fi
+AC_SUBST(USE_GDBM)
+
+dnl
+dnl Set use of SECURITY package (enabled by default)
+dnl
+AC_ARG_ENABLE(security, [  --disable-security        Disable SECURITY compilation], USE_SECURITY=$enableval, USE_SECURITY=yes)
+if test $USE_SECURITY = "yes" -o $USE_SECURITY = "1" ; then
+  USE_SECURITY=1
+  AC_DEFINE(USE_SECURITY,[])
+else
+  USE_SECURITY=0
+fi
+AC_SUBST(USE_SECURITY)
+
+dnl 
+dnl disable compilation of accent folding stuff for mgpp (and one day mg)
+dnl
+AC_ARG_ENABLE(accentfold, [  --disable-accentfold    Disable Accent Folding for MGPP], ENABLE_ACCENTFOLD=$enableval, ENABLE_ACCENTFOLD=yes)
+if test $ENABLE_ACCENTFOLD = "yes" -o $ENABLE_ACCENTFOLD = "1" ; then
+  ENABLE_ACCENTFOLD=1
+  AC_DEFINE(ENABLE_ACCENTFOLD,[])
+else
+  ENABLE_ACCENTFOLD=0
+fi
+AC_SUBST(ENABLE_ACCENTFOLD)
+
+dnl
+dnl Set use of SQLite (enabled by default)
+dnl
+AC_ARG_ENABLE(sqlite, [  --disable-sqlite        Disable SQLite support], USE_SQLITE=$enableval, USE_SQLITE=yes)
+if test $USE_SQLITE = "yes" -o $USE_SQLITE = "1" ; then
+  USE_SQLITE=1
+  AC_DEFINE(USE_SQLITE,[])
+else
+  USE_SQLITE=0
+fi
+AC_SUBST(USE_SQLITE)
+
+dnl
+dnl Set use of RSS (enabled by default)
+dnl
+AC_ARG_ENABLE(rss, [  --disable-rss        Disable RSS support], USE_RSS=$enableval, USE_RSS=yes)
+if test $USE_RSS = "yes" -o $USE_RSS = "1" ; then
+  USE_RSS=1
+  AC_DEFINE(USE_RSS,[])
+else
+  USE_RSS=0
+fi
+AC_SUBST(USE_RSS)
+
+
+dnl
+dnl Set use of Apache httpd (disabled by default)
+dnl
+AC_ARG_ENABLE(apache-httpd, [  --enable-apache-httpd  Enable Apache httpd support], USE_APACHE_HTTPD=$enableval, USE_APACHE_HTTPD=no)
+if test $USE_APACHE_HTTPD = "yes" -o $USE_APACHE_HTTPD = "1" ; then
+  USE_APACHE_HTTPD=1
+  AC_DEFINE(USE_APACHE_HTTPD,[])
+else
+  USE_APACHE_HTTPD=0
+fi
+AC_SUBST(USE_APACHE_HTTPD)
+
+
+dnl
+dnl Set compilation of MG (enabled by default)
+dnl
+AC_ARG_ENABLE(mg, [  --disable-mg        Disable MG compilation], ENABLE_MG=$enableval, ENABLE_MG=yes)
+if test $ENABLE_MG = "yes" -o $ENABLE_MG = "1" ; then
+  ENABLE_MG=1
+  AC_DEFINE(ENABLE_MG,[])
+else
+  ENABLE_MG=0
+fi
+AC_SUBST(ENABLE_MG)
+
+dnl
+dnl Set compilation of MGPP (enabled by default)
+dnl
+AC_ARG_ENABLE(mgpp, [  --disable-mgpp        Disable MGPP compilation], ENABLE_MGPP=$enableval, ENABLE_MGPP=yes)
+if test $ENABLE_MGPP = "yes" -o $ENABLE_MGPP = "1" ; then
+  ENABLE_MGPP=1
+  AC_DEFINE(ENABLE_MGPP,[])
+else
+  ENABLE_MGPP=0
+fi
+AC_SUBST(ENABLE_MGPP)
+
+dnl
+dnl Set compilation of lucene (enabled by default)
+dnl
+AC_ARG_ENABLE(lucene, [  --disable-lucene        Disable Lucene compilation], ENABLE_LUCENE=$enableval, ENABLE_LUCENE=yes)
+if test $ENABLE_JAVA = "1" -a \( $ENABLE_LUCENE = "yes" -o $ENABLE_LUCENE = "1" \) ; then
+  ENABLE_LUCENE=1
+  AC_DEFINE(ENABLE_LUCENE,[])
+else
+  ENABLE_LUCENE=0
+fi
+AC_SUBST(ENABLE_LUCENE)
+
+dnl Checks for programs.
+LDFLAGS=$LDFLAGS
+AC_SUBST(LDFLAGS)
+dnl only set CFLAGS if not already set in environment
+if test -z "$CFLAGS"; then
+CFLAGS=-O2
+fi
+AC_SUBST(CFLAGS)
+
+
+AC_PROG_CC
+AC_PROG_CXX
+if test $ENABLE_JAVA = "1" ; then
+  AC_PROG_JAVAC
+  AC_PROG_JAVA
+fi
+AC_PROG_AWK
+AC_PROG_YACC
+dnl get $target_cpu, $target_vendor, and $target_os
+dnl (as well as host_*)
+AC_CANONICAL_SYSTEM
+dnl do we actually want this? It adds a prefix based on host, system etc
+dnl AC_ARG_PROGRAM
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+AC_MSG_CHECKING(to see if architecture is 64-bit)
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  AC_MSG_RESULT(yes)
+  if test -z "$ARCH_DEP_FLAGS" ; then
+    ARCH_DEP_FLAGS="-fPIC"
+    gsdlarch='64'
+  fi
+else
+  AC_MSG_RESULT(no)
+  if test -z "$ARCH_DEP_FLAGS" ; then
+    ARCH_DEP_FLAGS=
+    gsdlarch='32'
+  fi
+fi
+
+export ARCH_DEP_FLAGS
+AC_SUBST(ARCH_DEP_FLAGS)
+
+
+#moved CORBA MICO directory test to get version of MICO
+if test $USE_CORBA = 1; then
+
+if test $MICO_DIR = "default"; then
+#do something
+MICO_INC="-I packages/mico/mico/include"
+else
+#build the micotest program
+MICO_INC= ""
+if test $MICO_DIR != yes; then
+MICO_INC="-I $MICO_DIR"
+fi
+fi
+
+#get MICO_VER value
+sh -c "$CC -c micotest.cpp -o micotest.o $MICO_INC 2>&1" > /dev/null
+sh -c "$CC -o micotest micotest.o -lstdc++ 2>&1" > /dev/null
+MICO_VER=`./micotest` || MICO_VER=2.3.13
+sh -c "rm micotest"
+sh -c "rm micotest.o"
+
+#do test of MICO_VER
+if test MICO_VER != 0; then
+AC_DEFINE(MICO_VER)
+AC_SUBST(MICO_VER)
+fi
+#end USE_CORBA test
+fi
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_AIX
+AC_ISC_POSIX
+AC_MINIX
+fp_C_PROTOTYPES
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl --- This should be in the stdc checking -----------------
+if test "$ac_cv_prog_cc_stdc" = '-Xc'; then
+dnl The Pyramids running SMP_DC.OSx on MIPS r3000 chips with
+dnl /usr/opt/cc3.11/bin/cc treat -Xc as full ANSI mode - no POSIX or
+dnl XOPEN extensions (like popen).
+dnl Unfortunately -D_{XOPEN,POSIX}_SOURCE can't provide all that mg
+dnl needs. So drop back to -Xa
+AC_TRY_COMPILE(
+[#include <stdio.h>
+], [ FILE *rubbish = popen("yes", "r"); ],,
+[CC="`echo $CC | sed 's/-Xc/-Xa/'`"    ac_cv_prog_cc_stdc='-Xa'])
+fi
+dnl ----------------------
+
+
+dnl Checks for libraries.
+dnl check for -lg:
+AC_HAVE_LIBRARY(g)
+dnl check for -lm:
+AC_HAVE_LIBRARY(m)
+dnl check for -lcrypt:
+AC_HAVE_LIBRARY(crypt)
+#if test $ENABLE_ACCENTFOLD = 1; then
+#AC_HAVE_LIBRARY(iconv)
+#fi
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h limits.h sys/time.h unistd.h crypt.h string.h memory.h sys/procfs.h sys/stat.h)
+AC_EGREP_HEADER(fread, stdio.h, AC_DEFINE(HAVE_FREAD_DECL))
+AC_EGREP_HEADER(fgetc, stdio.h, AC_DEFINE(HAVE_FGETC_DECL))
+AC_EGREP_HEADER(pr_brksize, sys/procfs.h, AC_DEFINE(HAVE_PR_BRKSIZE))
+
+dnl Checks for library functions.
+AC_FUNC_ALLOCA
+AC_PROG_GCC_TRADITIONAL
+AC_TYPE_SIGNAL
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(ftime select strftime strtol getrusage times mallinfo setbuffer getpagesize strerror)
+AC_REPLACE_FUNCS(ftruncate strstr strcasecmp)
+
+dnl see if gettext is in libc. (try the textdomain() function).
+AC_CHECK_FUNC(textdomain, AC_DEFINE(ENABLE_NLS ,1) )
+
+# *** Custom checking (based on GNU tar configure.in) ***
+# ---------------------------------------------------------------------------
+AC_MSG_CHECKING(for HP-UX needing gmalloc)
+if test "`(uname -s) 2> /dev/null`" = 'HP-UX'; then
+  AC_MSG_RESULT(yes)
+  AC_LIBOBJ([gmalloc])
+  AC_DEFINE(HAVE_VALLOC)
+else
+  AC_MSG_RESULT(no)
+  AC_CHECK_FUNCS(valloc)
+fi
+
+# we cannot generate static libraries under Darwin
+AC_MSG_CHECKING(for Apple MacOS X/Darwin)
+if test "`(uname -s) 2> /dev/null`" = 'Darwin'; then
+  AC_MSG_RESULT(yes)
+  STATIC=""
+else
+  AC_MSG_RESULT(no)
+  STATIC="-static "
+fi
+AC_SUBST(STATIC)
+
+fp_WITH_DMALLOC
+fp_WITH_REGEX
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc])
+  AC_LIBOBJ([error])
+fi
+
+
+# ---------------------------------------------------------------------------
+
+dnl
+dnl Switch into C++
+dnl
+AC_LANG_CPLUSPLUS
+
+dnl
+dnl Now check that Perl is actually around, and can be found
+dnl
+AC_MSG_CHECKING(that Perl 5 is available)
+success="no"
+pl_path="$PATH"
+IFS="${IFS=   }"; pl_save_ifs="$IFS"; IFS=":"
+for pl_dir in $pl_path; do
+  test -z "$pl_dir" && pl_dir=.
+  if test -x $pl_dir/perl; then
+    success="yes"
+    break
+  fi
+done
+IFS="$pl_save_ifs"
+
+dnl
+dnl Check if the STL library has any known faults;
+dnl In GCC 2.7.2.x series, some STL library headers are missing
+dnl a file called "new" which is referred to by other headers
+dnl (eg. vector/vector.h); if this applies, then all use of the
+dnl STL will cause a compile fail, so we'd better let the user
+dnl know now, before things really go wrong!
+dnl
+success=no
+AC_MSG_CHECKING("whether STL library has known faults")
+
+dnl - first shot, try simple good old vector on its own
+AC_TRY_COMPILE(
+[#include <vector>
+], 
+[],
+success=yes,
+)
+
+dnl - try using the .h equivalent
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <vector.h>
+], 
+[],
+success="yes",
+)
+fi
+
+dnl - now try for the objectspace headers
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <ospace\\std\\vector>
+], 
+[],
+success="yes",
+)
+fi
+
+if test $success = yes; then
+AC_MSG_RESULT("no")
+else
+AC_MSG_RESULT("yes")
+AC_MSG_ERROR("STL Broken - Obtain newer version of GNU C Compiler")
+fi
+
+gsdlos=`uname | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+# check for running bash under cygwin
+ if test "`echo $gsdlos | sed 's/cygwin//'`" != "$gsdlos" ;
+ then
+  gsdlos=windows
+ fi
+AC_SUBST(gsdlos)
+
+# Make gsdlarch empty if the OS bit value (32 or 64) is not used in naming 
+# directories already or if runtime-src is compiled up on its own.
+# E.g. 32/64 bit won't be used in the SVN version if only bin/linux exists.
+if test -d "../bin/$gsdlos" -o ! -f "../setup.bash" ; then
+   gsdlarch=""
+fi
+AC_SUBST(gsdlarch)
+
+# check for endianness
+AC_C_BIGENDIAN
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc.o])
+  AC_LIBOBJ([error])
+fi
+
+# ---------------------------------------------------------------------------
+
+
+dnl
+dnl Locate all children of the modules folder
+dnl
+moduleDirs=""
+MODULEDIRS=""
+if test -d modules ; then
+  for x in `find modules -mindepth 1 -maxdepth 2`; do
+    if test -d "$x"; then
+      d="$x/Makefile.in"
+      if test -e "$d"; then
+  dnl      echo $d
+        moduleDirs="$moduleDirs $x/Makefile"
+        MODULEDIRS="$MODULEDIRS $x"
+      fi
+    fi
+  done
+  echo "Making $moduleDirs in modules directory"
+  AC_SUBST(MODULEDIRS)
+fi
+
+
+AC_CONFIG_SUBDIRS(packages)
+
+# the list of folders in the src folder
+srclist="src/colservr/Makefile \
+         src/corba/Makefile \
+         src/protocol/Makefile \
+         src/recpt/Makefile \
+         src/oaiservr/Makefile \
+         src/z3950/Makefile \
+         src/java/org/nzdl/gsdl/GsdlCollageApplet/Makefile \
+         src/java/org/nzdl/gsdl/Phind/Makefile"
+
+AC_OUTPUT(packages/Makefile Makefile $srclist $moduleDirs)
+
+
Index: main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/runtime-src/packages_unfinished/Makefile.in
===================================================================
--- main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/runtime-src/packages_unfinished/Makefile.in	(revision 28886)
+++ main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/runtime-src/packages_unfinished/Makefile.in	(revision 28886)
@@ -0,0 +1,201 @@
+###########################################################################
+#
+# Makefile -- Makefile for packages included with Greenstone runtime
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2000 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+USE_Z3950=@USE_Z3950@
+USE_YAZ=@USE_YAZ@
+USE_APACHE_HTTPD=@USE_APACHE_HTTPD@
+
+USE_SECURITY=@USE_SECURITY@
+#ifeq ($(USE_SECURITY), 1)
+#else
+#SECURITY=
+#endif
+
+
+ifeq ($(USE_Z3950), 1)
+# make sure USE_YAZ is set
+USE_YAZ=1
+D2M=d2m
+else
+D2M=
+endif
+
+ifeq ($(USE_YAZ), 1)
+# we only compile the src and client dirs for now.
+YAZ=yaz/yaz-2.1.4/src yaz/yaz-2.1.4/client 
+else
+YAZ=
+endif
+
+
+USE_CORBA=@USE_CORBA@
+MICO_DIR=@MICO_DIR@
+ifeq ($(USE_CORBA), 1)
+ifeq ($(MICO_DIR), default)
+CORBA="mico/mico"
+else
+CORBA=
+endif
+else
+CORBA=
+endif
+
+GSDLOS = @gsdlos@
+
+ifeq ($(USE_APACHE_HTTPD), 1)
+HTTPD=apache-httpd/httpd-2.2.11
+else
+HTTPD=
+endif
+
+
+# PACKAGEDIRS contains the packages that we want to make and install.  It
+# is assumed that each package will have at least four rules: all, install,
+# clean, and distclean.
+INSTALLDIRS =   $(YAZ) $(D2M) $(CORBA) $(SECURITY)
+PACKAGEDIRS =	$(INSTALLDIRS) $(HTTPD)
+
+REPLACELIST = conf/extra/httpd-dav.conf \
+	conf/extra/httpd-manual.conf \
+	conf/extra/httpd-autoindex.conf \
+	conf/extra/httpd-vhosts.conf \
+	conf/extra/httpd-ssl.conf \
+	conf/extra/httpd-multilang-errordoc.conf \
+	conf/original/extra/httpd-dav.conf \
+	conf/original/extra/httpd-manual.conf \
+	conf/original/extra/httpd-autoindex.conf \
+	conf/original/extra/httpd-vhosts.conf \
+	conf/original/extra/httpd-ssl.conf \
+	conf/original/extra/httpd-multilang-errordoc.conf \
+	conf/original/httpd.conf\
+	lib/apr-util-1/apr_dbd_odbc.la \
+	lib/apr-util-1/apr_dbd_sqlite3.la \
+	lib/pkgconfig/apr-util-1.pc \
+	lib/pkgconfig/apr-1.pc \
+	lib/libaprutil-1.la \
+	lib/libapr-1.la \
+	build/config_vars.mk \
+	build/config.nice \
+	build/apr_rules.mk \
+	bin/dbmmanage \
+	bin/apu-1-config \
+	bin/apr-1-config \
+	include/ap_config_auto.h \
+	include/ap_config_layout.h
+
+all:
+	for odir in $(PACKAGEDIRS); do \
+          echo making $@ in $$odir; \
+          (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+        done
+ifeq ($(USE_APACHE_HTTPD), 1)
+# Need to make install here, otherwise src/recpt won't be able
+# to compile mod_gsdl.cpp with installed header files etc.
+	(cd $(HTTPD) && $(MAKE) $(MDEFINES) install) || exit 
+endif
+
+ifeq ($(CORBA), "mico/mico")
+	cd mico/mico; $(MAKE)  $(MDEFINES) install
+	mkdir -p ../bin/linux
+	mkdir -p ../lib
+	mkdir -p ../include
+	mkdir -p ../man
+	cp -f mico/bin/* ../bin/linux
+	cp -f mico/lib/* ../lib/
+	cp -fr mico/include/* ../include
+	cp -fr mico/man ../man
+endif
+ifeq ($(USE_YAZ), 1)
+# need to do make install in include and src dirs to get the header files and
+# lib file into the right place
+	cd yaz/yaz-2.1.4/include; $(MAKE)  $(MDEFINES) install
+	cd yaz/yaz-2.1.4/src; $(MAKE)  $(MDEFINES) install
+endif
+
+# make install all packages in the security folder
+
+
+# now install everything except apache, since that had already been installed during "all"
+install:
+	for idir in $(INSTALLDIRS); do \
+          echo installing $$idir; \
+          (cd $$idir && $(MAKE) install) || exit 1; \
+        done
+ifeq ($(USE_APACHE_HTTPD), 1)
+	mkdir -p ../../apache-httpd/$(GSDLOS)/conf
+	cp -f apache-httpd/httpd.conf.in ../../apache-httpd/$(GSDLOS)/conf/.
+	mkdir -p ../../etc/logs-gsi
+	@ echo "*************** INFO ***************"
+	@ echo "Run: source setup.bash, to set up the environment for greenstone"
+	@ echo "Type: make configure-admin, to set the admin password"
+	@ echo "Edit: llssite.cfg files to change the port number if necessary"
+	@ echo "Type: make configure-web, to configure the included apache webserver"
+	@ echo "EITHER type: make web-start, to launch the webserver from the command-line"
+	@ echo "OR run: gs2-server.sh, to launch the GUI version of the included webserver"
+	@ echo "************************************"
+endif
+
+clean:
+	for subdir in $(PACKAGEDIRS); do \
+          echo cleaning $@ in $$subdir; \
+          (cd $$subdir && $(MAKE) clean || exit 0) ; \
+        done
+
+distclean:
+	rm -f Makefile 
+	for subdir in $(PACKAGEDIRS); do \
+          echo cleaning $@ in $$subdir; \
+          (cd $$subdir && $(MAKE) distclean || exit 0) ; \
+        done
+
+apache-for-dist:
+	( httpddir=`cd ./apache-httpd/httpd* ; pwd` ; \
+	  cp $$httpddir/support/apxs.in ../../apache-httpd/$(GSDLOS)/apxs.in ; \
+	  cp apache-httpd/install-bindist.sh ../../apache-httpd/$(GSDLOS)/install-bindist.sh ; \
+	  chmod 755 ../../apache-httpd/$(GSDLOS)/install-bindist.sh ; \
+	  gsdldir=`cd ../.. ; pwd` ; \
+	  pre="$$gsdldir/apache-httpd/$(GSDLOS)" ; \
+	  for one_file in apachectl envvars envvars-std; do \
+	    sed -e "s%$$pre%*\*\APACHE_HOME_OS\*\*%" "$$pre/bin/$$one_file" > "$$pre/bin/$$one_file.in" ; \
+	    cp "$$pre/bin/$$one_file.in" "$$pre/bin/$$one_file" ; \
+	  done ; \
+	  for one_file in $(REPLACELIST); do \
+	    sed -e "s%$$pre%*\*\APACHE_HOME_OS\*\*%" "$$pre/$$one_file" > "$$pre/$$one_file.in" ; \
+	    cp "$$pre/$$one_file.in" "$$pre/$$one_file" ; \
+	  done ; \
+	  cat "$$pre/bin/apr-1-config" \
+	    | sed -e "s%^APR_SOURCE_DIR=.*%APR_SOURCE_DIR=%" \
+	    | sed -e "s%^APR_BUILD_DIR=.*%APR_BUILD_DIR=%" \
+	    > "$$pre/bin/apr-1-config.in" ; \
+	  cp "$$pre/bin/apr-1-config.in" "$$pre/bin/apr-1-config" ; \
+	  cat "$$pre/bin/apu-1-config" \
+	    | sed -e "s%^APU_SOURCE_DIR=.*%APU_SOURCE_DIR=%" \
+	    | sed -e "s%^APU_BUILD_DIR=.*%APU_BUILD_DIR=%" \
+	    > "$$pre/bin/apu-1-config.in" ; \
+	  cp "$$pre/bin/apu-1-config.in" "$$pre/bin/apu-1-config" ; \
+	  sed -e "s%^EXTRA_INCLUDES\s*=.*%EXTRA_INCLUDES=%" "$$pre/build/config_vars.mk" > "$$pre/build/config_vars.mk.in" ; \
+	  cp "$$pre/build/config_vars.mk.in" "$$pre/build/config_vars.mk" ; )
Index: main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/runtime-src/packages_unfinished/configure
===================================================================
--- main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/runtime-src/packages_unfinished/configure	(revision 28886)
+++ main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/configure_scripts/runtime-src/packages_unfinished/configure	(revision 28886)
@@ -0,0 +1,236 @@
+#! /bin/sh
+
+PACKAGES=`pwd`
+cd ../..
+GSDLHOME=`pwd`
+cd $PACKAGES
+
+GSDLOS=`uname -s |tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+# check for running bash under cygwin
+if test "`echo $GSDLOS | sed 's/cygwin//'`" != "$GSDLOS" ;
+then
+ GSDLOS=windows
+fi
+
+prefix=""
+bindir=""
+HOSTTARGETFLAGS=""
+
+# only some of the packages can take environment variables as options to 
+# configure 
+# format is VAR=value, e.g "LDFLAGS=-static"
+ENVIRONMENT=""
+
+# GDBM compilation enabled by default, can switch it off with --disable-gdbm
+USE_GDBM=true
+# SECURITY package compilation enabled by default, can switch it off with --disable-security
+USE_SECURITY=true
+# JDBM compilation enabled by default, can switch it off with --disable-jdbm
+USE_JDBM=true
+# SQLite support enabled by default, can switch it off with --disable-sqlite
+USE_SQLITE=true
+# yaz compilation enabled by default, can switch it off with --disable-yaz
+USE_YAZ=true
+# z3950 server disabled by default, switch it on with --enable-z3950
+USE_Z3950=false
+# CORBA support disabled by default, switch it on with --enable-corba
+USE_CORBA=false
+MICO_DIR=default
+# Apache's httpd (web server) enabled by default
+USE_APACHE_HTTPD=false
+
+# parse any arguments given from toplevel configure
+while test $# -ne 0; do
+    case "$1" in
+	--cache-file=*)
+	    cache_filename=`echo $1 | sed s/--cache-file=//`
+	    # turn relative path into an absolute path
+	    cache_dir=`echo $cache_filename | sed 's@/[^/]*$@@'`
+	    cache_dir=`cd $cache_dir 2>/dev/null && pwd`
+
+	    cache_basefile=`echo $cache_filename | sed 's@.*/@@'`
+	    cache_file="$cache_dir/$cache_basefile"
+	    if test ! -f "$cache_file"; then
+		CACHE_FILE=""
+	    else
+		CACHE_FILE="--cache-file=$cache_file"
+	    fi
+	    ;;
+	--disable-gdbm)
+	    USE_GDBM=false
+	    ;;
+	--disable-security)
+	    USE_SECURITY=false
+	    ;;
+	--disable-jdbm)
+	    USE_JDBM=false
+	    ;;
+	--disable-sqlite)
+	    USE_SQLITE=false
+	    ;;
+	--disable-yaz)
+	    USE_YAZ=false
+	    ;;
+	--enable-z3950)
+	    USE_Z3950=true
+	    ;;
+	--enable-corba)
+	    USE_CORBA=true
+	    ;;
+	--with-micodir=*)
+	    if test $1 = ""; then
+	      $1 = "default"
+            fi
+	    MICO_DIR=$1
+	    ;;       
+	--enable-apache-httpd)
+	    USE_APACHE_HTTPD=true
+	    ;;
+	--prefix=*)
+	    prefix=`echo $1 | sed s/--prefix=//`
+	    ;;
+	--bindir=*)
+	    # where to install binaries to
+	    bindir=`echo $1 | sed s/--bindir=//`
+	    # turn relative path into an absolute path
+	    if test -d "$bindir" ; then
+	      bindir=`cd "$bindir" ; pwd `
+	      cd "$PACKAGES"
+	    elif test -z `echo $bindir | sed '/^\// p;D'` ; then
+	      rel_bindir="`echo $bindir | sed s@/.*@@`"
+	      cd "$rel_bindir"
+	      bindir="`pwd`/`echo $bindir | sed s@^[^/]*/@@`"
+	      cd "$PACKAGES"
+	    else
+	      # bindir doesn't exist, and isn't relative
+	      true
+	    fi
+	    ;;
+	--host=* | --target=*)
+	    HOSTTARGETFLAGS="$HOSTTARGETFLAGS $1"
+	    ;;
+	*)
+	    # ignore all other options for now
+	    ;;
+    esac
+    shift
+done
+
+# note! Our GSDL package currently always installs into it's source
+# directory, ignoring any --prefix given to configure.
+# When this is fixed, uncomment the relevant lines below...
+
+##if test -z "$prefix" ; then
+prefix="${GSDLHOME}"
+##fi
+
+##if test -z "$bindir" ; then
+bindir="${prefix}/bin/$GSDLOS"
+##fi
+
+# This loads the top configure's cache file, with variables already set.
+if test -f "$cache_file" ; then
+  . $cache_file
+fi
+
+# we assume that gzip and tar are on the search path.
+# non-GNU versions of tar don't take the -z option.
+
+if test $USE_CORBA = true ; then
+  if test $MICO_DIR = default; then
+    # configure the MICO CORBA ORB
+    echo ""
+    echo "Configuring MICO CORBA"
+    echo ""
+
+    cd "$PACKAGES/mico"
+    gzip -dc mico-2.3.13-gs.tar.gz | tar -xf -
+    cd mico && \
+    ./configure $CACHE_FILE    --prefix=$PACKAGES/mico/  --disable-coss --disable-naming --disable-relship --disable-events --disable-streams --disable-property --disable-trader --disable-time 
+#--disable-debug 
+#--enable-optimize --enable-final --enable-speed-tune
+#    sed 's/tools//'  $PACKAGES/mico/mico/Makefile | sed 's/ldconfig//' >$PACKAGES/mico/mico/Makefile.out 
+
+# Remove any references to running 'tools' and 'ldconfig' as these require
+# admin permissions when running 'make install'.
+# Use fgrep here to knock out the entire line containing $(LDCONFIG), because
+# there may be a special tab preceding the line which in a Makefile can have
+# special meaning. Don't want to leave it in by itself.
+    sed 's/tools//'  $PACKAGES/mico/mico/Makefile | fgrep -iv ldconfig >$PACKAGES/mico/mico/Makefile.out
+    mv $PACKAGES/mico/mico/Makefile.out $PACKAGES/mico/mico/Makefile
+  else
+    #MICO is on the system path
+    echo ""
+    echo "Taking MICO from system paths"
+    echo ""
+  fi
+else
+  echo "corba support disabled - mico compiler not required."
+  echo "  add '--enable-corba' to the configure command to include corba support."
+  echo ""
+fi
+
+
+
+# D2M stuff needed for z3950server
+echo ""
+echo "Configuring D2M"
+if test x$USE_Z3950 = xtrue ; 
+then
+  USE_YAZ=true
+  echo ""
+  cd "$PACKAGES/d2m"
+  ./configure $CACHE_FILE --prefix="$PACKAGES/d2m" $HOSTTARGETFLAGS
+else
+  echo "Z39.50 support disabled - D2M library not required."
+  echo "  add '--enable-z3950' to the configure command to include z39.50 support."
+  echo ""
+fi
+   
+# YAZ Z39.50 toolkit
+echo ""
+echo "Configuring YAZ"
+if test x$USE_YAZ = xtrue ; 
+then
+  echo "YAZ library support enabled"
+  echo "add --disable-yaz to the configure command to disable this"
+  echo ""
+  cd "$PACKAGES/yaz" 
+  gzip -dc yaz-2.1.4.tar.gz | tar -xf -
+  cd yaz-2.1.4 && \
+    ./configure $CACHE_FILE --prefix="$PACKAGES/yaz" --bindir="$bindir" $HOSTTARGETFLAGS
+else
+  echo "YAZ support disabled"
+  echo ""
+fi
+
+
+# Apache's HTTPD web server
+echo ""
+echo "Configuring Apache httpd"
+if test x$USE_APACHE_HTTPD = xtrue ; 
+then
+  echo "Apache httpd support enabled"
+  echo "add --disable-apache-httpd to the configure command to disable this"
+  echo ""
+#  echo "Setting up libiconv (used by Apache httpd)"
+#  cd "$PACKAGES/apache-httpd" 
+#  if [ ! -e libiconv-1.13.1 ] ; then gzip -dc libiconv-1.13.1.tar.gz | tar -xf - ; fi
+#  cd libiconv-1.13.1&& \
+#    ./configure $CACHE_FILE --prefix="${prefix}/apache-httpd/${GSDLOS}" --disable-shared $HOSTTARGETFLAGS&&
+#    make && make install
+#  echo ""
+  echo "Configuring Apache httpd"
+  cd "$PACKAGES/apache-httpd" 
+  if [ ! -e httpd-2.2.11 ] ; then gzip -dc httpd-2.2.11-gs.tar.gz | tar -xf - ; fi
+  cd httpd-2.2.11&& \
+
+CFLAGS="$CFLAGS -I${GSDLHOME}/common-src/packages/iconv/include" CXXFLAGS="$CXXFLAGS -I${GSDLHOME}/common-src/packages/iconv/include" LDFLAGS="$LDFLAGS -L${GSDLHOME}/common-src/packages/iconv/lib -L${GSDLHOME}/common-src/packages/sqlite/lib" ./configure $CACHE_FILE --with-included-apr --with-layout=BinaryDistribution --enable-most --enable-rewrite --prefix="${prefix}/apache-httpd/${GSDLOS}" $HOSTTARGETFLAGS --with-iconv
+
+else
+  echo "Apache httpd support disabled"
+  echo "add --enable-apache-httpd to the configure command to enable this"
+  echo ""
+fi
+
+
Index: main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/esapitools.cpp
===================================================================
--- main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/esapitools.cpp	(revision 28886)
+++ main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/esapitools.cpp	(revision 28886)
@@ -0,0 +1,174 @@
+
+#include "esapitools.h"
+
+#include "gsdlunicode.h"
+
+#include "EsapiCommon.h"
+#include "EncoderConstants.h"
+#include "reference/DefaultEncoder.h"
+
+#include "codecs/Codec.h"
+#include "codecs/UnixCodec.h"
+#include "codecs/WindowsCodec.h"
+#include "codecs/HTMLEntityCodec.h"
+
+#include "util/TextConvert.h"
+#include "crypto/CryptoppCommon.h"
+
+#include "errors/NullPointerException.h"
+#include "errors/UnsupportedOperationException.h"
+
+
+esapi::NarrowString text_t_to_esapi_narrow_string(text_t& in)
+{
+    text_t in_short_padded_utf8 = to_utf8(in.begin(),in.end());
+    char* in_utf8 = in_short_padded_utf8.getcstr(); // MSB of each array position in the text_t will be 0
+    esapi::NarrowString out_nstring(in_utf8); // NarrowString is typedef for std::string
+
+    delete [] in_utf8;
+
+    return out_nstring;
+}
+
+
+
+esapi::WideString text_t_to_esapi_wide_string(text_t& in)
+{
+    text_t in_short_padded_utf8 = to_utf8(in.begin(),in.end());
+    char* in_utf8 = in_short_padded_utf8.getcstr(); // MSB of each array position in the text_t will be 0
+    esapi::NarrowString* in_nstring = new esapi::NarrowString(in_utf8); // NarrowString is typedef for std::string
+
+    esapi::WideString out_wstring = TextConvert::NarrowToWide(*in_nstring); // esapi::WideString is typedef for std::wstring
+
+    delete [] in_utf8;
+    delete in_nstring;
+
+    return out_wstring;
+
+}
+
+
+text_t esapi_narrow_string_to_text_t(esapi::NarrowString& in)
+{
+    const char* in_cstr = in.c_str();
+
+    text_t out_text_t(in_cstr);
+
+    return out_text_t;
+}
+
+text_t esapi_wide_string_to_text_t(esapi::WideString& in)
+{
+
+    esapi::NarrowString in_nstring = TextConvert::WideToNarrow(in); // esapi::NarrowString is typedef for std::string
+    const char* in_cstr = in_nstring.c_str();
+
+    text_t out_text_t(in_cstr);
+
+    return out_text_t;
+}
+
+
+
+static esapi::StringArray Make_HTML_Vector()
+  {
+    esapi::StringArray sa;
+    sa.push_back(","); sa.push_back(".");
+    sa.push_back("-"); sa.push_back("_");
+    sa.push_back(" ");
+    return sa;
+  }
+
+  static esapi::StringArray Make_HTMLATTR_Vector()
+  {
+    esapi::StringArray sa;
+    sa.push_back(","); sa.push_back(".");
+    sa.push_back("-"); sa.push_back("_");
+    return sa;
+  }
+
+  static esapi::StringArray Make_CSS_Vector()
+  {
+    esapi::StringArray sa;
+    sa.push_back("");
+    return sa;
+  }
+
+  static esapi::StringArray Make_JAVASCRIPT_Vector()
+  {
+    esapi::StringArray sa;
+    sa.push_back(","); sa.push_back(".");
+    sa.push_back("_");
+    return sa;
+  }
+
+  static esapi::StringArray Make_VBSCRIPT_Vector()
+  {
+    esapi::StringArray sa;
+    sa.push_back(","); sa.push_back(".");
+    sa.push_back("_");
+    return sa;
+  }
+
+  static esapi::StringArray Make_XML_Vector()
+  {
+    esapi::StringArray sa;
+    sa.push_back(","); sa.push_back(".");
+    sa.push_back("-"); sa.push_back("_");
+    sa.push_back(" ");
+    return sa;
+  }
+
+  static esapi::StringArray Make_SQL_Vector()
+  {
+    esapi::StringArray sa;
+    sa.push_back(" ");
+    return sa;
+  }
+
+  static esapi::StringArray Make_OS_Vector()
+  {
+    esapi::StringArray sa;
+    sa.push_back("-");
+    return sa;
+  }
+
+  static esapi::StringArray Make_XMLATTR_Vector()
+  {
+    esapi::StringArray sa;
+    sa.push_back(","); sa.push_back(".");
+    sa.push_back("-"); sa.push_back("_");
+    return sa;
+  }
+
+  static esapi::StringArray Make_XPATH_Vector()
+  {
+    esapi::StringArray sa;
+    sa.push_back(","); sa.push_back(".");
+    sa.push_back("-"); sa.push_back("_");
+    sa.push_back(" ");
+    return sa;
+  }
+
+static const esapi::StringArray IMMUNE_HTML = Make_HTML_Vector();
+static const esapi::StringArray IMMUNE_HTMLATTR = Make_HTMLATTR_Vector();
+static const esapi::StringArray IMMUNE_CSS = Make_CSS_Vector();
+static const esapi::StringArray IMMUNE_JAVASCRIPT = Make_JAVASCRIPT_Vector();
+static const esapi::StringArray IMMUNE_VBSCRIPT = Make_VBSCRIPT_Vector();
+static const esapi::StringArray IMMUNE_XML = Make_XML_Vector();
+static const esapi::StringArray IMMUNE_SQL = Make_SQL_Vector();
+static const esapi::StringArray IMMUNE_OS = Make_OS_Vector();
+static const esapi::StringArray IMMUNE_XMLATTR = Make_XMLATTR_Vector();
+static const esapi::StringArray IMMUNE_XPATH = Make_XPATH_Vector();
+
+//static esapi::LDAPCodec ldapCodec;
+static esapi::HTMLEntityCodec htmlCodec;
+/*static esapi::XMLEntityCodec xmlCodec;
+static esapi::PercentCodec percentCodec;
+static esapi::JavaScriptCodec javaScriptCodec;
+static esapi::VBScriptCodec vbScriptCodec;
+static esapi::CSSCodec cssCodec;
+*/
+esapi::NarrowString encodeForHTML(const esapi::NarrowString & input) {
+  return htmlCodec.encode( IMMUNE_HTML, input);  
+}
Index: main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/esapitools.h
===================================================================
--- main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/esapitools.h	(revision 28886)
+++ main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/esapitools.h	(revision 28886)
@@ -0,0 +1,23 @@
+#ifndef ESAPITOOLS_H
+#define ESAPITOOLS_H
+
+#include "EsapiCommon.h"
+#include "Encoder.h"
+using esapi::Encoder;
+#include "EsapiTypes.h"
+#include "reference/DefaultEncoder.h"
+using esapi::DefaultEncoder;
+#include "util/TextConvert.h"
+using esapi::TextConvert;
+
+#include "text_t.h"
+
+esapi::NarrowString text_t_to_esapi_narrow_string(text_t& in);
+esapi::WideString text_t_to_esapi_wide_string(text_t& in);
+
+text_t esapi_narrow_string_to_text_t(esapi::NarrowString& in);
+text_t esapi_wide_string_to_text_t(esapi::WideString& in);
+
+esapi::NarrowString encodeForHTML(const esapi::NarrowString & input);
+
+#endif
Index: main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/receptionist.cpp
===================================================================
--- main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/receptionist.cpp	(revision 28886)
+++ main/trunk/greenstone2/runtime-src/packages/security/gs-code-changes/receptionist.cpp	(revision 28886)
@@ -0,0 +1,1858 @@
+/**********************************************************************
+ *
+ * receptionist.cpp -- a web interface for the gsdl
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+// following line required to get fstream.filedesc() on darwin (Mac OS X)
+// gcc 2.91 automatically defines this in stream.h
+#define _STREAM_COMPAT  1
+
+#include "receptionist.h"
+#include "recptprototools.h"
+#include "fileutil.h"
+#include "cgiutils.h"
+#include "htmlutils.h"
+#include "gsdltools.h"
+#include "gsdltimes.h"
+#include "OIDtools.h"
+#include "securitytools.h"
+#include <assert.h>
+#include <time.h>
+#include <stdio.h> // for open()
+#include <fcntl.h> // for open() flags
+// following 2 are for printing Last-Modified http header.
+#include <sys/stat.h>
+#include <time.h>
+
+#include "EsapiCommon.h"
+//using esapi::String;
+#include "Encoder.h"
+using esapi::Encoder;
+#include "EsapiTypes.h"
+#include "reference/DefaultEncoder.h"
+using esapi::DefaultEncoder;
+#include "esapitools.h"
+//#include <string>
+
+#if defined (GSDL_USE_IOS_H)
+#include <fstream.h>
+#else 
+#include <fstream>
+#endif
+
+void recptconf::clear () {
+  gsdlhome.clear();
+  collecthome.clear();
+  dbhome.clear();
+  collectinfo.erase(collectinfo.begin(), collectinfo.end());
+  collection.clear();
+  collectdir.clear();
+  httpprefix.clear();
+  httpweb.clear();
+  gwcgi.clear();
+  macrofiles.erase(macrofiles.begin(), macrofiles.end());
+  saveconf.clear();
+  usecookies = false;
+  logcgiargs = false;
+  LogDateFormat = LocalTime;
+
+  maintainer.clear();
+  MailServer.clear();
+  LogEvents = Disabled;
+  EmailEvents = Disabled;
+  EmailUserEvents = false;
+
+  languages.erase(languages.begin(), languages.end());
+  encodings.erase(encodings.begin(), encodings.end());
+
+  site_auth = false;
+  HomePageType = "images";
+  HomePageCols = 3;
+  
+  // these default page parameters can always be overriden
+  // in the configuration file
+  pageparams.erase(pageparams.begin(), pageparams.end());
+  pageparams["c"] = ""; 
+  pageparams["l"] = "en"; 
+
+#ifdef MACROPRECEDENCE
+  macroprecedence = MACROPRECEDENCE;
+#else
+  macroprecedence.clear();
+#endif
+}
+
+
+void collectioninfo_t::clear () {
+  gsdl_gsdlhome.clear();
+  gsdl_dbhome.clear();
+
+  info_loaded = false;
+  info.clear();
+}
+
+void languageinfo_t::clear () {
+  longname.clear();
+  defaultencoding.clear();
+}
+
+receptionist::receptionist () {
+  // create a list of cgi arguments
+  // this must be done before the configuration
+
+  cgiarginfo ainfo;
+
+  ainfo.shortname = "e";
+  ainfo.longname = "compressed arguments";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::good;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, ainfo);
+
+  ainfo.shortname = "a";
+  ainfo.longname = "action";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, ainfo);
+
+  // w=western
+  ainfo.shortname = "w";
+  ainfo.longname = "encoding";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, ainfo);
+  
+  ainfo.shortname = "nw";
+  ainfo.longname = "new encoding";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, ainfo);
+  
+  ainfo.shortname = "c";
+  ainfo.longname = "collection";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, ainfo);
+  
+  // the interface language name should use the ISO 639
+  // standard
+  ainfo.shortname = "l";
+  ainfo.longname = "interface language";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::weak;
+  ainfo.argdefault = "en";
+  ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, ainfo);
+  
+  ainfo.shortname = "nl";
+  ainfo.longname = "new language";
+  ainfo.multiplechar = false;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = "0";
+  ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, ainfo);
+  
+  // the GSDL_UID (cookie)
+  ainfo.shortname = "z";
+  ainfo.longname = "gsdl uid";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, ainfo);
+}
+
+
+void receptionist::add_action (action *theaction) {
+  // make sure we have an action to add
+  if (theaction == NULL) return;
+
+  // add this action to the list of actions
+  actions.addaction(theaction);
+  
+  // add the cgi arguments from this action
+  argsinfo.addarginfo (NULL, *(theaction->getargsinfo()));
+}
+
+
+void receptionist::add_browser (browserclass *thebrowser) {
+  // make sure we have a browser to add
+  if (thebrowser == NULL) return;
+
+  // add this browser to the list of browsers
+  browsers.addbrowser(thebrowser);
+}
+
+
+void receptionist::setdefaultbrowser (const text_t &browsername) {
+  browsers.setdefaultbrowser (browsername);
+}
+
+
+// configure should be called for each line in the
+// configuration files to configure the receptionist and everything
+// it contains. The configuration should take place after everything
+// has been added but before the initialisation.
+
+void receptionist::configure (const text_t &key, const text_tarray &cfgline) {
+  // configure the receptionist
+
+   
+   
+  if (cfgline.size() >= 1) {
+    cgiarginfo *info = NULL;
+    if (key == "gsdlhome") {
+      configinfo.gsdlhome = cfgline[0];
+      if (configinfo.dbhome.empty()) configinfo.dbhome = cfgline[0];
+    }
+    else if (key == "collecthome") configinfo.collecthome = cfgline[0];
+    else if (key == "gdbmhome") configinfo.dbhome = cfgline[0];
+    else if (key == "collection") {
+      configinfo.collection = cfgline[0];
+      // also need to set the default arg to this collection
+      if ((info = argsinfo.getarginfo("c")) != NULL) {
+	info->defaultstatus = cgiarginfo::good;
+	info->argdefault = cfgline[0];
+      }
+      
+    }
+    else if (key == "collectdir") configinfo.collectdir = cfgline[0];
+    else if (key == "httpprefix") configinfo.httpprefix = cfgline[0];
+    else if (key == "httpweb") configinfo.httpweb = cfgline[0];
+    else if (key == "gwcgi") configinfo.gwcgi = cfgline[0];
+    else if (key == "macrofiles") {
+      // want to append to macrofiles (i.e. may be several config files
+      // contributing, maybe from several collections).
+      text_tarray::const_iterator here = cfgline.begin();
+      text_tarray::const_iterator end = cfgline.end();
+      while (here != end) {
+	configinfo.macrofiles.insert (*here);
+	++here;
+      }
+    }
+    else if (key == "saveconf") configinfo.saveconf = cfgline[0];
+    else if (key == "usecookies") configinfo.usecookies = (cfgline[0] == "true");
+    else if (key == "logcgiargs") configinfo.logcgiargs = (cfgline[0] == "true");
+    else if (key == "maintainer") configinfo.maintainer = cfgline[0];
+    else if (key == "MailServer") configinfo.MailServer = cfgline[0];
+    else if (key == "LogDateFormat") {
+      if (cfgline[0] == "UTCTime") configinfo.LogDateFormat = UTCTime;
+      else if (cfgline[0] == "Absolute") configinfo.LogDateFormat = Absolute;
+    } 
+    else if (key == "LogEvents") {
+      if (cfgline[0] == "CollectorEvents") configinfo.LogEvents = CollectorEvents;
+      else if (cfgline[0] == "AllEvents") configinfo.LogEvents = AllEvents;
+    } 
+    else if (key == "EmailEvents") {
+      if (cfgline[0] == "CollectorEvents") configinfo.EmailEvents = CollectorEvents;
+      else if (cfgline[0] == "AllEvents") configinfo.EmailEvents = AllEvents;
+    } 
+    else if (key == "EmailUserEvents") configinfo.EmailUserEvents = (cfgline[0] == "true");
+    else if (key == "pageparam") {
+      if (cfgline.size() >= 2) configinfo.pageparams[cfgline[0]] = cfgline[1];
+      else configinfo.pageparams[cfgline[0]] = "";
+    }
+    else if (key == "macroprecedence") configinfo.macroprecedence = cfgline[0];
+    else if (key == "collectinfo") {
+      if (cfgline.size() == 3) {
+	// for backwards compatability with older collections that only use
+	// gsdlhome and dbhome
+	collectioninfo_t cinfo;
+	cinfo.gsdl_gsdlhome = cfgline[1];
+	cinfo.gsdl_collecthome = filename_cat(cfgline[1],"collect");
+	cinfo.gsdl_dbhome = cfgline[2];
+	configinfo.collectinfo[cfgline[0]] = cinfo;
+      }
+      else if (cfgline.size() >= 4) {
+	collectioninfo_t cinfo;
+	cinfo.gsdl_gsdlhome = cfgline[1];
+	cinfo.gsdl_collecthome = cfgline[2];
+	cinfo.gsdl_dbhome = cfgline[3];
+	configinfo.collectinfo[cfgline[0]] = cinfo;
+      }
+    }
+
+    // Read in the value for the site_auth directive either true or false
+    else if (key == "site_auth") configinfo.site_auth = (cfgline[0] == "true");
+
+    else if (key == "site_group")
+       joinchar(cfgline,',',configinfo.site_group);
+       
+    else if (key == "SiteFormat") {
+       if (cfgline[0] == "HomePageType") {
+	  configinfo.HomePageType = cfgline[1];
+       } else if (cfgline[0] == "HomePageCols") {
+	  configinfo.HomePageCols = cfgline[1].getint();
+       }
+    }
+       
+    else if (key == "cgiarg") {
+      // get shortname
+      bool seen_defaultstatus = false;
+      text_t subkey, subvalue;
+      text_t shortname;
+      text_t::const_iterator cfglinesub_here;
+      text_tarray::const_iterator cfgline_here = cfgline.begin();
+      text_tarray::const_iterator cfgline_end = cfgline.end();
+      while (cfgline_here != cfgline_end) {
+	cfglinesub_here = getdelimitstr((*cfgline_here).begin(),
+					(*cfgline_here).end(), '=', subkey);
+	if (subkey == "shortname") {
+	  shortname = substr (cfglinesub_here, (*cfgline_here).end());
+	}
+	++cfgline_here;
+      }
+
+      // if we found the shortname process the line again filling in values
+      if (!shortname.empty()) {
+	cgiarginfo &chinfo = argsinfo[shortname];
+	chinfo.shortname = shortname; // in case this is a new argument
+	
+	cfgline_here = cfgline.begin();
+	while (cfgline_here != cfgline_end) {
+	  cfglinesub_here = getdelimitstr((*cfgline_here).begin(),
+					  (*cfgline_here).end(), '=', subkey);
+	  subvalue = substr (cfglinesub_here, (*cfgline_here).end());
+
+	  if (subkey == "longname") chinfo.longname = subvalue;
+	  else if (subkey == "multiplechar") chinfo.multiplechar = (subvalue == "true");
+	  else if (subkey == "multiplevalue") chinfo.multiplevalue = (subvalue == "true");
+	  else if (subkey == "defaultstatus") {
+	    seen_defaultstatus = true;
+	    if (subvalue == "none") chinfo.defaultstatus = cgiarginfo::none;
+	    else if (subvalue == "weak") chinfo.defaultstatus = cgiarginfo::weak;
+	    else if (subvalue == "good") chinfo.defaultstatus = cgiarginfo::good;
+	    else if (subvalue == "config") chinfo.defaultstatus = cgiarginfo::config;
+	    else if (subvalue == "imperative") chinfo.defaultstatus = cgiarginfo::imperative;
+	  }
+	  else if (subkey == "argdefault") {
+	    chinfo.argdefault = subvalue;
+	    if (!seen_defaultstatus) chinfo.defaultstatus = cgiarginfo::config;
+	  }
+	  else if (subkey == "savedarginfo") {
+	    if (subvalue == "mustnot") chinfo.savedarginfo = cgiarginfo::mustnot;
+	    else if (subvalue == "can") chinfo.savedarginfo = cgiarginfo::can;
+	    else if (subvalue == "must") chinfo.savedarginfo = cgiarginfo::must;
+	  }
+	  
+	  ++cfgline_here;
+	}
+      }
+
+    } else if (key == "Encoding") {
+
+      configure_encoding (cfgline);
+
+    } else if (key == "Language") {
+      text_t subkey, subvalue, shortname;
+      languageinfo_t lang;
+      text_t::const_iterator cfglinesub_here;
+      text_tarray::const_iterator cfgline_here = cfgline.begin();
+      text_tarray::const_iterator cfgline_end = cfgline.end();
+      while (cfgline_here != cfgline_end) {
+	cfglinesub_here = getdelimitstr((*cfgline_here).begin(),
+					(*cfgline_here).end(), '=', subkey);
+	if (subkey == "shortname") {
+	  shortname = substr (cfglinesub_here, (*cfgline_here).end());
+	} else if (subkey == "longname") {
+	  lang.longname = substr (cfglinesub_here, (*cfgline_here).end());
+	} else if (subkey == "default_encoding") {
+	  lang.defaultencoding = substr (cfglinesub_here, (*cfgline_here).end());
+	}
+	++cfgline_here;
+      }
+      if (!shortname.empty()) {
+	if (lang.longname.empty()) lang.longname = shortname;
+	configinfo.languages[shortname] = lang;
+      }
+    }
+  }
+  
+  // configure the actions
+  actionptrmap::iterator actionhere = actions.begin ();
+  actionptrmap::iterator actionend = actions.end ();
+
+  while (actionhere != actionend) {
+    assert ((*actionhere).second.a != NULL);
+    if ((*actionhere).second.a != NULL) 
+      (*actionhere).second.a->configure(key, cfgline);
+
+    ++actionhere;
+  }
+
+  // configure the protocols
+  recptprotolistclass::iterator protohere = protocols.begin ();
+  recptprotolistclass::iterator protoend = protocols.end ();
+
+  while (protohere != protoend) {
+    assert ((*protohere).p != NULL);
+    comerror_t err;
+    if ((*protohere).p != NULL) 
+      (*protohere).p->configure(key, cfgline, err);
+    
+    ++protohere;
+  }
+
+  // configure the browsers
+  browserptrmap::iterator browserhere = browsers.begin ();
+  browserptrmap::iterator browserend = browsers.end ();
+
+  while (browserhere != browserend) {
+    assert ((*browserhere).second.b != NULL);
+    if ((*browserhere).second.b != NULL) 
+      (*browserhere).second.b->configure(key, cfgline);
+    
+    ++browserhere;
+  }
+}
+
+
+void receptionist::configure (const text_t &key, const text_t &value) {
+  text_tarray cfgline;
+  cfgline.push_back (value);
+  configure(key, cfgline);
+}
+
+
+// init should be called after all the actions and protocols have been
+// added to the receptionist and after everything has been configured but
+// before any pages are created.  It returns true on success and false on
+// failure. If false is returned getpage should not be called (without
+// producing meaningless output), instead an error page should be produced
+// by the calling code.
+bool receptionist::init (ostream &logout) {
+
+  // first configure collectdir
+  if (!configinfo.collection.empty()) {
+
+    // collection specific mode
+
+    text_t collectdir = configinfo.gsdlhome;
+
+    if (!configinfo.collectdir.empty()) {
+      // has already been configured
+      collectdir = configinfo.collectdir;
+    } else {
+
+      // decide where collectdir is by searching for collect.cfg
+      // look in $GSDLHOME/collect/collection-name/etc/collect.cfg and
+      // then $GSDLHOME/etc/collect.cfg
+      collectdir = filename_cat (configinfo.gsdlhome, "collect");
+      collectdir = filename_cat (collectdir, configinfo.collection);
+      text_t filename = filename_cat (collectdir, "etc");
+      filename = filename_cat (filename, "collect.cfg");
+      
+      if (!file_exists(filename)) collectdir = configinfo.gsdlhome;
+    }
+
+    configure("collectdir", collectdir);
+
+  }
+  else {
+
+    text_t collecthome;
+    if (configinfo.collecthome.empty()) {
+      collecthome = filename_cat(configinfo.gsdlhome,"collect");
+    }
+    else {
+      collecthome = configinfo.collecthome;
+    }
+
+    configure("collecthome", collecthome);
+
+    // for backwards compatability collectdir set to gsdlhome
+    // (possible it could now be removed)
+    configure("collectdir", configinfo.gsdlhome); 
+  } 
+
+
+  // read in the macro files
+  if (!read_macrofiles (logout)) return false;
+
+  // there must be at least one action defined
+  if (actions.empty()) {
+    logout << "Error: no actions have been added to the receptionist\n";
+    return false;
+  }
+
+  // there must be at least one browser defined
+  if (browsers.empty()) {
+    logout << "Error: no browsers have been added to the receptionist\n";
+    return false;
+  }
+
+  // create a saveconf string if there isn't one already
+  if (configinfo.saveconf.empty())
+    configinfo.saveconf = create_save_conf_str (argsinfo, logout);
+
+  // check the saveconf string
+  if (!check_save_conf_str (configinfo.saveconf, argsinfo, logout))
+    return false;
+
+  // set a random seed
+  srand (time(NULL));
+
+  // if maintainer email address is something dodgy (for now I'll define
+  // dodgy as being anything that doesn't contain '@') disable EmailEvents
+  // and EmailUserEvents (we don't strictly need to disable EmailUserEvents
+  // in this case but we will as it seems likely that MailServer will also
+  // be screwed up if maintainer is).
+  text_t::const_iterator maintainer_end = configinfo.maintainer.end ();
+  text_t::const_iterator maintainer_here = findchar ((text_t::const_iterator)configinfo.maintainer.begin(),
+						     maintainer_end, '@');
+  if (maintainer_here == maintainer_end) {
+    configinfo.EmailEvents = Disabled;
+    configinfo.EmailUserEvents = Disabled;
+  } else {
+    // if MailServer isn't set it should default to mail.maintainer-domain
+    if (configinfo.MailServer.empty()) {
+      configinfo.MailServer = "mail." + substr (maintainer_here+1, maintainer_end);
+    }
+  }
+
+  // init the actions
+  actionptrmap::iterator actionhere = actions.begin ();
+  actionptrmap::iterator actionend = actions.end ();
+  while (actionhere != actionend) {
+    if (((*actionhere).second.a == NULL) || 
+	!(*actionhere).second.a->init(logout)) return false;
+    ++actionhere;
+  }
+
+  // init the protocols
+  recptprotolistclass::iterator protohere = protocols.begin ();
+  recptprotolistclass::iterator protoend = protocols.end ();
+  while (protohere != protoend) {
+    comerror_t err;    
+    if (((*protohere).p == NULL) ||
+	!(*protohere).p->init(err, logout)) return false;
+    ++protohere;
+  }
+
+  // init the browsers
+  browserptrmap::iterator browserhere = browsers.begin ();
+  browserptrmap::iterator browserend = browsers.end ();
+  while (browserhere != browserend) {
+    if (((*browserhere).second.b == NULL) || 
+	!(*browserhere).second.b->init(logout)) return false;
+    ++browserhere;
+  }
+
+  return true;
+}
+
+// get the default encoding for the given language - if it fails for any
+// reason return ""
+text_t receptionist::get_default_encoding (const text_t &language) {
+  
+  // make sure language is valid
+  if (configinfo.languages.find(language) == configinfo.languages.end()) return "";
+
+  text_t default_encoding = configinfo.languages[language].defaultencoding;
+
+  // make sure the encoding is valid
+  if (converters.find(default_encoding) == converters.end()) {
+    // we don't support the encoding specified as default for this language
+    if (configinfo.encodings.size()==1) {
+      // only 1 encoding specified in main.cfg, so use it
+      return configinfo.encodings.begin()->second;
+    }
+    return "";
+  }
+
+  return default_encoding;
+}
+
+// parse_cgi_args parses cgi arguments into an argument class.
+// This function should be called for each page request. It returns false
+// if there was a major problem with the cgi arguments.
+bool receptionist::parse_cgi_args (const text_t &argstr, 
+				   fileupload_tmap &fileuploads, 
+				   cgiargsclass &args, 
+				   ostream &logout, text_tmap &fcgienv) {
+
+  // get an initial list of cgi arguments
+  args.clear();
+  split_cgi_args (argsinfo, argstr, args);
+
+  // expand the compressed argument (if there was one)
+  if (!expand_save_args (argsinfo, configinfo.saveconf, args, logout)) return false;
+
+  // add the defaults
+  add_default_args (argsinfo, args, logout);
+
+  // add any file upload arguments
+  add_fileupload_args(argsinfo, args, fileuploads, logout);
+
+  // get the cookie
+  if (configinfo.usecookies) get_cookie(args["z"], fcgienv);
+  
+  // if we're changing languages, set the encoding to the default for the new language
+  if (args["nl"] == "1") {
+    args["nw"] = get_default_encoding(args["l"]);
+  }
+
+  // get the input encoding
+  // if encoding isn't set, set it to the default for the current language
+  if ((args.getarg("w") == NULL) || args["w"].empty()) {
+    args["w"] = get_default_encoding(args["l"]);
+  }
+
+  text_t &arg_w = args["w"];
+
+  inconvertclass defaultinconvert;
+  inconvertclass *inconvert = converters.get_inconverter (arg_w);
+  if (inconvert == NULL) inconvert = &defaultinconvert;
+
+  // see if the next page will have a different encoding
+  if (args.getarg("nw") != NULL) arg_w = args["nw"];
+
+  // convert arguments which aren't in unicode to unicode
+  args_tounicode (args, *inconvert);
+
+
+  // decide on the output conversion class (needed for checking the external
+  // cgi arguments)
+  rzwsoutconvertclass defaultoutconverter;
+  rzwsoutconvertclass *outconverter = converters.get_outconverter (arg_w);
+  if (outconverter == NULL) outconverter = &defaultoutconverter;
+  outconverter->reset();
+
+  // check the main cgi arguments
+  if (!check_mainargs (args, logout)) return false;
+
+  // check the arguments for the action
+  action *a = actions.getaction (args["a"]);
+  if (a != NULL) {
+    if (!a->check_cgiargs (argsinfo, args, &protocols, logout)) return false;
+  } else {
+    // the action was not found!!
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii << "Error: the action \"" << args["a"] 
+	   << "\" could not be found.\n";
+    return false;
+  }
+
+  // check external cgi arguments for each action
+  actionptrmap::iterator actionhere = actions.begin ();
+  actionptrmap::iterator actionend = actions.end ();
+  while (actionhere != actionend) {
+    assert ((*actionhere).second.a != NULL);
+    if ((*actionhere).second.a != NULL) {
+      if (!(*actionhere).second.a->check_external_cgiargs (argsinfo, args, *outconverter,
+							   configinfo.saveconf, logout))
+	return false;
+    }
+    ++actionhere;
+  }
+
+  // the action might have changed but we will assume that
+  // the cgiargs were checked properly when the change was made
+
+  return true;
+}
+
+
+// Returns true if cookie already existed, false if it was generated
+bool receptionist::get_cookie (text_t &cookie, text_tmap &fcgienv)
+{
+  // See if we can get the GSDL_UID cookie
+  text_t cookiestring = gsdl_getenv ("HTTP_COOKIE", fcgienv);
+  if (!cookiestring.empty()) // This should really be handled by the findword function...
+  {
+    // Check if the cookie contains GSDL_UID
+    text_t gsdl_uid = "GSDL_UID=";
+    text_t::iterator gsdl_uid_start = findword(cookiestring.begin(), cookiestring.end(), gsdl_uid);
+    if (gsdl_uid_start != cookiestring.end())
+    {
+      // Yes, so extract its value
+      cookie = substr(gsdl_uid_start + gsdl_uid.size(), findchar(gsdl_uid_start + gsdl_uid.size(), cookiestring.end(), ';'));
+      return true;
+    }
+  }
+
+  // Generate a new key "[host]-[epoch time]", e.g. test.com-1256764496
+  cookie.clear();
+  text_t host = gsdl_getenv("REMOTE_ADDR", fcgienv);
+  time_t ttime = time(NULL);
+  if (!host.empty())
+  {
+    cookie += host;
+    cookie.push_back ('-');
+  }
+  cookie += text_t(ttime);
+
+  return false;
+}
+
+
+// Same as above but just tests if cookie exists
+bool receptionist::get_cookie (text_tmap &fcgienv)
+{
+  text_t cookie_jar = "";
+  return get_cookie(cookie_jar, fcgienv);
+}
+
+
+bool receptionist::log_cgi_args (cgiargsclass &args, ostream &logout, text_tmap &fcgienv) {
+
+  // see if we want to log the cgi arguments
+  if (!configinfo.logcgiargs) return true;
+  
+  text_t host = gsdl_getenv ("REMOTE_HOST", fcgienv);
+  text_t script_name = gsdl_getenv ("SCRIPT_NAME", fcgienv);
+  if (host.empty()) host = gsdl_getenv ("REMOTE_ADDR", fcgienv);
+  text_t browser = gsdl_getenv ("HTTP_USER_AGENT", fcgienv);
+
+  cgiargsclass::const_iterator args_here = args.begin();
+  cgiargsclass::const_iterator args_end = args.end();
+
+  text_t argstr;
+  bool first = true;
+  while (args_here != args_end) {
+    if (!first) argstr += ", ";
+    argstr += (*args_here).first + "=" + (*args_here).second.value;
+    first = false;
+    ++args_here;
+  }
+
+  text_t logfile = filename_cat (configinfo.dbhome, "etc", "usage.txt");
+
+  text_t logstr = script_name;
+  logstr += " " + host;
+  logstr += " [";
+  if (configinfo.LogDateFormat == UTCTime) {
+    logstr += get_date (false);
+  } else if (configinfo.LogDateFormat == Absolute) {
+    time_t ttime = time(NULL);
+    logstr += ttime;
+  } else {
+    // LocalTime
+    logstr += get_date (true);
+  }
+  logstr += "] (" + argstr + ") \"";
+  logstr += browser;
+  logstr += "\"\n";
+
+  return append_logstr (logfile, logstr, logout);
+}
+
+bool receptionist::append_logstr (const text_t &filename, const text_t &logstr,
+				  ostream &logout) {
+
+  char *lfile = filename.getcstr();
+
+  int fd = open(lfile, O_CREAT | O_WRONLY | O_APPEND, 0777);
+  //int fd = open(lfile, O_CREAT | O_RDWR | O_APPEND, 0777);
+  
+  if (fd == -1) {
+    logout << "Error: Couldn't open file " << lfile << "\n";
+    delete []lfile;
+    return false;
+  }
+
+  // lock_val is set to 0 if file is locked successfully
+  int lock_val = 1;
+  GSDL_LOCK_FILE (fd);
+  if (lock_val == 0) {
+    // Write the string out in UTF-8
+    text_t tmp_log_str_utf8 = to_utf8(logstr);
+    char *buffer = tmp_log_str_utf8.getcstr();
+    size_t num_chars = tmp_log_str_utf8.size();
+    write(fd, buffer, num_chars);
+    GSDL_UNLOCK_FILE (fd);
+    delete []buffer;
+  } else {
+    logout << "Error: Couldn't lock file " << lfile << "\n";
+    close(fd);
+    delete []lfile;
+    return false;
+  }
+
+  close(fd);
+		
+  delete []lfile;
+  return true;
+}
+
+text_t receptionist::expandmacros (const text_t &astring, cgiargsclass &args, 
+				   ostream &logout) {
+  text_t outstring;
+  outconvertclass text_t2ascii;
+
+  action *a = actions.getaction (args["a"]);
+  if (a != NULL)
+  {
+    prepare_page (a, args, text_t2ascii, logout);
+  }
+  disp.expandstring (displayclass::defaultpackage, astring, outstring);
+  return outstring;
+}
+
+// produce_cgi_page will call get_cgihead_info and 
+// produce_content in the appropriate way to output a cgi header and
+// the page content (if needed). If a page could not be created it
+// will return false
+bool receptionist::produce_cgi_page (cgiargsclass &args, ostream &contentout, 
+				     ostream &logout, text_tmap &fcgienv) {
+  outconvertclass text_t2ascii;
+
+  response_t response;
+  text_t response_data;
+
+  // produce cgi header
+  get_cgihead_info (args, response, response_data, logout, fcgienv);
+  if (response == location) {
+    // location response (url may contain macros!!)
+    response_data = expandmacros (response_data, args, logout);
+
+    contentout << text_t2ascii << "Location: " << response_data << "\n\n";
+    contentout << flush;
+
+    return true;
+  } else if (response == content) {
+    // content response
+
+#ifdef GSDL_NOCACHE
+    contentout << "Expires: Mon, 26 Jul 1997 05:00:00 GMT\n"; // date in the past
+    tm *tm_ptr = NULL;
+    time_t t = time(NULL);
+    tm_ptr = gmtime (&t);
+    if (tm_ptr != NULL) {
+      char *timestr = new char[128];
+      strftime (timestr, 128, "%a, %d %b %Y %H:%M:%S", tm_ptr);
+      contentout << "Last-Modified: " << timestr << " GMT\n"; // always modified
+      delete []timestr;
+    }
+    contentout << "Cache-Control: no-cache, must-revalidate\n"; // HTTP/1.1
+    contentout << "Pragma: no-cache\n"; // HTTP/1.0
+
+#else
+
+    // use the later of build.cfg and collect.cfg modification times
+    // as the Last-Modified: header, for caching values
+    struct stat file_info;
+    time_t latest=0;
+
+    text_t collectname="";
+    collectname=args["c"];
+    if (collectname != "") {
+
+      text_t collecthome;
+      if (!configinfo.collecthome.empty()) {
+	collecthome = configinfo.collecthome;
+      }    
+      else {
+	collecthome=filename_cat(configinfo.gsdlhome,"collect");
+      }
+      text_t collectdir=filename_cat(collecthome,collectname);
+      
+      text_t buildcfg=filename_cat(collectdir,"index");
+      buildcfg=filename_cat(buildcfg,"build.cfg");
+      char *buildcfg_ptr=buildcfg.getcstr();
+      text_t collectcfg=filename_cat(collectdir,"etc");
+      collectcfg=filename_cat(collectcfg,"collect.cfg");
+      char *collectcfg_ptr=collectcfg.getcstr();
+
+      if (stat(buildcfg_ptr, &file_info)) {
+	// we got an error. Currently don't handle error :(
+	//	logout << 
+      } else {
+	latest=file_info.st_mtime;
+      }
+    
+      if (stat(collectcfg_ptr, &file_info)) {
+	// error - unhandled for now
+      } else {
+	if (latest<file_info.st_mtime) latest=file_info.st_mtime;
+      }
+      delete []buildcfg_ptr;
+      delete []collectcfg_ptr;
+
+      if (latest>0) {
+	// print out modified time, "DDD, dd MMM YYYY hh:mm:ss" format
+	// c library takes care of mem for this string... (has \n at end!!!!)
+	// latest is currently local time, convert to UTC.
+	struct tm* utc_latest;
+	utc_latest=gmtime(&latest);
+	contentout << "Last-Modified: " << asctime(utc_latest);
+      }
+    } // end of collection != ""
+
+#endif
+
+    contentout << text_t2ascii << "Content-type: " << response_data << "\n\n";
+  }
+  else if (response == undecided_location) {
+    // Wait until later to output the target location
+    // Used for the "I'm feeling lucky" functionality
+  }
+  else {
+    // unknown response
+    logout << "Error: get_cgihead_info returned an unknown response type.\n";
+    return false;
+  }
+
+  // produce cgi page
+  if (!produce_content (args, contentout, logout)) return false;
+
+  // flush contentout
+  contentout << flush;
+  return true;
+}
+
+
+// get_cgihead_info determines the cgi header information for
+// a set of cgi arguments. If response contains location then
+// response_data contains the redirect address. If reponse
+// contains content then reponse_data contains the content-type.
+// Note that images can now be produced by the receptionist.
+// Note also, alternative for get_cgihead_info below which
+// stores the information in a text_tmap so it is more easily digested
+
+void receptionist::get_cgihead_info (cgiargsclass &args, response_t &response,
+				     text_t &response_data, ostream &logout, 
+				     text_tmap &fcgienv) {
+  outconvertclass text_t2ascii;
+
+  // get the action
+  action *a = actions.getaction (args["a"]);
+  if (a != NULL) {
+    a->get_cgihead_info (args, &protocols, response, response_data, logout);
+
+  } else {
+    // the action was not found!!
+    logout << text_t2ascii << "Error receptionist::get_cgihead_info: the action \"" 
+	   << args["a"] << "\" could not be found.\n";
+    response = content;
+    response_data = "text/html";
+  }
+
+  // add the encoding information
+  if (response == content) {
+    if (converters.find(args["w"]) != converters.end()) {
+      response_data += "; charset=" + args["w"];
+    } else {
+      // default to latin 1
+      response_data += "; charset=ISO-8859-1";
+    }
+
+    // add cookie if required
+    if (configinfo.usecookies && !get_cookie(fcgienv))
+      response_data += "\nSet-Cookie: GSDL_UID=" + args["z"]
+	+ "; expires=Fri, 25-Dec-2037 00:00:00 GMT";
+  }
+}
+
+
+// Alternative version of get_cgihead_info, stores fielded infomation
+// in text_tmap rather than concatenated string
+void receptionist::get_cgihead_info (cgiargsclass &args, text_tmap &headers,
+				     ostream &logout, text_tmap &fcgienv) {
+
+  response_t response;
+  text_t response_data;
+
+  // get the action
+  action *a = actions.getaction (args["a"]);
+  if (a != NULL) {
+    a->get_cgihead_info (args, &protocols, response, response_data, logout);
+
+  } else {
+    // the action was not found!!
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii << "Error receptionist::get_cgihead_info: the action \"" 
+	   << args["a"] << "\" could not be found.\n";
+    response = content;
+    response_data = "text/html";
+  }
+
+  if (response == location) {
+    response_data = expandmacros(response_data, args, logout);
+    headers["Location"] = response_data;
+    return;
+  }
+
+  // add the encoding information
+  if (response == content) {
+
+    if (converters.find(args["w"]) != converters.end()) {
+      headers["content-encoding"] = args["w"];
+      response_data += "; charset=" + args["w"];
+    } else {
+      // default to utf-8
+      headers["content-encoding"] = "utf-8";
+      response_data += "; charset=utf-8";
+    }
+
+    headers["content-type"] = response_data;
+
+  }
+
+}
+
+
+
+// produce the page content
+bool receptionist::produce_content (cgiargsclass &args, ostream &contentout,
+				    ostream &logout) {
+
+  // decide on the output conversion class
+  text_t &arg_w = args["w"];
+  rzwsoutconvertclass defaultoutconverter;
+  rzwsoutconvertclass *outconverter = converters.get_outconverter (arg_w);
+  if (outconverter == NULL) outconverter = &defaultoutconverter;
+  outconverter->reset();
+
+  // needed for 16-bit unicode only - big endian marker 0xfeff (RFC 2781)
+  if (arg_w=="utf-16be") {
+    contentout << '\xfe' << '\xff' ;
+  }
+
+  recptproto *collectproto = protocols.getrecptproto (args["c"], logout);
+  if (collectproto != NULL) {
+    // get browsers to process OID
+    text_t OID = args["d"];
+    if (OID.empty()) OID = args["cl"];
+    if (!OID.empty()) {
+      text_tset metadata;
+      text_tarray OIDs;
+      OIDs.push_back (OID);
+      if (!is_top(OID)) OIDs.push_back (OID + ".pr");
+      FilterResponse_t response;
+      metadata.insert ("childtype");
+      if (get_info (OIDs, args["c"], args["l"], metadata, false, collectproto, response, logout)) {
+	text_t classifytype;
+	if (!response.docInfo[0].metadata["childtype"].values[0].empty())
+	  classifytype = response.docInfo[0].metadata["childtype"].values[0];
+	else if (!is_top (OID)) {
+	  // not sure why this is occasionally not set, but it will
+	  // cause a segfault... possibly if built with no_text? jrm21
+	  if (response.docInfo[1].metadata.find("childtype")
+	      == response.docInfo[1].metadata.end()) {
+	    cerr << "receptionist: no childtype element in metadata map!"
+		 << endl;
+	  } else {
+	    if (!response.docInfo[1].metadata["childtype"].values[0].empty())
+	      classifytype = response.docInfo[1].metadata["childtype"].values[0];
+	  }
+	}
+	browserclass *b = browsers.getbrowser (classifytype);
+	b->processOID (args, collectproto, logout);
+      }
+    }
+  
+    // translate "d" and "cl" arguments if required
+    translate_OIDs (args, collectproto, logout);
+  }
+  
+  // produce the page using the desired action
+  action *a = actions.getaction (args["a"]);
+  if (a != NULL) {
+    if (a->uses_display(args)) prepare_page (a, args, (*outconverter), logout);
+    if (!a->do_action (args, &protocols, &browsers, disp, (*outconverter), contentout, logout))
+      return false;
+  } else {
+    // the action was not found!!
+    outconvertclass text_t2ascii;
+
+    logout << text_t2ascii << "Error receptionist::produce_content: the action \"" 
+	   << args["a"] << "\" could not be found.\n";
+    
+    contentout << (*outconverter) 
+	       << "<html>\n"
+	       << "<head>\n"
+	       << "<title>Error</title>\n"
+	       << "</head>\n"
+	       << "<body>\n"
+	       << "<h2>Oops!</h2>\n"
+	       << "Undefined Page. The action \"" 
+	       << args["a"] << "\" could not be found.\n"
+	       << "</body>\n"
+	       << "</html>\n";
+  }
+  return true;
+}
+
+
+// returns the compressed argument ("e") corresponding to the argument
+// list. This can be used to save preferences between sessions.
+text_t receptionist::get_compressed_arg (cgiargsclass &args, ostream &logout) {
+  // decide on the output conversion class
+  text_t &arg_w = args["w"];
+  rzwsoutconvertclass defaultoutconverter;
+  rzwsoutconvertclass *outconverter = converters.get_outconverter (arg_w);
+  if (outconverter == NULL) outconverter = &defaultoutconverter;
+  outconverter->reset();
+
+  text_t compressed_args;
+  if (compress_save_args (argsinfo, configinfo.saveconf, args, 
+			  compressed_args, *outconverter, logout))
+    return compressed_args;
+
+  return g_EmptyText;
+}
+
+
+// will read in all the macro files. If one is not found an
+// error message will be written to logout and the method will
+// return false.
+bool receptionist::read_macrofiles (ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  // redirect the error output to logout
+  ostream *savedlogout = disp.setlogout (&logout);
+
+  // unload any macros that were previously loaded - this allows us to call
+  // this function a second time to reload all the macro files (useful for
+  // reading in changed macro files in server versions of greenstone)
+  disp.unloaddefaultmacros();
+
+  // load up the default macro files, the collection directory
+  // is searched first for the file (if this is being used in
+  // collection specific mode) and then the main directory(s)
+  text_t colmacrodir = filename_cat (configinfo.collectdir, "macros");
+
+  text_tset maindirs;
+  text_t gsdlmacrodir = filename_cat (configinfo.gsdlhome, "macros");
+  maindirs.insert (gsdlmacrodir);
+  colinfo_tmap::iterator colhere = configinfo.collectinfo.begin();
+  colinfo_tmap::iterator colend = configinfo.collectinfo.end();
+  while (colhere != colend) {
+    if (!((*colhere).second.gsdl_gsdlhome).empty()) {
+      gsdlmacrodir = filename_cat ((*colhere).second.gsdl_gsdlhome, "macros");
+      maindirs.insert (gsdlmacrodir);
+    }
+    ++colhere;
+  }
+
+  text_tset::iterator arrhere = configinfo.macrofiles.begin();
+  text_tset::iterator arrend = configinfo.macrofiles.end();
+  text_t filename;
+  while (arrhere != arrend) {
+    bool foundfile = false;
+
+    // try in the collection directory if this is being
+    // run in collection specific mode
+    if (!configinfo.collection.empty()) {
+      filename = filename_cat (colmacrodir, *arrhere);
+      if (file_exists (filename)) {
+	disp.loaddefaultmacros(filename);
+	foundfile = true;
+      }
+    }
+
+    // if we haven't found the macro file yet try in
+    // the main macro directory(s)
+    // if file is found in more than one main directory
+    // we'll load all copies
+    if (!foundfile) {
+      text_tset::const_iterator dirhere = maindirs.begin();
+      text_tset::const_iterator dirend = maindirs.end();
+      while (dirhere != dirend) {
+	filename = filename_cat (*dirhere, *arrhere);
+	if (file_exists (filename)) {
+	  disp.loaddefaultmacros(filename);
+	  foundfile = true;
+	}
+	++dirhere;
+      }
+    }
+
+    // see if we found the file or not
+    if (!foundfile) {
+      logout << text_t2ascii 
+	     << "Error: the macro file \"" << *arrhere << "\" could not be found.\n";
+      if (configinfo.collection.empty()) {
+	text_t dirs;
+	joinchar (maindirs, ", ", dirs);
+	logout << text_t2ascii 
+	       << "It should be in either of the following directories ("
+	       << dirs << ").\n\n";
+
+      } else {
+	logout << text_t2ascii
+	       << "It should be in either " << colmacrodir << " or in " 
+	       << gsdlmacrodir << ".\n\n";
+      }
+      // don't crap out if a macro file is missing
+      //disp.setlogout (savedlogout);
+      //return false;
+    }
+    ++arrhere;
+  }
+
+  // success
+
+  // reset logout to what it was
+  disp.setlogout (savedlogout);
+  return true;
+}
+
+
+
+
+// Go through the list of macro files looking to see
+// if any exist in the collectoin specific area.  If they
+// do then read them in and add them to the set of existing
+// current macros
+
+void receptionist::read_collection_macrofiles (const text_t& collection, ostream &logout) 
+{
+  outconvertclass text_t2ascii;
+
+  // disp.unloadcollectionmacros();
+
+  // redirect the error output to logout
+  ostream *savedlogout = disp.setlogout (&logout);
+
+  text_t colmacrodir 
+    = filename_cat (configinfo.collecthome,collection, "macros");
+
+  if (directory_exists (colmacrodir)) {
+
+    text_tset::iterator arrhere = configinfo.macrofiles.begin();
+    text_tset::iterator arrend = configinfo.macrofiles.end();
+    text_t filename;
+    while (arrhere != arrend) {
+
+      filename = filename_cat (colmacrodir, *arrhere);
+      if (file_exists (filename)) {
+	disp.loadcollectionmacros(filename);
+      }
+      
+      ++arrhere;
+    }
+  }
+
+  // reset logout to what it was
+  disp.setlogout (savedlogout);
+}
+
+
+
+
+// check_mainargs will check all the main arguments. If a major
+// error is found it will return false and no cgi page should
+// be created using the arguments.
+
+bool receptionist::check_mainargs (cgiargsclass &args, ostream &logout) {
+   
+   if(configinfo.site_auth)
+      {
+	 args["uan"] = "1";
+	 args["ug"] = configinfo.site_group;
+      }
+   
+   
+   // if this receptionist is running in collection dependant mode
+   // then it should always set the collection argument to the
+   // collection
+   if (!configinfo.collection.empty()) args["c"] = configinfo.collection;
+   
+   // if current collection uses ccscols make sure
+   // "ccs" argument is set and make "cc" default to
+   // all collections in "ccs"
+   if (args["a"] != "config" && !args["c"].empty()) {
+      
+      text_t &arg_c = args["c"];
+      recptproto *collectproto = protocols.getrecptproto (arg_c, logout);
+      if (collectproto == NULL) {
+	 // oops, this collection isn't valid
+	 outconvertclass text_t2ascii;
+	 logout << text_t2ascii << "ERROR: Invalid collection: " << arg_c << "\n";
+	 // args["c"].clear();
+	 
+      } else {
+	 
+	 ColInfoResponse_t *cinfo = get_collectinfo_ptr (collectproto, arg_c, logout);
+	 
+	 if(cinfo->authenticate == "collection")
+	    {
+	       args["uan"] = "1";
+	       args["ug"] = cinfo->auth_group;
+	    }
+	 
+	 
+      if (cinfo != NULL) {
+	 if (!cinfo->ccsCols.empty()) {
+	    args["ccs"] = 1;
+	    if (args["cc"].empty()) {
+	       text_tarray::const_iterator col_here = cinfo->ccsCols.begin();
+	       text_tarray::const_iterator col_end = cinfo->ccsCols.end();
+	       bool first = true;
+	       while (col_here != col_end) {
+		  // make sure it's a valid collection
+		  if (protocols.getrecptproto (*col_here, logout) != NULL) {
+		     if (!first) args["cc"].push_back (',');
+		     args["cc"] += *col_here;
+		     first = false;
+		  }
+	      ++col_here;
+	    }
+	  }
+	}
+      } else {
+	logout << "ERROR (receptionist::check_mainargs): get_collectinfo_ptr returned NULL\n";
+      }
+    }
+  }
+
+  // argument "v" can only be 0 or 1. Use the default value
+  // if it is out of range
+  int arg_v = args.getintarg ("v");
+  if (arg_v != 0 && arg_v != 1) {
+    cgiarginfo *vinfo = argsinfo.getarginfo ("v");
+    if (vinfo != NULL) args["v"] = vinfo->argdefault;
+  }
+
+  // argument "f" can only be 0 or 1. Use the default value
+  // if it is out of range
+  int arg_f = args.getintarg ("f");
+  if (arg_f != 0 && arg_f != 1) {
+    cgiarginfo *finfo = argsinfo.getarginfo ("f");
+    if (finfo != NULL) args["f"] = finfo->argdefault;
+  }
+
+  return true;
+}
+
+// translate_OIDs translates the "d" and "cl" arguments to their correct values
+// if they use the tricky ".fc", ".lc" type syntax.
+void receptionist::translate_OIDs (cgiargsclass &args, recptproto *collectproto, 
+				   ostream &logout) {
+
+  FilterResponse_t response;
+  FilterRequest_t request;
+  comerror_t err;
+  text_t &arg_d = args["d"];
+  text_t &arg_cl = args["cl"];
+  text_t &collection = args["c"];
+  
+  // do a call to translate OIDs if required
+  request.filterName = "NullFilter";
+  request.filterResultOptions = FROID;
+  if (!arg_d.empty() && needs_translating (arg_d)) {
+    request.docSet.push_back (arg_d);
+    collectproto->filter (collection, request, response, err, logout);
+    arg_d = response.docInfo[0].OID;
+    request.clear();
+  }
+  // we'll also check here that the "cl" argument has a "classify" doctype 
+  // (in case ".fc" or ".lc" have screwed up)
+  if (needs_translating (arg_cl)) {
+    request.fields.insert ("doctype");
+    request.docSet.push_back (arg_cl);
+    request.filterResultOptions = FRmetadata;
+    collectproto->filter (collection, request, response, err, logout);
+    // set to original value (without .xx stuff) if doctype isn't "classify"
+    if (response.docInfo[0].metadata["doctype"].values[0] != "classify")
+      strip_suffix (arg_cl);
+    else
+      arg_cl = response.docInfo[0].OID;
+  }
+}
+
+// prepare_page sets up page parameters, sets display macros
+// and opens the page ready for output 
+void receptionist::prepare_page (action *a, cgiargsclass &args, 
+				 outconvertclass &outconvert, 
+				 ostream &logout) {
+  // set up page parameters
+  text_t pageparams;
+  bool first = true;
+
+  text_tmap::iterator params_here = configinfo.pageparams.begin();
+  text_tmap::iterator params_end = configinfo.pageparams.end();
+  while (params_here != params_end) {
+    // page params are those from main.cfg (eg pageparam v 0) plus
+    // two defaults set in recptconf.clear() (c="" and l=en)
+    // This used to check if the current value of the page param
+    // == the default value, then don't add in it the list
+    // but if l=en, and there is a macro with [l=en], then it doesn't
+    // find it.
+    // so now all page params will go into the list. I assume this will 
+    // mean more attempts to find each macro, but nothing worsee than 
+    // that.  --kjdon
+    //if (args[(*params_here).first] != (*params_here).second) {
+      if (first)
+	first = false;
+      else
+	pageparams += ",";
+
+      pageparams += (*params_here).first;
+      pageparams += "=";
+      pageparams += args[(*params_here).first];
+      // }
+    
+    ++params_here;
+  }
+  
+
+  // open the page
+  disp.openpage(pageparams, configinfo.macroprecedence);
+
+  disp.unloadcollectionmacros();
+
+  text_t collection = args["c"];
+  if (!collection.empty()) {
+    read_collection_macrofiles(collection,logout);
+  }
+
+  // define external macros for each action
+  actionptrmap::iterator actionhere = actions.begin ();
+  actionptrmap::iterator actionend = actions.end ();
+
+  while (actionhere != actionend) {
+    assert ((*actionhere).second.a != NULL);
+    if ((*actionhere).second.a != NULL) {
+      (*actionhere).second.a->define_external_macros (disp, args, &protocols, logout);
+    }
+    ++actionhere;
+  }
+
+
+  // define internal macros for the current action
+  a->define_internal_macros (disp, args, &protocols, logout);
+  
+  // define general macros. the defining of general macros is done here so that
+  // the last possible version of the cgi arguments are used
+  define_general_macros (args, outconvert, logout);
+}
+
+
+void receptionist::define_general_macros (cgiargsclass &args, outconvertclass &/*outconvert*/, 
+					  ostream &logout) {
+
+  text_t &collection = args["c"];
+
+  disp.setmacro ("gsdlhome", displayclass::defaultpackage, dm_safe(configinfo.gsdlhome));
+  disp.setmacro ("gwcgi", displayclass::defaultpackage, configinfo.gwcgi);
+  disp.setmacro ("httpweb", displayclass::defaultpackage, configinfo.httpweb);
+  disp.setmacro ("httpprefix", displayclass::defaultpackage, configinfo.httpprefix);
+
+  // This perhaps should be done with gsdl_getenv() which takes the
+  // 'fcgienv' parameter (for fast-cgi), however if changed to this, this
+  // additional parameter would need to be passed into here (not sure how
+  // that would effect any virtual inheritence going on), or else moved
+  // higher up the calling to chain to, e.g., produce_cgi_page()
+
+  char* remote_addr = getenv("REMOTE_ADDR");
+
+  if (remote_addr != NULL) {
+     text_t remote_addr_t(remote_addr);
+     disp.setmacro ("remoteAddr", displayclass::defaultpackage, remote_addr_t);
+  }
+
+  char* remote_host = getenv("REMOTE_HOST");
+  if (remote_host != NULL) {
+     text_t remote_host_t(remote_host);
+     disp.setmacro ("remoteHost", displayclass::defaultpackage, remote_host_t);
+  }
+  else {
+     // setting this to "unknown" is easier to deal with in format/macro
+     // statements, rather than testing for _remoteHost_
+     disp.setmacro ("remoteHost", displayclass::defaultpackage, "unknown");
+  }
+
+
+  text_t compressedoptions = get_compressed_arg(args, logout);
+  disp.setmacro ("compressedoptions", displayclass::defaultpackage, dm_safe(compressedoptions));
+  // need a decoded version of compressedoptions for use within forms
+  // as browsers encode values from forms before sending to server
+  // (e.g. %25 becomes %2525)
+  decode_cgi_arg (compressedoptions); 
+  if (args["w"] == "utf-8") { // if the encoding was utf-8, then compressed options was utf-8, and we need unicode.
+    // if encoding wasn't utf-8, then compressed opotions may be screwed up, but seems to work for 8 bit encodings?
+    compressedoptions = to_uni(compressedoptions);
+  }
+  disp.setmacro ("decodedcompressedoptions", displayclass::defaultpackage, dm_safe(compressedoptions)); 
+
+#if defined (__WIN32__)
+  disp.setmacro ("win32", displayclass::defaultpackage, "1");
+#endif
+
+  // set _cgiargX_ macros for each cgi argument
+  cgiargsclass::const_iterator argshere = args.begin();
+  cgiargsclass::const_iterator argsend = args.end();
+  while (argshere != argsend) {
+
+    text_t macrovalue = (*argshere).second.value; // and stays like that if ((*argshere).first == "hp")
+
+    if (((*argshere).first == "q") ||
+	((*argshere).first == "qa") ||
+	((*argshere).first == "qtt") ||
+	((*argshere).first == "qty") ||
+	((*argshere).first == "qp") ||
+	((*argshere).first == "qpl") ||
+	((*argshere).first == "qr") ||
+	((*argshere).first == "q2"))
+      // need to escape special characters from query string
+      //disp.setmacro ("cgiarg" + (*argshere).first, 
+      //	     displayclass::defaultpackage, html_safe((*argshere).second.value));
+      macrovalue = html_safe(macrovalue);
+    else if ((*argshere).first != "hp") {
+      macrovalue = dm_safe(macrovalue);
+    }   
+
+    // set the default value for the macro
+    disp.setmacro ("cgiarg" + (*argshere).first, displayclass::defaultpackage, macrovalue);
+
+    // set the encoded values for the same macro
+    // https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
+    // http://owasp-esapi-cplusplus.googlecode.com/svn/trunk/doc/html/classesapi_1_1_encoder.html
+    // http://owasp-esapi-cplusplus.googlecode.com/svn/trunk/doc/html/classesapi_1_1_default_encoder.html
+    // http://owasp-esapi-cplusplus.googlecode.com/svn/trunk/doc/html/_default_encoder_8cpp_source.html
+    
+    // IMPORTANT: the API online is outdated/different to the actual method definitions in runtime-src/packages/security/installed/include
+
+    // Need to cast to Encoder& since getInstance() returns a const Encoder& which can't be used in the encode... functions
+    Encoder& encoder = (Encoder&)DefaultEncoder::getInstance();
+
+    // Contrary to the online API, where the param and return type of encode are WideString typedef to std::wstring defined in <string>
+    // actual encode() functions in security/installed/include return NarrowString which is typedef-ed to std::string defined in <string>
+    esapi::NarrowString macrovalue_nstring = text_t_to_esapi_narrow_string(macrovalue);
+
+
+    //esapi::NarrowString htmlsafe_nstring = encoder.encodeForHTML(macrovalue_nstring);
+    esapi::NarrowString htmlsafe_nstring = encodeForHTML(macrovalue_nstring);
+    text_t esapi_htmlsafe = esapi_narrow_string_to_text_t(htmlsafe_nstring);
+
+    text_t htmlsafe = encodeForHTML(macrovalue);
+    text_t attrsafe = encodeForHTMLAttr(macrovalue);
+    text_t urlsafe = encodeForURL(macrovalue);
+    text_t jssafe = encodeForJavascript(macrovalue);
+    text_t csssafe = encodeForCSS(macrovalue);
+
+    /*
+    if((*argshere).first == "o" ) {
+      
+      cout << "esapi::htmlsafe: " << esapi_htmlsafe << endl;
+      cout << "myhtmlsafe: " << htmlsafe << endl;
+      cout << "myattrsafe: " << attrsafe << endl;
+      cout << "myurlsafe: " << urlsafe << endl;
+      cout << "myjssafe: " << jssafe << endl;
+      cout << "mycsssafe: " << csssafe << endl;
+    }
+    */
+    /*
+    esapi::NarrowString attrsafe_nstring = encoder.encodeForHTMLAttribute(macrovalue_nstring);
+    text_t attrsafe = esapi_narrow_string_to_text_t(attrsafe_nstring);
+
+    esapi::NarrowString jssafe_nstring = encoder.encodeForJavaScript(macrovalue_nstring);
+    text_t jssafe = esapi_narrow_string_to_text_t(jssafe_nstring);
+
+    //text_t jsonsafe = esapi_narrow_string_to_text_t(encoder.encodeFor...(macrovalue_nstring));
+
+    esapi::NarrowString csssafe_nstring = encoder.encodeForCSS(macrovalue_nstring);
+    text_t csssafe = esapi_narrow_string_to_text_t(csssafe_nstring);
+
+    esapi::NarrowString urlsafe_nstring = encoder.encodeForURL(macrovalue_nstring);
+    text_t urlsafe = esapi_narrow_string_to_text_t(urlsafe_nstring);  
+    
+    */
+    disp.setmacro ("cgiarg" + (*argshere).first + "Htmlsafe", displayclass::defaultpackage, htmlsafe);    
+    disp.setmacro ("cgiarg" + (*argshere).first + "Attrsafe", displayclass::defaultpackage, attrsafe);
+    disp.setmacro ("cgiarg" + (*argshere).first + "Jssafe", displayclass::defaultpackage, jssafe);
+    disp.setmacro ("cgiarg" + (*argshere).first + "Csssafe", displayclass::defaultpackage, csssafe);
+    disp.setmacro ("cgiarg" + (*argshere).first + "Urlsafe", displayclass::defaultpackage, urlsafe);
+    
+
+    ++argshere;
+  }
+
+  // set collection specific macros
+  if (!collection.empty()) {
+    recptproto *collectproto = protocols.getrecptproto (collection, logout);
+    if (collectproto != NULL) {
+      FilterResponse_t response;
+      text_tset metadata;
+      get_info ("collection", collection, args["l"], metadata, false, 
+		collectproto, response, logout);
+      
+      if (!response.docInfo[0].metadata.empty()) {
+	MetadataInfo_tmap::const_iterator here = response.docInfo[0].metadata.begin();
+	MetadataInfo_tmap::const_iterator end = response.docInfo[0].metadata.end();
+	while (here != end) {
+	  if (((*here).first != "haschildren") && ((*here).first != "hasnext") &&
+	      ((*here).first != "hasprevious")) {
+	    // check for args in form name:lang
+	    text_t name = g_EmptyText;
+	    text_t lang = g_EmptyText;
+	    bool colonfound=false;
+	    text_t::const_iterator a = (*here).first.begin();
+	    text_t::const_iterator b = (*here).first.end();
+	    while (a !=b) {
+	      if (*a==':') {
+		colonfound=true;
+	      }
+	      else {
+		if (colonfound)
+		  lang.push_back(*a);
+		else name.push_back(*a);
+	      }
+	      ++a;
+	    }
+	    if (!lang.empty()) {
+	      if (args["l"]==lang) {
+		disp.setcollectionmacro(displayclass::defaultpackage, name, "", (*here).second.values[0]);
+	      }
+	    }
+	    else { // the default one
+	      disp.setcollectionmacro(displayclass::defaultpackage, (*here).first,  "", (*here).second.values[0]);
+	    }
+	  }
+	  ++here;
+	}
+      }
+
+      text_t iconcollection;
+      disp.expandstring (displayclass::defaultpackage, "_iconcollection_", iconcollection);
+      if (!iconcollection.empty())
+	{
+	  ColInfoResponse_t cinfo;
+	  comerror_t err;
+	  collectproto->get_collectinfo (collection, cinfo, err, logout);
+	  if (iconcollection[0]=='/' && !cinfo.httpdomain.empty())
+	    {
+	      // local but with full path
+	      iconcollection = "http://" + cinfo.httpdomain + iconcollection;
+	      disp.setmacro("iconcollection", displayclass::defaultpackage, iconcollection);
+	    }
+	}
+    }
+  }
+  
+  if (!collection.empty()) {
+    ColInfoResponse_t cinfo;
+    comerror_t err;
+    recptproto *collectproto = protocols.getrecptproto (collection, logout);
+    if (collectproto != NULL) {
+      collectproto->get_collectinfo (collection, cinfo, err, logout);
+
+
+      // This part of the code used to use "cinfo.httpprefix" regardless
+      // of the value it contained.  Since
+      // this can come back with an empty (in the case of gsdl_mod), the
+      // URL produced was invalid.
+      //
+      // Changed to test for empty first, and use configinfo.httpprefix as
+      // a "backup"
+      // 
+      // Point to consider: since configinfo.httpprefix has been offically 
+      // set as "httpprefix" in macros, it seems to make more sense to use
+      // always use that version and not the cinfo version at all.
+
+      text_t httpprefix 
+	= (!cinfo.httpprefix.empty()) ? cinfo.httpprefix : configinfo.httpprefix;
+    
+      text_t httpcollection;
+      if (!cinfo.httpdomain.empty()) httpcollection = "http://";
+      httpcollection += cinfo.httpdomain + httpprefix + "/collect/"
+	+ collection; 
+      disp.setmacro ("httpcollection", displayclass::defaultpackage,
+		     httpcollection); 
+      
+      // as of gsdl 2.53, collect.cfg can specify macros
+      if (cinfo.collection_macros.size() > 0) {
+	collectionmeta_map::const_iterator this_macro=cinfo.collection_macros.begin();
+	collectionmeta_map::const_iterator done_macro=cinfo.collection_macros.end();
+	while (this_macro != done_macro) {
+	  text_t package = "Global";
+	  text_t macroname = this_macro->first;
+	  // if this macro name is AAA:bbb then extract the package name
+	  text_t::const_iterator thischar, donechar;
+	  thischar = macroname.begin();
+	  donechar = macroname.end();
+	  while (thischar < donechar) {
+	    if (*thischar == ':') {
+	      package = substr(macroname.begin(),thischar);
+	      macroname = substr(thischar+1,donechar);
+	      break;
+	    }
+	    ++thischar;
+	  }
+
+	  text_tmap params_map = this_macro->second;
+	  text_tmap::const_iterator this_param = params_map.begin();
+	  text_tmap::const_iterator done_param = params_map.end();
+	  while (this_param != done_param) {
+	    disp.setcollectionmacro(package,
+				    macroname,
+				    this_param->first,
+				    this_param->second);
+	    ++this_param;
+	  }
+	  
+	  ++this_macro;
+	}
+      } // col macros
+    } // collectproto != NULL
+  }
+
+}
+
+// gets collection info from cache if found or 
+// calls collection server (and updates cache)
+// returns NULL if there's an error
+ColInfoResponse_t *receptionist::get_collectinfo_ptr (recptproto *collectproto, 
+						      const text_t &collection, 
+						      ostream &logout) {
+  
+  // check the cache
+  colinfo_tmap::iterator it = configinfo.collectinfo.find (collection);
+  if ((it != configinfo.collectinfo.end()) && ((*it).second.info_loaded)) {
+    // found it
+    return &((*it).second.info);
+  }
+
+  // not cached, get info from collection server
+  if (collectproto == NULL) {
+    logout << "ERROR: receptionist::get_collectinfo_ptr passed null collectproto\n";
+    return NULL;
+  }
+   
+  comerror_t err;
+  if (it == configinfo.collectinfo.end()) {
+    collectioninfo_t cinfo;
+    collectproto->get_collectinfo (collection, cinfo.info, err, logout);
+    if (err != noError) {
+      outconvertclass text_t2ascii;
+      logout << text_t2ascii << "ERROR (receptionist::getcollectinfo_ptr): \""
+	     << get_comerror_string (err) << "\"while getting collectinfo\n";
+      return NULL;
+    }
+    cinfo.info_loaded = true;
+    configinfo.collectinfo[collection] = cinfo;
+    return &(configinfo.collectinfo[collection].info);
+  } else {
+    collectproto->get_collectinfo (collection, (*it).second.info, err, logout);
+    if (err != noError) {
+      outconvertclass text_t2ascii;
+      logout << text_t2ascii << "ERROR (receptionist::getcollectinfo_ptr): \""
+	     << get_comerror_string (err) << "\"while getting collectinfo\n";
+      return NULL;
+    }
+    (*it).second.info_loaded = true;
+    return &((*it).second.info);
+  }
+}
+
+// removes a collection from the cache so that the next
+// call to get_collectinfo_ptr() for that collection will
+// retrieve the collection info from the collection server
+void receptionist::uncache_collection (const text_t &collection) {
+
+  colinfo_tmap::iterator it = configinfo.collectinfo.find (collection);
+  if ((it != configinfo.collectinfo.end()) && ((*it).second.info_loaded)) {
+
+    (*it).second.info_loaded = false;
+
+  }
+}
+
+// Handles an "Encoding" line from a configuration file - note that the
+// configinfo.encodings map is a bit of a hack (to be fixed when the
+// configuration files are tidied up).
+void receptionist::configure_encoding (const text_tarray &cfgline) {
+
+  text_t subkey, subvalue, shortname, longname, mapfile;
+  int multibyte = 0;
+  text_t::const_iterator cfglinesub_here;
+  text_tarray::const_iterator cfgline_here = cfgline.begin();
+  text_tarray::const_iterator cfgline_end = cfgline.end();
+  while (cfgline_here != cfgline_end) {
+    if (*cfgline_here == "multibyte") {
+      multibyte = 1;
+    } else {
+      cfglinesub_here = getdelimitstr((*cfgline_here).begin(),
+				      (*cfgline_here).end(), '=', subkey);
+      if (subkey == "shortname") {
+	shortname = substr (cfglinesub_here, (*cfgline_here).end());
+      } else if (subkey == "longname") {
+	longname = substr (cfglinesub_here, (*cfgline_here).end());
+      } else if (subkey == "map") {
+	mapfile = substr (cfglinesub_here, (*cfgline_here).end());
+      }
+    }
+    ++cfgline_here;
+  }
+  if (!shortname.empty()) {
+    if (longname.empty()) longname = shortname;
+
+    // add the converter
+    if (shortname == "utf-8") {
+      utf8inconvertclass *utf8inconvert = new utf8inconvertclass();
+      utf8outconvertclass *utf8outconvert = new utf8outconvertclass();
+      utf8outconvert->set_rzws(1);
+      add_converter (shortname, utf8inconvert, utf8outconvert);
+      configinfo.encodings[longname] = shortname;
+
+    } else if (shortname == "utf-16be") {
+      // we use the default input converter as this shouldn't ever be used
+      // for converting from unicode...
+      inconvertclass *inconverter = new inconvertclass();
+      utf16outconvertclass *outconverter = new utf16outconvertclass();
+      add_converter (shortname, inconverter, outconverter);
+      configinfo.encodings[longname] = shortname;
+	
+    } else if (!mapfile.empty()) {
+
+      if (mapfile == "8859_1.ump") {
+	// iso-8859-1 is a special case as it'll always be supported by the
+	// standard converter class and therefore doesn't need to use its
+	// mapping file
+	inconvertclass *inconvert = new inconvertclass();
+	rzwsoutconvertclass *outconvert = new rzwsoutconvertclass();
+	outconvert->set_rzws(1);
+	add_converter (shortname, inconvert, outconvert);  
+	configinfo.encodings[longname] = shortname;
+
+      } else {
+	text_t to_uc_map = filename_cat(configinfo.gsdlhome, "mappings", "to_uc", mapfile);
+	text_t from_uc_map = filename_cat(configinfo.gsdlhome, "mappings", "from_uc", mapfile);
+	if (file_exists(to_uc_map) && file_exists(from_uc_map)) {
+
+	  mapinconvertclass *mapinconvert = new mapinconvertclass();
+	  mapinconvert->setmapfile (to_uc_map, 0x003F);
+	  mapinconvert->set_multibyte (multibyte);
+	  mapoutconvertclass *mapoutconvert = new mapoutconvertclass();
+	  mapoutconvert->setmapfile (from_uc_map, 0x3F);
+	  mapoutconvert->set_multibyte (multibyte);
+	  mapoutconvert->set_rzws(1);
+	  add_converter (shortname, mapinconvert, mapoutconvert);
+	  configinfo.encodings[longname] = shortname;
+	}
+      }
+    }
+  }
+}
