From 9d13223e971c1bb37b141cb0b0a3a7dd4077f4d8 Mon Sep 17 00:00:00 2001
From: Raúl Benencia <rbenencia@linti.unlp.edu.ar>
Date: Thu, 2 Aug 2012 22:51:17 -0300
Subject: Fix various semantic errors

---
 core.py       | 64 ++++++++++++++++++++++++++++++++++-------------------------
 model.py      | 21 ++++++++++++--------
 pywhoisd.conf |  6 +++---
 pywhoisd.py   | 35 ++++++++++++++++++++++----------
 4 files changed, 78 insertions(+), 48 deletions(-)

diff --git a/core.py b/core.py
index 1ac7e4f..cdb5343 100644
--- a/core.py
+++ b/core.py
@@ -2,34 +2,33 @@ import socketserver
 import ipaddr
 
 class Daemon():
-    def __init__(data):
+    def __init__(self, data):
         self.data = data    
 
-    def query(q):
+    def query(self, q):
         if self.is_ip(q):
-            self.search_ip(q)
-            
+            self.search_ip(q)            
         elif self.is_domain(q):
-            self.search_domain(q)
-            
+            self.search_domain(q)            
         else:
             # Try to find a person with the given query
             person = search_person(q)
             if person:
                 return person
             else:
-                return self.show_help()
+                return self.get_help()
 
     def search_ip(self, ip):
         result = {}
 
         # Iterate over all IP block elements
-        for network in self.data.get_networks():
-           for block in network.ip_blocks:
+        networks = self.data.get_networks()
+        for key in networks:
+           for block in networks[key].ip_blocks:
                if ipaddr.IPAddress(ip) in ipaddr.IPNetwork(block):
-                   result['name'] = network.name
-                   for key in network.data:
-                       result[key] = network.data[key]
+                   result['name'] = networks[key].name
+                   for k in networks[key].data:
+                       result[k] = networks[key].data[k]
 
                    return result
                    
@@ -40,46 +39,57 @@ class Daemon():
     def search_domain(self, domain):
         pass
 
+    # TODO
+
     def search_person(self, query):
         pass
 
     # TODO
     def is_ip(self, query):
-        pass
+        return True
 
     # TODO
     def is_domain(self, query):
         pass
 
     # TODO
-    def show_help():
-        pass    
+    def get_help(self):
+        return "This will be the help"
+
+    # TODO
+    def get_footer(self):
+        return "This will be the footer"
+
+    # TODO
+    def get_header(self):
+        return "This will be the header"
 
 class WhoisHandler(socketserver.BaseRequestHandler):
 
+    def setup(self):
+        self.daemon = self.server.daemon
+
     def handle(self):
-        daemon = self.server.daemon
-        data = self.request.recv(100)
-        cur_thread = threading.current_thread()
-        response = daemon.get_header() + "\n" + daemon.query(data) + "\n" + daemon.get_footer()
+        data = str(self.request.recv(100), 'utf-8')[:-2]
+
+        response = self.daemon.get_header() + "\n"
+        response += self.daemon.query(data) + "\n"
+        response += self.daemon.get_footer()
         
         self.request.sendall(response)
     
-class ClassicServer(socketserver.ThreadingTCPServer):
+class ClassicServer(socketserver.ThreadingTCPServer):    
     def __init__(self, config, daemon):
         host = config['Servers']['classic_host']
-        port = config['Servers']['classic_port']
+        port = int(config['Servers']['classic_port'])
         self.daemon = daemon
 
-        ThreadingTCPServer.__init__(self, (host, port), WhoisHandler)
-
-    def start(self):
-        pass        
+        socketserver.ThreadingTCPServer.__init__(self, (host, port), WhoisHandler)
 
 class WebServer(socketserver.ThreadingTCPServer):
     def __init__(self, config, daemon):
         self.host = config['Servers']['web_host']
-        self.port = config['Servers']['web_port']
+        self.port = int(config['Servers']['web_port'])
         self.daemon = daemon
 
-        ThreadingTCPServer.__init__(self, (host, port), WhoisHandler)
+        socketserver.ThreadingTCPServer.__init__(self, (self.host, self.port), WhoisHandler)
diff --git a/model.py b/model.py
index 13bcfa8..99f368f 100644
--- a/model.py
+++ b/model.py
@@ -1,4 +1,4 @@
-from xml.etree import ElementTree
+from xml.etree.ElementTree import ElementTree
 
 class Network():
     """A simple network definition"""
@@ -37,9 +37,9 @@ class Data():
     
     def __init__(self, config):
         self.config = config
-        self.networks = []
-        self.domains = []
-        self.persons = []
+        self.networks = None
+        self.domains = None
+        self.persons = None
 
     def parse_config(self):
         """Parse neccesary config params depending on the method used
@@ -79,7 +79,7 @@ class Data():
 
         return self.persons
 
-class DataXML(model.Data):
+class DataXML(Data):
     """Reads network information from a XML file"""
     
     def parse_config(self):
@@ -90,8 +90,13 @@ class DataXML(model.Data):
     def load_data(self):
         """Parse XML for getting network information"""
 
+        self.parse_config()
         root = ElementTree(file=self.data_file).getroot()
         
+        self.networks = {}
+        self.domains = {}
+        self.persons = {}
+        
         for elem in root:
             if elem.tag == 'person':
                 self.add_person(elem)
@@ -105,7 +110,7 @@ class DataXML(model.Data):
     def add_person(self, elem):
         """Adds a new person"""
 
-        person = model.Person()
+        person = Person()
         for e in elem:
             if e.tag == 'name':
                 person.name = e.text
@@ -121,7 +126,7 @@ class DataXML(model.Data):
     def add_domain(self, elem):
         """Adds a new domain"""
 
-        domain = model.Domain()
+        domain = Domain()
         for e in elem:
             if e.tag == 'name':
                 domain.name == e.text
@@ -133,7 +138,7 @@ class DataXML(model.Data):
     def add_network(self, elem):
         """Adds a new network"""
         
-        network = model.Network()
+        network = Network()
         for e in elem:
             if e.tag == 'name':
                 network.name = e.text
diff --git a/pywhoisd.conf b/pywhoisd.conf
index b7d0662..b18da39 100644
--- a/pywhoisd.conf
+++ b/pywhoisd.conf
@@ -6,10 +6,10 @@ classic = yes
 
 # Only makes sense when classic server is enabled
 classic_host = localhost
-classic_port = 4343
+classic_port = 4344
 
 # Run a web whois server?
-web = yes
+web = no
 
 # Only makes sense when web server is enabled
 web_host = localhost
@@ -20,4 +20,4 @@ web_port = 8080
 mode = xml
 
 # Only makes sense when xml storage mode is enabled
-xml_file = networks.xml
\ No newline at end of file
+xml_file = examples/networks.xml
\ No newline at end of file
diff --git a/pywhoisd.py b/pywhoisd.py
index 6572cac..11ad133 100755
--- a/pywhoisd.py
+++ b/pywhoisd.py
@@ -1,5 +1,6 @@
 #!/usr/bin/python3
 import configparser
+import concurrent.futures
 
 import core
 import model
@@ -9,10 +10,14 @@ class PyWhoisD():
 
     def __init__(self):
         self.config = configparser.ConfigParser()
-        self.config.read('examples/pywhoisd.conf')
+        self.config.read('pywhoisd.conf')
 
         self.data = None
         self.daemon = None
+        self.classic_server = None
+        self.web_server = None
+
+        self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
 
     # What kind of storage are we using?
     def config_data(self):
@@ -24,7 +29,7 @@ class PyWhoisD():
         mode = self.config['Storage']['mode']
 
         if mode == 'xml':
-            self.data = xml.DataXML(self.config)
+            self.data = model.DataXML(self.config)
 
     def config_daemon(self):
         """Config common information source for all configured servers"""
@@ -40,34 +45,44 @@ class PyWhoisD():
 
     
     def classic(self):
-        """Returns true if web server is enabled"""
+        """Returns true if classic whois server is enabled"""
         
-        self.config['Servers']['classic'] == 'yes'
+        return self.config['Servers']['classic'] == 'yes'
 
     def config_servers(self):
         """Sets up server configuration from config files"""
         
         if self.classic():
-            self.classic_server = core.ClassicServer(self.config, self.daemon)
+            self.classic_server = core.ClassicServer(self.config, self.daemon)            
+        else:
+            print("[+] Classic server is not enabled")
                 
         if self.web():
             self.web_server = core.WebServer(self.config, self.daemon)
+        else:
+            print("[+] Web server is not enabled")
+
 
     def start_servers(self):
-        """Start configured servers"""
+        """Properly configure and start configured servers"""
         
         self.config_servers()
 
-        if self.classic():
-            self.classic_server.start()
+        if self.classic_server:
+            print("[+] Starting classic whois server")
+            self.executor.submit(self.classic_server.serve_forever)
             
-        if self.web():
-            self.web_server.start()
+        if self.web_server:
+            self.executor.submit(self.web_server.serve_forever)
+
 
     def main(self):
         self.config_daemon()
         self.start_servers()
 
+        # Wait for running server to finish. Probably never.
+        self.executor.shutdown()
+
 if __name__ == "__main__":
     pwd = PyWhoisD()
     pwd.main()
-- 
cgit v1.2.3