Ejemplo n.º 1
0
    def testDefaultTimeout(self):
        # Testing default timeout
        # The default timeout should initially be None
        self.assertEqual(socket.getdefaulttimeout(), None)
        s = socket.socket()
        self.assertEqual(s.gettimeout(), None)
        s.close()

        # Set the default timeout to 10, and see if it propagates
        socket.setdefaulttimeout(10)
        self.assertEqual(socket.getdefaulttimeout(), 10)
        s = socket.socket()
        self.assertEqual(s.gettimeout(), 10)
        s.close()

        # Reset the default timeout to None, and see if it propagates
        socket.setdefaulttimeout(None)
        self.assertEqual(socket.getdefaulttimeout(), None)
        s = socket.socket()
        self.assertEqual(s.gettimeout(), None)
        s.close()

        # Check that setting it to an invalid value raises ValueError
        self.assertRaises(ValueError, socket.setdefaulttimeout, -1)

        # Check that setting it to an invalid type raises TypeError
        self.assertRaises(TypeError, socket.setdefaulttimeout, "spam")
Ejemplo n.º 2
0
    def testDefaultTimeout(self):
        # Testing default timeout
        # The default timeout should initially be None
        self.assertEqual(socket.getdefaulttimeout(), None)
        s = socket.socket()
        self.assertEqual(s.gettimeout(), None)
        s.close()

        # Set the default timeout to 10, and see if it propagates
        socket.setdefaulttimeout(10)
        self.assertEqual(socket.getdefaulttimeout(), 10)
        s = socket.socket()
        self.assertEqual(s.gettimeout(), 10)
        s.close()

        # Reset the default timeout to None, and see if it propagates
        socket.setdefaulttimeout(None)
        self.assertEqual(socket.getdefaulttimeout(), None)
        s = socket.socket()
        self.assertEqual(s.gettimeout(), None)
        s.close()

        # Check that setting it to an invalid value raises ValueError
        self.assertRaises(ValueError, socket.setdefaulttimeout, -1)

        # Check that setting it to an invalid type raises TypeError
        self.assertRaises(TypeError, socket.setdefaulttimeout, "spam")
Ejemplo n.º 3
0
 def _rebootbyssh(self):
     '''Start reboot of Grandstream phone by ssh'''
     oldtimeout = socket.getdefaulttimeout()
     try:
         ssh = paramiko.SSHClient()
         ssh.set_missing_host_key_policy(paramiko.WarningPolicy())
         ssh.connect(self._ip,
                     username=self._ssh_username,
                     password=self._ssh_password,
                     timeout=5)
         stdin, stdout, stderr = ssh.exec_command('reboot')
         logging.info(
             'Endpoint %s@%s - about to set timeout of %d on stdout' % (
                 self._vendorname,
                 self._ip,
                 oldtimeout,
             ))
         stdout.channel.settimeout(5)
         try:
             s = stdout.read()
             logging.info('Endpoint %s@%s - answer follows:\n%s' % (
                 self._vendorname,
                 self._ip,
                 s,
             ))
         except socket.error, e:
             pass
         ssh.close()
         return True
Ejemplo n.º 4
0
def main(bitHopper):
    backdoor_port = bitHopper.config.getint('backdoor', 'port')
    try:
        lastDefaultTimeout = socket.getdefaulttimeout()
        socket.setdefaulttimeout(None)
        bitHopper.pile.spawn(backdoor.backdoor_server, eventlet.listen(('127.0.0.1', backdoor_port)), locals={'bh':bitHopper})
        socket.setdefaulttimeout(lastDefaultTimeout)
    except Exception, e:
        bitHopper.log_msg("Unable to start up backdoor: %s") % (e)
Ejemplo n.º 5
0
def main(bitHopper):
    backdoor_port = bitHopper.config.getint('backdoor', 'port')
    try:
        lastDefaultTimeout = socket.getdefaulttimeout()
        socket.setdefaulttimeout(None)
        bitHopper.pile.spawn(backdoor.backdoor_server,
                             eventlet.listen(('127.0.0.1', backdoor_port)),
                             locals={'bh': bitHopper})
        socket.setdefaulttimeout(lastDefaultTimeout)
    except Exception, e:
        logging.info("Unable to start up backdoor: %s") % (e)
Ejemplo n.º 6
0
def main(bitHopper):
    lastDefaultTimeout = socket.getdefaulttimeout()
    options = bitHopper.options
    config = bitHopper.config
    log = None 
    if options.debug:        
        backdoor_port = config.getint('backdoor', 'port')
        backdoor_enabled = config.getboolean('backdoor', 'enabled')
        if backdoor_enabled:
            try:
                socket.setdefaulttimeout(None)
                bitHopper.pile.spawn(backdoor.backdoor_server, eventlet.listen(('127.0.0.1', backdoor_port)), locals={'bh':bitHopper})
                socket.setdefaulttimeout(lastDefaultTimeout)
            except Exception, e:
                print e   
Ejemplo n.º 7
0
                '\r\n' +\
                '&Operation=Upload&DestUpFile=endpointconfig.cfg&' + '\r\n' +\
                '--' + boundary + '\r\n' +\
                'Content-Disposition: form-data; name="importConfigFile"; filename="endpointconfig.cfg"\r\n' +\
                'Content-Type: application/octet-stream\r\n' +\
                '\r\n' +\
                cfgcontent + '\r\n' +\
                '--' + boundary + '--\r\n'

            request = urllib2.Request(
                'http://' + self._ip + '/fcgi/do?id=6&id=2',
                postdata,
                {'Content-Type': ' multipart/form-data; boundary=' + boundary})

            # The phone configuration restore is known to hang for 25-30 seconds
            oldtimeout = socket.getdefaulttimeout()
            socket.setdefaulttimeout(40)
            try:
                response = opener.open(request)
            finally:
                socket.setdefaulttimeout(oldtimeout)

            body = response.read()
            if not 'reboot' in body.lower():
                logging.error('Endpoint %s@%s failed to maintain authentication (POST)' %
                        (self._vendorname, self._ip))
                os.remove(sConfigPath)
                return False
        except socket.error, e:
            logging.error('Endpoint %s@%s failed to connect - %s' %
                    (self._vendorname, self._ip, str(e)))
Ejemplo n.º 8
0
def main():
    parser = optparse.OptionParser(description='bitHopper')
    parser.add_option('--debug', action= 'store_true', default = False, help='Extra error output. Basically print all caught errors')
    parser.add_option('--trace', action= 'store_true', default = False, help='Extra debugging output')
    parser.add_option('--listschedulers', action='store_true', default = False, help='List alternate schedulers available')
    parser.add_option('--port', type = int, default=8337, help='Port to listen on')
    parser.add_option('--scheduler', type=str, default='DefaultScheduler', help='Select an alternate scheduler')
    parser.add_option('--threshold', type=float, default=None, help='Override difficulty threshold (default 0.43)')
    parser.add_option('--altslicesize', type=int, default=900, help='Override Default AltSliceScheduler Slice Size of 900')
    parser.add_option('--altminslicesize', type=int, default=60, help='Override Default Minimum Pool Slice Size of 60 (AltSliceScheduler only)')
    parser.add_option('--altslicejitter', type=int, default=0, help='Add some random variance to slice size, disabled by default (AltSliceScheduler only)')
    parser.add_option('--altsliceroundtimebias', action='store_true', default=False, help='Bias slicing slightly by round time duration with respect to round time target (default false)')
    parser.add_option('--altsliceroundtimetarget', type=int, default=1000, help='Round time target based on GHash/s (default 1000 Ghash/s)')
    parser.add_option('--altsliceroundtimemagic', type=int, default=10, help='Round time magic number, increase to bias towards round time over shares')
    parser.add_option('--config', type=str, default='bh.cfg', help='Select an alternate main config file from bh.cfg')
    parser.add_option('--p2pLP', action='store_true', default=False, help='Starts up an IRC bot to validate LP based hopping.')
    parser.add_option('--ip', type = str, default='', help='IP to listen on')
    parser.add_option('--auth', type = str, default=None, help='User,Password')
    parser.add_option('--logconnections', default = False, action='store_true', help='show connection log')
    parser.add_option('--simple_logging', default = False, action='store_true', help='remove RCP logging from output')
    options = parser.parse_args()[0]

    if options.trace == True: options.debug = True

    if options.listschedulers:
        schedulers = ""
        for s in scheduler.Scheduler.__subclasses__():
            schedulers += ", " + s.__name__
        print "Available Schedulers: " + schedulers[2:]
        return
    
    config = ConfigParser.ConfigParser()
    try:
        # determine if application is a script file or frozen exe
        if hasattr(sys, 'frozen'):
            application_path = os.path.dirname(sys.executable)
        elif __file__:
            application_path = os.path.dirname(__file__)
        if not os.path.exists(os.path.join(application_path, options.config)):
            print "Missing " + options.config + " may need to rename bh.cfg.default"
            os._exit(-1)        
        config.read(os.path.join(application_path, options.config))
    except:
        if not os.path.exists(options.config):
            print "Missing " + options.config + " may need to rename bh.cfg.default"
            os._exit(-1)        
        config.read(options.config)
    
    bithopper_instance = BitHopper(options, config)

    if options.auth:
        auth = options.auth.split(',')
        bithopper_instance.auth = auth
        if len(auth) != 2:
            print 'User,Password. Not whatever you just entered'
            return
    
    # auth from config
    try:
        c = config.get('auth', 'username'), config.get('auth', 'password')
        bithopper_instance.auth = c
    except:
        pass
    
    override_scheduler = False
    
    if options.scheduler != None:
        scheduler_name = options.scheduler
        override_scheduler = True
    try:
        sched = config.get('main', 'scheduler')
        if sched != None:
            override_scheduler = True
            scheduler_name = sched
    except:
        pass
    
    if override_scheduler:
        bithopper_instance.log_msg("Selecting scheduler: " + scheduler_name)
        foundScheduler = False
        for s in scheduler.Scheduler.__subclasses__():
            if s.__name__ == scheduler_name:
                bithopper_instance.scheduler = s(bithopper_instance)
                foundScheduler = True
                break
        if not foundScheduler:            
            bithopper_instance.log_msg("Error couldn't find: " + scheduler_name + ". Using default scheduler.")
            bithopper_instance.scheduler = scheduler.DefaultScheduler(bithopper_instance)
    else:
        bithopper_instance.log_msg("Using default scheduler.")
        bithopper_instance.scheduler = scheduler.DefaultScheduler(bithopper_instance)

    bithopper_instance.select_best_server()

    if options.p2pLP:
        bithopper_instance.log_msg('Starting p2p LP')
        bithopper_instance.lpBot = LpBot(bithopper_instance)

    lastDefaultTimeout = socket.getdefaulttimeout()  

    if options.logconnections:
        log = None
    else:
        log = open(os.devnull, 'wb')
        
    while True:
        try:
            listen_port = options.port            
            try:
                listen_port = config.getint('main', 'port')
            except ConfigParser.Error:
                bithopper_instance.log_dbg("Unable to load main listening port from config file")
                pass
            socket.setdefaulttimeout(None)
            wsgi.server(eventlet.listen((options.ip,listen_port)),bithopper_instance.website.handle_start, log=log)
            socket.setdefaulttimeout(lastDefaultTimeout)
            break
        except Exception, e:
            bithopper_instance.log_msg("Exception in wsgi server loop, restarting wsgi in 60 seconds\n%s") % (e)
            eventlet.sleep(60)
Ejemplo n.º 9
0
def main():
    parser = optparse.OptionParser(description="bitHopper")
    parser.add_option(
        "--debug", action="store_true", default=False, help="Extra error output. Basically print all caught errors"
    )
    parser.add_option("--trace", action="store_true", default=False, help="Extra debugging output")
    parser.add_option(
        "--listschedulers", action="store_true", default=False, help="List alternate schedulers available"
    )
    parser.add_option("--port", type=int, default=8337, help="Port to listen on")
    parser.add_option("--scheduler", type=str, default="OldDefaultScheduler", help="Select an alternate scheduler")
    parser.add_option("--threshold", type=float, default=None, help="Override difficulty threshold (default 0.43)")
    parser.add_option(
        "--altslicesize", type=int, default=900, help="Override Default AltSliceScheduler Slice Size of 900"
    )
    parser.add_option(
        "--altminslicesize",
        type=int,
        default=60,
        help="Override Default Minimum Pool Slice Size of 60 (AltSliceScheduler only)",
    )
    parser.add_option(
        "--altslicejitter",
        type=int,
        default=0,
        help="Add some random variance to slice size, disabled by default (AltSliceScheduler only)",
    )
    parser.add_option(
        "--altsliceroundtimebias",
        action="store_true",
        default=False,
        help="Bias slicing slightly by round time duration with respect to round time target (default false)",
    )
    parser.add_option(
        "--altsliceroundtimetarget",
        type=int,
        default=1000,
        help="Round time target based on GHash/s (default 1000 Ghash/s)",
    )
    parser.add_option(
        "--altsliceroundtimemagic",
        type=int,
        default=10,
        help="Round time magic number, increase to bias towards round time over shares",
    )
    parser.add_option("--config", type=str, default="bh.cfg", help="Select an alternate main config file from bh.cfg")
    parser.add_option(
        "--p2pLP", action="store_true", default=False, help="Starts up an IRC bot to validate LP based hopping."
    )
    parser.add_option("--ip", type=str, default="", help="IP to listen on")
    parser.add_option("--auth", type=str, default=None, help="User,Password")
    parser.add_option("--logconnections", default=False, action="store_true", help="show connection log")
    options = parser.parse_args()[0]

    if options.trace == True:
        options.debug = True

    if options.listschedulers:
        schedulers = ""
        for s in scheduler.Scheduler.__subclasses__():
            schedulers += ", " + s.__name__
        print "Available Schedulers: " + schedulers[2:]
        return

    config = ConfigParser.ConfigParser()
    try:
        # determine if application is a script file or frozen exe
        if hasattr(sys, "frozen"):
            application_path = os.path.dirname(sys.executable)
        elif __file__:
            application_path = os.path.dirname(__file__)
        if not os.path.exists(os.path.join(application_path, options.config)):
            print "Missing " + options.config + " may need to rename bh.cfg.default"
            os._exit(-1)
        config.read(os.path.join(application_path, options.config))
    except:
        if not os.path.exists(options.config):
            print "Missing " + options.config + " may need to rename bh.cfg.default"
            os._exit(-1)
        config.read(options.config)

    bithopper_instance = BitHopper(options, config)

    if options.auth:
        auth = options.auth.split(",")
        bithopper_instance.auth = auth
        if len(auth) != 2:
            print "User,Password. Not whatever you just entered"
            return

    # auth from config
    try:
        c = config.get("auth", "username"), config.get("auth", "password")
        bithopper_instance.auth = c
    except:
        pass

    override_scheduler = False

    if options.scheduler != None:
        scheduler_name = options.scheduler
        override_scheduler = True
    try:
        sched = config.get("main", "scheduler")
        if sched != None:
            override_scheduler = True
            scheduler_name = sched
    except:
        pass

    if override_scheduler:
        bithopper_instance.log_msg("Selecting scheduler: " + scheduler_name)
        foundScheduler = False
        for s in scheduler.Scheduler.__subclasses__():
            if s.__name__ == scheduler_name:
                bithopper_instance.scheduler = s(bithopper_instance)
                foundScheduler = True
                break
        if not foundScheduler:
            bithopper_instance.log_msg("Error couldn't find: " + scheduler_name + ". Using default scheduler.")
            bithopper_instance.scheduler = scheduler.DefaultScheduler(bithopper_instance)
    else:
        bithopper_instance.log_msg("Using default scheduler.")
        bithopper_instance.scheduler = scheduler.DefaultScheduler(bithopper_instance)

    bithopper_instance.select_best_server()

    if options.p2pLP:
        bithopper_instance.log_msg("Starting p2p LP")
        bithopper_instance.lpBot = LpBot(bithopper_instance)

    lastDefaultTimeout = socket.getdefaulttimeout()

    if options.logconnections:
        log = None
    else:
        log = open(os.devnull, "wb")

    while True:
        try:
            listen_port = options.port
            try:
                listen_port = config.getint("main", "port")
            except ConfigParser.Error:
                pass
            socket.setdefaulttimeout(None)
            wsgi.server(eventlet.listen((options.ip, listen_port)), bithopper_instance.website.handle_start, log=log)
            socket.setdefaulttimeout(lastDefaultTimeout)
            break
        except Exception, e:
            print e
            eventlet.sleep(60)
Ejemplo n.º 10
0
    def _sendPhoneConfiguration(self, xmlcontent):
        try:
            # Login into interface
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
            response = opener.open(
                'http://' + self._ip + '/console/j_security_check',
                urllib.urlencode({
                    'submit': 'Login',
                    'j_username': self._http_username,
                    'j_password': self._http_password
                }))
            body = response.read()
            if not '/console/start' in body:
                logging.error(
                    'Endpoint %s@%s - j_security_check failed login' %
                    (self._vendorname, self._ip))
                return False

            # Build a custom request with form data
            boundary = '------------------ENDPOINTCONFIG'
            postdata = '--' + boundary + '\r\n' +\
                'Content-Disposition: form-data; name="COMMAND"\r\n' +\
                '\r\n' +\
                'RX' + '\r\n' +\
                '--' + boundary + '\r\n' +\
                'Content-Disposition: form-data; name="RX"; filename="config.xml"\r\n' +\
                'Content-Type: text/xml\r\n' +\
                '\r\n' +\
                xmlcontent + '\r\n' +\
                '--' + boundary + '--\r\n'
            filerequest = urllib2.Request(
                'http://' + self._ip + '/console/configuration', postdata,
                {'Content-Type': 'multipart/form-data; boundary=' + boundary})
            # The phone configuration restore is known to hang for 25-30 seconds
            oldtimeout = socket.getdefaulttimeout()
            socket.setdefaulttimeout(40)
            try:
                response = opener.open(filerequest)
            finally:
                socket.setdefaulttimeout(oldtimeout)
            body = response.read()

            if not 'Configuration restore complete' in body:
                logging.error('Endpoint %s@%s - configuration post failed' %
                              (self._vendorname, self._ip))
                return False

            # Attempt to set just the provisioning server
            response = opener.open(
                'http://' + self._ip + '/console/general',
                urllib.urlencode({
                    'COMMAND': 'AP',
                    '@p.provisioningServer': self._serverip,
                    '@dhcp_option_protocol': 'TFTP'
                }))
            body = response.read()

            # Since the web interface will NOT immediately apply the network
            # changes, we need to go raw and ssh into the phone. Additionally,
            # if we are changing the network setting from DHCP to static or
            # viceversa, we expect the SSH connection to be disconnected in the
            # middle of the update. A timeout of 5 seconds should do it.
            if self._dhcp:
                command = '/root/dhcp-configure.sh'
            else:
                dns2 = 'none'
                if self._static_dns2 != None:
                    dns2 = self._static_dns2
                command = '/root/staticip-configure.sh %s %s %s %s %s' %\
                    (self._static_ip, self._static_mask, self._static_gw, self._static_dns1, dns2)
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.WarningPolicy())
            ssh.connect(self._ip,
                        username=self._ssh_username,
                        password=self._ssh_password,
                        timeout=5)
            stdin, stdout, stderr = ssh.exec_command(command)
            logging.info(
                'Endpoint %s@%s - about to set timeout of %d on stdout' % (
                    self._vendorname,
                    self._ip,
                    oldtimeout,
                ))
            stdout.channel.settimeout(5)
            try:
                s = stdout.read()
                logging.info('Endpoint %s@%s - answer follows:\n%s' % (
                    self._vendorname,
                    self._ip,
                    s,
                ))
            except socket.error, e:
                pass
            ssh.close()
            return True
Ejemplo n.º 11
0
def main():
    parser = optparse.OptionParser(description='bitHopper')
    parser.add_option('--debug', action= 'store_true', default = False, help='Extra error output. Basically print all caught errors')
    parser.add_option('--trace', action= 'store_true', default = False, help='Extra debugging output')
    parser.add_option('--listschedulers', action='store_true', default = False, help='List alternate schedulers available')
    parser.add_option('--port', type = int, default=8337, help='Port to listen on')
    parser.add_option('--scheduler', type=str, default='DefaultScheduler', help='Select an alternate scheduler')
    parser.add_option('--threshold', type=float, default=None, help='Override difficulty threshold (default 0.43)')
    parser.add_option('--config', type=str, default='bh.cfg', help='Select an alternate main config file from bh.cfg')
    parser.add_option('--ip', type = str, default='', help='IP to listen on')
    parser.add_option('--auth', type = str, default=None, help='User,Password')
    parser.add_option('--logconnections', default = False, action='store_true', help='show connection log')
#    parser.add_option('--simple_logging', default = False, action='store_true', help='remove RCP logging from output')
    options = parser.parse_args()[0]

    if options.debug:
        logging.getLogger().setLevel(logging.DEBUG)
    elif options.trace:
        logging.getLogger().setLevel(0)
    else:
        logging.getLogger().setLevel(logging.INFO)    
    

    if options.listschedulers:
        schedulers = ""
        for s in scheduler.Scheduler.__subclasses__():
            schedulers += ", " + s.__name__
        print "Available Schedulers: " + schedulers[2:]
        return
    
    config = ConfigParser.ConfigParser()
    try:
        # determine if application is a script file or frozen exe
        if hasattr(sys, 'frozen'):
            application_path = os.path.dirname(sys.executable)
        elif __file__:
            application_path = os.path.dirname(__file__)
        if not os.path.exists(os.path.join(application_path, options.config)):
            print "Missing " + options.config + " may need to rename bh.cfg.default"
            os._exit(1)
        config.read(os.path.join(application_path, options.config))
    except:
        if not os.path.exists(options.config):
            print "Missing " + options.config + " may need to rename bh.cfg.default"
            os._exit(1)
        config.read(options.config)
    
    bithopper_instance = BitHopper(options, config)

    if options.auth:
        auth = options.auth.split(',')
        bithopper_instance.auth = auth
        if len(auth) != 2:
            print 'User,Password. Not whatever you just entered'
            return
    
    # auth from config
    try:
        c = config.get('auth', 'username'), config.get('auth', 'password')
        bithopper_instance.auth = c
    except:
        pass
    
    override_scheduler = False
    
    if options.scheduler != None:
        scheduler_name = options.scheduler
        override_scheduler = True
    try:
        sched = config.get('main', 'scheduler')
        if sched != None:
            override_scheduler = True
            scheduler_name = sched
    except:
        pass
    
    if override_scheduler:
        logging.info("Selecting scheduler: " + scheduler_name)
        foundScheduler = False
        for s in scheduler.Scheduler.__subclasses__():
            if s.__name__ == scheduler_name:
                bithopper_instance.scheduler = s(bithopper_instance)
                foundScheduler = True
                break
        if not foundScheduler:            
            logging.info("Error couldn't find: " + scheduler_name + ". Using default scheduler.")
            bithopper_instance.scheduler = scheduler.DefaultScheduler(bithopper_instance)
    else:
        logging.info("Using default scheduler.")
        bithopper_instance.scheduler = scheduler.DefaultScheduler(bithopper_instance)

    bithopper_instance.select_best_server()

    lastDefaultTimeout = socket.getdefaulttimeout()  

    if options.logconnections:
        log = None
    else:
        log = open(os.devnull, 'wb')

    hook = plugins.Hook('plugins.bithopper.startup')
    hook.notify(bithopper_instance, config, options)
        
    while True:
        try:
            listen_port = options.port            
            try:
                listen_port = config.getint('main', 'port')
            except ConfigParser.Error:
                logging.debug("Unable to load main listening port from config file")
                pass

            #This ugly wrapper is required so wsgi server doesn't die
            socket.setdefaulttimeout(None)
            wsgi.server(eventlet.listen((options.ip,listen_port), backlog=500),bithopper_instance.website.handle_start, log=log, max_size = 8000)
            socket.setdefaulttimeout(lastDefaultTimeout)
            break
        except Exception, e:
            logging.info("Exception in wsgi server loop, restarting wsgi in 60 seconds\n%s" % (str(e)))
            eventlet.sleep(60)
Ejemplo n.º 12
0
def main():
    parser = optparse.OptionParser(description="bitHopper")
    parser.add_option(
        "--debug", action="store_true", default=False, help="Extra error output. Basically print all caught errors"
    )
    parser.add_option("--trace", action="store_true", default=False, help="Extra debugging output")
    parser.add_option(
        "--listschedulers", action="store_true", default=False, help="List alternate schedulers available"
    )
    parser.add_option("--port", type=int, default=8337, help="Port to listen on")
    parser.add_option("--scheduler", type=str, default="DefaultScheduler", help="Select an alternate scheduler")
    parser.add_option("--threshold", type=float, default=None, help="Override difficulty threshold (default 0.43)")
    parser.add_option("--config", type=str, default="bh.cfg", help="Select an alternate main config file from bh.cfg")
    parser.add_option("--ip", type=str, default="", help="IP to listen on")
    parser.add_option("--auth", type=str, default=None, help="User,Password")
    parser.add_option("--logconnections", default=False, action="store_true", help="show connection log")
    #    parser.add_option('--simple_logging', default = False, action='store_true', help='remove RCP logging from output')
    options = parser.parse_args()[0]

    if options.trace == True:
        options.debug = True

    if options.listschedulers:
        schedulers = ""
        for s in scheduler.Scheduler.__subclasses__():
            schedulers += ", " + s.__name__
        print "Available Schedulers: " + schedulers[2:]
        return

    config = ConfigParser.ConfigParser()
    try:
        # determine if application is a script file or frozen exe
        if hasattr(sys, "frozen"):
            application_path = os.path.dirname(sys.executable)
        elif __file__:
            application_path = os.path.dirname(__file__)
        if not os.path.exists(os.path.join(application_path, options.config)):
            print "Missing " + options.config + " may need to rename bh.cfg.default"
            os._exit(1)
        config.read(os.path.join(application_path, options.config))
    except:
        if not os.path.exists(options.config):
            print "Missing " + options.config + " may need to rename bh.cfg.default"
            os._exit(1)
        config.read(options.config)

    bithopper_instance = BitHopper(options, config)

    if options.auth:
        auth = options.auth.split(",")
        bithopper_instance.auth = auth
        if len(auth) != 2:
            print "User,Password. Not whatever you just entered"
            return

    # auth from config
    try:
        c = config.get("auth", "username"), config.get("auth", "password")
        bithopper_instance.auth = c
    except:
        pass

    override_scheduler = False

    if options.scheduler != None:
        scheduler_name = options.scheduler
        override_scheduler = True
    try:
        sched = config.get("main", "scheduler")
        if sched != None:
            override_scheduler = True
            scheduler_name = sched
    except:
        pass

    if override_scheduler:
        bithopper_instance.log_msg("Selecting scheduler: " + scheduler_name)
        foundScheduler = False
        for s in scheduler.Scheduler.__subclasses__():
            if s.__name__ == scheduler_name:
                bithopper_instance.scheduler = s(bithopper_instance)
                foundScheduler = True
                break
        if not foundScheduler:
            bithopper_instance.log_msg("Error couldn't find: " + scheduler_name + ". Using default scheduler.")
            bithopper_instance.scheduler = scheduler.DefaultScheduler(bithopper_instance)
    else:
        bithopper_instance.log_msg("Using default scheduler.")
        bithopper_instance.scheduler = scheduler.DefaultScheduler(bithopper_instance)

    bithopper_instance.select_best_server()

    lastDefaultTimeout = socket.getdefaulttimeout()

    if options.logconnections:
        log = None
    else:
        log = open(os.devnull, "wb")

    hook = plugins.Hook("plugins.bithopper.startup")
    hook.notify(bithopper_instance, config, options)

    while True:
        try:
            listen_port = options.port
            try:
                listen_port = config.getint("main", "port")
            except ConfigParser.Error:
                bithopper_instance.log_dbg("Unable to load main listening port from config file")
                pass
            socket.setdefaulttimeout(None)
            wsgi.server(eventlet.listen((options.ip, listen_port)), bithopper_instance.website.handle_start, log=log)
            socket.setdefaulttimeout(lastDefaultTimeout)
            break
        except Exception, e:
            bithopper_instance.log_msg("Exception in wsgi server loop, restarting wsgi in 60 seconds\n%s" % (str(e)))
            eventlet.sleep(60)