#!/usr/bin/env python

# Copyright C 2002-2008 by Isilon Systems, Inc. All rights not expressly
# granted herein are reserved.
# Created in the United States of America.
# 
# This digital media is protected by U.S. and international copyright and
# intellectual property laws. Unless otherwise specified, all information
# and screens appearing as part of this digital medium, including
# software, services, documents, text, images, icons, and logos design;
# the selection, assembly, arrangement, and design thereof; and the code
# that enables its presentation, are the sole property of Isilon Systems,
# Inc.
# 
# Except as otherwise required by applicable law, no part of any
# copyrighted material may be reproduced, modified, translated,
# distributed, published, or transmitted by any means, electronic or
# mechanical, for any purpose, without the prior written consent of Isilon
# Systems. 
#  
# Isilon and Isilon Systems are registered trademarks of Isilon Systems,
# Inc.  "Isilon IQ" is a trademark of Isilon Systems, Inc.  All other
# trademarks and registered trademarks are the property of their
# respective holders.

import os, sys, signal, errno, time
import isi.fs.enc as enc
import syslog
from isi.app.lib import safelockfile

SCRIPT_NAME = os.path.basename(sys.argv[0])
PID_FILE = '/var/run/vsftpd.pid'
LOCK_FILE = '/var/run/vsftpd.lock'
SERVICE_NAME = 'vsftpd'
SERVICE_PATH = '/usr/local/libexec/%s' % SERVICE_NAME
CONFIG_PATH = '/usr/local/etc/vsftpd.conf'


def start_cmd():
    print 'Starting %s ...' % SERVICE_NAME,
    #check if the server is already running.
    if os.path.isfile(PID_FILE):
        pid = int(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 %d 2>/dev/null' % pid)
            out = ps.read()
            ps.close()
            if out and SERVICE_NAME in out:
                print 'already running'
                sys.exit(0)
        try:
            os.remove(PID_FILE)
        except OSError:
            pass

    # set encoding to default
    try:
        enc.ifs_encoding(0)
    except StandardError as e:
        pass

    # Spawn process and save off the PID to the pid file
    pid =  os.spawnv(os.P_NOWAIT, SERVICE_PATH, (SERVICE_PATH, CONFIG_PATH))
    if pid:
        fh = open(PID_FILE, 'w')
        fh.write(str(pid))
        fh.close()
    else:
        print 'Could not determine pid.'
        sys.exit(1)
    
    print 'done'    
    

def stop_cmd():
    print 'Stopping %s ...' % SERVICE_NAME,
    if os.path.isfile(PID_FILE):
        pid = int(open(PID_FILE).read())
        if pid:
            ps = os.popen('ps -o command= -p %d 2>/dev/null' % pid)
            out = ps.read()
            ps.close()
            if out and SERVICE_NAME in out:
                try:
                    os.kill(pid, signal.SIGTERM)
                    # wait for a moment to see if the process dies
                    for n in range(10):
                        time.sleep(0.25)
                        try:
                            # poll the process state
                            os.kill(pid, 0)
                        except OSError, why:
                            if why[0] == errno.ESRCH:
                                # process has died
                                break
                            else:
                                raise
                    else:
                        sys.exit("error: pid %d did not die" % pid)
                except:
                    print 'error: Could not kill process %s names 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'
        

def help_cmd():
    print 'Usage: %s {%s}' % (SCRIPT_NAME, '|'.join([x for x in functions if x != 'help']))
    sys.exit(1)

    
def restart_cmd():
    stop_cmd()
    start_cmd()


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

functions = {'start': start_cmd,
             'stop': stop_cmd, 
             'restart': restart_cmd,
             'help': help_cmd}

if opt in functions:
    try:
        sentry = safelockfile(LOCK_FILE, 'w')
    except EnvironmentError, e:
        syslog.syslog(syslog.LOG_NOTICE,
                      "Locking error in vsftpdctl script: %s" % e)
        sys.exit(1)
        
    func = functions[opt]
    func()
    sentry.close()
    
else:
    help_cmd()

