From: richard Date: Mon, 23 Jul 2001 03:46:48 +0000 (+0000) Subject: moving the bin files to facilitate out-of-the-boxness X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=8eeba56b1422a66a31fc79e785ab514235b7c9bc;p=roundup.git moving the bin files to facilitate out-of-the-boxness git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@31 57a73879-2fb5-44c3-a270-3262357dd7e2 --- diff --git a/bin/roundup b/bin/roundup deleted file mode 100755 index 0ca6554..0000000 --- a/bin/roundup +++ /dev/null @@ -1,271 +0,0 @@ -#! /usr/bin/python - -# $Id: roundup,v 1.1 2001-07-22 11:15:45 richard Exp $ - -import sys -if int(sys.version[0]) < 2: - print 'Roundup requires python 2.0 or later.' - sys.exit(1) - -import string, os, getpass -from roundup import date, roundupdb, init - -def determineLogin(instance, argv, n = 2): - name = password = '' - if argv[2] == '-u': - l = argv[3].split(':') - name = l[0] - if len(l) > 1: - password = l[1] - n = 4 - elif os.environ.has_key('ROUNDUP_LOGIN'): - l = os.environ['ROUNDUP_LOGIN'].split(':') - name = l[0] - if len(l) > 1: - password = l[1] - while not name: - name = raw_input('Login name: ') - while not password: - password = getpass.getpass(' password: ') - # TODO use the password... - return n, instance.open(name) - -def usage(message=''): - if message: message = 'Problem: '+message+'\n' - print '''%sUsage: - - roundup [-i instance] init template - -- initialise the database - roundup [-i instance] spec classname - -- show the properties for a classname - roundup [-i instance] create [-u login] classname propname=value ... - -- create a new entry of a given class - roundup [-i instance] list [-c] classname - -- list the instances of a class - roundup [-i instance] history [-c] designator - -- show the history entries of a designator - roundup [-i instance] get [-c] designator[,designator,...] propname - -- get the given property of one or more designator(s) - roundup [-i instance] set [-u login] designator[,designator,...] propname=value ... - -- set the given property of one or more designator(s) - roundup [-i instance] find [-c] classname propname=value ... - -- find the class instances with a given property - roundup [-i instance] retire designator[,designator,...] - -- "retire" a designator - roundup help - -- this help - roundup morehelp - -- even more detailed help -'''%message - -def moreusage(message=''): - usage(message) - print ''' -All commands (except help) require an instance specifier. This is just the path -to the roundup instance you're working with. It may be specified in the environment -variable ROUNDUP_INSTANCE or on the command line as "-i instance". - -A designator is a classname and a nodeid concatenated, eg. bug1, user10, ... - -Property values are represented as strings in command arguments and in the -printed results: - . Strings are, well, strings. - . Date values are printed in the full date format in the local time zone, and - accepted in the full format or any of the partial formats explained below. - . Link values are printed as node designators. When given as an argument, - node designators and key strings are both accepted. - . Multilink values are printed as lists of node designators joined by commas. - When given as an argument, node designators and key strings are both - accepted; an empty string, a single node, or a list of nodes joined by - commas is accepted. - -When multiple nodes are specified to the roundup get or roundup set -commands, the specified properties are retrieved or set on all the listed -nodes. - -When multiple results are returned by the roundup get or roundup find -commands, they are printed one per line (default) or joined by commas (with -the -c) option. - -Where the command changes data, a login name/password is required. The -login may be specified as either "name" or "name:password". - . ROUNDUP_LOGIN environment variable - . the -u command-line option -If either the name or password is not supplied, they are obtained from the -command-line. - -Date format examples: - "2000-04-17.03:45" means - "2000-04-17" means - "01-25" means - "08-13.22:13" means - "11-07.09:32:43" means - "14:25" means - "8:47:11" means - "." means "right now" -''' - -def main(): - argv = sys.argv - - if len(argv) == 1: - usage('No command specified') - return 1 - - # handle help now - if argv[1] == 'help': - usage() - return 0 - if argv[1] == 'morehelp': - moreusage() - return 0 - - # figure the instance home - n = 1 - if argv[1] == '-i': - if len(argv) == 2: - usage() - return 1 - instance_home = argv[2] - n = 3 - else: - instance_home = os.environ.get('ROUNDUP_INSTANCE', '') - if not instance_home: - usage('No instance home specified') - return 1 - - # now figure the command - command = argv[n] - n = n + 1 - - if command == 'init': - adminpw = '' - confirm = 'x' - while adminpw != confirm: - adminpw = getpass.getpass('Admin Password:') - confirm = getpass.getpass(' Confirm:') - init.init(instance_home, argv[n], adminpw) - return 0 - - # get the instance - path, instance = os.path.split(instance_home) - sys.path.insert(0, path) - try: - instance = __import__(instance) - finally: - del sys.path[0] - - if command == 'get': - db = instance.open() - designators = string.split(argv[n], ',') - propname = argv[n+1] - # TODO: handle the -c option - for designator in designators: - classname, nodeid = roundupdb.splitDesignator(designator) - print db.getclass(classname).get(nodeid, propname) - - elif command == 'set': - n, db = determineLogin(instance, argv, n) - designators = string.split(argv[n], ',') - props = {} - for prop in argv[n+1:]: - key, value = prop.split('=') - props[key] = value - for designator in designators: - classname, nodeid = roundupdb.splitDesignator(designator) - cl = db.getclass(classname) - properties = cl.getprops() - for key, value in props.items(): - type = properties[key] - if type.isStringType: - continue - elif type.isDateType: - props[key] = date.Date(value) - elif type.isIntervalType: - props[key] = date.Interval(value) - elif type.isLinkType: - props[key] = value - elif type.isMultilinkType: - props[key] = value.split(',') - apply(cl.set, (nodeid, ), props) - - elif command == 'find': - db = instance.open() - classname = argv[n] - cl = db.getclass(classname) - - # look up the linked-to class and get the nodeid that has the value - propname, value = argv[n+1:].split('=') - propcl = cl[propname].classname - nodeid = propcl.lookup(value) - - # now do the find - # TODO: handle the -c option - print cl.find(propname, nodeid) - - elif command == 'spec': - db = instance.open() - classname = argv[n] - cl = db.getclass(classname) - for key, value in cl.properties.items(): - print '%s: %s'%(key, value) - - elif command == 'create': - n, db = determineLogin(instance, argv, n) - classname = argv[n] - cl = db.getclass(classname) - props = {} - properties = cl.getprops() - for prop in argv[n+1:]: - key, value = prop.split('=') - type = properties[key] - if type.isStringType: - props[key] = value - elif type.isDateType: - props[key] = date.Date(value) - elif type.isIntervalType: - props[key] = date.Interval(value) - elif type.isLinkType: - props[key] = value - elif type.isMultilinkType: - props[key] = value.split(',') - print apply(cl.create, (), props) - - elif command == 'list': - db = instance.open() - classname = argv[n] - cl = db.getclass(classname) - key = cl.getkey() or cl.properties.keys()[0] - # TODO: handle the -c option - for nodeid in cl.list(): - value = cl.get(nodeid, key) - print "%4s: %s"%(nodeid, value) - - elif command == 'history': - db = instance.open() - classname, nodeid = roundupdb.splitDesignator(argv[n]) - # TODO: handle the -c option - print db.getclass(classname).history(nodeid) - - elif command == 'retire': - n, db = determineLogin(instance, argv, n) - designators = string.split(argv[n], ',') - for designator in designators: - classname, nodeid = roundupdb.splitDesignator(designator) - db.getclass(classname).retire(nodeid) - - else: - print "Unknown command '%s'"%command - usage() - return 1 - - db.close() - return 0 - -if __name__ == '__main__': - sys.exit(main()) - -# -# $Log: not supported by cvs2svn $ -# - diff --git a/bin/roundup-mailgw b/bin/roundup-mailgw deleted file mode 100755 index 4add812..0000000 --- a/bin/roundup-mailgw +++ /dev/null @@ -1,34 +0,0 @@ -#! /usr/bin/python - -# $ID: $ - -import sys -if int(sys.version[0]) < 2: - print "Roundup requires Python 2.0 or newer." - sys.exit(1) - -# figure the instance home -import os -if len(sys.argv) > 1: - instance_home = sys.argv[1] -else: - instance_home = os.environ.get('ROUNDUP_INSTANCE', '') -if not instance_home: - print 'No instance home specified' - sys.exit(1) - -# get the instance -path, instance = os.path.split(instance_home) -sys.path.insert(0, path) -instance = __import__(instance) -sys.path[0] - -# invokde the mail handler -db = instance.open('admin') -handler = instance.MailGW(db) -handler.main(sys.stdin) - -# -# $Log: not supported by cvs2svn $ -# - diff --git a/bin/roundup-server b/bin/roundup-server deleted file mode 100755 index c1e12c1..0000000 --- a/bin/roundup-server +++ /dev/null @@ -1,223 +0,0 @@ -#!/usr/bin/python -""" HTTP Server that serves roundup. - -Stolen from CGIHTTPServer - -$Id: roundup-server,v 1.1 2001-07-22 11:15:45 richard Exp $ - -""" -import sys -if int(sys.version[0]) < 2: - print "Content-Type: text/plain\n" - print "Roundup requires Python 2.0 or newer." - -__version__ = "0.1" - -__all__ = ["RoundupRequestHandler"] - -import os, urllib, StringIO, traceback, cgi, binascii, string -import BaseHTTPServer -import SimpleHTTPServer - -# Roundup modules of use here -from roundup import cgitb, cgi_client - -# These are here temporarily until I get a real reload system in place -from roundup import date, hyperdb, hyper_bsddb, roundupdb, htmltemplate - -# -## Configuration -# - -# This indicates where the Roundup instance lives -ROUNDUPS = { - 'test': '/tmp/roundup_test', -} - -# Where to log debugging information to. Use an instance of DevNull if you -# don't want to log anywhere. -# TODO: actually use this stuff -#class DevNull: -# def write(self, info): -# pass -#LOG = open('/var/log/roundup.cgi.log', 'a') -#LOG = DevNull() - -# -## end configuration -# - - -class RoundupRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): - def send_head(self): - """Version of send_head that support CGI scripts""" - # TODO: actually do the HEAD ... - return self.run_cgi() - - def run_cgi(self): - """ Execute the CGI command. Wrap an innner call in an error - handler so all errors can be caught. - """ - save_stdin = sys.stdin - sys.stdin = self.rfile - try: - self.inner_run_cgi() - except cgi_client.Unauthorised: - self.wfile.write('Content-Type: text/html\n') - self.wfile.write('Status: 403\n') - self.wfile.write('Unauthorised') - except: - try: - reload(cgitb) - self.wfile.write("Content-Type: text/html\n\n") - self.wfile.write(cgitb.breaker()) - self.wfile.write(cgitb.html()) - except: - self.wfile.write("Content-Type: text/html\n\n") - self.wfile.write("
")
-                s = StringIO.StringIO()
-                traceback.print_exc(None, s)
-                self.wfile.write(cgi.escape(s.getvalue()))
-                self.wfile.write("
\n") - sys.stdin = save_stdin - - def inner_run_cgi(self): - ''' This is the inner part of the CGI handling - ''' - - rest = self.path - i = rest.rfind('?') - if i >= 0: - rest, query = rest[:i], rest[i+1:] - else: - query = '' - - # figure the instance - if rest == '/': - raise ValueError, 'No instance specified' - l_path = string.split(rest, '/') - instance = urllib.unquote(l_path[1]) - if ROUNDUPS.has_key(instance): - instance_home = ROUNDUPS[instance] - module_path, instance = os.path.split(instance_home) - sys.path.insert(0, module_path) - try: - instance = __import__(instance) - finally: - del sys.path[0] - else: - raise ValueError, 'No such instance "%s"'%instance - - # figure out what the rest of the path is - if len(l_path) > 2: - rest = '/'.join(l_path[2:]) - else: - rest = '/' - - # Set up the CGI environment - env = {} - env['REQUEST_METHOD'] = self.command - env['PATH_INFO'] = urllib.unquote(rest) - if query: - env['QUERY_STRING'] = query - host = self.address_string() - if self.headers.typeheader is None: - env['CONTENT_TYPE'] = self.headers.type - else: - env['CONTENT_TYPE'] = self.headers.typeheader - length = self.headers.getheader('content-length') - if length: - env['CONTENT_LENGTH'] = length - co = filter(None, self.headers.getheaders('cookie')) - if co: - env['HTTP_COOKIE'] = ', '.join(co) - env['SCRIPT_NAME'] = '' - env['SERVER_NAME'] = self.server.server_name - env['SERVER_PORT'] = str(self.server.server_port) - - decoded_query = query.replace('+', ' ') - - # if root, setuid to nobody - # TODO why isn't this done much earlier? - say, in main()? - if not os.getuid(): - nobody = nobody_uid() - os.setuid(nobody) - - # reload all modules - # TODO check for file timestamp changes and dependencies - reload(date) - reload(hyperdb) - reload(roundupdb) - reload(htmltemplate) - reload(cgi_client) - sys.path.insert(0, module_path) - try: - reload(instance) - finally: - del sys.path[0] - - # initialise the roundupdb, check for auth - db = instance.open('admin') - message = 'Unauthorised' - auth = self.headers.getheader('authorization') - if auth: - l = binascii.a2b_base64(auth.split(' ')[1]).split(':') - user = l[0] - password = None - if len(l) > 1: - password = l[1] - try: - uid = db.user.lookup(user) - except KeyError: - auth = None - message = 'Username not recognised' - else: - if password != db.user.get(uid, 'password'): - message = 'Incorrect password' - auth = None - db.close() - del db - if not auth: - self.send_response(401) - self.send_header('Content-Type', 'text/html') - self.send_header('WWW-Authenticate', 'basic realm="Roundup"') - self.end_headers() - self.wfile.write(message) - return - - self.send_response(200, "Script output follows") - - # do the roundup thang - db = instance.open(user) - client = instance.Client(self.wfile, db, env, user) - client.main() - do_POST = run_cgi - -nobody = None - -def nobody_uid(): - """Internal routine to get nobody's uid""" - global nobody - if nobody: - return nobody - try: - import pwd - except ImportError: - return -1 - try: - nobody = pwd.getpwnam('nobody')[2] - except KeyError: - nobody = 1 + max(map(lambda x: x[2], pwd.getpwall())) - return nobody - -if __name__ == '__main__': - # TODO make this configurable again? command-line seems ok to me... - address = ('', 8080) - httpd = BaseHTTPServer.HTTPServer(address, RoundupRequestHandler) - print 'Roundup server started on', address - httpd.serve_forever() - -# -# $Log: not supported by cvs2svn $ -# - diff --git a/roundup-admin b/roundup-admin new file mode 100755 index 0000000..1068301 --- /dev/null +++ b/roundup-admin @@ -0,0 +1,274 @@ +#! /usr/bin/python + +# $Id: roundup-admin,v 1.1 2001-07-23 03:46:48 richard Exp $ + +import sys +if int(sys.version[0]) < 2: + print 'Roundup requires python 2.0 or later.' + sys.exit(1) + +import string, os, getpass +from roundup import date, roundupdb, init + +def determineLogin(instance, argv, n = 2): + name = password = '' + if argv[2] == '-u': + l = argv[3].split(':') + name = l[0] + if len(l) > 1: + password = l[1] + n = 4 + elif os.environ.has_key('ROUNDUP_LOGIN'): + l = os.environ['ROUNDUP_LOGIN'].split(':') + name = l[0] + if len(l) > 1: + password = l[1] + while not name: + name = raw_input('Login name: ') + while not password: + password = getpass.getpass(' password: ') + # TODO use the password... + return n, instance.open(name) + +def usage(message=''): + if message: message = 'Problem: '+message+'\n' + print '''%sUsage: + + roundup [-i instance] init template + -- initialise the database + roundup [-i instance] spec classname + -- show the properties for a classname + roundup [-i instance] create [-u login] classname propname=value ... + -- create a new entry of a given class + roundup [-i instance] list [-c] classname + -- list the instances of a class + roundup [-i instance] history [-c] designator + -- show the history entries of a designator + roundup [-i instance] get [-c] designator[,designator,...] propname + -- get the given property of one or more designator(s) + roundup [-i instance] set [-u login] designator[,designator,...] propname=value ... + -- set the given property of one or more designator(s) + roundup [-i instance] find [-c] classname propname=value ... + -- find the class instances with a given property + roundup [-i instance] retire designator[,designator,...] + -- "retire" a designator + roundup help + -- this help + roundup morehelp + -- even more detailed help +'''%message + +def moreusage(message=''): + usage(message) + print ''' +All commands (except help) require an instance specifier. This is just the path +to the roundup instance you're working with. It may be specified in the environment +variable ROUNDUP_INSTANCE or on the command line as "-i instance". + +A designator is a classname and a nodeid concatenated, eg. bug1, user10, ... + +Property values are represented as strings in command arguments and in the +printed results: + . Strings are, well, strings. + . Date values are printed in the full date format in the local time zone, and + accepted in the full format or any of the partial formats explained below. + . Link values are printed as node designators. When given as an argument, + node designators and key strings are both accepted. + . Multilink values are printed as lists of node designators joined by commas. + When given as an argument, node designators and key strings are both + accepted; an empty string, a single node, or a list of nodes joined by + commas is accepted. + +When multiple nodes are specified to the roundup get or roundup set +commands, the specified properties are retrieved or set on all the listed +nodes. + +When multiple results are returned by the roundup get or roundup find +commands, they are printed one per line (default) or joined by commas (with +the -c) option. + +Where the command changes data, a login name/password is required. The +login may be specified as either "name" or "name:password". + . ROUNDUP_LOGIN environment variable + . the -u command-line option +If either the name or password is not supplied, they are obtained from the +command-line. + +Date format examples: + "2000-04-17.03:45" means + "2000-04-17" means + "01-25" means + "08-13.22:13" means + "11-07.09:32:43" means + "14:25" means + "8:47:11" means + "." means "right now" +''' + +def main(): + argv = sys.argv + + if len(argv) == 1: + usage('No command specified') + return 1 + + # handle help now + if argv[1] == 'help': + usage() + return 0 + if argv[1] == 'morehelp': + moreusage() + return 0 + + # figure the instance home + n = 1 + if argv[1] == '-i': + if len(argv) == 2: + usage() + return 1 + instance_home = argv[2] + n = 3 + else: + instance_home = os.environ.get('ROUNDUP_INSTANCE', '') + if not instance_home: + usage('No instance home specified') + return 1 + + # now figure the command + command = argv[n] + n = n + 1 + + if command == 'init': + adminpw = '' + confirm = 'x' + while adminpw != confirm: + adminpw = getpass.getpass('Admin Password:') + confirm = getpass.getpass(' Confirm:') + init.init(instance_home, argv[n], adminpw) + return 0 + + # get the instance + path, instance = os.path.split(instance_home) + sys.path.insert(0, path) + try: + instance = __import__(instance) + finally: + del sys.path[0] + + if command == 'get': + db = instance.open() + designators = string.split(argv[n], ',') + propname = argv[n+1] + # TODO: handle the -c option + for designator in designators: + classname, nodeid = roundupdb.splitDesignator(designator) + print db.getclass(classname).get(nodeid, propname) + + elif command == 'set': + n, db = determineLogin(instance, argv, n) + designators = string.split(argv[n], ',') + props = {} + for prop in argv[n+1:]: + key, value = prop.split('=') + props[key] = value + for designator in designators: + classname, nodeid = roundupdb.splitDesignator(designator) + cl = db.getclass(classname) + properties = cl.getprops() + for key, value in props.items(): + type = properties[key] + if type.isStringType: + continue + elif type.isDateType: + props[key] = date.Date(value) + elif type.isIntervalType: + props[key] = date.Interval(value) + elif type.isLinkType: + props[key] = value + elif type.isMultilinkType: + props[key] = value.split(',') + apply(cl.set, (nodeid, ), props) + + elif command == 'find': + db = instance.open() + classname = argv[n] + cl = db.getclass(classname) + + # look up the linked-to class and get the nodeid that has the value + propname, value = argv[n+1:].split('=') + propcl = cl[propname].classname + nodeid = propcl.lookup(value) + + # now do the find + # TODO: handle the -c option + print cl.find(propname, nodeid) + + elif command == 'spec': + db = instance.open() + classname = argv[n] + cl = db.getclass(classname) + for key, value in cl.properties.items(): + print '%s: %s'%(key, value) + + elif command == 'create': + n, db = determineLogin(instance, argv, n) + classname = argv[n] + cl = db.getclass(classname) + props = {} + properties = cl.getprops() + for prop in argv[n+1:]: + key, value = prop.split('=') + type = properties[key] + if type.isStringType: + props[key] = value + elif type.isDateType: + props[key] = date.Date(value) + elif type.isIntervalType: + props[key] = date.Interval(value) + elif type.isLinkType: + props[key] = value + elif type.isMultilinkType: + props[key] = value.split(',') + print apply(cl.create, (), props) + + elif command == 'list': + db = instance.open() + classname = argv[n] + cl = db.getclass(classname) + key = cl.getkey() or cl.properties.keys()[0] + # TODO: handle the -c option + for nodeid in cl.list(): + value = cl.get(nodeid, key) + print "%4s: %s"%(nodeid, value) + + elif command == 'history': + db = instance.open() + classname, nodeid = roundupdb.splitDesignator(argv[n]) + # TODO: handle the -c option + print db.getclass(classname).history(nodeid) + + elif command == 'retire': + n, db = determineLogin(instance, argv, n) + designators = string.split(argv[n], ',') + for designator in designators: + classname, nodeid = roundupdb.splitDesignator(designator) + db.getclass(classname).retire(nodeid) + + else: + print "Unknown command '%s'"%command + usage() + return 1 + + db.close() + return 0 + +if __name__ == '__main__': + sys.exit(main()) + +# +# $Log: not supported by cvs2svn $ +# Revision 1.1 2001/07/22 11:15:45 richard +# More Grande Splite stuff +# +# + diff --git a/roundup-mailgw b/roundup-mailgw new file mode 100755 index 0000000..c16e38e --- /dev/null +++ b/roundup-mailgw @@ -0,0 +1,37 @@ +#! /usr/bin/python + +# $ID: $ + +import sys +if int(sys.version[0]) < 2: + print "Roundup requires Python 2.0 or newer." + sys.exit(1) + +# figure the instance home +import os +if len(sys.argv) > 1: + instance_home = sys.argv[1] +else: + instance_home = os.environ.get('ROUNDUP_INSTANCE', '') +if not instance_home: + print 'No instance home specified' + sys.exit(1) + +# get the instance +path, instance = os.path.split(instance_home) +sys.path.insert(0, path) +instance = __import__(instance) +sys.path[0] + +# invokde the mail handler +db = instance.open('admin') +handler = instance.MailGW(db) +handler.main(sys.stdin) + +# +# $Log: not supported by cvs2svn $ +# Revision 1.1 2001/07/22 11:15:45 richard +# More Grande Splite stuff +# +# + diff --git a/roundup-server b/roundup-server new file mode 100755 index 0000000..ff4e0c1 --- /dev/null +++ b/roundup-server @@ -0,0 +1,226 @@ +#!/usr/bin/python +""" HTTP Server that serves roundup. + +Stolen from CGIHTTPServer + +$Id: roundup-server,v 1.1 2001-07-23 03:46:48 richard Exp $ + +""" +import sys +if int(sys.version[0]) < 2: + print "Content-Type: text/plain\n" + print "Roundup requires Python 2.0 or newer." + +__version__ = "0.1" + +__all__ = ["RoundupRequestHandler"] + +import os, urllib, StringIO, traceback, cgi, binascii, string +import BaseHTTPServer +import SimpleHTTPServer + +# Roundup modules of use here +from roundup import cgitb, cgi_client + +# These are here temporarily until I get a real reload system in place +from roundup import date, hyperdb, hyper_bsddb, roundupdb, htmltemplate + +# +## Configuration +# + +# This indicates where the Roundup instance lives +ROUNDUPS = { + 'test': '/tmp/roundup_test', +} + +# Where to log debugging information to. Use an instance of DevNull if you +# don't want to log anywhere. +# TODO: actually use this stuff +#class DevNull: +# def write(self, info): +# pass +#LOG = open('/var/log/roundup.cgi.log', 'a') +#LOG = DevNull() + +# +## end configuration +# + + +class RoundupRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): + def send_head(self): + """Version of send_head that support CGI scripts""" + # TODO: actually do the HEAD ... + return self.run_cgi() + + def run_cgi(self): + """ Execute the CGI command. Wrap an innner call in an error + handler so all errors can be caught. + """ + save_stdin = sys.stdin + sys.stdin = self.rfile + try: + self.inner_run_cgi() + except cgi_client.Unauthorised: + self.wfile.write('Content-Type: text/html\n') + self.wfile.write('Status: 403\n') + self.wfile.write('Unauthorised') + except: + try: + reload(cgitb) + self.wfile.write("Content-Type: text/html\n\n") + self.wfile.write(cgitb.breaker()) + self.wfile.write(cgitb.html()) + except: + self.wfile.write("Content-Type: text/html\n\n") + self.wfile.write("
")
+                s = StringIO.StringIO()
+                traceback.print_exc(None, s)
+                self.wfile.write(cgi.escape(s.getvalue()))
+                self.wfile.write("
\n") + sys.stdin = save_stdin + + def inner_run_cgi(self): + ''' This is the inner part of the CGI handling + ''' + + rest = self.path + i = rest.rfind('?') + if i >= 0: + rest, query = rest[:i], rest[i+1:] + else: + query = '' + + # figure the instance + if rest == '/': + raise ValueError, 'No instance specified' + l_path = string.split(rest, '/') + instance = urllib.unquote(l_path[1]) + if ROUNDUPS.has_key(instance): + instance_home = ROUNDUPS[instance] + module_path, instance = os.path.split(instance_home) + sys.path.insert(0, module_path) + try: + instance = __import__(instance) + finally: + del sys.path[0] + else: + raise ValueError, 'No such instance "%s"'%instance + + # figure out what the rest of the path is + if len(l_path) > 2: + rest = '/'.join(l_path[2:]) + else: + rest = '/' + + # Set up the CGI environment + env = {} + env['REQUEST_METHOD'] = self.command + env['PATH_INFO'] = urllib.unquote(rest) + if query: + env['QUERY_STRING'] = query + host = self.address_string() + if self.headers.typeheader is None: + env['CONTENT_TYPE'] = self.headers.type + else: + env['CONTENT_TYPE'] = self.headers.typeheader + length = self.headers.getheader('content-length') + if length: + env['CONTENT_LENGTH'] = length + co = filter(None, self.headers.getheaders('cookie')) + if co: + env['HTTP_COOKIE'] = ', '.join(co) + env['SCRIPT_NAME'] = '' + env['SERVER_NAME'] = self.server.server_name + env['SERVER_PORT'] = str(self.server.server_port) + + decoded_query = query.replace('+', ' ') + + # if root, setuid to nobody + # TODO why isn't this done much earlier? - say, in main()? + if not os.getuid(): + nobody = nobody_uid() + os.setuid(nobody) + + # reload all modules + # TODO check for file timestamp changes and dependencies + reload(date) + reload(hyperdb) + reload(roundupdb) + reload(htmltemplate) + reload(cgi_client) + sys.path.insert(0, module_path) + try: + reload(instance) + finally: + del sys.path[0] + + # initialise the roundupdb, check for auth + db = instance.open('admin') + message = 'Unauthorised' + auth = self.headers.getheader('authorization') + if auth: + l = binascii.a2b_base64(auth.split(' ')[1]).split(':') + user = l[0] + password = None + if len(l) > 1: + password = l[1] + try: + uid = db.user.lookup(user) + except KeyError: + auth = None + message = 'Username not recognised' + else: + if password != db.user.get(uid, 'password'): + message = 'Incorrect password' + auth = None + db.close() + del db + if not auth: + self.send_response(401) + self.send_header('Content-Type', 'text/html') + self.send_header('WWW-Authenticate', 'basic realm="Roundup"') + self.end_headers() + self.wfile.write(message) + return + + self.send_response(200, "Script output follows") + + # do the roundup thang + db = instance.open(user) + client = instance.Client(self.wfile, db, env, user) + client.main() + do_POST = run_cgi + +nobody = None + +def nobody_uid(): + """Internal routine to get nobody's uid""" + global nobody + if nobody: + return nobody + try: + import pwd + except ImportError: + return -1 + try: + nobody = pwd.getpwnam('nobody')[2] + except KeyError: + nobody = 1 + max(map(lambda x: x[2], pwd.getpwall())) + return nobody + +if __name__ == '__main__': + # TODO make this configurable again? command-line seems ok to me... + address = ('', 8080) + httpd = BaseHTTPServer.HTTPServer(address, RoundupRequestHandler) + print 'Roundup server started on', address + httpd.serve_forever() + +# +# $Log: not supported by cvs2svn $ +# Revision 1.1 2001/07/22 11:15:45 richard +# More Grande Splite stuff +# +# +