#!/usr/bin/python2.4 import os import WebInterfaceSites from CryptoBoxExceptions import * import sys try: import cherrypy except: print "Could not import the cherrypy module! Try 'apt-get install python-cherrypy'." sys.exit(1) ## TODO: it should be possible to override this via commandline arguments PID_FILE = '/var/run/cryptobox/webserver.pid' class CryptoBoxWebserver: '''this class starts the cherryp webserver and serves the single sites''' def __init__(self): try: cherrypy.root = WebInterfaceSites.WebInterfaceSites() except (CBConfigError,CBEnvironmentError), errMsg: sys.stderr.write("The CryptoBox is misconfigured - please fix it!\n") sys.stderr.write("%s\n" % str(errMsg)) sys.exit(1) #expose static content: #I currently have no idea how to cleanly extract the stylesheet path from #the config object without an extra CryptoBox.CryptoBoxProps instance. #perhaps put config handling into a separate class in CryptoBox.py? # # the following manual mapping is necessary, as we may not use relative # paths in the config file cherrypy.config.configMap.update({ "/cryptobox-misc": { "staticFilter.on" : True, "staticFilter.dir": os.path.abspath("/usr/share/cryptobox/html" )} }) def start(self): # just use this config, when we're started directly cherrypy.config.update(file = "/etc/cryptobox/cryptoboxwebserver.conf") cherrypy.server.start() def fork_to_background(): ## this is just copy'n'pasted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731 ## check the original for exhaustive comments try: pid = os.fork() except OSError, errMsg: sys.stderr.write("Failed to fork cryptobox daemon process!\n") sys.stderr.write("%s\n" % errMsg) sys.exit(1) if pid == 0: # the first child os.setsid() try: pid = os.fork() except OSError, errMsg: sys.stderr.write("Failed to fork second cryptobox daemon process!\n") sys.stderr.write("%s\n" % errMsg) sys.exit(1) if pid == 0: # the second child os.chdir(os.path.sep) os.umask(0) else: os._exit(0) else: os._exit(0) import resource # Resource usage information. maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] if (maxfd == resource.RLIM_INFINITY): maxfd = 1024 for fd in range(0, maxfd): try: os.close(fd) except OSError: # ERROR, fd wasn't open to begin with (ignored) pass os.open(os.devnull, os.O_RDWR) # standard input (0) os.dup2(0, 1) # standard output (1) os.dup2(0, 2) # standard error (2) def write_pid_file(pid_file): try: pidf = open(pid_file,"w") pidf.write(str(os.getpid())) pidf.close() except (IOError, OSError), errMsg: sys.stderr.write("Failed to write pid file (%s): %s\n" % (pid_file, errMsg)) ## it is just a warning - no need to break if __name__ == "__main__": ## TODO: add some argument checking: configFile, daemonMode, ... cbw = CryptoBoxWebserver() ## run the webserver as a daemon process fork_to_background() ## write pid file write_pid_file(PID_FILE) try: cbw.start() except Exceptions, errMsg: sys.stderr.write("Failed to start the CryptoBox webserver!\n") sys.stderr.write("%s\n" % str(errMsg)) sys.stderr.write("Check the log file for details.\n") sys.exit(1) sys.exit(0)