public final Address[] cc;
public final Address[] bcc;
public final Hashtable[] resent;
- public Trace[] traces;
+ public final Trace[] traces;
public final Address envelopeFrom;
public final Address[] envelopeTo;
- public Date arrival = null; // when the message first arrived at this machine
+ public final Date arrival = null; // when the message first arrived at this machine
public void dump(OutputStream os) throws IOException {
Writer w = new OutputStreamWriter(os);
}
public static class Malformed extends MailException.Malformed { public Malformed(String s) { super(s); } }
- public Message(LineReader rs) throws IOException, Malformed {
+ public Message(Address envelopeFrom, Address envelopeTo, LineReader rs) throws IOException, Malformed {
+ this.envelopeFrom = envelopeFrom;
+ this.envelopeTo = envelopeTo;
+ this.arrival = new Date();
+ this.headers = new Hashtable();
String key = null;
StringBuffer all = new StringBuffer();
- replyto = null;
- subject = null;
- messageid = null;
- cc = null;
- bcc = null;
- resent = null;
- traces = null;
- envelopeFrom = null;
- envelopeTo = null;
-
- headers = new Hashtable();
- date = null; // FIXME
- to = null;
- from = null;
+ Date date = null;
+ Address to = null, from = null, replyto = null;
+ String subject = null, messageid = null;
+ Vec cc = new Vec(), bcc = new Vec(), resent = new Vec(), traces = new Vec();
for(String s = rs.readLine(); s != null && !s.equals(""); s = rs.readLine()) {
all.append(s);
all.append("\r\n");
for(int i=0; i<s.length(); i++)
if (s.charAt(i) < 33 || s.charAt(i) > 126)
throw new Malformed("Header key contains invalid character \"" + s.charAt(i) + "\"");
- String val = s.substring(0, s.indexOf(':') + 1);
+ String val = s.substring(0, s.indexOf(':'));
while(Character.isSpace(val.charAt(0))) val = val.substring(1);
-
- if (headers.get(key) != null)
- if (key.startsWith("Resent-")) {
- // FIXME: multi-resent headers
-
- } else if (key.startsWith("Return-Path:")) {
- rs.pushback(s);
- Trace t = new Trace(rs);
- Trace[] newTraces = new Trace[traces == null ? 1 : traces.length + 1];
- if (traces != null) System.arraycopy(traces, 0, newTraces, 0, traces.length);
- traces = newTraces;
- traces[traces.length-1] = t;
-
- } else {
- // just append it to the previous one; valid for Comments/Keywords
- val = headers.get(key) + " " + val;
- }
-
- headers.put(key, val);
+ if (key.startsWith("Resent-")) {
+ if (key.startsWith("Resent-From")) resent.addElement(new Hashtable());
+ ((Hashtable)resent.lastElement()).put(key.substring(7), val);
+ } else if (key.startsWith("Return-Path:")) {
+ rs.pushback(s); traces.addElement(new Trace(rs));
+ } else {
+ // just append it to the previous one; valid for Comments/Keywords
+ if (headers.get(key) != null) val = headers.get(key) + " " + val;
+ headers.put(key, val);
+ }
}
+ this.date = headers.get("Date");
+ this.to = new Address((String)headers.get("To"));
+ this.from = new Address((String)headers.get("From"));
+ this.replyto = new Address((String)headers.get("Reply-To"));
+ this.subject = (String)headers.get("Subject");
+ this.messageid = (String)headers.get("Message-Id");
+ if (headers.get("Cc") != null) {
+ StringTokenizer st = new StringTokenizer((String)headers.get("Cc"));
+ this.cc = new Address[st.countTokens()];
+ for(int i=0; i<cc.length; i++) cc[i] = st.nextToken();
+ } else {
+ this.cc = new Address[0];
+ }
+ if (headers.get("Bcc") != null) {
+ StringTokenizer st = new StringTokenizer((String)headers.get("Bcc"));
+ this.bcc = new Address[st.countTokens()];
+ for(int i=0; i<bcc.length; i++) bcc[i] = st.nextToken();
+ } else {
+ this.bcc = new Address[0];
+ }
+ resent.copyInto(this.resent = new Hashtable[resent.size()]);
+ traces.copyInto(this.traces = new Trace[traces.size()]);
allHeaders = all.toString();
StringBuffer body = new StringBuffer();
for(String s = rs.readLine();; s = rs.readLine()) { if (s == null) break; else body.append(s + "\r\n"); }
}
// http://www.jwz.org/doc/mid.html
+ private static final Random random = new Random();
public static String generateFreshMessageId() {
StringBuffer ret = new StringBuffer();
ret.append('<');
return ret.toString();
}
- private static final Random random = new Random();
-
public String summary() {
return
" Subject: " + m.subject + "\n" +
public Message bounce(String reason) {
// use null-sender for error messages (don't send errors to the null addr)
// FIXME
- return null;
+ throw new RuntimeException("bounce not implemented");
}
}