#!/usr/bin/perl -T
# -*- Perl -*-

# This file is part of libdap, A C++ implmentation of the OPeNDAP Data
# Access Protocol.

# Copyright (c) 2002,2003 OPeNDAP, Inc.
# Author: James Gallagher <jgallagher@opendap.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

# Make sure that the path after the `#!' at the start of this file is the
# path to Perl on your system. If there are several versions of perl, make
# sure this points to a perl that is at least version 5.004.

# This script handles the dispatch of the URL to one of the filter programs
# that makes up the DODS server. The filter program is executed by this
# script using exec. If the filter program cannot be run, an error message
# will be returned.
#
# See the DODS_Dispatch.pm class for information about how environment
# variables are used.
#
# NB: This script assumes that all data is rooted in the http document
# directory subtree. If you want to access files outside that subtree, use a
# symbolic link and make sure that your server is set to follow symbolic
# links. To configure an Apache server to follow symbolic links, add
# FollowSymLinks to the Options in the httpd.conf file.
#
# Options: -T: use Perl's taint mode.
#
# $Id: nph-dods.in 12367 2005-10-12 09:11:24 -0600 (Wed, 12 Oct 2005) jimg $

# Force PATH. This should work for most UNIXs. Forcing PATH means that -T
# (taint) won't complain about running programs. Perl will consider any
# directory that's writeable by someone other than the owner as tainted, so
# adding, for example, /usr/local/bin here might break other operations
# (places where we use exec in DODS_Dispatch or DODS_Cache).

# A note about /usr: This works because autoconf substitutes /usr/local
# or some other literal string here. However, autoconf variables like
# /usr/bin don't work because they include make-style variables like
# ${exec_prefix}/bin and the ${var} notation tells perl to access a hash.

$ENV{PATH} = "/bin:/usr/bin:/usr/bin";
$ENV{IFS} = "" if $ENV{IFS};    # For the truly paranoid...

# Needed for Perl 5.6.0 on Linux 12/11/2000 jhrg
$ENV{BASH_ENV} = '';

# These environment variables are used by the JGOFS server when there's no
# JGOFS user on the host system. 5/31/2001 jhrg
# Assume this script will run in the cgi-bin directory and that all dap-server
# configuration files will also be in that directory. 5/17/2005 jhrg
$ENV{"JGOFS_OBJECT"} = "`pwd`";
$ENV{"JGOFS_METHOD"} = "`pwd`";

# sed must perform the substitution here because lib() will not evaluate
# a variable or perform string substitutions. I used sed above in the PATH
# since it seems easier to use the same mechanism everwhere.
use lib ("/usr/share/dap-server");
use DODS_Dispatch;
use DODS_Cache;

my $bad_command = "The DODS server dispatch software could not figure out how
to handle this request. Please check that the URL is correct. If you're sure
this should work, please contact the ";

# The DODS_Dispatch object reads information from environment variables
# and builds up a command based on the format of a DODS URL.
$dispatch = new DODS_Dispatch( "DAP2/3.8.0", "./dap-server.rc" );

# Note that the statistics 'stuff' has its own configuration file. That's
# because we're just evaluating this feature. 07/22/03 jhrg

# Small change: if there's a file called OPENDAP_STATISTICS in the CWD, then
# stats are on. The installServers script will create this in response to
# questions, but we can crate it too, so running the installServers script
# every time the servers change is no longer necessary. 09/27/02 jhrg
# I think we should probably move this information into the dods.conf/ini
# file. The reason for keeping it separate is that we want to make sure that
# this feature is not turned on accidentally. 10/23/02 jhrg
if ( -f "OPENDAP_STATISTICS" ) {
    $dispatch->is_stat_on(1);

    open( STATS, "OPENDAP_STATISTICS" );

  LINE:
    while (<STATS>) {
        next LINE if /^\#/;
        next LINE if /^$/;

        my ( $name, $value ) = split;

        if ( $name eq "access_log" ) {
            $dispatch->access_log($value);    # Path to httpd's access log
        } elsif ( $name eq "error_log" ) {
            $dispatch->error_log($value);     # Path to http'd error log
        } elsif ( $name eq "machine_names" ) {
            $dispatch->machine_names($value);  # Regex of names for this machine
        }
    }
} else {
    $dispatch->is_stat_on(0);      # Set to 1 if statistics are turned on.
    $dispatch->access_log();       # Path to httpd's access log
    $dispatch->error_log();        # Path to http'd error log
    $dispatch->machine_names();    # PERL Regex of names for this machine
}

# DODSter is part of an experimental system which is loosely based on
# Napster call MODSter. MODSter is 'Napster for MODIS data.' If you'd like
# more information, go to the NASA ESIP Federation web site and search for
# MODSter. 07/22/03 jhrg

my $dodster    = "";
my $compressed = is_compressed( $dispatch->filename() );

if ( $dodster || $compressed ) {
    purge_cache( $dispatch->cache_dir(), $dispatch->cache_size() );

    my ( $cache_entity, $error );
    if ($dodster) {
        ( $cache_entity, $error ) =
          dodster_and_cache( $dispatch->filename(), $dispatch->cache_dir() );
    } else {
        ( $cache_entity, $error ) =
          decompress_and_cache( $dispatch->filename(), $dispatch->cache_dir() );
    }

    $dispatch->print_error_msg( $error, 0 )
      if ( $cache_entity eq "" && $error ne "" );

    $dispatch->filename($cache_entity);
}

@command = $dispatch->command();

if ( $command[0] ne "" ) {    # if no error...
    exec(@command);
} else {
    $dispatch->print_error_msg( $bad_command, 1 );
}

# $Log: nph-dods.in,v $
# Revision 1.10  2005/05/27 22:38:00  jimg
# Now uses the dap_server.rc configuration file.
#
# Revision 1.9  2005/05/25 23:53:43  jimg
# Changes to mesh with the new netcdf handler project/module. make install in
# both will now yield a running server when nph-dods and dods.rc are copied to
# a cgi-bin directory.
#
# Revision 1.8  2005/05/19 14:43:26  jimg
# Update
#
# Revision 1.7  2004/01/22 17:29:37  jimg
# Merged with release-3-4.
#
# Revision 1.6.4.1  2003/07/24 00:14:04  jimg
# Now uses the new dods.rc configuration file.
#
# Revision 1.6  2003/01/23 00:44:34  jimg
# Updated the copyrights on various source files. OPeNDAP is adopting the
# GNU Lesser GPL.
#
# Revision 1.5  2003/01/22 00:41:47  jimg
# Changed dods.ini to dods.rc.
#
# Revision 1.4  2002/12/31 22:28:45  jimg
# Merged with release 3.2.10.
#
# Revision 1.1.4.9  2002/10/24 00:36:43  jimg
# Added dodster code.
# Changed the remote stats control file from STATISTICS to DODS_STATISTICS.
#
# Revision 1.1.4.8  2002/09/27 23:10:54  jimg
# Change in the statistics gathering scheme: Now the code looks for a file
# called STATISTICS. If present, stats are turned on and values for the various
# log files are read from there. This means that we can copy new scripts around
# effectively installing new servers and stats won't be inadvertently turned
# off. In the previous version of nph-dods, that was the case. For each new
# install for the server code, installServers had to be run again.
#
# Revision 1.1.4.7  2002/05/21 21:21:36  jimg
# Added code so that server log information can be accessed remotely.
#
# Revision 1.1.4.6  2001/10/14 00:42:32  jimg
# Merged with release-3-2-8
#
# Revision 1.1.4.5  2001/07/11 05:10:48  jimg
# Changed the way DODS_Cache::decpmpress_and_cache() is called. Check for an
# error message and return a DODS error response if appropriate.
#
# Revision 1.3  2001/06/15 23:38:36  jimg
# Merged with release-3-2-4.
#
# Revision 1.1.4.4  2001/06/08 23:51:52  jimg
# Changed the error message returned when @command is trashed.
# Changed the version info passed into DODS_Dispatch.pm; it matches the new
# version stuff.
#
# Revision 1.1.4.3  2001/06/01 00:54:46  jimg
# Added JGOFS environment variables along with a little comment explaining why
# they are here.
#
# Revision 1.1.4.2  2001/05/09 23:10:00  jimg
# For the directory service, files routed through the HTML form generator
# are now chosen based on the regexes listed in dods.ini. It's possible to
# configure a given nph-dods to not use some of the expressions in the
# dods.ini file, so regexes like .* won't do odd things like route all files
# through the form interface. This is a partial fix, really, since the
# regexes still might include files that will cause the server to gag.
#
# Revision 1.2  2001/01/26 19:18:14  jimg
# Merged with release-3-2.
#
# Revision 1.1.4.1  2000/12/11 20:42:44  jimg
# Added comments.
# Added explicit set of BASH_ENV because that was flagged by taint mode. This
# is probably only an issue under the Bash shell, but what will other shells
# do?
#
# Revision 1.1  2000/10/19 23:52:19  jimg
# Added.
#
