#!/usr/bin/env python
#
# WebKit application server
# part of Webware for Python
#
# /etc/init.d/webkit
#
# Generic init.d Python start script for Unix
#
# Note: You will also find shell start scripts for
# various Unix flavors in the StartScripts folder.
#

import os
import sys
import pwd
import grp
import signal

# START LOCAL CONFIGURATION

# If you store this script in your Webware working directory
# and create a symlink to it as /etc/init.d/webkit_appname,
# it will try to guess your configuration parameters. You can
# make changes either directly here or you can also override
# the configuration in the Launch.py script.

# The location and name of the start sript:
START_SCRIPT = sys.argv[0]
# Get the target file if start script is given as a link:
while os.path.islink(START_SCRIPT):
    START_SCRIPT = os.path.join(
        os.path.dirname(START_SCRIPT), os.readlink(START_SCRIPT))
APP_NAME = os.path.basename(START_SCRIPT)

# The location of the working directory:
WORK_DIR = os.path.dirname(START_SCRIPT)
if WORK_DIR == '/etc/init.d':
    # Put hard coded path to working directory here:
    WORK_DIR = '.'

# Make sure to have the absolute path:
if not os.path.isdir(WORK_DIR):
    print "Error: Working directory not found."
    sys.exit(5)
WORK_DIR = os.path.abspath(WORK_DIR)

# The app server launch script:
APP_SERVER = os.path.join(WORK_DIR, "AppServer")

if not os.path.isfile(APP_SERVER):
    print "Error: AppServer script not found."
    sys.exit(5)

# The WebKit app server log file
# (you can set this in Launch.py as well):
#LOG_FILE="/var/log/%s.log" % APP_NAME
LOG_FILE = "%s/Logs/webkit.log" % WORK_DIR
# Use this extension if you want to move the last log away
# (also consider using logrotate or something similar):
LOG_OLD = ".old"

# The app server process id file
# (you can set this in Launch.py as well):
#PID_FILE="/var/run/%s.pid" % APP_NAME
PID_FILE = "%s/webkit.pid" % WORK_DIR

# The user and group to run the app server
# (you can set this in Launch.py as well).
# If undefined, it will be the user and group
# running the start script (usually root).
# You should use a low-privilege account,
# like the work dir owner, wwwrun or nobody.
# This will use the owner of the AppServer script:
WEBWARE_USER = pwd.getpwuid(os.stat(APP_SERVER)[4])[0]
WEBWARE_GROUP = grp.getgrgid(os.stat(APP_SERVER)[5])[0]

# Set the following variable to False if you want to store
# the pid and log files as the user running the start script
# (usually root) or set it if you want these files to be
# written after switching to the WEBWARE_USER.
LAUNCH_AS_WEBWARE = True

# Additional options -u or -O to be passed on to Python:
PYTHONOPTS = ""
# Additional libraries to be included in the Python path:
PYTHONPATH = ""
if PYTHONPATH:
    os.environ['PYTHONPATH'] = PYTHONPATH

# END LOCAL CONFIGURATION

if len(sys.argv) > 1:
    opt = sys.argv[1].lower()
else:
    opt = None

if opt == 'start':
    print "Starting %s ..." % APP_NAME,
    # Keep backup of last log file:
    if LOG_OLD and os.path.isfile(LOG_FILE):
        if os.path.getsize(LOG_FILE):
            os.rename(LOG_FILE, LOG_FILE + LOG_OLD)
        else:
            os.remove(LOG_FILE)
    # Check if the server is already running:
    if os.path.isfile(PID_FILE):
        PID = open(PID_FILE).read()
        if PID:
            # Check on the command line if it is really our pid file:
            ps = os.popen('ps -o command= -p %s 2>/dev/null' % PID)
            out = ps.read()
            if ps.close():
                # MacOs has only "command", SunOS has only "args"
                ps = os.popen('ps -o args= -p %s 2>/dev/null' % PID)
                out = ps.read()
                if ps.close():
                    out = None
            if out and ' -i %s ' % PID_FILE in out:
                print "already running"
                sys.exit(0)
        try:
            os.remove(PID_FILE)
        except OSError:
            pass
    USER = pwd.getpwuid(os.getuid())[0]
    GROUP = grp.getgrgid(os.getgid())[0]
    if (not WEBWARE_USER or WEBWARE_USER == USER) and (
            not WEBWARE_GROUP or WEBWARE_GROUP == GROUP):
        CMD = '"%s" %s -i "%s" -d "%s" -o "%s" > /dev/null &' % (
            APP_SERVER, PYTHONOPTS, PID_FILE, WORK_DIR, LOG_FILE)
        os.system(CMD)
    else:
        if LAUNCH_AS_WEBWARE:
            # Switch user first, then create pid and log files:
            CMD = '"%s" %s -i "%s" -d "%s" -o "%s"' % (
                APP_SERVER, PYTHONOPTS, PID_FILE, WORK_DIR, LOG_FILE)
            os.system('su %s -c "%s" > /dev/null &' % (WEBWARE_USER, CMD))
        else:
            # Create pid and log files first, then switch user:
            CMD = '"%s" %s -i "%s" -d "%s" -u %s >> "%s" 2>&1 &' % (
                APP_SERVER, PYTHONOPTS, PID_FILE,
                WORK_DIR, WEBWARE_USER, LOG_FILE)
            os.system(CMD)
    print "done"
elif opt == 'stop':
    print "Stopping %s ..." % APP_NAME,
    if os.path.isfile(PID_FILE):
        PID = open(PID_FILE).read()
        if PID:
            ps = os.popen('ps -o command= -p %s 2>/dev/null' % PID)
            out = ps.read()
            if ps.close():
                ps = os.popen('ps -o args= -p %s 2>/dev/null' % PID)
                out = ps.read()
                if ps.close():
                    out = None
            if out and ' -i %s ' % PID_FILE in out:
                try:
                    os.kill(int(PID), signal.SIGTERM)
                except OSError:
                    print "error"
                    print "Could not kill process %s named in %s" % (
                        PID, PID_FILE)
                    sys.exit(1)
                else:
                    print "done"
            else:
                print "not running (removing stale pid file)"
        else:
            print "not running (removing empty pid file)"
        try:
            os.remove(PID_FILE)
        except OSError:
            pass
    else:
        print "not running"
else:
    print "Usage: %s {start|stop}" % sys.argv[0]
    sys.exit(1)
