graylist/whitelist updates
authoradam <adam@megacz.com>
Wed, 28 Feb 2007 06:51:04 +0000 (06:51 +0000)
committeradam <adam@megacz.com>
Wed, 28 Feb 2007 06:51:04 +0000 (06:51 +0000)
darcs-hash:20070228065104-5007d-c0b82c224aa3a29098fa6bf21049e1e04b63771f.gz

src/org/ibex/mail/Graylist.java
src/org/ibex/mail/SqliteTable.java [new file with mode: 0644]
src/org/ibex/mail/Whitelist.java

index 0628062..3754c62 100644 (file)
@@ -7,21 +7,16 @@ import java.io.*;
 import java.util.*;
 import java.sql.Timestamp;
 
-public class Graylist {
-
-    private Connection conn;
+public class Graylist extends SqliteTable {
 
     public Graylist(String filename) {
-        try {
-            Class.forName("org.sqlite.JDBC");
-            conn = DriverManager.getConnection("jdbc:sqlite:"+filename);
-            conn.prepareStatement("create table if not exists "+
-                                  "'whitelist' (ip unique)").executeUpdate();
-            conn.prepareStatement("create table if not exists "+
-                                  "'graylist' (ip,fromaddr,toaddr,date, primary key(ip,fromaddr,toaddr))").executeUpdate();
-        }
-        catch (SQLException e) { throw new RuntimeException(e); }
-        catch (ClassNotFoundException e) { throw new RuntimeException(e); }
+        super(filename,
+              new String[] {
+                  "create table if not exists 'whitelist' (ip unique)",
+                  "create table if not exists 'graylist' (ip,fromaddr,toaddr,date, primary key(ip,fromaddr,toaddr))"
+              },
+              "graylist",
+              "date");
     }
 
     public synchronized void addWhitelist(InetAddress ip) {
diff --git a/src/org/ibex/mail/SqliteTable.java b/src/org/ibex/mail/SqliteTable.java
new file mode 100644 (file)
index 0000000..085a9b6
--- /dev/null
@@ -0,0 +1,65 @@
+package org.ibex.mail;
+
+import org.ibex.io.*;
+import org.ibex.mail.protocol.*;
+import org.ibex.util.*;
+import org.ibex.net.*;
+import java.sql.*;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.sql.Timestamp;
+import java.sql.Connection;
+
+public class SqliteTable {
+
+    protected Connection conn;
+    private String filename;
+    private String reapTable;
+    private String reapColumn;
+
+    public SqliteTable(String filename, String[] tables, String reapTable, String reapColumn) {
+        this.filename = filename;
+        try {
+            Class.forName("org.sqlite.JDBC");
+            conn = DriverManager.getConnection("jdbc:sqlite:"+filename);
+            for(String s : tables)
+                conn.prepareStatement(s).executeUpdate();
+        }
+        catch (SQLException e) { throw new RuntimeException(e); }
+        catch (ClassNotFoundException e) { throw new RuntimeException(e); }
+        this.reapTable = reapTable;
+        this.reapColumn = reapColumn;
+        if (reapTable != null && reapColumn != null)
+            new Reaper().start();
+    }
+
+    public static final int REAPER_INTERVAL_SECONDS = 60 * 60;
+
+    private class Reaper extends Thread {
+
+        public void run() {
+            while(true) {
+                try {
+                    try { Thread.sleep(1000 * REAPER_INTERVAL_SECONDS); } catch (Exception e) { };
+                    Log.warn(Reaper.class, filename + " reaping...");
+                    long when = System.currentTimeMillis();
+                    when -= 5 * 24 * 60 * 60 * 1000;
+                    synchronized(SqliteTable.this) {
+                        PreparedStatement ps = conn.prepareStatement("select count(*) from "+reapTable+" where "+reapColumn+"<?");
+                        ps.setTimestamp(1, new Timestamp(when));
+                        ResultSet rs = ps.executeQuery();
+                        if (rs.next())
+                            Log.warn(Reaper.class, filename + " reaping " + rs.getInt(1) + " entries");
+                        Log.warn(Reaper.class, filename + ": " + "delete from "+reapTable+" where "+reapColumn+"<"+when);
+                        ps = conn.prepareStatement("delete from "+reapTable+" where "+reapColumn+"<?");
+                        ps.setTimestamp(1, new Timestamp(when));
+                        int rows = ps.executeUpdate();
+                        Log.warn(Reaper.class, filename + " done reaping; removed " + rows + " rows");
+                    }
+                } catch (Exception e) { Log.error(Reaper.class, e); }
+            }
+        }
+    }
+
+}
\ No newline at end of file
index 1fe679e..a9de5c5 100644 (file)
@@ -3,6 +3,7 @@ package org.ibex.mail;
 import org.ibex.io.*;
 import org.ibex.mail.protocol.*;
 import org.ibex.util.*;
+import org.ibex.net.*;
 import java.sql.*;
 import java.net.*;
 import java.io.*;
@@ -10,78 +11,58 @@ import java.util.*;
 import java.sql.Timestamp;
 import java.sql.Connection;
 
-// now all I need is the click-through page
+public class Whitelist extends SqliteTable {
 
-// FIXME: periodic cleanup
-public class Whitelist {
-
-    private Connection conn;
-
-    // FIXME very ugly
-    static {
-        new Thread() { public void run() { startWebServer(); } }.start();
+    public Whitelist(String filename) {
+        super(filename,
+              new String[] {
+                  "create table if not exists 'whitelist' (email)",
+                  "create table if not exists 'pending' (spamid,email,message,date)"
+              },
+              "pending",
+              "date");
     }
-    public static void startWebServer() {
+
+    public synchronized boolean handleRequest(org.ibex.io.Connection c) {
         try {
-            ServerSocket ss = new ServerSocket(8025);
-            while(true) {
-                final Socket sock = ss.accept();
-                new Thread() {
-                    public void run() {
-                        try {
-                            BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
-                            String s = br.readLine();
-                            String url = s.substring(s.indexOf(' ')+1);
-                            url = url.substring(0, url.indexOf(' '));
-                            while(s!=null && !s.equals(""))
-                                s = br.readLine();
-                            PrintWriter pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()));
-                            if (!url.startsWith("/whitelist/")) {
-                                pw.print("HTTP/1.0 404 Not FoundK\r\n");
-                                pw.print("Content-Type: text/plain\r\n");
-                                pw.print("\r\n");
-                                pw.println("you are lost.");
-                            } else {
-                                url = url.substring("/whitelist/".length());
-                                url = URLDecoder.decode(url);
-                                pw.print("HTTP/1.0 200 OK\r\n");
-                                pw.print("Content-Type: text/plain\r\n");
-                                pw.print("\r\n");
-                                try {
-                                    SMTP.whitelist.response(url);
-                                    pw.println("Thanks!  You've been added to my list of non-spammers and your message");
-                                    pw.println("has been moved to my inbox.");
-                                    pw.println("email id " + url);
-                                    pw.println("");
-                                } catch (Exception e) {
-                                    e.printStackTrace(pw);
-                                }
-                            }
-                            pw.flush();
-                            sock.close();
-                        } catch (Exception e) { throw new RuntimeException(e); }
-                    }
-                }.start();
+            Socket sock = c.getSocket();
+            BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
+            String s = br.readLine();
+            String url = s.substring(s.indexOf(' ')+1);
+            url = url.substring(0, url.indexOf(' '));
+            while(s!=null && !s.equals(""))
+                s = br.readLine();
+            PrintWriter pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()));
+            if (!url.startsWith("/whitelist/")) {
+                pw.print("HTTP/1.0 404 Not FoundK\r\n");
+                pw.print("Content-Type: text/plain\r\n");
+                pw.print("\r\n");
+                pw.println("you are lost.");
+            } else {
+                url = url.substring("/whitelist/".length());
+                url = URLDecoder.decode(url);
+                pw.print("HTTP/1.0 200 OK\r\n");
+                pw.print("Content-Type: text/plain\r\n");
+                pw.print("\r\n");
+                try {
+                    SMTP.whitelist.response(url);
+                    pw.println("Thanks!  You've been added to my list of non-spammers and your message");
+                    pw.println("has been moved to my inbox.");
+                    pw.println("email id " + url);
+                    pw.println("");
+                } catch (Exception e) {
+                    e.printStackTrace(pw);
+                }
             }
+            pw.flush();
+            sock.close();
         } catch (Exception e) { throw new RuntimeException(e); }
-    }
-
-
-    public Whitelist(String filename) {
-        try {
-            Class.forName("org.sqlite.JDBC");
-            conn = DriverManager.getConnection("jdbc:sqlite:"+filename);
-            conn.prepareStatement("create table if not exists "+
-                                  "'whitelist' (email)").executeUpdate();
-            conn.prepareStatement("create table if not exists "+
-                                  "'pending' (spamid,email,message,date)").executeUpdate();
-        }
-        catch (SQLException e) { throw new RuntimeException(e); }
-        catch (ClassNotFoundException e) { throw new RuntimeException(e); }
+        return true;
     }
 
     public synchronized boolean isWhitelisted(Address a) {
         try {
+            if (a==null) return false;
             PreparedStatement check = conn.prepareStatement("select * from 'whitelist' where email=?");
             check.setString(1, a.toString(false).toLowerCase());
             ResultSet rs = check.executeQuery();