// set up logging
String logto = System.getProperty("ibex.mail.root", File.separatorChar + "var" + File.separatorChar + "org.ibex.mail");
logto += File.separatorChar + "log";
- Log.file(logto);
+
+ //Log.file(logto);
+ Log.color = true;
new IMAPThread().start();
new SMTPThread().start();
}
private static class BogusAuthenticator implements IMAP.Server.Authenticator {
- final Mailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true);
+ final Mailbox root =
+ FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true).slash("user", true).slash("megacz", true);
public Mailbox authenticate(String u, String p) {
if (u.equals("megacz") && p.equals("pass")) return root;
return null;
package org.ibex.mail;
import java.util.*;
import org.ibex.mail.target.*;
+import org.ibex.util.*;
/**
* [immutable] This class encapsulates a query against a mailbox.
InetSocketAddress remote = (InetSocketAddress)conn.getRemoteSocketAddress();
Log.info(this, "connection from "+remote.getHostName()+":"+remote.getPort()+" ("+remote.getAddress()+")");
conversation = new PrintWriter(new OutputStreamWriter(new FileOutputStream(convdir + File.separatorChar + cid + ".txt")));
- boolean ret = handleRequest();
- Log.setThreadAnnotation("");
- conversation.close();
+ boolean ret = false;
+ try {
+ ret = handleRequest();
+ Log.setThreadAnnotation("");
+ } finally {
+ conversation.close();
+ }
return ret;
}
protected void println(String s) throws IOException {
+ if (inbound.length() > 0) { conversation.println("C: " + inbound.toString()); inbound.setLength(0); }
conversation.println("S: " + s);
+ conversation.flush();
pw.print(s);
pw.print("\r\n");
pw.flush();
protected String readln() throws IOException {
String line = lr.readLine();
conversation.println("C: " + line);
+ conversation.flush();
return line;
}
public char getc() throws IOException {
int ret = r.read();
if (ret == -1) throw new EOFException();
- if (ret == '\n') { if (inbound.length() > 0) { conversation.println("C: " + inbound.toString()); inbound.setLength(0); } }
+ if (ret == '\n') {
+ if (inbound.length() > 0) { conversation.println("C: " + inbound.toString()); inbound.setLength(0); } }
else if (ret != '\r') inbound.append((char)ret);
+ conversation.flush();
return (char)ret;
}
public char peekc() throws IOException {
String[] headers = null;
int start = -1, end = -1;
StringBuffer r = new StringBuffer();
- if (e) { r.append(num); r.append(" FETCH ("); }
+ if (e) { r.append(uid ? muid : num); r.append(" FETCH ("); }
int initlen = r.length();
if (uid) {
boolean good = false;
} else {
if (s.equalsIgnoreCase("BODY.PEEK")) spec |= PEEK;
else if (e) api.addFlags(Query.num(new int[] { num, num }), Mailbox.Flag.SEEN, false, false);
- if (i<t.length - 1 && (t[i+1].type == Token.LIST)) {if (e){r.append(" ");r.append(qq(m.body));} continue; }
+ if (!(i<t.length - 1 && (t[i+1].type == Token.LIST)))
+ {if (e){r.append(" ");r.append(qq(m.body));} continue; }
String payload = "";
r.append("[");
Token[] list = t[++i].l();
if (e) { r.append(" "); r.append(qq(payload)); }
}
}
- if (e) { r.append(")"); star(r.toString()); } else api.fetch(q, spec, headers, start, end, uid);
+ if (e) {
+ r.append(")");
+ star(r.toString());
+ } else {
+ api.fetch(q, spec, headers, start, end, uid);
+ }
}
private String headers(StringBuffer r, String[] headers, boolean negate, Message m, boolean e) {
case EXPUNGE: selected(); api.expunge(); break;
case UNSELECT: selected(); api.unselect(); selected = false; break;
case CREATE: api.create(token().astring()); break;
- case FETCH: selected(); lastuid=uid; fetch(Query.set(uid, token().set()), lastfetch = token().l(), 0, 0, 0, uid, 0); break;
+ case FETCH: selected(); fetch(Query.set(lastuid=uid, token().set()),
+ lastfetch=token().l(), 0, 0, 0, uid, 0); break;
case SEARCH: selected(); star("SEARCH " + Printer.join(api.search(query(), uid))); break;
case SELECT: {
String mailbox = token().astring();
StringTokenizer st = new StringTokenizer(s, ",");
while(st.hasMoreTokens()) {
String s = st.nextToken();
- if (s.indexOf(':') == -1) { ids.addElement(Integer.parseInt(s));ids.addElement(Integer.parseInt(s));continue; }
+ if (s.indexOf(':') == -1) {
+ ids.addElement(Integer.parseInt(s));
+ ids.addElement(Integer.parseInt(s));
+ continue; }
int start = Integer.parseInt(s.substring(0, s.indexOf(':')));
String end_s = s.substring(s.indexOf(':')+1);
if (end_s.equals("*")) { ids.addElement(start); ids.addElement(Integer.MAX_VALUE); }
else {
int end = Integer.parseInt(end_s);
- for(int j=Math.min(start,end); j<=Math.min(start,end); j++)
+ for(int j=Math.min(start,end); j<=Math.max(start,end); j++) {
ids.addElement(j);
+ ids.addElement(j);
+ }
}
}
return ids.dump();
return new Token(sb.toString(), false);
getc();
}
- } catch (IOException e) { e.printStackTrace(); } return null; }
+ } catch (IOException e) { Log.warn(this, e); } return null; }
}
public static class Printer {
println("250 " + (from = new Address(command.substring(10).trim())) + " is syntactically correct");
} else if (c.startsWith("RCPT TO:")) {
if (from == null) { println("503 MAIL FROM must precede RCPT TO"); continue; }
- command = command.substring(9).trim();
+ command = command.substring(8).trim();
if(command.indexOf(' ') != -1) command = command.substring(0, command.indexOf(' '));
Address addr = new Address(command);
InetAddress[] mx = getMailExchangerIPs(addr.host);
Log.setThreadAnnotation("[outgoing smtp] ");
Log.info(SMTP.Outgoing.class, "outgoing thread started; " + spool.count(Query.all()) + " messages to send");
while(true) {
- for(Mailbox.Iterator it = spool.iterator(); it.cur() != null; it.next())
+ for(Mailbox.Iterator it = spool.iterator(); it.next(); )
try { if (attempt(it.cur())) it.delete(); }
catch (IOException e) { Log.error(SMTP.Outgoing.class, e); }
synchronized(Outgoing.class) {
public synchronized void add(Message message) { add(message, Mailbox.Flag.RECENT); }
public synchronized void add(Message message, int flags) {
try {
- // FIXME: set flags
int num = new File(path).list(filter).length;
- File target = new File(path + slash + uidNext(true) + ".");
+ String name = path + slash + uidNext(true) + "." +
+ ((flags & Mailbox.Flag.DELETED) == Mailbox.Flag.DELETED ? "x" : "") +
+ ((flags & Mailbox.Flag.DRAFT) == Mailbox.Flag.DRAFT ? "d" : "") +
+ ((flags & Mailbox.Flag.RECENT) == Mailbox.Flag.RECENT ? "r" : "") +
+ ((flags & Mailbox.Flag.ANSWERED) == Mailbox.Flag.ANSWERED ? "a" : "") +
+ ((flags & Mailbox.Flag.FLAGGED) == Mailbox.Flag.FLAGGED ? "f" : "") +
+ ((flags & Mailbox.Flag.SEEN) == Mailbox.Flag.SEEN ? "s" : "");
+ File target = new File(name);
File f = new File(target.getCanonicalPath() + "-");
FileOutputStream fo = new FileOutputStream(f);
message.dump(fo);
public Iterator() { names = new File(path).list(filter); }
public Message cur() {
+ if (cur >= names.length) return null;
try {
File file = new File(path + File.separatorChar + names[cur]);
return new Message(null, null, new LineReader(new InputStreamReader(new FileInputStream(file))));
if (name.equals("mail")) { return getSub("mail"); }
if (name.equals("mail.my")) { return getSub("mail.my"); }
if (name.equals("mail.my.prefs")) { return prefs; }
- //if (name.equals("mail.my.mailbox")) { return Mailbox.getForUser("megacz"); }
+ if (name.equals("mail.my.mailbox")) {
+ return FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true).slash("user", true).slash("megacz", true).slash("newmail", true);
+ }
return super.get(name);
}