#!/usr/bin/python

from subprocess import *

import sys, os, time


class Main:
    _kdir = None
    _idir = None
    _ldir = None
    _logf = None
    _LOG  = None
    
    def __init__(self):
        self._sdir = "/home/sadrabinski/qa/ocspserver"
        self._kdir = "%s/keys"              % (self._sdir)
        self._idir = "%s/testCA"            % (self._kdir)
        self._ldir = "%s/logs"              % (self._sdir)
        self._pfile= "%s/ocspserver.pid"    % (self._sdir)
    # def __init__
    
    def run(self, action):
        self._LOG  = open("/dev/null", "w")
        
        if   (action == "start"     ): self._start()
        elif (action == "stop"      ): self._stop()
        elif (action == "restart"   ): self._restart()
        elif (action == "check"     ): self._check()
        elif (action == "keepalive" ): self._keepalive()
        else:                          self.help()
        
        self._LOG.close()
    # def run
    
    def help(self): self._print("Usage: ocspserver [start|stop|restart|check]\n\n")
    
    def _start(self, silent = False):
        if not (silent): self._print("Starting ocspserver ... ")
        self._logrotate()
        handle  = Popen("/usr/bin/openssl ocsp -index %s/index.txt -rsigner %s/2.rsa.cert.pem -CA %s/2.rsa.cert.pem -port 6277 -rkey %s/2.rsa.key.pem -text -out %s/%f.log &" % (self._idir, self._kdir, self._kdir, self._kdir, self._ldir, time.time()), shell=True, stdout=self._LOG, stderr=self._LOG, close_fds=True)
        pid     = "%s" % (handle.pid+1)
        
        try:
            fp  = open(self._pfile, "w")
            fp.write(pid)
            fp.close()
            self._print("pid: %s ... " % (pid))
        except:
            self._print("pid: %s [can't write file] ... " % (pid))
        # try except
        
        if not (silent): self._print("done.\n")
    # def _start
    
    def _stop(self):
        self._print("Stopping ocspserver ... ")
        pid = self._getpid()
        if (os.path.exists(self._pfile)): os.remove(self._pfile)
        
        if (pid != 0):
            handle = Popen("/bin/kill -9 %s" % (pid), shell=True, stdout=self._LOG, stderr=self._LOG, close_fds=True)
            
            while True:
                handle.poll()
                
                if (handle.returncode != None): break
                
                time.sleep(1)
            # while
        else:
            self._print("can't find pid ... ")
            
            handle = Popen("/bin/killall -9 openssl", shell=True, stdout=self._LOG, stderr=self._LOG, close_fds=True)
            
            while True:
                handle.poll()
                
                if (handle.returncode != None): break
                
                time.sleep(1)
            # while
        # if else
        
        self._print("done.\n")
    # def _stop
    
    def _filepid(self):
        fp  = open(self._pfile, "r")
        pid = fp.read()
        fp.close()
        
        return pid
    # def _filepid
    
    def _procpid(self):
        handle = Popen("/bin/ps aux | grep \"/usr/bin/openssl ocsp\"", shell=True, stdout=PIPE, stderr=PIPE, close_fds=True)
        pid    = 0
        
        while True:
            handle.poll()
            
            if (handle.returncode != None): break
            
            (out, err) = handle.communicate()
            time.sleep(1)
        # while
        
        line  = ""
        
        for c in out:
            line   += c
            
            if (c  != '\n'): continue
            
            line    = line.rstrip()
            
            if (line.find("/usr/bin/openssl ocsp -index") != -1):
                line    = line[line.find(" "):].strip()
                line    = line[:line.find(" ")].strip()
                pid     = line
            # if
            
            line = ""
        # for in
        
        return pid
    # def _procpid
    
    def _getpid(self):
        pid = 0
        
        try:
            pid = self._filepid()
            
            if not (pid.isdigit()): raise Exception("NotANuber", "bad pid '%s'" % (pid))
            
            self._print("pid: %s ... " % (pid))
        except:
            self._print("pid: ??? [can't read file] ... ")
            pid = self._procpid()
            if (pid != 0): self._print("found pid: %s ... " % (pid))
        # try except
        
        return pid
    # def _getpid
    
    def _restart(self):
        self._stop()
        time.sleep(2)
        self._start()
    # def _restart
    
    def _check(self):
        self._print("Checking ocspserver ... ")
        pid = self._procpid()
        
        if (pid == 0):
            self._print("dead.\n")
            print ""
            sys.exit(1)
        # if
        
        self._print("alive.\n")
    # def _check
    
    def _keepalive(self):
        self._print("Keepalive ocspserver ... ")
        pid = self._procpid()
        
        if (pid == 0):
            self._print("resurrecting ... ")
            self._start(silent = True)
        else:
            self._print("still alive ... ")
        # if else
        
        self._print("done.\n")
    # def _keepalive
    
    def _logrotate(self):
        if not (os.path.exists(self._ldir)): os.mkdir(self._ldir)
        
        logs = os.listdir(self._ldir)
        
        for log in logs:
            if (log.rfind(".gz") != -1): continue
            
            handle = Popen("/bin/gzip -9 %s/%s" % (self._ldir, log), shell=True, stdout=self._LOG, stderr=self._LOG, close_fds=True)
            
            while True:
                handle.poll()
                
                if (handle.returncode != None): break
                
                (out, err) = handle.communicate()
                time.sleep(1)
            # while
        # for in
    # def _logrotate
    
    def _print(self, msg):
        sys.stdout.write(msg)
        sys.stdout.flush()
    # def _print
# class Main

if (__name__ == "__main__"):
    start = Main()
    
    if (len(sys.argv) != 2): start.help()
    else:                    start.run(sys.argv[1])
    
    print ""
# if
