Index: /trunk/DataStoreServer/web/cgi/dsfits.cgi
===================================================================
--- /trunk/DataStoreServer/web/cgi/dsfits.cgi	(revision 16763)
+++ /trunk/DataStoreServer/web/cgi/dsfits.cgi	(revision 16763)
@@ -0,0 +1,43 @@
+#!/usr/bin/env perl
+
+use strict;
+use CGI ':standard';
+
+my $DS_DIR = '/var/www/html/ds/dsroot';
+#my $DS_DIR = '.';
+
+my $uri = $ENV{'REQUEST_URI'};
+
+$uri = $ARGV[0];
+print STDERR "uri is $uri\n";
+
+(my $left, my $param) = split(/\,/, $uri);
+
+print STDERR "left: $left param: $param\n";
+
+if ($left !~ /\.fits$/) {
+	print header( -status => '404 Not Found' );
+	exit;
+}
+
+my @path = split(/\//, $left);
+
+my $fn = @path[$#path];
+my $fpath = $DS_DIR.'/'.$left;
+
+
+
+print header(	-type => 'image/fits',
+				-attachment => $fn,
+				-content_length => -s $fpath,
+			);
+
+
+open F, $DS_DIR.'/'.$left;
+
+binmode(F);
+binmode(STDOUT);
+
+print while (<F>);
+
+close F;
Index: /trunk/DataStoreServer/web/cgi/dsgetindex
===================================================================
--- /trunk/DataStoreServer/web/cgi/dsgetindex	(revision 16763)
+++ /trunk/DataStoreServer/web/cgi/dsgetindex	(revision 16763)
@@ -0,0 +1,250 @@
+#!/usr/bin/env perl
+#
+# dsgetindex: Generate response to http GET for a DataStore index
+#
+# The only required argument is the REQUEST_URI.
+# The number of elements in the URI tell us whether we are listing
+# the root, a product, or a fileset.
+#
+# if a second argument -html is provided, the output is in HTML
+#
+# The only thing specific to the ipp used here is the exit codes.
+
+use warnings;
+use strict;
+
+use CGI ':standard';
+use IPC::Cmd 0.36 qw( can_run run );
+use PS::IPP::Config qw($PS_EXIT_SUCCESS
+		       $PS_EXIT_UNKNOWN_ERROR
+		       $PS_EXIT_SYS_ERROR
+		       $PS_EXIT_CONFIG_ERROR
+		       $PS_EXIT_PROG_ERROR
+		       $PS_EXIT_DATA_ERROR
+		       $PS_EXIT_TIMEOUT_ERROR
+		       metadataLookupStr
+		       metadataLookupBool
+		       caturi
+		       );
+
+my $uri = shift;
+
+if (!$uri) {
+    warn("need uri");
+    exit ($PS_EXIT_CONFIG_ERROR);
+}
+
+my @path;
+
+my $html_mode;
+my $arg = shift;
+if ($arg && ($arg eq "-html")) {
+    $html_mode = 1;
+}
+
+#
+# split up the uri into componnts.
+#
+# XXX: Find a simpler way to do this
+
+# collapse any multipe slashes in uri
+$uri = File::Spec->canonpath($uri);
+
+# split the directories from the file
+my $directories;
+my $file = "";
+my $query_str;
+
+if ($html_mode) {
+    # there is no file on the url
+
+    print STDERR "html mode\n";
+
+    ($directories, $query_str) = split/\?/, $uri;
+
+    # used by the pretty printer
+    @path = split(/\//, $directories);
+
+} else {
+    my $volume;
+    ( $volume, $directories, $file) = File::Spec->splitpath($uri);
+
+    # find the query string if any
+    # (This is only relevant for fileset queries but we follow conductor and do not enforse that restriction)
+    ($file, $query_str) = split/\?/, $file;
+
+    if ($file ne "index.txt") {
+        warn("unexepected index file name: $file");
+        exit ($PS_EXIT_CONFIG_ERROR);
+    }
+}
+
+if ($query_str) {
+    print STDERR "dsgetindex: $directories $file $query_str\n";
+} else {
+    print STDERR "dsgetindex: $directories $file\n";
+    $query_str = "";
+}
+
+my @dirs = split /\//, $directories;
+
+# shift out the empty string at left of the first /
+shift @dirs;
+# shift out 'ds'
+shift @dirs;
+
+# now we're left with either nothing, a product, or a product and a fileset
+my $product = shift @dirs;
+my $fileset = shift @dirs;
+
+if (@dirs) {
+    warn("unexpected extra directories: @dirs in uri: $uri");
+    exit ($PS_EXIT_CONFIG_ERROR);
+}
+
+my $program;
+if ($fileset) {
+    $program = "dsfsindex";
+} elsif ($product) {
+    $program = "dsprodindex";
+    $fileset .= " $query_str";
+} else {
+    $program = "dsrootindex";
+    $fileset = "";
+    $product = "";
+}
+
+my $missing_tools;
+my $index_program = can_run($program) or (warn "Can't find $program" and $missing_tools = 1);
+if ($missing_tools) {
+    #warn("Can't find required tools.");
+    exit ($PS_EXIT_CONFIG_ERROR);
+}
+
+{
+    my $command = "$index_program $product $fileset";
+
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 
+        run(command => $command, verbose => 0);
+
+    if ($success) {
+        if ($html_mode) {
+            html_index($stdout_buf);
+        } else {
+            print header('text/plain', '200 OK');
+            print @$stdout_buf;
+        }
+    } else {
+        if (0 && $html_mode) {
+            XXX: TODO
+
+        } else {
+            # since we're invoked as a redirect from a text file browsers are expecting
+            # 'text/plain' format
+            print header('text/plain', '404 ERROR');
+            #print header('text/plain', '200 OK');
+            print @$stderr_buf;
+            print STDERR @$stderr_buf;
+        }
+    }
+    exit $error_code >> 8;
+}
+
+
+sub html_index {
+
+    my $out_buf = $_[0];
+    #print header('text/plain', '200 OK');
+
+    #print "outputting from html_index\n";
+    #print @$out_buf;
+    pprint_pre();
+    my @lines = split /^/, $out_buf->[0];
+    foreach my $line (@lines) {
+        pprint($line);
+    }
+    pprint_post();
+}
+
+#
+# XXX:
+# quick hacky pretty printer
+# Stolen Eric's mock up
+#
+
+sub pprint_pre {
+    use Filesys::Df;
+
+    print header('text/html', '200 OK');
+    print start_html('Datastore');
+
+	# get free space
+        # XXX: need to configure DS_DIR
+        my $DS_DIR = '/var/www/html/ds/dsroot';
+	my $ref = df($DS_DIR);
+	printf '<p>Free space: %.2fG (%.1f%%)</p>',
+		$ref->{bfree}/(1024*1024),
+		100.0*$ref->{bfree}/$ref->{blocks};
+
+	# return link
+	if ($#path > 1) {
+		my $up = join('/', @path[0..$#path-1]);
+	    print a({-href=>"$up"}, "Up to $up");
+	}
+
+    print '<table cellpadding="3">';
+}
+
+
+sub pprint_post {
+    print '</table>';
+    print p();
+
+    print end_html();
+}
+
+
+sub pprint {
+    my $line = shift;
+
+    my $nolink;
+    my $celltag = 'td';
+
+	# assume a comment line means its the header
+    if ($line =~ /^\s*#/) {
+        $celltag = 'th';
+        $nolink = 1;
+    }
+
+    my @toks = split(/\|/, $line);
+
+    print '<tr>';
+
+    print "<$celltag>";
+
+    if ($nolink) {
+       print $toks[0];
+    }
+
+    else {
+		# assumes id is always first field
+	    my $wpath = join('/',@path)."/$toks[0]";
+
+		# if this is a file request, use a download cgi
+		if ($wpath =~ /\.fits$/) {
+			$wpath = '/ds-cgi/dsfits.cgi?'.substr($wpath, 4); # strip' /ds/'
+		}
+
+        print a({-href=>$wpath}, $toks[0]);
+    }
+
+    print "</$celltag>";
+
+    foreach my $val (@toks[1..$#toks]) {
+		print "<$celltag>";
+		print $val;
+		print "</$celltag>";
+    }
+
+    print '</tr>';
+}
Index: /trunk/DataStoreServer/web/cgi/dsindex.cgi
===================================================================
--- /trunk/DataStoreServer/web/cgi/dsindex.cgi	(revision 16763)
+++ /trunk/DataStoreServer/web/cgi/dsindex.cgi	(revision 16763)
@@ -0,0 +1,2 @@
+#!/bin/sh
+/export/data0/bills/psconfig/default.linrh64/bin/pstamp_runcommand.sh dsgetindex $REQUEST_URI -html
Index: /trunk/DataStoreServer/web/cgi/dstxtindex.cgi
===================================================================
--- /trunk/DataStoreServer/web/cgi/dstxtindex.cgi	(revision 16763)
+++ /trunk/DataStoreServer/web/cgi/dstxtindex.cgi	(revision 16763)
@@ -0,0 +1,2 @@
+#!/bin/sh
+/export/data0/bills/psconfig/default.linrh64/bin/pstamp_runcommand.sh dsgetindex $REQUEST_URI;
Index: /trunk/DataStoreServer/web/conf/httpd-datastore.conf
===================================================================
--- /trunk/DataStoreServer/web/conf/httpd-datastore.conf	(revision 16763)
+++ /trunk/DataStoreServer/web/conf/httpd-datastore.conf	(revision 16763)
@@ -0,0 +1,51 @@
+
+<Directory "/var/www/html/ds/dsroot">
+#<Directory "/ds/dsroot">
+
+  DirectoryIndex /ds-cgi/dsindex.cgi
+
+  #Options None
+
+  # turn on server side includes
+  Options +Includes
+
+  # files will be processed for server side includes if they have the
+  # executable bit set
+  XBitHack on
+
+  # attempt to turn caching off (doesn't seem to work)
+  ExpiresActive On
+  # expires 0 seconds after access (doesn't get applied)
+  ExpiresDefault A0
+
+#AddType text/plain .txt
+  AddOutputFilter INCLUDES .txt
+
+  AllowOverride None
+
+  Order allow,deny
+  Allow from all
+</Directory>
+
+<Directory "/cgi-bin/ds-cgi">
+#<Directory "/ds/cgi">
+  Options ExecCGI
+
+
+  Order allow,deny
+  Allow from all
+</Directory>
+
+Alias       /ds/     /var/www/html/ds/dsroot/
+ScriptAlias /ds-cgi/ /var/www/cgi-bin/ds-cgi/
+
+
+# these don't do what I want
+#AliasMatch (.*)(/index.txt)(.*) $1/$3
+
+#ScriptAliasMatch ^/.*/index.txt /ds-cgi/dsindex.cgi
+#ScriptAlias /var/www/html/ds/dsroot/pstamprequest/index.txt /ds-cgi/dsindex.cgi
+
+#RedirectMatch /ds/.*/index.txt /ds-cgi/dsindex.cgi
+#RedirectMatch /ds/.*  /ds-cgi/dsindex.cgi
+
