summaryrefslogtreecommitdiff
path: root/scripts/driver
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/driver')
-rw-r--r--scripts/driver314
1 files changed, 0 insertions, 314 deletions
diff --git a/scripts/driver b/scripts/driver
deleted file mode 100644
index 0fd025017..000000000
--- a/scripts/driver
+++ /dev/null
@@ -1,314 +0,0 @@
-# -*- python -*-
-
-# Copyright (C) 1998-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-# 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 True, you disable the printing
-# of this information to the web pages. This information is still, and
-# always, printed in the error logs.
-STEALTH_MODE = False
-
-# This will be set to the entity escaper.
-def websafe(s):
- return s
-
-SPACE = ' '
-
-
-
-# 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():
- global STEALTH_MODE, websafe
-
- # These will ensure that even if something between now and the
- # creation of the real logger below fails, we can still get
- # *something* meaningful.
- log = None
- try:
- import paths
- from Mailman.configuration import config
- config.load()
- # When running in non-stealth mode, we need to escape entities,
- # otherwise we're vulnerable to cross-site scripting attacks.
- try:
- if not STEALTH_MODE:
- from Mailman.Utils import websafe
- except:
- STEALTH_MODE = True
- raise
- # Initialize the standard loggers
- from Mailman.loginit import initialize
- initialize()
- import logging
- log = logging.getLogger('mailman.error')
- # Collect stdout and stderr in cStringIOs so that if /any/ errors
- # occur during printing it won't mess up our diagnostics page.
- from cStringIO import StringIO
- tempstdout = StringIO()
- tempstderr = 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')
- import signal
- signal.signal(signal.SIGTERM, sigterm_handler)
- try:
- try:
- sys.stdout = tempstdout
- sys.stderr = tempstderr
- main()
- sys.__stdout__.write(tempstdout.getvalue())
- sys.__stderr__.write(tempstderr.getvalue())
- finally:
- sys.stderr = sys.__stderr__
- sys.stdout = sys.__stdout__
- except SystemExit:
- # This is a valid way for the function to exit. Be sure any text
- # produced is still written out to the browser.
- sys.stdout.write(tempstdout.getvalue())
- except:
- print_traceback(log)
- print_environment(log)
-
-
-
-# If possible, we print the error to two places. One will always be stdout
-# and the other will be the log file if a log file was created. It is assumed
-# that stdout is an HTML sink.
-def print_traceback(log=None):
- try:
- import traceback
- except ImportError:
- traceback = None
- try:
- from Mailman.mm_cfg import VERSION
- except ImportError:
- VERSION = '<undetermined>'
-
- # Write to the log file first.
- if log:
- from cStringIO import StringIO
- outfp = StringIO()
-
- print >> outfp, '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
- print >> outfp, '[----- Mailman Version: %s -----]' % VERSION
- print >> outfp, '[----- Traceback ------]'
- if traceback:
- traceback.print_exc(file=outfp)
- else:
- print >> outfp, '[failed to import module traceback]'
- print >> outfp, '[exc: %s, var: %s]' % sys.exc_info()[0:2]
- # Don't use .exception() since that'll give us the exception twice.
- # IWBNI we could print directly to the log's stream, or treat a log
- # like an output stream.
- log.error('%s', outfp.getvalue())
-
- # 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>'''
- exc_info = sys.exc_info()
- if traceback:
- for line in traceback.format_exception(*exc_info):
- print websafe(line),
- else:
- print '[failed to import module traceback]'
- print '[exc: %s, var: %s]' % [websafe(x) for x in 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(log=None):
- try:
- import os
- except ImportError:
- os = None
-
- if log:
- from cStringIO import StringIO
- outfp = StringIO()
-
- # Write some information about our Python executable to the log file.
- print >> outfp, '[----- Python Information -----]'
- print >> outfp, 'sys.version =', sys.version
- print >> outfp, 'sys.executable =', sys.executable
- print >> outfp, 'sys.prefix =', sys.prefix
- print >> outfp, 'sys.exec_prefix =', sys.exec_prefix
- print >> outfp, 'sys.path =', sys.exec_prefix
- print >> outfp, 'sys.platform =', sys.platform
- print >> outfp, 'args =', SPACE.join(sys.argv)
-
- # 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.
- if log:
- print >> logfp, '[----- Environment Variables -----]'
- if os:
- for k, v in os.environ.items():
- print >> outfp, '\t%s: %s' % (k, v)
- else:
- print >> outfp, '[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>', websafe(k), \
- '</tt></td><td>', websafe(v), \
- '</td></tr>'
- print '</table>'
- else:
- print '<p><hr>[failed to import module os]'
-
- # Dump the log output
- if log:
- log.error('%s', outfp.getvalue())
-
-
-
-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]'
-
-
-
-# Signal handler to guarantee that, when running under traditional CGI, a
-# locked mailing list will be unlocked when a fatal signal is received.
-#
-# try/finally isn't enough because of this scenario: user hits a CGI page
-# which may take a long time to render; user gets bored and hits the browser's
-# STOP button; browser shuts down socket; server tries to write to broken
-# socket and gets a SIGPIPE. Under Apache 1.3/mod_cgi, Apache catches this
-# SIGPIPE (I presume it is buffering output from the cgi script), then turns
-# around and SIGTERMs the cgi process. Apache waits three seconds and then
-# SIGKILLs the cgi process. We /must/ catch the SIGTERM and do the most
-# reasonable thing we can in as short a time period as possible. If we get
-# the SIGKILL we're screwed because it's uncatchable and we'll have no
-# opportunity to clean up after ourselves.
-#
-# This signal handler catches the SIGTERM, unlocks the list, and then
-# exits the process. The effect of this is that the changes made to the
-# MailList object will be aborted, which seems like the only sensible
-# semantics.
-#
-# Note that we must not install this signal handler when running under the
-# HTTPRunner wsgi server because the sys.exit(0) will cause the supervisor
-# mailmanctl process to restart the HTTPRunner. When running in that
-# environment, just let the normal signal handling do the right thing.
-def sigterm_handler(signum, frame, mlist=mlist):
- # Make sure the list gets unlocked...
- if mlist.Locked():
- mlist.Unlock()
- # ...and ensure we exit, otherwise race conditions could cause us to
- # enter MailList.Save() while we're in the unlocked state, and that
- # could be bad!
- sys.exit(0)