FormMail. * * Author: Russell Robinson, 2nd October 2001 * Last Modified: RR 18:04 Thu 17 March 2005 * QVCS Version: $Revision: 1.87 $ * * Read This First * ~~~~~~~~~~~~~~~ * This script is very heavily documented! It looks daunting, but * really isn't. * If you have experience with PHP or other scripting languages, * here's what you *need* to read: * - Features * - Configuration (TARGET_EMAIL & DEF_ALERT) * - Creating Forms * That's it! (Alternatively, just read the Quick Start section below). * * Quick Start * ~~~~~~~~~~~ * 1. Edit this file and set TARGET_EMAIL for your requirements (approx * line 2467 in this file - replace "yourhost\.com" with your mail server's * name). We also strongly recommend you set DEF_ALERT (the next * configuration below TARGET_EMAIL). * 2. Install this file as formmail.php on your web server * 3. Create an HTML form and: * - specify a hidden field called "recipients" with the email address * of the person to receive the form's results. * - specify method "post" (or "get") and an action set to * the formmail.php you uploaded to your web server * * Once you have FormMail working, you may be interested in some advanced * usage and features. We have HOW-TO guides at www.tectite.com which * describe many of the advanced processing you can do with FormMail. * * Purpose: * ~~~~~~~~ * To accept HTTP POST information from a form and mail it to recipients. * This version can also supply data to a TectiteCRM document, usually * for insertion into the CRM database. * * What does this PHP script do? * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * On your web site, you may have one or more HTML forms that accept * information from people visiting your website. Your aim is for your * website to email that information to you and/or add it to a database. * formmail.php performs those functions. * * Features * ~~~~~~~~ * - Optionally sends email of form results to recipients that * can be specified in the form itself. * - Optionally stores the form results in a CSV (comma-separated- * values) file on your server. * - Optionally logs form activity. * - Optionally sends form results to a TectiteCRM document; generally, * to automatically update the CRM database. * - Recipient email addresses can be mangled in your forms to * protect them from spambots. * - Emails can be processed through any program (typically an * encryption program) before sending. * - Successful processing can redirect the user to any URL. * For example, for downloads, we redirect the user to the file * they want to download. * - Supports any number of recipients. For security, recipient * domains must be specified inside the script (see "Configuration" * for details). * - Failed processing can redirect to a custom URL. * - Failed processing can be reported to a specific email address. * - Supports both GET and POST methods of form submission. * - Supports file uploads (multiple files can be uploaded). * - Supports checkboxes and multiple-selection lists. * - Supports CC and BCC addresses. * - Supports deriving fields by concatenating other fields. * - Supports exclusion of fields (in email) * - Supports HTML emails via a template feature. * - Supports complex field validation mechanisms. * - Supports advanced user error handling features (including using our * free fmbadhandler.php script). * - Supports error and success template display. * - Provides most of the features of other formmail scripts. * * Security * ~~~~~~~~ * Security is the primary concern in accepting data from your website visitors. * formmail.php has several security features designed into it. Note, however, * it requires configuration for your particular web site. * * Configuration * ~~~~~~~~~~~~~ * For instructions on configuring this program, go to the section * titled "CONFIGURATION" (after reading the legal stuff below). * There is only one mandatory setting: TARGET_EMAIL * * Creating Forms * ~~~~~~~~~~~~~~ * This section explains how to call formmail.php from your HTML * forms. You already need to know how to create an HTML form, but * this section will tell you how to link it with this formmail script. * * Your form communicates its requirements to formmail.php through * a set of "hidden" fields (using ). The data to * be processed by formmail (e.g. the actual email to send) comes from * a combination of hidden fields and other form fields (i.e. data entry * fields from the user). * * Here are the steps to use formmail.php with your HTML form: * 1. Create your HTML form using standard HTML * 2. Ensure your form has the following fields defined. These are * fields you expect the user to fill in: * email the user's email address * realname the real name of the user * 3. Add the following hidden fields to your form. Note that all * are optional: * recipients a comma-separated list of email addresses that * the form results will be sent to. These must * be valid according to the "TARGET_EMAIL" configuration. * Example: * russ.robbo@rootsoftware.com,sales@rootsoftware.com.au * alert_to email address to send errors/alerts to * Example: * webmaster@rootsoftware.com * required a list of fields the user must provide, together * with a friendly name. The field list is separated * by commas, and you append the friendly name to * the field name with a ':'. * Example: * email:Your email address,realname:Your name,Country,Reason:The reason you're interested in our product * Note that field names and friendly names must not * contain any of these characters: * :|^!=, * Advanced usage allows you to do the following: * field1:name1|field2:name2 * either field1 or field2 is required * (both allowed, too) * field1:name1^field2:name2 * either field1 or field2 is required * (both not allowed) * field1:name1=field2:name2 * field1's value must be the same as * field2's value * field1:name1!=field2:name2 * field1's value must be different from * field2's value * In all the above ":name" is optional for any field. * * conditions a list of complex conditions, all of which must * evaluate to true. Conditions are a more powerful * alternative to the "required" specification. * The list of conditions is separated by a character * you specify by the first character in the list. You * specify the internal conditions component separator * as the second character in the list, as follows: * name="conditions" value=":@condition1:condition2 * :condition3" * specifies that the conditions are separated by the * asterisk character. * There are size limitations to fields, so you * can specifie any number of conditions fields like * this: * name="conditions1" value=":@condition1:condition2 * :condition3" * name="conditions2" value=":@condition4:condition5 * :condition6" * * A condition has this general format (spaces * optional): * COMMAND@ test1 @test2 @... @MESSAGE@ * COMMAND and MESSAGE are mandatory. MESSAGE is * the message to display to the user if the condition * fails. * "@" is the internal separator that you specified * as the second character of the conditions list. * The tests are field comparisons, and have this * general format: * field1 OP field2 * * OP is an operand. Tests are similar to the "required" * specification, but the friendly field names are not * allowed because you can provide a general message. * * field1 * field1 must have a value * field1&field2 * both field1 and field2 must have a value * field1|field2 * either field1 or field2 must have a value * (both allowed, too) * field1^field2 * either field1 or field2 must have a value * (both not allowed) * field1=field2 * field1's value must be the same as * field2's value * field1!=field2 * field1's value must be different from * field2's value * field1~pattern * field1's value must match the specified * perl regular expression * field1!~pattern * field1's value must not match the specified * perl regular expression * field1#=number * field1's value is interpreted as a number * and must equal the given number * field1#!=number * field1's value is interpreted as a number * and must be not equal to the given number * field1#number * field1's value is interpreted as a number * and must be greater than the given number * field1#<=number * field1's value is interpreted as a number * and must be less than or equal to the given number * field1#>=number * field1's value is interpreted as a number * and must be greater than or equal to the given number * ! * the test evaluates to "false". * an empty test evaluates to "true". * * The conditions are: * @TEST@test@message@ * the test must be true. If not, the * given message is shown. * Example: * @TEST@realname@Please provide your name so * that we can address you properly.@ * This is exactly the same as a "required" * specification except that you can provide * an arbitrary message. * * @IF@test1@test2@test3@message@ * if test1 is true then test2 * must be true. If test1 is false then * test3 must be true. * Examples: * @IF@salutation~usefirst@firstname@lastname@You * must provide your first name if you * want us to use it to address you or * your last name for Mr., Mrs., etc.@ * says that firstname is required * if salutation has the value "usefirst", * and lastname is required otherwise. * On failure, the given message is shown. * * @IF@payment~ccard@creditcard~/[1-9][0-9]{12,15}/@@You must * enter your credit card number to * pay by credit card.@ * says that if the payment value is "ccard" * then the creditcard field must contain * at least one digit. * * mail_options a list of options to control FormMail when * sending email * derive_fields a mechanism for deriving form fields by * contatenating other form fields * Example: * realname=firstname+lastname,fullphone=area.phone,address=street*suburb * Operators are: * + concatenate with a single space between, * but skip the space if the next field is * empty * . concatenate with no space between * * concatenate with a single space between * good_url the URL to redirect to on successful processing * bad_url the URL to redirect to on failed processing * this_form the URL of the form that's submitting the data; * used with intelligent bad_url processing * good_template a template file that FormMail can display on * successful processing * bad_template a template file that FormMail can display on * failed processing * template_list_sep a string to use when expanding lists * of values in templates. The default is comma. * subject a subject line for the email that's sent to your * recipients * Example: * Form Submission * env_report a comma-separated list of environment variables * you want included in the email * Example: * REMOTE_HOST,REMOTE_ADDR,HTTP_USER_AGENT,AUTH_TYPE,REMOTE_USER * filter name of a filter to process the email before sending. * You can encode or encrypt the email, for example. * filter_options comma-separated list of options to control the filter. * filter_fields comma-separated list of fields to filter. * The behaviour of this specification can vary slightly * depending on your other specifications. Refer * to our How-To guide on Filtering for more information. * logfile name of a file to append activity to. Note that * you must configure "LOGDIR" for this to work. * Example: * formmail.log * csvfile name of the CSV database to append results to. Note that * you must configure "CSVDIR" for this to work. You * must also specify the csvcolumns field. * Example: * formmail.csv * csvcolumns comma-separated list of field names you want to * store in the CSV database. These are the field * names in your form, and the order specifies the * order for storage in the CSV database. * Example: * email,realname,Country,Reason * autorespond comma-spearated list of specifications for the * Auto Repsonder feature. Specifications are: * Subject set to the subject line you * want in the email sent to the user * HTMLTemplate set to the name of the template * to use for sending HTML email to * the user * PlainTemplate set to the name of the template * to use for sending plain text email * to the user * TemplateMissing set to the string to use to * fill in unsubmitted fields in template * You can specify either HTMLTemplate or PlainTemplate * or both. * Example: * Subject=Thanks for your purchase,HTMLTemplate=orderemail.htm * crm_url a URL to send the form data to. This is for use * with the TectiteCRM system. * crm_spec a specification to pass to TectiteCRM. Please * read the TectiteCRM documentation for details of * how to use this field. * crm_options options to control processing of TectiteCRM * interface * * 4. Check that you've provided at least one of these fields: * recipients, or * logfile, or * csvfile and csvcolumns, or * crm_url and crm_spec * If you don't specify any of these, then formmail.php will fail * because you've given it no work to do! * * Note that we've provided a sample HTML form to get you started. * Look for "Sample HTML Form Using FormMail" on our forums at * http://www.tectite.com/. * * Note also that the default success and failure pages shown by formmail.php * are quite basic. We recommend that you provide your own pages * with "good_url" and "bad_url". * * Copying and Use * ~~~~~~~~~~~~~~~ * formmail.php is provided free of charge and may be freely distributed * and used provided that you: * 1. keep this header, including copyright and comments, * in place and unmodified; and, * 2. do not charge a fee for distributing it, without an agreement * in writing with Root Software Pty Ltd allowing you to do so; and, * 3. if you modify formmail.php before distributing it, you clearly * identify: * a) who you are * b) how to contact you * c) what changes you have made * d) why you have made those changes. * * Warranty and Disclaimer * ~~~~~~~~~~~~~~~~~~~~~~~ * formmail.php is provided free-of-charge and with ABSOLUTELY NO WARRANTY. * It has not been verified for use in critical applications, including, * but not limited to, medicine, defense, aircraft, space exploration, * or any other potentially dangerous activity. * * By using formmail.php you agree to indemnify Root Software Pty Ltd, * its agents, employees, and directors from any liability whatsoever. * * We still care * ~~~~~~~~~~~~~ * If you report problems to us, we will respond to your report and make * endeavours to rectify any faults you've detected as soon as possible. * To contact us, visit http://www.tectite.com/contacts.php. * * Version History * ~~~~~~~~~~~~~~~ * **Version 6.02: 17-Mar-2005 * * Added system error message to the alert that's sent when a check file * cannot be created. * * Added the "null" filter. * * Added new configuration setting ZERO_IS_EMPTY. * * Renamed "fm_modules" to "fmmodules". * * Implemented "and" for "conditions" testing. * **Version 6.01: 11-Mar-2005 * * EMAIL_NAME now includes '-', so you can use this to match email * addresses like "jack-smith@somesite.com". * The Upgrade Wizard will put in the new value and discard your * previous setting. * * Added some more comments/examples for Windows Servers. * * Added new filter options "KeepInLine". If you use the Attach option, * you can also specify KeepInLine. KeepInLine causes the filtered * results to be kept in the body of the email as well as being attached * according to the Attach option. KeepInLine is ignored if Attach is * not specified. * **Version 6.00: 20-Feb-2005 ******* MAJOR UPGRADE ******* * * Added support for new FMCompute module. This creates new special * fields called "fmcompute" or "fmcompute1...N", and "fm_modules". * Adds new configuration $MODULEDIR to hold the directory for * modules. * Added GeoIP module support via FMCompute. Adds new configuration * $GEOIP_LIC to hold your MaxMind license code. * Created IncludePath functions. * **Version 5.03: 31-Jan-2005 * * Workaround a problem with empty file uploads on some * servers and/or PHP versions. * **Version 5.02: 19-Jan-2005 * * Fixed problems with upgrading and copying the $FROM_USER and * $REAL_DOCUMENT_ROOT configurations. $REAL_DOCUMENT_ROOT has * been replaced with a setting called "$SET_REAL_DOCUMENT_ROOT". * * Added support for Environment Variables and Server Variables * to be accessed to create derived fields. * * Fixed bug in last version when processing FromAddr. * **Version 5.00rc1: 10-Dec-2004 ******* MAJOR UPGRADE FOR INTERNATIONALIZATION ******* * * Added support for languages other than English. * * FromAddr is now processed with the AT_MANGLE feature...this means you * can hide this mail_options setting from spam bots too. * * Altered some error messages. Socket filter errors are no longer shown * to the user. * **Version 4.10: 9-Dec-2004 * * Added default setting for $TEMPLATEURL - without it the Upgrade Wizard * failed to upgrade properly. * Fixed bug in filtering process. This bug would probably not manifest * on Unix servers, but may do on Windows servers. * **Version 4.09: 8-Dec-2004 * * Added new configuration options: * SENDMAIL_F_OPTION, which supersedes the "SendMailFOption" specification * in "mail_options" in forms * INI_SEND_FROM which allows you to workaround bad PHP * configurations on Windows servers * **Version 4.08: 29-Nov-2004 * * More changes to set $REAL_DOCUMENT_ROOT correctly. This is now * also an optional configuration setting. * **Version 4.07: 29-Nov-2004 * * Fixed bugs with handling regular expressions in "conditions" on * server configurations with magic_quotes_gpc set On. * With magic_quotes_gpc set On, any backslashes in your regular * expressions would be stripped, thereby changing the meaning of your * regular expressions. * * Fixed bugs with handling slashes in data. Backslashes were being stripped * twice on server configurations with magic_quotes_gpc set On. * * Also fixes problems with storing CSV data that contains innocuous * slashes. With LIMITED_IMPORT set to true, backslashes were being * unnecessarily stripped. * With LIMITED_IMPORT set to false, backslashes in data could cause the CSV * file to be unreadable by an intelligent importing program because they * were not being backslashed. They are now backslased (escaped). * **Version 4.06: 26-Nov-2004 * * Removed unused variable that would cause a warning message * on some systems. * **Version 4.05: 23-Nov-2004 * * Removed debugging code that could prevent correct setting of * $REAL_DOCUMENT_ROOT. * A failure to send an alert message with the "testalert" feature * now displays an error message. * Added support for sending mail using PEAR. * **Version 4.04: 20-Nov-2004 * * Disables "magic_quotes_runtime" setting, which breaks just about everything. * **Version 4.03: 14-Nov-2004 * * Added new mail_options setting "FromAddr". * You can specify an empty value or any email address. If this option is * used, the sender of form results will be set to the given address * instead of the value of the "email" field. This feature is necessary * for certain servers which don't let software specify an arbitrary * sender address. Yahoo is one such hosting service. * **Version 4.02: 28-Oct-2004 * * Improved to handle PHP sessions for browsers with cookies disabled. * This is primarily useful with Error Handling (including with our * FMBadHandler script). * **Version 4.01: 16-Oct-2004 * * Improved setting of $REAL_DOCUMENT_ROOT. This means the standard * filter setting for "encode" is more likely to work without change * on any server. * * Improved "testalert" feature to include some server variables in the * email. * **Version 4.00: 12-Oct-2004 ******* MAJOR UPGRADE ******* * * This new version provides new features that will be useful to * users of FormMailDecoder. * * Added support for "filter_fields" feature. Your forms can now * select which fields are to be filtered (encoded). All other * fields will be shown normally. The behaviour of this feature is * reasonably logical if you're also using the PlainTemplate and HTMLTemplate * features. However, if you are using them, we recommend that you * also specify the Attach feature in "filter_options". * * Added support for "filter_options" feature. Allows you to control * the way a filter operates. Currently, only the "Attach" feature is * provided: * Attach if specified, the output of the filter is attached * to the email instead of being inside the body of the * message. You must provide the name of the file. * Some examples: * Attach=ccard.fmencoded * Attach=data.txt * * See the HOW-TO guide on filtering for more information about these * new features (http://www.tectite.com/fmhowto/guides.php). * **Version 3.01: 22-Sep-2004 * * Workaround a problem in Microsoft IIS with uploaded files. * **Version 3.00: 2-Sep-2004 ******* MAJOR UPGRADE ******* * * Implemented the long-awaited Auto Responder feature! Requires * version 1.01 of "verifyimg.php". * * Improved the "Exclude" mail_option so that "realname" and "email" * special fields can be excluded from the body of the email. * * Added PlainTemplate mail_option feature. You can now create a template * that will be used for sending you a plain text email. You can use this, * for example, to put the data into CSV format. * **Version 2.17: 31-Aug-2004 * * When filling templates, values are now converted so that HTML * special characters in the values cannot break the HTML output. * * Alert messages now include the subject from the Form. Thanks * to Doug Wright for suggesting this. * * Added new "template_list_sep" hidden field. If you have list-type * fields in your form (checkboxes, multi-selection list boxes) and these * are expanded in a template, then FormMail uses "," to separate the values * by default. You can specify a different separator with the * template_list_sep hidden field. For example, * * will give you line breaks instead of comma. * * Added new mail_options setting "CharSet". Your form can specify the * character set to be used in emails with this option. For example, * * Thanks to Wojtek Linde for requesting this feature. * The default remains ISO-8859-1. * **Version 2.16: 18-Aug-2004 * * Added new "good_template" hidden field. This defines the template * to output (and fill) to the browser on successful submission. * * Added new "crm_options" hidden field to control processing * of CRM submissions. * * Added support for templates from URLs. This means you can use a * URL from $TEMPLATEURL instead of a file from $TEMPLATEDIR. This is great for * dynamically generated web pages. This adds a new configuration variable * called $TEMPLATEURL. * **Version 2.15: 4-Aug-2004 * * Fixed a bug in testing the PHP version - a couple of lines * were in the wrong order. This should stop "Undefined offset" * error form appearing in your php_errors file. * * Fixed bug in handling HTML + text emails with file attachments. * This bug was introduced after version 2.12. * * Improved MIME compliance with internal headers when BODY_LF is set * to something other than "\r\n". Improved to use the HEAD_CRLF * configuration variable. * **Version 2.14: 13-Jul-2004 * * Fixed problem with using sslencode filter. * Small redesign in the definition of filters for HTTP and HTTPs access so * that the FormMail Upgrade Wizard can be used to upgrade FormMail * to contain these new features. * **Version 2.13: 12-Jul-2004 * * Added support for executing filters via HTTP and HTTPS connections. * This overcomes the problem on some servers where even CGI-BIN programs * cannot be executed through PHP's "popen" or "system" functions. * **Version 2.12: 25-Jun-2004 * * Fixed bug in passing array variables to the bad_url via the session. * * Added new "SendMailFOption" option for "mail_options". This causes * FormMail to provide the "-faddr" option when it calls the "mail" function. * This is needed by certain sendmail server installations. * **Version 2.11: 23-Jun-2004 * * Improved further so that if no email address is provided the From line * is excluded (having a name only is not valid to RFC822). * Fixed some typos in comments. * **Version 2.10: 21-Jun-2004 * * Improved creation of email's From line - if neither the email * or realname is provided, no From line is included in the email. * **Version 2.09: 29-May-2004 * * Fixed bug: mail_options Exclude feature wouldn't allow a single field * name. * * Derived fields can now include arbitrary literal character using * this ASCII hexadecimal notation: %HH% where HH is two hexadecimal * characters: for example, 27 is a single quote, 2B is +, 2E is ., etc. * * Added simple check for internet spiders....no alert is sent. * * Added CONFIG_CHECK feature - currently checks for security * issues in TARGET_EMAIL patterns. * * Improved to destroy session data when no longer needed. * **Version 2.08: 23-May-2004 * * Fixed bug: wasn't handling 'ampm' in derived fields expansions. * * Added support for version check on servers that don't provide SERVER_NAME * (now uses a unique ID derived from $TARGET_EMAIL[0] instead of SERVER_NAME). * * Added optional SCRATCH_PAD configuration so that you can specify the * a directory that FormMail can write to on your server. * * Temporary files are now created in SCRATCH_PAD if it's configured. * * Alert messages are now filtered if a filter is specified (this is for * security purposes on the assumption that the filter is an encryption * program). * * Alert messages now use BODY_LF everywhere for line termination. * **Version 2.07: 13-May-2004 * * Fixed incorrect documentation for $CSVOPEN feature introduced * in v2.06. * * Added $CSVLINE configuration. Use this to customize your line * terminations in CSV files * **Version 2.06: 12-May-2004 * * Added $CSVOPEN configuration. Use this to ensure a text file * format for your operating system. * **Version 2.05: 11-May-2004 * * Added $CSVQUOTE configuration. This allows you to specify * the character used for quoting fields in a CSV file. If you don't * want quotes, you can set it to any empty string. * Quotes within fields in a CSV file are now swapped to the opposite * quote of that specified in $CSVQUOTE. * **Version 2.04: 10-May-2004 * * Passes some more information to the bad_url. This information is * used by fmbadhandler.php. * Template expansions now treat empty fields as missing. * Template expansions now put HTML BR tags where any new lines are found. * Some alerts provide more specific information * Added ALERT_ON_USER_ERROR configuration. * Switched off DEBUG mode that was accidentally left on. * The version check flag file now shows the server name. * The version check now works even if SERVER_NAME is not available. * **Version 2.03: 3-May-2004 * * Internal release - not generally available. * **Version 2.02: 1-May-2004 * * Fixed a problem that caused empty conditions to generate an alert message. * Since empty conditions are the default, that's an annoying problem! * Changed "Revision" to "Version" in this Version History. * **Version 2.01: 1-May-2004 * * Added support for creating date and time fields automatically. * Fixed some line formatting. * **Version 2.00: 1-May-2004 ******* MAJOR UPGRADE ******* * * Several sections re-written to improve consistency and logic checking. * * Default FILTERS now includes "fmencoder". * * Added support for "cc" and "bcc" addresses. This only have an * effect if "recipients" have also been specified. * * Added support for form checkboxes and multiple-selection lists * (thanks to Ted Boardman for getting us started on that). * * Added a lot more checking and reporting of errors or problems. * * Added a special test parameter to confirm that the DEF_ALERT setting * is working. The DEF_ALERT address is no longer subject to * verification through TARGET_EMAIL. You can now specify any address * for DEF_ALERT. ("alert_to" from a form is still tested against * TARGET_EMAIL). * * Added support for file uploads. Note, the form must specify: * enctype="multipart/form-data" method="post" * (this is a requirement of file uploading, not FormMail). * * Added support for "mail_options" field. This provides * extra control from the form. Options supported: * NoEmpty FormMail won't send results for fields that are empty. * KeepLines fields which contain lines (e.g. TEXTAREA's) keep the * lines; without this option (i.e. the default) FormMail * joins the lines together * AlwaysList don't format as an email even if there's only one * non-special field. If this option is set, the email is * always formatted like this: * name1: value1 * name2: value2 * DupHeader duplicate some header lines in the body of the email; * this was the default prior to Version 2.00. If you've * upgraded from 1.XX and you want your emails to look the * same, include this option. * StartLine include a --START-- line before the fields. This * option only works if you also specify BodyHeader. * If you've upgraded from 1.XX and you want your emails to * look the same, include this option. The --START-- line * is useful for some filter programs. * Exclude a list of fields to exclude from the email (special * fields cannot be excluded) * HTMLTemplate name of a template file to use to create an HTML * formatted email * PlainTemplate name of a template file to use to create an plain text * email * TemplateMissing string to insert for fields that are empty, * when filling an email template (HTMLTemplate or PlainTemplate) * CharSet the character set to specify in the Content-Type for * emails. Default is ISO-8859-1. * * CSV file support now provides configurable separators (see * $CSVSEP, $CSVINTSEP, and $CSVQUOTE). * * Improved list processing so that list items can whitespace * around them (e.g. ). * * Added support for derived fields. * * Errors are now distinguished between internal and user error. A user * error is, for example, failure to enter a field. Internal errors are * now shown as a generic message to the user (since the user can't do * anything about them). * * Generated pages are now XHTML compliant. * * Redirects now use several methods to perform the redirect: * Location header * JavaScript redirect * Text for the user: "please click here" * * All files that are opened are now subject to special processing to * prevent security breaches. * * All URLs that FormMail will open are now checked against the * TARGET_URLS setting (security feature). * * Added advanced tests in the "required" feature. * * Added complex field validations through the new "conditions" feature. * * Added new "bad_template" feature for customizing the error page. * * Improved "bad_url" handling - more error fields and data is now * send to "bad_url" so that it can redirect back to the original form. * * Added automatic regular check for new version of FormMail. * ****************************************************************************** * **Version 1.22: 11-Feb-2004 * Improved filter logic to handle options which might have slashes in them. * For example, a filter like "/path/to/fmencoder -k/path/to/keyfile.txt" * would not work (because the directory name was not evaluated correctly). * Added some more information when reporting filter failures. * **Version 1.21: 24-Jan-2004 * Fixed bug: required fields were not being checked if the form * was not sending email (e.g. if it was just writing to a CSV file). * Added alert messages for failure to open CSV and LOG files. * Improved some documentation and added some TARGET_EMAIL example lines. * **Version 1.19 & 1.20: 19-Jan-2004 * Added support for missing environment variables: if an environment variable * isn't in the environment, then FormMail looks in the server variables for it. * * Improved support for different server configurations; if SCRIPT_FILENAME * is not available, PATH_TRANSLATED is used; if one or more isn't available * no error message is produced (previous version displayed an error message * depending on the PHP configuration). * * Added configuration option for line termination in the email body. * * The FormMail version is now displayed in the default error page. * **Version 1.18: 13-Jan-2004 * Fixed a problem when mail sending failed; now, FormMail reports the error * to the user (by going to bad_url or generating the standard error page) * instead of showing success. * Added support for GET method of form submission (FormMail automatically * detects the method from the PHP Server variables). * **Version 1.16 & 1.17: 4-Jan-2004 & 5-Jan-2004 * Added support for PHP versions before 4.2.3 (i.e. from 4.0.0 onwards). * **Version 1.14 & 1.15: 3-Jan-2004 * Added some more comments. * **Version 1.13: 29-Dec-2003 * Added Quick Start section, some more samples, and some more comments. * **Version 1.12: 26-Sep-2003 * Replaced use of PATH_TRANSLATED with the more reliable SCRIPT_FILENAME. * **Version 1.10 & 1.11: 16-Sep-2003 * Added handling of magic_quotes_gpc setting. * **Version 1.9: 5-Sep-2003 * Added ex/vi initialisation string. * **Version 1.8: 9-Jul-2003 * Added a workaround for a PHP bug: http://bugs.php.net/bug.php?id=21311 * **Version 1.7: 19-May-2003 * If a form contains only one non-special field (a "special" field is * one of the pre-defined ones, like "email", "realname"), then formmail.php * formats the single field as the email to be sent. This feature allows * formmail.php to be used for a simple email interface. * Modified some wordings. * **Version 1.4: 13-May-2003 * First released version. */ // // Capture the current date and time, for various purposes. // $lNow = time(); set_magic_quotes_runtime(0); // disable this silly setting (usually not enabled) ini_set('track_errors',1); // enable $php_errormsg $aAlertInfo = array(); $aPHPVERSION = array(); $sLangID = ""; // the language ID $aMessages = array(); // all FormMail messages in the appropriate // language // // the following constants define all FormMail messages // define('MSG_SCRIPT_VERSION',0); // This script requires at least PHP version... define('MSG_END_VERS_CHK',1); // If you're happy... define('MSG_VERS_CHK',2); // A later version of FormMail is available... define('MSG_CHK_FILE_ERROR',3); // Unable to create check file... define('MSG_UNK_VALUE_SPEC',4); // derive_fields: unknown value specification... define('MSG_INV_VALUE_SPEC',5); // derive_fields: invalid value specification... define('MSG_DERIVED_INVALID',6); // Some derive_fields specifications... define('MSG_INT_FORM_ERROR',7); // Internal form error... define('MSG_OPTIONS_INVALID',8); // Some mail_options settings... define('MSG_PLSWAIT_REDIR',9); // Please wait while you are redirected... define('MSG_IFNOT_REDIR',10); // If you are not redirected... define('MSG_PEAR_OBJ',11); // Failed to create PEAR Mail object... define('MSG_PEAR_ERROR',12); // PEAR Mail error... define('MSG_NO_FOPT_ADDR',13); // You have specified "SendMailFOption"... define('MSG_MORE_INFO',14); // More information... define('MSG_INFO_STOPPED',15); // Extra alert information suppressed... define('MSG_FM_ALERT',16); // FormMail alert define('MSG_FM_ERROR',17); // FormMail script error define('MSG_FM_ERROR_LINE',18); // The following error occurred... define('MSG_USERDATA_STOPPED',19); // User data suppressed... define('MSG_FILTERED',20); // This alert has been filtered... define('MSG_TEMPLATES',21); // You must set either TEMPLATEDIR or TEMPLATEURL... define('MSG_OPEN_TEMPLATE',22); // Failed to open template... define('MSG_ERROR_PROC',23); // An error occurred while processing... define('MSG_ALERT_DONE',24); // Our staff have been alerted... define('MSG_PLS_CONTACT',25); // Please contact us directly... define('MSG_APOLOGY',26); // We apologize for any inconvenience... define('MSG_ABOUT_FORMMAIL',27); // Your form submission was processed by... define('MSG_PREG_FAILED',28); // preg_match_all failed in FindCRMFields... define('MSG_URL_INVALID',29); // CRM URL "$URL" is not valid... define('MSG_URL_OPEN',30); // Failed to open Customer Relationship... define('MSG_CRM_FAILED',31); // Failure report from CRM... define('MSG_CRM_FORM_ERROR',32); // Your form submission was not... define('MSG_OR',33); // "$ITEM1" or "$ITEM2" define('MSG_NOT_BOTH',34); // not both "$ITEM1" and "$ITEM2" define('MSG_XOR',35); // "$ITEM1" or "$ITEM2" (but not both) define('MSG_IS_SAME_AS',36); // "$ITEM1" is the same as "$ITEM2" define('MSG_IS_NOT_SAME_AS',37); // "$ITEM1" is not the same as "$ITEM2" define('MSG_REQD_OPER',38); // Operator "$OPER" is not valid for "required" define('MSG_PAT_FAILED',39); // Pattern operator "$OPER" failed: pattern... define('MSG_COND_OPER',40); // Operator "$OPER" is not valid... define('MSG_INV_COND',41); // Invalid "conditions" field... define('MSG_COND_CHARS',42); // The conditions field "$FLD" is not valid... define('MSG_COND_INVALID',43); // The conditions field "$FLD" is not valid... define('MSG_COND_TEST_LONG',44); // Field "$FLD" has too many components... define('MSG_COND_IF_SHORT',45); // Field "$FLD" has too few components for... define('MSG_COND_IF_LONG',46); // Field "$FLD" has too many components for... define('MSG_COND_UNK',47); // Field "$FLD" has an unknown command word... define('MSG_MISSING',48); // Missing "$ITEM"... define('MSG_NEED_ARRAY',49); // "$ITEM" must be an array... define('MSG_SUBM_FAILED',50); // Your form submission has failed... define('MSG_FILTER_WRONG',51); // Filter "$FILTER" is not properly... define('MSG_FILTER_CONNECT',52); // Could not connect to site "$SITE"... define('MSG_FILTER_PARAM',53); // Filter "$FILTER" has invalid parameter... define('MSG_FILTER_OPEN_FILE',54); // Filter "$FILTER" cannot open file... define('MSG_FILTER_FILE_ERROR',55); // Filter "$FILTER": read error on file... define('MSG_FILTER_READ_ERROR',56); // Filter '$filter' failed: read error... define('MSG_FILTER_NOT_OK',57); // Filter 'FILTER' failed... define('MSG_FILTER_UNK',58); // Unknown filter... define('MSG_FILTER_CHDIR',59); // Cannot chdir... define('MSG_FILTER_NOTFOUND',60); // Cannot execute... define('MSG_FILTER_ERROR',61); // Filter "$FILTER" failed... define('MSG_FLD_NOTFOUND',62); // "$FIELD" is not a field submitted... define('MSG_TEMPLATE_ERRORS',63); // Template "$NAME" caused the... define('MSG_TEMPLATE_FAILED',64); // Failed to process template "$NAME"... define('MSG_MIME_PREAMBLE',65); // (Your mail reader should not show this... define('MSG_MIME_HTML',66); // This message has been generated by FormMail... define('MSG_FILE_OPEN_ERROR',67); // Failed to open file "$NAME"... define('MSG_ATTACH_DATA',68); // Internal error: AttachFile requires... define('MSG_PHP_HTML_TEMPLATES',69); // HTMLTemplate option is only ... define('MSG_PHP_FILE_UPLOADS',70); // For security reasons, file upload... define('MSG_FILE_UPLOAD',71); // File upload attempt ignored... define('MSG_FILE_UPLOAD_ATTACK',72);// Possible file upload attack... define('MSG_PHP_PLAIN_TEMPLATES',73);// PlainTemplate option is only... define('MSG_ATTACH_NAME',74); // filter_options: Attach must contain a name... define('MSG_PHP_BCC',75); // Warning: BCC is probably not supported... define('MSG_CSVCOLUMNS',76); // The "csvcolumns" setting is not... define('MSG_CSVFILE',77); // The "csvfile" setting is not... define('MSG_TARG_EMAIL_PAT_START',78); // Warning: Your TARGET_EMAIL pattern... define('MSG_TARG_EMAIL_PAT_END',79); // Warning: Your TARGET_EMAIL pattern... define('MSG_CONFIG_WARN',80); // The following potential problems... define('MSG_PHP_AUTORESP',81); // Autorespond is only supported... define('MSG_ALERT',82); // This is a test alert message... define('MSG_NO_DEF_ALERT',83); // No DEF_ALERT value has been set.... define('MSG_TEST_SENT',84); // Test message sent. Check your email..... define('MSG_TEST_FAILED',85); // FAILED to send alert message... define('MSG_NO_DATA_PAGE',86); // This URL is a Form submission program... define('MSG_REQD_ERROR',87); // The form required some values that you... define('MSG_COND_ERROR',88); // Some of the values you provided... define('MSG_CRM_FAILURE',89); // The form submission did not succeed... define('MSG_FOPTION_WARN',90); // Warning: You've used SendMailFOption in... define('MSG_NO_ACTIONS',91); // The form has an internal error... define('MSG_NO_RECIP',92); // The form has an internal error... define('MSG_INV_EMAIL',93); // Invalid email addresses... define('MSG_FAILED_SEND',94); // Failed to send email... define('MSG_ARESP_EMAIL',96); // No "email" field was found. Autorespond... define('MSG_ARESP_SUBJ',97); // Your form submission... define('MSG_LOG_NO_VERIMG',98); // No VerifyImgString in session... define('MSG_ARESP_NO_AUTH',99); // Failed to obtain authorization... define('MSG_LOG_NO_MATCH',100); // User did not match image... define('MSG_ARESP_NO_MATCH',101); // Your entry did not match... define('MSG_LOG_FAILED',102); // Failed define('MSG_ARESP_FAILED',103); // Autoresponder failed define('MSG_LOG_OK',104); // OK define('MSG_THANKS_PAGE',105); // Thanks! We've received your.... define('MSG_LOAD_MODULE',106); // Cannot load module.... define('MSG_LOAD_FMCOMPUTE',107); // Cannot load FMCompute.... define('MSG_REGISTER_MODULE',108); // Cannot register module.... define('MSG_COMP_PARSE',109); // These parse errors occurred.... define('MSG_COMP_REG_DATA',110); // Failed to register data field.... define('MSG_COMP_ALERT',111); // The following alert messages.... define('MSG_COMP_DEBUG',112); // The following debug messages... define('MSG_AND',133); // "$ITEM1" and "$ITEM2" // Jump to: // // Return true if using the built-in language // function IsBuiltInLanguage() { global $sLangID; return (strpos($sLangID,"builtin") !== false); } $sSavePath = ""; $bPathSaved = false; // // Set include path to include the given directory. // function AddIncludePath($s_dir = ".") { global $sSavePath,$bPathSaved; $s_path = ini_get('include_path'); $i_path_len = strlen($s_path); $s_sep = IsServerWindows() ? ";" : ":"; // get path separator // // look for it in the include_path // $b_found = false; $i_pos = 0; $i_len = strlen($s_dir); while (!$b_found && ($i_pos = strpos($s_path,$s_dir,$i_pos)) !== false) { if ($i_pos == 0) { if ($i_len == $i_path_len) $b_found = true; // the path only has $s_dir elseif ($s_path{$i_len} == $s_sep) $b_found = true; } elseif ($s_path{$i_pos-1} == $s_sep && ($i_pos + $i_len == $i_path_len || $s_path{$i_pos + $i_len} == $s_sep)) $b_found = true; if (!$b_found) $i_pos++; } if (!$b_found) { // // allow multiple calls, but only store the original path once // if (!$bPathSaved) $sSavePath = $s_path; if (empty($s_path)) $s_path = $s_dir; else // // prepend the directory // $s_path = $s_dir.$s_sep.$s_path; ini_set('include_path',$s_path); $bPathSaved = true; } } // // Reset the include path after a call to AddIncludePath. // function ResetIncludePath() { global $sSavePath,$bPathSaved; if ($bPathSaved) { ini_set('include_path',$sSavePath); $bPathSaved = false; } } // // Load a language file // function LoadLanguageFile() { global $aMessages,$sLangID; AddIncludePath(); include("language.inc"); ResetIncludePath(); } // // Load the messages array from the default language, and then // override with an optional language file. // Note: all messages get the MNUM parameter sent which they can use. // If they don't use it, the message number is appended. // function LoadBuiltinLanguage() { global $aMessages,$sLangID; $sLangID = "English (builtin)"; // MSG_SCRIPT_VERSION is shown if the PHP version is too old to run // FormMail // Parameters: // $PHPREQ is the minimum required PHP version // $PHPVERS is the version the server currently has installed. $aMessages[MSG_SCRIPT_VERSION] = 'This script requires at least PHP version '. '$PHPREQ. You have PHP version $PHPVERS.'; // MSG_END_VERS_CHK is sent at the end of an Alert message when // FormMail detects that there's a newer version available // Parameters: none $aMessages[MSG_END_VERS_CHK] = '***************************************************\n'. 'If you are happy with your current version and want\n'. 'to stop these reminders, edit formmail.php and\n'. 'set CHECK_FOR_NEW_VERSION to false.\n'. '***************************************************\n'; // MSG_VERS_CHK is sent in an Alert message when // FormMail detects that there's a newer version available // Parameters: // $TECTITE the website to go to // $FM_VERS the current FormMail version // $NEWVERS the new FormMail version that's available $aMessages[MSG_VERS_CHK] = 'A later version of FormMail is available from $TECTITE.\n'. 'You are currently using version $FM_VERS.\n'. 'The new version available is $NEWVERS.\n'; // MSG_CHK_FILE_ERROR is sent in an Alert message when // FormMail cannot create a file to record the time of version check. // Parameters: // $FILE the file name that could not be created // $ERROR the actual error message $aMessages[MSG_CHK_FILE_ERROR] = 'Unable to create check file "$FILE": $ERROR'; // MSG_UNK_VALUE_SPEC is sent in an Alert message when // a form uses an unknown value specification in derive_fields. // Parameters: // $SPEC the unknown value specification $aMessages[MSG_UNK_VALUE_SPEC] = 'derive_fields: unknown value specification "$SPEC"'; // MSG_INV_VALUE_SPEC is sent in an Alert message when // a form uses a value specification in derive_fields that's // formatted incorrectly (missing terminating '%') // Parameters: // $SPEC the invalid value specification $aMessages[MSG_INV_VALUE_SPEC] = 'derive_fields: invalid value specification '. '"$SPEC" (possibly missing a "%")'; // MSG_DERIVED_INVALID is sent in an Alert message when // a form's derive_fields setting has errors // Parameters: none // A list of errors is appended on separate lines $aMessages[MSG_DERIVED_INVALID] = 'Some derive_fields specifications are invalid $MNUM:\n'; // MSG_INT_FORM_ERROR is sent in an Alert message and displayed // to the form user // Parameters: none $aMessages[MSG_INT_FORM_ERROR] = 'Internal form error'; // MSG_OPTIONS_INVALID is sent in an Alert message when // a form's options settings are invalid. This applies to // mail_options, filter_options, crm_options, and autorespond // Parameters: // $OPT the name of the options field // A list of errors is appended on separate lines $aMessages[MSG_OPTIONS_INVALID] = 'Some $OPT settings are undefined $MNUM:\n'; // MSG_PLSWAIT_REDIR is shown to the user for a redirect // with JavaScript // Parameters: none $aMessages[MSG_PLSWAIT_REDIR] = 'Please wait while you are redirected...'; // MSG_IFNOT_REDIR is shown to the user for a redirect // with JavaScript // Parameters: // $URL the URL to redirect to $aMessages[MSG_IFNOT_REDIR] = 'If you are not automatically redirected, '. 'please click here.'; // MSG_PEAR_OBJ is shown to the user if the PEAR Mail object // cannot be created // Parameters: none $aMessages[MSG_PEAR_OBJ] = 'Failed to create PEAR Mail object'; // MSG_PEAR_ERROR is sent in an Alert message if the PEAR Mail processing // reports an error // Parameters: // $MSG the error message from PEAR $aMessages[MSG_PEAR_ERROR] = 'PEAR Mail error: $MSG'; // MSG_NO_FOPT_ADDR is sent in an Alert message SendMailFOption is // specified in the form and no email address has been provided // Parameters: none $aMessages[MSG_NO_FOPT_ADDR] = 'You have specified "SendMailFOption" in your '. 'form, but there is no email address to use'; // MSG_MORE_INFO is sent in an Alert message on a line by itself, just // before extra information about the FormMail processing that may have // led to the alert message // Parameters: none $aMessages[MSG_MORE_INFO] = 'More information:'; // MSG_INFO_STOPPED is sent in an Alert message to say that extra // alert information has been suppressed because of potential security // problems with showing it. // Parameters: none $aMessages[MSG_INFO_STOPPED] = '(Extra alert information suppressed for '. 'security purposes. $MNUM)'; // MSG_FM_ALERT is sent as the subject line of an Alert message // Parameters: none $aMessages[MSG_FM_ALERT] = 'FormMail alert'; // MSG_FM_ERROR is sent as the subject line of an Alert message // Parameters: none $aMessages[MSG_FM_ERROR] = 'FormMail script error'; // MSG_FM_ERROR_LINE is sent in an Alert message on a // separate line to introduce the actual error message // Parameters: none $aMessages[MSG_FM_ERROR_LINE] = 'The following error occurred in FormMail $MNUM:'; // MSG_USERDATA_STOPPED is sent in an Alert message to say that the // user's data has been suppressed because of potential security // problems with showing it. // Parameters: none $aMessages[MSG_USERDATA_STOPPED] = '(User data suppressed for security '. 'purposes. $MNUM)'; // MSG_FILTERED is sent in an Alert message to show what filter // has been used on the message // Parameters: // $FILTER the name of the filter $aMessages[MSG_FILTERED] = 'This alert has been filtered through "$FILTER" '. 'for security purposes.'; // MSG_TEMPLATES is sent in an Alert message when a form tries // to use a template, but templates have not been configured in // formmail.php // Parameters: none $aMessages[MSG_TEMPLATES] = 'You must set either TEMPLATEDIR or TEMPLATEURL '. 'in formmail.php before you can specify '. 'templates in your forms.'; // MSG_OPEN_TEMPLATE is sent in an Alert message when FormMail cannot // open a template file // Parameters: // $NAME the name of the template file // $ERROR information about the error $aMessages[MSG_OPEN_TEMPLATE] = 'Failed to open template "$NAME" ($MNUM): $ERROR'; // MSG_ERROR_PROC is shown to the user as part of an error // page. This message introduces the error. // Parameters: none $aMessages[MSG_ERROR_PROC] = 'An error occurred while processing the '. 'form ($MNUM).\n\n'; // MSG_ALERT_DONE is shown to the user as part of an error // page if an Alert message has been sent to the website owner. // Parameters: none $aMessages[MSG_ALERT_DONE] = 'Our staff have been alerted to the error ($MNUM).\n'; // MSG_PLS_CONTACT is shown to the user as part of an error // page if an Alert message could *not* be sent to the website owner. // Parameters: none $aMessages[MSG_PLS_CONTACT] = 'Please contact us directly since this form '. 'is not working ($MNUM).\n'; // MSG_APOLOGY is shown to the user as part of an error // page as an apology for a problem with the form. // Parameters: none $aMessages[MSG_APOLOGY] = 'We apologize for any inconvenience this error '. 'may have caused.'; // MSG_ABOUT_FORMMAIL is shown to the user at the foot of pages // generated by FormMail (e.g. the default "Thanks" page and default // error page). // Parameters: // $FM_VERS the FormMail version number // $TECTITE www.tectite.com $aMessages[MSG_ABOUT_FORMMAIL] = 'Your form submission was processed by '. '($FM_VERS), available from '. '$TECTITE.'; // MSG_PREG_FAILED is sent in an Alert message if the TectiteCRM // system failed to return the expected result. // Parameters: none $aMessages[MSG_PREG_FAILED] = 'preg_match_all failed in FindCRMFields'; // MSG_URL_INVALID is sent in an Alert message if the specified // URL for TectiteCRM is not valid according to the TARGET_URLS // configuration setting // Parameters: // $URL the invalid URL $aMessages[MSG_URL_INVALID] = 'The URL "$URL" to access the Customer '. 'Relationship Management System is not valid '. '(see TARGET_URLS in formmail.php)'; // MSG_URL_OPEN is sent in an Alert message if the specified // URL for TectiteCRM cannot be opened // Parameters: // $URL the invalid URL // $ERROR information about the error $aMessages[MSG_URL_OPEN] = 'Failed to open Customer Relationship '. 'Management System URL "$URL" ($MNUM): $ERROR'; // MSG_CRM_FAILED is sent in an Alert message if the TectiteCRM // system doesn't return an OK message // Parameters: // $URL the invalid URL // $MSG more information $aMessages[MSG_CRM_FAILED] = 'Failure report from Customer Relationship '. 'Management System (url="$URL") ($MNUM): $MSG'; // MSG_CRM_FORM_ERROR is shown to the user if the information // passed to TectiteCRM was not accepted // Parameters: none $aMessages[MSG_CRM_FORM_ERROR] = 'Your form submission was not accepted'; // MSG_AND is shown to the user; it shows two items separated // by "and" // Parameters: // $ITEM1 the first item // $ITEM2 the second item $aMessages[MSG_AND] = '"$ITEM1" and "$ITEM2"'; // MSG_OR is shown to the user; it shows two items separated // by "or" // Parameters: // $ITEM1 the first item // $ITEM2 the second item $aMessages[MSG_OR] = '"$ITEM1" or "$ITEM2"'; // MSG_NOT_BOTH is shown to the user; it shows two items that must // be specified together // Parameters: // $ITEM1 the first item // $ITEM2 the second item $aMessages[MSG_NOT_BOTH] = 'not both "$ITEM1" and "$ITEM2"'; // MSG_XOR is shown to the user; it shows two items that must // not be specified together // Parameters: // $ITEM1 the first item // $ITEM2 the second item $aMessages[MSG_XOR] = '"$ITEM1" or "$ITEM2" (but not both)'; // MSG_IS_SAME_AS is shown to the user; it shows two items that must // not be the same value // Parameters: // $ITEM1 the first item // $ITEM2 the second item $aMessages[MSG_IS_SAME_AS] = '"$ITEM1" is the same as "$ITEM2"'; // MSG_IS_NOT_SAME_AS is shown to the user; it shows two items that must // be the same value // Parameters: // $ITEM1 the first item // $ITEM2 the second item $aMessages[MSG_IS_NOT_SAME_AS] = '"$ITEM1" is not the same as "$ITEM2"'; // MSG_REQD_OPER is sent in an Alert message when an unknown // operator has been used in a "required" specification // Parameters: // $OPER the unknown operator $aMessages[MSG_REQD_OPER] = 'Operator "$OPER" is not valid for "required"'; // MSG_PAT_FAILED is sent in an Alert message when a "conditions" pattern // match has not matched anything (this isn't necessarily an error) // Parameters: // $OPER the "conditions" operator // $PAT the "conditions" pattern // $VALUE the value that was searched $aMessages[MSG_PAT_FAILED] = 'Pattern operator "$OPER" failed: pattern '. '"$PAT", value searched was "$VALUE".'; // MSG_COND_OPER is sent in an Alert message when a "conditions" // operator is not value // Parameters: // $OPER the "conditions" operator $aMessages[MSG_COND_OPER] = 'Operator "$OPER" is not valid for "conditions"'; // MSG_INV_COND is sent in an Alert message when a "conditions" // field is not valid // Parameters: // FLD the field name $aMessages[MSG_INV_COND] = 'Invalid "conditions" field "$FLD" - not a string or array.'; // MSG_COND_CHARS is sent in an Alert message when a "conditions" // field is missing the mandatory first 2 characters (the separators) // Parameters: // FLD the field name // COND the conditions field value $aMessages[MSG_COND_CHARS] = 'The conditions field "$FLD" is not valid. '. 'You must provide the two separator '. 'characters at the beginning. You had "$COND".'; // MSG_COND_INVALID is sent in an Alert message when a "conditions" // field has the wrong format // Parameters: // FLD the field name // COND the conditions field value // SEP the internal separator character for the field. $aMessages[MSG_COND_INVALID] = 'The conditions field "$FLD" is not valid. '. 'There must be at least 5 components '. 'separated by "$SEP". Your value was "$COND".'; // MSG_COND_TEST_LONG is sent in an Alert message when a "conditions" // TEST value has too many components // Parameters: // FLD the field name // COND the conditions field value // SEP the list separator character for the field. $aMessages[MSG_COND_TEST_LONG] = 'Field "$FLD" has too many components for '. 'a "TEST" command: "$COND".\nAre you missing '. 'a "$SEP"?'; // MSG_COND_IF_SHORT is sent in an Alert message when a "conditions" // IF value has too few components // Parameters: // FLD the field name // COND the conditions field value // SEP the internal separator character for the field. $aMessages[MSG_COND_IF_SHORT] = 'Field "$FLD" has too few components for '. 'an "IF" command: "$COND".\nThere must be '. 'at least 6 components separated by "$SEP"'; // MSG_COND_IF_LONG is sent in an Alert message when a "conditions" // IF value has too many components // Parameters: // FLD the field name // COND the conditions field value // SEP the list separator character for the field. $aMessages[MSG_COND_IF_LONG] = 'Field "$FLD" has too many components for '. 'an "IF" command: "$COND".\nAre you missing '. 'a "$SEP"?'; // MSG_COND_UNK is sent in an Alert message when a "conditions" // value has an unknown command // Parameters: // FLD the field name // COND the conditions field value // CMD the unknown command $aMessages[MSG_COND_UNK] = 'Field "$FLD" has an unknown command word '. '"$CMD": "$COND".'; // MSG_MISSING is sent in an Alert message when // a socket filter is incorrectly defined // Parameters: // ITEM the missing item $aMessages[MSG_MISSING] = 'Missing "$ITEM"'; // MSG_NEED_ARRAY is sent in an Alert message when // a socket filter is incorrectly defined // Parameters: // ITEM the item that should be an array $aMessages[MSG_NEED_ARRAY] = '"$ITEM" must be an array'; // MSG_SUBM_FAILED is shown to the user when an internal error // as occurred and that error is not to be shown // Parameters: none $aMessages[MSG_SUBM_FAILED] = 'Your form submission has failed due to '. 'an error on our server.'; // MSG_FILTER_WRONG is sent in an Alert message when // a socket filter is incorrectly defined // Parameters: // FILTER the filter name // ERRORS a string containing a list of errors $aMessages[MSG_FILTER_WRONG] = 'Filter "$FILTER" is not properly defined: '. '$ERRORS'; // MSG_FILTER_CONNECT is sent in an Alert message when FormMail // cannot connect to a socket filter // Parameters: // FILTER the filter name // SITE the site // ERRNUM socket error number // ERRSTR socket error message $aMessages[MSG_FILTER_CONNECT] = 'Could not connect to site "$SITE" '. 'for filter "$FILTER" ($ERRNUM): $ERRSTR'; // MSG_FILTER_PARAM is sent in an Alert message when a socket // filter has an invalid parameter specification // Parameters: // FILTER the filter name // NUM parameter number // NAME parameter name $aMessages[MSG_FILTER_PARAM] = 'Filter "$FILTER" has invalid parameter '. '#$NUM: no "$NAME"'; // MSG_FILTER_OPEN_FILE is sent in an Alert message when a socket // filter cannot open the required file // Parameters: // FILTER the filter name // FILE the file that could not be opened // ERROR the error message $aMessages[MSG_FILTER_OPEN_FILE] = 'Filter "$FILTER" cannot open file '. '"$FILE": $ERROR'; // MSG_FILTER_FILE_ERROR is sent in an Alert message when a socket // filter gets an error message during reading a file // Parameters: // FILTER the filter name // FILE the file that could not be opened // ERROR the error message // NLINES the number of lines that were read successfully $aMessages[MSG_FILTER_FILE_ERROR] = 'Filter "$FILTER": read error on file '. '"$FILE" after $NLINES lines: $ERROR'; // MSG_FILTER_READ_ERROR is sent in an Alert message when a socket // filter gets an error during reading from the socket // Parameters: // FILTER the filter name // ERROR the error message $aMessages[MSG_FILTER_READ_ERROR] = 'Filter "$FILTER" failed: read error: '. '$ERROR'; // MSG_FILTER_NOT_OK is sent in an Alert message when a socket // filter fails to return the agreed __OK__ indicator // Parameters: // FILTER the filter name // DATA the data returned from the filter $aMessages[MSG_FILTER_NOT_OK] = 'Filter "$FILTER" failed (missing '. '__OK__ line): $DATA'; // MSG_FILTER_UNK is sent in an Alert message // when an unknown filter is specified by a form // Parameters: // FILTER the filter name $aMessages[MSG_FILTER_UNK] = 'Unknown filter "$FILTER"'; // MSG_FILTER_CHDIR is sent in an Alert message // when FormMail cannot change to the filter's directory // Parameters: // FILTER the filter name // DIR the directory name // ERROR an error message from the system $aMessages[MSG_FILTER_CHDIR] = 'Cannot chdir to "$DIR" to run filter '. '"$FILTER": $ERROR'; // MSG_FILTER_NOTFOUND is sent in an Alert message // when FormMail cannot execute the filter // Parameters: // FILTER the filter name // CMD the command line being executed // ERROR an error message from the system $aMessages[MSG_FILTER_NOTFOUND] = 'Cannot execute filter "$FILTER" with '. 'command "$CMD": $ERROR'; // MSG_FILTER_ERROR is sent in an Alert message // when a filter returns a non-zero status // Parameters: // FILTER the filter name // ERROR an error message from the system // STATUS the status return from the command $aMessages[MSG_FILTER_ERROR] = 'Filter "$FILTER" failed (status $STATUS): '. '$ERROR'; // MSG_FLD_NOTFOUND is sent as part of an Alert message // when a template refers to a non-existent form field // Parameters: // FIELD the field name $aMessages[MSG_FLD_NOTFOUND] = '"$FIELD" is not a field submitted from the form'; // MSG_TEMPLATE_ERRORS is sent as part of an Alert message // when a template has generated some errors. The message // should end with a new line and the actual errors are // output after it. // Parameters: // NAME the template name $aMessages[MSG_TEMPLATE_ERRORS] = 'Template "$NAME" caused the '. 'following errors ($MNUM):\n'; // MSG_TEMPLATE_FAILED is sent in an Alert message // when processing a template has failed. // Parameters: // NAME the template name $aMessages[MSG_TEMPLATE_FAILED] = 'Failed to process template "$NAME"'; // MSG_MIME_PREAMBLE is sent in the preamble of MIME emails // Parameters: none $aMessages[MSG_MIME_PREAMBLE] = '(Your mail reader should not show this '. 'text.\nIf it does you may need to '. 'upgrade to more modern software.)'; // MSG_MIME_HTML is sent in the preamble of HTML emails // Parameters: // NAME the template name $aMessages[MSG_MIME_HTML] = 'This message has been generated by FormMail '. 'using an HTML template\ncalled "$NAME". The '. 'raw text of the form results\nhas been '. 'included below, but your mail reader should '. 'display the HTML\nversion only (unless it\'s '. 'not capable of doing so).'; // MSG_FILE_OPEN_ERROR is sent in an Alert message when FormMail // cannot open a file // Parameters: // NAME the file name // TYPE the type of file // ERROR the system error message $aMessages[MSG_FILE_OPEN_ERROR] = 'Failed to open $TYPE file "$NAME": $ERROR'; // MSG_ATTACH_DATA is sent in an Alert message when the file // attachment through 'data' has gone wrong. // Parameters: none $aMessages[MSG_ATTACH_DATA] = 'Internal error: AttachFile requires '. '"tmp_name" or "data"'; // MSG_PHP_HTML_TEMPLATES is sent in an Alert message when an // HTML template is used but the PHP version is too old. // Parameters: // $PHPVERS the current PHP version $aMessages[MSG_PHP_HTML_TEMPLATES] = 'HTMLTemplate option is only supported '. 'with PHP version 4.0.5 or above. Your '. 'server is running version $PHPVERS.'; // MSG_PHP_FILE_UPLOADS is sent in an Alert message when // file upload is used but the PHP version is too old. // Parameters: // $PHPVERS the current PHP version $aMessages[MSG_PHP_FILE_UPLOADS] = 'For security reasons, file upload is only '. 'allowed with PHP version 4.0.3 or above. '. 'Your server is running version $PHPVERS.'; // MSG_FILE_UPLOAD is sent in an Alert message when // file upload is attempted but FormMail is not configured to allow // it // Parameters: none $aMessages[MSG_FILE_UPLOAD] = 'File upload attempt ignored'; // MSG_FILE_UPLOAD_ATTACK is sent in an Alert message when // possible file upload attack is detected // Parameters: // NAME file name // TEMP temporary file name $aMessages[MSG_FILE_UPLOAD_ATTACK] = 'Possible file upload attack '. 'detected: name="$NAME" temp name='. '"$TEMP"'; // MSG_PHP_PLAIN_TEMPLATES is sent in an Alert message when a // Plain template is used but the PHP version is too old. // Parameters: // $PHPVERS the current PHP version $aMessages[MSG_PHP_PLAIN_TEMPLATES] = 'PlainTemplate option is only supported '. 'with PHP version 4.0.5 or above. Your '. 'server is running version $PHPVERS.'; // MSG_ATTACH_NAME is sent in an Alert message when a // the form uses the Attach feature without specifying a file name // Parameters: none $aMessages[MSG_ATTACH_NAME] = 'filter_options: Attach must contain a name '. '(e.g. Attach=data.txt)'; // MSG_PHP_BCC is sent in an Alert message when a // the form uses the BCC feature and the PHP version may not support it // Parameters: // $PHPVERS the current PHP version $aMessages[MSG_PHP_BCC] = 'Warning: BCC is probably not supported on your '. 'PHP version ($PHPVERS)'; // MSG_CSVCOLUMNS is sent in an Alert message when a csvcolumns field // is not correct // Parameters: // $VALUE the csvcolumns field value $aMessages[MSG_CSVCOLUMNS] = 'The "csvcolumns" setting is not '. 'valid: "$VALUE"'; // MSG_CSVFILE is sent in an Alert message when a csvfile field // is not correct // Parameters: // $VALUE the csvfile field value $aMessages[MSG_CSVFILE] = 'The "csvfile" setting is not valid: "$VALUE"'; // MSG_TARG_EMAIL_PAT_START is sent in an Alert message when a // $TARGET_EMAIL pattern is insecure because of a missing '^' // at the beginning // Parameters: // $PAT the pattern $aMessages[MSG_TARG_EMAIL_PAT_START] = 'Warning: Your TARGET_EMAIL pattern '. '"$PAT" is missing a ^ at the '. 'beginning.'; // MSG_TARG_EMAIL_PAT_END is sent in an Alert message when a // $TARGET_EMAIL pattern is insecure because of a missing '$' // at the end // Parameters: // $PAT the pattern $aMessages[MSG_TARG_EMAIL_PAT_END] = 'Warning: Your TARGET_EMAIL pattern '. '"$PAT" is missing a $ at the end.'; // MSG_CONFIG_WARN is sent in an Alert message when the FormMail // configuration may have some problems. The messages are // passed on separate lines, so the line terminations below // are important. // Parameters: // $MESGS lines of messages $aMessages[MSG_CONFIG_WARN] = 'The following potential problems were found '. 'in your configuration:\n$MESGS\n\n'. 'These are not necessarily errors, but you '. 'should review the documentation\n'. 'inside formmail.php. If you are sure your '. 'configuration is correct\n'. 'you can disable the above messages by '. 'changing the CONFIG_CHECK settings.'; // MSG_PHP_AUTORESP is sent in an Alert message when the PHP version // does not support autoresponding // Parameters: // $PHPVERS current PHP version $aMessages[MSG_PHP_AUTORESP] = 'Autorespond is only supported with PHP '. 'version 4.0.5 or above. Your server is '. 'running version $PHPVERS.'; // MSG_ALERT is the test alert message (formmail.php?testalert=1) // Parameters: // $LANG the language ID // $PHPVERS PHP version // $FM_VERS FormMail version // $SERVER server type // $DOCUMENT_ROOT PHP's DOCUMENT_ROOT value // $SCRIPT_FILENAME PHP's SCRIPT_FILENAME value // $PATH_TRANSLATED PHP's PATH_TRANSLATED value // $REAL_DOCUMENT_ROOT the REAL_DOCUMENT_ROOT value $aMessages[MSG_ALERT] = 'This is a test alert message $MNUM\n'. 'Loaded language is $LANG\n'. 'PHP version is $PHPVERS\n'. 'FormMail version is $FM_VERS\n'. 'Server type: $SERVER\n'. '\n'. 'DOCUMENT_ROOT: $DOCUMENT_ROOT\n'. 'SCRIPT_FILENAME: $SCRIPT_FILENAME\n'. 'PATH_TRANSLATED: $PATH_TRANSLATED\n'. 'REAL_DOCUMENT_ROOT: $REAL_DOCUMENT_ROOT'; // MSG_NO_DEF_ALERT is displayed if you use the testalert feature // and no DEF_ALERT setting has been provided. // Parameters: none $aMessages[MSG_NO_DEF_ALERT] = 'No DEF_ALERT value has been set.'; // MSG_TEST_SENT is displayed if when use the testalert feature // Parameters: none $aMessages[MSG_TEST_SENT] = 'Test message sent. Check your email.'; // MSG_TEST_FAILED is displayed if when use the testalert feature // and the mail sending fails. // Parameters: none $aMessages[MSG_TEST_FAILED] = 'FAILED to send alert message. Check your '. 'server error logs.'; // MSG_NO_DATA_PAGE is the page that's displayed if the user // just opens the URL to FormMail directly. // Parameters: none $aMessages[MSG_NO_DATA_PAGE] = 'This URL is a Form submission program.\n'. 'It appears the form is not working '. 'correctly as there was no data found.\n'. 'You\'re not supposed to browse to this '. 'URL; it should be accessed from a form.'; // MSG_REQD_ERROR is displayed to the user as a default error // message when they haven't supplied some required fields // Parameters: none $aMessages[MSG_REQD_ERROR] = 'The form required some values that you '. 'did not seem to provide.'; // MSG_COND_ERROR is displayed to the user as a default error // message when some form conditions have failed // Parameters: none $aMessages[MSG_COND_ERROR] = 'Some of the values you provided are not valid.'; // MSG_CRM_FAILURE is displayed to the user when submission // to the CRM has failed. // Parameters: none $aMessages[MSG_CRM_FAILURE] = 'The form submission did not succeed due to '. 'a CRM failure.'; // MSG_FOPTION_WARN is sent in an Alert message when the form // uses the superseded SendMailFOption feature // Parameters: // $LINE line number for SENDMAIL_F_OPTION $aMessages[MSG_FOPTION_WARN] = 'Warning: You\'ve used SendMailFOption in '. '"mail_options" in your form. This has been '. 'superseded with a configuration setting '. 'inside formmail.php. Please update your '. 'formmail.php configuration (look for '. 'SENDMAIL_F_OPTION on line $LINE) and set '. 'it to "true", then remove SendMailFOption '. 'from your form(s).'; // MSG_NO_ACTIONS is sent in an Alert message when there is no // action to perform or email address to send to // Parameters: none $aMessages[MSG_NO_ACTIONS] = 'The form has an internal error - no actions '. 'or recipients were specified.'; // MSG_NO_RECIP is sent in an Alert message when there are no // valid recipients to send to // Parameters: none $aMessages[MSG_NO_RECIP] = 'The form has an internal error - no valid '. 'recipients were specified.'; // MSG_INV_EMAIL is sent in an Alert message when there are errors // in the email addresses specified in the form // Parameters: // $ERRORS list of errors $aMessages[MSG_INV_EMAIL] = 'Invalid email addresses were specified '. 'in the form $MNUM:\n$ERRORS'; // MSG_FAILED_SEND is sent in an Alert message when the mail sending fails. // Parameters: none $aMessages[MSG_FAILED_SEND] = 'Failed to send email'; // MSG_ARESP_EMAIL is sent in an Alert message when // no email address has been specified for an autoreponse // Parameters: none $aMessages[MSG_ARESP_EMAIL] = 'No "email" field was found. Autorespond '. 'requires the submitter\'s email address.'; // MSG_ARESP_SUBJ is the default subject for the auto response email // Parameters: none $aMessages[MSG_ARESP_SUBJ] = 'Your form submission'; // MSG_LOG_NO_VERIMG is written to the auto respond log file // if no VerifyImgString session variable was found // Parameters: none $aMessages[MSG_LOG_NO_VERIMG] = 'No VerifyImgString in session'; // MSG_ARESP_NO_AUTH is shown to the user // if no VerifyImgString session variable was found // Parameters: none $aMessages[MSG_ARESP_NO_AUTH] = 'Failed to obtain authorization to send you email'; // MSG_LOG_NO_MATCH is written to the auto respond log file // if the user's entry did not match the image verification // Parameters: none $aMessages[MSG_LOG_NO_MATCH] = 'User did not match image'; // MSG_ARESP_NO_MATCH is shown to the user // if the user's entry did not match the image verification // Parameters: none $aMessages[MSG_ARESP_NO_MATCH] = 'Your entry did not match the image'; // MSG_LOG_FAILED is written to the auto respond log file // if the autoresponding failed // Parameters: none $aMessages[MSG_LOG_FAILED] = 'Failed'; // MSG_ARESP_FAILED is sent in an Alert message // if the autoresponding failed // Parameters: none $aMessages[MSG_ARESP_FAILED] = 'Autoresponder failed'; // MSG_LOG_OK is written to the auto respond log file // if the autoresponding succeeded // Parameters: none $aMessages[MSG_LOG_OK] = 'OK'; // MSG_THANKS_PAGE is the default page that's displayed if the // submission is successful // Parameters: none $aMessages[MSG_THANKS_PAGE] = 'Thanks! We\'ve received your information '. 'and, if it\'s appropriate, we\'ll be in '. 'contact with you soon.'; // MSG_LOAD_MODULE is sent in an alert message if a module // could not be loaded. // Parameters: // $FILE the file name // $ERROR the error message $aMessages[MSG_LOAD_MODULE] = 'Cannot load module from file \'$FILE\': $ERROR'; // MSG_LOAD_FMCOMPUTE is sent in an alert message if the form // specifies at least one "fmcompute" field and the FMCompute // module cannot be loaded. // Parameters: // $FILE the file name // $ERROR the error message $aMessages[MSG_LOAD_FMCOMPUTE] = 'Cannot load FMCompute module from file '. '\'$FILE\': $ERROR'; // MSG_REGISTER_MODULE is sent in an alert message if a module // could not register with FMCompute // Parameters: // $NAME the name of the module // $ERROR the error message $aMessages[MSG_REGISTER_MODULE] = 'Cannot register module $NAME with '. 'FMCompute: $ERROR'; // MSG_COMP_PARSE is sent in an alert message if a parse error // occurs in an fmcompute field // Parameters: // $CODE the code with an error // $ERRORS the error messages $aMessages[MSG_COMP_PARSE] = 'These parse errors occurred in the following '. 'code:\n$ERRORS\n$CODE'; // MSG_COMP_REG_DATA is sent in an alert message if FormMail cannot // register a data field with the FMCompute module // Parameters: // $NAME the field name // $ERROR the error message $aMessages[MSG_COMP_REG_DATA] = 'Failed to register data field \'$NAME\': '. '$ERROR'; // MSG_COMP_ALERT is sent in an alert message if the FMCompute // module has generated some alert messages. // Parameters: // $ALERTS the alerts $aMessages[MSG_COMP_ALERT] = 'The following alert messages were reported '. 'from the FMCompute module: $ALERTS'; // MSG_COMP_DEBUG is sent in an alert message if the FMCompute // module has generated some debug messages. // Parameters: // $DEBUG the alerts $aMessages[MSG_COMP_DEBUG] = 'The following debug messages were reported '. 'from the FMCompute module: $DEBUG'; } // Jump to: // // Load the default language, and then override with an optional language file. // function LoadLanguage() { LoadBuiltinLanguage(); LoadLanguageFile(); } // // To return the value of a string or empty string if not set. // function CheckString($ss) { return (isset($ss) ? $ss : ""); } $aGetMessageSubstituteErrors = array(); $aGetMessageSubstituteFound = array(); $bGetMessageSubstituteNoErrors = false; // // Worker function for GetMessage's preg_replace_callback calls. // Returns the value of the matched variable name. // Variables are searched for in the global $aGetMessageValues. // If no such variable exists, an empty string is returned and the // global variable $aGetMessageSubstituteErrors lists the missing names. // function GetMessageSubstituteParam($a_matches) { global $aGetMessageValues,$aGetMessageSubstituteErrors; global $aGetMessageSubstituteFound,$bGetMessageSubstituteNoErrors; $s_name = $a_matches[1]; $aGetMessageSubstituteFound[] = $s_name; $s_value = ""; if (isset($aGetMessageValues[$s_name])) $s_value = $aGetMessageValues[$s_name]; elseif ($bGetMessageSubstituteNoErrors) $s_value = '$'.$s_name; else $aGetMessageSubstituteErrors[] = $s_name; return ($s_value); } // // Returns message text from a message number, with optional parameters. // function GetMessage($i_msg_num,$a_params = array(), $b_show_mnum = true,$b_no_errors = false) { global $aMessages,$sLangID; if (!isset($aMessages[$i_msg_num])) { SendAlert("Unknown Message Number $i_msg_num was used",false,true); $s_text = ""; } else $s_text = $aMessages[$i_msg_num]; $s_mno = "[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()); session_start(); // // we set references to the appropriate arrays to handle PHP version differences // if ($bUseOldVars) { $aServerVars = &$HTTP_SERVER_VARS; $aSessionVars = &$HTTP_SESSION_VARS; $aFormVars = &$HTTP_POST_VARS; $aFileVars = &$HTTP_POST_FILES; $aEnvVars = &$HTTP_ENV_VARS; } else { $aServerVars = &$_SERVER; $aSessionVars = &$_SESSION; $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(); function ZapSession() { session_destroy(); } 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 addresse, // 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("^peter.scherschel@jpsnet\.net$"); // // 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","jpsnetnet@gmail.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 you 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). // // $REAL_DOCUMENT_ROOT is used for $FILTERS and $SOCKET_FILTERS settings. // If you're not using the "filter" feature in your forms, you don't // need to worry about this setting. // // 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" // $SET_REAL_DOCUMENT_ROOT = ""; // overrides the value set by SetRealDocumentRoot function // // ** 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're protecting your email addresses // you specify on 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",""); // // ** OPTIONAL ** // Set TARGET_URLS to a list of URL prefixes that are acceptable. // Currently, URLs are only used for the "crm_url" feature. // 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 make 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. If not specified (comment it out), // formmail.php uses "FormMail@SERVER" where SERVER is determined // from your web server. If set to "NONE", then no sender is specified. // //$FROM_USER = "formmail@yourhost.com"; // example - replace with your email address //$FROM_USER = "NONE"; // use this to show no sender $FROM_USER = "website@jpsnet.net"; // 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). // define("SENDMAIL_F_OPTION",false); define("SENDMAIL_F_OPTION_LINE",__LINE__-1); // don't modify this line! // // ** 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 FromUser 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. // 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. // // The only use we can think of 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. // // 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 an 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 // acusing 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 proveds 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 MODULEDIR to the directory on your server 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. // // If you are reserving a directory for FormMail modules, set the // directory in this configuration setting. // $MODULEDIR = "."; // // ** 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 enviroment 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. // // This is a security measure. Setting to false prevents attackers from // using your FormMail to send you malicious file attachments. // define("FILEUPLOADS",false); // set to true to allow file attachments // // ** 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 // // ** 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 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 // "fmencoder", 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. // define("CHECK_FOR_NEW_VERSION",true); // // ** 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 $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" (with 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); /* 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!!!) */ /*****************************************************************************/ // // override $REAL_DOCUMENT_ROOT from the value (if any) // provided in the config section // if (isset($SET_REAL_DOCUMENT_ROOT) && $SET_REAL_DOCUMENT_ROOT !== "") $REAL_DOCUMENT_ROOT = $SET_REAL_DOCUMENT_ROOT; $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 loo