Index: MANIFEST
===================================================================
--- MANIFEST	(revision 3)
+++ MANIFEST	(revision 15)
@@ -2,8 +2,11 @@
 README
 setup.py
+bin/postman-mta
+bin/postman-server
+conf/postman-mta.conf
+conf/postman.conf
 postman/__init__.py
 postman/config.py
 postman/daemon.py
-postman/daemon_contrib.py
 postman/models.py
 postman/mta.py
Index: bin/postman-mta
===================================================================
--- bin/postman-mta	(revision 15)
+++ bin/postman-mta	(revision 15)
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+#
+# Run the Postman MTA client
+
+import sys
+from postman.mta import MTAClient
+
+def usage():
+    print """
+    Usage: postman-mta address < raw_email_data
+
+    address is a valid mailing list address
+
+    raw_email_data is the raw data (txt) that contains the information of
+    the email to be sent
+    """
+    return True
+
+if __name__ == '__main__':
+    if len(sys.argv) < 2:
+        usage()
+        raise SystemExit
+    try:
+        raw_email = sys.stdin.read()
+    except:
+        usage()
+        raise SystemExit
+    mta_client = MTAClient(address=sys.argv[1])
+    mta_client.get_raw_email(raw_email)
+    mta_client.run()
+
Index: bin/postman-server
===================================================================
--- bin/postman-server	(revision 15)
+++ bin/postman-server	(revision 15)
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+#
+# Run the Postman XML-RPC server
+
+from postman.daemon import PostmanDaemon
+
+if __name__ == '__main__':
+    daemon = PostmanDaemon()
+    daemon.run()
Index: n/postman_server
===================================================================
--- bin/postman_server	(revision 6)
+++ 	(revision )
@@ -1,9 +1,0 @@
-#!/usr/bin/env python
-#
-# Run the Postman XML-RPC server
-
-from postman.daemon import PostmanDaemon
-
-if __name__ == '__main__':
-    daemon = PostmanDaemon()
-    daemon.run()
Index: conf/postman-mta.conf
===================================================================
--- conf/postman-mta.conf	(revision 14)
+++ conf/postman-mta.conf	(revision 15)
@@ -1,9 +1,13 @@
 #
-# postman.conf - Postman MTA client configuration file
+# postman-mta.conf - Postman MTA client configuration file
 #
 
-[postman_server]
+[server]
 address = localhost
 port = 9876
+uri = http://%(address)s:%(port)s
 ssl = false
 
+[archive]
+persistent = true
+path = /usr/local/postman/archive-mta
Index: postman/config.py
===================================================================
--- postman/config.py	(revision 14)
+++ postman/config.py	(revision 15)
@@ -86,10 +86,10 @@
 class MTAClientConfig(DaemonConfig):
     @property
-    def default_filename():
+    def default_filename(self):
         return 'postman-mta.conf'
 
     @property
     def sections(self):
-        return ['postman_server', ]
+        return ['server', 'archive']
 
 
Index: postman/daemon.py
===================================================================
--- postman/daemon.py	(revision 13)
+++ postman/daemon.py	(revision 15)
@@ -189,5 +189,4 @@
                                                     'server.log'))
         logging.basicConfig(filename=self.logfile, level=logging.DEBUG)
-
         self.server = None
         self.ready_to_serve = False
Index: postman/mta.py
===================================================================
--- postman/mta.py	(revision 11)
+++ postman/mta.py	(revision 15)
@@ -11,27 +11,65 @@
 """
 
-import sys, email, smtplib
+import os, sys, email, smtplib, xmlrpclib
 from datetime import datetime
-from models import MailingList
-import config
+from postman.models import MailingList
+from postman.config import MTAClientConfig
+from postman.tools import validate_email_address
 
-class Sendmail():
+class MTAClient():
     
-    def __init__(self, mailing_list=None, configfile=None):
-        if not isinstance(mailing_list, MailingList):
-            raise ValueError(mailing_list, ' is not a valid mailing list')
-        self.mailing_list = mailing_list
-        self.suscriptors = self.mailing_list.members_addresses
-        self.reply_to = self.mailing_list.address
+    def __init__(self, address=None, configfile=None):
+        if not validate_email_address(address):
+            raise ValueError(address, ' is not a valid email address')
+
+        mta_config = MTAClientConfig()
+        mta_config.load()
+        self.config = mta_config.config
+        self.rpc = xmlrpclib.ServerProxy(self.config['server']['uri'])
+        self.address = self._validate_address(address)
+        self.suscriptors = self.rpc.members.list(address)
+        self.reply_to = self.address
         self.raw_email = None
         self.queue = []
-        self.archive_config = config.get_config_parameters('archive',
-                                                           configfile)
+
+    def _validate_archive_path(self):
+        """
+        Validate that the archive path exists. If not, try to create it
+        """
+        if not os.path.exists(self.config['archive']['path']):
+            # FIXME: This will raise an IOError if the user has no
+            # privileges to create the directory, perhaps we should catch
+            # that and show an error instead
+            os.makedirs(self.config['archive']['path'])
+        return True        
         
-    def get_raw_email(self):
-        try:        
-            self.raw_email = sys.stdin.read()
-        except:
-            raise IOError('Can not get a valid email from stdin')
+    def _validate_address(self, address=None):
+        """
+        The address provided by the user will be valid only if it is a
+        valid email address and if it is the email address of an already
+        existing mailing list
+        """
+        if not validate_email_address(address):
+            raise ValueError(address, ' is not a valid email address')
+        if not address in self.rpc.lists.addresses():
+            raise ValueError(address,
+                             ' is not the address of any existing mailing list')
+        # If it is valid, return it
+        return address
+    
+    def get_raw_email(self, raw_email=None):
+        """
+        get the raw data containing email information. If raw_email is None,
+        try to get the data from stdin
+        """
+        if not raw_email:
+            try:
+                self.raw_email = sys.stdin.read()
+            except:
+                raise IOError('Can not get a valid email from stdin')
+        else:
+            self.raw_email = raw_email
+        # FIXME: We should perform some checks on the raw data, ensuring
+        # it is a valid email text
         return self.raw_email
 
@@ -40,6 +78,8 @@
             # FIXME: perhaps a while loop here, with some maximum recursion
             # check, would be nice here
-            self.get_raw_email
-        filename = os.path.join(self.archive_config['path'],
+            self.get_raw_email()
+        # Check the path to the archive exists
+        self._validate_archive_path()
+        filename = os.path.join(self.config['archive']['path'],
                                 datetime.today().strftime('%Y%d%m%H%M%S%f'))
         tmpfile = file(filename, 'w')
@@ -49,4 +89,7 @@
 
     def send_email(self):
+        """
+        Send emails from the queue, if there is any
+        """
         if self.queue:
             next_email = self.queue.pop()
@@ -54,15 +97,17 @@
             email_data = email.message_from_file(email_file)
             email_file.close()
-
             email_data['Reply-to'] = self.reply_to
-
-            smtp_conn = smtplib.SMTP()
-            smtp_conn.connect()
-            smtp_conn.sendmail(email_data['From'], self.suscriptors,
-                               email_data.as_string())
-            smtp_conn.close()
+            print 'SENDING EMAIL:'
+            print email_data
+            #smtp_conn = smtplib.SMTP()
+            #smtp_conn.connect()
+            #smtp_conn.sendmail(email_data['From'], self.suscriptors,
+            #                   email_data.as_string())
+            #smtp_conn.close()
+            # FIXME: enable tmp data removal here:
+            # if not self.config['archive']['persistent']:
+            #     REMOVE THE FILE FROM DISK
 
     def run(self):
-        self.get_raw_email()
         self.save_raw_email()
         self.send_email()
Index: postman/tests/__init__.py
===================================================================
--- postman/tests/__init__.py	(revision 11)
+++ postman/tests/__init__.py	(revision 15)
@@ -12,4 +12,4 @@
 
 from models import *
-from mta import *
+# from mta import *
 from daemon import *
Index: postman/tests/mta.py
===================================================================
--- postman/tests/mta.py	(revision 10)
+++ postman/tests/mta.py	(revision 15)
@@ -1,11 +1,19 @@
 # -*- coding: utf-8 -*-
 
-import os, sys
+import os, sys, multiprocessing, time
 from unittest import TestCase
-from postman.mta import Sendmail
+from postman.mta import MTAClient
+from postman.daemon import PostmanDaemon
 from postman.models import Member, MailingList
 
-class TestSendmail(TestCase):
+
+class TestMTAClient(TestCase):
+    """
+    FIXME: These are dummy tests, they cover almost nothing from the
+    real postman mta client (yet)
+    """
     def setUp(self):
+        self.mta_configfile = os.path.join(os.path.dirname(__file__),
+                                           'postman-mta.conf')
         self.configfile = os.path.join(os.path.dirname(__file__),
                                        'postman.conf')
@@ -13,5 +21,4 @@
                                         members={}, configfile=self.configfile)
         self.member =  Member('test@example.com')
-        self.mta = Sendmail(self.mailing_list)
         self.raw_email_file = os.path.join(os.path.dirname(__file__),
                                            'sample_raw_email.txt')
@@ -19,24 +26,62 @@
         self.raw_email = tmp_to_read.read()
         tmp_to_read.close()
-        
+
     def test___init__(self):
+        # in order to start mta client instances, we need to have a postman
+        # daemon running on the background
+        # This should be added to the setUp() method, but then it would be
+        # more difficult to terminate the process after all the methods
+        # were called
+        daemon = PostmanDaemon(self.configfile)
+        daemon.port = 9100
+        p = multiprocessing.Process(target=daemon.run)
+        p.start()
+        # Add a delay here to allow the server to be fully started before
+        # starting to send requests from the client
+        time.sleep(1)
+
         with self.assertRaises(ValueError):
-            mta = Sendmail('test_list@example.com')
-            mta = Sendmail(self.member)
-            mta = Sendmail(None)
-        mta = Sendmail(self.mailing_list)
-        self.assertTrue(isinstance(mta, Sendmail))
-        self.assertEqual(mta.mailing_list, self.mailing_list)
+            mta = MTAClient(self.mailing_list, self.mta_configfile)
+            mta = MTAClient(self.member, self.mta_configfile)
+            mta = MTAClient(None, self.mta_configfile)
+        mta = MTAClient(self.mailing_list.address, self.mta_configfile)
+        self.assertTrue(isinstance(mta, MTAClient))
+        self.assertEqual(mta.address, self.mailing_list.address)
         self.assertEqual(mta.suscriptors, self.mailing_list.members_addresses)
         self.assertEqual(mta.reply_to, self.mailing_list.address)
 
+        p.terminate()
+
     def test_get_raw_email(self):
+        # in order to start mta client instances, we need to have a postman
+        # daemon running on the background
+        # This should be added to the setUp() method, but then it would be
+        # more difficult to terminate the process after all the methods
+        # were called
+        daemon = PostmanDaemon(self.configfile)
+        daemon.port = 9100
+        p = multiprocessing.Process(target=daemon.run)
+        p.start()
+        # Add a delay here to allow the server to be fully started before
+        # starting to send requests from the client
+        time.sleep(1)
+
+        mta = MTAClient(self.mailing_list.address, self.mta_configfile)
+
         sys_stdin = sys.stdin
         sys.stdin = open(self.raw_email_file, 'r')
-        self.assertEqual(self.mta.get_raw_email(),
+        self.assertEqual(mta.get_raw_email(),
                          self.raw_email)
         sys.stdin.close()
         with self.assertRaises(IOError):
-            self.mta.get_raw_email()
+            mta.get_raw_email()
+
+        tmp_file= open(self.raw_email_file('r'))
+        raw_data = tmp_file.read()
+        tmp_file.close()
+        self.assertEqual(mta.get_raw_email(raw_data),
+                         self.raw_email)
+
+        p.terminate()
 
     #def save_raw_email(self):
Index: postman/tests/postman-mta.conf
===================================================================
--- postman/tests/postman-mta.conf	(revision 15)
+++ postman/tests/postman-mta.conf	(revision 15)
@@ -0,0 +1,13 @@
+#
+# postman-mta.conf - Postman MTA client configuration file
+#
+
+[server]
+address = localhost
+port = 9100 # this port is hardcoded in tests/mta.py
+uri = http://%(address)s:%(port)s
+ssl = false
+
+[archive]
+persistent = true
+path = /tmp/postman-tests/mta/archive
Index: setup.py
===================================================================
--- setup.py	(revision 3)
+++ setup.py	(revision 15)
@@ -1,3 +1,15 @@
+import os
 from distutils.core import setup
+
+def proper_etc_path():
+    # Yes, I'm ommiting windoze...
+    BSDs = ['FreeBSD', 'OpenBSD', 'NetBSD', 'DragonFlyBSD']
+    linux = ['Linux']
+    osx = ['Darwin']
+    os_name = os.uname()[0]
+    if os_name in BSDs:
+        return '/usr/local/etc/'
+    if os_name in linux or os_name in osx:
+        return '/etc/'    
 
 setup(
@@ -11,3 +23,7 @@
     description='Mailing lists management software',
     long_description=open('README').read(),
+    scripts=['bin/postman-server', 'bin/postman-mta'],
+    #data_files=[(proper_etc_path()+'postman', ['conf/postman.conf',
+    #                                           'conf/postman-mta.conf']),
+    #            ]
 )
