Author: toad
Date: 2007-10-23 23:09:49 +0000 (Tue, 23 Oct 2007)
New Revision: 15514

Added:
   trunk/plugins/Freemail/src/freemail/support/
   trunk/plugins/Freemail/src/freemail/support/io/
   trunk/plugins/Freemail/src/freemail/support/io/LineReader.java
   trunk/plugins/Freemail/src/freemail/support/io/LineReadingInputStream.java
   trunk/plugins/Freemail/src/freemail/support/io/TooLongException.java
Modified:
   trunk/plugins/Freemail/build.xml
   trunk/plugins/Freemail/src/freemail/AckProcrastinator.java
   trunk/plugins/Freemail/src/freemail/Freemail.java
   trunk/plugins/Freemail/src/freemail/MailHeaderFilter.java
   trunk/plugins/Freemail/src/freemail/MessageSender.java
   trunk/plugins/Freemail/src/freemail/RTSFetcher.java
   trunk/plugins/Freemail/src/freemail/SingleAccountWatcher.java
   trunk/plugins/Freemail/src/freemail/fcp/FCPConnection.java
   trunk/plugins/Freemail/src/freemail/fcp/FCPMessage.java
   trunk/plugins/Freemail/src/freemail/imap/IMAPListener.java
   trunk/plugins/Freemail/src/freemail/smtp/SMTPListener.java
Log:
Apply patch from ET on Frost to make Freemail a plugin.

Modified: trunk/plugins/Freemail/build.xml
===================================================================
--- trunk/plugins/Freemail/build.xml    2007-10-23 23:03:14 UTC (rev 15513)
+++ trunk/plugins/Freemail/build.xml    2007-10-23 23:09:49 UTC (rev 15514)
@@ -37,7 +37,11 @@

                <!-- Bundle the whole lot together, unless anyone whinges.
                     It makes it much easier to run -->
-               <javac srcdir="${src}" destdir="${build}" debug="on" 
optimize="on" source="1.4" />
+               <javac srcdir="${src}" destdir="${build}" debug="on" 
optimize="on" source="1.4">
+                       <classpath>
+                               <pathelement 
location="${lib}/freenet-cvs-snapshot.jar"/>
+                       </classpath>
+               </javac>
                <copy todir="${build}/freemailgui/text">
                        <fileset dir="${src}/freemailgui/text" />
                </copy>
@@ -52,6 +56,7 @@
                <jar jarfile="${lib}/Freemail.jar" basedir="${build}">
                        <manifest>
                                <attribute name="Main-Class" 
value="freemail.Freemail"/>
+                               <attribute name="Plugin-Main-Class" 
value="freemail.Freemail"/>
                                <attribute name="Built-By" 
value="${user.name}"/>
                                <section name="common">
                                        <attribute name="Implementation-Title" 
value="Freemail"/>

Modified: trunk/plugins/Freemail/src/freemail/AckProcrastinator.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/AckProcrastinator.java  2007-10-23 
23:03:14 UTC (rev 15513)
+++ trunk/plugins/Freemail/src/freemail/AckProcrastinator.java  2007-10-23 
23:09:49 UTC (rev 15514)
@@ -39,6 +39,20 @@
  * Freemail is run more or less permanantly.
  */
 public class AckProcrastinator implements Runnable {
+       /**
+        * Object that is used for syncing purposes.
+        */
+       protected final Object syncObject = new Object();
+
+       /**
+        * Whether the thread this service runs in should stop.
+        */
+       protected volatile boolean stopping = false;
+
+       /**
+        * The currently running threads.
+        */
+       private Thread thread;
        private static final long MAX_DELAY = 12 * 60 * 60 * 1000;
        private static final int RANDOM_ACK_SIZE = 512;

@@ -65,7 +79,8 @@
        }

        public void run() {
-               while (true) {
+               thread = Thread.currentThread();
+               while (!stopping) {
                        File[] acks = getAckDir().listFiles();

                        int i;
@@ -116,8 +131,30 @@
                        } catch (InterruptedException ie) {
                        }
                }
+               synchronized (syncObject) {
+                       thread = null;
+                       syncObject.notify();
+               }
+
        }

+       /**
+        * This method will block until the
+        * thread has exited.
+        */
+       public void kill() {
+               synchronized (syncObject) {
+                       stopping = true;
+                       while (thread != null) {
+                               syncObject.notify();
+                               try {
+                                       syncObject.wait(1000);
+                               } catch (InterruptedException ie1) {
+                               }
+                       }
+               }
+       }
+
        /** As put(String key, String data), but insert random data
         */
        public static synchronized void put(String key) {

Modified: trunk/plugins/Freemail/src/freemail/Freemail.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/Freemail.java   2007-10-23 23:03:14 UTC 
(rev 15513)
+++ trunk/plugins/Freemail/src/freemail/Freemail.java   2007-10-23 23:09:49 UTC 
(rev 15514)
@@ -23,6 +23,8 @@

 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;

 import freemail.fcp.FCPContext;
 import freemail.fcp.FCPConnection;
@@ -30,8 +32,16 @@
 import freemail.smtp.SMTPListener;
 import freemail.config.Configurator;
 import freemail.config.ConfigClient;
+import freenet.pluginmanager.FredPlugin;
+import freenet.pluginmanager.FredPluginHTTP;
+import freenet.pluginmanager.FredPluginHTTPAdvanced;
+import freenet.pluginmanager.FredPluginThreadless;
+import freenet.pluginmanager.PluginHTTPException;
+import freenet.pluginmanager.PluginRespirator;
+import freenet.support.HTMLNode;
+import freenet.support.api.HTTPRequest;

-public class Freemail implements ConfigClient {
+public class Freemail implements ConfigClient, FredPlugin, FredPluginHTTP, 
FredPluginHTTPAdvanced, FredPluginThreadless {
        // version info
        public static final int VER_MAJOR = 0;
        public static final int VER_MINOR = 1;
@@ -48,6 +58,15 @@
        private static File tempdir;
        private static FCPConnection fcpconn;

+       
+       //Plugin
+       private static PluginRespirator pr;
+       private ArrayList singleAccountWatcherList = new ArrayList();
+       private MessageSender sender;
+       private SMTPListener smtpl;
+       private AckProcrastinator ackinserter;
+       private IMAPListener imapl;
+       
        public static File getTempDir() {
                return Freemail.tempdir;
        }
@@ -222,4 +241,156 @@
                        Freemail.globaldatadir = new File(val);
                }
        }
+       
+       // Plugin
+       public void runPlugin(PluginRespirator pr) {
+               Freemail.pr = pr;
+               String cfgfile = CFGFILE;
+               Configurator cfg = new Configurator(new File(cfgfile));
+               FCPContext fcpctx = new FCPContext();
+               
+               cfg.register("fcp_host", fcpctx, "localhost");
+               cfg.register("fcp_port", fcpctx, "9481");
+               
+               Freemail.fcpconn = new FCPConnection(fcpctx);
+               Thread fcpthread  = new Thread(fcpconn, "Freemail FCP 
Connection");
+               fcpthread.setDaemon(true);
+               fcpthread.start();
+               cfg.register("globaldatadir", new Freemail(), GLOBALDATADIR);
+               if (!globaldatadir.exists()) {
+                       if(!globaldatadir.mkdir()) {
+                               System.out.println("Freemail plugin: Couldn't 
create global data directory. Please ensure that the user you are running 
Freemail as has write access to its working directory");
+                               return;
+                       }
+               }
+               cfg.register("datadir", new Freemail(), Freemail.DATADIR);
+               if (!Freemail.datadir.exists()) {
+                       if (!Freemail.datadir.mkdir()) {
+                               System.out.println("Freemail plugin: Couldn't 
create data directory. Please ensure that the user you are running Freemail as 
has write access to its working directory");
+                               return;
+                       }
+               }
+               cfg.register("tempdir", new Freemail(), Freemail.TEMPDIRNAME);
+               if (!Freemail.tempdir.exists()) {
+                       if (!Freemail.tempdir.mkdir()) {
+                               System.out.println("Freemail plugin: Couldn't 
create temporary directory. Please ensure that the user you are running 
Freemail as has write access to its working directory");
+                               return;
+                       }
+               }
+               File[] files = Freemail.datadir.listFiles();
+               for (int i = 0; i < files.length; i++) {
+                       if (files[i].getName().equals(".") || 
files[i].getName().equals(".."))
+                               continue;
+                       if (!files[i].isDirectory()) continue;
+                       
+                       SingleAccountWatcher saw = new 
SingleAccountWatcher(files[i]); 
+                       singleAccountWatcherList.add(saw);
+                       Thread t = new Thread(saw, "Freemail Account Watcher 
for "+files[i].getName());
+                       t.setDaemon(true);
+                       t.start();
+               }
+               
+               // and a sender thread
+               sender = new MessageSender(Freemail.datadir);
+               Thread senderthread = new Thread(sender, "Freemail Message 
sender");
+               senderthread.setDaemon(true);
+               senderthread.start();
+               
+               // start the SMTP Listener
+               smtpl = new SMTPListener(sender, cfg);
+               Thread smtpthread = new Thread(smtpl, "Freemail SMTP Listener");
+               smtpthread.setDaemon(true);
+               smtpthread.start();
+               
+               // start the delayed ACK inserter
+               File ackdir = new File(globaldatadir, ACKDIR);
+               AckProcrastinator.setAckDir(ackdir);
+               ackinserter = new AckProcrastinator();
+               Thread ackinsthread = new Thread(ackinserter, "Freemail Delayed 
ACK Inserter");
+               ackinsthread.setDaemon(true);
+               ackinsthread.start();
+               
+               // start the IMAP listener
+               imapl = new IMAPListener(cfg);
+               Thread imaplthread = new Thread(imapl, "Freemail IMAP 
Listener");
+               imaplthread.setDaemon(true);
+               imaplthread.start();
+       }
+
+       public void terminate() {
+               Iterator it = singleAccountWatcherList.iterator();
+               while(it.hasNext()) {
+                       ((SingleAccountWatcher)it.next()).kill();
+                       it.remove();
+               }
+               sender.kill();
+               ackinserter.kill();
+               smtpl.kill();
+               imapl.kill();
+               fcpconn.kill();
+               return;
+       }
+
+       public String handleHTTPGet(HTTPRequest request) throws 
PluginHTTPException {
+               HTMLNode pageNode = pr.getPageMaker().getPageNode("Freemail 
plugin", false, null);
+               HTMLNode contentNode = 
pr.getPageMaker().getContentNode(pageNode);
+
+               if(request.getParam("add").equals("Add account")) {
+                       if(!(request.getParam("name").equals("") || 
request.getParam("password").equals(""))) {
+                               try {
+                                       
AccountManager.Create(request.getParam("name"));
+                                       
AccountManager.ChangePassword(request.getParam("name"), 
request.getParam("password"));
+                                       
if(!request.getParam("domain").equals("")) {
+                                               
AccountManager.addShortAddress(request.getParam("name"), 
request.getParam("domain"));
+                                       }
+                                       Thread t = new Thread(new 
SingleAccountWatcher(new File(DATADIR, request.getParam("name"))), "Account 
Watcher for "+request.getParam("name"));
+                                       t.setDaemon(true);
+                                       t.start();
+                                       HTMLNode addedBox = 
contentNode.addChild("div", "class", "infobox");
+                                       addedBox.addChild("div", "class", 
"infobox-header", "Added account");
+                                       addedBox.addChild("div", "class", 
"infobox-content", "Account for " + request.getParam("name") + " is created");
+                                       
+                               } catch (IOException ioe) {
+                                       HTMLNode errorBox = 
contentNode.addChild("div", "class", "infobox-error");
+                                       errorBox.addChild("div", "class", 
"infobox-header", "IO Error"); 
+                                       errorBox.addChild("div", "class", 
"infobox-content", "Couldn't create account. Please check write access to 
Freemail's working directory. If you want to overwrite your account, delete the 
appropriate directory manually in 'data' first. Freemail will intentionally not 
overwrite it. Error: "+ioe.getMessage());
+                               } catch (Exception e) {
+                                       HTMLNode errorBox = 
contentNode.addChild("div", "class", "infobox-error");
+                                       errorBox.addChild("div", "class", 
"infobox-header", "Error"); 
+                                       errorBox.addChild("div", "class", 
"infobox-content", "Couldn't change password for "+request.getParam("name")+". 
"+e.getMessage());
+                               }
+                       } else {
+                               HTMLNode errorBox = contentNode.addChild("div", 
"class", "infobox-error");
+                               errorBox.addChild("div", "class", 
"infobox-header", "Error"); 
+                               errorBox.addChild("div", "class", 
"infobox-content", "Couldn't create account, name or password is missing");
+                       }
+               }
+
+               HTMLNode addBox = contentNode.addChild("div", "class", 
"infobox");
+               addBox.addChild("div", "class", "infobox-header", "Add 
account");
+               HTMLNode table = addBox.addChild("div", "class", 
"infobox-content").addChild("form").addChild("table", "class", "plugintable");
+               HTMLNode tableRowName = table.addChild("tr");
+               tableRowName.addChild("td", "Name");
+               tableRowName.addChild("td").addChild("input", new String[] { 
"type", "name", "value", "size" }, new String[] { "text", "name", "", "30" });
+               HTMLNode tableRowPassword = table.addChild("tr");
+               tableRowPassword.addChild("td", "Password");
+               tableRowPassword.addChild("td").addChild("input", new String[] 
{ "type", "name", "value", "size" }, new String[] { "password", "password", "", 
"30" });
+               HTMLNode tableRowDomain = table.addChild("tr");
+               tableRowDomain.addChild("td", "Domain");
+               tableRowDomain.addChild("td").addChild("input", new String[] { 
"type", "name", "value", "size" }, new String[] { "text", "domain", "", "30" });
+               HTMLNode tableRowSubmit = table.addChild("tr");
+               tableRowSubmit.addChild("td");
+               tableRowSubmit.addChild("td").addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "submit", "add", "Add account"});
+               
+               return pageNode.generate();
+       }
+
+       public String handleHTTPPost(HTTPRequest request) throws 
PluginHTTPException {
+               return null;
+       }
+
+       public String handleHTTPPut(HTTPRequest request) throws 
PluginHTTPException {
+               return null;
+       }
+
 }

Modified: trunk/plugins/Freemail/src/freemail/MailHeaderFilter.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/MailHeaderFilter.java   2007-10-23 
23:03:14 UTC (rev 15513)
+++ trunk/plugins/Freemail/src/freemail/MailHeaderFilter.java   2007-10-23 
23:09:49 UTC (rev 15514)
@@ -29,7 +29,6 @@
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.lang.StringBuffer;
-import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.TimeZone;

Modified: trunk/plugins/Freemail/src/freemail/MessageSender.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/MessageSender.java      2007-10-23 
23:03:14 UTC (rev 15513)
+++ trunk/plugins/Freemail/src/freemail/MessageSender.java      2007-10-23 
23:09:49 UTC (rev 15514)
@@ -33,6 +33,20 @@
 import freemail.utils.DateStringFactory;

 public class MessageSender implements Runnable {
+       /**
+        * Object that is used for syncing purposes.
+        */
+       protected final Object syncObject = new Object();
+
+       /**
+        * Whether the thread this service runs in should stop.
+        */
+       protected volatile boolean stopping = false;
+
+       /**
+        * The currently running threads.
+        */
+       private Thread thread;
        public static final String OUTBOX_DIR = "outbox";
        private static final int MIN_RUN_TIME = 60000;
        public static final String NIM_KEY_PREFIX = "KSK at freemail-nim-";
@@ -92,12 +106,16 @@

        public void run() {
                this.senderthread = Thread.currentThread();
-               while (true) {
+               thread = Thread.currentThread();
+               while (!stopping) {
                        long start = System.currentTimeMillis();

                        // iterate through users
                        File[] files = this.datadir.listFiles();
                        for (int i = 0; i < files.length; i++) {
+                               if(stopping) {
+                                       break;
+                               }
                                if (files[i].getName().startsWith("."))
                                        continue;
                                File outbox = new File(files[i], OUTBOX_DIR);
@@ -108,6 +126,10 @@
                        }
                        // don't spin around the loop if nothing's
                        // going on
+                       if(stopping) {
+                               break;
+                       }
+
                        long runtime = System.currentTimeMillis() - start;

                        if (MIN_RUN_TIME - runtime > 0) {
@@ -117,7 +139,28 @@
                                }
                        }
                }
+               synchronized (syncObject) {
+                       thread = null;
+                       syncObject.notify();
+               }
        }
+
+       /**
+        * This method will block until the
+        * thread has exited.
+        */
+       public void kill() {
+               synchronized (syncObject) {
+                       stopping = true;
+                       while (thread != null) {
+                               syncObject.notify();
+                               try {
+                                       syncObject.wait(1000);
+                               } catch (InterruptedException ie1) {
+                               }
+                       }
+               }
+       }

        private void sendDir(File accdir, File dir) {
                File[] files = dir.listFiles();

Modified: trunk/plugins/Freemail/src/freemail/RTSFetcher.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/RTSFetcher.java 2007-10-23 23:03:14 UTC 
(rev 15513)
+++ trunk/plugins/Freemail/src/freemail/RTSFetcher.java 2007-10-23 23:09:49 UTC 
(rev 15514)
@@ -22,6 +22,8 @@
 package freemail;

 import freemail.fcp.HighLevelFCPClient;
+import freemail.support.io.LineReadingInputStream;
+import freemail.support.io.TooLongException;
 import freemail.utils.DateStringFactory;
 import freemail.utils.PropsFile;

@@ -50,8 +52,6 @@
 import org.bouncycastle.crypto.modes.CBCBlockCipher;
 import org.bouncycastle.crypto.DataLengthException;

-import freenet.support.io.LineReadingInputStream;
-import freenet.support.io.TooLongException;

 import org.archive.util.Base32;


Modified: trunk/plugins/Freemail/src/freemail/SingleAccountWatcher.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/SingleAccountWatcher.java       
2007-10-23 23:03:14 UTC (rev 15513)
+++ trunk/plugins/Freemail/src/freemail/SingleAccountWatcher.java       
2007-10-23 23:09:49 UTC (rev 15514)
@@ -28,6 +28,20 @@
 import freemail.utils.EmailAddress;

 public class SingleAccountWatcher implements Runnable {
+       /**
+        * Object that is used for syncing purposes.
+        */
+       protected final Object syncObject = new Object();
+
+       /**
+        * Whether the thread this service runs in should stop.
+        */
+       protected volatile boolean stopping = false;
+
+       /**
+        * The currently running threads.
+        */
+       private Thread thread;
        public static final String CONTACTS_DIR = "contacts";
        public static final String INBOUND_DIR = "inbound";
        public static final String OUTBOUND_DIR = "outbound";
@@ -85,7 +99,8 @@
        }

        public void run() {
-               while (true) {
+               thread = Thread.currentThread();
+               while (!stopping) {
                        long start = System.currentTimeMillis();

                        // is it time we inserted the mailsite?
@@ -95,7 +110,9 @@
                                        this.mailsite_last_upload = 
System.currentTimeMillis();
                                }
                        }
-                       
+                       if(stopping) {
+                               break;
+                       }
                        // send any messages queued in contact outboxes
                        File[] obcontacts = this.obctdir.listFiles();
                        if (obcontacts != null) {
@@ -106,12 +123,13 @@
                                        obct.doComm();
                                }
                        }
-                       
                        if (this.nf != null) {
                                nf.fetch();
                        }
-                       
                        this.rtsf.poll();
+                       if(stopping) {
+                               break;
+                       }

                        // poll for incoming message from all inbound contacts
                        File[] ibcontacts = this.ibctdir.listFiles();
@@ -125,7 +143,10 @@
                                        ibct.fetch(this.mb);
                                }
                        }
-                       
+                       if(stopping) {
+                               break;
+                       }
+               
                        long runtime = System.currentTimeMillis() - start;

                        if (MIN_POLL_DURATION - runtime > 0) {
@@ -135,5 +156,27 @@
                                }
                        }
                }
+               synchronized (syncObject) {
+                       thread = null;
+                       syncObject.notify();
+               }
+
        }
+
+       /**
+        * This method will block until the
+        * thread has exited.
+        */
+       public void kill() {
+               synchronized (syncObject) {
+                       stopping = true;
+                       while (thread != null) {
+                               syncObject.notify();
+                               try {
+                                       syncObject.wait(1000);
+                               } catch (InterruptedException ie1) {
+                               }
+                       }
+               }
+       }
 }

Modified: trunk/plugins/Freemail/src/freemail/fcp/FCPConnection.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/fcp/FCPConnection.java  2007-10-23 
23:03:14 UTC (rev 15513)
+++ trunk/plugins/Freemail/src/freemail/fcp/FCPConnection.java  2007-10-23 
23:09:49 UTC (rev 15514)
@@ -29,6 +29,21 @@
 import java.util.Iterator;

 public class FCPConnection implements Runnable {
+       /**
+        * Object that is used for syncing purposes.
+        */
+       protected final Object syncObject = new Object();
+
+       /**
+        * Whether the thread this service runs in should stop.
+        */
+       protected volatile boolean stopping = false;
+
+       /**
+        * The currently running threads.
+        */
+       private Thread thread;
+
        private final FCPContext fcpctx;
        private OutputStream os;
        private InputStream is;
@@ -76,10 +91,11 @@
        }

        public void run() {
-               while (true) {
+               thread = Thread.currentThread();
+               while (!stopping) {
                        try {
                                this.tryConnect();
-                               if (this.conn == null) throw new IOException();
+                               if (this.conn == null || stopping) throw new 
IOException();

                                FCPMessage msg = this.getMessage();
                                if (msg.getType() == null) throw new 
IOException("Connection closed");
@@ -102,8 +118,33 @@
                                }
                        }
                }
+               synchronized (syncObject) {
+                       thread = null;
+                       syncObject.notify();
+               }
        }

+       /**
+        * This method will block until the
+        * thread has exited.
+        */
+       public void kill() {
+               synchronized (syncObject) {
+                       stopping = true;
+                       try {
+                               finalize();
+                       } catch (Throwable t) {
+                       }
+                       while (thread != null) {
+                               syncObject.notify();
+                               try {
+                                       syncObject.wait(1000);
+                               } catch (InterruptedException ie1) {
+                               }
+                       }
+               }
+       }
+       
        protected void finalize() throws Throwable {
                try {
                        this.conn.close();

Modified: trunk/plugins/Freemail/src/freemail/fcp/FCPMessage.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/fcp/FCPMessage.java     2007-10-23 
23:03:14 UTC (rev 15513)
+++ trunk/plugins/Freemail/src/freemail/fcp/FCPMessage.java     2007-10-23 
23:09:49 UTC (rev 15514)
@@ -31,9 +31,9 @@
 import java.util.Collections;

 import freemail.Freemail;
+import freemail.support.io.LineReader;
+import freemail.support.io.LineReadingInputStream;

-import freenet.support.io.LineReader;
-import freenet.support.io.LineReadingInputStream;

 public class FCPMessage {
        private String messagetype;

Modified: trunk/plugins/Freemail/src/freemail/imap/IMAPListener.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/imap/IMAPListener.java  2007-10-23 
23:03:14 UTC (rev 15513)
+++ trunk/plugins/Freemail/src/freemail/imap/IMAPListener.java  2007-10-23 
23:09:49 UTC (rev 15514)
@@ -23,12 +23,28 @@

 import java.net.ServerSocket;
 import java.net.InetAddress;
+import java.net.SocketTimeoutException;
 import java.io.IOException;

 import freemail.config.Configurator;
 import freemail.config.ConfigClient;

 public class IMAPListener implements Runnable,ConfigClient {
+       /**
+        * Object that is used for syncing purposes.
+        */
+       protected final Object syncObject = new Object();
+
+       /**
+        * Whether the thread this service runs in should stop.
+        */
+       protected volatile boolean stopping = false;
+
+       /**
+        * The currently running threads.
+        */
+       private Thread thread;
+       private ServerSocket sock;
        private static final int LISTENPORT = 3143;
        private String bindaddress;
        private int bindport;
@@ -47,22 +63,49 @@
        }

        public void run() {
+               thread = Thread.currentThread();
                try {
                        this.realrun();
                } catch (IOException ioe) {
                        System.out.println("Error in IMAP server - 
"+ioe.getMessage());
                }
+               synchronized (syncObject) {
+                       thread = null;
+                       syncObject.notify();
+               }
        }

+       /**
+        * This method will block until the
+        * thread has exited.
+        */
+       public void kill() {
+               synchronized (syncObject) {
+                       stopping = true;
+                       try {
+                               sock.close();
+                       } catch (IOException ioe) {     }
+                       while (thread != null) {
+                               syncObject.notify();
+                               try {
+                                       syncObject.wait(1000);
+                               } catch (InterruptedException ie1) {
+                               }
+                       }
+               }
+       }
+
        public void realrun() throws IOException {
-               ServerSocket sock = new ServerSocket(this.bindport, 10, 
InetAddress.getByName(this.bindaddress));
-               
-               while (!sock.isClosed()) {
+               sock = new ServerSocket(this.bindport, 10, 
InetAddress.getByName(this.bindaddress));
+               sock.setSoTimeout(60000);
+               while (!sock.isClosed() && !stopping) {
                        try {
                                IMAPHandler newcli = new 
IMAPHandler(sock.accept());
                                Thread newthread = new Thread(newcli);
                                newthread.setDaemon(true);
                                newthread.start();
+                       } catch (SocketTimeoutException ste) {
+                               
                        } catch (IOException ioe) {

                        }

Modified: trunk/plugins/Freemail/src/freemail/smtp/SMTPListener.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/smtp/SMTPListener.java  2007-10-23 
23:03:14 UTC (rev 15513)
+++ trunk/plugins/Freemail/src/freemail/smtp/SMTPListener.java  2007-10-23 
23:09:49 UTC (rev 15514)
@@ -30,6 +30,21 @@
 import freemail.config.Configurator;

 public class SMTPListener implements Runnable,ConfigClient {
+       /**
+        * Object that is used for syncing purposes.
+        */
+       protected final Object syncObject = new Object();
+
+       /**
+        * Whether the thread this service runs in should stop.
+        */
+       protected volatile boolean stopping = false;
+
+       /**
+        * The currently running threads.
+        */
+       private Thread thread;
+       private ServerSocket sock;
        private static final int LISTENPORT = 3025;
        private final MessageSender msgsender;
        private String bindaddress;
@@ -42,12 +57,37 @@
        }

        public void run() {
+               thread = Thread.currentThread();
                try {
                        this.realrun();
                } catch (IOException ioe) {
                        System.out.println("Error in SMTP server - 
"+ioe.getMessage());
                }
+               synchronized (syncObject) {
+                       thread = null;
+                       syncObject.notify();
+               }
        }
+
+       /**
+        * This method will block until the
+        * thread has exited.
+        */
+       public void kill() {
+               synchronized (syncObject) {
+                       stopping = true;
+                       try {
+                               sock.close();
+                       } catch (IOException ioe) {     }
+                       while (thread != null) {
+                               syncObject.notify();
+                               try {
+                                       syncObject.wait(1000);
+                               } catch (InterruptedException ie1) {
+                               }
+                       }
+               }
+       }

        public void setConfigProp(String key, String val) {
                if (key.equalsIgnoreCase("smtp_bind_address")) {
@@ -58,9 +98,8 @@
        }

        public void realrun() throws IOException {
-               ServerSocket sock = new ServerSocket(this.bindport, 10, 
InetAddress.getByName(this.bindaddress));
-               
-               while (!sock.isClosed()) {
+               sock = new ServerSocket(this.bindport, 10, 
InetAddress.getByName(this.bindaddress));
+               while (!sock.isClosed() && !stopping) {
                        try {
                                SMTPHandler newcli = new 
SMTPHandler(sock.accept(), this.msgsender);
                                Thread newthread = new Thread(newcli);

Added: trunk/plugins/Freemail/src/freemail/support/io/LineReader.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/support/io/LineReader.java              
                (rev 0)
+++ trunk/plugins/Freemail/src/freemail/support/io/LineReader.java      
2007-10-23 23:09:49 UTC (rev 15514)
@@ -0,0 +1,9 @@
+package freemail.support.io;
+
+import java.io.IOException;
+
+public interface LineReader {
+
+       public String readLine(int maxLength, int bufferSize) throws 
IOException;
+       
+}

Added: 
trunk/plugins/Freemail/src/freemail/support/io/LineReadingInputStream.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/support/io/LineReadingInputStream.java  
                        (rev 0)
+++ trunk/plugins/Freemail/src/freemail/support/io/LineReadingInputStream.java  
2007-10-23 23:09:49 UTC (rev 15514)
@@ -0,0 +1,47 @@
+package freemail.support.io;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A FilterInputStream which provides readLine().
+ */
+public class LineReadingInputStream extends FilterInputStream implements 
LineReader {
+       private int lastBytesRead;
+
+       public LineReadingInputStream(InputStream in) {
+               super(in);
+       }
+
+       /**
+        * Read a line of US-ASCII. Used for e.g. HTTP. @return Null if end of 
file.
+        */
+       public String readLine(int maxLength, int bufferSize) throws 
IOException {
+               StringBuffer sb = new StringBuffer(bufferSize);
+               this.lastBytesRead = 0;
+               while(true) {
+                       int x = read();
+                       this.lastBytesRead++;
+                       if(x == -1) {
+                               if(sb.length() == 0) return null;
+                               return sb.toString();
+                       }
+                       char c = (char) x;
+                       if(c == '\n') {
+                               if(sb.length() > 0) {
+                                       if(sb.charAt(sb.length()-1) == '\r')
+                                               sb.setLength(sb.length()-1);
+                               }
+                               return sb.toString();
+                       }
+                       sb.append(c);
+                       if(sb.length() >= maxLength)
+                               throw new TooLongException();
+               }
+       }
+       
+       public int getLastBytesRead() {
+               return this.lastBytesRead;
+       }
+}

Added: trunk/plugins/Freemail/src/freemail/support/io/TooLongException.java
===================================================================
--- trunk/plugins/Freemail/src/freemail/support/io/TooLongException.java        
                        (rev 0)
+++ trunk/plugins/Freemail/src/freemail/support/io/TooLongException.java        
2007-10-23 23:09:49 UTC (rev 15514)
@@ -0,0 +1,8 @@
+package freemail.support.io;
+
+import java.io.IOException;
+
+/** Exception thrown by a LineReadingInputStream when a line is too long. */
+public class TooLongException extends IOException {
+       static final long serialVersionUID = -1;
+}


Reply via email to