This page is reference documentation for installing TFMail, software written by and available from The nms Project.

TFMail is one of many available programs that will email data entered into a web page form. Those programs are often called form-to-email, or just formmail, programs. They take over after an HTML form is submitted. The browser passes form field names and contents to the program via CGI.

How to install and configure TFMail is explained in 4 text files included with TFMail: README, README.dnsbl, EXAMPLES, and FAQ. This page offers an alternative, with very different explanations and organization, presented without examples, reasons, redundancy, and margins, to highlight symmetry, relationships, and the big picture.

Minimum to use TFMail

If nothing else is done, the template in the included file spage.trt will be used to create the resulting web page.

For security:

Your HTML specifies: the fields that users enter, the program (TFmail) to process those fields, and optionally the configuration file that specifies the text or files that specify the layout of the resulting page and email.

Configuration Files

There's so much more that can be done with TFMail, to customize it for your needs, by editing, and by creating and editing configuration and template files. Each run of TFMail uses one configuration file and any number of templates.

File Purpose Filename Extension Filename
set in as supplied set in default
Configuration CONFIG_EXT .trc _config field in HTML form default
Template TEMPLATE_EXT .trt 9 settings in configuration file see below

Put the configuration file and all the template files in the directory, relative to, specified by CONFIG_ROOT in With the file name, you can specify subdirectories with a maximum depth, under CONFIG_ROOT, as specified by MAX_DEPTH, default 0. The supplied TFMail if unaltered would require those files to be in the same directory as (ie, CONFIG_ROOT is '.' and MAX_DEPTH is 0). CONFIG_ROOT and CONFIG_EXT are also set in For security, put the configuration files where they won't be found or served via HTTP.

In configuration files, the first line needs to be %% NMS configuration file %%, and lines starting with # (may be preceded by space) are ignored. Settings, listed below, are assigned values by: setting: value (replace those 2 words with values listed below). Additional assignments to a setting add the values to the end of the setting. Values, except recipient, may contain the same directives available for templates.

Settings in and are in uppercase; settings in configuration files are in lowercase.

TFMail can be configured using which has 2 settings: LOCKFILE (initially '.lock'), and PASSWORD.

When a configuration or template file is not found, or _config is "", the resulting page says "Error; Application Error; An error has occurred in the program".


The output content from TFMail can by specified using templates. TFMail is named for its ability to use templates: Template Form Mail.

Output type Maximum per run First line in template file
Templates Output
Pages to display 5 1 %% NMS html template file %%
File insertions no limit no limit %% NMS email template file %%
Email to send 2 both %% NMS email template file %%

Each of the nine rows in the following three tables specify one template. All fields under the heading Set are set in the configuration file used for a submitted form. TFMail includes sample template files for 3 of the 4 default templates: spage.trt, missing.trt, and email.trt, but not log.trt.

Each template can be either in its own file, or in the configuration file (inline). If the latter, start it on the line after were you'd otherwise state the file name, omitting the line starting with %% NMS, and beginning each line with %; lines with only the % are ignored.

Web pages to display

The page that appears after a form is submitted is either: (1) created from a template, (2) at the specified URL, or (3) unchanged with an HTTP status code. Select only one of those 3 pages for each of the following 5 situations. If set to return a status code, then the template and URL are ignored. If a URL is specified, any template is ignored.

Situation Page template URL of page Status code only, no page change To enable
Set default Set Set Status Set to
IP address blocked blocked_template ? block_status 403: forbidden (default) block_lists DNS block lists (DNSBL)
Missing form fields missing_template missing missing_fields_redirect ? 400: bad request required form fields that shouldn't be blank
Success success_page_template spage redirect no_content 204: no content
GET accepted get_template get_redirect ? 204: no content 1 of them accept GET requests
Bad request method bad_method_template ? bad_method_status 405: method not allowed

When TFMail finds certain errors, it sends a short web page (XHTML 1.0 Transitional) to the visitor and appends one line with an error message to the server error log. The only difference between DEBUGGING set to 0 and 1, is 1 puts the error message also on the web page.

The success page, status code, or URL results after email is sent successfully, or would have been sent if no_email were not set.

The value for redirect may contain template directives.

GET is an HTTP request method. Bad request method means a method was requested that was neither POST (always allowed) nor GET (when you permit them). The missing and success conditions are possible only with POST.

Append and/or insert into files upon success

To enable writing to a file, set its name and directory in the configuration file. Request method must be POST.

Template Files written to
Set default Name Directory Extension as supplied
Append log_template log logfile LOGFILE_ROOT LOGFILE_EXT .log
Insert htmlfile_template_* * modify_html_files HTMLFILE_ROOT HTMLFILE_EXT .html

* in htmlfile_template_* is replaced with one of the the names to which modify_html_files is set. is an optional viewer for guestbooks. Included with TFMail is gb.trc, a sample configuration file for a guestbook. See an NMS TFmail guestbook example by Nick Cleaton.

LOGFILE_ROOT and HTMLFILE_ROOT must be changed from their default '' to allow writing to the files there. LOGFILE_ROOT and LOGFILE_EXT are also set in LOGFILE_ROOT also specifies the directory for a counter file (see below).

For inserting data, put <-- NMS insert above --> or <-- NMS insert below --> where you want the insertion. If not found, data is appended.

The value for logfile may contain template directives.

Email sent upon success

The handler is the person who handles the results of a form submitted by a user.

Email to Body template Subject (may include directives) From address (see default below) To address To suppress sending email
Set default Set Set to Set
Handler email_template email subject (default WWW Form Submission) email_input (realname_input) form fields recipient to addresses, or
recipient_input to form fields
no_email: 1 (default is 0)
User confirmation_template confirmation_subject (default Thanks) confirmation_email_from address same as handler from don't set confirmation_template

The default from address is the value of POSTMASTER set in Although, the default configuration (default.trc) has email_input set to email, and realname_input set to name.

For realname_input, you can specify multiple fields separated by white-space.

In the email header is put X-Http-Client: [] (remote IP address) and X-Generated-By: NMS TFmail v1.38 (NMStreq 1.16).

The value for subject may contain template directives.

The emails are sent only when request method is POST.

Minimum required email-related changes

Either put no_email: 0 in file default.trc to suppress sending email, or:

The email body will be created using the included email.trt file, unless you specify otherwise.

Template Directives, between {= and =}

Directive Value
by_submitter if the form supplies email or realname, it's {= by_submitter_by =} plus those.
date current date and time
session_id value of form field SessionID (details below)
counter number in a file incremented by TFMail (details below)
param.x value of form field x such as _config
env.x value of environment variable x (details below)
config.x value of x set in configuration file
opt.x value of x set in TFmail program
content_type.x MIME content-type of file uploaded via form field x
FOREACH x_field start of section to repeat for each x (input or missing) field (details below)
name form field name (put between FOREACH and END)
value value of current FOREACH form field
END end of section started with FOREACH or IF
IF x start of template section to use if x has a value
ELSE between IF and END, start of template section to use if x has no value

The template section between FOREACH and END is repeated once per form field. With FOREACH missing_field, only blank and missing fields that you required are included.

With FOREACH input_field, included are fields with values, and if print_blank_fields is 1, blank and missing fields also. Only form fields which start with a letter or number are included, to avoid unintentionally including _config and its value. No fields are included in confirmation email to avoid sending spam.

An IF without a parameter or with one undefined causes the ELSE clause, if any, to be used.

You can count the number of times a template is used by TFMail, at most once per TFMail run. Set counter_file to the name of a file, in directory specified by LOGFILE_ROOT, for TFMail to increment a number each time the first {= counter =} in a template is encountered. Request method must be POST.

Environment variables are set by the server. In generated email, consider including a link to the website (SERVER_NAME) and URL of the page containing the form the user submitted. For the form's URL, browsers don't always provide HTTP_REFERER, so consider also setting a hidden form field to SERVER_NAME plus REQUEST_URI, such as via SSI, although any field can be overridden using certain software.

Constants you may change

Constant opt directive Default/initial/supplied value Description Notes
DEBUGGING 0 include message on failure web page? L, C, G
MAILPROG '/usr/lib/sendmail -oi -t' sendmail or equivalent to send email
POSTMASTER 'me@my.domain' return-path, and when not supplied, from address
USE_MIME_LITE 1 use MIME for email? L, M
ENABLE_UPLOADS EnableUploads 0 allow upload of files to be attached to email L, M
n/a CGIPostMax 1000000 maximum size of CGI POST
CHARSET Charset 'iso-8859-1' character encoding C, G
n/a DateFormat %A, %B %d, %Y at %H:%M:%S local-date/time format (POSIX strftime) if not in config file
LIBDIR '.' directory for .pm files relative to D, C, G
MAX_DEPTH MaxDepth 0 max directory depth for config and template files L, G
CONFIG_ROOT ConfigRoot '.' directory for configuration and templates D, C, G
CONFIG_EXT ConfigExt '.trc' extension for configuration file name C, G
TEMPLATE_EXT TemplateExt '.trt' extension for template file name G
LOGFILE_ROOT '' directory of log file to append to Q, D, C
LOGFILE_EXT '.log' extension for log file name C
HTMLFILE_ROOT '' directory for HTML files to insert into Q, D, G
HTMLFILE_EXT '.html' extension for HTML file name G
SESSION_DIR '.' directory to put session information D

Note L: 0 means off or no; 1 means on or yes. Note Q: The '' (two single quotes) means don't write to the file. Note D: relative directories are relative to

Note M: MIME is used to send email if and only if you set USE_MIME_LITE or USE_MIME_LITE to 1 or any true value. MIME is implemented by module MIME::Lite. If it's installed with perl, that one is used; otherwise, the one included with TFMail is used. If you allow uploads, MIME is used, ignoring USE_MIME_LITE.

Note C: also in which also has LOCKFILE and PASSWORD. Note G: also in


For a multi-page form, TFMail can create a session ID that can be remembered on subsequent pages, between calls to TFMail. One method is to set session_cookies to 1 (instead of the default 0) to have TFMail look for or create a session cookie on the user's computer. Another method is to set session_field to a hidden form field so {= session_id =} is set to that value if it has one, otherwise to a new session ID. Set SESSION_DIR to the directory to store session IDs; TFMail comes with it set to '.', the same directory as

Whereas a POST request method is always allowed, a GET request method is allowed only when permitted by the configuration file, and will neither update the counter file, nor result in the missing or success pages, nor write to the log or insert files. A GET request method creates a session (cookie or field) which is used and removed with a later POST request.

I don't understand sessions. What am I missing?

Template output settings

Set Default Description
address_style 0 for email (realname) Set to 1 for realname <email>
sort order in form Sort order from {= FOREACH input_field =} template directive
print_blank_fields 0 To have FOREACH include blank fields, set this to 1.
by_submitter_by by Beginning of {= by_submitter =} if the form supplies a from address
date_fmt %A, %B %d, %Y at %H:%M:%S Format for {= date =}
locale server's locale Locale for names of months and days in {= date =}

CHARSET in all 3 .pl files, initially 'iso-8859-1', sets the character encoding for all output, and should match user input.

Attachments of uploaded files

To accept, via the form, HTTP uploaded files that will be attached to email sent to the handler:

Also, for each form field that will be a file to upload and attach:

File attachments are type application/octet-stream, encoding base64.

When a newer TFMail is released

Generally only the program (.pl and .pm) files are replaced when a new TFMail is released.

  1. Download newer from
  2. Unzip it. All files in are text files in directory tfmail, so no need to extract to its own directory.
  3. Optionally determine which programs you use have been updated; the remaining steps need be done only on those.
  4. Copy only your customizations to the .pl files of the previous version to the new ones. Comment with date and your name.
  5. Copy the new program files to the server.
These 3 program files are always used with TFMail: 1.38 2006-2-9 Program called from web forms. Never use as supplied. 1.16 2004-10-12 Handles configuration, templates, and CGI. 1.1 2002-7-30 Charset-aware object for handling text strings.
These 3 program are optional: 1.1 2002-5-25 For email, but only if MIME used and MIME::Lite not installed. 1.4 2004-7-28 Helps configure TFMail. 1.5 2004-10-12 Uses a a template to display data in a file generated by

The three .pm (module) files go into the directory specified by LIBDIR in the three .pl (program) files. The default directory is '.', the same directory as the .pl file. All six files are written in Perl.

Generally, the three .pl (program) files are customized by you, and the three .pm (module) files are used as they are supplied.

In each TFMail distribution, all files have the same date, even though some files are the same as in the previous release.

Files you probably don't want replaced when a newer TFMail is released

Be careful not to lose your modified configuration and template files when installing a newer TFMail.

By default, these 3 are used:
default.trc configuration You need to change recipients line.
spage.trt template for success page
email.trt template for email to handler
These 2 are not used unless you specify:
gb.trc configuration for guestbook
missing.trt template for when form fields are left blank

Of the above five files, all may be used as supplied except for default.trc.

The 6 documentation text files included with TFMail (MANIFEST, README, EXAMPLES, FAQ, ChangeLog, and README.dnsbl) don't need to be on the web server.


Formmail Hijacking

Contact forms on the web are used to send spam and to obtain email addresses. With some form-to-mail programs, anyone can: (1) obtain the email addresses to which the resulting email is sent, (2) send email to any email address, and (3) send spam to the addresses to which the form is configured to send email. Although TFMail does not fail to stop (3), it does stop (1) and (2) except to email the failed attempts to the addresses to which the form is configured to send email. There are programs that scan or search the web to find contact forms to abuse, and do it without human interaction. Here are 7 things you can do:

To stop email caused by posts to TFMail without anything from your form, either remove default.trc (will cause error log entries), or modify default.trc so that either no_email is 1 (wastes processing time) or requires is set (will use missing-fields template).

Subroutines in the Perl code

The following subroutines are called from main in Those subroutines call the subroutines listed within { braces }.

The following subroutines are called from the subroutines listed within braces above.

The following subroutines are in

At, site for development of open-source software

The earliest date in ChangeLog is 2002-4-30 for TFMail 1.1, 1.2, and 1.3. The first release listed in SourceForge is 1.10 (1.ten, not 1.1) released 2002-5-24.

Information elsewhere on the web

About this page

This page's 21 sections: top, minimum, configure, templates, pages, insert, email, email-min, directives, constants, sessions, settings, upload, update, once, permissions, spam, subroutines, SourceForge, elsewhere, about.

This document is not entirely accurate. I welcome corrections. Sometimes details take too much space, so a more elegant solution should be found for either the documentation or program.

This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License or the same license Perl and TFMail use. You pick. Some rights reserved. Give credit where due.

This page, last changed 2007 March 29, was written by David Cohen, using information learned from the NMS website and by using TFMail.

There are other Internet-related pages on this website.