#!/usr/bin/perl
# file: DirectMarkUP.cgi

#    Copyright (C) 1998,1999,2000 by Data EXchange Associates, Inc.
# 
#    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Data EXchange Associates, Inc.
# 230 Burnt Meadow Road			email: support@dexa.com
# Groton,  MA  01450			http://www.dexa.com
# Telephone: 978.448.3188 voice
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#

# DirectMarkUP allows a webmaster or other authorized maintainer to
# change named locations within an HTML document.  When interfaced with
# an HTML FORM to gather the new values the DirectMarkUP script will 
# MarkUP the specified HTML document and procduce a new web page online.
# This allows users not familiar with HTML to change fixed locations
# within a web document easily.

# 
# History:
#  1Jul00 MGiguere GPLed.
# 25May99 MGiguere Added markup and comment tags
#  8Sep98 MGiguere Platform independent code added.
# 31Jul98 MFB      Modify Scan for DIRECT tags loop cleaner.
# 29Jul98 MGiguere Display updated webpage in browser.
#  9Jul98 MGiguere Version 2.0
# 31Mar98 MGiguere Created.
#

$VERSION="DirectMarkUP.cgi Version 2.3";

# include a useful CGI library
require 'cgi-lib.pl';

# include DirectMarkUP library
require 'DirectMarkUP.pl';

# include the DirectMarkUP configuration file
require 'DirectMarkUP.pm';

# include the HTML tag parser code
require 'HTMLParser.pm';

# get the target HTML file name from the command line
$targetFile = shift @ARGV;

if ( ! $targetFile ) {
    CgiError("Error: ". __FILE__ .":". __LINE__,
	     "Error: No target file name specified",
	     );
    exit 1;
}

# read and parse FORM input
&ReadParse;

# test to see if we got any input before anything else
unless ( %in ) {
    CgiError("Error: ". __FILE__ .":". __LINE__,
	     "Error: No input recieved. Please fill in the form."
	     );
    exit 1;
}

# check if this is a path not a URL first
$templateFile = &pathify( $targetFile );
$isURL = &FALSE;
if (! -f $templateFile ) {  # no try as a URL
    $templateFile = &pathify( $docRoot . $targetFile );
    if ( ! -f $templateFile ) {
	CgiError("Error:  ". __FILE__ .":". __LINE__,
		 "Error: could not find the template file: $templateFile."
		 );
	exit 1;
    }
    $isURL = &TRUE;
}

# open the template doc. and read it into a local var.
unless ( open TFILE, $templateFile ) {
    CgiError("Error:  ". __FILE__ .":". __LINE__,
	     "Error: template file: $targetFile not found.",
	     "Report this to the Web Maintainer $admin"
	     );
    exit 1;
}

# read in entire the target file in one gulp
{
    local $/ = undef;
    $template = <TFILE>;
    close TFILE;
}

$pid = $$;
$tempFile = &pathify( "$tempDir/temp_$pid" );

# create a temp file to hold new HTML page
unless ( open TFILE, ">$tempFile" ) {
    CgiError("Error: ". __FILE__ .":". __LINE__,
	     "Error: could not create temporary file: $tempFile.",
	     "Could be permission or disk full?",
	     "Report this to the Web Maintainer: $admin"
	     );
    exit 1;
}

# Scan for DIRECT tags and update as required

$p = new HTMLParser( $template );
$tagList = $p->{'tags'};
$count = @$tagList;
@changed = ();
$newtext = '';    # non-empty only if in DIRECT bloc and new text provided

for ( $i = 0 ; $i < $count ; $i++ ) {
    $t = @$tagList->[ $i ];

    if ( $t->{type} =~ /text/ && !$newtext ) {	# text outside DIRECT bloc
	print TFILE $t->{content};
	next;
    }
    elsif ( $t->{type} =~ /markup/ ) {
	print TFILE "<!". $t->{content} . ">";
	next;
    }
    elsif ( $t->{type} =~ /comment/ ) {
	print TFILE "<!--". $t->{content} . "-->";
	next;
    }
    elsif ( ( $t->{type} =~ /tag$/ )	# a </DIRECT> tag or other tag outside
		&& ( !$newtext || ($t->{content} =~ /^\/DIRECT/i ) ) ) {
	print TFILE "<" . $t->{content} . ">";
	$newtext = '';
    }

    # else inside DIRECT bloc with newtext, ignore non DIRECT tags and text
    # Next, treat DIRECT tags specially
    if (( $t->{type} =~ /^starttag/ )	# a <DIRECT> tag
	and ( $t->{content} =~ /^DIRECT/i )) {
	if ( $newtext ) {
	    CgiError("Error: ". __FILE__ .":". __LINE__,
		     "Error: Missing </DIRECT> tag.",
		     "Report this to the Web Maintainer $admin"
		     );
	    exit 1;
	}
	my %atts = $p->attList( $t->{content} );
	$newtext = $in{$atts{name}};
	push( @changed, "\t$atts{name}=$newtext" );
	if ( $newtext ) {		# print new replacement text
	    print TFILE $newtext;
	}
	# if no newtext, just proceed as if not in DIRECT bloc
    }
}
# newtext must be empty upon leaving loop (not left in a DIRECT bloc).
if ( $newtext ) {
    CgiError("Error: ". __FILE__ .":". __LINE__,
	     "Error: missing </DIRECT> tag",
	     "Report this to the Web Maintainer $admin"
	     );
    close TFILE;
    unlink $tempFile;
    exit 1;
}

close TFILE;

# now that we have successfully created the temp file
# we will back-up the orginal and replace it with the new one.

# make back-up copy of original page.

if (! &moveFile( $templateFile, "$templateFile.bak" )) {
    CgiError("Error: ". __FILE__ .":". __LINE__,
	     "Error: unable to backup $templateFile.",
	     "Could be permission problem or filesystem full?",
	     "Report this to the Web Maintainer $admin"
	     );
    exit 1;
}

# replace original page with new one

if ( ! &moveFile( $tempFile, $templateFile )) {
    CgiError("Error: ". __FILE__ .":". __LINE__,
	     "Error: unable to update page: $targetFile.",
	     "Could be permission problem?",
	     "Report this to the Web Maintainer $admin"
	     );
    unlink $tempFile;
    exit 1;
}

# update timestamp on file to force server & browser cache update
$now = time;
utime( $now, $now, $templateFile );

&EvtLog( ( "Success: $targetFile updated", @changed ) );

# jump to the updated webpage

if ( $isURL ) {
    print "Location: $server/$targetFile\n\n";
}
else {
    CgiError( "Success!",
	     "", "Target page: $targetFile successfully changed.",
	     "", "Browse $targetFile to assure it is correct.",
	     "", "Thank you." );
}

exit 0;
