# -*- python -*- # Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. # # 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; either version 2 # of the License, or (at your option) any later version. # # 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; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # This better succeed. If this fails, Python is royally screwed so we might # as well let the Web server give us a fatal and obtrusive error. import sys # From here on we are as bulletproof as possible! # The driver script prints out a lot of information when a Mailman bug is # encountered. This really helps for development, but it also reveals # information about the host system that some administrators are not # comfortable with. By setting STEALTH_MODE to 1, you disable the printing of # this information to the web pages. This information is still, and always, # printed in the error logs. STEALTH_MODE = 0 # This standard driver script is used to run CGI programs, wrapped in code # that catches errors, and displays them as HTML. This guarantees that # (almost) any problem in the Mailman software doesn't result in a Web server # error. It is much more helpful to generate and show a traceback, which the # user could send to the administrator, than to display a server error and # have to trudge through server logs. # Note: this isn't 100% perfect! Here are some things that can go wrong that # are not caught and reported as traceback-containing HTML: # # - This file could contain a syntax error. In that case, you would indeed # get a Web server error since this file wouldn't even compile, and there's # no way to catch that. Mailman's install procedure should make this highly # unlikely. # # - The sys module could be royally screwed, probably we couldn't import it. # This would indicate a serious problem with the Python installation, so # it's also highly unlikely to occur. def run_main(): # These will ensure that even if something between now and the # creation of the real logger below fails, we can still get # *something* meaningful. logger = None try: # Insert the relative path to the parent of the Mailman package # directory, so we can pick up the Utils module. import os # sys gets imported at module level below. sys.path.insert(0, os.pardir) # Map stderr to a logger, if possible. from Mailman.Logging.StampedLogger import StampedLogger logger = StampedLogger('error', label='admin', manual_reprime=1, nofail=0, immediate=1) # Pre-load the `cgi' module. We do this because we're distributing a # slightly different version than the standard Python module. It's # essentially Python 1.5.2's module, with an experimental patch to # handle clients that give bogus or non-existant content-type headers. # # We assign sys.modules['cgi'] to this special cgi module because we # don't want to have to rewrite all the Mailman.Cgi modules to get the # special one. import Mailman.pythonlib.cgi sys.modules['cgi'] = Mailman.pythonlib.cgi # # TBD: Stick the i18n translation function into the builtins. This is # bogus because it's too magical, but it's also quite convenient # during the i18n integration phase. This will change before the # release! import __builtin__ from Mailman.i18n import _ __builtin__._ = _ # # The name of the module to run is passed in argv[1]. What we # actually do is import the module named by argv[1] that lives in the # Mailman.Cgi package. That module must have a main() function, which # we dig out and call. # scriptname = sys.argv[1] # See the reference manual for why we have to do things this way. # Note that importing should have no side-effects! pkg = __import__('Mailman.Cgi', globals(), locals(), [scriptname]) module = getattr(pkg, scriptname) main = getattr(module, 'main') try: try: sys.stderr = logger main() finally: sys.stderr = sys.__stderr__ except SystemExit: # This is a valid way for the function to exit. pass except: print_traceback(logger) print_environment(logger) # We are printing error reporting to two places. One will always be stdout # and the other will always be the log file. It is assumed that stdout is an # HTML sink and the log file is a plain text sink. def print_traceback(logfp=None): if logfp is None: logfp = sys.__stderr__ try: import traceback except ImportError: traceback = None try: from Mailman.mm_cfg import VERSION except ImportError: VERSION = '<undetermined>' # Write to the log file first. print >> logfp, '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' print >> logfp, '[----- Mailman Version: %s -----]' % VERSION print >> logfp, '[----- Traceback ------]' if traceback: traceback.print_exc(file=logfp) else: print >> logfp, '[failed to import module traceback]' print >> logfp, '[exc: %s, var: %s]' % sys.exc_info()[0:2] # Write to the HTML sink. print """\ Content-type: text/html
If you would like to help us identify the problem, please email a copy of this page to the webmaster for this site with a description of what happened. Thanks!
'''
if traceback:
traceback.print_exc(file=sys.stdout)
else:
print '[failed to import module traceback]'
print '[exc: %s, var: %s]' % sys.exc_info()[0:2]
print '\n\n'
else:
print '''Please inform the webmaster for this site of this problem. Printing of traceback and other system information has been explicitly inhibited, but the webmaster can find this information in the Mailman error logs.''' def print_environment(logfp=None): if logfp is None: logfp = sys.__stderr__ try: import os except ImportError: os = None # Write some information about our Python executable to the log file. print >> logfp, '[----- Python Information -----]' print >> logfp, 'sys.version =', sys.version print >> logfp, 'sys.executable =', sys.executable print >> logfp, 'sys.prefix =', sys.prefix print >> logfp, 'sys.exec_prefix =', sys.exec_prefix print >> logfp, 'sys.path =', sys.exec_prefix print >> logfp, 'sys.platform =', sys.platform # Write the same information to the HTML sink. if not STEALTH_MODE: print '''\
| Variable | Value |
|---|---|
| sys.version | ', \ sys.version, ' |
| sys.executable | ', \ sys.executable, ' |
| sys.prefix | ', sys.prefix, ' |
| sys.exec_prefix | ', \ sys.exec_prefix, ' |
| sys.path | ', \ sys.exec_prefix, ' |
| sys.platform | ', \ sys.platform, ' |
| Variable | Value |
|---|---|
| ', k, ' | ', v, ' |