From: adam Date: Wed, 19 Jul 2006 06:34:08 +0000 (+0000) Subject: mailing list improvements (and nntp) X-Git-Url: http://git.megacz.com/?p=org.ibex.mail.git;a=commitdiff_plain;h=bc83134e919098665f5027be4b2b11d971270d15 mailing list improvements (and nntp) darcs-hash:20060719063408-5007d-19ffb483ad8dd3ea53e300ec8930a4ae8a7bceba.gz --- diff --git a/src/org/ibex/mail/MailingList.java b/src/org/ibex/mail/MailingList.java index 90f2487..4eca2c1 100644 --- a/src/org/ibex/mail/MailingList.java +++ b/src/org/ibex/mail/MailingList.java @@ -10,8 +10,6 @@ import org.ibex.mail.protocol.*; import java.util.*; import java.io.*; import java.net.*; -//import org.prevayler.*; -//import org.prevayler.Query; import javax.servlet.*; import javax.servlet.http.*; @@ -29,16 +27,27 @@ public class MailingList implements Target, Iterable { } public void banner(HttpServletRequest request, HttpServletResponse response) throws IOException { - String basename = request.getServletPath(); + String basename = request.getRequestURL()+""; PrintWriter pw = new PrintWriter(response.getWriter()); + /* pw.println(""); + pw.println(" "); + pw.println(" "); + pw.println(" "); pw.println(" "); + */ String confirm = request.getParameter("confirm"); if (confirm != null) { - Subscribe sub = (Subscribe)Confirmation.decode(confirm, Long.parseLong(properties.get("secret")), new Date()); + Subscribe sub = (Subscribe)Confirmation.decode(confirm, secret, new Date()); String email = sub.email; synchronized(this) { - String path = this.path.getAbsolutePath() + File.separatorChar + "subscribers" + File.separatorChar + sub.email; + String path = this.path.getAbsolutePath() + File.separatorChar + "subscribers" + File.separatorChar+sub.email; if (sub.un) new File(path).delete(); else { Log.warn(null, "creating " + path); @@ -47,30 +56,42 @@ public class MailingList implements Target, Iterable { } pw.println(" successfully "+sub.adj+"d " + email + " to " + properties.get("address")); } else { - pw.println(" "+properties.get("address")+"
"); - pw.println(" "+properties.get("nntp")+"
"); String action = request.getParameter("action"); String email = request.getParameter("email"); if (action != null) { Subscribe sub = new Subscribe(email, request.getRequestURL().toString(), action.equals("unsubscribe")); - sub.signAndSend(new Address(properties.get("owner")), Long.parseLong(properties.get("secret")), new Date()); - pw.println("a confirmation email has been sent to " + email + "; click the enclosed link to confirm your request to " + action); + sub.signAndSend(new Address(properties.get("owner")), + secret, new Date()); + pw.println("a confirmation email has been sent to " + email + + "; click the enclosed link to confirm your request to " + action); } else { - pw.println("
"); + pw.println("
"); + pw.println(" "+properties.get("address")+"
"); + pw.println(" "+properties.get("description")+" "); + pw.println("
"); + pw.println("access via: "); + if (path.getAbsolutePath().startsWith("/afs/")) + pw.println("[AFS] "); + pw.println("[NNTP]"); + pw.println("[SMTP]"); + pw.println("[HTTP]"); + pw.println("
"); + pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); pw.println(" "); + pw.println("
"); } } - pw.println(" "); - pw.println(""); + //pw.println(" "); + //pw.println(""); pw.flush(); - pw.close(); } public class Subscribe extends Confirmation { diff --git a/src/org/ibex/mail/Main.java b/src/org/ibex/mail/Main.java index cfad5c1..b2af366 100644 --- a/src/org/ibex/mail/Main.java +++ b/src/org/ibex/mail/Main.java @@ -21,13 +21,10 @@ public class Main implements Listener { try { if (conn.getLocalPort() == 143) new IMAP.Listener(auth).handleRequest(conn); else if (conn.getLocalPort() == 25) new SMTP.Server().handleRequest(conn); - else if (conn.getLocalPort() == 8080) new SMTP.Server().handleRequest(conn); + else if (conn.getLocalPort() == 8080) new SMTP.Server().handleRequest(conn); else if (conn.getLocalPort() == 119) new NNTP.Listener(auth).handleRequest(conn); //else if (conn.getLocalPort() == 110) new POP3.Listener(auth).handleRequest(conn); - else if (conn.getLocalPort() == 8099) GMail.handleRequest(conn); - // else if (conn.getLocalPort() == 8080) Jetty.instance().accept(conn); - //else if (conn.getLocalPort() == 443) Jetty.instance().accept(conn); - //else if (conn.getLocalPort() == 80) Jetty.instance().accept(conn); + //else if (conn.getLocalPort() == 8099) GMail.handleRequest(conn); else return false; return true; } finally { @@ -37,35 +34,23 @@ public class Main implements Listener { private static final Auth auth = new Auth(); private static class Auth implements Login { - public Account anonymous() { return null; } - public Object login(String user, String pass, Class protocol) { - //if (protocol == IMAP.class && user.endsWith("@gmail.com")) return GMail.getGMail(user, pass).getIMAP(); - return login(user, pass); + public Account anonymous() { + final Mailbox root = + FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT + "/user", true); + return new Account("anonymous", null, root.slash("anonymous", true)){ + public Mailbox getMailbox(Class protocol) { + return super.getMailbox(protocol); + } + }; } + public Object login(String user, String pass, Class protocol) { return login(user, pass); } public Account login(String user, String pass) { - //if (user.indexOf("@gmail.com") != -1) return GMail.getGMail(user, pass); if (!EtcPasswd.verify(user, pass)) return null; final Mailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT + "/user", true); return new Account(user, null, root.slash(user, true)){ public Mailbox getMailbox(Class protocol) { - //if (protocol == IMAP.class) return super.getMailbox(protocol).slash("newmail", false).slash("pending", false); - /* - if (protocol == NNTP.class) { - final Mailbox arch = new MailmanArchives(); - return new Mailbox.Default() { - public void add(Message m) { throw new RuntimeException("not supported"); } - public void add(Message m, int i) { throw new RuntimeException("not supported"); } - public int uidValidity() { return 1; } - public Mailbox.Iterator iterator() { return null; } - public int uidNext() { return 0; } - public String[] children() { return new String[] { "us" }; } - public Mailbox slash(String name, boolean create) { return arch; } - }; - } else { - */ - return super.getMailbox(protocol); - //} + return super.getMailbox(protocol); } }; } diff --git a/src/org/ibex/mail/protocol/NNTP.java b/src/org/ibex/mail/protocol/NNTP.java index 6d441e7..b59a15e 100644 --- a/src/org/ibex/mail/protocol/NNTP.java +++ b/src/org/ibex/mail/protocol/NNTP.java @@ -47,7 +47,8 @@ public class NNTP { public boolean ihave(String messageid); public Article next(); public Article last(); - public boolean post(Message m); + public boolean postok(); + public void post(Message m) throws IOException; public Article article(String messageid, boolean head, boolean body); public Article article(int messagenum, boolean head, boolean body); public Group[] list(); @@ -59,7 +60,12 @@ public class NNTP { private final Mailbox root; private Mailbox current; private int ptr = 0; - public MailboxWrapper(Mailbox root) { this.root = root; } + private boolean post; + public MailboxWrapper(Mailbox root) { this(root, false); } + public MailboxWrapper(Mailbox root, boolean post) { this.root = root; this.post = post; } + public boolean postok() { return post; } + public void post(Message m) throws IOException { current.accept(m); } + public Group group(String s) { ptr = 0; Group g = getgroup(s); @@ -69,7 +75,6 @@ public class NNTP { } public boolean ihave(String messageid) { /* FEATURE */ return false; } - public boolean post(Message m) { /* FEATURE */ return false; } public Article next() { return article(ptr++, false, false); } public Article last() { return article(ptr--, false, false); } @@ -158,7 +163,7 @@ public class NNTP { String user = null; String pass = null; Account account = login.anonymous(); - this.api = account == null ? null : new MailboxWrapper(account.getMailbox(NNTP.class)); + this.api = account == null ? null : new MailboxWrapper(account.getMailbox(NNTP.class), true); for(String line = conn.readln(); line != null; line = conn.readln()) try { Log.warn("[nntp-read]", line); StringTokenizer st = new StringTokenizer(line, " "); @@ -175,7 +180,8 @@ public class NNTP { if (pass == null) { println("381 Password required"); continue; } account = login.login(user, pass); if (account == null) { println("502 Invalid"); continue; } - this.api = new MailboxWrapper(account.getMailbox(NNTP.class)); + Mailbox box = account.getMailbox(NNTP.class); + this.api = new MailboxWrapper(box, true); println("281 Good to go"); continue; } @@ -274,16 +280,28 @@ public class NNTP { // newgroup [moderated] -- body of message is a description of the group // rmgroup - /* - boolean postok = api.post(); + boolean postok = api.postok(); if (!postok) { println("440 no posting allowed"); } else { - */ - println("340 send the article"); - // FIME read the article here - println("240 article posted ok"); - //} + println("340 send the article"); + StringBuffer buf = new StringBuffer(); + while(true) { + String s = conn.readln(); + if (s == null) throw new RuntimeException("connection closed"); + if (s.equals(".")) break; + if (s.startsWith(".")) s = s.substring(1); + buf.append(s + "\r\n"); + } + String body = buf.toString(); + try { + api.post(Message.newMessage(new Fountain.StringFountain(body))); + println("240 article posted ok"); + } catch (Exception e) { + e.printStackTrace(); + println("441 posting failed: " + e); + } + } } else if (command.equals("XROVER")) { // equivalent to "XHDR References" diff --git a/src/org/ibex/mail/protocol/SMTP.java b/src/org/ibex/mail/protocol/SMTP.java index 8d16b43..2ba9fdc 100644 --- a/src/org/ibex/mail/protocol/SMTP.java +++ b/src/org/ibex/mail/protocol/SMTP.java @@ -73,7 +73,7 @@ public class SMTP { String remotehost = null; for(String command = conn.readln(); ; command = conn.readln()) try { if (command == null) return; - Log.warn(conn.getRemoteAddress()+"", command); + Log.warn("**"+conn.getRemoteAddress()+"**", command); String c = command.toUpperCase(); if (c.startsWith("HELO")) { remotehost = c.substring(5).trim(); @@ -99,6 +99,13 @@ public class SMTP { command = command.substring(8).trim(); if(command.indexOf(' ') != -1) command = command.substring(0, command.indexOf(' ')); Address addr = new Address(command); + /* + Log.warn("**"+conn.getRemoteAddress()+"**", + "addr.isLocal(): " + addr.isLocal() + "\n" + + "conn.getRemoteAddress().isLoopbackAddress(): " + conn.getRemoteAddress().isLoopbackAddress() + "\n" + + "johnw: " + (from!=null&&from.toString().indexOf("johnw")!=-1) + "\n" + ); + */ if (addr.isLocal()) { // FEATURE: should check the address further and give 550 if undeliverable conn.println("250 " + addr + " is on this machine; I will deliver it"); @@ -364,6 +371,7 @@ public class SMTP { ret = new InetAddress[1]; try { ret[0] = InetAddress.getByName(hostName); + if (ret[0].equals(IP.getIP(127,0,0,1)) || ret[0].isLoopbackAddress()) throw new UnknownHostException(); return ret; } catch (UnknownHostException uhe) { Log.warn(SMTP.class, "no MX hosts or A record for " + hostName); @@ -378,7 +386,7 @@ public class SMTP { mx = mx.substring(mx.indexOf(" ") + 1); if (mx.charAt(mx.length() - 1) == '.') mx = mx.substring(0, mx.length() - 1); InetAddress ia = InetAddress.getByName(mx); - if (ia.equals(IP.getIP(127,0,0,1))) continue; + if (ia.equals(IP.getIP(127,0,0,1)) || ia.isLoopbackAddress()) continue; ret[i++] = ia; } } diff --git a/src/org/ibex/mail/target/FileBasedMailbox.java b/src/org/ibex/mail/target/FileBasedMailbox.java index c700ae0..e5a420a 100644 --- a/src/org/ibex/mail/target/FileBasedMailbox.java +++ b/src/org/ibex/mail/target/FileBasedMailbox.java @@ -152,9 +152,10 @@ public class FileBasedMailbox extends Mailbox.Default { PrintWriter pw = new PrintWriter(response.getWriter()); pw.println(""); if (top) { - pw.println(" "); - pw.println(" "); - pw.println(" "); + pw.println(" "); + //pw.println(" "); + //pw.println(" "); + pw.println(" "); pw.println(" "); } else { pw.println(" "); @@ -202,20 +203,55 @@ public class FileBasedMailbox extends Mailbox.Default { throws IOException { PrintWriter pw = new PrintWriter(response.getWriter()); pw.println(""); + pw.println(" "); + pw.println(" "); + pw.println(" "); pw.println(" "); - pw.println("
");
             if (request.getParameter("msgnum") != null) {
                 int target = Integer.parseInt(request.getParameter("msgnum"));
-                for(Mailbox.Iterator it = mbox.iterator(); it.next();) {
-                    if (it.num() == target) {
-                        StringBuffer tgt = new StringBuffer();
-                        it.cur().getBody().getStream().transcribe(tgt);
-                        pw.println(tgt.toString());
+                Mailbox.Iterator it = mbox.iterator();
+                while(it.next())
+                    if (it.num() == target)
                         break;
+                if (it.cur() != null) {
+                    pw.println("    ");
+                    pw.println("      
"); + Headers h = it.cur().headers; + pw.println(" Subject: " + it.cur().subject +"
"); + pw.println(" From: " + it.cur().from +"
"); + pw.println(" Date: " + it.cur().date +"
"); + /* + for(java.util.Enumeration e = h.names(); e.hasMoreElements();) { + String key = (String)e.nextElement(); + if (key==null || key.length()==0 || key.equals("from") || + key.equals("to") || key.equals("subject") || key.equals("date")) continue; + key = Character.toUpperCase(key.charAt(0)) + key.substring(1); + String val = h.get(key); + for(int i=key.length(); i<15; i++)pw.print(" "); + pw.print(key+": "); + pw.println(val); } + */ + pw.print("
");
+                    StringBuffer tgt = new StringBuffer();
+                    it.cur().getBody().getStream().transcribe(tgt);
+                    pw.println(tgt.toString());
+                    pw.println("    
"); } } - pw.println("
"); pw.println(" "); pw.println(""); pw.flush(); @@ -235,6 +271,12 @@ public class FileBasedMailbox extends Mailbox.Default { pw.println(""); pw.println(" "); pw.println("