diff options
Diffstat (limited to '')
-rw-r--r-- | scripts/driver | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/scripts/driver b/scripts/driver new file mode 100644 index 00000000..60c8c79e --- /dev/null +++ b/scripts/driver @@ -0,0 +1,243 @@ +# -*- python -*- + +# Copyright (C) 1998,1999,2000,2001,2002 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: + import paths + # 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) + # Collect stdout in a cStringIO so that if /any/ errors occur during + # printing it won't mess up our diagnostics page. + from cStringIO import StringIO + tempstdout = StringIO() + # 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 + sys.stdout = tempstdout + main() + sys.__stdout__.write(tempstdout.getvalue()) + finally: + sys.stderr = sys.__stderr__ + sys.stdout = sys.__stdout__ + 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 + +<head><title>Bug in Mailman version %(VERSION)s</title></head> +<body bgcolor=#ffffff><h2>Bug in Mailman version %(VERSION)s</h2> +<p><h3>We're sorry, we hit a bug!</h3> +""" % locals() + if not STEALTH_MODE: + print '''<p>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! + +<h4>Traceback:</h4><p><pre>''' + 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</pre></body>' + else: + print '''<p>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 '''\ +<p><hr><h4>Python information:</h4> + +<p><table> +<tr><th>Variable</th><th>Value</th></tr> +''' + print '<tr><td><tt>sys.version</tt></td><td>', \ + sys.version, '</td></tr>' + print '<tr><td><tt>sys.executable</tt></td><td>', \ + sys.executable, '</td></tr>' + print '<tr><td><tt>sys.prefix</tt></td><td>', sys.prefix, '</td></tr>' + print '<tr><td><tt>sys.exec_prefix</tt></td><td>', \ + sys.exec_prefix, '</td></tr>' + # what else? + print '<tr><td><tt>sys.path</tt></td><td>', \ + sys.exec_prefix, '</td></tr>' + print '<tr><td><tt>sys.platform</tt></td><td>', \ + sys.platform, '</td></tr>' + print '</table>' + + # Write environment variables to the log file. + print >> logfp, '[----- Environment Variables -----]' + if os: + for k, v in os.environ.items(): + print >> logfp, '\t%s: %s' % (k, v) + else: + print >> logfp, '[failed to import module os]' + + # Write environment variables to the HTML sink. + if not STEALTH_MODE: + print '''\ +<p><hr><h4>Environment variables:</h4> + +<p><table> +<tr><th>Variable</th><th>Value</th></tr> +''' + if os: + for k, v in os.environ.items(): + print '<tr><td><tt>', k, '</tt></td><td>', v, '</td></tr>' + print '</table>' + else: + print '<p><hr>[failed to import module os]' + + + +try: + run_main() +except: + # Some exception percolated all the way back up to the top. This + # generally shouldn't happen because the run_main() call is similarly + # wrapped, but just in case, we'll give it one last ditch effort to report + # problems to *somebody*. Most likely this will end up in the Web server + # log file. + try: + print_traceback() + print_environment() + except: + # Nope, we're quite screwed + print """\ +Content-type: text/html + +<p><h3>We're sorry, we hit a bug!</h3> + +Mailman experienced a very low level failure and could not even generate a +useful traceback for you. Please report this to the Mailman administrator at +this site. +""" + print >> sys.__stderr__, '[Mailman: low level unrecoverable exception]' |