aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/driver
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/driver')
-rw-r--r--scripts/driver243
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]'