#
# ----------------------
# DBMan
# ----------------------
# Database Administrator
#
# File: html.pl
# Description: This file contains all the HTML that the program generates.
# Author: Alex Krohn
# Web: http://www.gossamer-threads.com/
# Version: 2.05
# CVS Revision: $Id: html.pl,v 1.3 2000/07/08 18:14:40 alex Exp $
#
# COPYRIGHT NOTICE:
#
# Copyright 1997 Gossamer Threads Inc. All Rights Reserved.
#
# This program is being distributed as shareware. It may be used and
# modified free of charge for personal, academic, government or non-profit
# use, so long as this copyright notice and the header above remain intact.
# Any commercial use should be registered. Please also send me an email,
# and let me know where you are using this script. By using this program
# you agree to indemnify Gossamer Threads Inc. from any liability.
#
# Selling the code for this program without prior written consent is
# expressly forbidden. Obtain permission before redistributing this
# program over the Internet or in any other medium. In all cases
# copyright and header must remain intact.
#
# Please check the README file for full details on registration.
# =====================================================================
##########################################################
## HTML Globals ##
##########################################################
# Put any globals you like in here for your html pages.
$html_title = 'PRTC Inquiries Database';
##########################################################
## Record Layout ##
##########################################################
sub html_record_form {
# --------------------------------------------------------
# The form fields that will be displayed each time a record is
# edited (including searching). You don't want to put the
#
tags for each field.
# The values to be displayed are in %rec and should be incorporated
# into your form. You can use &build_select_field, &build_checkbox_field
# and &build_radio_field to generate the respective input boxes. Text and
# Textarea inputs can be inserted as is. If you turn on form auto
# generation, the program will build the forms for you (all though they may
# not be as nice). See the README for more info.
my (%rec) = @_;
($db_auto_generate and print &build_html_record_form(%rec) and return);
my $font_color = 'Font face="Arial, Helvetica, sans-serif" Size=2 Color=#555555';
print qq|
American Plan: accommodation packages include meals maid and dock service
Housekeeping: you prepare your own meals and do your own housekeeping
Outpost: a single cabin in the wilderness
<$font_color>Access to the Lodge, Resort, Camp or Outpost:
|;
}
sub html_record {
# --------------------------------------------------------
# How a record will be displayed. This is used primarily in
# returning search results and how it is formatted. The record to
# be displayed will be in the %rec hash.
my (%rec) = @_; # Load any defaults to put in the VALUE field.
$rec{$db_key} =~ s/.B>//g; # email record hack line
($db_auto_generate and print &build_html_record(%rec) and return);
my $font_color = 'Font face="Arial, Helvetica, sans-serif" Size=2 Color=#555555';
my $font = 'Font face="Arial, Helvetica, sans-serif" Size=2';
$url{'Email'} = $rec{'Email'};
$url{'Email'} =~ s/<\/?B>//g;
$rec{'Description'} =~ s/\n/ /g;
print qq|
|;
}
##########################################################
## Home Page ##
##########################################################
sub html_home {
# --------------------------------------------------------
# The database manager home page.
##### add cookie hack
if($in{'cookie'} =="1"){
print "Location: $db_script_link_url&Userid=$db_userid&view_records=1&ww=on\n\n";
}
else{
&html_print_headers;
print qq|
$html_title: Main Menu.
|;
&html_print_htmlstuffs;
print qq|
<$font_title>
Main Menu
Permissions: |;
print " Search " if ($per_view);
print " Add " if ($per_admin);
print " Delete " if ($per_del);
print " Modify " if ($per_mod);
print " Admin " if ($per_admin);
print " None " if (!($per_view || $per_add || $per_del || per_mod));
print qq|
<$font>
Welcome to the PRTC inquiry database. As a member in good standing of the Patricia Regional Tourist Council, you have access to this up-to-date
database containing the inquiries we receive daily over our web site and 1-800 numbers. Please make your selection:
|; &html_footer; print qq|
|;
} #### close else for cookie hack
}
sub html_footer {
# --------------------------------------------------------
# Print the menu and the footer and logo. It would be nice if you left
# the logo in. ;)
#
# We only print options that the user have permissions for.
#
my $font = 'Font face="Arial, Helvetica, sans-serif" Size=2';
print qq!
<$font>!;
print qq!| Home ! if ($per_view);
print qq!| Add ! if ($per_admin);
print qq!| Search ! if ($per_view);
print qq!| Delete ! if ($per_del);
print qq!| Modify ! if ($per_mod);
print qq!| List All ! if ($per_view);
print qq!| Admin ! if ($per_admin);
print qq!| Log Off ! if ($per_admin);
print qq!
!;
# Print the Footer.
print qq~
The Patricia Regional Tourist Council can be reached at 807-223-6792 or fax 807-223-2465.
~;
}
sub html_footer_for_add {
# --------------------------------------------------------
# Print the menu and the footer and logo. It would be nice if you left
# the logo in. ;)
#
# We only print options that the user have permissions for.
#
my $font = 'Font face="Arial, Helvetica, sans-serif" Size=2';
print qq!
<$font>!;
print qq!| Home ! if ($per_view);
print qq!| Add ! if ($per_admin);
print qq!| Search ! if ($per_view);
print qq!| Delete ! if ($per_del);
print qq!| Modify ! if ($per_mod);
print qq!| Show last 7 Days ! if ($per_view);
print qq!| List All ! if ($per_view);
print qq!| Admin ! if ($per_admin);
print qq!| Log Off ! if ($per_admin);
print qq!
~;
}
sub html_search_options {
# --------------------------------------------------------
# Search options to be displayed at the bottom of search forms.
#
print qq~
Search Options:
Keyword Search (will match against all fields)
Max. Returned Hits
Sort By:
~;
}
##########################################################
## Adding ##
##########################################################
sub html_add_form {
# --------------------------------------------------------
# The add form page where the user fills out all the details
# on the new record he would like to add. You should use
# &html_record_form to print out the form as it makes
# updating much easier. Feel free to edit &get_defaults
# to change the default values.
&html_print_headers;
print qq|
Get a FREE Canadian Fishing Map
|;
&html_print_htmlstuffs;
print qq|
|;
}
sub html_add_success {
# --------------------------------------------------------
# The page that is returned upon a successful addition to
# the database. You should use &get_record and &html_record
# to verify that the record was inserted properly and to make
# updating easier.
############## Send admin email when record added ###################
open (MAIL, "$mailprog") or &cgierr("Can't start mail program");
print MAIL "To: $admin_email\n";
print MAIL "From: $in{$db_cols[7]}\n";
print MAIL "Subject: Patricia Tourist Council Information Request Form\n\n";
print MAIL "-" x 75 . "\n\n";
print MAIL "The following is an inquiry forwarded to you from the Patricia Regional Tourist Council web site.\nTo contact the council please\nphone 807-223-6792 OR\nwrite P.O. Box 66 Dryden, ON P8N 2Y7\n\nTo unsubscribe from this list please email us at ruth\@freemap.ca with the subject line UNSUBSCRIBE FROM INQUIRY LIST\n\n";
foreach $column(@db_cols) {
print MAIL "$column: $in{$column}\n";
}
print MAIL "-" x 75 . "\n\n";
print MAIL "Inquiries mailing list\nInquiries@freemap.ca\nhttp://lists.freemap.ca/mailman/listinfo/inquiries\n\n";
close MAIL;
######## end admin email ###########
&html_print_headers;
print qq|
Thank you. We will be sending out your info ASAP
|;
&html_print_htmlstuffs;
print qq|
THANK YOU
We're taking you to our places to stay in Canada's
Heartland page.
|;
}
sub html_add_failure {
# --------------------------------------------------------
# The page that is returned if the addition failed. An error message
# is passed in explaining what happened in $message and the form is
# reprinted out saving the input (by passing in %in to html_record_form).
my ($message) = $_[0];
&html_print_headers;
print qq|
$html_title: Error! Unable to Add Record.
|;
&html_print_htmlstuffs;
print qq|
|; &html_footer; print qq|
|;
}
##########################################################
## Viewing ##
##########################################################
sub html_view_search {
# --------------------------------------------------------
# This page is displayed when a user requests to search the
# database for viewing.
# Note: all searches must use GET method.
#
open (DB, "<$db_file_name") or &cgierr("unable to open db file: $db_file_name.\nReason: $!");
if ($db_use_flock) { flock(DB, 1); }
@lines = ;
close DB;
$number_of_records = scalar(@lines);
&html_print_headers;
print qq|
$html_title: Search the Database.
|;
&html_print_htmlstuffs;
print qq|
|; &html_footer; print qq|
|;
}
sub html_advanced_search {
# --------------------------------------------------------
# This page is displayed when a user requests to search the
# database for viewing.
# Note: all searches must use GET method.
#
&html_print_headers;
print qq|
$html_title: Search the Database.
|;
&html_print_htmlstuffs;
print qq|
|; &html_footer; print qq|
|;
}
sub html_view_success {
# --------------------------------------------------------
# This page displays the results of a successful search.
# You can use the following variables when displaying your
# results:
#
# $numhits - the number of hits in this batch of results.
# $maxhits - the max number of hits displayed.
# $db_total_hits - the total number of hits.
# $db_next_hits - html for displaying the next set of results.
#
my (@hits) = @_;
my ($numhits) = ($#hits+1) / ($#db_cols+1);
my ($maxhits); $in{'mh'} ? ($maxhits = $in{'mh'}) : ($maxhits = $db_max_hits);
&html_print_headers;
print qq|
$html_title: Search Results.
|;
&html_print_htmlstuffs;
print qq|
<$font>Your search returned $db_total_hits matches.
|;
if ($db_next_hits) {
print " <$font>Pages: $db_next_hits";
}
# Go through each hit and convert the array to hash and send to
# html_record for printing.
$new_url = $ENV{'QUERY_STRING'};
$new_url =~ s/\&sb=\d+//;
$new_url =~ s/\&so=\w+//;
for ($col=0; $col <=$#db_cols; ++$col) {
if ($in{'sb'} == $col) {
if ($in{'so'} eq 'descend') { $sb[$col] = 'ascend'; }
else { $so[$col] = 'descend'; }
}
else { $so[$col] = 'ascend'; }
}
# Note: In each of the header cells, replace # with the field number
# of the field that is associated with that header -- in both places within each line.
print qq|
|;
}
sub html_view_failure {
# --------------------------------------------------------
# The search for viewing failed. The reason is stored in $message
# and a new search form is printed out.
my ($message) = $_[0];
&html_print_headers;
print qq|
$html_title: Search Failed.
|;
&html_print_htmlstuffs;
print qq|
|; &html_footer; print qq|
|;
}
##########################################################
## Deleting ##
##########################################################
sub html_delete_search {
# --------------------------------------------------------
# The page is displayed when a user wants to delete records. First
# the user has to search the database to pick which records to delete.
# That's handled by this form.
&html_print_headers;
print qq|
$html_title: Search the Database for Deletion.
|;
&html_print_htmlstuffs;
print qq|
|;
}
sub html_delete_form {
# --------------------------------------------------------
# The user has searched the database for deletion and must now
# pick which records to delete from the records returned. This page
# should produce a checkbox with name=ID value=delete for each record.
# We have to do a little work to convert the array @hits that contains
# the search results to a hash for printing.
my ($status, @hits) = &query("mod");
my ($numhits) = ($#hits+1) / ($#db_cols+1);
my ($maxhits); $in{'mh'} ? ($maxhits = $in{'mh'}) : ($maxhits = $db_max_hits);
my (%tmp);
&html_print_headers;
print qq|
$html_title: Delete Record(s).
|;
&html_print_htmlstuffs;
print qq|
|;
}
sub html_delete_success {
# --------------------------------------------------------
# This page let's the user know that the records were successfully
# deleted.
my $message = shift;
&html_print_headers;
print qq|
$html_title: Record(s) Deleted.
|;
&html_print_htmlstuffs;
print qq|
$html_title: Record(s) Deleted.
<$font_title>
Record(s) Deleted
<$font>
The following records were deleted from the database: '$message'.
|; &html_footer; print qq|
|;
}
sub html_delete_failure {
# --------------------------------------------------------
# This page let's the user know that some/all of the records were
# not deleted (because they were not found in the database).
# $errstr contains a list of records not deleted.
my ($errstr) = $_[0];
&html_print_headers;
print qq|
$html_title: Error: Record(s) Not Deleted.
|;
&html_print_htmlstuffs;
print qq|
$html_title: Error: Record(s) Not Deleted
<$font_title>
Error: Record(s) Not Deleted
<$font>
The records with the following keys were not found in the database: '$errstr'.
|; &html_footer; print qq|
|;
}
##########################################################
## Modifying ##
##########################################################
sub html_modify_search {
# --------------------------------------------------------
# The page is displayed when a user wants to modify a record. First
# the user has to search the database to pick which record to modify.
# That's handled by this form.
&html_print_headers;
print qq|
$html_title: Search the Database for Modifying.
|;
&html_print_htmlstuffs;
print qq|
|;
}
sub html_modify_form {
# --------------------------------------------------------
# The user has searched the database for modification and must now
# pick which record to modify from the records returned. This page
# should produce a radio button with name=modify value=ID for each record.
# We have to do a little work to convert the array @hits that contains
# the search results to a hash for printing.
my (%tmp);
my ($status, @hits) = &query("mod");
my ($numhits) = ($#hits+1) / ($#db_cols+1);
if (($numhits == 1) and !$in{'nh'}) { $in{'modify'} = $hits[$db_key_pos]; &html_modify_form_record(); return; }
my ($maxhits); $in{'mh'} ? ($maxhits = $in{'mh'}) : ($maxhits = $db_max_hits);
&html_print_headers;
print qq|
$html_title: Modify Record.
|;
&html_print_htmlstuffs;
print qq|
|;
}
sub html_modify_form_record {
# --------------------------------------------------------
# The user has picked a record to modify and it should appear
# filled in here stored in %rec. If we can't find the record,
# the user is sent to modify_failure.
my (%rec) = &get_record($in{'modify'});
if (!%rec) { &html_modify_failure("unable to find record/no record specified: $in{'modify'}"); return; }
&html_print_headers;
print qq|
$html_title: Modify a Record.
|;
&html_print_htmlstuffs;
print qq|
|;
}
sub html_modify_success {
# --------------------------------------------------------
# The user has successfully modified a record, and this page will
# display the modified record as a confirmation.
&html_print_headers;
print qq|
$html_title: Record Modified.
|;
&html_print_htmlstuffs;
print qq|
$html_title: Record Modified.
<$font_title>
Record Modified
<$font>
The following record was successfully modified:
|; print qq|
|;
}
sub html_modify_failure {
# --------------------------------------------------------
# There was an error modifying the record. $message contains
# the reason why.
my ($message) = $_[0];
&html_print_headers;
print qq|
$html_title: Error! Unable to Modify Record.
|;
&html_print_htmlstuffs;
print qq|
|;
}
sub html_login_failure {
# --------------------------------------------------------
# There was an error loggin in. The error message is stored in $message.
my ($message) = $_[0];
&html_print_headers;
print qq|
$html_title: Login Error.
|;
&html_print_htmlstuffs;
print qq|
|;
}
sub html_admin_display {
# --------------------------------------------------------
# The displays the list of current users.
my ($message, $user_list, $password, $permissions) = @_;
&html_print_headers;
print qq|
$html_title: User Management.
|;
&html_print_htmlstuffs;
print qq|
|;
}
sub html_unauth {
# --------------------------------------------------------
# A user tried to do something he was not authorized for.
&html_print_headers;
print qq|
$html_title: Error! Unauthorized Action.
|;
&html_print_htmlstuffs;
print qq|
$html_title: Error! Unauthorized Action.
<$font_title>
Error: Unauthorized Action
<$font>
The database program received a command that you are not authorized for.
|; &html_footer; print qq|
|;
}
sub html_signup_form {
# --------------------------------------------------------
# This form is displayed for new users who want to create an account.
#
my $error = shift;
&html_print_headers;
print qq|
$html_title: Create Account.
|;
&html_print_htmlstuffs;
print qq|
|;
}
sub html_signup_success {
# --------------------------------------------------------
# The user has successfully created a new account.
&html_print_headers;
print qq|
$html_title: Account Created.
|;
&html_print_htmlstuffs;
print qq|
|;
}
##########################################################
## Misc ##
##########################################################
sub html_unkown_action {
# --------------------------------------------------------
# The program received a command it did not recognize.
&html_print_headers;
print qq|
$html_title: Error! Unknown Action.
|;
&html_print_htmlstuffs;
print qq|
$html_title: Error! Unkown Action.
<$font_title>
Error: Unknown Action
<$font>
The database program received a command that it did not understand.
|; &html_footer; print qq|
|;
}
sub html_define_pdf_long {
# --------------------------------------------------------
# This page redisplays the results of a previous successful search.
# A new form is produced by &html_pdf_customization_form
# with the meaningful parameters of the old query as hidden input
# PLEASE NOTE: this one is for use with the standard setup
# of DBMan. If you use this one, change "&html_define_pdf" in
# the previously added subroutine 'customize_PDF' in db.cgi, to
# "&html_define_pdf_long"
# People using the short/long display mod by JPDeni should use
# sub html_define_pdf and change the reference to this sub in
# the previously added subroutine customize_PDF in db.cgi.
#
# $numhits - the number of hits in this batch of results.
# $maxhits - the max number of hits displayed.
# $db_total_hits - the total number of hits.
# $db_next_hits - html for displaying the next set of results.
#
my (@hits) = @_;
my ($numhits) = ($#hits+1) / ($#db_cols+1);
my ($maxhits); $in{'mh'} ? ($maxhits = $in{'mh'}) : ($maxhits = $db_max_hits);
&html_print_headers;
&extract_query; #### PDF addition
$thisSorting = $extract_sb . $extract_so;
$thisSorting =~ s/ \/ //;
print qq|
$html_title: PDF customization.
$html_title: PDF customization
<$font>
Your search returned $db_total_hits matches.
based on the following search criteria: $extract_query|; #### PDF addition
if (length ($thisSorting)>15) { print " ($thisSorting)
"; }
else {print " ($thisSorting)
";}
if ($db_next_hits) {
print " <$font>Pages: $db_next_hits";
}
# Go through each hit and convert the array to hash and send to
# html_record for printing.
for (0 .. $numhits - 1) {
print "
";
&html_record (&array_to_hash($_, @hits));
}
if ($db_next_hits) {
print " <$font>Pages: $db_next_hits";
}
&html_pdf_customization_form; #### PDF addition: here the actual customization form is put
print qq|
|; &html_footer; print qq|
|;
}
sub html_pdf_customization_form {
# --------------------------------------------------------
# a subroutine, which produces a new form
# to customize the output of a pdf-export call
# the previous query is recycled as hidden input using &recycle_old_query_for_pdf
$submit_button = "Make!";
$reset_button = "Back to default values";
print qq|
|;
}
sub html_pdf_direct_footer {
# --------------------------------------------------------
# a subroutine, which produces a small form with only two submit-buttons
# one to direclty produce the standard output of a pdf-export call
# the other to take the use to a new page, on which a customization form is produced
# the previous query is recycled as hidden input using &recycle_old_query_for_pdf
$submit_button = "Make Address Labels";
print qq|
|;
}
sub html_redirect_pdf {
print qq|
$html_title: Your labels are ready!
|;
&html_print_htmlstuffs;
print qq|
$html_title: labels exported to a PDF document
<$font_title>Your labels are ready!
<$font>You will be transferred automatically to the file.
If not: click this link to open the document in Acrobat.
If you do not already have Adobe Acrobat installed, you can download it here.
|; &html_footer; print qq|
|;
}
sub html_print_headers {
# --------------------------------------------------------
# Print out the headers if they haven't already been printed.
if (!$html_headers_printed) {
print "Content-type: text/html\n\n";
$html_headers_printed = 1;
}
}
sub html_print_htmlstuffs {
# --------------------------------------------------------
# Print out the headers if they haven't already been printed.
if (!$html_htmlstuffs_printed) {
print qq~
~;
$html_htmlstuffs_printed = 1;
}
}
####################################
# START OF html.pl EXPORT SUBROUTINES
####################################
sub export_to_Excel {
# --------------------------------------------------------
# Exports the results of a successful search.
# Exports all non-admin fields
# What we send depends on the Browser
my ($browser) = "";
my ($match) = ($ENV{'HTTP_USER_AGENT'} =~ m# MSIE #);
if ($match) { # Internet Explorer
if ($ENV{'HTTP_USER_AGENT'} =~ m# MSIE 3#) {
# this is recognized by PCs with Internet Explorer and Excel
# Check to see that is a registered type just in case
my ($match) = ($ENV{'HTTP_ACCEPT'} =~ m#vnd.ms-excel#);
if ($match) {
# Internet Explorer 3 with registered type
$browser = "IE3";
print qq| Content-type: application/vnd.ms-excel\n\n|;
}
}
if ($browser eq "") {
# must create a CSV file,
# otherwise IE4 et. al. gets mixed up with spaces in
# default Internet Temporary Files location
# it's easier then asking user to manually change his Internet options
$browser = "IE4";
&html_print_headers; # for page with link to CSV file
}
}
else {
# Ideally we could use javascript to check navigator.mimeType array
# Old code....
# print qq| Content-type: application/msexcel\n\n|;
# Start new code ...
$match = ($ENV{'HTTP_USER_AGENT'} =~ m#Mozilla/4.#);
if ($match) {
print qq| Content-type: application/vnd.ms-excel\n\n|;
}
else {
print qq| Content-type: application/msexcel\n\n|;
}
# End new code ............
# Netscape needs html header info, MSIE gets mixed up.
print qq|
$html_title: Search Results.
|;
}
my (@hits) = @_;
my ($numhits) = ($#hits+1) / ($#db_cols+1);
my ($maxhits); $in{'mh'} ? ($maxhits = $in{'mh'}) : ($maxhits = $db_max_hits);
if ($browser ne "IE4") {
&xl_header();
# Go through each hit and convert the array to hash and send to
# html_record for printing.
for (0 .. $numhits - 1) {
&xl_record (&array_to_hash($_, @hits));
}
print "
";
}
else {
# Open temporary csv file
my ($csvfilename) = "$db_uid" . ".csv";
my ($csvfileloc) = ">$db_csv_path$csvfilename";
open(CSVFILE, $csvfileloc) || die "Unable to open CSV file location ($csvfileloc).";
&csv_header();
# Go through each hit and convert the array to hash and send to
# csv_record for printing.
for (0 .. $numhits - 1) {
&csv_record (&array_to_hash($_, @hits));
}
close CSVFILE || die "Unable to close CSV file ($csvfilename).";
# Create link to CSV file for user to open
# delete file after use.
print "$html_title: Search Results.";
print qq|
|;
&html_print_htmlstuffs;
print qq|
Tip: to download, hold down "shift" and click the link above. Or, if you are using a Macintosh, hold down "option" and click.
How to use the Excel Export Once you have downloaded the file
Launch Microsoft Excel, or a similar spreadsheet program.
In Excel, select "open" and open the file you downloaded.
Excel will now put the inquiries you exported in a spreadsheet format.
|;
&html_footer;
}
print "";
}
sub csv_header {
# --------------------------------------------------------
# print field name headers for each column of data
my $num = 0;
for (my $i =0; $i <= $#db_cols; $i++) {
# Export all non-admin fields (admin form length = -2)
if ($db_form_len{$db_cols[$i]} >= -1) {
if ($num > 0) {print CSVFILE ",";}
print CSVFILE qq|$db_cols[$i]|;
$num += 1;
}
}
print CSVFILE "\n";
}
sub csv_record {
# --------------------------------------------------------
# writes record in CSV format
my (%rec) = @_; # Load any defaults to put in the VALUE field.
($db_auto_generate and print &build_html_record(%rec) and return);
my $num = 0;
for (my $i =0; $i <= $#db_cols; $i++) {
if ($db_form_len{$db_cols[$i]} >= -1) {
# Export all non-admin fields (admin form length = -2)
if ($num > 0) {print CSVFILE ",";}
print CSVFILE qq|"$rec{$db_cols[$i]}"|;
$num += 1;
}
}
print CSVFILE "\n";
}
sub xl_header {
# --------------------------------------------------------
# print field name headers for each column of data
print qq|
|;
for (my $i =0; $i <= $#db_cols; $i++) {
if ($db_form_len{$db_cols[$i]} >= -1) {
# Export all non-admin fields (admin form length = -2)
print qq|
<$font>$db_cols[$i]
|;
}
}
print "
";
}
sub xl_record {
# --------------------------------------------------------
# writes record in table format for Excel export
my (%rec) = @_; # Load any defaults to put in the VALUE field.
my $num = 0;
print "
";
for (my $i =0; $i <= $#db_cols; $i++) {
if ($db_form_len{$db_cols[$i]} >= -1) {
# Export all non-admin fields (admin form length = -2)
print qq|
<$font_title>Send an email Want to keep this inquiry for your records? Email it to yourself:
|;
if ($message) { print qq|There was a problem: $message|; }
print qq|
<$font>Fill in your email address, the subject of your email and the
message you wish to send.
|;
print qq|
|;
&html_footer;
print qq|
|;
}
###############################################################################
#file: html.pl #
# new subroutine #
# sub html_forward_email_success #
###############################################################################
sub html_forward_email_success {
#-----------------------------------------------
&html_print_headers;
print qq|
$html_title: Send an email
|;
&html_print_htmlstuffs;
print qq|