#!/usr/bin/perl -wT use strict; # # $Id: GBview.pl,v 1.1 2002/07/19 19:39:10 nickjc Exp $ # # USER CONFIGURATION SECTION # -------------------------- # Modify these to your own settings, see the README file # for detailed instructions. use constant DEBUGGING => 0; use constant LIBDIR => '/home/tfmail/lib'; use constant CONFIG_ROOT => '/home/tfmail/cfg'; use constant MAX_DEPTH => 0; use constant CONFIG_EXT => '.trc'; use constant TEMPLATE_EXT => '.trt'; use constant HTMLFILE_ROOT => '/home/tfmail/html'; use constant HTMLFILE_EXT => '.html'; use constant CHARSET => 'iso-8859-1'; # USER CONFIGURATION << END >> # ---------------------------- # (no user serviceable parts beyond here) =head1 NAME GBview.pl - viewer script for a guestbook generated by TFmail.pl =head1 DESCRIPTION This CGI script reads a file in an XML-like format generated by TFmail.pl, formats the data in the file using a template and outputs it. See the C section near the end of the F file for more details. =cut use Fcntl ':flock'; use lib LIBDIR; use NMStreq; BEGIN { use vars qw($VERSION); $VERSION = substr q$Revision: 1.1 $, 10, -1; } delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; $ENV{PATH} =~ /(.*)/ and $ENV{PATH} = $1; use vars qw($done_headers); $done_headers = 0; # # We want to trap die() calls, output an error page and # then do another die() so that the script aborts and the # message gets into the server's error log. If there is # already a __DIE__ handler installed then we must # respect it on our final die() call. # eval { local $SIG{__DIE__} ; main() }; if ($@) { my $message = $@; error_page($message); die($message); } sub main { my $treq = NMStreq->new( ConfigRoot => CONFIG_ROOT, MaxDepth => MAX_DEPTH, ConfigExt => CONFIG_EXT, TemplateExt => TEMPLATE_EXT, EnableUploads => 0, CGIPostMax => 10000, ); if ( HTMLFILE_ROOT eq '' ) { die "No HTMLFILE_ROOT set, nothing for this script to do\n"; } my $htmlfile = $treq->config('gbview_htmlfile', 'guestbook'); unless ( $htmlfile =~ /^([\w\-\/]+)$/ ) { die "bad gbview_htmlfile value [$htmlfile] in config file"; } $htmlfile = "@{[ HTMLFILE_ROOT ]}/$1@{[ HTMLFILE_EXT ]}"; open LOCK, ">>$htmlfile.lck" or die "open >>$htmlfile.lck: $!"; flock LOCK, LOCK_SH or die "flock $htmlfile.lck: $!"; open IN, "<$htmlfile" or die "open $htmlfile: $!"; my @entries; { local $/ = '' ; @entries = grep m##, }; close IN; close LOCK; unless ( $treq->config('gbview_oldest_first', 0) ) { @entries = reverse @entries; } my $total = scalar @entries; my $startat = $treq->param('startat') || 0; $startat =~ /^(\d{1,4})$/ or die "bad startat value [$startat]\n"; $startat = $1; splice @entries, 0, $startat; my $perpage = $treq->config('gbview_perpage', 0); $perpage =~ /^(\d{1,4})$/ or die "bad gbview_perpage value [$perpage] in config file\n"; $perpage = $1; my ($page_count, $this_is_page) = (1, 1); if ($perpage > 0) { splice @entries, $perpage; $page_count = int( ($total-1) / $perpage ) + 1; $this_is_page = int ( $startat / $perpage ) + 1; } $treq->install_foreach('entry', [map {extract_values($_)} @entries]); $treq->install_directive('can_go_back', ($startat > 0 ? 1 : 0)); $treq->install_directive('can_go_on', ($startat+$perpage <= $total-1 ? 1 : 0)); $treq->install_directive('prev_page_start', $startat - $perpage); $treq->install_directive('next_page_start', $startat + $perpage); $treq->install_directive('page_count', $page_count); $treq->install_directive('this_is_page', $this_is_page); $treq->install_directive('multiple_pages', ($page_count > 1 ? 1 : 0) ); $treq->install_foreach('page', [ map {{ page => $_, this => ($_ == $this_is_page ? 1 : 0), start => ($_-1) * $perpage, }} (1..$page_count) ]); my $template = $treq->config('gbview_template', 'gbview'); html_page($treq, $template); } =head1 INTERNAL FUNCTIONS =over =item extract_values ( STRING ) Converts a string consisting of named values encoded in an XML-like format into a hashref. The format is: $value Where C<$name> and C<$value> are the strings that end up as keys and values in the hash. Stores a reference to the value rather than the value itself, to prevent HTML metacharacters in the values from being escaped when they're displayed via a template. This is nessessary to avoid double escaping, since HTML metacharacters were escaped by TFmail.pl when the data was written to the file. =cut sub extract_values { my ($string) = @_; my %hash; while ( $string =~ m#(.*?)#sg ) { my ($key, $val) = ($1, $2); $hash{$key} = \$val; } return \%hash; } =item html_page ( TREQ, TEMPLATE ) Outputs an HTML page using the template TEMPLATE. =cut sub html_page { my ($treq, $template) = @_; print "Content-type: text/html; charset=@{[ CHARSET ]}\n\n"; $done_headers = 1; $treq->process_template($template, 'html', \*STDOUT); } =item error_page ( MESSAGE ) Displays an "S" page, without using a template since the error may have arisen during template resolution. =cut sub error_page { my ($message) = @_; unless ( $done_headers ) { print < Error EOERR $done_headers = 1; } if ( DEBUGGING ) { $message = '

' . NMStreq->escape_html($message) . '

'; } else { $message = ''; } print <Application Error

An error has occurred in the program

$message EOERR } =back =head1 MAINTAINERS The NMS project, Ehttp://nms-cgi.sourceforge.net/E To request support or report bugs, please email Enms-cgi-support@lists.sourceforge.netE =head1 COPYRIGHT Copyright 2002 London Perl Mongers, All rights reserved =head1 LICENSE This script is free software; you are free to redistribute it and/or modify it under the same terms as Perl itself. =cut