#!/usr/bin/perl -T -w

use strict;

# Contact Form is a Perl script that you can run on your website that will
# allow others to send you email through a web interface.
# See: http://ostermiller.org/contactform/
# Copyright (C) 2002-2008 Stephen Ostermiller
# http://ostermiller.org/contact.pl?regarding=Contact+Form
#
# 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.
#
# See copying.txt for details.

my(%SubmittedData, $mail_message, %AliasesMap, @AliasesOrdered,
%FieldMap, @Field_Order, $template_error, $field_name_to,
$field_name_from_email, $field_name_from_name, $field_name_subject,
$field_name_regarding, $field_name_referrer, $NO_DESCRIPTION,
$version, $LETTER, $DIGIT, $DOSEOL, $EOL, $LETTER_DIGIT,
$LETTER_DIGIT_HYPHEN, $HEX_DIGIT, $QUOTEDSTRING, $ATOM, $SUBDOMAIN, $WORD,
$DOMAIN, $LOCALPART, $EMAIL, $PHONE_DIGIT, $PHONE, $ZIPCODE, $PRICE, $FLOAT,
$INTEGER, $SOMETHING, $ANYTHING, $ONE_LINE_REQUIRED, $ONE_LINE_OPTIONAL,
$ZIPCODE_REQUIRED, $ZIPCODE_OPTIONAL, $PHONE_REQUIRED, $PHONE_OPTIONAL,
$EMAIL_REQUIRED, $EMAIL_OPTIONAL, $PRICE_REQUIRED, $PRICE_OPTIONAL,
$FLOAT_REQUIRED, $FLOAT_OPTIONAL, $INTEGER_REQUIRED, $INTEGER_OPTIONAL,
$BLANK, $PHONE_NO_AREA_CODE_OPTIONAL, $PHONE_NO_AREA_CODE_REQUIRED,
$PHONE_NO_AREA_CODE, @Aliases, $captcha,
@FormFields,
%disallowed_text
);

sub settings(){
	my %settings = ();

	# If the configuration file is set, then anything in the configuration
	# file over rides settings directly in this file.
	# It is recommended that the configuration file live outside of
	# webserver document root and it should be accessed by absolute path
	# here.  For example: configuration_file = "/etc/contact_form.conf"
	$settings{'configuration_file'} = "";

	# List of email address to which mail can be sent.
	# Mail cannot be sent to any email address which is not on this list.
	# If a single address is listed, it will be a hidden value on the
	# form, otherwise, the user will be presented with a pulldown menu
	# of aliases to which email can be sent.
	# The addresses listed here are never visible via served web pages.
	@Aliases = (
		#'administrator',&safeHeader($ENV{'SERVER_ADMIN'}),
		# The following aliases are commented out examples, remove the leading # sign to use them
		'Oļegs','olegs@velokurjers.lv,uldis@velokurjers.lv',
		#'postmaster','postmaster@yoursite.tld',
		#'two people','webmaster@yoursite.tld,postmaster@yoursite.tld',
	);

	# Modify the following to control how the HTML pages look

	# Page titles for the input and thank your pages
	$settings{'input_page_title'} = 'Svētceļojuma velobrauciens „DIEVNAMI ZIEMEĻKURZEMES PIEKRASTĒ”';
	$settings{'sent_page_title'} = 'Pieteikums nosūtīts.';

	# Extra text (may be html formatted) that will be placed on
	# the page before the the form
	$settings{'input_page_text'} = '<div align="center">
<h2>Svētceļojuma velobrauciena</h2>
<h1>&bdquo;DIEVNAMI ZIEMEĻKURZEMES PIEKRASTĒ&rdquo;</h1>
<h2>Rīga &ndash; Ventspils </h2>
<h2>15.- 23. augusts 2009</h2>
<h2><br />
dalībnieka anketa</h2>
</div>
Ar velobrauciena <a href="../pivot/entry.php?id=149" title="Velobrauciena nolikums">nolikumu</a> esmu iepazinies un tam piekrītu.<h3> <h3>';
	$settings{'sent_page_text'} = '<p class="contactform cf_message" id="cf_thankyoumessage">Paldies par Jūsu pieteikumu!</p>';
	$settings{'preview_page_text'} = '<p class="contactform cf_message" id="cf_previewmessage">Lūdzu pirms pieteikšanās pārbaudiet un vajadzības gadījumā labojiet anketas datus.</p>';

	# Page structure -- the look and feel of the page
	# This variable may be either changed directly, or if the
	# page_template_file variable is set, this variable is
	# ignored and the template file is used instead.
	# Contact form can place content into any of four places:
	# $title -- the title of the page
	# $css -- style rules that control how the form looks
	# $javascript -- client side validation rules.
	# $content -- the form itself.
	# The css and title variables are optional and can easily
	# be omitted and replaced with your own elements to better
	# suit your taste.  The form will not work properly if either
	# the javascript or content variables are removed or duplicated.
	$settings{'page_template'} =
	'<html>
	<head>
	<title>$title</title>
	$css
	$javascript
	</head>
	<body class="contactform cf_body" id="cf_body">
	<h1 class="contactform cf_header" id="cf_titleheader"></h1>
	$content
	</body>
	</html>
	';

	# if the template file is set, the page_template variable
	# is ignored and the template is loaded from the named file.
	# for example:
	# my $page_template_file = "mytemplate.html";
	# or
	# my $page_template_file = "/home/me/contact.template";
	# If this file is set, the file will be read every time this script
	# is called, not the most efficient, but very convenient.
	# The template file must be in the same format as the page_template
	# variable above
	$settings{'page_template_file'} = "";

	# Link back to contact form.
	# You may remove the link by setting this variable to the empty string:
	# my $contact_form_link = "";
	# If you do remove it, please tell your friends about contact form,
	# link to contact form somewhere else, write a blog entry about
	# contact form, post in a forum about contact form, or otherwise
	# spread the word.
	$settings{'contact_form_link'} = "<p class=\"contactform cf_message\" id=\"cf_version\"><a class=\"contactform cf_link\" href=\"http://ostermiller.org/contactform/\">Contact Form $version</a></p>";

	# FormFields is the list of questions the user is expected
	# to answer. The questions will appear in the same order as
	# they are ordered here. You may safely remove the subject,
	# email, name, and message from the form. The to field should
	# not be removed. The name of each field should contain only
	# letters, numbers, and underscore.  Spaces or symbols should
	# not be used.  Each has several attributes that control the
	# display of the question to the user.
	#
	# "required"
	# a regular expression that describes what a valid submission looks
	# like.  By default, any entry at all is allowed.
	# Consider using the following pre-defined regular expressions:
	# $SOMETHING, $ANYTHING, $ONE_LINE_REQUIRED, $ONE_LINE_OPTIONAL,
	# $ZIPCODE_REQUIRED, $ZIPCODE_OPTIONAL, $PHONE_REQUIRED,
	# $PHONE_OPTIONAL, $EMAIL_REQUIRED, $EMAIL_OPTIONAL, $PRICE_REQUIRED,
	# $PRICE_OPTIONAL, $FLOAT_REQUIRED, $FLOAT_OPTIONAL,
	# $INTEGER_REQUIRED, $INTEGER_OPTIONAL, $BLANK, $PHONE_NO_AREA_CODE_OPTIONAL,
	# $PHONE_NO_AREA_CODE_REQUIRED
	#
	# "error"
	# A user friendly error message for each required
	# element that a user gets wrong.
	#
	# "type"
	# Type of input in web pages for each field.
	# Currently supported are 'text', 'hidden', 'radio',
	# 'select', and 'textarea'
	# If there is no type, 'text' is assumed.
	# Setting the type for the to field will have no effect since
	# the to field is handled specially.
	#
	# "description"
	# Description to appear next to entry forms and in
	# the email or $NO_DESCRIPTION for none
	# If no description is given the field name followed
	# by a colon is used
	#
	# "selected"
	# For fields of type "select", or "radio" indicates
	# the default selection
	#
	# "special"
	# Any special purpose for which the field is used.
	# Must be one of "to", "from", "name", "subject",
	# "regarding", or "referrer"
	#
	@FormFields = (
		'to', {
			'required' => $ONE_LINE_REQUIRED,
			'error' => 'Norādiet saņēmēju.',
			'description' => 'Kam:',
			# Alias of the address put in the "To:" field of the email.
			'special' => 'to',
		},
		'name', {
			'required' => $ONE_LINE_REQUIRED,
			'error' => 'Jums jāieraksta savs vārds un uzvārds.',
			'type' => 'text',
			'description' => 'Jūsu vārds, uzvārds:',
			# Put in the "From:" field of the email as the name of the person it is from
			'special' => 'name',
		},
		'pk', {
			'required' => $FLOAT_REQUIRED,
			'error' => 'Jums jāieraksta savs personas kods.',
			'type' => 'text',
			'description' => 'Jūsu personas kods:',
			# Put in the "From:" field of the email as the name of the person it is from
			'special' => 'pk',
		},
		'phone', {
			'required' => $PHONE_NO_AREA_CODE_REQUIRED,
			'error' => 'Jūs ievadījāt nederīgu tālruņa numuru.',
			'type' => 'text',
			'description' => 'Telefona numurs (vēlams mobilais):',
		},
		'address1', {
			'required' => $ONE_LINE_REQUIRED,
			'error' => 'Lūdzu norādiet savu dzīves vietu.',
			'type' => 'text',
			'description' => 'Jūsu dzīves vieta:',
		},
		'email', {
			'required' => $EMAIL_REQUIRED,
			'error' => 'Šī nav derīga e-pasta adrese.',
			'type' => 'text',
			'description' => 'Jūsu e-pasta adrese:',
			# Put in the "From:" field of the email as the email of the person it is from
			'special' => 'from',
		},
		'message', {
			'required' => $SOMETHING,
			'error' => 'Aprakstiet savu velotūrisma pieredzi.',
			'type' => 'textarea',
			'description' => 'Iepriekšējā velopieredze.',
		},
		'phonerad', {
			'required' => $PHONE_NO_AREA_CODE_OPTIONAL,
			'error' => 'Jūs ievadījāt nederīgu tālruņa numuru.',
			'type' => 'text',
			'description' => 'Radinieka tel. (kam paziņot dalībnieka traumas utt. gadījumā):',
		},
		'true_false1', {
			# radio buttons with a prefilled option
			'type' => 'radio',
			'required' => '^(?:jā|nē)$',
			'error' => 'Lūdzu atbildiet uz jautājumu.',
			'description' => '<h2>Piedalīšos šādos svētceļojuma posmos:</h2><br/>1.diena:  15.augusts, sestdiena Rīga - Bulduri - Dubulti – Sloka - Ķemeri',
			'selected' => 'nē',
		},
		'true_false2', {
			# radio buttons with a prefilled option
			'type' => 'radio',
			'required' => '^(?:jā|nē)$',
			'error' => 'Lūdzu atbildiet uz jautājumu.',
			'description' => '2.diena:  16.augusts, svētdiena Ķemeri – Tukums -Sēme - Engure',
			'selected' => 'nē',
		},
		'true_false3', {
			# radio buttons with a prefilled option
			'type' => 'radio',
			'required' => '^(?:jā|nē)$',
			'error' => 'Lūdzu atbildiet uz jautājumu.',
			'description' => '3.diena:  17.augusts, pirmdiena Engure – Dzirciems – Balgale – Lauciena – Talsi',
			'selected' => 'nē',
		},
		'true_false4', {
			# radio buttons with a prefilled option
			'type' => 'radio',
			'required' => '^(?:jā|nē)$',
			'error' => 'Lūdzu atbildiet uz jautājumu.',
			'description' => '4.diena:  18.augusts, otrdiena Talsi – Dārta – Iģene – Kūļciems – Mērsrags',
			'selected' => 'nē',
		},
		'true_false5', {
			# radio buttons with a prefilled option
			'type' => 'radio',
			'required' => '^(?:jā|nē)$',
			'error' => 'Lūdzu atbildiet uz jautājumu.',
			'description' => '5.diena:  19.augusts, trešdiena Mērsrags – Kaltene - Roja',
			'selected' => 'nē',
		},
		'true_false6', {
			# radio buttons with a prefilled option
			'type' => 'radio',
			'required' => '^(?:jā|nē)$',
			'error' => 'Lūdzu atbildiet uz jautājumu.',
			'description' => '6.diena:  20.augusts, ceturtdiena Roja – Valdemārpils – Dundaga – Ģipka',
			'selected' => 'nē',
		},
		'true_false7', {
			# radio buttons with a prefilled option
			'type' => 'radio',
			'required' => '^(?:jā|nē)$',
			'error' => 'Lūdzu atbildiet uz jautājumu.',
			'description' => '7.diena:  21.augusts, piektdiena Ģipka –Kolka – Mazirbe',
			'selected' => 'nē',
		},
		'true_false8', {
			# radio buttons with a prefilled option
			'type' => 'radio',
			'required' => '^(?:jā|nē)$',
			'error' => 'Lūdzu atbildiet uz jautājumu.',
			'description' => '8.diena:  22.augusts, sestdiena Mazirbe – Miķeļtornis – Rinda',
			'selected' => 'nē',
		},
		'true_false9', {
			# radio buttons with a prefilled option
			'type' => 'radio',
			'required' => '^(?:jā|nē)$',
			'error' => 'Lūdzu atbildiet uz jautājumu.',
			'description' => '9.diena:  23.augusts, svētdiena Rinda – Ventspils',
			'selected' => 'nē',
		},
		'yes_no', {
			# required radio buttons
			'type' => 'radio',
			'required' => '^(?:jā|nē)$',
			'error' => 'Lūdzu atbildiet uz jautājumu.',
			'description' => 'Vai Jums nepieciešama velotransporta īre?',
		},
		'confirm', {
			# This is a field designed to thwart automated submissions
			# This field is not visible to the user.
			# Bots may attempt to fill it in which will prevent submission.
			'required' => $BLANK,
			'error' => 'This field should be left blank',
			'type' => 'trap',
			'description' => 'Leave blank:',
		},
		'subject', {
			'required' => $ONE_LINE_REQUIRED,
			'error' => 'You must enter a subject.',
			'type' => 'text',
			'description' => 'Subject:',
			# Put in the "Subject:" field of the email.
			'special' => 'subject',
			'enabled' => 0,
		},
		'regarding', {
			'required' => $ANYTHING,
			'error' => '',
			'type' => 'hidden',
			'description' => $NO_DESCRIPTION,
			# Put in the "Subject:" field of the email in parenthesis.
			'special' => 'regarding',
		},
		'referrer', {
			'required' => $ANYTHING,
			'error' => '',
			'type' => 'hidden',
			'description' => $NO_DESCRIPTION,
			# The original referring url.
			'special' => 'referrer',
		},
		# The following fields are disabled examples, remove the 'enabled' => 0 line to use them

		'fax', {
			'required' => $PHONE_OPTIONAL,
			'error' => 'The fax number you entered does not appear to be valid.',
			'type' => 'text',
			'description' => 'Fax Number:',
			'enabled' => 0,
		},
		'address2', {
			'required' => $ONE_LINE_OPTIONAL,
			'error' => 'Please enter your address.',
			'type' => 'text',
			'description' => $NO_DESCRIPTION,
			'enabled' => 0,
		},
		'city', {
			'required' => '^(?:[a-zA-Z ]*)$',
			'error' => 'Your city does not appear to be valid.',
			'type' => 'text',
			'description' => 'City:',
			'enabled' => 0,
		},
		'state', {
			'required' => '^(?:AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MH|MA|MI|FM|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VA|VI|WA|WV|WI|WY)$',
			'error' => 'Please choose your state.',
			'type' => 'select',
			'description' => 'State:',
			'enabled' => 0,
		},
		'zip', {
			'required' => $ZIPCODE_OPTIONAL,
			'error' => 'Your zipcode does not appear to be valid.',
			'type' => 'text',
			'description' => 'Zipcode:',
			'enabled' => 0,
		},
		'most_basic_question', {
			# uses the default values for required, error, type, and description
			'enabled' => 0,
		},
		'color', {
			# A required select drop down
			'type' => 'select',
			'required' => '^(?:Red|Orange|Yellow|Green|Blue|Purple|Black|White)$',
			'error' => 'Please choose a color.',
			'description' => 'Choose a color:',
			'enabled' => 0,
		},
		'vegetable', {
			# An optional select drop down
			'type' => 'select',
			'required' => '^(?:|Corn|Peas|Beans|Carrots|Broccoli)$',
			'error' => 'Please choose a valid vegetable.',
			'description' => 'Which (if any) is your favorite vegetable:',
			'enabled' => 0,
		},
		'letter', {
			# A select drop down with a pre-filled option
			'type' => 'select',
			'required' => '^(?:A|B|C|D)$',
			'error' => 'Please choose on of the four letters.',
			'description' => 'Choose a letter (C is selected by default):',
			'selected' => 'C',
			'enabled' => 0,
		},
		'vegetable2', {
			# optional radio buttons
			'type' => 'radio',
			'required' => '^(?:|Lettuce|Tomato|Brussel Sprouts)$',
			'error' => 'Please choose a valid vegetable.',
			'description' => 'Which (if any) is your favorite vegetable:',
			'enabled' => 0,
		},
		'about', {
			# prefilled
			'type' => 'text',
			'required' => $ANYTHING,
			'error' => 'Please enter what this message is about.',
			'description' => 'What is this message about:',
			'default' => 'Email',
			'enabled' => 0,
		},
	);

	# Captcha settings -- Displays distorted text that the user
	# must type in to prove that they are human.
	# Sign up for a recaptach account at http://recaptcha.net/
	# enter the public and private keys that they give you here
	# Your server must have the Captcha::reCAPTCHA library installed.
	# To install it, talk to your admin or use the command line:
	# cpan install 'Captcha::reCAPTCHA'
	$settings{'recaptcha_public_key'} = '';
	$settings{'recaptcha_private_key'} = '';

	# The name of the field for submit/preview action
	$settings{'field_name_submit'} = 'do';

	# Regular expression describing urls which can host forms
	# pointing to this program. The referral URL is generated on the
	# client side by the browser. Therefore it useless to prevent
	# unauthorized submission by mail software robots. You can
	# prevent somebody from reliably hosting, on another server,
	# a form pointing to this email software.
	# Consider the following options:
	# This form can be used from any site at all: .*
	# This form can only be used from pages on yoursite.tld: ^http[s]?\\:\\/\\/yoursite\\.tld\\/
	# This form can only be used from pages on the domain or ip address: ^http[s]?\\:\\/\\/((yoursite\\.tld)|(127\\.0\\.0\\.1))\\/'
	# This form can only be used from a specific page: ^http[s]?\\:\\/\\/yoursite\\.tld\\/directory\\/page\\.html\\$'
	$settings{'allowedReferers'} = ".*";

	# Regular expressions for text that is not allowed in any fields
	%disallowed_text = (
		"\\<[ \\r\\n\\t]*[Aa][ \\r\\n\\t]","You appear to be trying to include HTML formatted links.  Links should not be formatted like this.",
		"\\[[ \\r\\n\\t]*[Uu][Rr][Ll][ \\r\\n\\t]*\\=","You appear to be trying to include message board formatted links.  Links should not be formatted like this.",
	);

	# Whether or not users are required to preview
	# their message before sending.
	# 0 -- preview disabled (allows users to send mail the fastest)
	# 1 -- preview required (best for spam prevention)
	# 2 -- preview available, but not required  (most choice for users)
	$settings{'require_preview'} = 1;

	# The character set for the contact page.
	$settings{'charset'} = 'UTF-8';

	# Command line program used to send email
	# '/usr/lib/sendmail -i -t' almost always works fine
	$settings{'sendmail'} = '/usr/lib/sendmail -i -t';

	# Whether or not to include javascript that checks the form
	# before it is submitted.
	# This is generally good, but it increases the page size, increases the
	# complexity of the page, and could alert hackers to the
	# regular expressions you are using for verification.
	# Set to 0 to disable, 1 to enable.
	$settings{'use_client_side_verification'} = 1;

	# This should be either 'POST' or 'GET'
	$settings{'submit_method'} = 'POST';

	# Placed next to form elements that must be filled in
	$settings{'required_marker'} = '<span class="contactform cf_required">*</span>';
	$settings{'required_marker_note'} = "<p class=\"contactform cf_message\" id=\"cf_requiredexplain\">".$settings{'required_marker'}." apzīmē obligāti aizpildāmu lauku.</p>";

	# Style rules for the input page.
	# to put question and answer on the same line use:
	# .cf_userentry, .cf_radioselection { display:inline; margin-left:0.25cm; }
	$settings{'input_page_css'} =
	'<style>
	.cf_error { color:red; }
	.cf_textentry { min-width:300px; width:100%; max-width:600px; width:expression(document.body.clientWidth>600?"600px":"auto");}
	textarea.contactform { height:4in; }
	.cf_required { color:green; }
	#cf_version { text-align:right; }
	#cf_global_error { margin-bottom:0.25cm; }
	.cf_field { margin-bottom:0.5cm; }
	.cf_nt { display:none; }
	.cf_preview { border:thin black ridge; padding:1cm; max-width:600px; width:expression(document.body.clientWidth>600?"600px":"auto");margin-bottom:1cm;}
	</style>';

	# Style rules for thank you page
	$settings{'sent_page_css'} =
	'<style>
	.cf_sent { border:thin black ridge; padding:1cm; max-width:600px; width:expression(document.body.clientWidth>600?"600px":"auto");}
	#cf_version { text-align:right; }
	</style>';

	# Link to favicon, placed in the head after the JavaScript
	$settings{'icon_link'}='<link rel="icon" href="'.&escapeHTML($ENV{'SCRIPT_NAME'}).'/contactformicon.png" type="image/png">';

	# Form copyright header placed in the head after the JavaScript
	$settings{'copyright_link'} = '<link rel="copyright" href="http://ostermiller.org/contactform/" type="text/html">';

	# Redirect to this url after the message has been sent
	# By default there is no redirect.  The url must
	# be fully qualified (must start with http://)
	# Example: my $redirect_url_sent = "http://example.com/";
	$settings{'redirect_url_sent'} = "";

	# Show the sent confirmation for this many seconds before redirecting
	# after the message has been sent if the redirect_url_sent has been defined.
	# If zero is specified, the message sent confirmation will not
	# be shown at all (you can redirect to your own thank you)
	$settings{'redirect_delay_sent'} = 15;

	return %settings;
}

#=====================================================================
# You need to know Perl to and have a strong stomach to
# modify much of anything below this line


&initConstants();
my %settings = &settings();
&loadConfiguration();
&loadTemplate();
&parseInput();
&createMaps();
&sanityCheck();
&composeEmail();
&previewMessage();
&sendEmail();
&sentPage();

sub initConstants {

	# initialize the path to something safe so we can later call sendmail
	$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';

	if (&safeHeader($ENV{'PATH_INFO'}) eq '/contactformicon.png'){
		&contactformicon();
	}

	# denotes that no description is desired.
	$NO_DESCRIPTION = "-";

	# Version number of this software.
	$version = "3.00.00";

	# Reqular expression building blocks
	$LETTER = "[a-zA-Z]";
	$DIGIT = "[0-9]";
	$DOSEOL = "(?:[\r][\n])";
	$EOL = "(?:[\r\n]|$DOSEOL)";
	$LETTER_DIGIT = "[0-9a-zA-Z]";
	$LETTER_DIGIT_HYPHEN = "(?:[0-9a-zA-Z-])";
	$HEX_DIGIT = "(?:[0-9a-fA-F])";
	$QUOTEDSTRING = "(?:[\\\"](?:[^\\\"]|(?:[\\][\\\"]))*[\\\"])";
	$ATOM = "(?:[\\!\\#-\\\\\\'\\*\\+\\-\\/-9\\=\\?A-Z\\^-\\~]+)";
	$SUBDOMAIN = "(?:" . $LETTER_DIGIT . "(?:" . $LETTER_DIGIT_HYPHEN . "*" . $LETTER_DIGIT . ")?)";
	$WORD = "(?:" . $ATOM . "|" . $QUOTEDSTRING . ")";
	$DOMAIN = "(?:" . $SUBDOMAIN . "(?:[\\.]" . $SUBDOMAIN . ")+)";
	$LOCALPART = "(?:" . $WORD . "(?:[\\.]" . $WORD . ")*)";
	$EMAIL = "(?:" . $LOCALPART . "[\\@]" . $DOMAIN . ")";
	$PHONE_DIGIT = "[\\.\\-\\(\\)\\+\\ Xx]*";
	$PHONE = "(?:(?:" . $PHONE_DIGIT . $DIGIT . "){10,20})";
	$PHONE_NO_AREA_CODE = "(?:(?:" . $PHONE_DIGIT . $DIGIT . "){7,20})";
	$ZIPCODE = "(?:" . $DIGIT . "{5}(?:[\\-]" . $DIGIT . "{4})?)";
	$PRICE = "(?:" . $DIGIT . "+(?:[\\.]" . $DIGIT . "{2})?)|(?:[\\.]" . $DIGIT . "{2})";
	$FLOAT = "(?:" . $DIGIT . "+(?:[\\.]" . $DIGIT . "*)?)|(?:[\\.]" . $DIGIT . "+)";
	$INTEGER = "(?:" . $DIGIT . "+)";

	# Some recommended regular expressions
	$SOMETHING = ".+";
	$ANYTHING = ".*";
	$ONE_LINE_REQUIRED = "^(?:(?:[^\\n\\r])+)\$";
	$ONE_LINE_OPTIONAL = "^(?:(?:[^\\n\\r])*)\$";
	$ZIPCODE_REQUIRED = "^" . $ZIPCODE . "\$";
	$ZIPCODE_OPTIONAL = "^(?:" . $ZIPCODE . "?)\$";
	$PHONE_REQUIRED = "^" . $PHONE . "\$";
	$PHONE_OPTIONAL = "^(?:" . $PHONE . "?)\$";
	$PHONE_NO_AREA_CODE_REQUIRED = "^" . $PHONE_NO_AREA_CODE . "\$";
	$PHONE_NO_AREA_CODE_OPTIONAL = "^(?:" . $PHONE_NO_AREA_CODE . "?)\$";
	$EMAIL_REQUIRED = "^" . $EMAIL . "\$";
	$EMAIL_OPTIONAL = "^(?:" . $EMAIL . "?)\$";
	$PRICE_REQUIRED = "^" . $PRICE . "\$";
	$PRICE_OPTIONAL = "^(?:" . $PRICE . "?)\$";
	$FLOAT_REQUIRED = "^" . $FLOAT . "\$";
	$FLOAT_OPTIONAL = "^(?:" . $FLOAT . "?)\$";
	$INTEGER_REQUIRED = "^" . $INTEGER . "\$";
	$INTEGER_OPTIONAL = "^(?:" . $INTEGER . "?)\$";
	$BLANK = "^\$";
}

sub loadConfiguration(){
	return if (! defined $settings{'configuration_file'} or $settings{'configuration_file'} eq "");

	my $xmlmodule = "XML::Simple";
	eval "use $xmlmodule";
	if ($@) {
		&errorPage(
			"$xmlmodule Perl Module Not Installed",
			"Install the $xmlmodule module or do not use the configuration file feature"
		);
	}
	my $xmlsimple = $xmlmodule->new(forcearray => 1, keyattr => ['Aliases','FormFields']);
	my $xmlconf;
	eval {
		$xmlconf = $xmlsimple->XMLin($settings{'configuration_file'});
	};
	if ($@) {
		&errorPage(
			"Could Not Read Configuration File",
			"Check configuration file existence, permissions, and validity of XML, or do not use a configuration file."
		);
	}

	if ($xmlconf->{Aliases}){
		@Aliases = ();
		if ($xmlconf->{Aliases}->[0] and $xmlconf->{Aliases}->[0]->{Alias}){
			foreach my $alias(@{$xmlconf->{Aliases}->[0]->{Alias}}){
				my $name =  $alias->{name};
				my $email = $alias->{content};
				$email = &safeHeader($ENV{'SERVER_ADMIN'}) if ($email eq "SERVER_ADMIN");
				push(@Aliases, $name);
				push(@Aliases, $email);
			}
		}
	}

	if ($xmlconf->{Setting}){
		foreach my $setting(@{$xmlconf->{Setting}}){
			my $name = $setting->{name};
			if ($name){
				my $value = $setting->{content};
				$value='' if (!$value);
				$value =~ s/CONTACTFORM_VERSION/$version/g;
				$value =~ s/REQUIRED_MARKER/$settings{'required_marker'}/g;
				if (defined $ENV{'SCRIPT_NAME'}){
					$value =~ s/SCRIPT_NAME_ESCAPED/&escapeHTML($ENV{'SCRIPT_NAME'})/g;
				}
				$value = &trimEachLine($value);
				$settings{$name} = $value;
			}
		}
	}

	if ($xmlconf->{DisallowedText}){
		%disallowed_text = ();
		if ($xmlconf->{DisallowedText}->[0] and $xmlconf->{DisallowedText}->[0]->{Disallow}){
			foreach my $disallow(@{$xmlconf->{DisallowedText}->[0]->{Disallow}}){
				my $regex =  &trimEachLine($disallow->{content});
				my $message = $disallow->{message};
				$disallowed_text{$regex} = $message;
			}
		}
	}

	if ($xmlconf->{FormFields}){
		@FormFields = ();
		if ($xmlconf->{FormFields}->[0] and $xmlconf->{FormFields}->[0]->{Field}){
			foreach my $field(@{$xmlconf->{FormFields}->[0]->{Field}}){
				my $name = $field->{name};
				my $required = &trimEachLine($field->{content});
				$required =~ s/\$SOMETHING/$SOMETHING/g if ($required);
				$required =~ s/\$ANYTHING/$ANYTHING/g if ($required);
				$required =~ s/\$ONE_LINE_REQUIRED/$ONE_LINE_REQUIRED/g if ($required);
				$required =~ s/\$ONE_LINE_OPTIONAL/$ONE_LINE_OPTIONAL/g if ($required);
				$required =~ s/\$ZIPCODE_REQUIRED/$ZIPCODE_REQUIRED/g if ($required);
				$required =~ s/\$ZIPCODE_OPTIONAL/$ZIPCODE_OPTIONAL/g if ($required);
				$required =~ s/\$PHONE_REQUIRED/$PHONE_REQUIRED/g if ($required);
				$required =~ s/\$PHONE_OPTIONAL/$PHONE_OPTIONAL/g if ($required);
				$required =~ s/\$PHONE_NO_AREA_CODE_REQUIRED/$PHONE_NO_AREA_CODE_REQUIRED/g if ($required);
				$required =~ s/\$PHONE_NO_AREA_CODE_OPTIONAL/$PHONE_NO_AREA_CODE_OPTIONAL/g if ($required);
				$required =~ s/\$EMAIL_REQUIRED/$EMAIL_REQUIRED/g if ($required);
				$required =~ s/\$EMAIL_OPTIONAL/$EMAIL_OPTIONAL/g if ($required);
				$required =~ s/\$PRICE_REQUIRED/$PRICE_REQUIRED/g if ($required);
				$required =~ s/\$PRICE_OPTIONAL/$PRICE_OPTIONAL/g if ($required);
				$required =~ s/\$FLOAT_REQUIRED/$FLOAT_REQUIRED/g if ($required);
				$required =~ s/\$FLOAT_OPTIONAL/$FLOAT_OPTIONAL/g if ($required);
				$required =~ s/\$INTEGER_REQUIRED/$INTEGER_REQUIRED/g if ($required);
				$required =~ s/\$INTEGER_OPTIONAL/$INTEGER_OPTIONAL/g if ($required);
				$required =~ s/\$BLANK/$BLANK/g if ($required);
				my $error = $field->{error};
				my $type = $field->{type};
				my $description = $field->{description};
				$description =~ s/\$NO_DESCRIPTION/$NO_DESCRIPTION/g if($description);
				my $enabled = $field->{enabled};
				my $default = $field->{default};
				my $selected = $field->{selected};
				my $special = $field->{special};
				push (@FormFields, $name);
				push (@FormFields, {
					'required' =>  $required,
					'error' =>  $error,
					'type' =>  $type,
					'description' =>  $description,
					'enabled' =>  $enabled,
					'default' =>  $default,
					'selected' =>  $selected,
					'special' =>  $special,
				});
			}
		}
	}
}

sub trimEachLine(){
	my ($s) = @_;
	return '' if (!$s);
	$s =~ s/^[ \t\n\r]+//g;
	$s =~ s/[ \t\n\r]+$//g;
	$s =~ s/[\n \t\r]*\n[\n \t\r]*/\n/g;
	return $s;
}

sub loadTemplate(){
	$template_error = "";
	if (defined $settings{'page_template_file'} and $settings{'page_template_file'} ne ""){
		if (!open(TEMPLATE, $settings{'page_template_file'})){
			$template_error = '<div class="contactform cf_error cf_message">The template file could not be opened.</div>\n';
			return;
		}
		$settings{'page_template'} = join("", <TEMPLATE>);
		close(TEMPLATE);
	}
}

sub createMaps {
	# Since hash maps are not ordered, Aliases and Form_Fields
	# Are declared as arrays.  We need to create two data structures
	# from each.  The first is an undered map, the second is an
	# ordered key set.
	%AliasesMap = @Aliases;
	my $useAlias = 1;
	foreach my $alias (@Aliases){
		if ($useAlias){
			push(@AliasesOrdered, $alias);
			$useAlias = 0;
		} else {
			$useAlias = 1;
		}
	}

	$field_name_to = '';
	$field_name_from_email = '';
	$field_name_from_name = '';
	$field_name_subject = '';
	$field_name_regarding = '';
	$field_name_referrer = '';

	%FieldMap = @FormFields;
	foreach my $key (@FormFields){
		if ($FieldMap{$key} and (! defined ${$FieldMap{$key}}{"enabled"} or ${$FieldMap{$key}}{"enabled"} != 0)){
			push(@Field_Order, $key);
			if (defined ${$FieldMap{$key}}{"special"}){
				my $special = ${$FieldMap{$key}}{"special"};
				if ($special eq "to"){
					$field_name_to = $key;
				} elsif ($special eq "from"){
					$field_name_from_email = $key;
				} elsif ($special eq "name"){
					$field_name_from_name = $key;
				} elsif ($special eq "subject"){
					$field_name_subject = $key;
				} elsif ($special eq "regarding"){
					$field_name_regarding = $key;
				} elsif ($special eq "referrer"){
					$field_name_referrer = $key;
				}
			}
			if (defined ${$FieldMap{$key}}{"default"}){
				${$FieldMap{$key}}{"selected"} = ${$FieldMap{$key}}{"default"};
			}
		}
	}

	# Put the referrer header into the map if it is not there already
	if ($field_name_referrer ne "" and $FieldMap{$field_name_referrer} and ! exists $SubmittedData{$field_name_referrer}){
		if (defined $ENV{'HTTP_REFERER'}){
			$SubmittedData{$field_name_referrer} = $ENV{'HTTP_REFERER'};
		} else {
			$SubmittedData{$field_name_referrer} = "-";
		}
	}
}

sub errorPage {
	my ($title, $body) =  @_;
	&outputPage(
		$title,
		"",
		"",
		"<span style=\"color:red\">$body</span>\n"
	);

}

sub parseInput {
	my ($pair, @pairs, $buffer);

	if ($settings{'recaptcha_public_key'} and $settings{'recaptcha_private_key'}){
		my $captchamodule = "Captcha::reCAPTCHA";
		eval "use $captchamodule";
		if ($@) {
			&errorPage(
				"$captchamodule Perl Module Not Installed",
				"Install the $captchamodule module or do not use the captcha feature"
			);
		}
		$captcha = $captchamodule->new();
	}

	if (&safeHeader($ENV{'REQUEST_METHOD'}) eq 'GET'){
		@pairs = split(/&/, $ENV{'QUERY_STRING'});
	} elsif (&safeHeader($ENV{'REQUEST_METHOD'}) eq 'POST'){
		read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
		@pairs = split(/&/, $buffer);
	} elsif ($ENV{'SERVER_NAME'}){
		&inputPage("This form must be submitted via either 'GET' or 'POST'.");
	}

	foreach $pair (@pairs){
		if ($pair =~ /([^\=]+)(?:\=(.*))?/){

			my $name = $1;
			$name =~ tr/+/ /;
			$name =~ s/%($HEX_DIGIT{2})/pack("C", hex($1))/eg;
			$name =~ tr/\0//d;

			my $value = "";
			if ($2){
				$value = $2;
				$value =~ tr/+/ /;
				$value =~ s/%($HEX_DIGIT{2})/pack("C", hex($1))/eg;
				$value =~ tr/\0//d;
			}

			$SubmittedData{$name} = $value;
		}
	}
}

sub getRequired {
	my ($key) = @_;
	if (defined ${$FieldMap{$key}}{"required"}){
		return ${$FieldMap{$key}}{"required"};
	} elsif (&getType($key) eq "select" || &getType($key) eq "radio"){
		return "";
	} else {
		return $ANYTHING;
	}
}

sub getError {
	my ($key) = @_;
	if (defined ${$FieldMap{$key}}{"error"}){
		return ${$FieldMap{$key}}{"error"};
	} else {
		return "The field '$key' does not appear to be valid.";
	}
}

sub getType {
	my ($key) = @_;
	if ($key eq $field_name_to){
		if ($#AliasesOrdered > 0){
			 return "select";
		} else {
			return "hidden";
		}
	}
	if (defined ${$FieldMap{$key}}{"type"}){
		return ${$FieldMap{$key}}{"type"};
	} else {
		return "text";
	}
}

sub getSelected {
	my ($key) = @_;
	if (defined ${$FieldMap{$key}}{"selected"}){
		return ${$FieldMap{$key}}{"selected"};
	} else {
		return undef;
	}
}

sub getDescription {
	my ($key) = @_;
	if (defined ${$FieldMap{$key}}{"description"}){
		return ${$FieldMap{$key}}{"description"};
	} else {
		"$key:";
	}
}

sub isDefined(){
	my ($key) = @_;
	return defined($SubmittedData{$key});
}

sub getSelection {
	my ($key) = @_;
	if (defined($SubmittedData{$key})){
		return $SubmittedData{$key};
	}
	if (&getSelected($key)){
		return &getSelected($key);
	}
	return "";
}

sub sanityCheck {

	# Check the referrer
	my $allowedReferers = $settings{'allowedReferers'};
	if (&safeHeader($ENV{'HTTP_REFERER'}) && &safeHeader($ENV{'HTTP_REFERER'}) !~ /$allowedReferers/g){
		&inputPage("This form cannot be submitted from".&escapeHTML($ENV{'HTTP_REFERER'}).".");
	}

	my $some_required_field_present = 0;
	my $errorCount = 0;
	my %errorHash = ();

	my @field_keys = &getOrderedFields();
	foreach my $key (@field_keys){
		my $required_value = &getRequired($key);
		my $data = &getSelection($key);
		my $form_type = &getType($key);
		$errorHash{$key} = "";
		if ($data !~ /$required_value/g){
			if(&isDefined($key)){
				$errorCount++;
				$errorHash{$key} = &getError($key);
			}
		} elsif (&isDefined($key) && $form_type ne 'hidden'){
			$some_required_field_present = 1;
		}

		foreach my $disallow_check (keys(%disallowed_text)){
			if ($data =~ /$disallow_check/){
				$errorCount++;
				$errorHash{$key} .= $disallowed_text{$disallow_check};
			}
		}
	}
	if (!($some_required_field_present) or defined($SubmittedData{"prefill"})){
		&inputPage('', $settings{'input_page_text'});
	}

	foreach my $key (@field_keys){
		if (&getType($key) eq "trap" and !&isDefined($key)){
			$errorCount++;
			$errorHash{$key} .=  &getError($key);
		}
	}
	if ($errorCount > 0){
		my $errorMessage = "";
		if ($errorCount == 1){
			$errorMessage = "<p>Please correct the error to continue.</p>";
		} else {
			$errorMessage = "<p>Please correct all errors to continue.</p>";
		}
		&inputPage($errorMessage, "", \%errorHash);
	}

	if ($captcha and !&messagePreviewSubmitted()){
		my $captchaResult = $captcha->check_answer(
			$settings{'recaptcha_private_key'},
			$ENV{'REMOTE_ADDR'},
			$SubmittedData{"recaptcha_challenge_field"},
			$SubmittedData{"recaptcha_response_field"}
		);
		if (!$captchaResult->{is_valid}){
			$errorHash{"captcha"} = $captchaResult->{error}. " -- Please try again";
			&inputPage("<p>Please correct the error to continue.</p>", "", \%errorHash, 1);
		}
	}

	if ((!$SubmittedData{$field_name_to}) || $SubmittedData{$field_name_to} eq ""){
		&inputPage('', $settings{'input_page_text'});
	} else {
		my $recipent = $SubmittedData{$field_name_to};
		if ((!$AliasesMap{$recipent})){
			&inputPage("Your message cannot be sent to the specified recipient.");
		}
	}
}

sub composeEmail {
	my ($subject, $from, @field_keys, $key);

	if ($field_name_from_email ne '' and $FieldMap{$field_name_from_email}){
		$from = &safeHeader(&getSelection($field_name_from_email));
	} else {
		$from = '';
	}
	if ($from !~ /$EMAIL_REQUIRED/g){
		$from = 'nobody';
	}
	if ($field_name_from_name ne "" and $FieldMap{$field_name_from_name} and &getSelection($field_name_from_name) ne ''){
		$from = &safeHeaderName(&getSelection($field_name_from_name))." <$from>";
	}

	if ($field_name_subject ne "" and $FieldMap{$field_name_subject} and &getSelection($field_name_subject)){
		$subject = &safeHeader(&getSelection($field_name_subject));
	} else {
		$subject = "Pieteikuma anketa";
	}

	if ($field_name_regarding ne "" and $FieldMap{$field_name_regarding} and &getSelection($field_name_regarding) ne ''){
		$subject .= " (".&safeHeader(&getSelection($field_name_regarding)).")";
	}


	$mail_message	= "From: $from\n";
	$mail_message .= "Subject: $subject\n";
	$mail_message .= "\n";

	@field_keys = &getOrderedFields();
	foreach $key (@field_keys){
		if ($key ne $field_name_to && $key ne $field_name_subject &&
			$key ne $field_name_from_name && $key ne $field_name_from_email &&
			$key ne $field_name_regarding && $key ne $field_name_referrer &&
			&getType($key) ne "trap"){
			my $mail_description = &getDescription($key);
			if ($mail_description eq $NO_DESCRIPTION){
				$mail_description = "";
			} else {
				$mail_description .= "\n";
			}
			$mail_message .= $mail_description;
			$mail_message .= &getSelection($key)."\n";
			$mail_message .= "\n";
		}
	}
}

sub sendEmail {
	my @to_address_list = split(/,/,$AliasesMap{&getSelection($field_name_to)});
	foreach my $to_address (@to_address_list){
		open(MAIL,"|".$settings{'sendmail'});
		print MAIL "To: ".&safeHeader($to_address)."\n";
		print MAIL "Content-Type: text/plain; charset=".&safeHeader($settings{'charset'})."\n";
		print MAIL "X-Mailer: ContactForm/".&safeHeader($version)." (http://ostermiller.org/contactform/)\n";
		print MAIL "X-Server-Name: ".&safeHeader($ENV{'SERVER_NAME'})."\n";
		print MAIL "X-Server-Admin: ".&safeHeader($ENV{'SERVER_ADMIN'})."\n";
		print MAIL "X-Script-Name: ".&safeHeader($ENV{'SCRIPT_NAME'})."\n";
		print MAIL "X-Path-Info: ".&safeHeader($ENV{'PATH_INFO'})."\n";
		print MAIL "X-Remote-Host: ".&safeHeader($ENV{'REMOTE_HOST'})."\n";
		print MAIL "X-Remote-Addr: ".&safeHeader($ENV{'REMOTE_ADDR'})."\n";
		print MAIL "X-Remote-User: ".&safeHeader($ENV{'REMOTE_USER'})."\n";
		print MAIL "X-HTTP-User-Agent: ".&safeHeader($ENV{'HTTP_USER_AGENT'})."\n";
		print MAIL "X-HTTP-Referer: ".&safeHeader($ENV{'HTTP_REFERER'})."\n";
		if ($field_name_referrer ne ""){
			print MAIL "X-First-HTTP-Referer: ".&safeHeader(&getSelection($field_name_referrer))."\n";
		}
		print MAIL $mail_message;
		close (MAIL);
	}
}

sub previewRequired(){
	return 1 if ($settings{'require_preview'} == 1);
	return 0;
}

sub previewMessage(){
	return if (!&previewRequired());
	return if (&messageSendSubmitted());

	my ($message);
	$message = &textToHTML("To: ".&getSelection($field_name_to)."\n".$mail_message);

	&inputPage(
		'',
		$settings{'preview_page_text'}."<div class=\"contactform cf_preview\">$message</div>"
	);
}

sub sentPage {
	my ($message);
	$message = &textToHTML("To: ".&getSelection($field_name_to)."\n".$mail_message);

	my $javascript = ""; # No javascript

	if ($settings{'redirect_url_sent'} ne ""){
		if ($settings{'redirect_delay_sent'} == 0){
			&redirect($settings{'redirect_url_sent'});
		} else {
			$javascript = "<meta http-equiv=\"refresh\" content=\"".$settings{'redirect_delay_sent'}.";url=".$settings{'redirect_url_sent'}."\">\n"
		}
	}

	&outputPage(
		$settings{'sent_page_title'},
		$settings{'sent_page_css'},
		$javascript,
		$settings{'sent_page_text'}."<div class=\"contactform cf_sent\">$message</div>"
	);
}

sub redirect {
	my ($url) = @_;
	print "Location: $url\n\n";
	exit 0;
}

sub inputPage {
	my ($error, $preview, $fieldErrors, $allowSendAnyway) = @_;
	my $haserror = 1;
	if (!defined($error) or $error eq ""){
		$error = "";
		$haserror = 0;
	}
	my %FieldErrorsHash = ();
	if (defined($fieldErrors)){
		%FieldErrorsHash = %$fieldErrors;
	}
	if (!defined($preview)){
		$preview = "";
	}
	my (@orderedKeys, $key, $form_html, $script_call, $alias_selected, $client_side_check_script);

	my $errorStyle=" style=\"display:none;\"";
	if ($error ne ""){
		$errorStyle="";
	}
	$error = "<div id=cf_global_error$errorStyle class=\"contactform cf_error cf_message\">\n" . $error . "</div>\n";
	$script_call = '';
	if ($settings{'use_client_side_verification'}){
		$script_call="onSubmit='return cfCheckForm(this);'";
	}

	my $submit_method = "POST";
	if (defined $settings{'submit_method'} and $settings{'submit_method'} eq "GET"){
		$submit_method = "GET";
	}

	$form_html="<form class=contactform id=cf_form action=\"".&escapeHTML($ENV{'SCRIPT_NAME'})."\" method=".$settings{'submit_method'}." $script_call>\n";
	@orderedKeys = &getOrderedFields();
	foreach $key (@orderedKeys){
		my $html_description = &getDescription($key);
		if ($html_description eq $NO_DESCRIPTION){
			$html_description = '';
		} else {
			$html_description = "<label class=\"contactform cf_fieldlabel\" for='$key'>$html_description</label>";
		}
		my $fieldErrorMessage = "";
		my $errorStyle=" style=\"display:none;\"";
		if (defined $FieldErrorsHash{$key} and $FieldErrorsHash{$key} ne ""){
			$fieldErrorMessage = $FieldErrorsHash{$key};
			$errorStyle = "";
		}
		$fieldErrorMessage= "<span id=cf_error_$key$errorStyle class=\"contactform cf_error cf_fielderror\">".&escapeHTML($fieldErrorMessage)."</span>";
		if ($key eq $field_name_to){
			if ($#AliasesOrdered == 0){
				my $alias = $AliasesOrdered[0];
				$form_html.= "$fieldErrorMessage <input type=hidden name='$field_name_to' value='$alias'>\n";
			} else {
				$form_html.= "<div class=\"contactform cf_field\">".$settings{'required_marker'}." $html_description $fieldErrorMessage\n<div class=\"contactform cf_userentry\"><select id='$key' name='$field_name_to'>\n";
				$form_html.= "<option value=''></option>\n";
				foreach my $alias (@AliasesOrdered){
					if (defined $SubmittedData{$field_name_to} and $alias eq $SubmittedData{$field_name_to}){
						$alias_selected = 'selected'
					} else {
						$alias_selected = '';
					}
						$form_html.= "<option value='$alias' $alias_selected>$alias</option>\n";
				}
				$form_html.= "</select></div></div>\n";
			}
		} else {
			my $mark = '';
			my $required_value = &getRequired($key);
			my $data = &getSelection($key);
			my $fieldText = "";
			if (($data !~ /$required_value/g) && $html_description ne ''){
				if (length($fieldText) > 0){
					$fieldText .= " ";
				}
				$fieldText .= $settings{'required_marker'};
			}
			if (length($html_description) > 0){
				if (length($fieldText) > 0){
					$fieldText .= " ";
				}
				$fieldText .= $html_description;
			}
			if (length($fieldErrorMessage) > 0){
				if (length($fieldText) > 0){
					$fieldText .= " ";
				}
				$fieldText .= $fieldErrorMessage;
			}
			my $form_type=&getType($key);
			if ($form_type eq 'select'){
				$form_html.="<div class=\"contactform cf_field\">$fieldText<div class=\"contactform cf_userentry\"><select id='$key' class=\"contactform cf_select\" name='$key'>";
				my $required = &getRequired($key);
				if ("" !~ /$required/ and !&getSelected($key)){
					$form_html.="<option value=\"\"></option>";
				}
				my $selectvalue = $required;
				$selectvalue =~ s/^[\^\(\?\:]+//g;
				$selectvalue =~ s/[\)\$]+$//g;
				my @selectvalues = split(/\|/, $selectvalue);
				foreach my $selectval (@selectvalues){
					$selectval =~ s/^[\(\?\:]+//g;
					$selectval =~ s/[\)]+$//g;
					$selectval = &escapeHTML($selectval);
					my $selected="";
					if ($selectval eq $data){
						$selected = " selected";
					}
					$form_html.="<option value=\"$selectval\"$selected>$selectval</option>";
				}
				$form_html.="</select></div></div>\n";
			} elsif ($form_type eq 'radio'){
				$form_html.="<div class=\"contactform cf_field\">$fieldText<div class=\"contactform cf_userentry\"><span id='$key' class=\"contactform cf_radio\">";
  				my $selectvalue = &getRequired($key);
				$selectvalue =~ s/^[\^\(\?\:]+//g;
				$selectvalue =~ s/[\)\$]+$//g;
				my @selectvalues = split(/\|/, $selectvalue);
				my $radionum=0;
				foreach my $selectval (@selectvalues){
					$selectval =~ s/^[\(\?\:]+//g;
					$selectval =~ s/[\)]+$//g;
					$selectval = &escapeHTML($selectval);
					if ($selectval ne ""){
						my $selected="";
						if ($selectval eq $data){
							$selected = " checked";
						}
						$form_html.="<div class=\"contactform cf_radioselection\"><input type=\"radio\" name=\"$key\" id=\"$key$radionum\" value=\"$selectval\"$selected><label for=\"$key$radionum\">$selectval</label></div>";
						$radionum++;
					}
				}
				$form_html.="</span></div></div>\n";
			} elsif ($form_type eq 'textarea'){
				$form_html.="<div class=\"contactform cf_field\">$fieldText<div class=\"contactform cf_userentry\"><textarea id='$key' class=\"contactform cf_textentry\" wrap=virtual name='$key'>".&escapeHTML($data)."</textarea></div></div>\n";
			} elsif ($form_type eq 'hidden'){
				$form_html.="$fieldErrorMessage <input type=hidden name='$key' value='".&escapeHTML($data)."'>\n";
			} elsif ($form_type eq 'trap'){
				$form_html.="<div class=\"contactform cf_field cf_nt\">$fieldText<div class=\"contactform cf_userentry\"><input id='$key' class=\"contactform cf_textentry\" type=text name='$key' value='".&escapeHTML($data)."'></div></div>\n";
			} else {
				$form_html.="<div class=\"contactform cf_field\">$fieldText<div class=\"contactform cf_userentry\"><input id='$key' class=\"contactform cf_textentry\" type=text name='$key' value='".&escapeHTML($data)."'></div></div>\n";
			}
		}
	}
	my $hasSendButton = &hasSendButton($haserror);
	$hasSendButton = 1 if ($allowSendAnyway);
	if ($hasSendButton and $captcha){
		$form_html.="<div class=\"contactform cf_field\"><label class=\"contactform cf_fieldlabel\" for='recaptcha_response_field'>";
		$form_html.=$settings{'required_marker'}." Prove that you are a human:";
		if (defined $FieldErrorsHash{"captcha"} and $FieldErrorsHash{"captcha"} ne ""){
			$form_html.=" <span id=cf_error_captcha class=\"contactform cf_error cf_fielderror\">".$FieldErrorsHash{"captcha"}."</span> ";
		}
		$form_html.="</label>\n";
		$form_html.=$captcha->get_html($settings{'recaptcha_public_key'});
		$form_html.="</div>\n";
	}
	if ($settings{'require_preview'} eq "1" or $settings{'require_preview'} eq "2"){
		$form_html.="<input class=\"contactform\" id=cf_submit type=submit name=".$settings{'field_name_submit'}." value=Pārbaudīt>\n";
	}
	if ($hasSendButton){
		$form_html.="<input class=\"contactform\" id=cf_submit type=submit name=".$settings{'field_name_submit'}." value=Nosūtīt>\n";
	}
	$form_html.=$settings{'required_marker_note'}."\n";
	$form_html.="</form>";

	$client_side_check_script = "";
	if ($settings{'use_client_side_verification'}){
		$client_side_check_script .= "<script language=javascript type='text/javascript'><!--\n";
		$client_side_check_script .= "function cfRadioSelected(r){\n";
		$client_side_check_script .= "for (i=0;i<r.length;i++) {\n";
		$client_side_check_script .= "if (r[i].checked)return true;\n";
		$client_side_check_script .= "}\n";
		$client_side_check_script .= "return false;\n";
		$client_side_check_script .= "}\n";
		$client_side_check_script .= "function cfErrorOn(k,d,m,s,f,b){\n";
		$client_side_check_script .= "var df=document.getElementById(d);\n";
		$client_side_check_script .= "df.innerHTML=m;\n";
		$client_side_check_script .= "df.style.display=b;\n";
		$client_side_check_script .= "if(s)k.select();\n";
		$client_side_check_script .= "if(f)k.focus();\n";
		$client_side_check_script .= "}\n";
		$client_side_check_script .= "function cfErrorOff(d){\n";
		$client_side_check_script .= "var f=document.getElementById(d);\n";
		$client_side_check_script .= "f.innerHTML='';\n";
		$client_side_check_script .= "f.style.display='none';\n";
		$client_side_check_script .= "}\n";
		$client_side_check_script .= "function cfCheckForm(form){\n";
		$client_side_check_script .= "var major = parseInt(navigator.appVersion);\n";
		$client_side_check_script .= "var agent = navigator.userAgent.toLowerCase();\n";
		$client_side_check_script .= "if (agent.indexOf('msie')!=-1){\n";
		$client_side_check_script .= "major = parseFloat(agent.split('msie')[1]);\n";
		$client_side_check_script .= "}\n";
		$client_side_check_script .= "if (agent.indexOf('mozilla')==0 && major<=4){\n";
		$client_side_check_script .= "// Internet Explorer 4 or Netscape 4 and earlier.\n";
		$client_side_check_script .= "return true;\n";
		$client_side_check_script .= "} else if (agent.indexOf('opera')!=-1){\n";
		$client_side_check_script .= "// Opera doesn't seem to do regular expressions properly.\n";
		$client_side_check_script .= "return true;\n";
		$client_side_check_script .= "}\n";
		$client_side_check_script .= "var ec=0;\n";
		foreach $key (reverse(@orderedKeys)){
			my $formType = &getType($key);
			my $check = "";
			if($formType eq 'hidden'){
				$check = "";
			} elsif ($formType eq "select"){
				my $required = &getRequired($key);
				if ("" !~ /$required/ and !&getSelected($key)){
					$check = "form.$key.selectedIndex == 0";
				} else {
					$check = "";
				}
			} elsif ($formType eq "radio"){
				my $required = &getRequired($key);
				if ("" !~ /$required/ and !&getSelected($key)){
					$check = "!cfRadioSelected(form.$key)"
				} else {
					$check = "";
				}
			} else {
				$check = "!form.$key.value.match(new RegExp('".&escapeJavaScript(&getRequired($key))."', 'g'))";
			}
			if ($check ne ""){
				my $dofocus = "false";
				if ($formType ne "radio"){
					$dofocus = "true";
				}
				my $doselect = "false";
				if ($formType eq "text" or $formType eq "textarea"){
					$doselect = "true";
				}
				$client_side_check_script .= "if ($check){\n";
				$client_side_check_script .= "cfErrorOn(form.$key,'cf_error_$key','".&escapeJavaScript(&getError($key))."',$doselect,$dofocus,'inline');\n";
				$client_side_check_script .= "ec++;\n";
				$client_side_check_script .= "} else {\n";
				$client_side_check_script .= "cfErrorOff('cf_error_$key');\n";
				$client_side_check_script .= "}\n";
			} else {
				$client_side_check_script .= "cfErrorOff('cf_error_$key');\n";
			}
		}
		$client_side_check_script .= "\n";
		$client_side_check_script .= "if(ec>0){\n";
		$client_side_check_script .= "cfErrorOn('','cf_global_error','Lai turpinātu, lūdzu izlabojiet '+(ec==1?'kļūdu':'visas kļūdas')+'.',false,false,'block');\n";
		$client_side_check_script .= "scroll(0,0);";
		$client_side_check_script .= "return false;\n";
		$client_side_check_script .= "} else {\n";
		$client_side_check_script .= "cfErrorOff('cf_global_error');\n";
		$client_side_check_script .= "return true;\n";
		$client_side_check_script .= "}\n";
		$client_side_check_script .= "}\n";
		$client_side_check_script .= "//--></script>\n";
	}

	&outputPage(
		$settings{'input_page_title'},
		$settings{'input_page_css'},
		$client_side_check_script,
		$preview.$error.$form_html
	);
}

sub hasSendButton(){
	my ($haserror) = @_;
	return 1 if ($settings{'require_preview'} eq "0");
	return 1 if ($settings{'require_preview'} eq "2" );
	return 1 if (!$haserror and &messagePreviewSubmitted());
	return 0;
}

sub messagePreviewSubmitted(){
	return 0 if (!defined $SubmittedData{$settings{'field_name_submit'}});
	return 1 if ($SubmittedData{$settings{'field_name_submit'}} eq "Pārbaudīt");
	return 0;
}

sub messageSendSubmitted(){
	return 1 if (!defined $SubmittedData{$settings{'field_name_submit'}});
	return 1 if ($SubmittedData{$settings{'field_name_submit'}} eq "Nosūtīt");
	return 0;
}

sub outputPage(){
	my ($title, $css, $javascript, $content) = @_;

	my $page = $settings{'page_template'};
	$page =~ s/\$title/$title/g;
	$page =~ s/\$css/$css/g;
	my $icon_link = $settings{'icon_link'};
	my $copyright_link = $settings{'copyright_link'};
	$page =~ s/\$javascript/$javascript$icon_link\n$copyright_link/g;
	my $contact_form_link = $settings{'contact_form_link'};
	$template_error = "" if (!$template_error);
	$page =~ s/\$content/$template_error$content$contact_form_link/g;

	if ($ENV{'SERVER_NAME'}){
		print "Content-type: text/html; charset=",$settings{'charset'},"\n";
		print "\n";
	}

	print $page;

	exit;
}

# Remove characters that would be unsafe in an email header.
sub safeHeader {
	my ($headerText) = @_;
	if (!defined($headerText)){
		$headerText="";
	}
	$headerText =~ s/[\0\n\r]+/ /g;
	return $headerText;
}

sub safeHeaderName {
	my ($headerText) = @_;
	if (!defined($headerText)){
		$headerText="";
	}
	$headerText =~ s/[\0\n\r\(\)\@\%\<\>]+/ /g;
	return $headerText;
}

# Convert <, >, & and " to their HTML equivalents.
sub escapeHTML {
	my ($value) = @_;
	if (!defined($value)){
		$value="";
	}
	$value =~ s/\&/\&amp;/g;
	$value =~ s/</\&lt;/g;
	$value =~ s/>/\&gt;/g;
	$value =~ s/"/\&quot;/g;
	$value =~ s/'/\&#39;/g;
	return $value;
}

# escape HTML and make text into HTML paragraphs.
sub textToHTML {
	my ($value) = @_;
	if (!defined($value)){
		$value="";
	}
	$value = escapeHTML($value);
	$value =~ s/(\n[\r\n]+)|(\r\n[\r\n]+)|(\r\r[\r\n]*)/<p>/g;
	$value =~ s/[\r\n]+/<br>/g;
	$value =~ s/\<p\>/\n<p>\n/g;
	$value =~ s/\<br\>/<br>\n/g;
	return $value;
}

# put in javascript escape sequences.
sub escapeJavaScript {
	my ($value) = @_;
	if (!defined($value)){
		$value="";
	}
	$value =~ s/\\/\\\\/g;
	$value =~ s/\'/\\'/g;
	$value =~ s/\n/\\n'/g;
	$value =~ s/\r/\\r'/g;
	$value =~ s/\t/\\t'/g;
	return $value;
}

sub getOrderedFields {
	return @Field_Order;
}

sub contactformicon {
	print "Content-type: image/png\n";
	print "\n";
	print "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52";
	print "\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff";
	print "\x61\x00\x00\x01\xbc\x49\x44\x41\x54\x78\x9c\xa5\x92\x4d\x6e\x13";
	print "\x41\x10\x85\xbf\xea\xee\xb1\x31\x72\xe2\xbf\x90\xe4\x0a\x88\x25";
	print "\x87\x60\x83\x60\xc9\x6d\xb8\x0b\x6b\x96\x88\x15\x6b\x8e\x00\x6c";
	print "\xed\x28\x12\xc1\x7f\x33\x4e\x6c\xc7\xe3\xe9\xae\x62\xe1\x38\x8e";
	print "\x09\x28\x20\x6a\xd7\xaa\xf7\x5e\xd7\x7b\x55\xf0\x9f\x25\xef\xde";
	print "\x5f\xbc\xed\x1c\xda\x4b\xef\x39\xaf\xa2\x9c\x95\x6b\x06\x55\x64";
	print "\x20\x22\x83\x5a\x26\x67\xb5\x4c\xa6\xaf\x5f\x3c\x49\x7f\x14\xf8";
	print "\xf8\xe9\xfb\x57\xef\x79\x7a\xd2\x53\xbc\x03\x03\x52\x82\xaa\x12";
	print "\xd6\x11\x4b\x89\xcb\xa4\x72\x9e\x94\x41\x15\xe9\x97\x6b\x19\xac";
	print "\x4a\xfa\x49\xa5\x1f\xbc\x7c\x0b\xe2\x48\xa7\x3d\xe5\xc7\xd4\x71";
	print "\xda\x53\x44\x20\x78\x08\xde\x68\x80\x00\x2d\xb0\x16\xf0\x6c\xfb";
	print "\xab\x1a\xcc\x97\xc2\x70\x22\x9f\x1d\x46\x74\x0e\x8e\x3b\x1b\x11";
	print "\xb3\x87\x7d\xa7\x04\x31\x42\xaf\x6d\x3d\x67\x50\x01\x78\x0f\xbd";
	print "\x96\x32\xca\xe5\x41\x72\x71\x25\x74\x5b\x06\x20\xce\x8c\xb8\x6d";
	print "\x66\x01\xda\x07\xc6\xb8\xf8\xbd\x88\x19\x4c\x66\xc2\x51\xfb\x66";
	print "\x4c\xc1\x39\x90\x78\x17\x54\xcb\xa0\xd9\x30\x86\xd3\xfb\x22\xa3";
	print "\x7c\x43\x96\x5d\xcb\x39\x33\xab\x7e\x05\x2e\x4b\xc1\x7b\x98\xce";
	print "\x76\xc8\x49\x21\xa8\x71\x97\x0c\x86\x06\x33\xf6\x04\xae\x96\x42";
	print "\x70\x70\xd8\x34\xae\x4b\x61\x5c\x08\xde\x41\xe3\x11\x74\x6a\xb6";
	print "\x6f\x01\x2c\x98\xc9\x7a\xfb\x5a\xad\xa1\xaa\xd8\x06\x44\xa3\x6e";
	print "\x64\x1e\x92\x41\x3d\xdb\x60\x0e\x1e\x1b\xb3\xb9\xd0\x6a\xda\x26";
	print "\x03\x35\x16\x00\x55\x84\xd9\x2e\xdd\xdb\x0a\x61\x47\x06\xa8\xd7";
	print "\xc0\x39\x58\x95\xb7\x19\x10\x55\x61\x9c\x3b\x8e\xbb\x7f\x71\x04";
	print "\x37\x53\x5c\x97\x42\x4a\x48\x50\x65\x7d\x31\x71\x9c\x74\x75\x3f";
	print "\xa0\xad\x49\xdb\x5c\x9e\x2a\xa4\x24\x24\x85\xa4\x98\x08\xe5\x28";
	print "\x77\x5f\xc2\xe2\x5a\x3e\x64\xc1\x9e\x0f\x73\x37\x57\x25\x57\xa5";
	print "\x48\x4a\x1e\x93\xe4\x31\x51\xc4\x48\x9e\x94\xdc\x8c\x42\x44\x72";
	print "\xef\x28\x42\x90\x4b\xef\xdd\xe2\xcd\xab\xa3\x7b\x1b\xfc\xe7\xfa";
	print "\x09\xfd\xc8\xe6\x8e\x15\xeb\x74\x06\x00\x00\x00\x00\x49\x45\x4e";
	print "\x44\xae\x42\x60\x82\x00";
	exit;
}

