Configuration script for Foswiki. Once you have a basic webserver
configuration that lets you access this script, the rest of the
configuration process is done from here.

The script works from the top down, by checking features of the
environment before moving on. The sequence is:
1. Check the version of perl
2. Check we have the modules to run this script
3. Check the environment
4. Check we have the modules to load the rest of configure
… and so on. At any stage, the script reports any errors in the
best way it can given the environment established so far.
When the basic checks are complete, the script moves into the
real configuration steps; setting configuration variables.

This phase of the configure environment follows a Model-View-
Controller pattern.

—++ Controller
This script is the controller; it handles communication with the
browser (and thus the user). Communication is very simple; this script
is re-invoked with different ‘action’ parameters to determine what it does.

—++ Model
The Model consists of a simple node tree, where each node represents a
structural element in the *presentation* of the configuration (this may
not be consistent with the structure of $Foswiki:cfg, so beware). Each
leaf node has an associated Type (in the Types subdirectory) that has
collected model and view behaviours for the basic types.

Class hierarchy
* Foswiki::Configure::Item
* Foswiki::Configure::Value – a leaf value
* Foswiki::Configure::Section – a running node
* Foswiki::Configure::Root – a root section
* Foswiki::Configure::Pluggable – a plug-in subsection
* Foswiki::Configure::Pluggables::FINDEXTENSIONS – etc
* Foswiki::Configure::Checkers::Introduction – should be a Pluggable
* Foswiki::Configure::Checkers::Welcome – should be a Pluggable
* Foswiki::Configure::Checkers::MSWin32 – should be a Pluggable
The Model is independent of the language used to represent the
configuration. There is one parser/generator provided, FoswikiCfg, but it
would be trivial to add others.

—++ View
The View is a DOM document, generated as HTML by a set of UI classes,
all subclasses of Foswiki::Configure::UI. The UI classes visit the
model in order to generate the HTML.

—+++ UIs
Each class in the model (Root, Section, Value, Item) has a corresponding UI
decorator object, which renders HTML for the model. There are also a
number of bespoke UIs, some of which assist =configure= in the generation
of full screens (Introduction, Welcome, AUTH, UPDATE, EXTEND, EXTENSIONS,
UPDATE) and others which relate to the Pluggables (FINDEXTENSIONS, LANGUAGES,
PLUGINS). The special UI CGISetup is a specialised Section focused on groping
the CGI configuration. Several of the bespoke UIs (CGISetup, Introduction,
Welcome) have corresponding Checkers, which act as placeholders in the
model for these sections.

—+++ Checkers
Checkers give checking and guessing support for configuration values. Checkers
are all subclasses of Foswiki::Configure::Checker, and inhabit a class
hierarchy under it that mirrors the organisation of configuration keys in
Foswiki.spec. Checkers include read-only checking UI used for checking
environment sanity (BasicSanity)

Note that when configure is run for the first time (before LocalSite.cfg
has been created) then only the first section of Foswiki.spec is loaded,
and thus checkers only for that subset will be created and run. This means
that on some platforms, initial configuration is a two-phase process, as
the initial path checks are performed on the first run, and only on the
second run, when LocalSite.cfg exists, are the other checkers built and
invoked. This needs improving on.

—+++ Types
Types provide some UI support in the form of type-specific prompters.
This is really an abuse of the Model, but it saves creating
decorator classes for all the Model types.

HTML is generated for the model using Visitor pattern. Each node in the tree
is visited in depth-first order.

TODO:
The type classes are the obvious place to attach client-side javascript
validators, thus releasing the server-side checkers to consider the “deeper”
issues.

=cut

use strict;
use warnings;

# This is absolutely essential for error reporting. We load it using
# an eval so we can report the problem.
eval “use CGI::Carp qw(fatalsToBrowser)”;
if ($@) {
print <<"REPORT";
Content-type: text/plain

Could not load CGI::Carp. Please install this module before continuing.
It can be downloaded from http://www.cpan.org

The error seen was:
$@
REPORT
exit 1;
}

###########################################################
# VERY basic stuff required for configure to work. Any errors
# during this phase will throw a die, which will be picked up
# using CGI::Carp fatalsToBrowser

# Warnings are fatal
$SIG{'__WARN__'} = sub { die @_ };

eval 'require 5.00503';
die $@ if $@;

# We warn against running Foswiki on an older Perl version then 5.8.4
# but we will not let configure die in this situation. The user
# may have updated many libraries and tweaked Foswiki so let us give
# him a chance.
my $perlversion = $];
if ( $perlversion < 5.006 ) {
print STDERR <) || ”; };

# No joy. Remember the failure so we can report it later.
$localLibFailure = $@;

# Stick the root/lib on the path; there’s a high probability we’ll be
# able to find the bits of Foswiki::Configure that way. We will report
# the setlib error later.
unshift( @INC, File::Spec->catfile( @root, ‘lib’ ) );
}

::_loadBasicModule(‘CGI qw(:any)’);

$| = 1; # no buffering on STDOUT

# We are configuring $Foswiki::cfg, so we need to be in package Foswiki from
# now on.
package Foswiki;

# Try to use Cygwin’s ‘id’ command – may be on the path, since Cygwin
# is probably installed to supply ls, egrep, etc – if it isn’t, give
# up.
# Run command without stderr output, to avoid CGI giving error.
# Get names of primary and other groups.
# This is down here because it takes 30s to execute on Strawberry perl
$::WebServer_gid = lc(qx(sh -c ‘( id -un ; id -gn) 2>/dev/null’ 2>nul ));
}

###########################################################
# From this point on we shouldn’t have any more “fatal” (to configure)
# errors, so we can report errors in the browser (i.e. without using die)

###########################################################
# Grope the OS. This duplicates a bit of code in Foswiki.pm,
# but it has to be duplicated because we don’t want to deal
# with loading Foswiki just yet.

# This is the dispatcher; $action is the name of the action to perform,
# this is concatenated to _action to determine the name of the procedure.
# Dispatcher methods return a boolean to indicate whether to generate a
# link back to the main page at the end.

# If this pass created the LocalSite.cfg, need to rerun the sanity check
# to re-establish that the configuration is valid
my $sanityStatement = ”;
if ($badLSC) {
my $stub = new Foswiki::Configure::Item();

# Load the config structures.
# If $isFirstTime is true, only Foswiki.spec will be loaded
# (extension Config.spec files will *not* be loaded) and
# only the first section of Foswiki.spec will be processed
# i.e. all other sections will be skipped.
Foswiki::Configure::FoswikiCfg::load( $root, !$isFirstTime );

Copyright (C) 2008-2010 Foswiki Contributors. Foswiki Contributors
are listed in the AUTHORS file in the root of this distribution.
NOTE: Please extend that file, not this notice.

Additional copyrights apply to some or all of the code in this
file as follows:

Copyright (C) 2000-2007 TWiki Contributors. All Rights Reserved.

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. For
more details read LICENSE in the root of this distribution.

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.