<s> import os , errno , sys <EOL> from twisted . python import log , syslog , logfile , usage <EOL> from twisted . python . util import switchUID , uidFromString , gidFromString <EOL> from twisted . application import app , service <EOL> from twisted . internet . interfaces import IReactorDaemonize <EOL> from twisted import copyright <EOL> def _umask ( value ) : <EOL> return int ( value , <NUM_LIT:8> ) <EOL> class ServerOptions ( app . ServerOptions ) : <EOL> synopsis = "<STR_LIT>" <EOL> optFlags = [ [ '<STR_LIT>' , '<STR_LIT:n>' , "<STR_LIT>" ] , <EOL> [ '<STR_LIT>' , None , "<STR_LIT>" ] , <EOL> [ '<STR_LIT>' , None , "<STR_LIT>" ] , <EOL> [ '<STR_LIT>' , '<STR_LIT>' , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ] , <EOL> ] <EOL> optParameters = [ <EOL> [ '<STR_LIT>' , None , '<STR_LIT>' , <EOL> "<STR_LIT>" ] , <EOL> [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> "<STR_LIT>" ] , <EOL> [ '<STR_LIT>' , None , None , <EOL> '<STR_LIT>' ] , <EOL> [ '<STR_LIT>' , '<STR_LIT:u>' , None , "<STR_LIT>" , uidFromString ] , <EOL> [ '<STR_LIT>' , '<STR_LIT:g>' , None , "<STR_LIT>" , gidFromString ] , <EOL> [ '<STR_LIT>' , None , None , <EOL> "<STR_LIT>" , _umask ] , <EOL> ] <EOL> compData = usage . Completions ( <EOL> optActions = { "<STR_LIT>" : usage . CompleteFiles ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : usage . CompleteDirs ( descr = "<STR_LIT>" ) , <EOL> "<STR_LIT>" : usage . CompleteGroups ( descr = "<STR_LIT>" ) , <EOL> "<STR_LIT>" : usage . CompleteUsernames ( descr = "<STR_LIT>" ) , <EOL> "<STR_LIT>" : usage . Completer ( descr = "<STR_LIT>" ) , <EOL> } , <EOL> ) <EOL> def opt_version ( self ) : <EOL> """<STR_LIT>""" <EOL> print '<STR_LIT>' % copyright . version <EOL> print copyright . copyright <EOL> sys . exit ( ) <EOL> def postOptions ( self ) : <EOL> app . ServerOptions . postOptions ( self ) <EOL> if self [ '<STR_LIT>' ] : <EOL> self [ '<STR_LIT>' ] = os . path . abspath ( self [ '<STR_LIT>' ] ) <EOL> def checkPID ( pidfile ) : <EOL> if not pidfile : <EOL> return <EOL> if os . path . exists ( pidfile ) : <EOL> try : <EOL> pid = int ( open ( pidfile ) . read ( ) ) <EOL> except ValueError : <EOL> sys . exit ( '<STR_LIT>' % pidfile ) <EOL> try : <EOL> os . kill ( pid , <NUM_LIT:0> ) <EOL> except OSError , why : <EOL> if why [ <NUM_LIT:0> ] == errno . ESRCH : <EOL> log . msg ( '<STR_LIT>' % pidfile , isError = True ) <EOL> os . remove ( pidfile ) <EOL> else : <EOL> sys . exit ( "<STR_LIT>" % <EOL> ( pid , pidfile , why [ <NUM_LIT:1> ] ) ) <EOL> else : <EOL> sys . exit ( """<STR_LIT>""" % pid ) <EOL> class UnixAppLogger ( app . AppLogger ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , options ) : <EOL> app . AppLogger . __init__ ( self , options ) <EOL> self . _syslog = options . get ( "<STR_LIT>" , False ) <EOL> self . _syslogPrefix = options . get ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> self . _nodaemon = options . get ( "<STR_LIT>" , False ) <EOL> def _getLogObserver ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _syslog : <EOL> return syslog . SyslogObserver ( self . _syslogPrefix ) . emit <EOL> if self . _logfilename == '<STR_LIT:->' : <EOL> if not self . _nodaemon : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> logFile = sys . stdout <EOL> elif self . _nodaemon and not self . _logfilename : <EOL> logFile = sys . stdout <EOL> else : <EOL> if not self . _logfilename : <EOL> self . _logfilename = '<STR_LIT>' <EOL> logFile = logfile . LogFile . fromFullPath ( self . _logfilename ) <EOL> try : <EOL> import signal <EOL> except ImportError : <EOL> pass <EOL> else : <EOL> if not signal . getsignal ( signal . SIGUSR1 ) : <EOL> def rotateLog ( signal , frame ) : <EOL> from twisted . internet import reactor <EOL> reactor . callFromThread ( logFile . rotate ) <EOL> signal . signal ( signal . SIGUSR1 , rotateLog ) <EOL> return log . FileLogObserver ( logFile ) . emit <EOL> def daemonize ( reactor , os ) : <EOL> """<STR_LIT>""" <EOL> if IReactorDaemonize . providedBy ( reactor ) : <EOL> reactor . beforeDaemonize ( ) <EOL> if os . fork ( ) : <EOL> os . _exit ( <NUM_LIT:0> ) <EOL> os . setsid ( ) <EOL> if os . fork ( ) : <EOL> os . _exit ( <NUM_LIT:0> ) <EOL> null = os . open ( '<STR_LIT>' , os . O_RDWR ) <EOL> for i in range ( <NUM_LIT:3> ) : <EOL> try : <EOL> os . dup2 ( null , i ) <EOL> except OSError , e : <EOL> if e . errno != errno . EBADF : <EOL> raise <EOL> os . close ( null ) <EOL> if IReactorDaemonize . providedBy ( reactor ) : <EOL> reactor . afterDaemonize ( ) <EOL> def launchWithName ( name ) : <EOL> if name and name != sys . argv [ <NUM_LIT:0> ] : <EOL> exe = os . path . realpath ( sys . executable ) <EOL> log . msg ( '<STR_LIT>' + name ) <EOL> os . execv ( exe , [ name , sys . argv [ <NUM_LIT:0> ] , '<STR_LIT>' ] + sys . argv [ <NUM_LIT:1> : ] ) <EOL> class UnixApplicationRunner ( app . ApplicationRunner ) : <EOL> """<STR_LIT>""" <EOL> loggerFactory = UnixAppLogger <EOL> def preApplication ( self ) : <EOL> """<STR_LIT>""" <EOL> checkPID ( self . config [ '<STR_LIT>' ] ) <EOL> self . config [ '<STR_LIT>' ] = ( self . config [ '<STR_LIT>' ] <EOL> or self . config [ '<STR_LIT>' ] ) <EOL> self . oldstdout = sys . stdout <EOL> self . oldstderr = sys . stderr <EOL> def postApplication ( self ) : <EOL> """<STR_LIT>""" <EOL> self . startApplication ( self . application ) <EOL> self . startReactor ( None , self . oldstdout , self . oldstderr ) <EOL> self . removePID ( self . config [ '<STR_LIT>' ] ) <EOL> def removePID ( self , pidfile ) : <EOL> """<STR_LIT>""" <EOL> if not pidfile : <EOL> return <EOL> try : <EOL> os . unlink ( pidfile ) <EOL> except OSError , e : <EOL> if e . errno == errno . EACCES or e . errno == errno . EPERM : <EOL> log . msg ( "<STR_LIT>" ) <EOL> else : <EOL> log . err ( e , "<STR_LIT>" ) <EOL> except : <EOL> log . err ( None , "<STR_LIT>" ) <EOL> def setupEnvironment ( self , chroot , rundir , nodaemon , umask , pidfile ) : <EOL> """<STR_LIT>""" <EOL> daemon = not nodaemon <EOL> if chroot is not None : <EOL> os . chroot ( chroot ) <EOL> if rundir == '<STR_LIT:.>' : <EOL> rundir = '<STR_LIT:/>' <EOL> os . chdir ( rundir ) <EOL> if daemon and umask is None : <EOL> umask = <NUM_LIT:0> <NUM_LIT> <EOL> if umask is not None : <EOL> os . umask ( umask ) <EOL> if daemon : <EOL> from twisted . internet import reactor <EOL> daemonize ( reactor , os ) <EOL> if pidfile : <EOL> f = open ( pidfile , '<STR_LIT:wb>' ) <EOL> f . write ( str ( os . getpid ( ) ) ) <EOL> f . close ( ) <EOL> def shedPrivileges ( self , euid , uid , gid ) : <EOL> """<STR_LIT>""" <EOL> if uid is not None or gid is not None : <EOL> extra = euid and '<STR_LIT:e>' or '<STR_LIT>' <EOL> desc = '<STR_LIT>' % ( extra , extra , uid , gid ) <EOL> try : <EOL> switchUID ( uid , gid , euid ) <EOL> except OSError : <EOL> log . msg ( '<STR_LIT>' % desc ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> else : <EOL> log . msg ( '<STR_LIT>' % desc ) <EOL> def startApplication ( self , application ) : <EOL> """<STR_LIT>""" <EOL> process = service . IProcess ( application ) <EOL> if not self . config [ '<STR_LIT>' ] : <EOL> launchWithName ( process . processName ) <EOL> self . setupEnvironment ( <EOL> self . config [ '<STR_LIT>' ] , self . config [ '<STR_LIT>' ] , <EOL> self . config [ '<STR_LIT>' ] , self . config [ '<STR_LIT>' ] , <EOL> self . config [ '<STR_LIT>' ] ) <EOL> service . IService ( application ) . privilegedStartService ( ) <EOL> uid , gid = self . config [ '<STR_LIT>' ] , self . config [ '<STR_LIT>' ] <EOL> if uid is None : <EOL> uid = process . uid <EOL> if gid is None : <EOL> gid = process . gid <EOL> self . shedPrivileges ( self . config [ '<STR_LIT>' ] , uid , gid ) <EOL> app . startApplication ( application , not self . config [ '<STR_LIT>' ] ) </s>
