Soupermail - a generic CGI WWW form handler written in Perl
<form method="post" action="/cgi-bin/soupermail.pl">
Soupermail is a generic HTML form handling script designed to provide a high degree of control over a form's behaviour and output. It provides the following features:
Soupermail can be used to handle single standalone forms, or generate and control complex multipart forms.
Soupermail assumes some form fields have special meanings. These field names ARE CASE SENSITIVE. The following is a list of such fields:
Soupermail is controlled on a per form basis by using configuration files. Each form handled by soupermail must have an associated configuration file.
The location of the file is passed to soupermail through the PATH_INFO CGI variable, or by using 'SoupermailConf' as a form parameter. The PATH_INFO is set by providing a path after the call to soupermail in the <form> element of the HTML page.
<form method="post" action="/cgi-bin/soupermail.pl/forms/config.txt"
>
or as a form variable with:
<input type="hidden" name="SoupermailConf" value="/forms/config.txt"
>
The second method of supplying the config file is recommended. People running under a cgiwrapped environment will have problems with the first method, and even worse, the IIS webserver defaults to not supporting the PATH_INFO method.
The path to the configuration file must be relative to the web server's root directory. Do not use URLs or absolute paths to the configuration file.
The format for a configuration file is a series of configuration statements of the form:
name : value
or
if : condition then name : value
or
unless : condition then name : value
If a badly phrased or incorrect configuration file is passed to soupermail, it will complain, so always check your soupermail configurations carefully.
Valid names for the configuration file are:
mailtemplate
,
the form fields are displayed in the email in alphabetical order.
Setting this value to no does not sort the fields, and returns them
in the same order that the browser sent them.
sendertemplate
and
htmlsendertemplate
. X is a number identifying the attachment.
See also listattachmentX
attachment1 : /forms/download/myfile.pdf attachment3 : file2.doc
See also listattachmentXmime
attachment2 : /wordfile.doc attachment2mime : application/x-msword attachment5 : /forms/download/myfile.pdf attachment5mime : application/pdf
mailto
addresses. See also senderbcc
.
blank : /forms/config/blank.tpl
blank
template. Also
see successmime
, expiresmime
and failuremime
.
filereadable
config command actually work.
cookie1domain : myhost.domainname.com
Will only send cookie1 to pages on the myhost.domainname.com webserver. See the section on COOKIES for more information.
Absolute dates and times can also be specified.
See the section on COOKIES for more information.
cookie1expires : 1-4-1999 12:00:00
will expire the first cookie at midday on 1 April 1999.
cookie2expires : +1M
will expire the second cookie one month from when the form was submitted
By default, cookies expire 24 hours from when they were set.
cookie1name: zippy
sets the first cookie's name to 'zippy'
cookie3path : /products
Would only send cookie 3 to pages below the /products directory of a website.
yes
, this specifies that counter X will be incremented
if a blank form is submitted.
yes
this specifies that counter X will be incremented
if the form is submitted after its expiry date.
yes
this specifies that counter X will be incremented
if the form is missing required fields.
yes
this specifies that counter X will be incremented
if the form is submitted successfully. The default is to increase the counter
by is 1.
mailcharset
option, then Subject lines are encoded as described in RFC 2047.
http_config_error
. If an
error is set, SQL commands will not run, and Soupermail will run in a
failure mode.
expires : 24-12-1998
This means the form would not be submittable after the 24st of December 1998
expirestemplate
is sent
out. See also successmime
, blankmime
and failuremime
.
failure : /forms/config/bad.tpl
failure
template is sent
out. See also successmime
, blankmime
and expiresmime
.
fileattop
, new data can be written
at the start of the file (although after any specified header).
fileattop : yes
filemaxbytes
limit.
The value for this can include formatting codes as listed in the FORMATS section of this document. This lets you generate a number of backups with a very fine level of detail.
The value specified in filereadable
will affect any backup files generated.
filebackupformat: /files/backup.txt
would always backup the file to /files/backup.txt
filebackupformat: /files/%yyyy%%mmm%%dd%backup.txt
would backup to /files/19980801backup.txt on 1 August 1998.
filemaxbytes
, then the file will be cleared of all other entries.
If you would like to save backup copies of the file, rather than simply
deleting it, specify a filebackupformat
as described above.
To force a deletion after each entry, set the filemaxbytes to 1. Note that setting it to 0 (zero), effectively resets filemaxbytes, and so has no effect.
filemaxbytes: 10000
filepgpuserid
to securely store data.
filepgpuserid: [email protected]
Will store data encrypted for [email protected]
filereadable
, the file can be made readable by the
webserver.
Note that this only affects people reading the file from a web browser, it does not secure the file from other types of access (eg. from FTP or through the filesystem). So, don't go storing credit card numbers in a file unless you're damn sure that your machine's secure.
filereadable : yes
fileto
. See the section on TEMPLATES for more
information.
fileto : output/out.txt
If no filetemplate
is given, the output form a form is written as a series
of lines matching:
name = value[,value ...]
Where a form field has multiple values, these are listed separated by commas.
fileto
.
blank
field, the file is not a template, and so should not contain
<output> elements. CGI variable replacement can be used in the value of gotoblank
to achieve PIPELINING.
gotoblank : http://myserver/errors/blank.htm
expires
date.
CGI variable replacement can be used in the value of gotoexpires
to achieve PIPELINING.
failure
entry, this is not a template
and should not contain <output> elements. CGI variable replacement
can be used in the value of gotofailure
to achieve PIPELINING.
gotofailure : http://myserver/errors/failed.htm
success
field, this is not a template and should
not contain <output> elements. CGI variable replacement can be
used in the value of gotosuccess
to achieve PIPELINING.
gotosuccess : http://myserver/forms/success.htm
gnupg
to yes in your configuration. If you do not,
then Soupermail will assume encryption is using PGP. This command is now
deprecated in favour of pgpversion
.
fileto
.
listtemplate
must be used for mailing lists to work.
If you specify both htmlmailtemplate
and mailtemplate
a mixed
text and HTML message is generated. This will allow people who don't have
HTML capable mail clients to read your mail.
htmlmailtemplate
is sent to the mailto
address, this
template is used when sending mail to the submitter of the form. It behaves
in the same way as htmlmailtemplate
when it comes to link handling.
ignore
them so that
you can check for situations where the user doesn't complete any fields. Only
one form field can be specified on an ignore line. Use multiple ignore lines
if you wish to ignore more than one field. The soupermail special form
variable SoupermailConf
is ignored automatically.
ignore : hidden1 ignore : hidden2
This would ignore the values of fields 'hidden1' and 'hidden2' when determining if a form was left blank.
if : (division eq 'Accounts') then mailto : [email protected]
This would set mailto
to [email protected] if the form contained
a field called 'division' and its value was 'Accounts'.
iscreditcard: creditc
If the validation fails, the failure
template is activated. Validation will
not fail if the field is left blank.
attachmentX
.
attachmentXmime
for the syntax.
senderbase
and
mailbase
.
sqlname
, sqluser
, sqlpassword
and appropriate sqlbind
values have been set. listsql
is an SQL command in the
same format
as sqlrunX
commands.
The data returned from the SQL statement must have the user's email address as the first column.
htmllisttemplate
must be specified for a
mailing list to work.
mailto
address, Soupermail inserts a
Content-Location email header based on the submitting form's URL. Use this
option to modify it for your own needs. Similar to senderbase
and
listbase
.
mailbase : http://www.example.com/graphics/
maillist : /forms/config/mynames.csv
mailtemplate : /forms/config/mail.tpl
mailto : [email protected], [email protected], [email protected]
mimeon : yes
This would allow MIME attachments to be sent.
nofilecr
will do this.
nofilecr : yes
This would remove newline characters from fields written to a file.
nomailfooter : yes
success
template in your config file. See the MAKING PDFs section for more
details.
mailto
email recipient as an email attachment. It can be used
in conjunction with mailtemplate
and htmlmailtemplate
.
sendertemplate
and htmlsendertemplate
.
pgpserver : pgpkeys.mit.edu
pgpuserid : [email protected]
ref : REF%yy%%mmm%%dd%%rrrr%
This may generate a reference like: REF9704016364 on April 1 1997
replyto : [email protected]
required : ((name && address) || telephone)
The above expression requires either the fields name and address to be completed, or the field telephone to be completed.
returntosender : yes
listbase
and
mailbase
.
sendertemplate
is specified.
See also bcc
.
sendertemplate
, the email address used in the email back to
the form's sender is set to this. The preferred order email addresses are
chosen for the sender's From field is:
This field is useful if you need an auto-reply function from your form, but don't want to obviously expose the mailto address directly to the sender of a form.
sendertemplate
config option.
sendertemplate
, this is a subject line only to
be used in email messages send directly back to the form's submitter. If its
not set, the subject line set with the subject
config line is used.
mailto
or replyto
configuration values. See the section on TEMPLATES for
more information.
sqlbind
command allows you to specify a variable that will
be used in the next SQL statement specified by a sqlrunX
command.
sqlbind2: "$form_second_field" sqlrun1: SELECT * FROM TABLE WHERE field1 = ? AND field2 = ?
In this example, the value of the form field "second_field" is used to replace the second question-mark value in the SQL statement.
Binding does all the character escaping needed by the SQL, so there is no need to enclose strings in single quotes.
sqlname: dbi:mysql:database=test;host=mysql.example.net
sqluser
.
sqlpassword: my_random_password
sqlrunX
command. Statements are
executed in the order they are seen in the config file, working from
top to bottom.
The number at the end of the sqlrunX
name is used to
identify the results of the command for later use in the config
file and in templates.
Variables that you want to use in your SQL command that come from
form, cookie or counter data must be passed in by binding the
values. Binding involves using a question-mark character to represent
a variable, and setting a sqlbind
command to indicate something to
use.
sqlbind1: "$form_name" sqlrun1: SELECT id FROM users WHERE name LIKE ?
The bind command attaches the value of the form field to the first question-mark in the next SQL statement. In this case, if the value of the form field 'name' was 'fred', then the SQL command would become:
SELECT id FROM users WHERE name LIKE 'fred'
For security reasons SQL commands will not run if there are required, or invalid field types.
sqlpassword
.
sqluser: root
subject : This is a feedback email
success : /forms/config/success.tpl
success
template. Values given here should
be of the form word/word
. Its related to the failuremime
,
blankmime
and expiresmime
config commands.
successmime : text/xml; charset=utf8
if
command, but performs the opposite
of what the if
tests do. Using this, you can check for when values are not
set. See the section on CONDITIONAL STATEMENTS for more information.
wrap : 60
Sometimes it is useful to concatenate some of the configuration values, for
instance where you need to specify more that one mailto
recipient based
on the user's input. In order to do this, you can use the following variables
in you configuration files:
mailto
in the configuration. This will be
expanded to the value when the configuration is parsed.
mailto : [email protected] mailto : "$mailto, [email protected]"
This example initially sets mailto
to [email protected]. Then it sets
mailto
to [email protected], [email protected]. Notice that the expansion
occurs only if the value is enclosed in double quotes (").
subject
subject : Feedback of type - if (feedtype eq 'comment') then subject : "$subject Comment" if (feedtype eq 'problem') then subject : "$subject Problem"
This example changes the subject
based on a field in the original form
called 'feedtype'.
replyto
field.
replyto : [email protected] if : (interested has 'rod') then replyto : "$replyto, [email protected]" if : (interested has 'jane') then replyto : "$replyto, [email protected]" if : (interested has 'freddy') then replyto : "$replyto, [email protected]"
If the form contained a set of checkboxes all called 'interested' with the values of 'rod', 'jane' and 'freddy', this configuration will add the email addresses of rod, jane and freddy depending upon which checkboxes were set by the user.
$http_user_agent
will return the web browser name.
Subject: "Form response from $form_TheirName"
Subject: "The cookie named Bungle has value $cookie_Bungle"
Replacements can only be used when setting the subject, mailto, replyto, reference number and cookie value fields.
Replacement value will only be used when they are enclosed in double-quotes. So, the following will NOT work:
However, this will work:
Conditional statements in configuration files allow you to control the configuration of a form based on the user's form input, values from a users cookies or any of the http_ variables. A conditional statement is made up of a boolean expression followed by a configuration statement.
if : boolean_expression then configuration_statement
or
unless : boolean_expression then configuration_statement
The only configuration statement disallowed in a conditional statement is another if or unless.
Conditional statements are executed in the same order that they appear in the configuration file.
A boolean expression is something that can either be true or false. If it's true, then the configuration statement is set, otherwise it isn't.
The simplest boolean expression is just the name of a form field. If the form field was completed by the user, then the boolean is true.
subject
line based on this name being set, you could use the
following configuration statements:
subject : They haven't set their name if : name then subject : They have set their name!
Initially, subject is set to 'They haven't set their name'. However, if the 'name' field is completed on the form, the conditional statement is activated and the subject is reset to 'They have set their name!'.
If you want to check on cookies, prefix the cookie's name with $cookie_. So, if you wanted to test if the user had sent a cookie called "MyName", use a condition like this:
if: $cookie_MyName then Subject: "Cookie MyName was set to $cookie_MyName"
Boolean expressions in soupermail use three basic operators, AND (&&), OR (||) and NOT (!). An expression with an AND in will be true if BOTH of the things around the AND are true. An expression with an OR in will be true if one or more of the things around the OR is true. An expression preceded by a NOT will be true if the thing following it is false.
x || y will be true if x is true or y is true
x && y || z will be true if x and y are both true, or x is true.
!x will be true if x is false.
Boolean expressions can contain any number of smaller boolean expressions. To make life easy, you can group these with brackets "(" and ")".
name && (address || telephone || Email)
Notice the use of brackets, to enclose the ORs. If the brackets were missed out, the expression would have meant the user must complete their name and address, or their telephone, or their email; or as a boolean expression:
(name && address) || telephone || Email
This is because AND is considered to be more important than OR.
If you have form fields that contain spaces, you can still use them in boolean expressions, but you must enclose them in double quotes (").
<input type="text" name="First Name">
Any boolean expression using this field name must use it quoted:
"First Name"
Other operators available in boolean expressions are:
if : age == 45 then subject : You are 45
if : age != 50 then subject : You are NOT 50
if : age
<= 50 then subject : You are younger than 51
if : age
>= 50 then subject : You are older than 49
if : age < 50 then subject : You are younger than 50
if : age > 50 then subject : You are older than 50
if : name eq 'Humphry' then subject : You are called Humphry
if : name ne 'Humphry' then subject : You are NOT called Humphry
if : name contains 'on' then subject: Your name contains the letters on
The above example would match names such as "Ron" or "Donna".
if : name longerthan 5 then subject: Your name has more than 5 characters
if : name shorterthan 5 then subject: Your name has less than 5 characters
Soupermail uses a series of templates specified by the configuration file to control the output, either to the screen, a file or to email. All the template locations should be specified relative to the location of the configuration file, as absolute paths (things starting with a '/' character) from the web server's root, or as private paths (things starting with a '~' character). The basis for a template are the HTML-like elements called <output>, <only> and <loop>.
Templates can be used for emails, files and pages returned to the browser. Templates returned to the browser can be given different MIME types, meaning you can return things like WML for WAP sites.
When sending HTML email templates, you can set the base for images embedded in
the email with the listbase
, mailbase
and senderbase
commands.
The <only> element defines a block in a template to use if its if attribute is matched. The if attribute should contain a boolean expression. See Boolean Expressions for more information about what the if attribute can contain.
Its December, so here's December's calendar:
<!--#include virtual="dec.txt"-->
</only>
<only> elements cannot be nested, but they can contain any number of <output> elements and includes.
<loop> elements allow one part of a template to be repeated multiple times. Using loops, you can repeat a section of template a fixed number of times, or loop through the values of form field.
Loops can take five attributes:
To get the value out, surround the loop's name by @ characters inside the loop block.
<loop name="loopvalue" start="1" end="5"> @loopvalue@ </loop>
This loop will return '1 2 3 4 5'.
<loop name="loopvalue" start="1" end="5" step="2"> @loopvalue@ </loop>
This loop will return '1 3 5'.
<select multiple="multiple" name="multiselect"> <option>value one <option>another value <option>yet another value </select>
you can use the following loop to get the values:
<loop name="selectfield" field="multiselect"> One of the values is @selectfield@ </loop>
The <output> element can be considered as analogous to the HTML <input> element.
Where an <output> element appears in a template, Soupermail replaces it with some appropriate text. The value of the replacement text depends upon the attributes specified in the <output> element.
The following is a list of attributes that can be placed in template <output> elements.
name
attribute is replaced in the
<output> element. However, using altvar
, another variable
can be used if name
hasn't a value.
<output name="month" altvar="http_date" format="%mmm%">
charmap
attribute allows a character to be changed to a string (or removed). The
format for the charmap
attribute should be the character to change,
followed by a comma, followed by the string to change it to.
<output name="fieldname" charmap='",""'>
To remove all occurrences of the letter 'a':
<output name="fieldname" charmap="a,">
To turn underscores into hyphens:
<output name="fieldname" charmap="_,-">
data
attribute
can have the following values: number, notnumber, integer,
notinteger, email, notemail, creditcard, notcreditcard
If the check fails, then the output element will return its alt
value.
<output name="foo" data="number" alt="fail" sub="pass"> = pass
<output name="foo" data="integer" alt="fail" sub="pass"> = fail
<output name="foo" data="notnumber" alt="fail" sub="pass"> = fail
<output name="foo" data="notinteger" alt="fail" sub="pass"> = pass
<output name="foo" data="email" alt="fail" sub="pass"> = fail
The credit card check is a simple LUHN checksum that makes sure the number given looks like a credit card number. It does not mean the number is a real card number, or that there's any money in the account.
list
.
list
attribute to ul|ol|menu|dir|text, a
specific type of HTML list can be achieved. The text value will return a
non-HTML text list. The format of this text list can be controlled by the
delim
attribute.
math
expression, and they will be
replaced before the expression is evaluated. Values that are undefined or
non-numeric are replaced by zero. If the name
attribute is multi-valued,
the math
expression is evalued for each value.
The following are the maths operators available:
*
sum()
count()
To add two fields together:
<output name="field1" math="field1 + field2">
To calculate an average of a number of fields:
<output name="field1" math="(field1 + field2 + field3) / 3">
newline
has the value html, then newline characters
are converted to <br> tags. If it has the value of none, then
newline characters are replaced by spaces. If it has a value of
unchanged then newlines are left as is. The value of paragraphs
replaces breaks of more than 2 newlines with only 2 newlines - useful
for formatting plain text entries.
alt
or sub
attributes. For multivalue entries, the post
section is placed after each
list item.
alt
or
sub
attributes. For multivalue entries, the pre
section is placed
before each list item.
math
attribute, this value is the number of
decimal places to display numbers to.
altvar
attribute, but comes into play when the
variable set be the name
attribute has a value.
[+|-]
num[smhdMy]
Where, the initial plus and minus indicate the direction of the offset,
num represents how much to offset by, and s
indicates an offset in
seconds, m
an offset in minutes, h
an offset in hours, d
an
offset in days, M
an offset in months and y
an offset in years.
<input type="text" name="val">
and this in a template:
<input type=hidden name=val value="<output name="val">">
and the user's typed something like this into the field:
The "sum" is > than the "parts"
If you don't escape the output tag, you get broken HTML like this:
<input type=hidden name=val value="The "sum" is > than the "parts"">
However, if you used <output name="val" type="html">, you'd get:
<input type=hidden name=val value="The &#34;sum&#34; is > than the &#34;parts&#34;">
which is HTML safe.
name
has a value, it is returned by the
<output> element. However, if value
is set, it is only returned
if its value equals that of value. The alt
attribute will become active
if the values do not match and the sub
attribute will become active if
they do match. This may sound pretty daft, but its
useful for regenerating drop down lists in multipart forms. See the
Multipart form example that comes with Soupermail.
value
attribute, but affects the use of altvar
and
subvar
replacement.
Server Side Includes (SSI) are a means of dropping one file into another before sending a page onto the user's browser. Soupermail can provide a basic inclusion mechanism using the same syntax as normal SSI directives. Soupermail will only handle <!--#include virtual="..."--> type includes, #exec is too much of a processing burden. The path can either be an absolute path from the server's root, or a path relative to the location of the config file.
If you are putting the include into a HTML page, and don't want characters like < to be specially treated by the browser, then you should put the type="html" attribute in the include call: <!--#include virtual="..." type="html"-->. ALWAYS do this if you do not trust the source of the include.
CGI variables are set by the web server, and in some specific cases, Soupermail. These names should not be used as field names in your HTML forms.
error
config command.
mailist
line of data. X is the
column number of the data to use. Columns start at one (the email
address). See MAILING LISTS for more information.
Formats allow the http_time, http_date and http_ref variables to be controlled. A format is a one line string containing the following substrings. When the <output> element is expanded, the substrings are expanded into the following:
format="%cccc%"
which would give you something like:
1234 5678 9876 5432
format="%ccc%"
would give you:
123 456 789 876 543 2
Non-numeric characters are removed from the value.
Counters are a way of storing and reading the number of times Soupermail has done something. They are specified in the configuration file, and you can have any number of them in use. In their simplest guise, you can use them to count how many people have submitted a form. More complex uses include setting the maximum number of times a form's submitted, online voting systems and renaming the filenames form information is saved to.
The behaviour of counters can be slightly odd for the unwary. Firstly, they are always defined in the config file, but simply declaring a counter file does not mean it gets updated, its value just becomes available for the config file and for templates. To update a counter, an onsuccess, onfailure, onblank or onexpires setting for the counter must be set.
Secondly, the value returned by a counter in the config file is the value stored in the counter file BEFORE any increments have been performed on the counter, however, the value returned in templates and the http_ref value are set AFTER increments have been applied to the counter.
mailto: [email protected] counter1file: counters/count1.txt counter1onsuccess: yes if : ("$counter_1" == 10) then setcounter1 : 1 if : ("$counter_1" == 10) then mailto : [email protected]
The above example would result in counter1 being set to 1 and the mailto
address set to [email protected] whenever the counter reached 10.
Note that even though the
setcounter1
is set in the config file, it does not have an immediate
effect, and does not prevent the second if
statement being used.
Cookies were introduced in Netscape Navigator 2.0. They are a means of storing information on the user's browser even after they've turned off their computer. Soupermail allows up to nine cookies to be set, each cookie holding at most 516 characters worth of data, and with a cookie name less than 50 characters long. The restriction on the cookie size and number of cookies is mainly out of politeness, because its not considered nice to flood users with cookies.
More information on cookies can be found at http://home.netscape.com/eng/mozilla/3.0/handbook/javascript/index.html
PGP is a means of encrypting text through a public key and decrypting through a private key. Using PGP, Soupermail can send secure encrypted email over an insecure Internet.
To use PGP, you will need to place a public keyring (pubring.pkr for PGP 5, pubring.pgp for PGP 2.6.3 or pubring.gpg for GPG) in the directory where your form's configuration file is located. In your configuration file, set pgpuserid to be a user in the pubring keyring. When soupermail generates an email, it will encrypt the message using the public key of the given user. By default, this version of Soupermail assumes that GPG is being used.
As of Soupermail 1.0.3, GNU Privacy Guard (GPG) is supported as an alternative
to using PGP. Using GPG rather than PGP differs only in that the public
keyring file is called pubring.gpg. The pgpversion
config option must be set
to choose between the different encryption methods. See the GPG documentation
for more information.
If you have problems using PGP or GPG, make sure your webserver has the ability to run the scripts - some server installations may not give the nobody user rights for this. Generating a debug file is the best diagnostic option.
Versions of Soupermail greater than 1.0.8 have support for PGP 5.0i and 2.6.3i (I've only tested the international versions so people using US versions may have different results).
You can also specify a PGP keyserver in the configuration file. If specified, the PGP encryption will look on the key server for encryption keys. THE PGP KEYSERVER CODE IS EXPERIMENTAL AND HASN'T BEEN TESTED! USE AT YOUR OWN RISK!
For more information on PGP, please look at http://www.pgpi.org/
For more information on GPG, please look at http://www.gnupg.org/
From version 1.0.7, Soupermail can generate Adobe PDF files by hooking up to lout and ghostscript.
Lout is a nifty document formatting language, which is used to generate postscript files. Ghostscript is a postscript processor which can generate PDF files (amongst other things).
To use this feature, you're going to have to look into how lout templates work.
Its a powerful language, so spend some time delving though the documentation
that comes with lout. Basically, Soupermail hooks into lout by allowing
you to use <output> elements in lout templates. Soupermail reads
the lout templates you specify with the pdftemplate
config options, fills
in the <output> elements, then passes this on to lout and
ghostscript to handle. The results can be emailed out, or returned to
the browser depending on the config options you have used.
One of the nice things about using lout and ghostscript together is
the ability to include EPS images in your generated PDFs. To do this,
place your EPS files in the same directory as your lout templates and
use lout's include image command in your templates. Soupermail assumes that
EPS files end in a .eps
file extension.
The Soupermail example files contain an example of using Soupermail's PDF commands.
To use the PDF commands, you'll need to install GhostScript from http://www.cs.wisc.edu/~ghost/index.html and Lout from ftp://ftp.cs.usyd.edu.au/jeff/lout/.
Version 1.0.7 of Soupermail brings along mailing lists, which are ways of
sending Soupermail generated email to a set of people defined in a
file. To do this, you should specify a maillist
file in your form's
configuration. The maillist
file should be a set of lines, each one
starting with and email address, and with other optional columns following,
separated by commas.
[email protected],Mr Foo,nothing special [email protected],"Bloggs, Fred",geezer [email protected],XYZ Man,unable to think of a better name,other stuff
As you should see from the example, there can be any number of extra
columns of data in the file. When Soupermail is given a mailing list file,
it generates an email for each address in the file based on the
listtemplate
and htmllisttemplate
config options. However, these
templates can also take data from extra columns in the maillist file
and use them in <output> elements.
listtemplate
contains the following:
Hi
<output name="maillist_2"
>, Email:
<output name="maillist_1"
>
Then the email sent out to [email protected] would contain:
Hi Mr Foo, Email: [email protected]
the email sent out to [email protected] would contain:
Hi Bloggs, Fred, Email: [email protected]
and the email sent out to [email protected] would contain
Hi XYZ Man, Email: [email protected]
Email addresses and other column data is not shared between the email addresses in the list. However, if your list is private, you should ensure it isn't browsable from the internet.
Sometimes, you don't have your mailing list data in a file - to handle this, there
are two other sources of list information. It is possible to pull list information
from a form field using the listformfield
config command to provide
the list data. The format of the list data provided by the form field should
be the same format as for the data file - ie. email as the first field, with
other fields separated by commas.
Even more useful, it is possible to pull mailing list information from a
SQL database by using the listsql
command. This specifies a SQL statement
which returns a table, the first field of which should be an email address.
It is possible to attach files to emails sent out with a mailing list using
the listattachmentX
and listattachmentXmime
commands.
Other list config commands are: listsubject
, listfrom
and
listreplyto
.
Pipelining Soupermail allows you to use Soupermail to process a form and then send on the original information to another URL for processing. This is useful if you want to use Soupermail as a logger, or as a quick email function to another web application.
To use pipelining, you need to use the gotosuccess
, gotoblank
,
gotofailure
and gotoexpires
config commands. These commands
usually specify a URL to go to once Soupermail has finished, but they
can also be used dynamically by using variable replacement of
CGI VARIABLES.
success: http://www.example.org/myscript?
foo=
bar
Now though, suppose I want to send whatever the user typed into one of my form fields (eg. myfoofield). I can use the following:
success: "http://wwww.example.org/myscript?
foo=
${form_myfoofield}"
Some things to notice; The value of the config command has been wrapped in double quotes - this allows CGI value replacement to happen. The CGI value replacement is wrapped in { } braces - this makes it easier to distinguish the value.
What about sending multiple values? Well, you can have things like:
foo
=${form_myfoofield}
&
baz
=
${cookie_myBazCookie}
Here, foo is set to whatever value myfoofield was in the original form, and baz is set to whatever value the cookie myBazCookie has. The ampersand (&) character is used to separate the values.
For those of you who may be doing advanced pipelining, you should know that URI escaping is only done to replaced values. So, this is wrong:
foo=my value&baz=${form_baz}
The space is illegal in URLs. It should be:
foo=my%20value&baz=${form_baz}
As from version 1.0.8, Soupermail has included support for database access. It can be used to query, insert, amend and delete records in a database. The commands used for this are:
One important feature of Soupermail is the ability to use the values
returned by SQL SELECT statements in your config files and in templates.
All sqlrunX
commands have an identifying number. All SQL commands
that return a table populate a two dimensional array of values. Used
in conjunction with the command number, it is possible to get
any return value from a SQL command.
1 | foo | boo |
2 | dish | dash |
3 | moo | maa |
Then, we have the following in our config:
sqlrun1: SELECT * FROM test
We can get values back from this by using the variable sql_[command_number]_[row_number]_[col_number]. In config files, this value should be prefixed with a $ sign.
In a config file:
if: "$sql_1_3_1" then subject: The test table has at least 3 rows
In a template:
The third field on the second row of the table test is:
<output name="sql_1_2_3"> = dash
To make use of database support with Soupermail, you'll need perl's DBI module installed, and an appropriate DBD driver for your database. This driver must support placeholders and bind values. Consult your DBD driver's manual for more information on this.
From version 1.0.8, it is possible to store configuration files, attachment files, templates and writable locations outside your webserver's document tree. This is to allow you to store information without it being viewable with a browser.
Not all ISP's will provide you with a directory outside your document tree, so you may need to ask their support staff for an appropriate location.
To call a config file in a private root, prefix the filename with a '~' character when setting SoupermailConf.
<input type="hidden" name="SoupermailConf" value="~/subscribe/sub.con">
Looks for a config file $privateRoot/subscribe/sub.con
One security restriction on private roots is that config files outside the private root cannot read data from inside the config root. ie. You can not have a config file outside the private root calling a template inside the private root. The aim of this is to save you if someone manages to write a config file on your server. See the section on SECURITY for more information about making Soupermail paranoid.
With the introduction of database support, Soupermail has become a bit of a security headache for the consciencious webmaster. Here are some tips about using Soupermail in a secure manner.
Firstly, NEVER put a database password and username in an unsecured config file. If the config file can be read by a user with a web browser, and the file contains database connection information, then you are in trouble. Use the $privateRoot Soupermail has to put your config files outside the webserver tree.
NEVER use a database user with high privileges (eg. sa, system, sys, root) to access your database via Soupermail, unless you are in a very trusted environment and you know exactly what will be going into your SQL statements.
ALWAYS ensure you are using a good random password for your database access - people's names and stuff are trivial to brute-force.
If you have a database with a network daemon, ALWAYS consider ways you can restrict access to only known hosts.
ALWAYS use requires, length checking and type checking in config files to make sure the data you pass to your SQL commands is valid.
NEVER make web writable directories in your CGI area.
ALWAYS consider how you will protect files written by Soupermail on your webserver. Protecting the files usually involves ensuring that they are safe from being read from a browser, the area being written to cannot contain executables, that there is no means of anonymously FTPing to the area and that other users on the system cannot exploit the area.
ALWAYS remove backup files and temporary files from your live sites.
NEVER transmit credit card details by un-encrypted email.
NEVER store credit card numbers un-encrypted on your webspace.
Get to know the admin staff of your server space, or, at least find your way around your service provider's support web pages. If they don't have support web pages, then worry.
If your job is to maintain your website, make sure you've read http://www.w3.org/Security/FAQ/. Website security is easily compromised by misconfiguration of software - if you didn't read up about it, its your fault.
Where possible, use secure communications to your webspace, rather than insecure access (eg. SCP rather than FTP, SSH rather than Telnet, encrypted pcAnywhere, etc). IMHO, this is simple common sense, but it never hurts to say it again.
When you have Soupermail installed, you should be extra careful about people being able to write config files to your system. If you are using something like a message board, it may be possible for someone to write a config file with it, and then use that config file to read sensitive pages off your website. Beware!
To help counter this, from version 1.0.8, Soupermail will not read any files from a directory containing a file called "soupermail.deny" (all lower case). This file doesn't have to contain anything, just exist. Place a soupermail.deny file in any directory that contains untrusted content. Also place a soupermail.deny in any directory that contains sensitive information (eg. ASP or PHP code containing database logon details).
For even more security, you can set the $paranoid variable in Soupermail. In this mode, Soupermail won't read any files from a directory, unless the directory contains a file called "soupermail.allow". This is the recommended approach for security conscious webmasters.
Soupermail requires perl 5.004 or better. See http://www.perl.com/ for where to get perl from, or http://www.activestate.com/ if you need the Windows NT version of Perl.
To handle the CGI input, Soupermail needs Lincoln D. Stein's excellent CGI module, available from http://www.genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html
To do anything, Soupermail needs the MIME::Lite module installed on your server. This module can be downloaded from CPAN. http://www.cpan.org/modules/by-module/MIME/
To send email, Soupermail either needs a working Net::SMTP perl module installed on the server, or, if you are on a UNIX server, a working sendmail. Net::SMTP is distributed as part of the Libnet set of packages available from CPAN. For users on Windows NT, libnet is available with Activestate's Perl Package Manager.
On UNIX boxes, PGP requires PGP 2.6.3 or 5.0, available internationally from http://www.pgpi.org/
Under NT, you can use the DOS version of PGP 5, again, available from http://www.pgpi.org/. Unfortunately, I haven't got version 6.x to work yet, so its the 16bit only.
GNU Privacy Guard is available from http://www.gnupg.org/
Some examples are distributed with Soupermail in http://soupermail.sourceforge.net/downloads/examples.zip. If anyone has any good sites with examples, please let me know.
Vittal Aithal <[email protected]>
I'd would be wrong to say I wrote this all on my own, other people made my life difficult on the way, so I'd better credit them (only joking guys :) A round of applause for everyone at http://soupermail.sourceforge.net/credits.txt
Soupermail started life in late 1995 as a fairly lightweight CGI to handle emails. However, as the years went by, it began to suffer heavily from creeping featuritis, and has now grown into a monster. It started life at Unipalm PIPEX, and various copies/versions are used by a number of companies. UUNET UK ( http://www.uk.uu.net/ ) maintain a copy for their WorldWeb service users, this copy escaped and worked at Ionica. However, things went a bit pear-shaped, so now it teleworks from my house or from Revolution ( http://www.revolutionltd.com/ ).
Success with PGP/GPG is highly variable upon platform its run on :( GPG often depends on the Entropy Gathering Daemon to generate random numbers and this may not work in a webserver user context.
CGIWrapped environments can prevent the config file location being passed in with the PATH_INFO option, and will result in a config file error unless the config location is passed in with the SoupermailConf form field.
Soupermail suffers from major bloat, but I just haven't worked up the will to cull it down. The template code really needs to be modularised out.
Empty config files return a Thank you message, although nothing has happened. Its debatable if this is correct.