mailing list improvements
[org.ibex.mail.git] / src / org / ibex / mail / target / Script.java
index 3a87567..616d5ac 100644 (file)
@@ -4,6 +4,7 @@
 
 package org.ibex.mail.target;
 import org.ibex.js.*;
+import org.ibex.io.*;
 import org.ibex.util.*;
 import org.ibex.mail.*;
 import org.ibex.mail.filter.*;
@@ -11,12 +12,12 @@ import org.ibex.mail.target.*;
 import java.io.*;
 import java.util.*;
 
-public class Script extends Target {
+public class Script extends JS.Obj implements Target {
 
     private static final JS.Method METHOD = new JS.Method();
 
     private static Script root = null;
-    private static final String DEFAULT_CONF = File.separatorChar + "etc" + File.separatorChar + "org.ibex.mail.conf";
+    private static final String DEFAULT_CONF = Mailbox.STORAGE_ROOT + "conf" + File.separatorChar + "inbound.js";
     public static Script root() {
         try {
             if (root == null) root = new Script(System.getProperty("ibex.mail.conf", DEFAULT_CONF));
@@ -62,6 +63,7 @@ public class Script extends Target {
             Object ret = js.call(null, new JS[] { m });
             Log.debug(this, "configuration script returned " + ret);
             if (ret == null) throw new IOException("configuration script returned null");
+            while (ret instanceof JSReflection.Wrapper) ret = ((JSReflection.Wrapper)ret).unwrap();
             if (ret instanceof Target)      ((Target)ret).accept(m);
             //else if (ret instanceof Filter) ((Filter)ret).process(m);
             else throw new IOException("configuration script returned a " + ret.getClass().getName());
@@ -111,19 +113,33 @@ public class Script extends Target {
             case "log.warn": return METHOD;
             case "log.error": return METHOD;
             case "list": return getSub("list");
+            case "url": return getSub("url");
+            case "url.encode": return METHOD;
             case "mail": return getSub("mail");
             case "mail.forward": return METHOD;
             case "mail.forward2": return METHOD;
             case "mail.send": return METHOD;
+            case "mail.attempt": return METHOD;
+            case "mail.later": return Later.instance;
+           case "mail.drop": return METHOD;
+           case "mail.razor": return getSub("mail.razor");
+            case "mail.razor.check": return METHOD;
+           case "mail.dcc": return getSub("mail.dcc");
+            case "mail.dcc.check": return METHOD;
+            case "mail.bounce": return METHOD;
+            case "mail.reject": return METHOD;
             case "mail.my": return getSub("mail.my");
+            case "mail.dir": return METHOD;
+            case "mail.shell": return METHOD;
             case "mail.my.prefs": try {
                     return new org.ibex.js.Directory(new File("/etc/org.ibex.mail.prefs"));
             } catch (IOException e) { throw new JSExn(e.toString()); }
+            case "mail.whitelist": return JSReflection.wrap(org.ibex.mail.protocol.SMTP.whitelist);
             case "mail.my.mailbox":
-                FileBasedMailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true);
-                return root.slash("user", true).slash("megacz", true).slash("newmail", true);
+                Mailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true);
+                return root.slash("user", true).slash("megacz", true);
+            case "mail.list": return METHOD;
             //#end
-            if (JSU.toString(name).startsWith("list.")) { return MailingList.getList(JSU.toString(name).substring(5)); }
             return super.get(name);
         }
 
@@ -134,8 +150,37 @@ public class Script extends Target {
             final int nargs = args.length;
             String name = JSU.toString(name0);
             try {
+                if (name.equals("url.encode")) return JSU.S(java.net.URLEncoder.encode(JSU.toString(args[0])));
+                if (name.equals("mail.list")) return JSReflection.wrap(FileBasedMailbox.getFileBasedMailbox(JSU.toString(args[0]), false));
+                if (name.equals("mail.dir")) {
+                    return new org.ibex.js.Directory(new File(JSU.toString(args[0])));
+                }
+                if (name.equals("mail.shell")) {
+                    // FIXME: EEEEEVIL!
+                    Log.warn("dbug", args[0].getClass().getName());
+                    Log.warn("dbug", args[1].getClass().getName());
+                    final Process p = Runtime.getRuntime().exec(JSU.toString(args[1]));
+                    Message m = (Message)args[0];
+                    new Thread() {
+                        public void run() {
+                            try {
+                                BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
+                                String s = null;
+                                while((s = br.readLine())!=null) 
+                                    Log.warn("shell", s);
+                            } catch (Exception e) { e.printStackTrace(); }
+                        }
+                    }.start();
+                    OutputStream os = p.getOutputStream();
+                    Stream stream = new Stream(os);
+                    m.getStream().transcribe(stream);
+                    stream.close();
+                    p.waitFor();
+                    return null;
+                }
                 if (name.equals("date")) { return new JSDate(args); }
-                if (name.equals("mail.send") || name.equals("send")) {
+                if (name.equals("mail.send") || name.equals("send") || name.equals("mail.attempt") || name.equals("attempt")) {
+                    boolean attempt = name.equals("mail.attempt") || name.equals("attempt");
                     JS m = (JS)a;
                     StringBuffer headers = new StringBuffer();
                     String body = "";
@@ -153,17 +198,57 @@ public class Script extends Target {
                     }
                     if (envelopeTo == null) envelopeTo = to;
                     if (envelopeFrom == null) envelopeFrom = from;
-                    Message message = Message.newMessage(new org.ibex.io.Stream(headers.toString() + "\r\n" + body),
-                                                         envelopeFrom,
-                                                         envelopeTo);
-                    //org.ibex.mail.protocol.SMTP.Outgoing.accept(message);
-                    boolean ok = org.ibex.mail.protocol.SMTP.Outgoing.attempt(message);
-                    if (!ok) throw new JSExn("SMTP server rejected message");
-                    return JSU.T;
+                    Message message =
+                        Message.newMessage(new org.ibex.io.Fountain.StringFountain(headers.toString() + "\r\n" + body),
+                                           envelopeFrom,
+                                           envelopeTo
+                                           );
+                    
+                    boolean ok = false;
+                    try {
+                        if (attempt) {
+                            org.ibex.mail.protocol.SMTP.Outgoing.attempt(message);
+                        } else {
+                            org.ibex.mail.protocol.SMTP.Outgoing.accept(message);
+                        }
+                        ok = true;
+                    } catch (Exception ex) {
+                        if (!attempt) Log.warn(this, ex);
+                    }
+                    if (!ok && !attempt) throw new JSExn("SMTP server rejected message");
+                    return JSU.B(ok);
+                }
+                if (name.equals("mail.razor.check")) {
+                   Process p = Runtime.getRuntime().exec("razor-check");
+                   ((Message)args[0]).getStream().transcribe(new Stream(p.getOutputStream()), true);
+                   return JSU.N(p.waitFor());
+               }
+                if (name.equals("mail.dcc.check")) {
+                   Process p = Runtime.getRuntime().exec(new String[] { "dccproc", "-H" });
+                   ((Message)args[0]).getStream().transcribe(new Stream(p.getOutputStream()), true);
+                   StringBuffer ret = new StringBuffer();
+                   new Stream(p.getInputStream()).transcribe(ret);
+                   p.waitFor();
+                   return JSU.S(ret.toString());
+               }
+                if (name.equals("mail.drop")) {
+                    return args.length==0 ? new Drop() : new Drop(JSU.toString(args[0]));
+               }
+                if (name.equals("mail.bounce")) {
+                    return new JSTarget() {
+                            public void accept(Message m) throws MailException {
+                                try {
+                                    Message m2 = m.bounce(JSU.toString(a));
+                                    org.ibex.mail.protocol.SMTP.Outgoing.accept(m2);
+                                    Log.error(this, "BOUNCING! " + m2.summary());
+                                } catch (Exception e) {
+                                    Log.warn(this, e);
+                                }
+                            } };
                 }
                 if (name.equals("mail.forward2") || name.equals("forward2")) {
                     try {
-                        Message m2 = Message.newMessage(new org.ibex.io.Stream(m.toString()),
+                        Message m2 = Message.newMessage(new org.ibex.io.Fountain.StringFountain(m.toString()),
                                                         m.envelopeFrom,
                                                         new Address(JSU.toString(a)));
                         org.ibex.mail.protocol.SMTP.Outgoing.accept(m2);
@@ -173,18 +258,13 @@ public class Script extends Target {
                     }
                     return null;
                 }
-                if (name.equals("mail.forward") || name.equals("forward")) { return new Target() {
-                        public void accept(Message m) throws MailException {
-                            try {
-                                Message m2 = Message.newMessage(new org.ibex.io.Stream(m.toString()),
-                                                                m.envelopeFrom,
-                                                                new Address(JSU.toString(a)));
-                                org.ibex.mail.protocol.SMTP.Outgoing.accept(m2);
-                            } catch (Exception e) {
-                                throw new MailException(e.toString());
-                            }
-                        }
-                    }; }
+                if (name.equals("mail.forward") || name.equals("forward")) {
+                    Message m2 = Message.newMessage(Script.this.m, Script.this.m.envelopeFrom, new Address(JSU.toString(a)));
+                    org.ibex.mail.protocol.SMTP.Outgoing.attempt(m2, false);
+                    return Drop.instance;
+                }
+                if (name.equals("mail.reject"))
+                    return new Reject(JSU.toString(a));
                 if (name.equals("log.debug") || name.equals("debug")) {    JSU.debug(a== null ? "**null**" : JSU.toString(a)); return null; }
                 if (name.equals("log.info") || name.equals("info")) {     JSU.info(a== null ? "**null**" : JSU.toString(a)); return null; }
                 if (name.equals("log.warn") || name.equals("warn")) {     JSU.warn(a== null ? "**null**" : JSU.toString(a)); return null; }
@@ -196,6 +276,7 @@ public class Script extends Target {
                 case 2:
                     if (name.equals("regexp")) {return new JSRegexp(a, b); }
                 }
+            } catch (MailException e) { throw e;
             } catch (Exception e) {
                 Log.warn(this, "ibex."+name+"() threw: " + e);
                 Log.warn(this, e);
@@ -236,4 +317,6 @@ public class Script extends Target {
                 }
             };
     }
+
+    private static abstract class JSTarget extends JS.Obj implements Target { }
 }