";
}
else
$s_text = $aMessages[$i_msg_num];
$s_mno = $bShowMesgNumbers ? "[M$i_msg_num]" : "";
//
// substitute parameters; only works with PHP version 4.0.5 or later
//
if (strpos($s_text,'$') !== false)
{
global $aGetMessageValues,$aGetMessageSubstituteErrors;
global $aGetMessageSubstituteFound,$bGetMessageSubstituteNoErrors;
$aGetMessageSubstituteErrors = array();
$aGetMessageSubstituteFound = array();
$aGetMessageValues = $a_params;
$bGetMessageSubstituteNoErrors = $b_no_errors;
$aGetMessageValues["MNUM"] = $s_mno; // add the message number
//
// search for words in this form:
// $word
// where word begins with an alphabetic character and
// consists of alphanumeric and underscore
//
$s_text = preg_replace_callback('/\$([a-z][a-z0-9_]*)/i',
'GetMessageSubstituteParam',$s_text);
if (count($aGetMessageSubstituteErrors) > 0)
SendAlert("Message Number $i_msg_num in language $sLangID ".
"specified the following unsupported parameters: ".
implode(',',$aGetMessageSubstituteErrors));
if (!in_array("MNUM",$aGetMessageSubstituteFound))
//
// append the message number
//
$s_text .= $b_show_mnum ? " $s_mno" : "";
}
else
//
// append the message number
//
$s_text .= $b_show_mnum ? " $s_mno" : "";
//
// replace '\n' sequences with new lines
//
return (str_replace('\n',"\n",$s_text));
}
//
// Check for old version of PHP - die if too old.
//
function IsOldVersion(&$a_this_version)
{
$a_modern = array(4,1,0); // versions prior to this are "old" - "4.1.0"
$s_req_string = "4.0.5"; // version 4.0.5 of PHP is required from
// FormMail 5.00 onward (because we use
// preg_replace_callback for all messages to
// support languages other than English)
$a_too_old = explode(".",$s_req_string);
$i_cannot_use = ($a_too_old[0] * 10000) +
($a_too_old[1] * 100) +
$a_too_old[2];
$s_vers_string = phpversion();
$a_this_version = explode(".",$s_vers_string);
$i_this_num = ($a_this_version[0] * 10000) +
($a_this_version[1] * 100) +
$a_this_version[2];
if ($i_this_num <= $i_cannot_use)
die(GetMessage(MSG_SCRIPT_VERSION,array("PHPREQ"=>$s_req_string,
"PHPVERS"=>$s_vers_string)));
$i_modern_num = ($a_modern[0] * 10000) +
($a_modern[1] * 100) +
$a_modern[2];
return ($i_this_num < $i_modern_num);
}
//
// Check if the server is Windows
//
function IsServerWindows()
{
static $bGotAnswer = false;
static $bAnswer;
if (!$bGotAnswer)
{
if ((isset($_ENV["OS"]) && stristr($_ENV["OS"],"windows") !== false) ||
(isset($_SERVER["PATH"]) && stristr($_SERVER["PATH"],"winnt") !== false) ||
(isset($_SERVER["PATH"]) && stristr($_SERVER["PATH"],"windows") !== false) ||
(isset($_SERVER["SystemRoot"]) && stristr($_SERVER["SystemRoot"],"winnt") !== false) ||
(isset($_ENV["SystemRoot"]) && stristr($_ENV["SystemRoot"],"winnt") !== false) ||
(isset($_SERVER["SystemRoot"]) && stristr($_SERVER["SystemRoot"],"windows") !== false) ||
(isset($_ENV["SystemRoot"]) && stristr($_ENV["SystemRoot"],"windows") !== false) ||
(isset($_SERVER["Path"]) && stristr($$_SERVER["Path"],"windows") !== false))
$bAnswer = true;
else
$bAnswer = false;
$bGotAnswer = true;
}
return ($bAnswer);
}
//
// To return a temporary file name.
//
function GetTempName($s_prefix)
{
global $SCRATCH_PAD;
if (isset($SCRATCH_PAD) && !empty($SCRATCH_PAD))
{
switch (substr($SCRATCH_PAD,-1))
{
case '/':
case '\\':
$s_dir = substr($SCRATCH_PAD,0,-1);
break;
default:
$s_dir = $SCRATCH_PAD;
break;
}
//
// Ideally, we could use tempnam. But,
// tempnam is system dependent and might not use the
// SCRATCH_PAD directory even if we tell it to.
// So, we'll force the file into SCRATCH_PAD.
//
// Note that we do *not* create the file, even though tempnam
// does create it in PHP version 4.0.3 and above. (The reason is
// we can't guarantee a non-race condition anyway.)
//
do
{
$i_rand = mt_rand(0,16777215); // 16777215 is FFFFFF in hex
$s_name = $SCRATCH_PAD."/".$s_prefix.sprintf("%06X",$i_rand);
}
while (file_exists($s_name));
}
else
$s_name = tempnam("/tmp",$s_prefix);
return ($s_name);
}
//
// To find a directory on the server for temporary files.
//
function GetTempDir()
{
$s_name = GetTempName("fm");
if (file_exists($s_name))
unlink($s_name);
$s_dir = dirname($s_name);
return ($s_dir);
}
//
// Returns true if the PHP version is at or later than the string specified
// (can't use "version_compare" before 4.1.0).
//
function IsPHPAtLeast($s_vers)
{
global $aPHPVERSION;
$a_test_version = explode(".",$s_vers);
if (count($a_test_version) < 3)
return (false);
return ($aPHPVERSION[0] > $a_test_version[0] ||
($aPHPVERSION[0] == $a_test_version[0] &&
($aPHPVERSION[1] > $a_test_version[1] ||
$aPHPVERSION[1] == $a_test_version[1] &&
$aPHPVERSION[2] >= $a_test_version[2])));
}
define('DEBUG',false); // for production
//define('DEBUG',true); // for development and debugging
if (DEBUG)
{
error_reporting(E_ALL); // trap everything!
LoadLanguage();
}
else
{
$iOldLevel = error_reporting(E_ALL ^ E_WARNING);
LoadLanguage();
//
// report everyting except warnings and notices
//
error_reporting(E_ALL ^ E_WARNING ^ E_NOTICE);
}
$bUseOldVars = IsOldVersion($aPHPVERSION);
//
// seed the random number generate if not version 4.2.0 or later
//
if (!IsPHPAtLeast("4.2.0"))
mt_srand(time());
//
// we set references to the appropriate arrays to handle PHP version differences
// Session vars are selected after we start the session.
//
if ($bUseOldVars)
{
$aServerVars = &$HTTP_SERVER_VARS;
$aGetVars = &$HTTP_GET_VARS;
$aFormVars = &$HTTP_POST_VARS;
$aFileVars = &$HTTP_POST_FILES;
$aEnvVars = &$HTTP_ENV_VARS;
}
else
{
$aServerVars = &$_SERVER;
$aGetVars = &$_GET;
$aFormVars = &$_POST;
$aFileVars = &$_FILES;
$aEnvVars = &$_ENV;
}
$bIsGetMethod = false;
//
// If the form submission was using the GET method, switch to the
// GET vars instead of the POST vars
//
if (isset($aServerVars["REQUEST_METHOD"]) && $aServerVars["REQUEST_METHOD"] === "GET")
{
$bIsGetMethod = true;
if ($bUseOldVars)
$aFormVars = &$HTTP_GET_VARS;
else
$aFormVars = &$_GET;
}
function SetRealDocumentRoot()
{
global $aServerVars,$REAL_DOCUMENT_ROOT;
if (isset($aServerVars['SCRIPT_FILENAME']))
$REAL_DOCUMENT_ROOT = $aServerVars['SCRIPT_FILENAME'];
elseif (isset($aServerVars['PATH_TRANSLATED']))
$REAL_DOCUMENT_ROOT = $aServerVars['PATH_TRANSLATED'];
else
$REAL_DOCUMENT_ROOT = "";
//
// look for 'www' or 'public_html' and strip back to that if found,
// otherwise just get the directory name
//
if (($i_pos = strpos($REAL_DOCUMENT_ROOT,"/www/")) !== false)
$REAL_DOCUMENT_ROOT = substr($REAL_DOCUMENT_ROOT,0,$i_pos+4);
elseif (($i_pos = strpos($REAL_DOCUMENT_ROOT,"/public_html/")) !== false)
$REAL_DOCUMENT_ROOT = substr($REAL_DOCUMENT_ROOT,0,$i_pos+12);
elseif (!empty($REAL_DOCUMENT_ROOT))
$REAL_DOCUMENT_ROOT = dirname($REAL_DOCUMENT_ROOT);
elseif (isset($aServerVars['DOCUMENT_ROOT']) &&
!empty($aServerVars['DOCUMENT_ROOT']))
$REAL_DOCUMENT_ROOT = $aServerVars['DOCUMENT_ROOT'];
}
if (!isset($REAL_DOCUMENT_ROOT))
SetRealDocumentRoot();
if (isset($aServerVars['SERVER_PORT']))
$SCHEME = ($aServerVars['SERVER_PORT'] == 80) ? "http://" : "https://";
else
$SCHEME = "";
if (isset($aServerVars['SERVER_NAME']))
$SERVER = $aServerVars['SERVER_NAME'];
else
$SERVER = "";
/*****************************************************************************/
/* CONFIGURATION (do not alter this line in any way!!!) */
/*****************************************************************************
* This is the *only* place where you need to modify things to use formmail.php
* on your particular system. This section finishes at "END OF CONFIGURATION".
*
* Each variable below is marked as LEAVE, OPTIONAL or MANDATORY.
* What we mean is:
* LEAVE you can change this if you really want to and know what
* you're doing, but we recommend that you leave it unchanged
*
* OPTIONAL you can change this if you need to, but its current
* value is fine and we recommend that you leave it unchanged
* unless you need a different value
*
* MANDATORY you *must* modify this for your system. The script will
* not work if you don't set the value correctly.
*
*****************************************************************************/
//
// ** LEAVE **
// EMAIL_NAME is a limited set of characters that you can use for your
// target email user names (the text before the "@");
// these are accepted:
// russellr
// russ.robinson
// russ61robbo
//
// The pattern we've provided doesn't match every valid user name in an
// email address, but, since these email addresses are ones you'll
// choose and are part of your organisation, the limited set is generally
// no problem.
//
// If you want to use other user names, then you need to change the pattern
// accordingly.
//
// We recommend that you don't modify this pattern, but, rather, use
// conforming email user names as your target email addresses.
// BTW, the pattern is processed case-insensitively, so there's
// no need to provide upper and lower case values.
//
define("EMAIL_NAME","^[-a-z0-9.]+"); // the '^' is an important security feature!
//
// ** MANDATORY **
// Set TARGET_EMAIL to a list of patterns that callers are allowed
// to send mail to; this is a *critical* security mechanism and
// prevents relaying. Relaying is where an unauthorized person uses this
// script to send mail to *anyone* in the world.
//
// By setting TARGET_EMAIL to a set of patterns for your email addresses,
// then relaying is prevented.
//
// More information about TARGET_EMAIL.
//
// Instructions
// ~~~~~~~~~~~~
// 1. If you only have one host or domain name:
// replace "yourhost" with the name of your email server computer.
// For example,
// EMAIL_NAME."@yourhost\.com$"
// becomes:
// EMAIL_NAME."@microsoft\.com$"
// If you work for Microsoft (microsoft.com).
//
// 2. If you have a domain name other than ".com":
// replace "yourhost\.com" with your email server's full
// domain name.
// For example,
// EMAIL_NAME."@yourhost\.com$"
// becomes:
// EMAIL_NAME."@apache\.org$"
// If you work for the Apache organisation (apache.org).
// Another example is:
// EMAIL_NAME."@rootsoftware\.com\.au$"
// If you work for Root Software in Australia (rootsoftware.com.au).
//
// 3. If you want to accept email to several domains, you can do that too.
// Here's an example. At Root Software, our forms can send to any of
// the following domains:
// rootsoftware.com
// rootsoftware.com.au
// ttmaker.com
// timetabling.org
// timetabling-scheduling.com
// tectite.com
// To achieve this, we have the following setting:
// $TARGET_EMAIL = array(EMAIL_NAME."@rootsoftware\.com$",
// EMAIL_NAME."@rootsoftware\.com\.au$",
// EMAIL_NAME."@ttmaker\.com$",
// EMAIL_NAME."@timetabling\.org$",
// EMAIL_NAME."@timetabling-scheduling\.com$",
// EMAIL_NAME."@tectite\.com$",
// );
//
// 4. If you want to accept email to several specific email addresses,
// that's fine too. Here's an example:
// $TARGET_EMAIL = array("^russell\.robinson@rootsoftware\.com$",
// "^info@ttmaker\.com$",
// "^sales@timetabling\.org$",
// "^webmaster@timetabling-scheduling\.com$",
// );
// or just one email address:
// $TARGET_EMAIL = array("^russell\.robinson@rootsoftware\.com$");
//
//
// More Instructions
// ~~~~~~~~~~~~~~~~~
// TARGET_EMAIL is an array. This means it can contain many "elements".
// Each element is a string (a set of characters in quotes).
// To create many elements, you simply list the strings separated by
// a comma.
// For example:
// $TARGET_EMAIL = array("String 1","String 2","String 3");
//
// You can put a newline after each comma, to make it more readable.
// Like this:
// $TARGET_EMAIL = array("String 1",
// "String 2",
// "String 3");
//
// If you look below, you may be wondering why you can see the following:
// EMAIL_NAME."@yourhost\.com$"
// and that's not a string!
//
// It's a string concatenation. EMAIL_NAME is a string (and you can
// see it defined above), and the "." after it says "append the following
// string to EMAIL_NAME and make one larger string".
//
// So,
// EMAIL_NAME."@yourhost\.com$"
// becomes the string:
// "^[-a-z0-9.]+@yourhost\.com$"
//
// What are all the \ ^ $ and other punctuation characters?
//
// The strings we're defining contain "patterns". We won't go into
// patterns here (it's a large subject), but we will explain a few
// important things:
// ^ means the beginning; we want email user names to match only
// at the beginning of the input, so that's why EMAIL_NAME starts
// with ^
// . matches any single character
// \ stops the following character from being a pattern matcher
// $ matches the end
//
// So, when we want to match ".com", we need to say "\.com". Otherwise,
// ".com" would match "Xcom", "Ycom", "xcom", etc., as well as ".com".
// The "\." says match only ".".
//
// Also, if your server is "yourhost.com", you don't want to match
// "yourhost.com.anythingelse", so we put "yourhost\.com$" to match
// the end.
//
// Note: if you're going to send to a domain that you don't own (e.g.
// yahoo.com or hotmail.com), *DO NOT* use the EMAIL_NAME feature.
// If you do, then your installation of FormMail could become a
// spam gateway! Instead, specify exact email addresses using one
// of the examples below.
//
// For security purposes, it's best to include ^ at the start and
// $ at the end of all email address patterns. This will prevent spammers
// from exploiting any vulnerabilities in your server or its software.
//
// Finally, don't use your AT_MANGLE (see below) characters here.
// The $TARGET_EMAIL needs to look like a real email address or pattern.
// You must use "@". Don't worry, spammers can't see inside formmail.php
// so they can't get the email addresses or patterns you put in $TARGET_EMAIL.
//
$TARGET_EMAIL = array("^info@waterworldusa\.com$");
//
// here are some other examples...
//
//$TARGET_EMAIL = array("^yourname@yourhost\.com$");
//$TARGET_EMAIL = array("^yourname@yourhost\.com$","^someone@yourhost\.com$");
//$TARGET_EMAIL = array(EMAIL_NAME."@yourhost\.com$",EMAIL_NAME."@otherhost\.com$");
//
// ** OPTIONAL BUT STRONGLY RECOMMENDED **
// Set DEF_ALERT to the email address that will be sent any alert
// messages (such as errors) from the script. This value is
// only used if the 'alert_to' is not provided by the form.
// If neither alert_to nor DEF_ALERT are provided, no alerts are sent.
//
// DEF_ALERT can be any email address and it's independent of
// the TARGET_EMAIL setting.
//
// Example:
// webmaster@yourhost.com
//
// If you set DEF_ALERT, you can do some initial tests with your browser.
// Just open this URL:
// http://www.your-site.com/formmail.php?testalert=1
//
//define("DEF_ALERT","you@yoursite.com"); // example - straight email address
define("DEF_ALERT","sal@waterworldusa.com");
//
// ** OPTIONAL **
// SET_REAL_DOCUMENT_ROOT tells FormMail the DocumentRoot for your website.
//
// Automatically finding the document root for your website in PHP can be
// quite problematical. $_SERVER["DOCUMENT_ROOT"] is often correct,
// but sometimes it's not provided (e.g. with a CGI interface) and with
// certain secure server configurations, it's completely inappropriate.
//
// For example, our website at http://www.tectite.com/ also lives
// at https://secure.rootsoftware.com/~tectite/. If we run FormMail
// from the latter location (such as when you place an order)
// $_SERVER["DOCUMENT_ROOT"] is set to "/home/secure" - which is completely
// wrong and won't work.
//
// The function above - SetRealDocumentRoot - is designed to set
// $REAL_DOCUMENT_ROOT to the right value based on the setting
// of SCRIPT_FILENAME or PATH_TRANSLATED (or as a last attempt, DOCUMENT_ROOT).
//
// SetRealDocumentRoot should work on most servers in most situations.
// However, it might not work on your server. Therefore, you can set
// $SET_REAL_DOCUMENT_ROOT to the correct value for your website.
// Use an absolute directory pathname such as:
//
// /home/yourname/public_html
// d:/inet/user/htdocs
//
// NOTE: on Windows servers, use '/' instead of '\' or double the
// '\' like this:
// "d:\\path\\to\\document_root"
// or
// "d:/path/to/document_root"
//
// If you're not using the "filter" feature in your forms, you don't
// need to worry about these settings.
//
$SET_REAL_DOCUMENT_ROOT = ""; // overrides the value set by SetRealDocumentRoot function
//
// override $REAL_DOCUMENT_ROOT from the $SET_REAL_DOCUMENT_ROOT value (if any)
// Do not alter the following code (next 3 lines)!
//
if (isset($SET_REAL_DOCUMENT_ROOT) && $SET_REAL_DOCUMENT_ROOT !== "")
$REAL_DOCUMENT_ROOT = $SET_REAL_DOCUMENT_ROOT;
//
// ** OPTIONAL **
// CONFIG_CHECK tells FormMail which configuration variables to check.
//
// Currently, only TARGET_EMAIL is checked and it is tested for
// the best known patterns for securing your FormMail installation.
//
// If you're sure you've got your configuration correct and want to
// stop warnings you are receiving in alert messages, you can
// remove the name of the configuration variable you *don't* want
// checked from the CONFIG_CHECK array.
//
$CONFIG_CHECK = array("TARGET_EMAIL");
//
// ** OPTIONAL **
// Set AT_MANGLE to a string to replace with "@". To disable this
// feature, set to empty string.
//
// If you enable this feature, you can protect the email addresses
// you specify in your forms from SpamBots.
//
// SpamBots are programs that search for email addresses on the
// Internet. Typically, they look for "mailto:someone@somewhere".
//
// However, email addresses you specify in your forms will be like
// this:
//
//
// It is possible that some SpamBots will find your email addresses hidden
// in your forms.
//
// The AT_MANGLE feature allows you to mangle your email addresses and
// protect them from SpamBots.
//
// Here's an example:
// define("AT_MANGLE","_*_");
//
// This tells formmail.php to replace "_*_" in your email address with "@".
// So, in your forms you can specify:
//
//
// No SpamBot will recognize this as an email address, and your addresses
// will be safe!
//
// If you use this feature, we encourage you to be creative and different
// from everyone else.
//
// Here are some more examples:
// define("AT_MANGLE","_@_"); // e.g. john_@_yourhost.com
// // SpamBots may recognize this,
// // but it'll be an invalid address
//
// define("AT_MANGLE","AT"); // e.g. johnATyourhost.com
//
// Note that the AT_MANGLE pattern match is case-sensitive, so "AT" is
// different from "at".
//
define("AT_MANGLE","DBHAA");
//
// ** OPTIONAL **
// Set TARGET_URLS to a list of URL prefixes that are acceptable.
// TARGET_URLS is used for the "crm_url" feature and for multi-page
// forms.
// No pattern matching is allowed, and all comparisons are
// performed by first converting to lower case.
//
$TARGET_URLS = array(); // default; no URLs allowed
// The following example allows one URL. NOTE: the trailing '/' is important
// for security! It prevents attackers from specifying port numbers.
//$TARGET_URLS = array("http://www.yourhost.com/")
// The following example specifies a number of URLs.
//$TARGET_URLS = array( "http://www.yourhost.com/",
// "http://www.someotherhost.com/",
// "http://www.specialplace.com:81/");
//
// ** LEAVE **
// HEAD_CRLF is the line termination for email header lines. The email
// standard (RFC-822) specifies line termination should be CR plus LF.
//
// Many mail systems will work with just LF and some are reported to
// actually fail if the email conforms to the standard (with CR+LF).
//
// If you have special requirements you can change HEAD_CRLF to another
// string (such as "\n" to just get LF (line feed)), but be warned that
// this may break the email standard.
//
// Note: the following information was reported by a customer, which he
// found on php.net:
// "If you're using Postfix for SMTP on FreeBSD you MUST end header
// lines with \n and not \r\n."
// The relevant URL is: http://php.net/mail
//
define("HEAD_CRLF","\r\n");
//
// ** OPTIONAL **
// BODY_LF is the line termination for email body lines. The email
// standard (RFC-822) does not clearly specify line termination for the body
// of emails; the body doesn't have to have any "lines" at all. However,
// it does allow CR+LF between sections of text in the body.
//
// RFC-821 specifies a line length that must be supported of 998 octets
// (1000 include the CR+LF).
//
// Most mail systems will work with just LF and that used to be the default
// for FormMail prior to version 2.00.
//
// With the implementation of HTML template support (using MIME RFC-2045)
// we've changed the default to CR+LF.
//
// If you want your email bodies to be line terminated differently, you
// can specify a different value below.
//
// To change the setting, you must comment out the "define" line you
// don't want (put '//' at the beginning of the line) and un-comment
// the line you do want (remove '//' from the beginning of the line).
//
//define("BODY_LF","\n"); // the old default: just LF
define("BODY_LF","\r\n"); // the new default: use this for CR+LF
//
// ** OPTIONAL **
// Set FROM_USER to the email address that will be the sender
// of alert/error messages and Auto Responses (if used).
// If you do not specify FROM_USER (that is, you comment it out),
// formmail.php uses "FormMail@SERVER" where SERVER is determined
// from your web server. If you set it to "NONE", then no sender is
// specified.
// NOTE: FROM_USER is not used for form results, it is only used
// for alert messages and Auto Responses.
//
//$FROM_USER = "formmail@yourhost.com"; // example - replace with your email address
//$FROM_USER = "NONE"; // use this to show no sender
$FROM_USER = ""; // the default - setting not used
//
// ** LEAVE **
// SENDMAIL_F_OPTION controls whether to use the "-f" option when
// sending mail. Some servers use a Mail Transfer Agent called "sendmail"
// and some of these require the "-f" option to be provided - this option
// tells sendmail the "From" user or sender.
// FormMail originally supported this feature using the "mail_options"
// setting inside your HTML forms. That was a silly place for us to
// put this feature! It's a server configuration, so it should live
// in this configuration section of FormMail, not in your forms.
//
// Set SENDMAIL_F_OPTION to true to tell FormMail to specify the "-f"
// option when sending mail or set it to false to prevent FormMail
// from specifying it.
//
// Now this gets a little complicated....
// FormMail distinguishes between the "From" address and the "sender".
// The "sender" is used by SENDMAIL_F_OPTION. The "From" address is not.
//
// For form results:
// The "From" address for form results is usually the email address
// entered by the user on the form (the "email" field). If you set
// FromAddr in mail_options, the "From" address is set to this value
// and the "sender" is also set to this value. If you do not set
// FromAddr, then the "From" address is set to the "email" field
// (plus the "realname" field) from the form and there is no "sender".
//
// For alert messages:
// Both "From" address and "sender" are set according to the
// rules for the $FROM_USER configuration (see above).
//
// Following is a complete description of the emailing logic. This logic
// is quite complicated because different servers have different and,
// often, conflicting requirements.
//
// We define these concepts:
// Sender is an email address that is deemed to be sending
// an email.
// From Line is an email address that is deemed to be the
// "From" address in an email being sent.
//
// For Form Results (see below for Alert Messages and Auto Responses):
// If the "FromAddr" feature is used by the form, then:
// 1. Set Sender to the FromAddr value; and
// 2. Set From Line to FromAddr value.
// If the "FromAddr" feature is not used by the form, then:
// 1. If SET_SENDER_FROM_EMAIL is set to true, then
// Set Sender to the "email" value from the form,
// otherwise,
// leave Sender unset; and
// 2. Set From Line to the realname + email fields from
// the form.
//
// For Alert Messages and Auto Responses (see above for Form Results):
// if FROM_USER (in FormMail's configuration) is set and is not
// empty, then:
// if has the value "NONE", then:
// do not set either Sender or From Line values
// otherwise:
// set Sender and From Line values to the FROM_USER value;
// if FROM_USER is not set or it's empty, then:
// set Sender and From Line values to a fake address on the
// server (FormMail@domain).
//
// For all emails (form results, alerts and auto responses):
// If SENDMAIL_F_OPTION is true:
// if Sender is set, specify its value with the -f option
// in the mail command.
// If INI_SET_FROM is true:
// if Sender is set, specify its value to the "sendmail_from"
// PHP option.
// In every case:
// set the "From:" field of the email to the value of From Line.
//
define("SENDMAIL_F_OPTION",false);
define("SENDMAIL_F_OPTION_LINE",__LINE__-1); // don't modify this line!
//
// ** LEAVE **
// SET_SENDER_FROM_EMAIL controls whether the "Sender" is set from the
// email field.
//
// Some servers require a Sender to be specified for emails sent.
// If your server requires this and you do not want to use the
// FromAddr feature for form results, set SET_SENDER_FROM_EMAIL
// to true.
//
// You may also need to set SENDMAIL_F_OPTION to true.
//
// Review the email logic description above the SENDMAIL_F_OPTION
// configuration setting for full details.
//
// Note that SET_SENDER_FROM_EMAIL is not used if the form specifies
// FromAddr.
//
define("SET_SENDER_FROM_EMAIL",false);
//
// ** LEAVE **
// INI_SET_FROM controls whether FormMail attempts to set the
// "sendmail_from" feature in the PHP configuration. This PHP
// feature only applies to Windows servers.
// You can find this feature inside the "php.ini" file. On most servers
// it will be set correctly and you don't need to change it.
// However, some servers have this set incorrectly in php.ini and this
// prevents PHP scripts from sending mail!
//
// Set INI_SET_FROM to true to request FormMail to set this PHP
// feature to the sender of the emails it sends. You may also
// need to set $FROM_USER in this configuration section (for alert messages)
// and use the FromAddr feature in "mail_options" in your forms (for
// sending form results). However, test each case individually.
//
// INI_SET_FROM sets the sender according to the documentation shown
// above for SENDMAIL_F_OPTION. This means that if you need
// INI_SET_FROM set to true, then you must also either require the "email"
// field on a form or specify the FromAddr in the "mail_options" on
// the form.
//
// Review the email logic description above the SENDMAIL_F_OPTION
// configuration setting for full details.
//
define("INI_SET_FROM",false);
//
// ** OPTIONAL **
// Set LOGDIR to the directory on your server where log files are
// stored. When the form provides a 'logfile' value, formmail.php
// expects the file to be in this directory.
// Generally you want this to be outside your server's WWW directory.
// For example, if your server's root (WWW) directory is:
// /home/yourname/www
// use a directory like
// /home/yourname/logs
//
// If you don't want to support log files, make this an empty string:
// $LOGDIR = "";
//
// The log file simply contains a log of FormMail activity. It contains
// the date/time, the form user's real name, their email address, and
// the value of the "subject" field on the form.
//
// One use for the log file is for auditing: you can
// check the number of successful form submissions and when they occurred.
// You might use this, for example, to verify that a day's work has been
// processed by your employees.
//
// FormMail user AlecRaenos told us how he uses the log file:
// We keep "lead" counts and this log file will be a HUGE help
// to us to determine:
// 1) if our server is sending out all the processed forms -we
// have had trouble with this and
// 2) auditing how many leads we get for our business.
//
// You might find other uses, if so, please let us know.
//
// NOTE: you'll need to create the log file on your server and make
// it writable by the web server software. For security reasons,
// FormMail cannot do this for you.
// In general, the correct permissions for your log file are:
// rw-rw-rw-
//
// NOTE: on Windows servers, use '/' instead of '\' or double the
// '\' like this:
// "d:\\path\\to\\logs"
// or
// "d:/path/to/logs"
//
$LOGDIR = ""; // directory for log files; empty string to
// disallow log files
//
// ** OPTIONAL **
// Set AUTORESPONDLOG to the filename on your server where auto-responding
// activity is logged.
//
// This file is stored in the $LOGDIR directory and it *must* be outside
// your web server directory. If it isn't, then someone may be able to
// harvest the email addresses from your server!
//
// If you don't want to to keep a log of auto responding activity,
// make this an empty string:
// $AUTORESPONDLOG = "";
//
// Auto responding is a potential dangerous thing to allow from FormMail.
// That's why FormMail will only do auto responding after image verification.
//
// However, image verification is not perfect. It is possible for a very
// motivated Spammer to overcome the image verification (e.g. he could
// pay people to type in the image contents for him).
//
// Therefore, you should keep a log of auto responding activity. This
// way you can:
// - confirm correct operation
// - detect unusual activity
// - respond to any queries from your hosting company or anyone else
// accusing you of being a spam gateway
//
// The log file contains:
// - the date/time
// - the IP address from where the user is submitting
// - the email address that the auto response was sent to
// - the subject line that was put in the email.
// - information about the activity (success, failure, etc.)
//
// NOTE: you'll need to create the log file on your server and make
// it writable by the web server software. For security reasons,
// FormMail cannot do this for you.
// In general, the correct permissions for your log file are:
// rw-rw-rw-
//
$AUTORESPONDLOG = ""; // file name in $LOGDIR for the auto responder
// log; empty string for no auto responder log
//
// ** OPTIONAL **
// Set CSVDIR to the directory on your server where CSV files are
// stored. When the form provides a 'csvfile' value, formmail.php
// expects the file to be in this directory.
// Generally you want this to be outside your server's WWW directory.
// For example, if your server's root (WWW) directory is:
// /home/yourname/www
// use a directory like
// /home/yourname/csv
//
// If you don't want to support CSV files, make this an empty string:
// $CSVDIR = "";
//
// NOTE: you'll need to create the CSV file on your server and make
// it writable by the web server software. For security reasons,
// FormMail cannot do this for you.
// In general, the correct permissions for your CSV file are:
// rw-rw-rw-
//
// NOTE: on Windows servers, use '/' instead of '\' or double the
// '\' like this:
// "d:\\path\\to\\csv"
// or
// "d:/path/to/csv"
//
$CSVDIR = ""; // directory for csv files; empty string to
// disallow csv files
//
// ** OPTIONAL **
// If you're creating a CSV database, you can choose the field
// separators below.
//
// The defaults below will suit most purposes.
//
$CSVSEP = ","; // comma separator between fields (columns)
$CSVINTSEP = ";"; // semicolon is the separator for fields (columns)
// with multiple values (checkboxes, etc.)
$CSVQUOTE = '"'; // all fields in the CSV are quoted with this character;
// default is double quote. You can change it to
// single quote or leave it empty for no quotes.
//$CSVQUOTE = "'"; // use this if you want single quotes
$CSVOPEN = ""; // set to "b" to force line terminations to be
// kept as $CSVLINE setting below, regardless of
// operating system. Keep as empty string and
// leave $CSVLINE unchanged, to get text file
// terminations for your server's operating system.
// (Line feed on UNIX, carriage-return line feed on Windows).
$CSVLINE = "\n"; // line termination for CSV files. The default is
// a single line feed, which may be modified for your
// server's operating system. If you want to change
// this value, you *must* set $CSVOPEN = "b".
//
// ** OPTIONAL **
// Set TEMPLATEDIR to the directory on your server where template files are
// stored.
//
// If you want to specify "good_template", "bad_template" or "HTMLTemplate"
// in your forms, the templates must be found in the directory you specify
// below.
// This is a necessary step to prevent security problems. For example,
// without this measure, an attacker might be able to gain access to
// any file on your server.
//
// We recommend you set aside a particular directory on your
// server for all your templates.
//
// NOTE: on Windows servers, use '/' instead of '\' or double the
// '\' like this:
// "d:\\path\\to\\templates"
// or
// "d:/path/to/templates"
//
$TEMPLATEDIR = ""; // directory for template files; empty string
// if you don't have any templates
//
// ** OPTIONAL **
// Set TEMPLATEURL to the URL where template files can be fetched.
// If you set TEMPLATEDIR too, that takes precedence and TEMPLATEURL
// is ignored.
//
// TEMPLATEURL is analogous to TEMPLATEDIR, but allows for templates
// to be read from a web server. This is useful for cases where
// you want the template to be generated via a PHP script, for example.
//
// You can use $SCHEME and $SERVER to refer to your own server.
//
// Note that the HTTP_USER_AGENT string is passed to any URL opened
// through TEMPLATEURL with a parameter, for example:
// http://blah.blah/templatedir/template.php?USER_AGENT=blahblah
//
// This is useful for dynamically generated pages which generate different
// content depending on the user's browser.
//
$TEMPLATEURL = ""; // default; no template URL
//$TEMPLATEURL = $SCHEME.$SERVER."/templatedir"; // a sample using your server
//
// ** OPTIONAL **
// Set MULTIFORMDIR to the directory on your server where multi-form
// template files are stored.
//
// If you want to specify "next_form" in your forms, the templates must
// be found in the directory you specify below.
//
// This is a necessary step to prevent security problems. For example,
// without this measure, an attacker might be able to gain access to
// any file on your server.
//
// We recommend you set aside a particular directory on your
// server for all your multi-form templates.
//
// NOTE: on Windows servers, use '/' instead of '\' or double the
// '\' like this:
// "d:\\path\\to\\multiforms"
// or
// "d:/path/to/multiforms"
//
$MULTIFORMDIR = ""; // directory for multi-form template files; empty string
// if you're not using multi-forms
//
// ** OPTIONAL **
// Set MULTIFORMURL to the URL where multi-form template files can be fetched.
// If you set MULTIFORMDIR too, that takes precedence and MULTIFORMURL
// is ignored.
//
// MULTIFORMURL is analogous to MULTIFORMDIR, but allows for templates
// to be read from a web server. This is useful for cases where
// you want the template to be generated via a PHP script, for example.
//
// You can use $SCHEME and $SERVER to refer to your own server.
//
// Note that the HTTP_USER_AGENT string is passed to any URL opened
// through MULTIFORMURL with a parameter, for example:
// http://blah.blah/multiforms/page2.php?USER_AGENT=blahblah
//
// This is useful for dynamically generated pages which generate different
// content depending on the user's browser.
//
$MULTIFORMURL = ""; // default; no multi-forms templates URL
//$MULTIFORMURL = $SCHEME.$SERVER."/multiforms"; // a sample using your server
//
// ** OPTIONAL **
// When FormMail returns to a form for the user in a multi-page
// form sequence, it opens a URL to read in the form. This means your
// server is opening a URL to itself.
//
// If your form requires authentication, you need FormMail to be
// able to authenticate with the server to open the URL.
//
// FormMail version 7.05 attempts to provide the authentication information
// automatically.
//
// If this doesn't work on your site or you want to provide a separate
// authentication for FormMail, put the value(s) here.
//
// $AUTHENTICATE is placed as the value of the "Authorization:" header.
// For example:
// Basic cnVzc2VsbHI6dGVzdA==
// The second value is the Base-64 encoded user name and password
// separated by ":". (The above value is: "russellr:test".)
//
// If this is inconvenient for you, leave $AUTHENTICATE empty and
// set $AUTH_USER and $AUTH_PW as normal strings
// (e.g. "russellr" and "test"). When using $AUTH_USER and $AUTH_PW
// FormMail will automatically specify "Basic" authentication.
//
// Note: this configruation is similar to that in FMBadHandler, but
// in FormMail it's only used in multi-page form processing.
//
$AUTHENTICATE = "";
//$AUTHENTICATE = "Basic cnVzc2VsbHI6dGVzdA=="; // example
$AUTH_USER = "";
$AUTH_PW = "";
//
// ** OPTIONAL **
// Set $FORM_INI_FILE to the file name on your server
// where you keep secret settings for your forms.
//
// This is how you hide email addresses, force particular conditions,
// or other settings that you don't want exposed in the HTML.
//
$FORM_INI_FILE = "";
//$FORM_INI_FILE = "/home/mysite/formmail.ini";
//
// ** OPTIONAL **
// Set MODULEDIR to the directory on your server where you install
// FormMail compatible modules.
//
// The default value ('.' for current directory) is suitable if
// you install modules in the same directory as formmail.php.
//
// Because modules may be accessible from internet browsers, you
// may wish to install them in a different directory, which you
// protect from unauthorized access.
//
// The modules we provide are generally safe from unauthorized access
// but we still recommend you use a separate directory for modules
// and protect it from unauthorized access using a .htaccess file or
// equivalent for your web server.
//
// If you are reserving a directory for FormMail modules, set the
// directory in this configuration setting.
//
// NOTE: on Windows servers, use '/' instead of '\' or double the
// '\' like this:
// "d:\\path\\to\\templates"
// or
// "d:/path/to/templates"
//
$MODULEDIR = ".";
//
// ** LEAVE **
// Set FMCOMPUTE to the name of the "fmcompute.php" module you want
// to load.
//
// This is a standard name, but you may want to use a different name
// for temporary testing purposes.
// The module is always loaded from $MODULEDIR (above).
//
$FMCOMPUTE = "fmcompute.php";
//
// ** LEAVE **
// Set FMGEOIP to the name of the "fmgeoip.php" module you want
// to load.
//
// This is a standard name, but you may want to use a different name
// for temporary testing purposes.
// The module is always loaded from $MODULEDIR (above).
//
$FMGEOIP = "fmgeoip.php";
//
// ** OPTIONAL **
// Set LIMITED_IMPORT to false if your target database understands
// escaped quotes and newlines within CSV files.
//
// When formmail.php is instructed to write to a CSV file, it
// can strip special encodings or leave them intact.
//
// What you want to do depends on the final destination of your
// CSV file. If you intend to import the CSV file into a database,
// and the database doesn't accept these special encodings, you
// must leave LIMITED_IMPORT set to true.
//
// Microsoft Access is one example of a database that doesn't
// understand escaped quotes and newlines, so you need LIMITED_IMPORT
// set to true.
//
// When LIMITED_IMPORT is true, the following transformations are made
// on every form value before placement in the CSV file:
// \\ is replaced by \
// \X is replaced by X where X is any character except \
// plus
// control characters and multiple spaces are replaced with a single
// space (the means new lines are removed too)
//
define("LIMITED_IMPORT",true); // set to true if your database cannot
// handle escaped quotes or newlines within
// imported data. Microsoft Access is one
// example.
//
// ** OPTIONAL **
// Set VALID_ENV to the environment variables the script is allowed to
// report. No need to change.
//
$VALID_ENV = array('HTTP_REFERER','REMOTE_HOST','REMOTE_ADDR','REMOTE_USER',
'HTTP_USER_AGENT');
//
// ** OPTIONAL **
// Set FILEUPLOADS to true if you want to allow forms to upload files.
// Leave at false to prevent file attachments in your emails or file
// storage on the server.
//
// This is a security measure. Setting to false prevents attackers from
// using your FormMail to send you malicious file attachments or saving
// files on your server.
//
// The php.ini and httpd.conf files can set file_uploads to false to
// disable file uploading. You cannot override a false setting in
// these files.
//
define("FILEUPLOADS",false); // set to true to allow file attachments
//
// ** OPTIONAL **
// Set MAX_FILE_UPLOAD_SIZE to the maximum size you want to allow for a file
// upload. Setting this to 0 means that the HTML form or and the PHP
// configuration (upload_max_filesize) on your server specify the limit.
//
// Specify MAX_FILE_UPLOAD_SIZE in kilobytes. For example, "4" means
// 4 kilobytes, which is 4096 bytes (4 * 1024).
//
// You can set this in the HTML form (MAX_FILE_SIZE), but it's easily
// overridden by an attacker.
//
// You can also set this in the php.ini or httpd.conf if you have access
// to these files. If you don't have access to these files, then you can't
// successfully set a *larger* size below (these files provide a hard upper
// limit that a PHP script cannot override).
//
// But if you want a *smaller* size than specified in php.ini and httpd.conf
// then you can set MAX_FILE_UPLOAD_SIZE to that smaller amount and FormMail
// will enforce the smaller limit.
//
define("MAX_FILE_UPLOAD_SIZE",0); // default of 0 means that other software
// controls the maximum file upload size
// (FormMail doesn't test the file size)
//
// ** OPTIONAL **
// Set $FILE_REPOSITORY to the directory path on your server where uploaded
// files are to be stored. If you set this to a directory path, then
// uploaded files are saved there instead of being attached to the email.
//
// Setting to an empty string disables the server-side storage and uploaded
// files are sent by email as an attachment.
//
$FILE_REPOSITORY = "";
//
// ** OPTIONAL **
// Set FILE_MODE to the permission mode you want for files saved
// to $FILE_REPOSITORY.
//
// To understand the valid values, you can read about the "chmod" command
// on any Linux system. This page is also helpful: http://www.php.net/chmod
//
// Useful values:
// 0664 read-write by owner and group, read by others
// 0666 read-write by everyone
// 0444 read-only by everyone
// 0644 read-write by owner, read by everyone else
// 0 don't set the protection mode (skips setting)
//
// Remember that uploaded files may be owned by "apache" or "nobody".
//
// FILE_MODE may have no effect on Windows servers.
//
define("FILE_MODE",0664); // always precede with 0 to specify octal!
//
// ** OPTIONAL **
// Set PUT_DATA_IN_URL to false if you want to prevent FormMail
// from placing data in the URL when redirecting to bad_url.
//
// The default value is "true" and will work fine for forms with a small
// amount of data (less than 2000 bytes, approximately.)
//
// However, URLs have a finite length that's dependent on the user's
// browser. If you've got forms with large amounts of data, then
// a redirect to bad_url will probably cause an error display to
// the user, for example:
// Cannot find server or DNS Error
//
// By setting PUT_DATA_IN_URL to false, you avoid this problem.
//
// In any case, error information and the data submitted in the form will
// be placed in PHP session variables.
//
// So, if your bad_url target is written in PHP and your PHP version is
// sufficient to handle sessions correctly, you'll be fine with
// PUT_DATA_IN_URL set to false. (As always, test thoroughly!)
//
// Otherwise, you'll need to keep PUT_DATA_IN_URL set to true and your
// forms will need to be small.
//
define("PUT_DATA_IN_URL",true); // set to true to place data in the URL
// for bad_url redirects
//
// ** LEAVE **
// Set DB_SEE_INPUT to true for debugging purposes only. If set to
// true the script does nothing except generate a page showing you what
// it will do.
//
define("DB_SEE_INPUT",false); // set to true to just see the input values
//
// ** LEAVE **
// Set DB_SEE_INI to true for debugging purposes only. If set to
// true the script does nothing except generate a page showing you what
// it found in the $FORM_INI_FILE file.
//
define("DB_SEE_INI",false); // set to true to just see the ini file
//
// ** OPTIONAL **
// Set MAXSTRING to limit the maximum length of any value accepted
// from the form. Increase this if you have TEXTAREAs in your forms
// and you want users to be able to enter lots of data.
// This value has no effect on file upload size.
//
define("MAXSTRING",1024); // maximum string length for a value
//
// ** OPTIONAL **
// Set $bShowMesgNumbers to true to set message numbers on.
// if message numbers are shown then every message from FormMail
// as [Mnnn] displayed with it, where nnn is the message number.
// The message number is useful if:
// - you use a language other than English and you need to contact
// us (who only speak English) to tell us the exact messages being
// issued by FormMail,
// or
// - you prefer to know the precise error message being produced
// regardless of the text (for example, for searching the FormMail
// source for the occurrence of the message)
//
// Initially, FormMail always showed message numbers. However, several
// customers found this annoying and, so, we've made it optional with
// the default being "off".
//
$bShowMesgNumbers = false;
//
// ** OPTIONAL **
// Set FILTERS to the filter programs you want to support.
// A filter program is used to process the data before sending in email.
// For example, an encryption program can be used to encrypt the mail.
// Note that formmail.php changes to the directory of the filter program
// before running the filter, so file name arguments are relative
// to that directory.
//
// The format for each filter program is:
// "name"=>"program path [program options]"
// Here's an example:
// $FILTERS = array("encode"=>"$REAL_DOCUMENT_ROOT/cgi-bin/fmencoder");
//
// This says that when the form specifies a 'filter' value of
// "encode", run the email through this program:
// $REAL_DOCUMENT_ROOT/cgi-bin/fmencoder
//
// You can use the special variable $REAL_DOCUMENT_ROOT to refer
// to the top of your web server directory.
// The program can also be outside of the web server directory, e.g.:
// /home/yourname/bin/fmencoder
//
// The default value below is ready for use with FormMailEncoder.
// FormMailEncoder allows your form results to be strongly encrypted
// before being mailed to you.
//
// Use this to collect credit card payments from your customers or
// just to keep their details private.
//
// You need our FormMailDecoder product to decrypt these messages.
// You can purchase FormMailDecoder and FormMailEncoder
// from us at http://www.tectite.com.
//
// The settings below have no effect unless your HTML forms request
// their use. So, you can leave them set to the values below.
//
// Please note that on Windows servers, you can use '/' to separate
// directory names. But, if you use '\', then you must double it
// like this:
// "encode"=>"d:\\websites\\yoursite\\fmencoder -kpubkey.txt"
// or
// "encode"=>"d:/websites/yoursite/fmencoder -kpubkey.txt"
//
//
// Note: the "null" filter does nothing to the message.
// You can use the null filter for testing your form prior to changing
// to a real filter.
// You can also use the null filter to attach the form submission to the
// email instead of having it in the body of the email (use the
// filter_options "Attach=filename" feature).
//
$FILTERS = array("encode"=>"$REAL_DOCUMENT_ROOT/cgi-bin/fmencoder -kpubkey.txt",
"null"=>"null");
//
// ** OPTIONAL **
// Set SOCKET_FILTERS to filter programs you want to access via HTTP
// or HTTPS connections.
//
// Server Restrictions
// ~~~~~~~~~~~~~~~~~~~
//
// Some server setups prevent the execution of external programs.
// Provided you can execute cgi-bin programs from a web browser (i.e.
// an HTTP connection), we've provided a workaround for this situation.
// FormMail can execute your cgi-bin filter program using an HTTP (or,
// if your PHP is configured correctly, an HTTPS) connection.
//
// Note: this is supported by fmencoder version 1.4 and above only.
//
// To execute fmencoder via HTTP, do this:
// 1. Change the "site" value for "httpencode" to your site's web
// address.
// 2. Upload your public key to the file "pubkey.txt" in your cgi-bin
// directory (or change the "file" setting in the "params" value).
// 3. Add this hidden field to your HTML form:
//
//
// This is still secure because the information never leaves your
// server in clear text form. However, if you need to execute fmencoder
// on another server (i.e. a server different from the one that has
// your FormMail script), you need to use the "sslencode" filter
// instead of the "httpencode" filter. Contact us for assistance if
// you require this.
//
$SOCKET_FILTERS = array(
"httpencode"=>array("site"=>"YourSiteHere",
"port"=>80,
"path"=>"/cgi-bin/fmencoder",
"params"=>array(array("name"=>"key",
"file"=>"$REAL_DOCUMENT_ROOT/cgi-bin/pubkey.txt"))),
"sslencode"=>array("site"=>"ssl://YourSecureSiteHere",
"port"=>443,
"path"=>"/cgi-bin/fmencoder",
"params"=>array(array("name"=>"key",
"file"=>"$REAL_DOCUMENT_ROOT/cgi-bin/pubkey.txt"))),
);
//
// ** OPTIONAL **
// Set FILTER_ATTRIBS to describe the attributes of your filters.
//
// Supported attributes are:
// Strips the filter returns a block of data, stripped of any
// formatting (e.g. any HTML is removed)
// MIME the MIME type that the filter outputs:
// MIME=text/plain
//
$FILTER_ATTRIBS = array("encode"=>"Strips,MIME=text/plain",
"httpencode"=>"Strips,MIME=text/plain",
"sslencode"=>"Strips,MIME=text/plain",);
//
// ** OPTIONAL **
// Set CHECK_FOR_NEW_VERSION to false if you don't want FormMail
// to check for a new version and report it to you.
//
// The check is made once every 3 days or if your server is rebooted (or
// its system directory for temporary files is cleaned).
//
// If a new version is found, then this is reported to you via an Alert.
//
// FormMail attempts to create a unique file in your server's temporary
// directory (e.g. /tmp on Linix) to record when it last performed a version
// check. The unique file name is derived from your $TARGET_EMAIL setting.
//
// If you provide a value for SCRATCH_PAD (see below), then that directory
// is used instead of /tmp. If your web server software cannot write
// to your server's /tmp directory, set SCRATCH_PAD if you want version
// checks.
//
// CHECK_DAYS specifies the number of days between checks (if your server
// is rebooted, a check may be made regardless).
//
define("CHECK_FOR_NEW_VERSION",true);
define("CHECK_DAYS",30);
//
// ** OPTIONAL **
// Set SCRATCH_PAD to a directory into which FormMail can create files.
// The SCRATCH_PAD directory must be writable by your web server software.
// On Linux, the following mode should work:
// rwxrwxrwx
//
// If you set it, the SCRATCH_PAD directory is used for CHECK_FOR_NEW_VERSION
// processing and any other time FormMail needs to create a temporary
// file. If you don't set it, then FormMail uses your system's temporary
// directory (e.g. /tmp on Linux).
//
// We recommend you create the directory *above* your web server document
// directory, if possible. For example, if your web pages are served
// from:
// /home/your-site/public_html
// create a directory called:
// /home/your-site/fmscratchpad
//
// This more secure as no browser will be able to view the scratch pad
// directory.
//
// Do not specify a system directory where other FormMail installations
// may write to.
//
// We recommend specifying the full path (not a relative path) in SCRATCH_PAD.
//
// NOTE: on Windows servers, use '/' instead of '\' or double the
// '\' like this:
// "d:\\path\\to\\scratchpad"
// or
// "d:/path/to/scratchpad"
//
$SCRATCH_PAD = "";
//
// ** OPTIONAL **
// If you need to use an outgoing mail server other than the one configured
// directly for PHP, *and* your PHP installation has PEAR support,
// you can configure FormMail to use PEAR's "Mail" object to send
// mail.
//
// To do this, you need to set $PEAR_SMTP_HOST to the name of the
// outgoing mail server. The default port for SMTP is 25, but you
// can specify a different one if required.
// If you don't need authentication, leave $PEAR_SMTP_USER blank,
// otherwise, set it to the user name and set $PEAR_SMTP_PWD to the
// required password. Note that servers frequently require a complete
// email address for $PEAR_SMTP_USER (e.g. "russellr@rootsoftware.com"
// instead of just "russellr").
//
// When using PEAR, emails seem to require a sender (a 'From' address).
// Therefore, you may need to set "$FROM_USER" (above) to get alert messages
// to work.
//
// Note that with PEAR mailing enabled, the SendMailFOption "mail_options"
// setting is ignored (and so is SENDMAIL_F_OPTION).
//
// Test your PEAR settings with the "testalert" feature:
// http://yoursite.com/formmail.php?testalert=1
//
$PEAR_SMTP_HOST = "";
$PEAR_SMTP_PORT = 25;
$PEAR_SMTP_USER = "";
$PEAR_SMTP_PWD = "";
//
// ** OPTIONAL **
// Set ALERT_ON_USER_ERROR to false if you don't want FormMail
// to send you an alert when a user error (e.g. missing field) occurs
// on your forms.
// We recommend you leave this "true" while you debug your forms and
// either leave it that way or set it to "false" for your production
// environment.
//
define("ALERT_ON_USER_ERROR",true);
//
// ** OPTIONAL **
// Set ENABLE_ATTACK_DETECTION to false if you don't want FormMail
// to try to detect an attack designed to abuse your server.
//
// The only reason you may want to set this to false is if you're
// testing FormMail's attack detection features.
//
// FormMail has never been vulnerable to any of the attacks that it
// can detect. The *purpose* of attack detection is merely to prevent
// it from sending you an annoying alert whenever an attack happens.
//
// If you're using our FormMail, the only effect of this attack is one
// or more annoying alert messages (your server is safe).
//
define("ENABLE_ATTACK_DETECTION",true);
//
// ** OPTIONAL **
// Set ALERT_ON_ATTACK_DETECTION to true if you want FormMail
// to send you an alert when it detects an attack designed to
// abuse your server.
// If you set this to true, you may get lots of alert messages
// each time an attack occurs.
//
define("ALERT_ON_ATTACK_DETECTION",false);
//
// ** LEAVE **
// Set ATTACK_DETECTION_MIME to false if you don't want FormMail's
// attack detection to check for the MIME attack.
// The MIME attack is where the recipient's address is carefully
// crafted to try to fool FormMail into sending an with a virus
// or other malware file attached.
//
define("ATTACK_DETECTION_MIME",true);
//
// ** OPTIONAL **
// Set $ATTACK_DETECTION_DUPS to the list of fields on your forms
// that should *not* have duplicate values.
//
// One annoying attack on HTML forms scripts is to submit an email address in
// every field, with the aim of getting the script to send email to
// someone via your server.
//
// If you use one form on your server, just list some or all of the fields
// that should never contain duplicate data. For example, a person's
// name is never the same as their address or their email address.
//
// If you use more than one form, you can list fields from each of
// them or just use a common set.
//
// FormMail ignores empty or missing fields when performing this particular
// abuse detection. This means listing field names you don't actually
// have on a form is OK.
//
// If you don't want FormMail to perform this particular attack detection,
// set it to an empty array like this:
// $ATTACK_DETECTION_DUPS = array();
//
// Following is a list of common fields you might want FormMail to check
// for duplicate data. Use this unless you think it's valid for a user to put
// the same data in *any* of these fields. If your fields have different
// names, change the names.
//
// Do not list checkbox, radio button, or select fields that have
// simple values such as "yes", "no", "0", "1". Only list fields
// that will have long and unique values.
//
$ATTACK_DETECTION_DUPS = array("realname","address1","address2","country","zip",
"phone","postcode","state","email");
//
// ** LEAVE **
// Set ATTACK_DETECTION_SPECIALS to false if you don't want FormMail's
// attack detection to check for the "email address in a special field"
// attack.
//
define("ATTACK_DETECTION_SPECIALS",true);
//
// ** OPTIONAL **
// Set $GEOIP_LIC to the license key for your GeoIP account.
// GeoIP provides geographical positioning and other information
// about an IP address. You can use this for helping to detect
// credit card fraud, for example, by locating the form submitter's
// IP address and comparing it with their stated address (For example,
// "John Smith" submits your form and claims to be in Sydney
// Australia. But the GeoIP information indicates his actual IP address
// is in Pakistan!)
// For more information about GeoIP, go to:
// http://www.tectite.com/geoip.php
//
$GEOIP_LIC = ""; // default - no GeoIP
//
// ** OPTIONAL **
// Set ZERO_IS_EMPTY to false if you don't want a field containing
// exactly "0" (without the quotes) to be treated as empty.
//
// The default behaviour of PHP is to treat a field containing "0" as empty
// and this behaviour is what FormMail mimics by default.
//
// In many cases this is what you would want for a web form.
//
// By setting ZERO_IS_EMPTY to false, then a field must be completely
// empty to be treated as such.
//
// This setting affects "required" testing, "derived_fields" + operator,
// "conditions" testing, and template filling.
//
// References:
// http://au2.php.net/empty
// http://aspn.activestate.com/ASPN/docs/PHP/migration4.empty.html
//
// If you're upgrading FormMail through the Upgrade Wizard, the setting
// will be set to "true" to replicate previous behaviour. New FormMail
// downloads get the setting as "false".
//
define("ZERO_IS_EMPTY",false);
//
// ** OPTIONAL **
// Set SESSION_NAME to a non-empty string to get a unique PHP session for
// your FormMail processing. You only need to do this if your site
// is a PHP-based site that uses sessions.
//
// FormMail attaches to or creates a PHP session so it can pass error
// information to bad_url. On succcessful completion, and if you're not
// using good_url, FormMail destroys the session. If you use the default
// PHP session name on your site and within FormMail, this will cause any
// session information from your site to be discarded.
//
// In summary, you'll only have a problem with sessions, and need to
// set $SESSION_NAME if *all* the following statements are true:
// 1. Your website uses PHP sessions.
// 2. Your website's PHP session name is the default for PHP.
// 3. You do not specify "good_url" in your HTML form
//
// By specifying a unique name here, you avoid this problem. You should set
// the same name in FMBadHandler too, if you're using that script.
// Also, VerifyImg.php if you're using that.
//
$SESSION_NAME = "";
//
// ** OPTIONAL **
// Set $HOOK_DIR to a directory path on your server where you store
// include files for the FormMail Hook System.
//
// Note that this setting has to be a directory (folder) path, not a URL.
//
// If set to an empty string (the default), the Hook System is disabled.
//
$HOOK_DIR = "";
/* UPGRADE CONTROL
**
** FILTER_ATTRIBS:lt:4.00:no_keep:The FILTER_ATTRIBS configuration has
** been modified to include new information about the standard filters.:
**
** SET_REAL_DOCUMENT_ROOT:gt:4.07:copy_from=REAL_DOCUMENT_ROOT:The
** REAL_DOCUMENT_ROOT configuration has been renamed to SET_REAL_DOCUMENT_ROOT.:
**
** EMAIL_NAME:lt:6.01:no_keep:The EMAIL_NAME configuration has
** been modified to match hyphens ('-') in email addresses.:
**
** ZERO_IS_EMPTY:le:6.01:set_to=true:ZERO_IS_EMPTY has been
** set to a value that duplicates previous behaviour.:
**
** END OF CONTROL
*/
/*****************************************************************************/
/* END OF CONFIGURATION (do not alter this line in any way!!!) */
/*****************************************************************************/
//
// Hook system: before initialization (but after configuration)
//
if ($HOOK_DIR !== "")
@include("$HOOK_DIR/fmhookpreinit.inc");
if (!empty($SESSION_NAME))
session_name($SESSION_NAME);
session_start();
function ZapSession()
{
session_destroy();
}
if ($bUseOldVars)
$aSessionVars = &$HTTP_SESSION_VARS;
else
$aSessionVars = &$_SESSION;
$aSessionVars["FormError"] = NULL;
unset($aSessionVars["FormError"]); // start with no error
$aSessionVars["FormErrorInfo"] = NULL;
unset($aSessionVars["FormErrorInfo"]); // start with no error
$aSessionVars["FormErrorCode"] = NULL;
unset($aSessionVars["FormErrorCode"]); // start with no error
$aSessionVars["FormErrorItems"] = NULL;
unset($aSessionVars["FormErrorItems"]); // start with no error
$aSessionVars["FormData"] = NULL;
unset($aSessionVars["FormData"]); // start with no data
$aSessionVars["FormIsUserError"] = NULL;
unset($aSessionVars["FormIsUserError"]); // start with no data
$aSessionVars["FormAlerted"] = NULL;
unset($aSessionVars["FormAlerted"]); // start with no data
//
// Note that HTTP_REFERER is easily spoofed, so there's no point in
// using it for security.
//
//
// SPECIAL_FIELDS is the list of fields that formmail.php looks for to
// control its operation
//
$SPECIAL_FIELDS = array(
"email", // email address of the person who filled in the form
"realname", // the real name of the person who filled in the form
"recipients", // comma-separated list of email addresses to which we'll send the results
"cc", // comma-separated list of email addresses to which we'll CC the results
"bcc", // comma-separated list of email addresses to which we'll BCC the results
"required", // comma-separated list of fields that must be found in the input
"conditions", // complex condition tests
"fmcompute", // computations
"fmmodules", // list of modules required
"mail_options", // comma-separated list of options
"good_url", // URL to go to on success
"good_template",// template file to display on success
"bad_url", // URL to go to on error
"bad_template", // template file to display on error
"template_list_sep", // separator when expanding lists in templates
"this_form", // the URL of the form (can be used by bad_url)
"subject", // subject for the email
"env_report", // comma-separated list of environment variables to report
"filter", // a supported filter to use
"filter_options",// options for using the filter
"filter_fields",// list of fields to filter (default is to filter all fields)
"logfile", // log file to write to
"csvfile", // file to write CSV records to
"csvcolumns", // columns to save in the csvfile
"crm_url", // URL for sending data to the CRM; note that the
// value must have a valid prefix specified in TARGET_URLS
"crm_spec", // CRM specification (field mapping)
"crm_options", // comma-separated list of options to control CRM processing
"derive_fields", // a list of fields to derive from other fields
"file_names", // specifies names for files being uploaded
"autorespond", // specification for auto-responding
"arverify", // verification field to allow auto-responding
"imgverify", // verification field to allow submission
"multi_start", // set this field on the first page of a multi-page form sequence
"multi_keep", // set this field on the pages of a multi-page form sequence
// to the list of fields that should be kept when moving
// forward after going backwards
"next_form", // next form name or empty for last form
"multi_go_back",// this field should be set when the user clicks the
// back button or link in a multi-page form sequence
"alert_to"); // email address to send alerts (errors) to
//
// $SPECIAL_MULTI is the list of fields from $SPECIAL_FIELDS that can
// have multiple values, for example:
// name="conditions1"
// name="conditions2"
//
$SPECIAL_MULTI = array(
"conditions",
"fmcompute",
);
//
// $SPECIAL_NOSTRIP is the list of fields from $SPECIAL_FIELDS that
// should not be stripped (other than for magic_quotes_gpc reasons).
//
$SPECIAL_NOSTRIP = array(
"conditions",
"fmcompute",
);
//
// VALID_MAIL_OPTIONS lists the valid mail_options words
//
$VALID_MAIL_OPTIONS = array(
"AlwaysList"=>true,
"CharSet"=>true,
"DupHeader"=>true,
"Exclude"=>true,
"FromAddr"=>true,
"HTMLTemplate"=>true,
"KeepLines"=>true,
"NoEmpty"=>true,
"NoPlain"=>true,
"PlainTemplate"=>true,
"SendMailFOption"=>true,
"StartLine"=>true,
"TemplateMissing"=>true,
);
//
// VALID_CRM_OPTIONS lists the valid crm_options words
//
$VALID_CRM_OPTIONS = array(
"ErrorOnFail"=>true,
);
//
// VALID_AR_OPTIONS lists the valid autorespond words
//
$VALID_AR_OPTIONS = array(
"Subject"=>true,
"HTMLTemplate"=>true,
"PlainTemplate"=>true,
"TemplateMissing"=>true,
);
//
// VALID_FILTER_OPTIONS lists the valid filter_options words
//
$VALID_FILTER_OPTIONS = array(
"Attach"=>true,
"KeepInLine"=>true,
);
//
// SPECIAL_VALUES is set to the value of the fields we've found
// usage: $SPECIAL_VALUES["email"] is the value of the email field
//
$SPECIAL_VALUES = array();
//
// Array of mail options; set by the function 'ProcessMailOptions'
//
$MAIL_OPTS = array();
//
// Array of crm options; set by the function 'ProcessCRMOptions'
//
$CRM_OPTS = array();
//
// Array of autorespond options; set by the function 'ProcessAROptions'
//
$AR_OPTS = array();
//
// Array of filter options; set by the function 'ProcessFilterOptions'
//
$FILTER_OPTS = array();
//
// initialise $SPECIAL_VALUES so that we don't fail on using unset values
//
foreach ($SPECIAL_FIELDS as $sFieldName)
$SPECIAL_VALUES[$sFieldName] = "";
//
// Special defaults for some fields....
//
$SPECIAL_VALUES['template_list_sep'] = ",";
//
// FORMATTED_INPUT contains the input variables formatted nicely
// This is used for error reporting and debugging only.
//
$FORMATTED_INPUT = array();
//
// $FILTER_ATTRIBS_LOOKUP is the parsed $FILTER_ATTRIBS array
//
$FILTER_ATTRIBS_LOOKUP = array();
//
// $EMAIL_ADDRS is the array of email addresses from the $FORM_INI_FILE
//
$EMAIL_ADDRS = array();
//
// Access the www.tectite.com website to get the current version.
//
function CheckVersion()
{
global $FM_VERS;
$fp = fopen("http://www.tectite.com/fmversion.txt","r");
if ($fp !== false)
{
//
// version file looks like this:
// Version=versionumber
// Message=a message to send in the alert
//
$s_version = "";
$s_message = "";
$s_line = "";
$b_in_mesg = false;
while (!feof($fp))
{
$s_line = fgets($fp,1024);
if ($b_in_mesg)
$s_message .= $s_line;
else
{
$s_prefix = substr($s_line,0,8);
if ($s_prefix == "Message=")
{
$s_message .= substr($s_line,8);
$b_in_mesg = true;
}
elseif ($s_prefix == "Version=")
$s_version = substr($s_line,8);
}
}
fclose($fp);
$s_version = str_replace("\r","",$s_version);
$s_version = str_replace("\n","",$s_version);
$s_stop_mesg = GetMessage(MSG_END_VERS_CHK);
if ((float) $s_version > (float) $FM_VERS)
SendAlert(GetMessage(MSG_VERS_CHK,array(
"TECTITE"=>"www.tectite.com",
"FM_VERS"=>"$FM_VERS",
"NEWVERS"=>$s_version,
))."\n$s_message\n$s_stop_mesg",true,true);
}
}
//
// Check for new FormMail version
//
function Check4Update($s_chk_file,$s_id = "")
{
global $lNow,$php_errormsg;
@ $l_last_chk = filemtime($s_chk_file);
if ($l_last_chk === false || $lNow - $l_last_chk >= (CHECK_DAYS*24*60*60))
{
CheckVersion();
//
// update the check file's time stamp
//
@ $fp = fopen($s_chk_file,"w");
if ($fp !== false)
{
fwrite($fp,"FormMail version check ".
(empty($s_id) ? "" : "for identifier '$s_id' ").
"at ".date("H:i:s d-M-Y",$lNow)."\n");
fclose($fp);
}
else
SendAlert(GetMessage(MSG_CHK_FILE_ERROR,array("FILE"=>$s_chk_file,
"ERROR"=>CheckString($php_errormsg))));
}
}
//
// Perform various processing at the end of the script's execution.
//
function OnExit()
{
global $TARGET_EMAIL,$CHECK_FILE;
//
// Check the www.tectite.com website for a new version, but only
// do this check once every 3 days (or on server reboot).
//
if (CHECK_FOR_NEW_VERSION)
{
global $SERVER;
if (isset($TARGET_EMAIL[0]))
{
//
// use the first few characters of the MD5 of first email
// address pattern from $TARGET_EMAIL to get a unique file
// for the server
//
$s_id = "";
if (isset($SERVER) && !empty($SERVER))
$s_id = $SERVER;
$s_dir = GetTempDir();
$s_md5 = md5($TARGET_EMAIL[0]);
$s_uniq = substr($s_md5,0,6);
$s_chk_file = "fm"."$s_uniq".".txt";
Check4Update($s_dir."/".$s_chk_file,$s_id);
}
}
}
register_shutdown_function('OnExit');
//
// Return the array with each string urlencode'd.
//
function URLEncodeArray($a_array)
{
foreach ($a_array as $m_key=>$s_str)
{
//
// only encode the value after the '='
//
if (($i_pos = strpos($s_str,'=')) !== false)
$a_array[$m_key] = substr($s_str,0,$i_pos+1).
urlencode(substr($s_str,$i_pos+1));
else
$a_array[$m_key] = urlencode($s_str);
}
return ($a_array);
}
//
// Add a parameter or list of parameters to a URL.
//
function AddURLParams($s_url,$m_params,$b_encode = true)
{
if (!empty($m_params))
{
if (!is_array($m_params))
$m_params = array($m_params);
if (strpos($s_url,'?') === false)
$s_url .= '?';
else
$s_url .= '&';
$s_url .= implode('&',($b_encode) ? URLEncodeArray($m_params) : $m_params);
}
return ($s_url);
}
//
// Recursively trim an array of strings (non string values are converted
// to a string first).
//
function TrimArray($a_list)
{
foreach ($a_list as $m_key=>$m_item)
if (is_array($m_item))
$a_list[$m_key] = TrimArray($m_item);
elseif (is_scalar($m_item))
$a_list[$m_key] = trim("$m_item");
else
$a_list[$m_key] = "";
return ($a_list);
}
//
// Parse a derivation specification and return an array of
// field names and operators.
//
function ParseDerivation($a_form_data,$s_fld_spec,$s_name,&$a_errors)
{
$a_deriv = array();
while (($i_len = strlen($s_fld_spec)) > 0)
{
//
// we support the following operators:
// + concatenate with a single space between, but skip the space
// if the next field is empty
// * concatenate with a single space between
// . concatenate with no space between
//
$i_span = strcspn($s_fld_spec,'+*.');
if ($i_span == 0)
{
$a_errors[] = $s_name;
return (false);
}
$a_deriv[] = trim(substr($s_fld_spec,0,$i_span));
if ($i_span < $i_len)
{
$a_deriv[] = substr($s_fld_spec,$i_span,1);
$s_fld_spec = substr($s_fld_spec,$i_span+1);
}
else
$s_fld_spec = "";
}
return ($a_deriv);
}
//
// Test if a character is an alphabetic.
//
function IsAlpha($ch)
{
return (strpos("abcdefghijklmnopqrstuvwxyz",strtolower($ch)) !== false);
}
//
// Test if a character is a digit.
//
function IsNumeric($ch)
{
return (strpos("0123456789",$ch) !== false);
}
//
// Test if a character is an alphanumeric
//
function IsAlnum($ch)
{
return (IsAlpha($ch) || IsNumeric($ch));
}
//
// Return an array of tokens extracted from the given string.
// A token is:
// - a word (begins with alpha or _, and is followed by any number
// of alphanumerics or _ chars)
// - a number (any number of consecutive digits with up to one period)
// - a string enclosed in specified quotes (this can be disabled)
// - any punctuation character
//
// Anything not matching the above is silently ignored!
//
function GetTokens($s_str,$s_quotes = "'\"")
{
$b_allow_strings = ($s_quotes !== "") ? true : false;
$ii = 0;
$i_len = strlen($s_str);
$a_toks = array();
while ($ii < $i_len)
{
switch ($ch = $s_str{$ii})
{
case " ":
case "\t":
case "\n":
case "\r":
$ii++;
continue;
}
//
// start of a token
//
$i_start = $ii;
if ($ch == "_" || IsAlpha($ch))
{
//
// a word
//
$i_count = 1;
while (++$ii < $i_len &&
($s_str{$ii} == "_" || IsAlnum($s_str{$ii})))
++$i_count;
$a_toks[] = substr($s_str,$i_start,$i_count);
}
elseif (($ch == "." && $ii < ($i_len-1) && IsNumeric($s_str{$ii+1}))||
IsNumeric($ch))
{
//
// a number
//
$b_had_dot = ($ch == ".");
$i_count = 1;
while (++$ii < $i_len)
{
if (IsNumeric($s_str{$ii}))
++$i_count;
elseif ($s_str{$ii} == "." && !$b_had_dot)
{
++$i_count;
$b_had_dot = true;
}
else
break;
}
$a_toks[] = substr($s_str,$i_start,$i_count);
}
elseif ($b_allow_strings && strpos($s_quotes,$ch) !== false)
{
$c_quote = $ch;
//
// a quoted string
//
while (++$ii < $i_len)
{
if ($s_str{$ii} == $c_quote)
{
++$ii; // include the terminating quote
break;
}
}
$a_toks[] = substr($s_str,$i_start,$ii-$i_start);
}
else
{
$s_punct = "~!@#$%^&*()-+={}[]|:;<>,.?/`\\";
if (!$b_allow_strings)
$s_punct .= "'\"";
if (strpos($s_punct,$ch) !== false)
$a_toks[] = $ch;
++$ii;
}
}
return ($a_toks);
}
//
// Return the value from a derive_fields specification.
// Specifications are in this format:
// %info%
// where info is a predefined word or a literal in quotes
// (e.g. 'the time is ')
//
function ValueSpec($s_spec,$a_form_data,&$a_errors)
{
global $lNow;
$s_value = "";
switch (trim($s_spec))
{
case 'date': // "standard" date format: DD-MMM-YYYY
$s_value = date('d-M-Y',$lNow);
break;
case 'time': // "standard" time format: HH:MM:SS
$s_value = date('H:i:s',$lNow);
break;
case 'ampm': // am or pm
$s_value = date('a',$lNow);
break;
case 'AMPM': // AM or PM
$s_value = date('A',$lNow);
break;
case 'dom0': // day of month with possible leading zero
$s_value = date('d',$lNow);
break;
case 'dom': // day of month with no leading zero
$s_value = date('j',$lNow);
break;
case 'day': // day name (abbreviated)
$s_value = date('D',$lNow);
break;
case 'dayname': // day name (full)
$s_value = date('l',$lNow);
break;
case 'daysuffix': // day number suffix for English (st for 1st, nd for 2nd, etc.)
$s_value = date('S',$lNow);
break;
case 'moy0': // month of year with possible leading zero
$s_value = date('m',$lNow);
break;
case 'moy': // month of year with no leading zero
$s_value = date('n',$lNow);
break;
case 'month': // month name (abbreviated)
$s_value = date('M',$lNow);
break;
case 'monthname': // month name (full)
$s_value = date('F',$lNow);
break;
case 'year': // year (two digits)
$s_value = date('y',$lNow);
break;
case 'fullyear': // year (full)
$s_value = date('Y',$lNow);
break;
case 'rfcdate': // date formatted according to RFC 822
$s_value = date('r',$lNow);
break;
case 'tzname': // timezone name
$s_value = date('T',$lNow);
break;
case 'tz': // timezone difference from Greenwich +NNNN or -NNNN
$s_value = date('O',$lNow);
break;
case 'hour120': // hour of day (01-12) with possible leading zero
$s_value = date('h',$lNow);
break;
case 'hour240': // hour of day (00-23) with possible leading zero
$s_value = date('H',$lNow);
break;
case 'hour12': // hour of day (1-12) with no leading zero
$s_value = date('g',$lNow);
break;
case 'hour24': // hour of day (0-23) with no leading zero
$s_value = date('G',$lNow);
break;
case 'min': // minute of hour (00-59)
$s_value = date('i',$lNow);
break;
case 'sec': // seconds of minute (00-59)
$s_value = date('s',$lNow);
break;
default:
if ($s_spec{0} == "'")
{
//
// to get a quote, use 3 quotes:
// '''
//
if ($s_spec == "'''")
$s_value = "'";
elseif (substr($s_spec,-1,1) == "'")
$s_value = substr($s_spec,1,-1);
else
//
// missing final quote is OK
//
$s_value = substr($s_spec,1);
}
elseif (strspn($s_spec,"0123456789ABCDEF") == 2)
{
//
// insert the ASCII character corresponding to
// the hexadecimal value
//
$i_val = intval(substr($s_spec,0,2),16);
$s_value = chr($i_val);
}
else
{
//
// look for supported functions, start by getting all
// the tokens
//
$a_toks = GetTokens($s_spec);
if (count($a_toks) > 0)
{
switch ($a_toks[0])
{
case "if":
//
// "if" function: test first field
// if not empty, then use second field
// else, use third field
//
// Example: if(fld1 ; fld2 ; fld3)
//
// tokens are:
// 1 (
// 2 the field name to test (first)
// 3 ;
// 4 the "then" spec (can be missing)
// 5 ;
// 6 the "else" spec (can be missing)
// 7 )
//
if (($n_tok = count($a_toks)) < 6 ||
$a_toks[1] != "(" ||
$a_toks[3] != ";" ||
$a_toks[$n_tok-1] != ")")
SendAlert(GetMessage(MSG_DER_FUNC_ERROR,
array("SPEC"=>$s_spec,
"MSG"=>GetMessage(MSG_DER_FUNC_IF_FMT))));
else
{
$b_ok = true;
$s_fld_name = $a_toks[2];
$s_then_spec = $s_else_spec = "";
for ($ii = 4 ; $ii < $n_tok && $a_toks[$ii] != ';' ; $ii++)
$s_then_spec .= $a_toks[$ii];
if ($ii == $n_tok)
$b_ok = false;
else
{
//
// Concatenate tokens until the ')'.
// This provides the "else" spec.
//
for ( ; ++$ii < $n_tok && $a_toks[$ii] != ')' ; )
$s_else_spec .= $a_toks[$ii];
if ($ii == $n_tok)
$b_ok = false;
}
if ($b_ok)
{
if (!TestFieldEmpty($s_fld_name,$a_form_data,$s_mesg))
$s_fld_spec = $s_then_spec;
else
$s_fld_spec = $s_else_spec;
$s_value = GetDerivedValue($a_form_data,$s_fld_spec);
}
else
SendAlert(GetMessage(MSG_DER_FUNC_ERROR,
array("SPEC"=>$s_spec,
"MSG"=>GetMessage(MSG_DER_FUNC_IF_FMT))));
}
break;
case "size":
if (count($a_toks) != 4 ||
$a_toks[1] != "(" ||
$a_toks[3] != ")")
SendAlert(GetMessage(MSG_DER_FUNC_ERROR,
array("SPEC"=>$s_spec,
"MSG"=>GetMessage(MSG_DER_FUNC_SIZE_FMT))));
elseif (($i_size = GetFileSize($a_toks[2])) !== false)
$s_value = "$i_size";
break;
default:
SendAlert(GetMessage(MSG_UNK_VALUE_SPEC,
array("SPEC"=>$s_spec,"MSG"=>"")));
break;
}
}
else
SendAlert(GetMessage(MSG_UNK_VALUE_SPEC,array("SPEC"=>$s_spec,
"MSG"=>"")));
}
break;
}
return ($s_value);
}
//
// Return the value of an object or array as a string.
//
function GetObjectAsString($m_value)
{
ob_start();
print_r($m_value);
$s_ret = ob_get_contents();
ob_end_clean();
return ($s_ret);
}
//
// Return a Server or Environment variable value. Returns false if
// not found, otherwise a string value.
//
function GetEnvValue($s_name)
{
global $aServerVars,$aEnvVars;
if (isset($aEnvVars[$s_name]))
$m_value = $aEnvVars[$s_name];
elseif (isset($aServerVars[$s_name]))
$m_value = $aServerVars[$s_name];
//
// some values might not be strings - so convert
//
if (isset($m_value) && !is_scalar($m_value))
$m_value = GetObjectAsString($m_value);
return (isset($m_value) ? ((string) $m_value) : false);
}
//
// Same as "empty" but checks for true emptiness if ZERO_IS_EMPTY is
// set to false.
//
function IsFieldEmpty($s_value)
{
if (ZERO_IS_EMPTY || is_array($s_value))
return (empty($s_value));
else
return ($s_value === "");
}
//
// Test if a field is set in the given vars array or in the uploaded
// files.
//
function IsFieldSet($s_fld,$a_main_vars)
{
global $aFileVars;
return (isset($a_main_vars[$s_fld]) ||
(FILEUPLOADS && isset($aFileVars[$s_fld])));
}
//
// Return the info for the uploaded file, or false on error.
//
function GetFileInfo($s_fld)
{
global $aFileVars;
if (FILEUPLOADS && isset($aFileVars[$s_fld]))
{
$a_upload = $aFileVars[$s_fld];
if (isset($a_upload['tmp_name']) && !empty($a_upload['tmp_name']) &&
isset($a_upload['name']) && !empty($a_upload['name']))
{
//
// $a_upload['moved'] is our own internal flag to say we've
// saved the file
//
if ((isset($a_upload['moved']) && $a_upload['moved']) ||
is_uploaded_file($a_upload['tmp_name']))
return ($a_upload);
}
}
return (false);
}
//
// Return the original name of the uploaded file or false on error.
//
function GetFileName($s_fld)
{
if (($a_upload = GetFileInfo($s_fld)) !== false)
return ($a_upload['name']);
return (false);
}
//
// Return the size of the uploaded file or false on error.
//
function GetFileSize($s_fld)
{
if (($a_upload = GetFileInfo($s_fld)) !== false)
return ($a_upload['size']);
return (false);
}
//
// Return a field value. Empty string is returned if the field is
// not found. File fields return the original name of the uploaded file.
//
function GetFieldValue($s_fld,$a_main_vars)
{
if (!isset($a_main_vars[$s_fld]))
{
if (($s_name = GetFileName($s_fld)) === false)
$s_name = "";
return ($s_name);
}
return ((string) $a_main_vars[$s_fld]);
}
//
// Tests a field against an array of vars for emptyness.
// If the var isn't found there, then the POSTed files array is checked.
// Returns true if the field is empty (a specific error may
// be returned in the $s_mesg parameter).
//
function TestFieldEmpty($s_fld,$a_main_vars,&$s_mesg)
{
global $aFileVars;
$s_mesg = "";
$b_empty = TRUE;
if (!isset($a_main_vars[$s_fld]))
{
//
// Each file var is an array with these elements:
// 'name' => The original name of the file on the client machine.
// 'type' => The mime type of the file, if the browser provided this information.
// 'tmp_name' => The temporary filename of the file in which the uploaded file was stored on the server.
// 'error' => The error code associated with this file upload.
// NOTE: 'error' was added in PHP 4.2.0
// 'size' => The size, in bytes, of the uploaded file.
//
// Error codes (the constants are only available from PHP 4.3.0 so
// we have to use the raw numbers):
// UPLOAD_ERR_OK
// Value: 0; There is no error, the file uploaded with success.
// UPLOAD_ERR_INI_SIZE
// Value: 1; The uploaded file exceeds the upload_max_filesize directive in php.ini.
// UPLOAD_ERR_FORM_SIZE
// Value: 2; The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the html form.
// UPLOAD_ERR_PARTIAL
// Value: 3; The uploaded file was only partially uploaded.
// UPLOAD_ERR_NO_FILE
// Value: 4; No file was uploaded.
//
if (FILEUPLOADS && isset($aFileVars[$s_fld]))
{
$a_upload = $aFileVars[$s_fld];
if (isset($a_upload['tmp_name']) && !empty($a_upload['tmp_name']) &&
isset($a_upload['name']) && !empty($a_upload['name']))
{
//
// $a_upload['moved'] is our own internal flag to say we've
// saved the file
//
if ((isset($a_upload['moved']) && $a_upload['moved']) ||
is_uploaded_file($a_upload['tmp_name']))
$b_empty = false;
}
if ($b_empty && isset($a_upload['error']))
switch ($a_upload['error'])
{
case 1:
$s_mesg = GetMessage(MSG_FILE_UPLOAD_ERR1);
break;
case 2:
$s_mesg = GetMessage(MSG_FILE_UPLOAD_ERR2);
break;
case 3:
$s_mesg = GetMessage(MSG_FILE_UPLOAD_ERR3);
break;
case 4:
$s_mesg = GetMessage(MSG_FILE_UPLOAD_ERR4);
break;
default:
$s_mesg = GetMessage(MSG_FILE_UPLOAD_ERR_UNK,
array("ERRNO"=>$a_upload['error']));
break;
}
}
}
else
$b_empty = IsFieldEmpty($a_main_vars[$s_fld]);
return ($b_empty);
}
//
// Return a derived field value or value specification.
//
function GetDerivedValue($a_form_data,$s_word,&$a_errors)
{
global $aFileVars;
$s_value = "";
//
// a field name or a value specification
// value specifications have the following format:
// %spec%
//
if (substr($s_word,0,1) == '%')
{
if (substr($s_word,-1,1) != '%')
{
SendAlert(GetMessage(MSG_INV_VALUE_SPEC,array("SPEC"=>$s_word)));
$s_value = $s_word;
}
else
{
$s_spec = substr($s_word,1,-1);
$s_value = ValueSpec($s_spec,$a_form_data,$a_errors);
}
}
else
{
$s_fld_name = $s_word;
//
// try form data first, then the environment/server data
//
if (IsFieldSet($s_fld_name,$a_form_data))
$s_value = GetFieldValue($s_fld_name,$a_form_data);
elseif (($s_value = GetEnvValue($s_fld_name)) === false)
$s_value = "";
$s_value = trim($s_value);
}
return ($s_value);
}
//
// Derive a value from the form data using the specification returned
// from ParseDerivation.
//
function DeriveValue($a_form_data,$a_value_spec,$s_name,&$a_errors)
{
$s_value = "";
for ($ii = 0 ; $ii < count($a_value_spec) ; $ii++)
{
switch ($a_value_spec[$ii])
{
case '+':
//
// concatenate with a single space between, but skip the space
// if the next field is empty
//
if ($ii < count($a_value_spec)-1)
{
$s_temp = GetDerivedValue($a_form_data,$a_value_spec[$ii+1],$a_errors);
if (!IsFieldEmpty($s_temp))
$s_value .= ' ';
}
break;
case '.':
//
// concatenate with no space between
//
break;
case '*':
//
// concatenate with a single space between
//
$s_value .= ' ';
break;
default:
//
// a field name or a value specification
// value specifications have the following format:
// %name%
//
$s_value .= GetDerivedValue($a_form_data,$a_value_spec[$ii],$a_errors);
break;
}
}
return ($s_value);
}
//
// Create derived fields specified by the "derive_fields" value.
//
function CreateDerived($a_form_data)
{
if (isset($a_form_data["derive_fields"]))
{
$a_errors = array();
//
// get the list of derived field specifications
//
$a_list = TrimArray(explode(",",$a_form_data["derive_fields"]));
foreach ($a_list as $s_fld_spec)
{
if ($s_fld_spec === "")
//
// silently ignore empty derivations
//
continue;
if (($i_pos = strpos($s_fld_spec,"=")) === false)
{
$a_errors[] = $s_fld_spec;
continue;
}
$s_name = trim(substr($s_fld_spec,0,$i_pos));
$s_fld_spec = substr($s_fld_spec,$i_pos+1);
if (($a_value_spec = ParseDerivation($a_form_data,$s_fld_spec,
$s_name,$a_errors)) === false)
break;
$a_form_data[$s_name] = DeriveValue($a_form_data,$a_value_spec,$s_name,$a_errors);
}
if (count($a_errors) > 0)
{
SendAlert(GetMessage(MSG_DERIVED_INVALID).implode("\n",$a_errors));
Error("derivation_failure",GetMessage(MSG_INT_FORM_ERROR));
}
}
return ($a_form_data);
}
//
// To process the name specification for files and update the
// array of file variables accordingly.
//
function SetFileNames($s_name_spec,$a_order,$a_fields,$a_raw_fields,$a_file_vars)
{
$a_errors = array();
//
// get the list of file name derivations
//
$a_list = TrimArray(explode(",",$s_name_spec));
foreach ($a_list as $s_fld_spec)
{
if ($s_fld_spec === "")
//
// silently ignore empty file name derivations
//
continue;
if (($i_pos = strpos($s_fld_spec,"=")) === false)
{
$a_errors[] = $s_fld_spec;
continue;
}
$s_name = trim(substr($s_fld_spec,0,$i_pos));
$s_fld_spec = substr($s_fld_spec,$i_pos+1);
if (($a_value_spec = ParseDerivation($a_raw_fields,$s_fld_spec,
$s_name,$a_errors)) === false)
break;
if (isset($a_file_vars[$s_name]) && is_array($a_file_vars[$s_name]))
{
//
// we create our own special entry in the file variable's data
//
$a_file_vars[$s_name]['new_name'] = DeriveValue($a_raw_fields,
$a_value_spec,$s_name,
$a_errors);
//
// we also create (derive) a new field called 'name_of_X'
// where X is the file fields's name
//
ProcessField("name_of_$s_name",$a_file_vars[$s_name]['new_name'],
$a_order,$a_fields,$a_raw_fields);
}
else
SendAlert(GetMessage(MSG_FILE_NAMES_NOT_FILE,
array("NAME"=>$s_name)));
}
if (count($a_errors) > 0)
{
SendAlert(GetMessage(MSG_FILE_NAMES_INVALID).implode("\n",$a_errors));
Error("file_names_derivation_failure",GetMessage(MSG_INT_FORM_ERROR));
}
return (array($a_order,$a_fields,$a_raw_fields,$a_file_vars));
}
//
// Process a list of attributes or options.
// Format for each attribute/option:
// name
// or
// name=value
//
// Values can be simple values or semicolon (;) separated lists:
// avalue
// value1;value2;value3;...
//
// Returns attribute/options in the associative array $a_attribs.
// Optionally, valid attributes can be provided in $a_valid_attribs
// (if empty, all attributes found are considered valid).
// Errors are returned in $a_errors.
//
function ProcessAttributeList($a_list,&$a_attribs,&$a_errors,
$a_valid_attribs = array())
{
$b_got_valid_list = (count($a_valid_attribs) > 0);
foreach ($a_list as $s_attrib)
{
//
// if the name begins with '.' then silently ignore it;
// this allows you to temporarily disable an option without
// getting an alert message
//
if (($i_pos = strpos($s_attrib,"=")) === false)
{
$s_name = trim($s_attrib);
if (empty($s_name) || $s_name{0} == '.')
continue;
//
// option is a simple "present" value
//
$a_attribs[$s_name] = true;
}
else
{
$s_name = trim(substr($s_attrib,0,$i_pos));
if (empty($s_name) || $s_name{0} == '.')
continue;
$s_value_list = substr($s_attrib,$i_pos+1);
if (($i_pos = strpos($s_value_list,";")) === false)
//
// single value
//
$a_attribs[$s_name] = trim($s_value_list);
else
//
// list of values
//
$a_attribs[$s_name] = TrimArray(explode(";",$s_value_list));
}
if ($b_got_valid_list && !isset($a_valid_attribs[$s_name]))
$a_errors[] = $s_name;
}
}
//
// Process the options specified in the form.
// Options can be specified in this format:
// option1,option2,option3,...
// Each option can be a simple word or a word and value:
// name
// name=value
// No name or value can contain a comma.
// Values can be simple values or semicolon (;) separated lists:
// avalue
// value1;value2;value3;...
// No value can contain a semicolon.
// Be careful of values beginning and ending with whitespace characters;
// they will be trimmed.
//
function ProcessOptions($s_name,$a_form_data,&$a_options,$a_valid_options)
{
$a_errors = array();
$a_options = array();
if (isset($a_form_data[$s_name]))
{
//
// get the options list and trim each one
//
$a_list = TrimArray(explode(",",$a_form_data[$s_name]));
ProcessAttributeList($a_list,$a_options,$a_errors,$a_valid_options);
}
if (count($a_errors) > 0)
SendAlert(GetMessage(MSG_OPTIONS_INVALID,array("OPT"=>$s_name)).
implode("\n",$a_errors));
}
//
// Process the mail_options specified in the form.
//
function ProcessMailOptions($a_form_data)
{
global $MAIL_OPTS,$VALID_MAIL_OPTIONS;
ProcessOptions("mail_options",$a_form_data,$MAIL_OPTS,$VALID_MAIL_OPTIONS);
}
//
// Check if an option is set
//
function IsMailOptionSet($s_name)
{
global $MAIL_OPTS;
return (isset($MAIL_OPTS[$s_name]));
}
//
// Return an option's value or NULL if not set.
//
function GetMailOption($s_name)
{
global $MAIL_OPTS;
return (isset($MAIL_OPTS[$s_name]) ? $MAIL_OPTS[$s_name] : NULL);
}
//
// Process the crm_options specified in the form.
//
function ProcessCRMOptions($a_form_data)
{
global $CRM_OPTS,$VALID_CRM_OPTIONS;
ProcessOptions("crm_options",$a_form_data,$CRM_OPTS,$VALID_CRM_OPTIONS);
}
//
// Check if an option is set
//
function IsCRMOptionSet($s_name)
{
global $CRM_OPTS;
return (isset($CRM_OPTS[$s_name]));
}
//
// Return an option's value or NULL if not set.
//
function GetCRMOption($s_name)
{
global $CRM_OPTS;
return (isset($CRM_OPTS[$s_name]) ? $CRM_OPTS[$s_name] : NULL);
}
//
// Check if a field is in the mail exclusion list.
//
function IsMailExcluded($s_name)
{
$a_list = GetMailOption("Exclude");
if (!isset($a_list))
return (false);
if (is_array($a_list))
return (in_array($s_name,$a_list));
else
return ($s_name === $a_list);
}
//
// Process the autorespond specified in the form.
//
function ProcessAROptions($a_form_data)
{
global $AR_OPTS,$VALID_AR_OPTIONS;
ProcessOptions("autorespond",$a_form_data,$AR_OPTS,$VALID_AR_OPTIONS);
}
//
// Check if an option is set
//
function IsAROptionSet($s_name)
{
global $AR_OPTS;
return (isset($AR_OPTS[$s_name]));
}
//
// Return an option's value or NULL if not set.
//
function GetAROption($s_name)
{
global $AR_OPTS;
return (isset($AR_OPTS[$s_name]) ? $AR_OPTS[$s_name] : NULL);
}
//
// Process the mail_options specified in the form.
//
function ProcessFilterOptions($a_form_data)
{
global $FILTER_OPTS,$VALID_FILTER_OPTIONS;
ProcessOptions("filter_options",$a_form_data,$FILTER_OPTS,$VALID_FILTER_OPTIONS);
}
//
// Check if an option is set
//
function IsFilterOptionSet($s_name)
{
global $FILTER_OPTS;
return (isset($FILTER_OPTS[$s_name]));
}
//
// Return an option's value or NULL if not set.
//
function GetFilterOption($s_name)
{
global $FILTER_OPTS;
return (isset($FILTER_OPTS[$s_name]) ? $FILTER_OPTS[$s_name] : NULL);
}
//
// Lookup a filter attribute for the given filter.
// Return it's value or false if not set.
//
function GetFilterAttrib($s_filter,$s_attrib)
{
global $FILTER_ATTRIBS,$FILTER_ATTRIBS_LOOKUP;
if (!isset($FILTER_ATTRIBS[$s_filter]))
//
// no attributes for the filter
//
return (false);
if (!isset($FILTER_ATTRIBS_LOOKUP[$s_filter]))
{
//
// the attributes have not yet been parsed - create the lookup table
//
$a_list = TrimArray(explode(",",$FILTER_ATTRIBS[$s_filter]));
$FILTER_ATTRIBS_LOOKUP[$s_filter] = array();
$a_errors = array();
ProcessAttributeList($a_list,$FILTER_ATTRIBS_LOOKUP[$s_filter],$a_errors);
}
//
// perform the lookup and return the value
//
if (!isset($FILTER_ATTRIBS_LOOKUP[$s_filter][$s_attrib]))
return (false);
return ($FILTER_ATTRIBS_LOOKUP[$s_filter][$s_attrib]);
}
//
// Check the filter attributes for the given filter.
// Return true if the given attribute is set otherwise false.
//
function IsFilterAttribSet($s_filter,$s_attrib)
{
return (GetFilterAttrib($s_filter,$s_attrib));
}
//
// Process the given .ini file.
//
function ProcessFormIniFile($s_file)
{
global $EMAIL_ADDRS;
$a_sections = parse_ini_file($s_file,TRUE);
if (DB_SEE_INI)
{
//
// just display the ini file
//
$s_text = "The following settings were found in the file '$s_file':
";
foreach ($a_sections as $s_sect=>$a_settings)
{
$s_text .= "[$s_sect]\n";
foreach ($a_settings as $s_name=>$s_value)
$s_text .= "$s_name = \"$s_value\"\n";
$s_text .= "
";
}
CreatePage($s_text);
exit;
}
//
// Load the email_addresses section.
//
if (isset($a_sections["email_addresses"]))
$EMAIL_ADDRS = $a_sections["email_addresses"];
//
// Process special fields
//
if (isset($a_sections["special_fields"]))
{
foreach ($a_sections["special_fields"] as $s_name=>$m_value)
{
if (IsSpecialField($s_name))
SetSpecialField($s_name,$m_value);
//
// check for multiple valued special fields
//
if (($a_multi_fld = IsSpecialMultiField($s_name)) !== false)
SetSpecialMultiField($a_multi_fld[0],$a_multi_fld[1],$m_value);
}
}
}
//
// UnMangle an email address
//
function UnMangle($email)
{
global $EMAIL_ADDRS;
//
// map from a name to the real email address
//
if (isset($EMAIL_ADDRS[$email]))
$email = $EMAIL_ADDRS[$email];
//
// unmangle
//
if (AT_MANGLE != "")
$email = str_replace(AT_MANGLE,"@",$email);
return ($email);
}
//
// Check a list of email addresses (comma separated); returns a list
// of valid email addresses (comma separated).
// The return value is true if there is at least one valid email address.
//
function CheckEmailAddress($s_addr,&$s_valid,&$s_invalid)
{
global $TARGET_EMAIL;
$s_invalid = $s_valid = "";
$a_list = TrimArray(explode(",",$s_addr));
$a_invalid = array();
for ($ii = 0 ; $ii < count($a_list) ; $ii++)
{
$s_email = UnMangle($a_list[$ii]);
//
// UnMangle works with INI files too, and a single
// word can expand to a list of email addresses.
//
$a_this_list = TrimArray(explode(",",$s_email));
foreach ($a_this_list as $s_email)
{
$b_is_valid = false;
for ($jj = 0 ; $jj < count($TARGET_EMAIL) ; $jj++)
if (eregi($TARGET_EMAIL[$jj],$s_email))
{
if (empty($s_valid))
$s_valid = $s_email;
else
$s_valid .= ",".$s_email;
$b_is_valid = true;
break;
}
if (!$b_is_valid)
$a_invalid[] = $s_email;
}
}
if (count($a_invalid) > 0)
$s_invalid = implode(",",$a_invalid);
return (!empty($s_valid));
}
//
// Redirect to another URL
//
function Redirect($url)
{
//
// for browsers without cookies enabled, append the Session ID
//
if (defined("SID"))
$url = AddURLParams($url,SID);
//
// this is probably a good idea to ensure the session data
// is written away
//
if (function_exists('session_write_close'))
session_write_close();
header("Location: $url");
//
// if the header doesn't work, try JavaScript.
// if that doesn't work, provide a manual link
//
$s_text = GetMessage(MSG_PLSWAIT_REDIR)."\n\n";
$s_text .= "";
$s_text .= "\n\n".GetMessage(MSG_IFNOT_REDIR,array("URL"=>$url));
CreatePage($s_text);
exit;
}
//
// JoinLines is just like "implode" except that it checks
// the end of each array for the separator already being
// there. This allows us to join a mixture of mail
// header lines (already terminated) with body lines.
// This logic works if HEAD_CRLF, for example, is the same
// as BODY_LF (i.e. both "\r\n") or if BODY_LF is the
// same as the last character in HEAD_CRLF (i.e.
// HEAD_CRLF = "\r\n" and BODY_LF = "\n").
// Other value combinations may break things.
//
function JoinLines($s_sep,$a_lines)
{
$s_str = "";
if (($i_sep_len = strlen($s_sep)) == 0)
//
// no separator
//
return (implode("",$a_lines));
$n_lines = count($a_lines);
for ($ii = 0 ; $ii < $n_lines ; $ii++)
{
$s_line = $a_lines[$ii];
if (substr($s_line,-$i_sep_len) == $s_sep)
$s_str .= $s_line;
else
{
$s_str .= $s_line;
//
// don't append a separator to the last line
//
if ($ii < $n_lines-1)
$s_str .= $s_sep;
}
}
return ($s_str);
}
//
// Expands an array of mail headers into mail header lines.
//
function ExpandMailHeaders($a_headers)
{
$s_hdrs = "";
foreach ($a_headers as $s_name=>$s_value)
if ($s_name != "")
{
if ($s_hdrs != "")
$s_hdrs .= HEAD_CRLF;
$s_hdrs .= $s_name.": ".$s_value;
}
return ($s_hdrs);
}
//
// Expands an array of mail headers into an array containing header lines.
//
function ExpandMailHeadersArray($a_headers)
{
$a_hdrs = array();
foreach ($a_headers as $s_name=>$s_value)
if ($s_name != "")
$a_hdrs[] = $s_name.": ".$s_value.HEAD_CRLF;
return ($a_hdrs);
}
//
// Low-level email send function; either calls PHP's mail function
// or uses the PEAR Mail object.
// NOTE: for some errors, there's no point trying to email
// an alert message! So, in these cases, we just display the error to
// the user.
//
function DoMail($s_to,$s_subject,$s_mesg,$a_headers)
{
global $PEAR_SMTP_HOST,$PEAR_SMTP_PORT,$PEAR_SMTP_USER,$PEAR_SMTP_PWD;
if (isset($PEAR_SMTP_HOST) && !empty($PEAR_SMTP_HOST))
{
require_once("Mail.php");
$a_params = array( "host"=>$PEAR_SMTP_HOST,
"port"=>$PEAR_SMTP_PORT);
if (isset($PEAR_SMTP_USER) && !empty($PEAR_SMTP_USER))
{
$a_params["auth"] = TRUE;
$a_params["username"] = $PEAR_SMTP_USER;
$a_params["password"] = $PEAR_SMTP_PWD;
}
$mailer = Mail::factory("smtp",$a_params);
if (!is_object($mailer))
{
ShowError("pear_error",GetMessage(MSG_PEAR_OBJ),FALSE,FALSE);
exit;
}
if (get_class($mailer) === 'pear_error')
{
ShowError("pear_error",$mailer->getMessage(),FALSE,FALSE);
exit;
}
if (!isset($a_headers['To']) && !isset($a_headers['to']))
$a_headers['To'] = $s_to;
if (!isset($a_headers['Subject']) && !isset($a_headers['subject']))
$a_headers['Subject'] = $s_subject;
$res = $mailer->send($s_to,$a_headers,$s_mesg);
if ($res === TRUE)
return (TRUE);
global $aAlertInfo;
$aAlertInfo[] = GetMessage(MSG_PEAR_ERROR,array("MSG"=>$res->getMessage()));
return (FALSE);
}
return (mail($s_to,$s_subject,$s_mesg,ExpandMailHeaders($a_headers)));
}
//
// Send an email
//
function SendCheckedMail($to,$subject,$mesg,$sender,$a_headers = array())
{
global $PEAR_SMTP_HOST;
$b_f_option = false;
$b_form_option = IsMailOptionSet("SendMailFOption"); // this is superseded, but still supported
if (SENDMAIL_F_OPTION || $b_form_option)
{
if (empty($sender))
{
//
// SENDMAIL_F_OPTION with no sender is silently ignored
//
if ($b_form_option)
{
//
// form has specified SendMailFOption, but there's no
// sender address
//
static $b_in_here = false;
global $SERVER;
if (!$b_in_here) // prevent infinite recursion
{
$b_in_here = true;
SendAlert(GetMessage(MSG_NO_FOPT_ADDR));
$b_in_here = false;
}
//
// if there's no from address, create a dummy one
//
$sender = "dummy@".(isset($SERVER) ? $SERVER : "UnknownServer");
$a_headers['From'] = $sender;
$b_f_option = true;
}
}
else
$b_f_option = true;
}
if (INI_SET_FROM && !empty($sender))
ini_set('sendmail_from',$sender);
if ((!isset($PEAR_SMTP_HOST) || empty($PEAR_SMTP_HOST)) && $b_f_option)
return (mail($to,$subject,$mesg,ExpandMailHeaders($a_headers),"-f$sender"));
else
return (DoMail($to,$subject,$mesg,$a_headers));
}
//
// Send an alert email
//
function SendAlert($s_error,$b_filter = true,$b_non_error = false)
{
global $SPECIAL_VALUES,$FORMATTED_INPUT,$FROM_USER,$aServerVars,$aStrippedFormVars;
global $aAlertInfo;
$s_error = str_replace("\n",BODY_LF,$s_error);
$b_got_filter = (isset($SPECIAL_VALUES["filter"]) && !empty($SPECIAL_VALUES["filter"]));
//
// if there is a filter specified and we're not sending the alert
// through the filter, don't show the user's data. This is
// on the assumption that the filter is an encryption program; so,
// we don't want to send the user's data in clear text inside the
// alerts.
//
$b_show_data = true;
if ($b_got_filter && !$b_filter)
$b_show_data = false;
$s_form_subject = $s_alert_to = "";
$b_check = true;
//
// might be too early to have $SPECIAL_VALUES set, so
// look in the form vars too
//
if (isset($SPECIAL_VALUES["alert_to"]))
$s_alert_to = trim($SPECIAL_VALUES["alert_to"]);
if (empty($s_alert_to) && isset($aStrippedFormVars["alert_to"]))
$s_alert_to = trim($aStrippedFormVars["alert_to"]);
if (isset($SPECIAL_VALUES["subject"]))
$s_form_subject = trim($SPECIAL_VALUES["subject"]);
if (empty($s_form_subject) && isset($aStrippedFormVars["subject"]))
$s_form_subject = trim($aStrippedFormVars["subject"]);
if (empty($s_alert_to))
{
$s_alert_to = DEF_ALERT;
$b_check = false;
}
if (!empty($s_alert_to))
{
$s_from_addr = $s_from = "";
$a_headers = array();
if (isset($FROM_USER) && !empty($FROM_USER))
{
if ($FROM_USER != "NONE")
{
$a_headers['From'] = $FROM_USER;
$s_from = "From: $FROM_USER";
$s_from_addr = $FROM_USER;
}
}
else
{
global $SERVER;
$s_from_addr = "FormMail@".$SERVER;
$a_headers['From'] = $s_from_addr;
$s_from = "From: $s_from_addr";
}
$s_mesg = "To: ".UnMangle($s_alert_to).BODY_LF;
if (!empty($s_from))
$s_mesg .= $s_from.BODY_LF;
$s_mesg .= BODY_LF;
if (count($aAlertInfo) > 0)
{
if ($b_show_data)
{
$s_error .= BODY_LF.GetMessage(MSG_MORE_INFO).BODY_LF;
$s_error .= implode(BODY_LF,$aAlertInfo);
}
else
$s_error .= BODY_LF.GetMessage(MSG_INFO_STOPPED).BODY_LF;
}
if ($b_non_error)
{
$s_mesg .= $s_error.BODY_LF.BODY_LF;
$s_subj = GetMessage(MSG_FM_ALERT);
if (!empty($s_form_subject))
$s_subj .= " ($s_form_subject)";
}
else
{
$s_mesg .= GetMessage(MSG_FM_ERROR_LINE).BODY_LF.
$s_error.BODY_LF.BODY_LF;
$s_subj = GetMessage(MSG_FM_ERROR);
if (!empty($s_form_subject))
$s_subj .= " ($s_form_subject)";
if ($b_show_data)
$s_mesg .= implode(BODY_LF,$FORMATTED_INPUT);
else
$s_mesg .= GetMessage(MSG_USERDATA_STOPPED);
}
if ($b_filter && $b_got_filter)
$s_mesg = GetMessage(MSG_FILTERED,
array("FILTER"=>$SPECIAL_VALUES["filter"])).
BODY_LF.BODY_LF.
Filter($SPECIAL_VALUES["filter"],$s_mesg);
if (isset($aServerVars['HTTP_REFERER']))
$s_mesg .= BODY_LF.BODY_LF."Referring page was ".$aServerVars['HTTP_REFERER'];
elseif (isset($SPECIAL_VALUES['this_form']) && $SPECIAL_VALUES['this_form'] !== "")
$s_mesg .= BODY_LF.BODY_LF."Referring form was ".$SPECIAL_VALUES['this_form'];
if (isset($aServerVars['REMOTE_ADDR']))
$s_mesg .= BODY_LF.BODY_LF."User IP address was ".$aServerVars['REMOTE_ADDR'];
if ($b_check)
{
if (CheckEmailAddress($s_alert_to,$s_valid,$s_invalid))
return (SendCheckedMail($s_valid,$s_subj,$s_mesg,$s_from_addr,$a_headers));
}
else
return (SendCheckedMail($s_alert_to,$s_subj,$s_mesg,$s_from_addr,$a_headers));
}
return (false);
}
//
// Read the lines in a file and return an array.
// Each line is stripped of line termination characters.
//
function ReadLines($fp)
{
$a_lines = array();
while (!feof($fp))
{
$s_line = fgets($fp,4096);
//
// strip carriage returns and line feeds
//
$s_line = str_replace("\r","",$s_line);
$s_line = str_replace("\n","",$s_line);
$a_lines[] = $s_line;
}
return ($a_lines);
}
//
// Open a URL and return the data from it as a string.
// Returns false on failure ($s_error has the error string)
//
function GetURL($s_url,&$s_error)
{
global $php_errormsg,$aServerVars,$FM_VERS;
global $AUTHENTICATE,$AUTH_USER,$AUTH_PW;
//
// parse the URL to get the component parts
//
$a_parts = parse_url($s_url);
//
// must have a host
//
if (!isset($a_parts["host"]))
{
$s_error = GetMessage(MSG_URL_PARSE);
return (false);
}
$s_host_hdr = $a_parts["host"];
//
// if no port number is given, we support http and https
//
if (!isset($a_parts["port"]))
{
if (!isset($a_parts["scheme"]) || strtolower($a_parts["scheme"]) == "http")
$a_parts["port"] = 80;
elseif (strtolower($a_parts["scheme"]) == "https")
$a_parts["port"] = 443;
else
{
$s_error = GetMessage(MSG_URL_SCHEME,
array("SCHEME"=>$a_parts["scheme"]));
return (false);
}
}
if ($a_parts["port"] == 443)
//
// fsockopen requires ssl:// in the host name
//
$a_parts["host"] = "ssl://".$a_parts["host"];
//
// default the path if empty
//
if (!isset($a_parts["path"]) || $a_parts["path"] === "")
$a_parts["path"] = "/";
$f_sock = @fsockopen($a_parts["host"],(int) $a_parts["port"],$i_errno,$s_errstr,30);
if ($f_sock === false)
{
$s_error = GetMessage(MSG_SOCKET,
array("ERRNO"=>$i_errno,
"ERRSTR"=>$s_errstr,
"PHPERR"=>isset($php_errormsg) ? $php_errormsg : ""));
return (false);
}
//
// the GET request
//
fputs($f_sock,"GET ".$a_parts["path"]." HTTP/1.0\r\n");
//
// Determine authentication requirements
//
if ($AUTHENTICATE !== "" || $AUTH_USER !== "" || $AUTH_PW !== "")
{
if ($AUTHENTICATE === "")
fputs($f_sock,"Authorization: Basic ".
base64_encode("$AUTH_USER:$AUTH_PW")."\r\n");
else
fputs($f_sock,"Authorization: $AUTHENTICATE\r\n");
}
else
{
if (isset($a_parts["user"]) || isset($a_parts["pass"]))
{
$s_auth_user = isset($a_parts["user"]) ? $a_parts["user"] : "";
$s_auth_pass = isset($a_parts["pass"]) ? $a_parts["pass"] : "";
}
else
{
$s_auth_type = isset($aServerVars["PHP_AUTH_TYPE"]) ? $aServerVars["PHP_AUTH_TYPE"] : "";
$s_auth_user = isset($aServerVars["PHP_AUTH_USER"]) ? $aServerVars["PHP_AUTH_USER"] : "";
$s_auth_pass = isset($aServerVars["PHP_AUTH_PW"]) ? $aServerVars["PHP_AUTH_PW"] : "";
}
if (!isset($s_auth_type) || $s_auth_type === "")
$s_auth_type = "Basic";
//
// Add the authentication header
//
if ($s_auth_user !== "" || $s_auth_pass !== "")
fputs($f_sock,"Authorization: $s_auth_type ".
base64_encode("$s_auth_user:$s_auth_pass")."\r\n");
}
//
// Specify the host name
//
fputs($f_sock,"Host: $s_host_hdr\r\n");
//
// Specify the user agent
//
fputs($f_sock,"User-Agent: FormMail/$FM_VERS (from www.tectite.com)\r\n");
//
// Accept any output
//
fputs($f_sock,"Accept: */*\r\n");
//
// End of request headers
//
fputs($f_sock,"\r\n");
//
// Read and parse the response header
//
$i_http_code = 0;
$s_status = "";
while (!feof($f_sock))
{
$s_line = fgets($f_sock,4096);
if ($s_line == "\r\n" || $s_line == "\n")
break;
if (substr($s_line,0,4) == "HTTP")
{
$i_pos = strpos($s_line," ");
$s_status = substr($s_line,$i_pos+1);
$i_end_pos = strpos($s_status," ");
if ($i_end_pos === false)
$i_end_pos = strlen($s_status);
$i_http_code = (int) substr($s_status,0,$i_end_pos);
}
}
if ($i_http_code < 200 || $i_http_code > 299)
{
$s_error = GetMessage(MSG_GETURL_OPEN,array("STATUS"=>$s_status));
fclose($f_sock);
return (false);
}
//
// read content into one big string buffer and return
//
$s_buf = "";
while (!feof($f_sock))
$s_buf .= fread($f_sock,1024);
fclose($f_sock);
return ($s_buf);
}
//
// Load a template file into a string.
//
function LoadTemplate($s_name,$s_dir,$s_url,$b_ret_lines = false)
{
global $php_errormsg;
$s_buf = "";
$a_lines = array();
if (!empty($s_dir))
{
$s_name = "$s_dir/".basename($s_name);
@ $fp = fopen($s_name,"r");
if ($fp === false)
{
SendAlert(GetMessage(MSG_OPEN_TEMPLATE,array("NAME"=>$s_name,
"ERROR"=>CheckString($php_errormsg))));
return (false);
}
if ($b_ret_lines)
$a_lines = ReadLines($fp);
else
//
// load the whole template into a string
//
$s_buf = fread($fp,filesize($s_name));
fclose($fp);
}
else
{
global $aServerVars;
$s_name = "$s_url/".basename($s_name);
if (isset($aServerVars['HTTP_USER_AGENT']))
$s_name = AddURLParams($s_name,"USER_AGENT=".$aServerVars['HTTP_USER_AGENT']);
@ $fp = fopen($s_name,"r");
if ($fp === false)
{
SendAlert(GetMessage(MSG_OPEN_TEMPLATE,array("NAME"=>$s_name,
"ERROR"=>CheckString($php_errormsg))));
return (false);
}
if ($b_ret_lines)
$a_lines = ReadLines($fp);
else
//
// load the whole template into a string
//
while (!feof($fp))
$s_buf .= fread($fp,4096);
fclose($fp);
}
return ($b_ret_lines ? $a_lines : $s_buf);
}
//
// To show an error template. The template must be HTML and, for security
// reasons, must be a file on the server in the directory specified
// by $TEMPLATEDIR or $TEMPLATEURL.
// $a_specs is an array of substitutions to perform, as follows:
// tag-name replacement string
//
// For example:
// "fmerror"=>"An error message"
//
function ShowErrorTemplate($s_name,$a_specs,$b_user_error)
{
global $TEMPLATEURL,$TEMPLATEDIR;
if (empty($TEMPLATEDIR) && empty($TEMPLATEURL))
{
SendAlert(GetMessage(MSG_TEMPLATES));
return (false);
}
if (($s_buf = LoadTemplate($s_name,$TEMPLATEDIR,$TEMPLATEURL)) === false)
return (false);
//
// now look for the tags to replace
//
foreach ($a_specs as $s_tag=>$s_value)
//
// search for
//
// with optional whitespace
//
$s_buf = preg_replace('/<\s*'.preg_quote($s_tag,"/").'\s*\/\s*>/ims',
nl2br($s_value),$s_buf);
if ($b_user_error)
{
// strip any and tags
//
// You can show information that's specific to user
// errors between these special tags.
//
$s_buf = preg_replace('/<\s*\/?\s*fmusererror\s*>/ims','',$s_buf);
//
// since this isn't a system error, strip anything between
// and
//
$s_buf = preg_replace('/<\s*fmsyserror\s*>.*<\s*\/\s*fmsyserror\s*>/ims','',$s_buf);
}
else
{
// strip any and tags
//
// You can show information that's specific to system
// errors between these special tags.
//
$s_buf = preg_replace('/<\s*\/?\s*fmsyserror\s*>/ims','',$s_buf);
//
// since this isn't a user error, strip anything between
// and
//
$s_buf = preg_replace('/<\s*fmusererror\s*>.*<\s*\/\s*fmusererror\s*>/ims','',$s_buf);
}
//
// just output the page
//
echo $s_buf;
return (true);
}
//
// To show an error to the user.
//
function ShowError($error_code,$error_mesg,$b_user_error,
$b_alerted = false,$a_item_list = array(),$s_extra_info = "")
{
global $SPECIAL_FIELDS,$SPECIAL_MULTI,$SPECIAL_VALUES;
global $aServerVars,$aSessionVars,$aStrippedFormVars;
//
// Testing with PHP 4.0.6 indicates that sessions don't always work.
// So, we'll also add the error to the URL, unless
// PUT_DATA_IN_URL is false.
//
$aSessionVars["FormError"] = $error_mesg;
$aSessionVars["FormErrorInfo"] = $s_extra_info;
$aSessionVars["FormErrorCode"] = $error_code;
$aSessionVars["FormErrorItems"] = $a_item_list;
$aSessionVars["FormIsUserError"] = $b_user_error;
$aSessionVars["FormAlerted"] = $b_alerted;
$aSessionVars["FormData"] = array();
$bad_url = $SPECIAL_VALUES["bad_url"];
$bad_template = $SPECIAL_VALUES["bad_template"];
$this_form = $SPECIAL_VALUES["this_form"];
if (!empty($bad_url))
{
$a_params = array();
$a_params[] = "this_form=".urlencode("$this_form");
$a_params[] = "bad_template=".urlencode("$bad_template");
if (PUT_DATA_IN_URL)
{
$a_params[] = "error=".urlencode("$error_mesg");
$a_params[] = "extra=".urlencode("$s_extra_info");
$a_params[] = "errcode=".urlencode("$error_code");
$a_params[] = "isusererror=".($b_user_error ? "1" : "0");
$a_params[] = "alerted=".($b_alerted ? "1" : "0");
$i_count = 1;
foreach ($a_item_list as $s_item)
{
$a_params[] = "erroritem$i_count=".urlencode("$s_item");
$i_count++;
}
}
else
//
// tell the bad_url to look in the session only
//
$a_params[] = "insession=1";
//
// Add the posted data to the URL so that an intelligent
// $bad_url can call the form again
//
foreach ($aStrippedFormVars as $s_name=>$m_value)
{
//
// skip special fields
//
$b_special = false;
if (in_array($s_name,$SPECIAL_FIELDS))
$b_special = true;
else
{
foreach ($SPECIAL_MULTI as $s_multi_fld)
{
$i_len = strlen($s_multi_fld);
if (substr($s_name,0,$i_len) == $s_multi_fld)
{
$i_index = (int) substr($s_name,$i_len);
if ($i_index > 0)
{
$b_special = true;
break;
}
}
}
}
if (!$b_special)
{
if (PUT_DATA_IN_URL)
{
if (is_array($m_value))
foreach ($m_value as $s_value)
$a_params[] = "$s_name".'[]='.
urlencode(substr($s_value,0,MAXSTRING));
else
$a_params[] = "$s_name=".urlencode(substr($m_value,0,MAXSTRING));
}
else
{
if (is_array($m_value))
$aSessionVars["FormData"]["$s_name"] = $m_value;
else
$aSessionVars["FormData"]["$s_name"] = substr($m_value,0,MAXSTRING);
}
}
}
//
// Now add the authentication data, if any
//
if ((isset($aServerVars["PHP_AUTH_USER"]) &&
$aServerVars["PHP_AUTH_USER"] !== "") ||
(isset($aServerVars["PHP_AUTH_PW"]) &&
$aServerVars["PHP_AUTH_PW"] !== ""))
{
if (PUT_DATA_IN_URL)
{
if (isset($aServerVars["PHP_AUTH_USER"]))
$a_params[] = "PHP_AUTH_USER=".urlencode($aServerVars["PHP_AUTH_USER"]);
if (isset($aServerVars["PHP_AUTH_PW"]))
$a_params[] = "PHP_AUTH_PW=".urlencode($aServerVars["PHP_AUTH_PW"]);
if (isset($aServerVars["PHP_AUTH_TYPE"]))
$a_params[] = "PHP_AUTH_TYPE=".urlencode($aServerVars["PHP_AUTH_TYPE"]);
}
else
{
if (isset($aServerVars["PHP_AUTH_USER"]))
$aSessionVars["FormData"]["PHP_AUTH_USER"] = $aServerVars["PHP_AUTH_USER"];
if (isset($aServerVars["PHP_AUTH_PW"]))
$aSessionVars["FormData"]["PHP_AUTH_PW"] = $aServerVars["PHP_AUTH_PW"];
if (isset($aServerVars["PHP_AUTH_TYPE"]))
$aSessionVars["FormData"]["PHP_AUTH_TYPE"] = $aServerVars["PHP_AUTH_TYPE"];
}
}
$bad_url = AddURLParams($bad_url,$a_params,false);
Redirect($bad_url);
}
else
{
if (!empty($bad_template))
{
$a_specs = array("fmerror"=>htmlspecialchars("$error_mesg"),
"fmerrorcode"=>htmlspecialchars("$error_code"),
"fmfullerror"=>htmlspecialchars("$error_mesg")."\n".
htmlspecialchars("$s_extra_info"),
"fmerrorextra"=>htmlspecialchars("$s_extra_info"),);
$i_count = 1;
foreach ($a_item_list as $s_item)
{
$a_specs["fmerroritem$i_count"] = htmlspecialchars($s_item);
$i_count++;
}
$s_list = "";
foreach ($a_item_list as $s_item)
$s_list .= "".htmlspecialchars($s_item)." \n";
$a_specs["fmerroritemlist"] = $s_list;
if (ShowErrorTemplate($bad_template,$a_specs,$b_user_error))
return;
}
$s_text = GetMessage(MSG_ERROR_PROC);
if ($b_user_error)
$s_text .= $error_mesg."\n".$s_extra_info;
else
{
if ($b_alerted)
$s_text .= GetMessage(MSG_ALERT_DONE);
else
$s_text .= GetMessage(MSG_PLS_CONTACT);
$s_text .= GetMessage(MSG_APOLOGY);
}
CreatePage($s_text);
//
// the session data is not needed now
//
ZapSession();
}
}
//
// Report an error
//
function Error($error_code,$error_mesg,$b_filter = true,$show = true,$int_mesg = "")
{
$b_alerted = false;
if (SendAlert("$error_code\n *****$int_mesg*****\nError=$error_mesg\n",$b_filter))
$b_alerted = true;
if ($show)
ShowError($error_code,$error_mesg,false,$b_alerted);
else
//
// show something to the user
//
ShowError($error_code,GetMessage(MSG_SUBM_FAILED),false,$b_alerted);
exit;
}
//
// Report a user error
//
function UserError($s_error_code,$s_error_mesg,
$s_extra_info = "",$a_item_list = array())
{
$b_alerted = false;
if (ALERT_ON_USER_ERROR &&
SendAlert("$s_error_code\nError=$s_error_mesg\n$s_extra_info\n"))
$b_alerted = true;
ShowError($s_error_code,$s_error_mesg,true,$b_alerted,$a_item_list,$s_extra_info);
exit;
}
//
// Create a simple page with the given text.
//
function CreatePage($text)
{
global $FM_VERS;
echo "";
echo "";
echo "";
echo "";
echo nl2br($text);
echo "
";
echo GetMessage(MSG_ABOUT_FORMMAIL,array("FM_VERS"=>$FM_VERS,
"TECTITE"=>"www.tectite.com"));
echo "
";
echo "";
echo "";
}
//
// Strip slashes if magic_quotes_gpc is set.
//
function StripGPC($s_value)
{
if (get_magic_quotes_gpc() != 0)
$s_value = stripslashes($s_value);
return ($s_value);
}
//
// return an array, stripped of slashes if magic_quotes_gpc is set
//
function StripGPCArray($a_values)
{
if (get_magic_quotes_gpc() != 0)
foreach ($a_values as $m_key=>$m_value)
if (is_array($m_value))
//
// strip arrays recursively
//
$a_values[$m_key] = StripGPCArray($m_value);
else
//
// convert scalar to string and strip
//
$a_values[$m_key] = stripslashes("$m_value");
return ($a_values);
}
//
// Strip a value of unwanted characters, which might be hacks.
// If $b_conv_quotes is true, also swaps all double quotes with single quotes.
//
function Strip($value,$b_conv_quotes = true)
{
if ($b_conv_quotes)
//
// "standard" quote conversion
//
$value = str_replace("\"","'",$value);
$value = preg_replace('/[[:cntrl:][:space:]]+/'," ",$value); // zap all control chars and multiple blanks
return ($value);
}
//
// Clean a value. This means:
// 1. convert to string
// 2. truncate to maximum length
// 3. strip the value of unwanted or dangerous characters (hacks)
// 4. trim both ends of whitespace
// Each element of an array is cleaned as above. This process occurs
// recursively, so arrays of arrays work OK too (though there's no
// need for that in this program).
//
// Non-scalar values are changed to the string "" where X is the type.
// In general, FormMail won't receive non-scalar non-array values, so this
// is more a future-proofing measure.
//
function CleanValue($m_value,$b_conv_quotes = true)
{
if (is_array($m_value))
{
foreach ($m_value as $m_key=>$m_item)
$m_value[$m_key] = CleanValue($m_item,$b_conv_quotes);
}
elseif (!is_scalar($m_value))
$m_value = "<".gettype($m_value).">";
else
{
//
// convert to string and truncate
//
$m_value = substr("$m_value",0,MAXSTRING);
//
// strip unwanted chars and trim
//
$m_value = trim(Strip($m_value,$b_conv_quotes));
}
return ($m_value);
}
//
// Clean a special value. Special values listed in $SPECIAL_NOSTRIP
// will not be cleaned.
//
function SpecialCleanValue($s_name,$m_value)
{
global $SPECIAL_NOSTRIP;
if (!in_array($s_name,$SPECIAL_NOSTRIP))
$m_value = CleanValue($m_value);
return ($m_value);
}
//
// Return the fields and their values in a string containing one
// field per line.
//
function MakeFieldOutput($a_order,$a_fields,$s_line_feed = BODY_LF)
{
$n_order = count($a_order);
$s_output = "";
for ($ii = 0 ; $ii < $n_order ; $ii++)
{
$s_name = $a_order[$ii];
if (isset($a_fields[$s_name]))
$s_output .= "$s_name: ".$a_fields[$s_name].$s_line_feed;
}
return ($s_output);
}
//
// Check if a field name is special. Returns true if it is.
//
function IsSpecialField($s_name)
{
global $SPECIAL_FIELDS;
return (in_array($s_name,$SPECIAL_FIELDS));
}
//
// Set a special field value.
//
function SetSpecialField($s_name,$m_value)
{
global $SPECIAL_VALUES;
//
// special values cannot be arrays; ignore them if they are
//
if (!is_array($m_value))
$SPECIAL_VALUES[$s_name] = SpecialCleanValue($s_name,$m_value);
}
//
// Check if a field name is a special "multi" field.
// A multi field is the name plus a sequence number. For example,
// conditions1
// conditions2
// Returns a list (array) if it is, otherwise false if not.
// The list contains:
// 1. the name of the special multi field
// 2. the index number for multi field
//
function IsSpecialMultiField($s_name)
{
global $SPECIAL_MULTI;
foreach ($SPECIAL_MULTI as $s_multi_fld)
{
$i_len = strlen($s_multi_fld);
//
// look for nameN where N is a number starting from 1
//
if (substr($s_name,0,$i_len) == $s_multi_fld)
{
$i_index = (int) substr($s_name,$i_len);
if ($i_index > 0)
{
//
// re-index to zero
//
--$i_index;
return (array($s_multi_fld,$i_index));
}
}
}
return (false);
}
//
// Set a multi field value.
//
function SetSpecialMultiField($s_name,$i_index,$m_value)
{
global $SPECIAL_VALUES;
//
// special fields cannot be arrays - ignore if it is
//
if (!is_array($m_value))
$SPECIAL_VALUES[$s_name][$i_index] = SpecialCleanValue($s_name,$m_value);
}
//
// Process a field
//
function ProcessField($s_name,$raw_value,&$a_order,&$a_fields,&$a_raw_fields)
{
global $FORMATTED_INPUT;
//
// fields go into an array of special values or an array of other values
//
$b_special = false;
if (IsSpecialField($s_name))
{
SetSpecialField($s_name,$raw_value);
$b_special = true;
}
//
// check for multiple valued special fields
//
if (($a_multi_fld = IsSpecialMultiField($s_name)) !== false)
{
SetSpecialMultiField($a_multi_fld[0],$a_multi_fld[1],$raw_value);
$b_special = true;
}
if (!$b_special)
{
//
// return the raw value unchanged in the $a_raw_fields array
//
$a_raw_fields[$s_name] = $raw_value;
//
// handle checkboxes and multiple-selection lists
// Thanks go to Theodore Boardman for the suggestion
// and initial working code.
//
if (is_array($raw_value))
{
//
// the array must be an array of scalars (not an array
// of arrays, for example)
//
if (is_scalar($raw_value[0]))
{
$a_cleaned_values = CleanValue($raw_value);
//
// the output is a comma separated list of values for the
// checkbox. For example,
// events: Diving,Cycling,Running
//
// Set the clean value to the list of cleaned checkbox
// values.
// First, remove any commas in the values themselves.
//
$a_cleaned_values = str_replace(",","",$a_cleaned_values);
$s_cleaned_value = implode(",",$a_cleaned_values);
}
else
$s_cleaned_value = "";
}
else
{
//
// NOTE: there is a minor bug here now that we support
// $FORM_INI_FILE. The INI file is processed at the end
// so if you set the mail_options below in the INI file they
// won't get processed here. This means you must set
// the following mail_options in the HTML form for now.
// (To be fixed at a later date. RJR 17-Feb-06).
//
//
// if the form specifies the "KeepLines" option,
// don't strip new lines
//
if (IsMailOptionSet("KeepLines") && strpos($raw_value,"\n") !== false)
{
//
// truncate first
//
$s_truncated = substr("$raw_value",0,MAXSTRING);
//
// split into lines, clean each individual line,
// then put it back together again
//
$a_lines = explode("\n",$s_truncated);
$a_lines = CleanValue($a_lines);
$s_cleaned_value = implode(BODY_LF,$a_lines);
//
// and, for this special case, prepend a new line
// so that the value is shown on a fresh line
//
$s_cleaned_value = BODY_LF.$s_cleaned_value;
}
else
$s_cleaned_value = CleanValue($raw_value);
}
//
// if the form specifies the "NoEmpty" option, skip
// empty values.
//
if (!IsMailOptionSet("NoEmpty") || !IsFieldEmpty($s_cleaned_value))
if (!IsMailExcluded($s_name))
{
//
// by default, we maintain the order as passed in
// the HTTP request
//
$a_order[] = $s_name;
$a_fields[$s_name] = $s_cleaned_value;
}
//
// add to the $FORMATTED_INPUT array for debugging and
// error reporting
//
array_push($FORMATTED_INPUT,"$s_name: '$s_cleaned_value'");
}
}
//
// Parse the input variables and return:
// 1. an array that specifies the required field order in the output
// 2. an array containing the non-special cleaned field values indexed
// by field name.
// 3. an array containing the non-special raw field values indexed by
// field name.
//
function ParseInput($a_vars)
{
$a_order = array();
$a_fields = array();
$a_raw_fields = array();
//
// scan the array of values passed in (name-value pairs) and
// produce slightly formatted (not HTML) textual output
// and extract any special values found.
//
foreach ($a_vars as $s_name=>$raw_value)
ProcessField($s_name,$raw_value,$a_order,$a_fields,$a_raw_fields);
return (array($a_order,$a_fields,$a_raw_fields));
}
//
// Get the URL for sending to the CRM.
//
function GetCRMURL($spec,$vars,$url)
{
$bad = false;
$list = TrimArray(explode(",",$spec));
$map = array();
for ($ii = 0 ; $ii < count($list) ; $ii++)
{
$name = $list[$ii];
if ($name)
{
//
// the specification must be in this format:
// form-field-name:CRM-field-name
//
if (($i_crm_name_pos = strpos($name,":")) > 0)
{
$s_crm_name = substr($name,$i_crm_name_pos + 1);
$name = substr($name,0,$i_crm_name_pos);
if (isset($vars[$name]))
{
$map[] = $s_crm_name."=".urlencode($vars[$name]);
$map[] = "Orig_".$s_crm_name."=".urlencode($name);
}
}
else
{
//
// not the right format, so just include as a parameter
// check for name=value format to choose encoding
//
$a_values = explode("=",$name);
if (count($a_values) > 1)
$map[] = urlencode($a_values[0])."=".urlencode($a_values[1]);
else
$map[] = urlencode($a_values[0]);
}
}
}
if (count($map) == 0)
return ("");
return (AddURLParams($url,$map,false));
}
//
// strip the HTML from a string
//
function StripHTML($s_str,$s_line_feed = "\n")
{
//
// strip HTML comments (s option means include new lines in matches)
//
$s_str = preg_replace('//s','',$s_str);
//
// strip any scripts (i option means case-insensitive)
//
$s_str = preg_replace('/