예제 #1
0
 def add(self, hash, data):
     peer_id = createPeerID(self.counter)
     self.counter += 1
     d = SingleDownload(self, hash, data['metainfo'], self.config, peer_id)
     self.torrent_list.append(hash)
     self.downloads[hash] = d
     d.start()
예제 #2
0
 def add(self, hash, data):
     peer_id = createPeerID(self.counter)
     self.counter += 1
     d = SingleDownload(self, hash, data['metainfo'], self.config, peer_id)
     self.torrent_list.append(hash)
     self.downloads[hash] = d
     d.start()
예제 #3
0
 def add(self, hash, data):
     c = self.counter
     self.counter += 1
     x = ''
     for _ in xrange(3):
         x = mapbase64[c & 0x3F] + x
         c >>= 6
     peer_id = createPeerID(x)
     d = SingleDownload(self, hash, data['metainfo'], self.config, peer_id)
     self.torrent_list.append(hash)
     self.downloads[hash] = d
     d.start()
예제 #4
0
 def add(self, hash, data):
     c = self.counter
     self.counter += 1
     x = ''
     for _ in xrange(3):
         x = mapbase64[c & 0x3F] + x
         c >>= 6
     peer_id = createPeerID(x)
     d = SingleDownload(self, hash, data['metainfo'], self.config, peer_id)
     self.torrent_list.append(hash)
     self.downloads[hash] = d
     d.start()
예제 #5
0
    def __init__(self, config, Output):
        try:
            self.config = config
            self.Output = Output

            self.torrent_dir = config['torrent_dir']
            self.torrent_cache = {}
            self.file_cache = {}
            self.blocked_files = {}
            self.scan_period = config['parse_dir_interval']
            self.stats_period = config['display_interval']

            self.torrent_list = []
            self.downloads = {}
            self.counter = 0
            self.doneflag = threading.Event()

            self.hashcheck_queue = []
            self.hashcheck_current = None

            self.rawserver = RawServer(self.doneflag,
                                       config['timeout_check_interval'],
                                       config['timeout'],
                                       ipv6_enable=config['ipv6_enabled'],
                                       failfunc=self.failed,
                                       errorfunc=self.exchandler)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    self.listen_port = self.rawserver.find_and_bind(
                        config['minport'],
                        config['maxport'],
                        config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type,
                        randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        self.Output.message(
                            'WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    self.failed("Couldn't listen - " + str(e))
                    return

            self.ratelimiter = RateLimiter(self.rawserver.add_task,
                                           config['upload_unit_size'])
            self.ratelimiter.set_upload_rate(config['max_upload_rate'])

            self.handler = MultiHandler(self.rawserver, self.doneflag, config)
            random.seed(createPeerID())
            self.rawserver.add_task(self.scan, 0)
            self.rawserver.add_task(self.stats, 0)

            self.handler.listen_forever()

            self.Output.message('shutting down')
            self.hashcheck_queue = []
            for hash in self.torrent_list:
                self.Output.message('dropped "{}"'.format(
                    self.torrent_cache[hash]['path']))
                self.downloads[hash].shutdown()
            self.rawserver.shutdown()

        except Exception:
            data = StringIO()
            print_exc(file=data)
            Output.exception(data.getvalue())
예제 #6
0
def run(params):
    h = HeadlessDisplayer()
    while 1:
        configdir = ConfigDir('downloadheadless')
        defaultsToIgnore = ['metafile', 'url', 'priority']
        configdir.setDefaults(defaults, defaultsToIgnore)
        configdefaults = configdir.loadConfig()
        defaults.append(
            ('save_options', 0, 'whether to save the current options as the '
             'new default configuration (only for btdownloadheadless.py)'))
        try:
            config = parse_params(params, configdefaults)
        except ValueError as e:
            print('error: {}\n'.format(e),
                  'run with no args for parameter explanations')
            break
        if not config:
            print(get_usage(defaults, 80, configdefaults))
            break
        if config['save_options']:
            configdir.saveConfig(config)
        configdir.deleteOldCacheData(config['expire_cache_data'])

        myid = createPeerID()
        random.seed(myid)

        doneflag = threading.Event()

        def disp_exception(text):
            print(text)

        rawserver = RawServer(doneflag,
                              config['timeout_check_interval'],
                              config['timeout'],
                              ipv6_enable=config['ipv6_enabled'],
                              failfunc=h.failed,
                              errorfunc=disp_exception)
        upnp_type = UPnP_test(config['upnp_nat_access'])
        while True:
            try:
                listen_port = rawserver.find_and_bind(
                    config['minport'],
                    config['maxport'],
                    config['bind'],
                    ipv6_socket_style=config['ipv6_binds_v4'],
                    upnp=upnp_type,
                    randomizer=config['random_port'])
                break
            except socket.error as e:
                if upnp_type and e == UPnP_ERROR:
                    print('WARNING: COULD NOT FORWARD VIA UPnP')
                    upnp_type = 0
                    continue
                print("error: Couldn't listen - ", e)
                h.failed()
                return

        metainfo = get_metainfo(config['metafile'], config['url'], h.error)
        if not metainfo:
            break

        infohash = hashlib.sha1(bencode(metainfo['info'])).digest()

        dow = BT1Download(h.display, h.finished, h.error, disp_exception,
                          doneflag, config, metainfo, infohash, myid,
                          rawserver, listen_port, configdir)

        if not dow.saveAs(h.chooseFile, h.newpath):
            break

        if not dow.initFiles(old_style=True):
            break
        if not dow.startEngine():
            dow.shutdown()
            break
        dow.startRerequester()
        dow.autoStats()

        if not dow.am_I_finished():
            h.display(activity='connecting to peers')
        rawserver.listen_forever(dow.getPortHandler())
        h.display(activity='shutting down')
        dow.shutdown()
        break
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not h.done:
        h.failed()
예제 #7
0
def run(scrwin, errlist, params):
    doneflag = threading.Event()
    d = CursesDisplayer(scrwin, errlist, doneflag)
    try:
        while 1:
            configdir = ConfigDir('downloadcurses')
            defaultsToIgnore = ['responsefile', 'url', 'priority']
            configdir.setDefaults(defaults, defaultsToIgnore)
            configdefaults = configdir.loadConfig()
            defaults.append(
                ('save_options', 0, 'whether to save the current options as '
                 'the new default configuration (only for btdownloadcurses.py)'
                 ))
            try:
                config = parse_params(params, configdefaults)
            except ValueError as e:
                d.error('error: {}\nrun with no args for parameter '
                        'explanations'.format(e))
                break
            if not config:
                d.error(get_usage(defaults, d.fieldw, configdefaults))
                break
            if config['save_options']:
                configdir.saveConfig(config)
            configdir.deleteOldCacheData(config['expire_cache_data'])

            myid = createPeerID()
            random.seed(myid)

            rawserver = RawServer(
                doneflag, config['timeout_check_interval'], config['timeout'],
                ipv6_enable=config['ipv6_enabled'], failfunc=d.failed,
                errorfunc=d.error)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    listen_port = rawserver.find_and_bind(
                        config['minport'], config['maxport'], config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type, randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        d.error('WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    d.error("Couldn't listen - " + str(e))
                    d.failed()
                    return

            response = get_response(config['responsefile'], config['url'],
                                    d.error)
            if not response:
                break

            infohash = hashlib.sha1(bencode(response['info'])).digest()

            dow = BT1Download(
                d.display, d.finished, d.error, d.error, doneflag, config,
                response, infohash, myid, rawserver, listen_port, configdir)

            if not dow.saveAs(d.chooseFile):
                break

            if not dow.initFiles(old_style=True):
                break
            if not dow.startEngine():
                dow.shutdown()
                break
            dow.startRerequester()
            dow.autoStats()

            if not dow.am_I_finished():
                d.display(activity='connecting to peers')
            rawserver.listen_forever(dow.getPortHandler())
            d.display(activity='shutting down')
            dow.shutdown()
            break

    except KeyboardInterrupt:
        # ^C to exit...
        pass
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not d.done:
        d.failed()
예제 #8
0
def run(scrwin, errlist, params):
    doneflag = threading.Event()
    d = CursesDisplayer(scrwin, errlist, doneflag)
    try:
        while 1:
            configdir = ConfigDir('downloadcurses')
            defaultsToIgnore = ['responsefile', 'url', 'priority']
            configdir.setDefaults(defaults, defaultsToIgnore)
            configdefaults = configdir.loadConfig()
            defaults.append(
                ('save_options', 0, 'whether to save the current options as '
                 'the new default configuration (only for btdownloadcurses.py)'
                 ))
            try:
                config = parse_params(params, configdefaults)
            except ValueError as e:
                d.error('error: {}\nrun with no args for parameter '
                        'explanations'.format(e))
                break
            if not config:
                d.error(get_usage(defaults, d.fieldw, configdefaults))
                break
            if config['save_options']:
                configdir.saveConfig(config)
            configdir.deleteOldCacheData(config['expire_cache_data'])

            myid = createPeerID()
            random.seed(myid)

            rawserver = RawServer(
                doneflag, config['timeout_check_interval'], config['timeout'],
                ipv6_enable=config['ipv6_enabled'], failfunc=d.failed,
                errorfunc=d.error)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    listen_port = rawserver.find_and_bind(
                        config['minport'], config['maxport'], config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type, randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        d.error('WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    d.error("Couldn't listen - " + str(e))
                    d.failed()
                    return

            response = get_response(config['responsefile'], config['url'],
                                    d.error)
            if not response:
                break

            infohash = hashlib.sha1(bencode(response['info'])).digest()

            dow = BT1Download(
                d.display, d.finished, d.error, d.error, doneflag, config,
                response, infohash, myid, rawserver, listen_port, configdir)

            if not dow.saveAs(d.chooseFile):
                break

            if not dow.initFiles(old_style=True):
                break
            if not dow.startEngine():
                dow.shutdown()
                break
            dow.startRerequester()
            dow.autoStats()

            if not dow.am_I_finished():
                d.display(activity='connecting to peers')
            rawserver.listen_forever(dow.getPortHandler())
            d.display(activity='shutting down')
            dow.shutdown()
            break

    except KeyboardInterrupt:
        # ^C to exit...
        pass
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not d.done:
        d.failed()
예제 #9
0
import socket
from traceback import print_exc
from .NetworkAddress import AddrList
from BitTornado.clock import clock
from BitTornado.Application.PeerID import createPeerID

DEBUG = False

EXPIRE_CACHE = 30  # seconds
ID = "BT-" + createPeerID()[-4:]

try:
    import pythoncom
    import win32com.client
    _supported = 1
except ImportError:
    _supported = 0


class _UPnP1(object):  # derived from Myers Carpenter's code
    # seems to use the machine's local UPnP
    # system for its operation.  Runs fairly fast

    def __init__(self):
        self.map = None
        self.last_got_map = -10e10

    def _get_map(self):
        if self.last_got_map + EXPIRE_CACHE < clock():
            try:
                dispatcher = win32com.client.Dispatch("HNetCfg.NATUPnP")
예제 #10
0
import socket
from traceback import print_exc
from .NetworkAddress import AddrList
from BitTornado.clock import clock
from BitTornado.Application.PeerID import createPeerID

DEBUG = False

EXPIRE_CACHE = 30   # seconds
ID = b'BT-' + createPeerID()[-4:]

try:
    import pythoncom
    import win32com.client
    _supported = 1
except ImportError:
    _supported = 0


class _UPnP1(object):   # derived from Myers Carpenter's code
                        # seems to use the machine's local UPnP
                        # system for its operation.  Runs fairly fast

    def __init__(self):
        self.map = None
        self.last_got_map = -10e10

    def _get_map(self):
        if self.last_got_map + EXPIRE_CACHE < clock():
            try:
                dispatcher = win32com.client.Dispatch("HNetCfg.NATUPnP")
예제 #11
0
    def __init__(self, config, Output):
        try:
            self.config = config
            self.Output = Output

            self.torrent_dir = config['torrent_dir']
            self.torrent_cache = {}
            self.file_cache = {}
            self.blocked_files = {}
            self.scan_period = config['parse_dir_interval']
            self.stats_period = config['display_interval']

            self.torrent_list = []
            self.downloads = {}
            self.counter = 0
            self.doneflag = threading.Event()

            self.hashcheck_queue = []
            self.hashcheck_current = None

            self.rawserver = RawServer(
                self.doneflag, config['timeout_check_interval'],
                config['timeout'], ipv6_enable=config['ipv6_enabled'],
                failfunc=self.failed, errorfunc=self.exchandler)

            upnp_type = UPnP_test(config['upnp_nat_access'])
            while True:
                try:
                    self.listen_port = self.rawserver.find_and_bind(
                        config['minport'], config['maxport'], config['bind'],
                        ipv6_socket_style=config['ipv6_binds_v4'],
                        upnp=upnp_type, randomizer=config['random_port'])
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        self.Output.message(
                            'WARNING: COULD NOT FORWARD VIA UPnP')
                        upnp_type = 0
                        continue
                    self.failed("Couldn't listen - " + str(e))
                    return

            self.ratelimiter = RateLimiter(self.rawserver.add_task,
                                           config['upload_unit_size'])
            self.ratelimiter.set_upload_rate(config['max_upload_rate'])

            self.handler = MultiHandler(self.rawserver, self.doneflag, config)
            random.seed(createPeerID())
            self.rawserver.add_task(self.scan, 0)
            self.rawserver.add_task(self.stats, 0)

            self.handler.listen_forever()

            self.Output.message('shutting down')
            self.hashcheck_queue = []
            for hash in self.torrent_list:
                self.Output.message('dropped "{}"'.format(
                    self.torrent_cache[hash]['path']))
                self.downloads[hash].shutdown()
            self.rawserver.shutdown()

        except Exception:
            data = StringIO()
            print_exc(file=data)
            Output.exception(data.getvalue())
예제 #12
0
import socket
from traceback import print_exc
from .NetworkAddress import AddrList
from BitTornado.clock import clock
from BitTornado.Application.PeerID import createPeerID

DEBUG = False

EXPIRE_CACHE = 30  # seconds
ID = b'BT-' + createPeerID()[-4:]

try:
    import pythoncom
    import win32com.client
    _supported = 1
except ImportError:
    _supported = 0


class _UPnP1(object):  # derived from Myers Carpenter's code
    # seems to use the machine's local UPnP
    # system for its operation.  Runs fairly fast

    def __init__(self):
        self.map = None
        self.last_got_map = -10e10

    def _get_map(self):
        if self.last_got_map + EXPIRE_CACHE < clock():
            try:
                dispatcher = win32com.client.Dispatch("HNetCfg.NATUPnP")
예제 #13
0
def run(params):
    h = HeadlessDisplayer()
    while 1:
        configdir = ConfigDir('downloadheadless')
        defaultsToIgnore = ['metafile', 'url', 'priority']
        configdir.setDefaults(defaults, defaultsToIgnore)
        configdefaults = configdir.loadConfig()
        defaults.append(
            ('save_options', 0, 'whether to save the current options as the '
             'new default configuration (only for btdownloadheadless.py)'))
        try:
            config = parse_params(params, configdefaults)
        except ValueError as e:
            print('error: {}\n'.format(e),
                  'run with no args for parameter explanations')
            break
        if not config:
            print(get_usage(defaults, 80, configdefaults))
            break
        if config['save_options']:
            configdir.saveConfig(config)
        configdir.deleteOldCacheData(config['expire_cache_data'])

        myid = createPeerID()
        random.seed(myid)

        doneflag = threading.Event()

        def disp_exception(text):
            print(text)
        rawserver = RawServer(
            doneflag, config['timeout_check_interval'], config['timeout'],
            ipv6_enable=config['ipv6_enabled'], failfunc=h.failed,
            errorfunc=disp_exception)
        upnp_type = UPnP_test(config['upnp_nat_access'])
        while True:
            try:
                listen_port = rawserver.find_and_bind(
                    config['minport'], config['maxport'], config['bind'],
                    ipv6_socket_style=config['ipv6_binds_v4'],
                    upnp=upnp_type, randomizer=config['random_port'])
                break
            except socket.error as e:
                if upnp_type and e == UPnP_ERROR:
                    print('WARNING: COULD NOT FORWARD VIA UPnP')
                    upnp_type = 0
                    continue
                print("error: Couldn't listen - ", e)
                h.failed()
                return

        metainfo = get_metainfo(config['metafile'], config['url'], h.error)
        if not metainfo:
            break

        infohash = hashlib.sha1(bencode(metainfo['info'])).digest()

        dow = BT1Download(
            h.display, h.finished, h.error, disp_exception, doneflag, config,
            metainfo, infohash, myid, rawserver, listen_port, configdir)

        if not dow.saveAs(h.chooseFile, h.newpath):
            break

        if not dow.initFiles(old_style=True):
            break
        if not dow.startEngine():
            dow.shutdown()
            break
        dow.startRerequester()
        dow.autoStats()

        if not dow.am_I_finished():
            h.display(activity='connecting to peers')
        rawserver.listen_forever(dow.getPortHandler())
        h.display(activity='shutting down')
        dow.shutdown()
        break
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not h.done:
        h.failed()
예제 #14
0
def run(scrwin, errlist, params):
    doneflag = threading.Event()
    d = CursesDisplayer(scrwin, errlist, doneflag)
    try:
        while 1:
            configdir = ConfigDir("downloadcurses")
            defaultsToIgnore = ["metafile", "url", "priority"]
            configdir.setDefaults(defaults, defaultsToIgnore)
            configdefaults = configdir.loadConfig()
            defaults.append(
                (
                    "save_options",
                    0,
                    "whether to save the current options as "
                    "the new default configuration (only for btdownloadcurses.py)",
                )
            )
            try:
                config = parse_params(params, configdefaults)
            except ValueError as e:
                d.error("error: {}\nrun with no args for parameter " "explanations".format(e))
                break
            if not config:
                d.error(get_usage(defaults, d.fieldw, configdefaults))
                break
            if config["save_options"]:
                configdir.saveConfig(config)
            configdir.deleteOldCacheData(config["expire_cache_data"])

            myid = createPeerID()
            random.seed(myid)

            rawserver = RawServer(
                doneflag,
                config["timeout_check_interval"],
                config["timeout"],
                ipv6_enable=config["ipv6_enabled"],
                failfunc=d.failed,
                errorfunc=d.error,
            )

            upnp_type = UPnP_test(config["upnp_nat_access"])
            while True:
                try:
                    listen_port = rawserver.find_and_bind(
                        config["minport"],
                        config["maxport"],
                        config["bind"],
                        ipv6_socket_style=config["ipv6_binds_v4"],
                        upnp=upnp_type,
                        randomizer=config["random_port"],
                    )
                    break
                except socket.error as e:
                    if upnp_type and e == UPnP_ERROR:
                        d.error("WARNING: COULD NOT FORWARD VIA UPnP")
                        upnp_type = 0
                        continue
                    d.error("Couldn't listen - " + str(e))
                    d.failed()
                    return

            metainfo = get_metainfo(config["metafile"], config["url"], d.error)
            if not metainfo:
                break

            infohash = hashlib.sha1(bencode(metainfo["info"])).digest()

            dow = BT1Download(
                d.display,
                d.finished,
                d.error,
                d.error,
                doneflag,
                config,
                metainfo,
                infohash,
                myid,
                rawserver,
                listen_port,
                configdir,
            )

            if not dow.saveAs(d.chooseFile):
                break

            if not dow.initFiles(old_style=True):
                break
            if not dow.startEngine():
                dow.shutdown()
                break
            dow.startRerequester()
            dow.autoStats()

            if not dow.am_I_finished():
                d.display(activity="connecting to peers")
            rawserver.listen_forever(dow.getPortHandler())
            d.display(activity="shutting down")
            dow.shutdown()
            break

    except KeyboardInterrupt:
        # ^C to exit...
        pass
    try:
        rawserver.shutdown()
    except Exception:
        pass
    if not d.done:
        d.failed()
예제 #15
0
    def __init__(self, config, rawserver):
        self.config = config
        self.response_size = config['response_size']
        self.dfile = config['dfile']
        self.natcheck = config['nat_check']
        favicon = config['favicon']
        self.parse_dir_interval = config['parse_dir_interval']
        self.favicon = None
        if favicon:
            try:
                with open(favicon, 'r') as h:
                    self.favicon = h.read()
            except IOError:
                print "**warning** specified favicon file -- %s -- does not " \
                    "exist." % favicon
        self.rawserver = rawserver
        self.cached = {}    # format: infohash: [[time1, l1, s1], ...]
        self.cached_t = {}  # format: infohash: [time, cache]
        self.times = {}
        self.state = {}
        self.seedcount = {}

        self.allowed_IPs = None
        self.banned_IPs = None
        if config['allowed_ips'] or config['banned_ips']:
            self.allowed_ip_mtime = 0
            self.banned_ip_mtime = 0
            self.read_ip_lists()

        self.only_local_override_ip = config['only_local_override_ip']
        if self.only_local_override_ip == 2:
            self.only_local_override_ip = not config['nat_check']

        if CHECK_PEER_ID_ENCRYPTED and not CRYPTO_OK:
            print '**warning** crypto library not installed, cannot ' \
                'completely verify encrypted peers'

        if os.path.exists(self.dfile):
            try:
                with open(self.dfile, 'rb') as h:
                    ds = h.read()
                tempstate = bdecode(ds)
                if 'peers' not in tempstate:
                    tempstate = {'peers': tempstate}
                statefiletemplate(tempstate)
                self.state = tempstate
            except (IOError, ValueError, TypeError):
                print '**warning** statefile ' + self.dfile + \
                    ' corrupt; resetting'
        self.downloads = self.state.setdefault('peers', {})
        self.completed = self.state.setdefault('completed', {})

        self.becache = {}
        ''' format: infohash: [[l0, s0], [l1, s1], ...]
                l0,s0 = compact, not requirecrypto=1
                l1,s1 = compact, only supportcrypto=1
                l2,s2 = [compact, crypto_flag], all peers
            if --compact_reqd 0:
                l3,s3 = [ip,port,id]
                l4,l4 = [ip,port] nopeerid
        '''
        if config['compact_reqd']:
            x = 3
        else:
            x = 5
        self.cache_default = [({}, {}) for _ in xrange(x)]
        for infohash, ds in self.downloads.iteritems():
            self.seedcount[infohash] = 0
            for x, y in ds.iteritems():
                ip = y['ip']
                if self.allowed_IPs and ip not in self.allowed_IPs \
                        or self.banned_IPs and ip in self.banned_IPs:
                    del ds[x]
                    continue
                if not y['left']:
                    self.seedcount[infohash] += 1
                if y.get('nat', -1):
                    continue
                gip = y.get('given_ip')
                if gip and is_valid_ip(gip) and \
                        (not self.only_local_override_ip or ip in local_IPs):
                    ip = gip
                self.natcheckOK(infohash, x, ip, y['port'], y)

        for x in self.downloads:
            self.times[x] = {}
            for y in self.downloads[x]:
                self.times[x][y] = 0

        self.trackerid = createPeerID('-T-')
        random.seed(self.trackerid)

        self.reannounce_interval = config['reannounce_interval']
        self.save_dfile_interval = config['save_dfile_interval']
        self.show_names = config['show_names']
        rawserver.add_task(self.save_state, self.save_dfile_interval)
        self.prevtime = clock()
        self.timeout_downloaders_interval = config[
            'timeout_downloaders_interval']
        rawserver.add_task(self.expire_downloaders,
                           self.timeout_downloaders_interval)
        self.logfile = None
        self.log = None
        if config['logfile'] and config['logfile'] != '-':
            try:
                self.logfile = config['logfile']
                self.log = open(self.logfile, 'a')
                sys.stdout = self.log
                print "# Log Started: ", isotime()
            except IOError:
                print "**warning** could not redirect stdout to log file: " + \
                    sys.exc_info()[0]

        if config['hupmonitor']:
            def huphandler(signum, frame, self=self):
                try:
                    self.log.close()
                    self.log = open(self.logfile, 'a')
                    sys.stdout = self.log
                    print "# Log reopened: ", isotime()
                except IOError:
                    print "**warning** could not reopen logfile"

            signal.signal(signal.SIGHUP, huphandler)

        self.allow_get = config['allow_get']

        self.t2tlist = T2TList(config['multitracker_enabled'], self.trackerid,
                               config['multitracker_reannounce_interval'],
                               config['multitracker_maxpeers'],
                               config['http_timeout'],
                               self.rawserver)

        if config['allowed_list']:
            if config['allowed_dir']:
                print '**warning** allowed_dir and allowed_list options ' \
                    'cannot be used together'
                print '**warning** disregarding allowed_dir'
                config['allowed_dir'] = ''
            self.allowed = self.state.setdefault('allowed_list', {})
            self.allowed_list_mtime = 0
            self.parse_allowed()
            self.remove_from_state('allowed', 'allowed_dir_files')
            if config['multitracker_allowed'] == 'autodetect':
                config['multitracker_allowed'] = 'none'
            config['allowed_controls'] = 0

        elif config['allowed_dir']:
            self.allowed = self.state.setdefault('allowed', {})
            self.allowed_dir_files = self.state.setdefault(
                'allowed_dir_files', {})
            self.allowed_dir_blocked = set()
            self.parse_allowed()
            self.remove_from_state('allowed_list')

        else:
            self.allowed = None
            self.remove_from_state('allowed', 'allowed_dir_files',
                                   'allowed_list')
            if config['multitracker_allowed'] == 'autodetect':
                config['multitracker_allowed'] = 'none'
            config['allowed_controls'] = 0

        self.uq_broken = urllib.unquote('+') != ' '
        self.keep_dead = config['keep_dead']
        self.Filter = Filter(rawserver.add_task)

        aggregator = config['aggregator']
        if aggregator == '0':
            self.is_aggregator = False
            self.aggregator_key = None
        else:
            self.is_aggregator = True
            if aggregator == '1':
                self.aggregator_key = None
            else:
                self.aggregator_key = aggregator
            self.natcheck = False

        send = config['aggregate_forward']
        if not send:
            self.aggregate_forward = None
        else:
            sends = send.split(',')
            self.aggregate_forward = sends[0]
            self.aggregate_password = sends[1] if len(sends) > 1 else None

        self.dedicated_seed_id = config['dedicated_seed_id']
        self.is_seeded = {}

        self.cachetime = 0
        self.cachetimeupdate()