diff options
Diffstat (limited to 'scripts/driver')
| -rw-r--r-- | scripts/driver | 314 |
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) |
