#!/usr/bin/python3
# LAVA Box Agent - Copyright 2020 LAVA Controls - Stephen Loeckle

import argparse
import configparser
import inspect
import json
import logging
import netifaces
import os
import pickle
import platform
import requests
import shlex
import socketserver
import sqlite3
import struct
import subprocess
import sys
import tkinter
import traceback
from time import time, sleep
from datetime import datetime, timedelta
from lavaboxagentlib import api, boxinfo, browserrestart, checkdisplayconnection, cloudcmd, configbuilder, configextension, devicereboot, displaysize, emailscreenshot, getcurrenturl, gettoken, jobs, HotKeyWatcher, maintenance, netinfo, occam, sendemail, sendlog, stats, systemanalysis, updatedict, uptime, version
from multiprocessing import Process, freeze_support

osplatform = platform.system().lower()

if osplatform == 'linux':
    tmpdir = '/media/ramdisk'
if osplatform == 'windows':
    import tempfile
    import zc.lockfile
    from lavaboxagentlib import wineventlog
    tmpdir = tempfile.gettempdir()
    

class LogRecordStreamHandler(socketserver.StreamRequestHandler):
    def handle(self):
        while True:
            chunk = self.connection.recv(4)
            if len(chunk) < 4:
                break
            slen = struct.unpack('>L', chunk)[0]
            chunk = self.connection.recv(slen)
            while len(chunk) < slen:
                chunk = chunk + self.connection.recv(slen - len(chunk))
            obj = self.unPickle(chunk)
            record = logging.makeLogRecord(obj)
            self.handleLogRecord(record)

    def unPickle(self, data):
#        sortedresults = collections.OrderedDict(sorted(pickle.loads(data).items()))
#        for key,val in sortedresults.items():
#            print("{0} = {1}".format(key,val))
        return pickle.loads(data)

    def handleLogRecord(self, record):
        # if a name is specified, we use the named logger rather than the one
        # implied by the record.
        if self.server.logname is not None:
            name = self.server.logname
        else:
            name = record.name
        logger = logging.getLogger(name)
        # N.B. EVERY record gets logged. This is because Logger.handle
        # is normally called AFTER logger-level filtering. If you want
        # to do filtering, do it at the client end to save wasting
        # cycles and network bandwidth!
        logger.handle(record)

class LogRecordSocketReceiver(socketserver.ThreadingTCPServer):
    allow_reuse_address = True
    lavaboxagentloggingport = 9043
    def __init__(self, host='localhost',
                 port=lavaboxagentloggingport,
                 handler=LogRecordStreamHandler):
        socketserver.ThreadingTCPServer.__init__(self, (host, port), handler)
        self.abort = 0
        self.timeout = 1
        self.logname = None

    def serve_until_stopped(self):
        import select
        abort = 0
        while not abort:
            rd, wr, ex = select.select([self.socket.fileno()],
                                       [], [],
                                       self.timeout)
            if rd:
                self.handle_request()
            abort = self.abort
        
def logserver(sysinfo):
    gotthefunc = inspect.stack()[0][3]
    msg = ('Entered {} function'.format(gotthefunc))
    if osplatform == 'windows':
        wineventlog([gotthefunc,msg],10)
#    logging.basicConfig(format='%(asctime)s %(processName)-10s %(name)s %(levelname)-8s %(message)s',handlers=[logging.handlers.RotatingFileHandler('/var/log/lavaboxagent/lavaboxagent.log', mode='a', maxBytes=10*1024*1024, backupCount=0, encoding=None, delay=False)])
    logging.basicConfig(format='%(asctime)s %(processName)-10s %(name)s %(levelname)-8s %(message)s',handlers=[logging.handlers.RotatingFileHandler(sysinfo['SYSTEM']['LAVABOXAGENTLOGFILE'], mode='a', maxBytes=10000*1024, backupCount=30, encoding=None, delay=False)])
#    logging.basicConfig(format='%(asctime)s %(processName)-10s %(name)s %(levelname)-8s %(message)s',filename='/var/log/lavaboxagent/lavaboxagent.log')
    tcpserver = LogRecordSocketReceiver()
    tcpserver.serve_until_stopped()

def main(fromservice=0,pid=None,application_path=None):
    msg = 'LAVA Box Agent {} Startup'.format(version())
    print(msg)
    gotthefunc = inspect.stack()[0][3]
    msg = ('Entered {} function'.format(gotthefunc))
    if osplatform == 'windows':
        wineventlog([gotthefunc,msg],10)

# Setup system defaults
    sysinfo = {}
    sysinfo['SYSTEM'] = {}
    sysinfo['SYSTEM']['DAILYREBOOTTIME'] = None
    sysinfo['SYSTEM']['DAILYRESTARTTIME'] = None
    sysinfo['SYSTEM']['PID'] = pid
    sysinfo['SYSTEM']['TOKEN'] = None
    sysinfo['SYSTEM']['BROWSER'] = {}
    sysinfo['SYSTEM']['NETWORK'] = {}
    sysinfo['SYSTEM']['MAC'] = None
    sysinfo['PLATFORM'] = {}
    
    if osplatform == 'linux':
        sysinfo['SYSTEM']['DATABASEFILE'] = ('/var/lib/lavaboxagent/lavaboxagent.db')
        sysinfo['SYSTEM']['LAVABOXAGENTCONFIGFILE'] = ('/etc/lavaboxagent/lavaboxagent.conf')
        sysinfo['SYSTEM']['LAVABOXAGENTLOGFILE'] = ('/var/log/lavaboxagent/lavaboxagent.log')
        sysinfo['SYSTEM']['LAVABOXAGENTLOCKFILE'] = ('/var/lib/lavaboxagent/lavaboxagent.run')
        sysinfo['SYSTEM']['LAVABOXAGENTNETFILE'] = ('/var/lib/lavaboxagent/lavaboxagent.netinfo')
        sysinfo['SYSTEM']['LAVABOXAGENTSTATEFILE'] = ('{}\\db\\lavaboxagent.state'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTFFMPEG'] = ('/usr/bin/ffmpeg')
        sysinfo['SYSTEM']['LAVABOXAGENTCONVERT'] = ('convert')
        sysinfo['SYSTEM']['LAVABOXAGENTIDENTIFY'] = ('identify')
        sysinfo['SYSTEM']['LAVABOXAGENTSS'] = ('scrot')
        sysinfo['SYSTEM']['LAVABOXAGENTTESS'] =  ('tesseract')
    elif osplatform == 'windows':
        if not application_path:
            application_path = os.getcwd()
        sysinfo['SYSTEM']['DATABASEFILE'] = ('{}\\db\\lavaboxagent.db'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTCONFIGFILE'] = ('{}\\conf\\lavaboxagent.conf'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTLOGFILE'] = ('{}\\logs\\lavaboxagent.log'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTLOCKFILE'] = ('{}\\db\\lavaboxagent.run'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTNETFILE'] = ('{}\\db\\lavaboxagent.netinfo'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTSTATEFILE'] = ('{}\\db\\lavaboxagent.state'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTCONVERT'] = ('{}\\convert'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTFFMPEG'] = ('{}\\ffmpeg'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTIDENTIFY'] = ('{}\\identify'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTSS'] = ('{}\\scrot'.format(application_path))
        sysinfo['SYSTEM']['LAVABOXAGENTTESS'] =  ('{}\\tesseract'.format(application_path))
        sysinfo['SYSTEM']['TCLPATH'] =  ('{}\\Tcl\\tcl8.6'.format(application_path))
        sysinfo['SYSTEM']['TKPATH'] =  ('{}\\Tcl\\tk8.6'.format(application_path))
        os.environ['TCL_LIBRARY'] = sysinfo['SYSTEM']['TCLPATH']
        os.environ['TK_LIBRARY'] = sysinfo['SYSTEM']['TKPATH']
    
    mainworkers = []
    try:
        mainworker = Process(target=logserver, args=(sysinfo,))
        mainworkers.append(mainworker)
        mainworker.start()
    except:
        err = traceback.format_exc()
        msg = ('Error Detail: {0}'.format(err))
        print(gotthefunc, msg, 10)
        if osplatform == 'windows':
            wineventlog([gotthefunc,msg],10)
        sys.exit()
    else:
        msg = ('Started log server')
        print(gotthefunc, msg, 10)
        if osplatform == 'windows':
            wineventlog([gotthefunc,msg],10)
    
    logger = logging.getLogger('main')
    sock = logging.handlers.SocketHandler('localhost', 9043)
    logger.addHandler(sock)
    logger.setLevel(logging.DEBUG)
    
    sleep(2)
    
    msg = 'LAVA Box Agent {} Startup'.format(version())
    sendlog(gotthefunc, msg, 20)
    if osplatform == 'windows':
        wineventlog([gotthefunc,msg],10)

    config = configparser.ConfigParser()
    try:
        config.read([sysinfo['SYSTEM']['LAVABOXAGENTCONFIGFILE']])
    except configparser.Error as e:
        msg = ('Unable to read configuration file {}! Halting!'.format(sysinfo['SYSTEM']['LAVABOXAGENTCONFIGFILE']))
        sendlog(gotthefunc, msg, 40)
        sys.exit()
    except:
        msg = ('Unknown Error in {0} Reading Config! Halting!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 40)
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sendlog(gotthefunc, msg, 10)
        sys.exit()

    try:
        sysinfo['SYSTEM']['DAILYREBOOTTIME'] = config.get('system', 'dailyreboottime')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        pass
    except configparser.Error as e:
        pass
    except:
        pass
        err = traceback.format_exc()
        msg = ('Error Detail: {0}'.format(err))
        sendlog(gotthefunc, msg, 10)
        
    try:
        sysinfo['SYSTEM']['DAILYRESTARTTIME'] = config.get('system', 'dailyrestarttime')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        pass
    except configparser.Error as e:
        pass
    except:
        pass
        err = traceback.format_exc()
        msg = ('Error Detail: {0}'.format(err))
        sendlog(gotthefunc, msg, 10)
        
    try:
        sysinfo['SYSTEM']['PLATFORM'] = config.get('system', 'platform')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        msg = ('No platform type in configuration file! Halting!')
        sendlog(gotthefunc, msg, 40)
        sys.exit()
    except configparser.Error as e:
        msg = ('Config read entry system platform type error! Defaulting to lava!')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['PLATFORM'] = 'lava'
    except:
        msg = ('Error in {0} Reading Config! Defaulting to lava!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 40)
        err = traceback.format_exc()
        msg = ('Error Detail: {0}'.format(err))
        sendlog(gotthefunc, msg, 10)
        sysinfo['SYSTEM']['PLATFORM'] = 'lava'
    else:
        if sysinfo['SYSTEM']['PLATFORM'] == 'lava':
            sysinfo['PLATFORM']['API'] = 'https://endpoint.lavacontrols.com'
            sysinfo['PLATFORM']['APP'] = 'https://app.lavacontrols.com'
            sysinfo['PLATFORM']['STREAM'] = 'rtmp://172.30.132.28'
        elif sysinfo['SYSTEM']['PLATFORM'] == 'lava-dev':
            sysinfo['PLATFORM']['API'] = 'https://api-dev.lavacontrols.com'
            sysinfo['PLATFORM']['APP'] = 'https://app-dev.lavacontrols.com'
            sysinfo['PLATFORM']['STREAM'] = 'rtmp://172.30.132.28'
        elif sysinfo['SYSTEM']['PLATFORM'] == 'onprem' or sysinfo['SYSTEM']['PLATFORM'] == 'on-prem':
            try:
                sysinfo['PLATFORM']['API'] = config.get('platform', 'api')
            except:
                msg = ('Error in {0} Reading Config! Cannot read onprem api server entry. Halting.'.format(gotthefunc))
                sendlog(gotthefunc, msg, 40)
                err = traceback.format_exc()
                msg = ('Error Detail: {0}'.format(err))
                sendlog(gotthefunc, msg, 10)
                sys.exit()
            try:
                sysinfo['PLATFORM']['APP'] = config.get('platform', 'app')
            except:
                msg = ('Error in {0} Reading Config! Cannot read onprem api server entry. Halting.'.format(gotthefunc))
                sendlog(gotthefunc, msg, 40)
                err = traceback.format_exc()
                msg = ('Error Detail: {0}'.format(err))
                sendlog(gotthefunc, msg, 10)
                sys.exit()
            try:
                sysinfo['PLATFORM']['STREAM'] = config.get('platform', 'stream')
            except:
                msg = ('Error in {0} Reading Config! Cannot read onprem api server entry. Halting.'.format(gotthefunc))
                sendlog(gotthefunc, msg, 40)
                err = traceback.format_exc()
                msg = ('Error Detail: {0}'.format(err))
                sendlog(gotthefunc, msg, 10)
                sys.exit()
        else:
            sysinfo['SYSTEM']['PLATFORM'] = 'lava'
            sysinfo['PLATFORM']['API'] = 'https://endpoint.lavacontrols.com'
            sysinfo['PLATFORM']['APP'] = 'https://app.lavacontrols.com'
            sysinfo['PLATFORM']['STREAM'] = 'rtmp://172.30.132.28'
        msg = ('CONFIG: Loaded platform type {} with API {}'.format(sysinfo['SYSTEM']['PLATFORM'], sysinfo['PLATFORM']['API']))
        sendlog(gotthefunc, msg, 10)
        
    try:
        sysinfo['SYSTEM']['CGROUPS'] = config.get('system', 'cgroups')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        msg = ('No cgroups in configuration file! Defaulting to false!')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['CGROUPS'] = False
    except configparser.Error as e:
        msg = ('Config read entry system cgroups error! Defaulting to false!')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['CGROUPS'] = False
    except:
        msg = ('Error in {0} Reading Config! Defaulting to false!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 40)
        err = traceback.format_exc()
        msg = ('Error Detail: {0}'.format(err))
        sendlog(gotthefunc, msg, 10)
        sysinfo['SYSTEM']['CGROUPS'] = False
    else:
        msg = ('CONFIG: Loaded cgroups')
        sendlog(gotthefunc, msg, 10)
    try:
        sysinfo['SYSTEM']['SINGLECOLORDETECTION'] = config.get('system', 'singlecolordetection')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        msg = ('No singlecolordetection in configuration file! Defaulting to true!')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['SINGLECOLORDETECTION'] = True
    except configparser.Error as e:
        msg = ('Config read entry system platform type error! Defaulting to lava!')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['SINGLECOLORDETECTION'] = True
    except:
        msg = ('Error in {0} Reading Config! Defaulting to lava!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 40)
        err = traceback.format_exc()
        msg = ('Error Detail: {0}'.format(err))
        sendlog(gotthefunc, msg, 10)
        sysinfo['SYSTEM']['SINGLECOLORDETECTION'] = True
    else:
        if sysinfo['SYSTEM']['SINGLECOLORDETECTION'] == 0 or sysinfo['SYSTEM']['SINGLECOLORDETECTION'] == '0' or sysinfo['SYSTEM']['SINGLECOLORDETECTION'] == 'false' or sysinfo['SYSTEM']['SINGLECOLORDETECTION'] == 'False' or sysinfo['SYSTEM']['SINGLECOLORDETECTION'] == 'off' or sysinfo['SYSTEM']['SINGLECOLORDETECTION'] == 'Off':
            sysinfo['SYSTEM']['SINGLECOLORDETECTION'] = False
        msg = ('CONFIG: Loaded singlecolordetection')
        sendlog(gotthefunc, msg, 10)
    try:
        sysinfo['SYSTEM']['EMAIL'] = [e.strip() for e in config.get('system', 'emailnotification').split(',')]
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        msg = ('No email(s) for notifications specified in configuration file. Continuing with no notifications.')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['EMAIL'] = None
        pass
    except configparser.Error as e:
        msg = ('Config read entry system email notification error! Clearing entry.')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['EMAIL'] = None
        pass
    except:
        msg = ('Unknown Error in {0} Reading Config! Halting!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 40)
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sendlog(gotthefunc, msg, 10)
        sys.exit()
    try:
        sysinfo['SYSTEM']['SMTPHOST'] = config.get('system', 'smtphost')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        msg = ('No smtp hosts for notifications specified in configuration file. Default to localhost.')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['SMTPHOST'] = 'localhost'
        pass
    except configparser.Error as e:
        msg = ('Config read entry system email notification error! Clearing entry.')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['SMTPHOST'] = 'localhost'
        pass
    except:
        msg = ('Unknown Error in {0} Reading Config! Halting!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 40)
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sendlog(gotthefunc, msg, 10)
        sys.exit()
    try:
        sysinfo['SYSTEM']['LATENCYHOST'] = config.get('system', 'latencyhost')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        msg = ('No latency host specified in configuration file. Default to 172.25.16.1, LAVA connectivity gateway.')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['LATENCYHOST'] = '172.25.16.1'
        pass
    except configparser.Error as e:
        msg = ('Config read entry system email notification error! Clearing entry.')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['LATENCYHOST'] = '172.25.16.1'
        pass
    except:
        msg = ('Unknown Error in {0} Reading Config! Halting!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 40)
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sendlog(gotthefunc, msg, 10)
        sys.exit()
    try:
        sysinfo['SYSTEM']['BOXTYPE'] = config.get('system', 'boxtype')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
    except configparser.Error as e:
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
    except:
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sys.exit()
    try:
        sysinfo['SYSTEM']['INTERVAL'] = int(config.get('system', 'interval'))
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sysinfo['SYSTEM']['INTERVAL'] = 1
    except configparser.Error as e:
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sysinfo['SYSTEM']['INTERVAL'] = 1
    except:
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sysinfo['SYSTEM']['INTERVAL'] = 1
    try:
        sysinfo['SYSTEM']['STARTUPSECS'] = int(config.get('system', 'startupsecs'))
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        sysinfo['SYSTEM']['STARTUPSECS'] = 60
    except configparser.Error as e:
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sysinfo['SYSTEM']['STARTUPSECS'] = 60
    except:
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sysinfo['SYSTEM']['STARTUPSECS'] = 60
    try:
        sysinfo['SYSTEM']['SYSTEMANALYSISSECS'] = int(config.get('system', 'systemanalysissecs'))
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        sysinfo['SYSTEM']['SYSTEMANALYSISSECS'] = 30
    except configparser.Error as e:
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sysinfo['SYSTEM']['SYSTEMANALYSISSECS'] = 30
    except:
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sysinfo['SYSTEM']['SYSTEMANALYSISSECS'] = 30
    try:
        sysinfo['SYSTEM']['SYSTEMANALYSISPROBLEMSECS'] = int(config.get('system', 'systemanalysisproblemsecs'))
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        sysinfo['SYSTEM']['SYSTEMANALYSISPROBLEMSECS'] = 15
    except configparser.Error as e:
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sysinfo['SYSTEM']['SYSTEMANALYSISPROBLEMSECS'] = 15
    except:
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sysinfo['SYSTEM']['SYSTEMANALYSISPROBLEMSECS'] = 15
    if osplatform == 'linux':
        try:
            sysinfo['SYSTEM']['USER'] = config.get('system', 'user')
        except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
            msg = ('No run-as user defined in configuration file! Defaulting to kiosk!')
            sendlog(gotthefunc, msg, 40)
            sysinfo['SYSTEM']['USER'] = 'kiosk'
        except configparser.Error as e:
            msg = ('Config read entry system user error! Halting!')
            sendlog(gotthefunc, msg, 40)
            sys.exit()
        except:
            msg = ('Unknown Error in {0} Reading Config! Halting!'.format(gotthefunc))
            sendlog(gotthefunc, msg, 40)
            err = traceback.format_exc()
            msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
            print(msg)
            sendlog(gotthefunc, msg, 10)
            sys.exit()
    try:
        sysinfo['SYSTEM']['LOGLEVEL'] = config.get('system', 'loglevel')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        msg = ('No logging type specified in configuration file. Defaulting to INFO!')
        sendlog(gotthefunc, msg, 40)
        sysinfo['SYSTEM']['LOGLEVEL'] = '10'
        pass
    except configparser.Error as e:
        msg = ('Config read entry system loglevel error! Halting!')
        sendlog(gotthefunc, msg, 40)
        sys.exit()
    except:
        msg = ('Unknown Error in {0} Reading Config! Halting!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 40)
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sendlog(gotthefunc, msg, 10)
        sys.exit()
    try:
        sysinfo['SYSTEM']['HTTPTIMEOUT'] = int(config.get('system', 'httptimeout'))
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        msg = ('No HTTPTIMEOUT specified in config. Defaulting to 60 seconds.')
        sendlog(gotthefunc, msg, 10)
        sysinfo['SYSTEM']['HTTPTIMEOUT'] = 60
        pass
    except configparser.Error as e:
        msg = ('No HTTPTIMEOUT specified in config. Defaulting to 60 seconds.')
        sendlog(gotthefunc, msg, 10)
        sysinfo['SYSTEM']['HTTPTIMEOUT'] = 60
        pass
    except:
        msg = ('Error in {0} Reading Config! Halting!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 10)
        err = traceback.format_exc()
        msg = ('Error Detail: {0}'.format(err))
        sendlog(gotthefunc, msg, 10)
        sysinfo['SYSTEM']['HTTPTIMEOUT'] = 60
        msg = ('No HTTPTIMEOUT specified in config. Defaulting to 60 seconds.')
        sendlog(gotthefunc, msg, 10)
        pass
    else:
        msg = ('CONFIG: Got http timeout of {}'.format(sysinfo['SYSTEM']['HTTPTIMEOUT']))
        sendlog(gotthefunc, msg, 10)
    if sysinfo['SYSTEM']['BOXTYPE'] == 'display':
        try:
            sysinfo['SYSTEM']['BROWSER']['NAME'] = config.get('browser', 'name')
        except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
            msg = ('No browser name specified. Defaulting to {}.'.format(sysinfo['SYSTEM']['BROWSER']['NAME']))
            sendlog(gotthefunc, msg, 40)
            pass
        except configparser.Error as e:
            msg = ('Config read entry browser name! Defaulting to {}.'.format(sysinfo['SYSTEM']['BROWSER']['NAME']))
            sendlog(gotthefunc, msg, 40)
            pass
        except:
            msg = ('Unknown Error in {0} Reading Config! Halting!'.format(gotthefunc))
            sendlog(gotthefunc, msg, 40)
            err = traceback.format_exc()
            msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
            print(msg)
            sendlog(gotthefunc, msg, 10)
            sys.exit()
        try:
            sysinfo['SYSTEM']['BROWSER']['PATH'] = config.get('browser', 'path')
        except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
            msg = ('No browser path specified. Defaulting to {}.'.format(sysinfo['SYSTEM']['BROWSER']['PATH']))
            sendlog(gotthefunc, msg, 40)
            pass
        except configparser.Error as e:
            msg = ('Config read entry browser path! Defaulting to {}.'.format(sysinfo['SYSTEM']['BROWSER']['PATH']))
            sendlog(gotthefunc, msg, 40)
            pass
        except:
            msg = ('Unknown Error in {0} Reading Config! Halting!'.format(gotthefunc))
            sendlog(gotthefunc, msg, 40)
            err = traceback.format_exc()
            msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
            print(msg)
            sendlog(gotthefunc, msg, 10)
            sys.exit()
        try:
            sysinfo['SYSTEM']['BROWSER']['OPTIONS'] = config.get('browser', 'options')
        except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
            msg = ('No browser options specified. Defaulting to {}.'.format(sysinfo['SYSTEM']['BROWSER']['OPTIONS']))
            sendlog(gotthefunc, msg, 40)
            pass
        except configparser.Error as e:
            msg = ('Config read entry browser options! Defaulting to {}.'.format(sysinfo['SYSTEM']['BROWSER']['OPTIONS']))
            sendlog(gotthefunc, msg, 40)
            pass
        except:
            msg = ('Unknown Error in {0} Reading Config! Halting!'.format(gotthefunc))
            sendlog(gotthefunc, msg, 40)
            err = traceback.format_exc()
            msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
            print(msg)
            sendlog(gotthefunc, msg, 10)
            sys.exit()
    try:
        sysinfo['SYSTEM']['NETWORK']['HTTPPROXY'] = config.get('network', 'httpproxy')
    except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
        msg = ('No network http proxy specified. Defaulting to {}.'.format(sysinfo['SYSTEM']['NETWORK']['HTTPPROXY']))
        sendlog(gotthefunc, msg, 40)
        pass
    except configparser.Error as e:
        msg = ('Config read entry network options! Defaulting to {}.'.format(sysinfo['SYSTEM']['NETWORK']['HTTPPROXY']))
        sendlog(gotthefunc, msg, 40)
        pass
    except:
        msg = ('Unknown Error in {0} Reading Config! Halting!'.format(gotthefunc))
        sendlog(gotthefunc, msg, 40)
        err = traceback.format_exc()
        msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
        print(msg)
        sendlog(gotthefunc, msg, 10)
        sys.exit()

    os.environ["DISPLAY"] = ":0"
    


    if sysinfo['SYSTEM']['NETWORK']['HTTPPROXY']:
        os.environ["http_proxy"] = sysinfo['SYSTEM']['NETWORK']['HTTPPROXY']
        os.environ["https_proxy"] = sysinfo['SYSTEM']['NETWORK']['HTTPPROXY']
        
# Parse CLI options
        
    parser = argparse.ArgumentParser(description='LAVA Box Agent System')
    parser.add_argument('-e', '--engines', help = 'Run lavaboxagent client engines', action="store_true")
    parser.add_argument('-r', '--reconfigure', help = 'Reconfigure lavaboxagent', action='store_true')
    parser.add_argument('-s', '--stats', help = 'Show lavaboxagent stats', action='store_true')
    parser.add_argument('-se', '--statsemail', metavar = 'EMAILADDRESS', help = 'Send stats to email address. Email address required. Multiple email addresses can be added, space delimited', nargs='+')
    parser.add_argument('-m', '--maint', help = 'Put system in maintenance mode. Restarts Chrome out of kiosk mode.', action='store_true')
    parser.add_argument('-mon', '--mainton', help = 'Put system in permenant maintenance mode until removed. Restarts Chrome out of kiosk mode.', action='store_true')
    parser.add_argument('-moff', '--maintoff', help = 'Take system out of permenant maintenance mode.', action='store_true')
    parser.add_argument('-es', '--emailscreenshot', metavar = 'EMAILADDRESS', help = 'Send screenshot to email address. Email address required. Multiple email addresses can be added, space delimited.', nargs='+')
    parser.add_argument('-sd', '--shutdown', help = 'Shutdown the system', action='store_true')
    parser.add_argument('-u', '--url', help = 'Get current URL from Chrome', action='store_true')
    
    
    args = parser.parse_args()
    if (not args.engines and not args.reconfigure and not args.stats and not args.maint and not args.emailscreenshot and not args.mainton and not args.maintoff and not args.statsemail and not args.shutdown and not args.url) and fromservice == 0:
        parser.print_help()
    if args.engines or fromservice == 1:
        sleep(10)
        if os.path.exists(sysinfo['SYSTEM']['DATABASEFILE']):
            conn = sqlite3.connect(sysinfo['SYSTEM']['DATABASEFILE'])
            c = conn.cursor()
        else:
            msg = ('Database not found! Halting!')
            sendlog(gotthefunc, msg, 50)
            sys.exit()
        c.execute('UPDATE system SET value = ? WHERE tags = ?', (0, 'shutdown'))
        c.execute('UPDATE system SET value = ? WHERE tags = ?', (0, 'apishutdowncomplete'))
        c.execute('UPDATE system SET value = ? WHERE tags = ?', (0, 'cloudcmdshutdowncomplete'))
        c.execute('UPDATE system SET value = ? WHERE tags = ?', (0, 'systemanalysisshutdowncomplete'))
        c.execute('SELECT value from system WHERE tags = ?', ('maintenance',))
        row = c.fetchone()
        if row[0] == 1:
            c.execute('UPDATE system SET value = ? WHERE tags = ?', (0, 'maintenance'))
        if row[0] == 2:
            subject = 'Permenant Maintenance Mode Notification'
            message = 'Reminder: this box is in permenant maintenance mode.'
            try:
                sendemail(sysinfo,subject,msg)
            except:
                pass
                msg = ('Error in {}!'.format(gotthefunc))
                sendlog(gotthefunc, msg, 40)
                err = traceback.format_exc()
                msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
                sendlog(gotthefunc, msg, 10)
        c.execute('UPDATE system SET value = ? WHERE tags = ?', (0, 'urlerrors'))
        c.execute('UPDATE system SET value = ? WHERE tags = ?', (0, 'checkfundamentalsruns'))
        c.execute('UPDATE system SET value = ? WHERE tags = ?', (0, 'screenanalysisruns'))
        c.execute('UPDATE system SET value = ? WHERE tags = ?', (0, 'activeproblemcount'))
        c.execute('UPDATE system SET strvalue = ? WHERE tags = ?', ('', 'activeproblem'))
        c.execute('UPDATE system SET strvalue = ? WHERE tags = ?', ('' ,'remediation'))
        datenow = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        c.execute('UPDATE system SET strvalue = ? WHERE tags = ?', (datenow, 'startuptime'))
        conn.commit()

        if osplatform == 'linux':
            if sysinfo['SYSTEM']['CGROUPS'] == True:
                mem = boxinfo('m')
                cghardmem = int(mem.total*.9)
                cgsoftmem = int(mem.total*.8)
                cgcmd = ('{} {} {}'.format('sudo','/usr/bin/lavaboxagent/lavaboxagent-cg',cghardmem,cgsoftmem))
                try:
                    subprocess.call(shlex.split(cgcmd))
                except:
                    pass
                    msg = ("Unexpected error:", sys.exc_info()[0])
                    sendlog(gotthefunc, msg, 40)
                    err = traceback.format_exc()
                    msg = ('Unknown Error in {0} Detail: {1}'.format(gotthefunc,err))
                    sendlog(gotthefunc, msg, 10)
        
        if sysinfo['SYSTEM']['BOXTYPE'] == 'display':
            browserpid = browserrestart(sysinfo)
            c.execute('UPDATE system SET value = ? WHERE tags = ?', (browserpid,'browserpid'))
            conn.commit()
        elif sysinfo['SYSTEM']['BOXTYPE'] == 'occam':
            occampid = occam(sysinfo)
        else:
            pass
        while True:
            try:
                sysinfo['SYSTEM']['MAC'], sysinfo['SYSTEM']['MYIP'], sysinfo['SYSTEM']['MYIFACE'] = netinfo(sysinfo)
            except:
                msg = ('Error in {0} calling netinfo! Halting!'.format(gotthefunc))
                sendlog(gotthefunc, msg, 40)
                err = traceback.format_exc()
                msg = ('Error Detail: {0}'.format(err))
                sendlog(gotthefunc, msg, 10)
            else:
                if sysinfo['SYSTEM']['MAC'] != 'ERROR' and sysinfo['SYSTEM']['MYIP'] != 'ERROR':
                    msg = ('CONFIG: Using MAC {}, IP {}, IFACE {} for operations.'.format(sysinfo['SYSTEM']['MAC'], sysinfo['SYSTEM']['MYIP'], sysinfo['SYSTEM']['MYIFACE']))
                    sendlog(gotthefunc, msg, 10)
                    break
                elif sysinfo['SYSTEM']['MAC'] == 'ERROR' or sysinfo['SYSTEM']['MYIP'] == 'ERROR':
                    pass
                else:
                    msg = ('ERROR: Received MAC "{}", IP "{}", IFACE "{}" from netinfo. Retrying.'.format(sysinfo['SYSTEM']['MAC'], sysinfo['SYSTEM']['MYIP'], sysinfo['SYSTEM']['MYIFACE']))
                    sendlog(gotthefunc, msg, 10)
            sleep(1)
        try:
            sysinfo['SYSTEM']['TOKEN'] = config.get('system', 'token')
        except (configparser.NoOptionError, configparser.InterpolationMissingOptionError):
            err = traceback.format_exc()
            msg = ('Error in {0} Detail: {1}'.format(gotthefunc,err))
            sendlog(gotthefunc, msg, 10)
        except configparser.Error as e:
            err = traceback.format_exc()
            msg = ('Error in {0} Detail: {1}'.format(gotthefunc,err))
            sendlog(gotthefunc, msg, 10)
        except:
            err = traceback.format_exc()
            msg = ('Error in {0} Detail: {1}'.format(gotthefunc,err))
            sendlog(gotthefunc, msg, 10)
            sys.exit()
        notified = 0
        if not sysinfo['SYSTEM']['TOKEN']:
            while True:
#                try:
#                    popup(sysinfo,'LAVA Box Self-Provisioning','Please stand by.',3000)
#                except:
#                    err = traceback.format_exc()
#                    msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
#                    sendlog(gotthefunc, msg, 10)
#                    pass
                try:
                    sysinfo['SYSTEM']['TOKEN'] = gettoken(sysinfo)
                except:
                    err = traceback.format_exc()
                    msg = ('Error in {0} Detail: {1}'.format(gotthefunc,err))
                    sendlog(gotthefunc, msg, 10)
                    if notified == 0:
                        subject = 'LAVA Box Failed Self-Provisioning'
                        message = 'LAVA Box Failed Self-Provisioning using mac address: {} \n {}'.format(sysinfo['SYSTEM']['MAC'],msg)
                #        print(message)
                        try:
                            sendemail(sysinfo,subject,message)
                        except:
                            pass
                            msg = ('Error in {}!'.format(gotthefunc))
                            sendlog(gotthefunc, msg, 40)
                            err = traceback.format_exc()
                            msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
                            sendlog(gotthefunc, msg, 10)
                        notified = 1
#                    try:
#                        popup(sysinfo,'LAVA Box Failed Self-Provisioning','Please contact support@lavacontrols.com!',30000)
#                    except:
#                        err = traceback.format_exc()
#                        msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
#                        print(msg)
#                        pass
                    sleep(30)
                else:
                    try:
                        configbuilder(sysinfo, token=sysinfo['SYSTEM']['TOKEN'])
                    except:
                        err = traceback.format_exc()
                        msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
                        print(msg)
                        break
                    else:
                        subject = 'LAVA Box Self-Provisioning Succeeded'
                        message = 'LAVA Box Self-Provisioning Succeeded in Agent Configuration\n'
                        try:
                            sendemail(sysinfo,subject,msg)
                        except:
                            pass
                            msg = ('Error in {}!'.format(gotthefunc))
                            sendlog(gotthefunc, msg, 40)
                            err = traceback.format_exc()
                            msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
                            sendlog(gotthefunc, msg, 10)
#                            try:
#                                popup(sysinfo,'LAVA Box Self-Provisioning Succeeded','LAVA Box Self-Provisioning Succeeded',3000)
#                            except:
#                                err = traceback.format_exc()
#                                msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
#                                print(msg)
#                                pass
                            break
                    try:
                        configextension(sysinfo, token=sysinfo['SYSTEM']['TOKEN'])
                    except:
                        err = traceback.format_exc()
                        msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
                        print(msg)
                        break
                    else:
                        subject = 'LAVA Box Self-Provisioning Succeeded'
                        message = 'LAVA Box Self-Provisioning Succeeded in Extension Configuration\n'
                        try:
                            sendemail(sysinfo,subject,msg)
                        except:
                            pass
                            msg = ('Error in {}!'.format(gotthefunc))
                            sendlog(gotthefunc, msg, 40)
                            err = traceback.format_exc()
                            msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
                            sendlog(gotthefunc, msg, 10)
#                            try:
#                                popup(sysinfo,'LAVA Box Self-Provisioning Succeeded','LAVA Box Self-Provisioning Succeeded',3000)
#                            except:
#                                err = traceback.format_exc()
#                                msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
#                                print(msg)
#                                pass
                            break
                        sleep(1)
                        break
#        ut, us = uptime()
#        startupthreshold = 300
#        startupwaittime = 15
#        if ut < startupthreshold:
#            msg = ('Uptime is less than {}. Pausing startup for {} seconds.'.format(startupthreshold, startupwaittime))
#            sleep(startupwaittime)
#        gateways = netifaces.gateways()
#        try:
#            sysinfo['SYSTEM']['DEFAULTGATEWAY'] = gateways['default'][netifaces.AF_INET][0]
#        except:
#            pass

        mainworker = Process(target=api, args=(sysinfo,))
        mainworkers.append(mainworker)
        mainworker.start()
        sleep(1)
    
        displayconnected = 0

        while displayconnected == 0:
            try:
                displayroot = tkinter.Tk()
            except:
                pass
                err = traceback.format_exc()
                msg = ('Unknown Error: {}'.format(err))
                sendlog(gotthefunc, msg, 10)
                if osplatform == 'linux':
                    try:
                        isConnected = checkdisplayconnection()
                    except:
                        err = traceback.format_exc()
                        msg = ('Unknown Error: {}'.format(err))
                        sendlog(gotthefunc, msg, 40)
                        pass
                        sleep(5)
                    else:
                        sendlog(gotthefunc, isConnected, 40)
                        if isConnected.startswith('connected'):
                            Xauth = '/home/{}/.Xauthority'.format(sysinfo['SYSTEM']['USER'])
                            msg = ('In engines, got tkinter.TclError but checkdisplayconnection() reports {}. Deleting {} and rebooting now.'.format(isConnected,Xauth))
                            sendlog(gotthefunc, msg, 40)
                            try:
                                os.remove(Xauth)
                            except:
                                err = traceback.format_exc()
                                msg = ('Unknown Error: {}'.format(err))
                                sendlog(gotthefunc, msg, 40)
                                pass
                            else:
                                subject = 'Display Weirdness. Rebooting'
                                try:
                                    sendemail(sysinfo,subject,msg)
                                except:
                                    pass
                                    msg = ('Error in {}!'.format(gotthefunc))
                                    sendlog(gotthefunc, msg, 40)
                                    err = traceback.format_exc()
                                    msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
                                    sendlog(gotthefunc, msg, 10)
                                devicereboot()
                        else:
                            msg = ('In engines, got tkinter.TclError but checkdisplayconnection() reports {}. Sleeping for 30 seconds.'.format(isConnected,Xauth))
                            sendlog(gotthefunc, msg, 10)
                            sleep(30)            
            else:
                dh,dv = displaysize(displayroot)
                msg = ('Display Connected. Resolution: {} x {}'.format(dh,dv))
                sendlog(gotthefunc, msg, 10)
                displayconnected = 1
                displayroot.destroy()
                sysinfo['SYSTEM']['RESOLUTION'] = '{}x{}'.format(dh,dv)
                
                if osplatform == 'linux':                        
                    xsetcmd = ('{} {} {} {} {}'.format('xset', 'dpms', '0', '0', '0'))
                    subprocess.call(shlex.split(xsetcmd))
                    xsetcmd = ('{} {} {} {} {} {} {} {}'.format('xset', '-dpms', 's', 'off', 's', 'noblank', 's', 'noexpose'))
                    subprocess.call(shlex.split(xsetcmd))
                    xsetcmd = ('{} {} {} {}'.format('xset', 's', '0', '0'))
                    subprocess.call(shlex.split(xsetcmd))    
    
                systemanalysisworker = Process(target=systemanalysis, args=(sysinfo,))
                systemanalysisworker.start()
                sleep(3)
                mainworker = Process(target=jobs, args=(sysinfo,))
                mainworkers.append(mainworker)
                mainworker.start()
                mainworker = Process(target=cloudcmd, args=(sysinfo,))
                mainworkers.append(mainworker)
                mainworker.start()
                if osplatform == 'linux':
                    mainworker = Process(target=HotKeyWatcher, args=(sysinfo,))
                    mainworkers.append(mainworker)
                    mainworker.start()
        for w in mainworkers:
            w.join()
    elif args.reconfigure:
        configbuilder(sysinfo)
    elif args.stats:
        stats(sysinfo,1)
    elif args.statsemail:
        subject = 'Stats Email'
        message = stats(sysinfo,2)
###### We aren't simply passing the config file email address to allow for a different recipient to receive stats. So, we're creating the variables required to run sendemail from CLI arguments and existing SMTP host data.
        statsemailinfo = {}
        statsemailinfo['SYSTEM'] = {}
        statsemailinfo['SYSTEM']['EMAIL'] = args.statsemail
        statsemailinfo['SYSTEM']['SMTPHOST'] = sysinfo['SYSTEM']['SMTPHOST']
        try:
            sendemail(sysinfo,subject,msg)
        except:
            pass
            msg = ('Error in {}!'.format(gotthefunc))
            sendlog(gotthefunc, msg, 40)
            err = traceback.format_exc()
            msg = ('Error in {} Detail: {}'.format(gotthefunc,err))
            sendlog(gotthefunc, msg, 10)
    elif args.maint:
        maintenance(sysinfo)
    elif args.mainton:
        maintenance(sysinfo,0,2)
    elif args.maintoff:
        maintenance(sysinfo,0,0)
    elif args.emailscreenshot:
        emailscreenshot(sysinfo, args.emailscreenshot)
    elif args.url:
        currenturl = getcurrenturl(sysinfo['SYSTEM']['USER'])
        print(currenturl)
    elif args.shutdown:
        if os.path.exists(sysinfo['SYSTEM']['DATABASEFILE']):
            conn = sqlite3.connect(sysinfo['SYSTEM']['DATABASEFILE'])
            c = conn.cursor()
        else:
            msg = ('Database not found! Halting!')
            sendlog(gotthefunc, msg, 50)
            sys.exit()
        dbsuccess = 0
        while dbsuccess == 0:
            try:
                c.execute('UPDATE system SET strvalue = ?, notes = ? WHERE tags = ?', ('shutdown','Shutdown request from API','remediation'))
                conn.commit()
            except sqlite3.OperationalError:
                msg = ('API: Database locked. Trying again.')
                sendlog(gotthefunc, msg, 10)
                pass
                sleep(1)
            else:
                dbsuccess = 1
                conn.close()
    else:
        parser.print_help()

if __name__ == '__main__':
    freeze_support()
    gotthefunc = inspect.stack()[0][3]
    msg = ('Entered {} function'.format(gotthefunc))
    application_path = None
    fromservice = 0
    if osplatform == 'windows':
        wineventlog([gotthefunc,msg],10)
        application_path = os.getcwd()
        if 'system32' in application_path.lower():
            fromservice = 1
            apppath = sys.argv[0].rsplit('\\', 1)
            application_path = apppath[0].replace('\\\\','\\')
        msg = application_path
        wineventlog([gotthefunc,msg],10)
        lockfile = ('{}\\db\\lavaboxagent.run'.format(application_path))
        try:
            lock = zc.lockfile.LockFile(lockfile, content_template='{pid};{hostname}')
        except:
            msg = 'Lockfile exists. Halting.'
            wineventlog([gotthefunc,msg],10)
            sys.exit()
        else:
            msg = 'Lockfile set. Continuing.'
            wineventlog([gotthefunc,msg],10)
        msg = 'Started lavacontrols.exe'
        wineventlog([gotthefunc,msg],10)
    if application_path:
        main(fromservice,os.getpid(),application_path)
    else:
        main(fromservice,os.getpid())