NNTP support
authoradam <adam@megacz.com>
Wed, 21 Jul 2004 21:06:26 +0000 (21:06 +0000)
committeradam <adam@megacz.com>
Wed, 21 Jul 2004 21:06:26 +0000 (21:06 +0000)
darcs-hash:20040721210626-5007d-067253ad4b50d81e06735450a3731743d8db1566.gz

src/org/ibex/mail/Main.java
src/org/ibex/mail/protocol/NNTP.java

index bafbebb..009c0bf 100644 (file)
@@ -12,10 +12,9 @@ public class Main implements Listener {
 
     public void accept(Connection conn) {
         Log.error(this, "connection port is " + conn.getLocalPort());
-        if (conn.getLocalPort() == 25) {
-            new SMTP.Server().handleRequest(conn);
-        } else if (conn.getLocalPort() == 143) {
-            new IMAP.Listener().handleRequest(conn);
+        if (conn.getLocalPort() == 25) {         new SMTP.Server().handleRequest(conn);
+        } else if (conn.getLocalPort() == 143) { new IMAP.Listener().handleRequest(conn);
+        } else if (conn.getLocalPort() == 119) { new NNTP.Listener().handleRequest(conn);
         }
         conn.close();
     }
index 6f0f6b9..7cf409c 100644 (file)
@@ -67,6 +67,7 @@ public class NNTP {
         public Group[]  list() { return list(root, ""); }
         private Group[] list(Mailbox who, String prefix) {
             Vec v = new Vec();
+            if (who == null) who = root;
             String[] s = who.children();
             for(int i=0; i<s.length; i++) {
                 v.addElement(new Group(prefix + s[i], true, 0, 0, 0)); // FIXME numbers
@@ -97,38 +98,65 @@ public class NNTP {
     public static class Listener implements Worker {
         private Server api;
         private Connection conn;
+        public Listener(Server api) { this.api = api; }
+        public Listener() {
+            Mailbox root = FileBasedMailbox.getFileBasedMailbox("/var/org.ibex.mail/user/megacz/newmail/", true);
+            this.api = new MailboxWrapper(root);
+        }
+
+        private void println(String s) { Log.warn("[nntp-write]", s); conn.println(s); }
+        private void println() { Log.warn("[nntp-write]", ""); conn.println(); }
+
         private void article(String numOrMessageId, boolean head, boolean body) {
             String s = numOrMessageId.trim();
             Article a;
             if (s.startsWith("<")) a = api.article(s.substring(0, s.length() - 1), head, body);
             else                   a = api.article(Integer.parseInt(s), head, body);
+            if (a == null) {
+                println("423 No such article.");
+                return;
+            }
             int code = (head && body) ? 220 : head ? 221 : body ? 222 : 223;
-            conn.println(code + " " + a.num + " <" + a.messageid + "> get ready for some stuff...");
-            if (head) conn.println(a.message.headers.raw);
-            if (head && body) conn.println();
-            if (body) conn.println(a.message.body);
-            conn.println(".");
+            println(code + " " + a.num + " <" + a.messageid + "> get ready for some stuff...");
+            if (head) println(a.message.headers.raw);
+            if (head && body) println();
+            if (body) println(a.message.body);
+            println(".");
         }
         public void handleRequest(Connection conn) {
             this.conn = conn;
-            api = new NNTP.MailboxWrapper(null);  // FIXME
             conn.setTimeout(30 * 60 * 1000);
-            conn.println("200 " + conn.vhost + " [" + NNTP.class.getName() + "]");
+            println("200 " + conn.vhost + " [" + NNTP.class.getName() + "]");
             for(String line = conn.readln(); line != null; line = conn.readln()) try {
+                Log.warn("[nntp-read]", line);
                 StringTokenizer st = new StringTokenizer(line, " ");
                 String command = st.nextToken().toUpperCase();
                 if        (command.equals("ARTICLE"))   { article(st.hasMoreTokens() ? st.nextToken() : null, true,  true); 
                 } else if (command.equals("HEAD"))      { article(st.hasMoreTokens() ? st.nextToken() : null, true,  false); 
+                } else if (command.equals("MODE"))      { println("201 Hello, you can post.");
                 } else if (command.equals("BODY"))      { article(st.hasMoreTokens() ? st.nextToken() : null, false, true); 
                 } else if (command.equals("STAT"))      { article(st.hasMoreTokens() ? st.nextToken() : null, false, false); 
-                } else if (command.equals("HELP"))      { conn.println("100 you are beyond help."); conn.println(".");
-                } else if (command.equals("SLAVE"))     { conn.println("220 I don't care");
-                } else if (command.equals("LAST"))      { Article a = api.last(); conn.println("223 "+a.num+" "+a.messageid+" ok");
-                } else if (command.equals("NEXT"))      { Article a = api.next(); conn.println("223 "+a.num+" "+a.messageid+" ok");
-                } else if (command.equals("QUIT"))      { conn.println("205 Bye."); conn.close(); return; 
+                } else if (command.equals("HELP"))      { println("100 you are beyond help."); println(".");
+                } else if (command.equals("SLAVE"))     { println("220 I don't care");
+                } else if (command.equals("XOVER"))     {
+                    println("224 Overview information follows");
+                    MailboxWrapper api = (MailboxWrapper)this.api;
+                    String range = st.hasMoreTokens() ? st.nextToken() : (api.ptr+"-"+api.ptr);
+                    int start = Integer.parseInt(range.substring(0, range.indexOf('-')));
+                    int end   = Integer.parseInt(range.substring(range.indexOf('-') + 1));
+                    Mailbox.Iterator it = api.current.iterator(Query.messagenum(start, end));
+                    while(it.next()) {
+                        Message m = it.cur();
+                        println(it.num()+"\t"+m.subject+"\t"+m.from+"\t"+m.date+"\t"+m.messageid+"\t"+
+                                m.headers.gets("references") + "\t" + m.size() + "\t" + m.lines);
+                    }
+                    println(".");
+                } else if (command.equals("LAST"))      { Article a = api.last(); println("223 "+a.num+" "+a.messageid+" ok");
+                } else if (command.equals("NEXT"))      { Article a = api.next(); println("223 "+a.num+" "+a.messageid+" ok");
+                } else if (command.equals("QUIT"))      { println("205 Bye."); conn.close(); return; 
                 } else if (command.equals("GROUP"))     {
                     Group g = api.group(st.nextToken().toLowerCase());
-                    conn.println("221 " + g.count + " " + g.first + " " + g.last + " " + g.name);
+                    println("221 " + g.count + " " + g.first + " " + g.last + " " + g.name);
                 } else if (command.equals("NEWGROUPS") || command.equals("NEWNEWS")) { 
                     String groups = command.equals("NEWNEWS") ? st.nextToken() : null;
                     String datetime = st.nextToken() + " " + st.nextToken();
@@ -151,18 +179,18 @@ public class NNTP {
 
                     if (command.equals("NEWGROUPS")) {
                         Group[] g = api.newgroups(d, dists);
-                        conn.println("231 list of groups follows");
+                        println("231 list of groups follows");
                         for(int i=0; i<g.length; i++)
-                            conn.println(g[i].name + " " + g[i].last + " " + g[i].first + " " + (g[i].post ? "y" : "n"));
-                        conn.println(".");
+                            println(g[i].name + " " + g[i].last + " " + g[i].first + " " + (g[i].post ? "y" : "n"));
+                        println(".");
                     } else {
                         st = new StringTokenizer(groups, ",");
                         String[] g = new String[st.countTokens()];
                         for(int i=0; st.hasMoreTokens(); i++) g[i] = st.nextToken();
                         String[] a = api.newnews(g, d, dists);
-                        conn.println("230 list of article messageids follows");
-                        for(int i=0; i<a.length; i++) conn.println(a[i]);
-                        conn.println(".");
+                        println("230 list of article messageids follows");
+                        for(int i=0; i<a.length; i++) println(a[i]);
+                        println(".");
                     }
 
                 } else if (command.equals("POST"))      { 
@@ -170,33 +198,33 @@ public class NNTP {
                     /*
                     boolean postok = api.post();
                     if (!postok) {
-                        conn.println("440 no posting allowed");
+                        println("440 no posting allowed");
                     } else {
                     */
-                        conn.println("340 send the article");
+                        println("340 send the article");
                         // FIME read the article here
-                        conn.println("240 article posted ok");
+                        println("240 article posted ok");
                         //}
 
                 } else if (command.equals("LIST"))      { 
                     Group[] g = api.list();
-                    conn.println("215 list of groups follows");
+                    println("215 list of groups follows");
                     for(int i=0; i<g.length; i++)
-                        conn.println(g[i].name + " " + g[i].last + " " + g[i].first + " " + (g[i].post ? "y" : "n"));
-                    conn.println(".");
+                        println(g[i].name + " " + g[i].last + " " + g[i].first + " " + (g[i].post ? "y" : "n"));
+                    println(".");
 
                 } else if (command.equals("IHAVE"))     {
                     boolean want = api.ihave(st.nextToken());
                     if (!want) {
-                        conn.println("435 No thanks");
+                        println("435 No thanks");
                     } else {
-                        conn.println("335 Proceed");
+                        println("335 Proceed");
                         // FIXME read article here
-                        conn.println("235 Got it");
+                        println("235 Got it");
                     }
                 }
-            } catch (No n)  { conn.println(n.code + " " + n.getMessage());
-            } catch (Bad b) { conn.println(b.code + " " + b.getMessage()); Log.warn(this, b); }
+            } catch (No n)  { println(n.code + " " + n.getMessage());
+            } catch (Bad b) { println(b.code + " " + b.getMessage()); Log.warn(this, b); }
             conn.close();
         }
     }