#!/usr/bin/env python # the line above must contain the path to python on your web server '''gypsymail.py is a Python clone of the cgiemail form mail script Copyright (C) 2001 Sheila King This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; It is in the file gpl.txt. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. you can contact the author, Sheila King at: sheila@thinkspot.net ''' ################ begin configuration section ######################### # the full path to your template and config text files # this is something like /usr/local/etc/yoursite/cgi-bin/templates # the path must be enclosed in quotes, as shown below TemplatesPATH = "/big/dom/xdomain/cgi-bin/templates" ###### end configuration section: do NOT edit anything below ######### try: from gypsyutils import * except ImportError, errmssg: print "Content-type: text/html\n" print "Import Error: could not import gypsyutils module" print errmssg import os, sys, cgi, traceback, string from time import strftime, gmtime, time, localtime, asctime myversionNumber = "0.7.1 beta" GypsyMailHomePage = "http://www.thinkspot.net/sheila/computers/software/gypsymail.html" Disallowed = ['\nTo:', '\nCc:', '\nBcc:'] if myversionNumber != versionNumber: gypsyversion = "gypsymail.py version = %s" % myversionNumber utilsversion = "gypsyutils.py version = %s" % versionNumber Debug("version numbers of gypysmail.py and gypsutils.py do not match!\n%s\n%s" % \ (gypsyversion, utilsversion)) if debug: Debug("Version = %s\nTemplatesPATH = %s" % (versionNumber, TemplatesPATH)) environvars = [] for key in os.environ.keys(): keypair = '%s = %s' % (key, os.environ[key]) environvars.append(keypair) Debug(string.join(environvars, '\n')) ###-------------------------------------------------------------- '''begin main script''' ###-------------------------------------------------------------- ### instantiate form form = cgi.FieldStorage(keep_blank_values=1) if debug: formdata = [] for key in form.keys(): formpair = '%s = %s' % (key, str(form[key])) formdata.append(formpair) Debug('Form contents:\n%s' % string.join(formdata, '\n')) PATH_INFO = os.environ.get("PATH_INFO", '') ### getting filenames for template file and config file if PATH_INFO: pathstring = PATH_INFO[1:] filenames = string.split(pathstring,'/', 2) Debug('filenames = %s' % str(filenames)) if len(filenames) < 2: FatalErrorPage( "The Path Info did not contain correct information "+\ "to access the required template and config files
"+\ "The script cannot continue") raise IndexError("Incorrect Length on PATH_INFO") configfile = filenames[0] templatefile = filenames[1] if len(filenames) == 3: subdirpath = filenames[2] else: subdirpath = "" else: FatalErrorPage("No PATH_INFO information in Environment Variables.
"+\ "Cannot continue") raise IndexError("No PATH_INFO") ### open the template file and retrieve contents if configfile: configpath = os.path.join(TemplatesPATH, subdirpath, configfile) Debug('configpath = %s' % configpath) configDict, valueDict = returnConfigFileContents(configpath) Debug('configDict and valueDict initialized\nconfigDict:\n%s\n\nvalueDict:\n%s' %\ (str(configDict), str(valueDict))) else: Debug('configfile not specified') message = "No Config file was specified
" message = message + "GypsyMail cannot continue without a Config File" FatalErrorPage(message) raise KeyError("No Config file was specified") if templatefile: templatepath = os.path.join(TemplatesPATH, subdirpath, templatefile) Debug('templatepath = %s' % templatepath) try: f = open(templatepath, 'r') except IOError, OSError: ErrorMessage = "\nCouldn't open file template file at: "+templatefile+" \n" exc, val, tb = sys.exc_info() PrintErrorToLogFile(exc, val, tb, ErrMessage=ErrorMessage, dict = configDict) del tb PrintHTTPHeader(configDict["ErrorPageTitle"]) print "

Template File Not Found


" print "

You may wish to notify the webmaster of this error

" PrintClosingHTMLTags(dict = configDict) raise else: ErrorMessage = "Script called with no template file specified in the Request_URI\n" PrintErrorToLogFile(exc = None, val = None, tb = None, ErrMessage = ErrorMessage,\ dict = configDict) PrintHTTPHeader(configDict["ErrorPageTitle"]) print "

The Request URI didn't specify any Template File

" print "

You may wish to notify the webmaster of this error

" PrintClosingHTMLTags(dict=configDict) raise ValueError ### read in the data from the template file text = f.read() f.close() ### check if any required values or confirm values are blank and send error message missingFieldValue = 0 requireList = [] confirmList = [] successDict = {} for field in form.keys(): if string.find(field, "require-")==0: requireList.append(field) if form[field].value == "": missingFieldValue = 1 elif string.find(field, "confirm-")==0: confirmList.append(field) if form[field].value == "": missingFieldValue = 1 if missingFieldValue: PrintHTTPHeader(configDict["ErrorPageTitle"]) PrintMissingFieldError(field) raise KeyError ### since all required fields are complete, check for any "confirm" fields # and check that they match their "require" counterpart for item in confirmList: basename = string.replace(item, "confirm-", "") requireMatch = "require-"+basename if form.has_key(requireMatch): if form[item].value != form[requireMatch].value: PrintHTTPHeader(configDict["ErrorPageTitle"]) PrintNonMatchingFieldError(basename) PrintClosingHTMLTags(dict = configDict, Error=2) raise ValueError ### Obtain the PassList from the Config File Dictionary # This is the list of form fields that should not be checked for extra headers PassList = string.split(configDict["PassFields"], ',') for item in PassList: strippedItem = string.strip(item) if strippedItem != item: PassList[PassList.index(item)]= strippedItem UpperCasePassList = string.split(string.upper(string.join(PassList))) ### parse file for field in form.keys(): value = form[field] if type(value) is type([]): valueList = value value ="" for item in valueList: value = value + item.value + '\n' else: value = value.value passfield = 0 for substring in UpperCasePassList: if string.find(string.upper(field), substring) > -1: passfield =1 if not passfield: for item in Disallowed: if string.find(string.upper(value),string.upper(item)) > -1: PrintHTTPHeader(configDict["ErrorPageTitle"]) print "

Illegal string in submitted field

" print "Unable to process form
" print "In the field ", field, " you had one of the following strings " print "at the beginning of a new line: To:, Cc:, or Bcc. This is not" print "permitted. Please correct your submission.
" print "Use the Back-Button on your browser to return to the form.
" PrintClosingHTMLTags(dict=configDict, Error = 2) raise ValueException if valueDict.has_key(field): valueList = string.split(valueDict[field], ',') for item in valueList: valueList[valueList.index(item)] = string.strip(item) if value not in valueList: PrintHTTPHeader(configDict["ErrorPageTitle"]) print "

Invalid Value for the Field ", field, "

" print "You gave the value ", value print "
Acceptable values are:
" for item in valueList: print item, "
\n" PrintClosingHTMLTags(dict = configDict, Error =2) raise ValueError text = string.replace(text, '['+field+']', value) successDict['['+field+']'] = value text = string.replace(text, '\r\n', '\n') Debug('text = %s' % text) headerstring, body = sendMessage(text, configDict) sentMessage = "%s\n%s" % (headerstring, body) # Now that mail message has been successfully sent, print # success page if configDict.has_key("SuccessOptions"): successoption = configDict["SuccessOptions"] Debug("successoption = %s" % successoption) if successoption == "1": try: print "Location: ", print configDict["SuccessRedirectURL"], print "\n\n" except StandardError, errmssg: Debug('When trying to deliver redirect URL %s the following error occurred:\n%s' % \ (configDict["SuccessRedirectURL"], errmssg)) printDefaultSuccess(configDict, sentMessage) PrintClosingHTMLTags(dict = configDict, Error=0) elif successoption >= "2": try: templatefile = open(os.path.join(TemplatesPATH, configDict["SuccessTemplateFile"]), 'r') templatetext = templatefile.read() templatefile.close() printTemplateSuccess(templatetext, sentMessage, headerstring, body, successDict, successoption) except StandardError, errmssg: Debug("When trying to deliver custom success template %s, the following error occurred:\n%s" % \ (configDict["SuccessTemplateFile"], errmssg)) printDefaultSuccess(configDict, sentMessage+'\n\nError: '+str(errmssg)) PrintClosingHTMLTags(dict = configDict, Error=0) else: printDefaultSuccess(configDict, sentMessage) PrintClosingHTMLTags(dict = configDict, Error=0) else: printDefaultSuccess(configDict, sentMessage) PrintClosingHTMLTags(dict = configDict, Error=0)