package org.ibex.mail;
import org.ibex.js.*;
import org.ibex.io.*;
+import org.ibex.io.Fountain;
import org.ibex.util.*;
import org.ibex.mail.filter.*;
import org.ibex.mail.target.*;
import java.util.*;
import java.text.*;
+// FIXME: check for binaries (razor, clamassassin, etc) and complain if not present
+
+//
+// - better matching syntax:
+// - src-ip
+// - from *@foo.com
+// - list-id
+// - ==> {discard, refuse, bounce}
+//
+
public class Script extends JS.Obj implements Target {
private static final JS.Method METHOD = new JS.Method();
this.m = m;
try {
Object ret = js.call(null, new JS[] { m });
- Log.debug(this, "configuration script returned " + ret);
+ Log.warn(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);
case "mail.drop": return METHOD;
case "mail.razor": return getSub("mail.razor");
case "mail.razor.check": return METHOD;
+ case "mail.clamav": return getSub("mail.clamav");
+ case "mail.clamav.check": return METHOD;
+ case "mail.procmail": /* FEATURE */ return null;
+ case "mail.vacation": /* FEATURE */ return null;
case "mail.dcc": return getSub("mail.dcc");
case "mail.dcc.check": return METHOD;
case "mail.bounce": return METHOD;
} catch (IOException e) { throw new JSExn(e.toString()); }
case "mail.whitelist": return JSReflection.wrap(org.ibex.mail.SMTP.whitelist);
case "mail.my.mailbox":
- Mailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true);
- return root.slash("user", true).slash("megacz", true);
+ MailTree root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true);
+ return (JS)root.slash("user", true).slash("megacz", true);
case "mail.list": return METHOD;
//#end
return super.get(name);
}
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() {
+ Log.warn("dbug", a.getClass().getName());
+ Log.warn("dbug", b.getClass().getName());
+ Message m = (Message)b;
+ final Process p = Runtime.getRuntime().exec(JSU.toString(a));
+ Main.threadPool.start(new Runnable() {
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
Log.warn("shell", s);
} catch (Exception e) { e.printStackTrace(); }
}
- }.start();
+ });
OutputStream os = p.getOutputStream();
Stream stream = new Stream(os);
- m.getStream().transcribe(stream);
+
+ // why do I need to go via an sb here?
+ StringBuffer sb = new StringBuffer();
+ m.getBody().getStream().transcribe(sb);
+ stream.println(sb.toString());
+
+ stream.flush();
stream.close();
p.waitFor();
return null;
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 = "";
Address from = null, to = null, envelopeFrom = null, envelopeTo = null;
JS.Enumeration e = m.keys();
+ Headers headers = new Headers();
for(; e.hasNext();) {
JS key = (JS)e.next();
JS val = m.get(key) == null ? null : m.get(key);
if ("body".equalsIgnoreCase(JSU.toString(key))) body = JSU.toString(val);
- else headers.append(JSU.toString(key) + ": " + JSU.toString(val) + "\r\n");
+ else headers = new Headers(headers, new String[] { JSU.toString(key), JSU.toString(val) });
if ("from".equalsIgnoreCase(JSU.toString(key))) from = Address.parse(JSU.toString(val));
if ("to".equalsIgnoreCase(JSU.toString(key))) to = Address.parse(JSU.toString(val));
if ("envelopeFrom".equalsIgnoreCase(JSU.toString(key))) envelopeFrom = Address.parse(JSU.toString(val));
if (envelopeTo == null) envelopeTo = to;
if (envelopeFrom == null) envelopeFrom = from;
Message message =
- Message.newMessage(new org.ibex.io.Fountain.StringFountain(headers.toString() + "\r\n" + body),
- envelopeFrom,
- envelopeTo
- );
+ Message.newMessageFromHeadersAndBody(headers, Fountain.Util.create(body), envelopeFrom, envelopeTo);
boolean ok = false;
try {
if (attempt) {
org.ibex.mail.SMTP.Outgoing.attempt(message);
} else {
- org.ibex.mail.SMTP.Outgoing.accept(message);
+ org.ibex.mail.SMTP.Outgoing.enqueue(message);
}
ok = true;
} catch (Exception ex) {
((Message)args[0]).getStream().transcribe(new Stream(p.getOutputStream()), true);
return JSU.N(p.waitFor());
}
+ if (name.equals("mail.clamav.check")) {
+ // FIXME: this is returning "is-virus-laden" when clamdscan is unhappy -- BAD!
+ // should use error code: 0=clean, 1=virus, 2=malfunction
+ Process p = Runtime.getRuntime().exec("clamdscan - --stdout --quiet");
+ ((Message)args[0]).getStream().transcribe(new Stream(p.getOutputStream()), true);
+ int result = p.waitFor();
+ if (result==0) return JSU.N(0);
+ StringBuffer ret = new StringBuffer();
+ new Stream(p.getInputStream()).transcribe(ret);
+ return JSU.S(ret.toString());
+ }
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());
+ String result = ret.toString();
+ Log.warn("dcc", ((Message)args[0]).summary() + ":\n " + result);
+ int body = 0;
+ int fuz1 = 0;
+ int fuz2 = 0;
+ int i_body = result.indexOf("Body=");
+ int i_fuz1 = result.indexOf("Fuz1=");
+ int i_fuz2 = result.indexOf("Fuz2=");
+ if (i_body != -1) try {
+ String s = result.substring(i_body+5);
+ if (s.indexOf(' ') != -1) s = s.substring(0, s.indexOf(' '));
+ if (s.indexOf('\n') != -1) s = s.substring(0, s.indexOf('\n'));
+ body = s.trim().equals("many") ? 999 : Integer.parseInt(s.trim());
+ } catch (Exception e) { Log.error("", e); }
+ if (i_fuz1 != -1) try {
+ String s = result.substring(i_fuz1+5);
+ if (s.indexOf(' ') != -1) s = s.substring(0, s.indexOf(' '));
+ if (s.indexOf('\n') != -1) s = s.substring(0, s.indexOf('\n'));
+ fuz1 = s.trim().equals("many") ? 999 : Integer.parseInt(s.trim());
+ } catch (Exception e) { Log.error("", e); }
+ if (i_fuz2 != -1) try {
+ String s = result.substring(i_fuz2+5);
+ if (s.indexOf(' ') != -1) s = s.substring(0, s.indexOf(' '));
+ if (s.indexOf('\n') != -1) s = s.substring(0, s.indexOf('\n'));
+ fuz2 = s.trim().equals("many") ? 999 : Integer.parseInt(s.trim());
+ } catch (Exception e) { Log.error("", e); }
+ JSArray jsa = new JSArray();
+ jsa.put(JSU.N(0), JSU.N(body));
+ jsa.put(JSU.N(1), JSU.N(fuz1));
+ jsa.put(JSU.N(2), JSU.N(fuz2));
+ return jsa;
}
if (name.equals("mail.drop")) {
return args.length==0 ? new Drop() : new Drop(JSU.toString(args[0]));
public void accept(Message m) throws MailException {
try {
Message m2 = m.bounce(JSU.toString(a));
- org.ibex.mail.SMTP.Outgoing.accept(m2);
+ org.ibex.mail.SMTP.Outgoing.enqueue(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.Fountain.StringFountain(m.toString()),
- m.envelopeFrom,
- new Address(JSU.toString(a)));
- org.ibex.mail.SMTP.Outgoing.accept(m2);
+ Message m2 = m.withEnvelope(m.envelopeFrom, new Address(JSU.toString(a)));
+ org.ibex.mail.SMTP.Outgoing.enqueue(m2);
} catch (Exception e) {
Log.warn(this, e);
throw new JSExn(e.toString());
return null;
}
if (name.equals("mail.forward") || name.equals("forward")) {
- Message m2 = Message.newMessage(Script.this.m, Script.this.m.envelopeFrom, new Address(JSU.toString(a)));
+ Message m2 = Script.this.m.withEnvelope(Script.this.m.envelopeFrom, new Address(JSU.toString(a)));
org.ibex.mail.SMTP.Outgoing.attempt(m2, false);
return Drop.instance;
}
}
}
-
}