#!/usr/bin/env python

# standard modules
import os
import re
import sys
import time                
import dbus
import logging
import fileinput

# for encryption/decryption
import base64
from Crypto.Cipher import AES

##############################################################
#    smscon - remote control utility                         #
##############################################################

BUILD    = '1'
BRANCH   = '0.8'
VERSION  = '%s.%s' % (BRANCH, BUILD)
NAME     = 'smscon'
DATE     = '13/6/2011'

##############################################################

# check if run as root
if os.geteuid() != 0:
    print 'ERROR: smscon must run as "root".'
    sys.exit(1)

##############################################################

TIME       = True

Path       = '/opt/%s' % NAME
BootPath   = '/etc/event.d'

DaemonFile = '%s_daemon' % NAME
CodeFile   = '%s_code' % NAME
ConfigFile = '%s_config' % NAME
BootFile   = '%s_boot' % NAME
ScriptFile = '%s_script' % NAME

BootCode   = 'description "%s v%s - nokia n900 remote control utility"\n' % (NAME, VERSION) + \
"""
start on started hildon-desktop
stop on starting shutdown

console none

script
    while [ ! -e %s ]; do
        sleep 3
    done
    exec %s/%s -start > /tmp/%s_boot.log 2>&1
end script
""" % (Path, Path, NAME, NAME)

##############################################################

ConfigVars = ['SENDERNUMBER',                 
              'EMAILADDRESS',
              'COM_CHECK',
              'COM_REBOOT',
              'COM_POWEROFF',
              'COM_POWER',
              'COM_LOCATION',
              'COM_REMOTEON',
              'COM_REMOTEOFF',
              'COM_CAMERA',
              'COM_CALL',
              'COM_LOCK', 
              'COM_UNLOCK',
              'COM_TRACKON',
              'COM_TRACKOFF',
              'COM_CUSTOM',
              'COM_SHELL',
              'COM_ALARM',
              'COM_RESTART',
              'ENABLECHECKHOST',
              'CHECKHOST',
              'CHECKTIME',
              'USER',         
              'PASSWORD',        
              'EMAILFROM',       
              'MAILSERVER',      
              'MAILPORT',
              'REMOTEHOST',            
              'REMOTEPORT',           
              'REMOTEUSER',       
              'REMOTEPASSWORD',
              'MESSAGESEND',
              'ENABLERESEND',
              'RESENDTIME',
              'COMMANDREPLY',
              'KEYBOARDDETECT',
              'AUTODEVICELOCK',
              'SIMUNLOCK',
              'AUTOBATREPORT',
              'SILENCEDEVICE',
              'GPSTIMEOUT',
              'GPSPOLLING',
              'GPSINTERVAL',
              'GPSSEND']

##############################################################

EncryptedConfigVars = ['USER',         
                       'PASSWORD',        
                       'REMOTEUSER',       
                       'REMOTEPASSWORD']

TabSize   = 18
BlockSize = 16
Padding   = '{'
Pad       = lambda s: s + (BlockSize - len(s) % BlockSize) * Padding
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(Pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(Padding)
Secret    = '6983456712936753'

##############################################################

LogPath    = Path #'/tmp'
LogFile    = '%s.log' % NAME

if TIME:
    logging.basicConfig(filename = '%s/%s' % (LogPath, LogFile),
                        level    = logging.DEBUG,
                        format   = 'SMSCON %(levelname)s: %(message)s (%(asctime)s)',
                        datefmt  = '%d-%m-%Y %H:%M:%S')
else:
    logging.basicConfig(filename = '%s/%s' % (LogPath, LogFile),
                        level    = logging.DEBUG,
                        format   = 'SMSCON %(levelname)s: %(message)s')
    
##############################################################

def StatusSMScon():
    """
    Check if smscon_daemon is active.
    """

    Output = os.popen( 'ps ax | grep -v grep | grep %s' % DaemonFile ).read()

    if Output == '': 
        return False
    else: 
        return True

##############################################################    

def StartSMScon():
    """
    Start smscon_daemon.
    """

    os.system( '%s/%s &' % (Path, DaemonFile) )
    logging.info('----- %s is started & running -----' % DaemonFile)

##############################################################

def StopSMScon():
    """
    Kill smscon_daemon.
    """

    Output = os.popen('ps ax | grep -v grep | grep %s' % DaemonFile).read()

    if Output != '':
        Exp = re.compile('(\d+) root')
        PIDdaemon = Exp.search(Output).group(1)

        if PIDdaemon != '': 
            os.system('kill %s' % PIDdaemon)
            logging.info( '%s [PID=%s] is stopped' % (DaemonFile, PIDdaemon) )
            print '%s is stopped.' % DaemonFile
        else: 
            logging.error('%s status unknown' % DaemonFile)
            print 'ERROR: %s status unknown.' % DaemonFile
    else:
        logging.info('%s was not running' % DaemonFile)
        print '%s was not running.' % DaemonFile

##############################################################

def StartDaemon(Mode, Function):
    """
    Start the smscon_daemon.
    """

    os.system( '%s/%s %s "%s" &' % (Path,
                                    DaemonFile,
                                    Mode,
                                    Function) )

    print '%s started.' % DaemonFile

##############################################################

def KillSSH():
    """
    Kill ssh connection (if running).
    """

    if os.popen('pidof ssh').read().strip('\n') != '':
        os.system('kill $(pidof ssh)')
        print 'ssh connection stopped.'

##############################################################

def KillScript():
    """
    Kill smscon_script file (if running).
    """

    if os.popen('pidof %s' % ScriptFile).read().strip('\n') != '':
        os.system('kill $(pidof %s)' % ScriptFile)
        print '%s stopped.' % ScriptFile

##############################################################

def ShowLog():
    """
    Show the logfile.
    """

    if CheckFile(LogPath, LogFile) == True:
        f = open('%s/%s' % (LogPath, LogFile), 'r')
        Output = f.readlines() 
        if Output == []:
            print '%s is empty.' % LogFile 
        else:
            for Text in Output:
                print Text.strip('\n')   
        f.close()
    else:
        print "%s doesn't excist." % LogFile

##############################################################

def CheckFile(Path, File):
    """
    Check if a file exists.
    """

    try:
        f = open('%s/%s' % (Path, File), 'r')
        f.close()
    except:
        return False
    else:
        return True

##############################################################

def SetBoot():
    """
    Set start smscon_daemon at device boot.
    """
    
    if CheckFile(BootPath, BootFile) == True:
        print '%s is already active.' % BootFile  
    else:
        print "%s doesn't excist." % BootFile
        f = open('%s/%s' % (BootPath, BootFile), "w")
        f.writelines(BootCode + '\n')
        f.close()
        print 'new %s created & active.' % BootFile 

##############################################################

def ShowIMSI():
    """
    Show IMSI number from smscon_code file.
    """

    if CheckFile(Path, CodeFile) == True:
        f = open('%s/%s' % (Path, CodeFile), 'r')
        Output = f.readlines() 
        f.close()

        if Output == []:
            print 'ERROR: %s is empty.' % CodeFile
        else:
            for n, Text in enumerate(Output):
                if Text != '' and Text != '\n':
                    print 'IMSI_%s = %s' % ( n + 1, Text.strip('\n') )   
    else:
        print "%s doesn't excist." % CodeFile

##############################################################

def Delete(Path, File):
    """
    Delete file.
    """

    if CheckFile(Path, File) == True:
        try:
            os.system( 'rm %s/%s' % (Path, File) )
        except:
            print 'ERROR: %s delete failure.' % File
        else:
            print '%s deleted.' % File
    else:
        print '%s already deleted.' % File

##############################################################

def ShowCommands():
    """
    Show available SMS commands.
    """

    SmsCommandsList  = []
    SmsCommandPreFix = 'COM_'
    TabSize          = 18

    if CheckFile(Path, ConfigFile) == True:
        f = open('%s/%s' % (Path, ConfigFile), 'r')
        ConfigLines = f.readlines() 
        if ConfigLines == []:
            print 'ERROR: %s is empty.' % ConfigFile
        else:
            try:
                for Line in ConfigLines:
                    Line = Line.strip().replace('\r', '').replace('\n', '')
                        
                    # detect sms command in text line
                    if Line.startswith(SmsCommandPreFix):
                        Data = Line.split('=')
                        Variable = Data[0].replace(' ', '')
                        Value    = Data[1].lstrip(' ')
                        if Value.startswith("'") and Value.endswith("'"):
                            SmsCommandsList.append( (Variable, Value) )
                        else:
                            print 'ERROR: syntax error in user settings (%s).' % Line

                for SmsCommand in SmsCommandsList:
                    print '%s= %s' % (SmsCommand[0].ljust(TabSize, ' '), SmsCommand[1])
            except:
                print 'ERROR: error reading user settings.'
        f.close()
    else:
        print "ERROR: %s doesn't excist." % ConfigFile

##############################################################

def InitConfig(Force=False):
    """
    Check if smscon_config exists, else create new default one.
    """

    ConfigTemplate = '# SMSCON user settings (v%s)\n' % VERSION + \
"""
# SMS number
SENDERNUMBER      = '+XXXXXXXXXXX'

# SMS commands
COM_CHECK         = 'Check'
COM_REBOOT        = 'Reboot'
COM_POWEROFF      = 'Poweroff'
COM_POWER         = 'Power'
COM_LOCATION      = 'Location'
COM_REMOTEON      = 'Remoteon'
COM_REMOTEOFF     = 'Remoteoff'
COM_CAMERA        = 'Camera'
COM_CALL          = 'Call'
COM_LOCK          = 'Lock'
COM_UNLOCK        = 'Unlock'
COM_TRACKON       = 'Trackon'
COM_TRACKOFF      = 'Trackoff'
COM_CUSTOM        = 'Script'
COM_SHELL         = 'uptime >> /tmp/commandlog'
COM_ALARM         = 'Alarm'
COM_RESTART       = 'Restart'

# REMOTE command
# (check server file at remote host to trigger smscon: 'yes', 'no')
ENABLECHECKHOST   = 'no'
# (check host)
CHECKHOST         = 'XXXXXXXX'
# (check interval in minutes)
CHECKTIME         = 15

# Email settings
EMAILADDRESS      = 'XXXXX@XXXXXXXXXXX.XX'
# (encrypted setting)
USER              = 'CTf6qr+x76lU13erkRFHoQ=='
# (encrypted setting)
PASSWORD          = 'CTf6qr+x76lU13erkRFHoQ=='
EMAILFROM         = 'XXXXXXXX@XXXXXX.XX'
MAILSERVER        = 'XXXX.XXXXXXXX.XX'
MAILPORT          = 25

# SSH settings
REMOTEHOST        = 'XXX.XXXXXXXX.XX'
REMOTEPORT        = 22
# (encrypted setting)
REMOTEUSER        = 'CTf6qr+x76lU13erkRFHoQ=='
# (encrypted setting)
REMOTEPASSWORD    = 'CTf6qr+x76lU13erkRFHoQ=='

# Reply message settings
# (method to send reply messages: 'sms' / 'email' / 'both' / 'none')
MESSAGESEND       = 'sms'
# (enable resending of reply message after <RESENDTIME> minutes
#  until successful sending; 'yes' / 'no')
ENABLERESEND      = 'no'
# (resend waiting time in minutes)
RESENDTIME        = 15

# Send acknowledge SMS
# (send acknowledge SMS after receiving valid SMS command: 'yes' / 'no')
COMMANDREPLY      = 'no'

# Detect keyboard use
# (send acknowledge SMS if keyboard is sliding: 'yes' / 'no')
KEYBOARDDETECT    = 'no'

# Device lock
# (lock device after receiving valid SMS command: 'yes' / 'no')
AUTODEVICELOCK    = 'yes'

# Auto battery status SMS report
# (sends SMS when SMSCON is set active with a SMS command & battery
#  is depleting: 'yes' / 'no')
AUTOBATREPORT     = 'no'

# Auto device unlock
# (unlocks device when new SIM is inserted; 'yes' / 'no')
SIMUNLOCK         = 'no'

# Silence the phone 
# (disable all phone sounds when SMSCON is set active with a SMS command: 'yes' / 'no')
SILENCEDEVICE     = 'no'

# GPS settings
# (if no GPS coordinates after <GPSTIMEOUT> seconds then stop aquiring)
GPSTIMEOUT        = 1800
# (number of GPS coordinates to acquire and use the most accurate in "Location"-mode)
GPSPOLLING        = 3
# (time between sending GPS coordinate SMS in "Trackon"-mode: 10 / 20 / 30 / 60 / 120)
GPSINTERVAL       = 60
# (method to send GPS coordinates: 'email' / 'sms' / 'both')
GPSSEND           = 'sms'
"""

    if Force == False:
        if CheckFile(Path, ConfigFile) == True:
            return True
        else:
            print 'creating new user config file in "%s/%s".' % (Path, ConfigFile)

            f = open('%s/%s' % (Path, ConfigFile), 'w')
            f.writelines(ConfigTemplate)
            f.close()
            
            print 'WARNING: first edit %s before using smscon!' % ConfigFile
            return False
    else:
        print 'WARNING: forced to create new user config file in "%s/%s".' % (Path, ConfigFile)

        f = open('%s/%s' % (Path, ConfigFile), 'w')
        f.writelines(ConfigTemplate)
        f.close()
        
        print 'WARNING: first edit %s before using smscon!' % ConfigFile
        return False        

##############################################################

def InitScript(Force=False):
    """
    Check if smscon_script exists, else create new default one.
    """    

    ScriptTemplate = '#!/bin/sh\n' + '# %s script (v%s)\n' % (NAME, VERSION) + '# (edit below)\n\n\n'

    if Force == False:
        if CheckFile(Path, ScriptFile) == True:
            return True
        else:
            print 'creating new script file "%s/%s".' % (Path, ScriptFile)

            f = open('%s/%s' % (Path, ScriptFile), 'w')
            f.writelines(ScriptTemplate)
            f.close()

            if os.WEXITSTATUS( os.system( 'chmod 755 %s/%s' % (Path, ScriptFile) ) ) != 0:
                print 'ERROR: failed to set user permissions on %s/%s' % (Path, ScriptFile)
                sys.exit(1)            

            if os.WEXITSTATUS( os.system( 'chown root %s/%s' % (Path, ScriptFile) ) ) != 0:
                print 'ERROR: failed to set owner of %s/%s' % (Path, ScriptFile)
                sys.exit(1) 

            print 'WARNING: first edit %s (if used) before using smscon!' % ScriptFile
            return False
    else:
        print 'WARNING: forced to create new script file "%s/%s".' % (Path, ScriptFile)

        f = open('%s/%s' % (Path, ScriptFile), 'w')
        f.writelines(ScriptTemplate)
        f.close()

        if os.WEXITSTATUS( os.system( 'chmod 755 %s/%s' % (Path, ScriptFile) ) ) != 0:
            print 'ERROR: failed to set user permissions on %s/%s' % (Path, ScriptFile)
            sys.exit(1)            

        if os.WEXITSTATUS( os.system( 'chown root %s/%s' % (Path, ScriptFile) ) ) != 0:
            print 'ERROR: failed to set owner of %s/%s' % (Path, ScriptFile)
            sys.exit(1) 

        print 'WARNING: first edit %s (if used) before using smscon!' % ScriptFile
        return False        

##############################################################

def ShowFile(Path, File, Option=False):
    """
    Show file.
    """

    if CheckFile(Path, File) == True:
        if Option == False:
            os.system( 'cat %s/%s' % (Path, File) )
        elif Option == True:
            f = open('%s/%s' % (Path, File), 'r')
            ConfigLines = f.readlines() 

            if ConfigLines == []:
                print '%s is empty.' % File
                sys.exit(1)
            else:
                for Line in ConfigLines:
                    Line = Line.strip().replace('\r', '').replace('\n', '')
                    
                    for Var in ConfigVars:
                        # get user variable & it's value from text line
                        if Line.startswith('%s' % Var):
                            try:
                                if Var in EncryptedConfigVars: # encrypted text value
                                    Variable, EncryptedValue = Line.split('=', 1)
                                else: # plain text value
                                    Variable, Value = Line.split('=', 1)
                            except:
                                print 'syntax error in line (%s = %s) of "%s" file' % (Variable.rstrip(' '), Value, File)
                                f.close()
                                sys.exit(1)
                            else:
                                if Var in EncryptedConfigVars: # encrypted text value
                                    EncryptedValue = EncryptedValue.lstrip(' ')
                                else: # plain text value
                                    Value = Value.lstrip(' ')
                                try:
                                    # encrypted text value
                                    if Var in EncryptedConfigVars:
                                        if EncryptedValue.startswith("'") == True and EncryptedValue.endswith("'") == True:
                                            EncryptedValue = EncryptedValue.strip("'")
                                            print '%s= %s' % ( Var.ljust(TabSize), DecodeAES(AES.new(Secret), EncryptedValue) ) # get string
                                        else:
                                            print 'syntax error; (%s)' % EncryptedValue
                                            f.close()
                                            sys.exit(1)                                     
                                    else:
                                        if Value.startswith("'") == True and Value.endswith("'") == True: # plain text value
                                            print '%s= %s' % ( Var.ljust(TabSize), Value.strip("'") ) # get string
                                        else: # plain text integer
                                            print '%s= %s' % ( Var.ljust(TabSize), int(Value) ) # get integer
                                except:
                                    print 'syntax error in line (%s = %s)' % (Variable.rstrip(' '), Value)
                                    f.close()
                                    sys.exit(1)           
            
    else:
        print 'ERROR: %s not found' % File

##############################################################
            
def ShowOptions():
    """
    Show options for smscon.
    """

    print '== smscon v%s - Nokia N900 remote control utility ==' % VERSION
    print ' Options:'
    print '   -start             : start %s' % DaemonFile
    print '   -restart           : stop & restart %s' % DaemonFile
    print '   -stop              : stop %s' % DaemonFile
    print '   -status            : get %s status' % DaemonFile
    print '   -log               : show log file'
    print '   -del log           : erase log file'
    print '   -sms               : show SMS commands'
    print '   -set name "value"  : set user setting (name = "value")'
    print '   -config            : show %s file' % ConfigFile.replace(NAME + '_', '')
    print '   -script            : show %s file' % ScriptFile.replace(NAME + '_', '')
    print '   -boot              : start %s at device boot' % DaemonFile
    print '   -unboot            : remove start of %s at device boot' % DaemonFile
    print '   -add imsi          : add current IMSI code to %s file' % CodeFile.replace(NAME + '_', '')
    print '   -remove imsi       : remove current IMSI code from %s file' % CodeFile.replace(NAME + '_', '')
    print '   -help              : this help menu'
    print ' Special options (normally not needed!):'
    print '   -reset             : factory default (delete %s, %s, %s & %s file)' % ( BootFile.replace(NAME + '_', ''),
                                                                                      ConfigFile.replace(NAME + '_', ''),
                                                                                      CodeFile.replace(NAME + '_', ''),
                                                                                      ScriptFile.replace(NAME + '_', '') )
    print '   -imsi              : show IMSI code file'
    print '   -del imsi          : delete %s file' % CodeFile.replace(NAME + '_', '')
    print '   -init              : create default %s & %s file' % (ConfigFile.replace(NAME + '_', ''), ScriptFile.replace(NAME + '_', ''))
    print '   -del config        : delete %s file' % ConfigFile.replace(NAME + '_', '')
    print '   -del script        : delete %s file' % ScriptFile.replace(NAME + '_', '')

##############################################################
            
def ShowHiddenOptions():
    """
    Show hidden options for smscon.
    """

    print ' Developer options:'
    print '   -devhelp           : this extended help menu'
    print '   -branch            : show branch number'
    print '   -build             : show build number'
    print '   -version           : show full version number'    
    print '   -force init        : create default %s & %s file even if already exists' % (ConfigFile.replace(NAME + '_', ''), ScriptFile.replace(NAME + '_', ''))
    print '   -test "test"       : run developer test (gps1, gps2, ssh, cam, sms, email1, email2, call, script)'
    print '   -comtest "command" : run smscon command as received simulated SMS message'
    print '   -devconfig         : show uncrypted %s file' % ConfigFile.replace(NAME + '_', '')

##############################################################

def SaveUserSetting(UserSetting, UserVar):
    """
    Save user setting in config file.
    """ 

    TabSize = 18

    if UserSetting in ConfigVars:
        try:
            File = '%s/%s' % (Path, ConfigFile)
            for Line in fileinput.FileInput(File, inplace = True):
                if Line.startswith(UserSetting + ' ') or Line.startswith(UserSetting + '='):
                    if UserSetting in EncryptedConfigVars:
                        UserVar = "'%s'" % EncodeAES(AES.new(Secret), UserVar)
                    else:
                        if not UserVar.isdigit():
                            UserVar = "'%s'" % UserVar
                    Line = '%s' % UserSetting.ljust(TabSize) + '= %s' % UserVar
                print Line.rstrip()
        except:
            print 'ERROR: failed to save [%s = %s].' % (UserSetting, UserVar)
        else:
            if UserSetting in EncryptedConfigVars:
                print 'user setting [%s = %s] is saved.' % ( UserSetting, DecodeAES(AES.new(Secret), UserVar) )
            else:
                print 'user setting [%s = %s] is saved.' % (UserSetting, UserVar)
    else:
        print 'unknown user setting (%s).' % UserSetting

###############################

def RemoveIMSIcode():
    """
    Remove current inserted SIM IMSI code from code file.
    """

    try:
        # get current IMSI code
        Output = os.popen('dbus-send --system --type=method_call --print-reply --dest=com.nokia.phone.SIM /com/nokia/phone/SIM Phone.Sim.get_imsi').read()
        E = re.compile('string "(\S+)"')
        Code = E.findall(Output)[0]
    except:
        print 'ERROR: failed to acquire IMSI code.'
    else:
        # remove IMSI cod from code file
        if Code in ReadIMSIcode():
            try:
                File = '%s/%s' % (Path, CodeFile)
                for Line in fileinput.FileInput(File, inplace = True):
                    if Line != '%s\n' % Code:
                        print Line.rstrip()
            except:
                print 'ERROR: failed to delete IMSI code.'
            else:
                print 'current IMSI code (%s) removed from "%s" file.' % (Code, CodeFile)
        else:
            print 'IMSI code (%s) not present in "%s" file.' % (Code, CodeFile)
 
###############################

def SaveIMSIcode():
    """
    Get current inserted SIM IMSI code & save to code file.
    """

    try:
        # get current IMSI code
        Output = os.popen('dbus-send --system --type=method_call --print-reply --dest=com.nokia.phone.SIM /com/nokia/phone/SIM Phone.Sim.get_imsi').read()
        E = re.compile('string "(\S+)"')
        Code = E.findall(Output)[0]
    except:
        print 'ERROR: failed to acquire IMSI code.'
    else:
        if CheckFile(Path, CodeFile) == False:
            print 'IMSI code file not found; creating new "%s" file.' % CodeFile
                
            # create new code file
            f = open('%s/%s' % (Path, CodeFile), 'w')
            f.writelines('%s\n' % Code)
            f.close()

            print 'IMSI code (%s) saved to new "%s" file' % (Code, CodeFile)
        else:
            CodeList = ReadIMSIcode()
            if CodeList != None:
                if Code in CodeList:
                    print 'current IMSI code already in "%s" file' % CodeFile
                else:
                    # append to current code file
                    f = open('%s/%s' % (Path, CodeFile), 'a')
                    f.writelines('%s\n' % Code)
                    f.close() 

                    print 'added IMSI code (%s) to "%s" file' % (Code, CodeFile)

###############################

def ReadIMSIcode():
    """
    Read IMSI code(s) from code file.
    """

    try:
        # read code file
        List = []
        f = open('%s/%s' % (Path, CodeFile), 'r+')
        List = f.readlines()
        f.close()

        # create list of found IMSI codes
        for n, Code in enumerate(List):
            List[n] = Code.strip('\n').strip(' ') 

        CodeList = [] 
        for L in List:
            if L != '' and L != '\n':
                CodeList.append(L) # = ['XXXXXXXXXXXXX', 'XXXXXXXXXXXXX', etc.]
    except:
        print 'ERROR: failed to read valid IMSI code from "%s" file' % CodeFile
        return None
    else:
        return CodeList 
    
##############################################################
#    Main
##############################################################

Delay = 0.5

if sys.argv[1:] != []: # 1 or more args given
    NumOfArg = len(sys.argv[1:])

    if NumOfArg == 1: # 1 arg given
        Mode = sys.argv[1] 

        if Mode == '-init':
            if CheckFile(Path, ConfigFile) == False:
                InitConfig()
            else:
                print '%s already created.' % ConfigFile

            if CheckFile(Path, ScriptFile) == False:
                InitScript()
            else:
                print '%s already created.' % ScriptFile
          
        elif Mode == '-start':
            if CheckFile(Path, ConfigFile) == True and CheckFile(Path, ScriptFile) == True:
                if StatusSMScon() == True:
                    print '%s already active.' % DaemonFile
                else:
                    StartSMScon()
                    time.sleep(Delay)
                    if StatusSMScon() == True:
                        print '%s started.' % DaemonFile
                    else:
                        print 'ERROR: %s failed to start.' % DaemonFile
                        sys.exit(1)
            else:
                if CheckFile(Path, ConfigFile) == False:
                    print 'ERROR: no %s file present' % ConfigFile
                if CheckFile(Path, ScriptFile) == False:
                    print 'ERROR: no %s file present' % ScriptFile
                sys.exit(1)

        elif Mode == '-restart':
            if CheckFile(Path, ConfigFile) == True and CheckFile(Path, ScriptFile) == True:
                if StatusSMScon() == True:
                    StopSMScon()           
                    time.sleep(Delay)
                StartSMScon()
                time.sleep(Delay)
                if StatusSMScon() == True:
                    print '%s started.' % DaemonFile
                else:
                    print 'ERROR: %s failed to start.' % DaemonFile
                    sys.exit(1)
            else:
                if CheckFile(Path, ConfigFile) == False:
                    print 'ERROR: no %s file present' % ConfigFile
                if CheckFile(Path, ScriptFile) == False:
                    print 'ERROR: no %s file present' % ScriptFile
                sys.exit(1)

        elif Mode == '-stop':
            StopSMScon()
            KillSSH()
            KillScript()

        elif Mode == '-reset':
            if StatusSMScon() == True:
                StopSMScon()
            else:
                print '%s already stopped.' % DaemonFile
            time.sleep(Delay)
            Delete(LogPath, LogFile)
            time.sleep(Delay)
            Delete(BootPath, BootFile)
            time.sleep(Delay)
            Delete(Path, CodeFile)
            time.sleep(Delay)
            Delete(Path, ConfigFile)
            time.sleep(Delay)            
            Delete(Path, ScriptFile)
            time.sleep(Delay) 
            KillSSH()
            KillScript()

        elif Mode == '-boot':
            SetBoot()

        elif Mode == '-unboot':
            Delete(BootPath, BootFile)                    

        elif Mode == '-status':
            if StatusSMScon() == True:
                print '%s is running.' % DaemonFile
            else:
                print '%s off.' % DaemonFile
    
        elif Mode == '-log':
            ShowLog()

        elif Mode == '-imsi':
            ShowIMSI()

        elif Mode == '-sms':
            ShowCommands()

        elif Mode == '-config':
            ShowFile(Path, ConfigFile)

        elif Mode == '-script':
            ShowFile(Path, ScriptFile)

        elif Mode == '-version':
            print '%s.%s' % (BRANCH, BUILD)        

        elif Mode == '-branch':
            print BRANCH

        elif Mode == '-build':
            print BUILD

        elif Mode == '-help':
            ShowOptions() 

        elif Mode == '-devhelp':
            ShowOptions()
            ShowHiddenOptions()

        elif Mode == '-devconfig':
            ShowFile(Path, ConfigFile, True)

        else:
            print 'unknown option (%s).' % Mode
            
    elif NumOfArg == 2: # 2 args given
        Mode = sys.argv[1]
        Func = sys.argv[2]

        if Mode == '-test' or Mode == '-comtest': # /* ONLY FOR DEVELOPMENT USAGE */
            if StatusSMScon() == True:
                StopSMScon()
                print '%s stopped.' % DaemonFile
                time.sleep(Delay)
                Delete(LogPath, LogFile)
                time.sleep(Delay)
                StartDaemon(Mode, Func)
                time.sleep(Delay)
                if StatusSMScon() == False:
                    print 'ERROR: %s failed to start.' % DaemonFile
                    sys.exit(1)
                else:
                    logging.info( '"%s" TEST: %s active' % (Func.upper(), DaemonFile) )
            else:
                StartDaemon(Mode, Func)
                time.sleep(Delay)
                if StatusSMScon() == False:
                    print 'ERROR: %s failed to start.' % DaemonFile
                    sys.exit(1)
                else:
                    logging.info( '"%s" TEST: %s active' % (Func.upper(), DaemonFile) )

        elif Mode == '-del': # delete log file
            if Func == 'log':
                Delete(LogPath, LogFile)
                
            elif Func == 'imsi': # delete imsi code file
                Delete(Path, CodeFile)

            elif Func == 'config': # delete config file
                Delete(Path, ConfigFile)

            elif Func == 'script': # delete script file
                Delete(Path, ScriptFile)

            else:
                print 'unknown option (%s).' % Func

        elif Mode == '-add': # add current IMSI code to smscon_code file
            if Func == 'imsi':
                SaveIMSIcode()
            else:
                print 'unknown option (%s).' % Func

        elif Mode == '-remove': # add current IMSI code to smscon_code file
            if Func == 'imsi':
                RemoveIMSIcode()
            else:
                print 'unknown option (%s).' % Func

        elif Mode == '-force': # force to initialize config & script file
            if Func == 'init':
                # stop smscon if running
                if StatusSMScon() == True:
                    StopSMScon()
                time.sleep(Delay)
                InitConfig(True)
                InitScript(True)

            else:
                print 'unknown option (%s).' % Func            

        else:
            print 'option error.'

    elif NumOfArg == 3: # 3 args given
        Mode        = sys.argv[1]
        UserSetting = sys.argv[2]
        UserVar     = sys.argv[3]
        
        if Mode == '-set': # set user variable in config file
            SaveUserSetting(UserSetting, UserVar)
        else:
            print 'unknown option (%s).' % Mode

    else: # 4 or more args given
        print 'option error.'

else: # no arg given
    ShowOptions()  
    sys.exit(1)

##############################################################
