import java.util.*;
import java.io.*;
import java.net.*;
-//import org.prevayler.*;
-//import org.prevayler.Query;
import javax.servlet.*;
import javax.servlet.http.*;
}
public void banner(HttpServletRequest request, HttpServletResponse response) throws IOException {
- String basename = request.getServletPath();
+ String basename = request.getRequestURL()+"";
PrintWriter pw = new PrintWriter(response.getWriter());
+ /*
pw.println("<html>");
+ pw.println(" <head>");
+ pw.println(" <style>");
+ pw.println(" TH, TD, P, LI, BODY {");
+ pw.println(" font-family: helvetica, verdana, arial, sans-serif;");
+ pw.println(" font-size: 12px; ");
+ pw.println(" text-decoration:none; ");
+ pw.println(" }");
+ pw.println(" </style>");
+ pw.println(" </head>");
pw.println(" <body>");
+ */
String confirm = request.getParameter("confirm");
if (confirm != null) {
- Subscribe sub = (Subscribe)Confirmation.decode(confirm, Long.parseLong(properties.get("secret")), new Date());
+ Subscribe sub = (Subscribe)Confirmation.decode(confirm, secret, new Date());
String email = sub.email;
synchronized(this) {
- String path = this.path.getAbsolutePath() + File.separatorChar + "subscribers" + File.separatorChar + sub.email;
+ String path = this.path.getAbsolutePath() + File.separatorChar + "subscribers" + File.separatorChar+sub.email;
if (sub.un) new File(path).delete();
else {
Log.warn(null, "creating " + path);
}
pw.println(" <b>successfully "+sub.adj+"d " + email + " to " + properties.get("address"));
} else {
- pw.println(" <b>"+properties.get("address")+"</b><br>");
- pw.println(" <tt><a href="+properties.get("nntp")+">"+properties.get("nntp")+"</a></tt><br>");
String action = request.getParameter("action");
String email = request.getParameter("email");
if (action != null) {
Subscribe sub = new Subscribe(email, request.getRequestURL().toString(), action.equals("unsubscribe"));
- sub.signAndSend(new Address(properties.get("owner")), Long.parseLong(properties.get("secret")), new Date());
- pw.println("a confirmation email has been sent to " + email + "; click the enclosed link to confirm your request to " + action);
+ sub.signAndSend(new Address(properties.get("owner")),
+ secret, new Date());
+ pw.println("a confirmation email has been sent to " + email +
+ "; click the enclosed link to confirm your request to " + action);
} else {
- pw.println(" <form action='"+basename+"' method=post name=form1>");
+ pw.println("<table width=100% border=0 cellpadding=0 cellspacing=0><tr><td>");
+ pw.println(" <b>"+properties.get("address")+"</b><br> ");
+ pw.println(" <i>"+properties.get("description")+"</i> ");
+ pw.println("</td><td align=right>");
+ pw.println("<i>access via:</i> ");
+ if (path.getAbsolutePath().startsWith("/afs/"))
+ pw.println("<a target=_top href='file:" + path.getAbsolutePath() +"'>[AFS]</a> ");
+ pw.println("<a target=_top href="+properties.get("nntp")+">[NNTP]</a></tt>");
+ pw.println("<a target=_top href='mailto:"+properties.get("address")+"'>[SMTP]</a></tt>");
+ pw.println("<a target=_top href='"+request.getRequestURL()+"'>[HTTP]</a></tt>");
+ pw.println("</td></tr><tr><td colspan=2 align=right>");
+ pw.println(" <form action='"+basename+"' method=post name=form1 target=_top>");
pw.println(" <input type=text width=100 value='your@email.com' name=email>");
pw.println(" <input type=hidden name=frame value=banner>");
pw.println(" <select name=action onchange='form1.submit()'>");
pw.println(" <option>--choose action--</option>");
pw.println(" <option>subscribe</option>");
pw.println(" <option>unsubscribe</option>");
+ pw.println(" <option>preferences</option>");
pw.println(" </select>");
pw.println(" </form>");
+ pw.println("</td></tr></table>");
}
}
- pw.println(" </body>");
- pw.println("</html>");
+ //pw.println(" </body>");
+ //pw.println("</html>");
pw.flush();
- pw.close();
}
public class Subscribe extends Confirmation {
try {
if (conn.getLocalPort() == 143) new IMAP.Listener(auth).handleRequest(conn);
else if (conn.getLocalPort() == 25) new SMTP.Server().handleRequest(conn);
- else if (conn.getLocalPort() == 8080) new SMTP.Server().handleRequest(conn);
+ else if (conn.getLocalPort() == 8080) new SMTP.Server().handleRequest(conn);
else if (conn.getLocalPort() == 119) new NNTP.Listener(auth).handleRequest(conn);
//else if (conn.getLocalPort() == 110) new POP3.Listener(auth).handleRequest(conn);
- else if (conn.getLocalPort() == 8099) GMail.handleRequest(conn);
- // else if (conn.getLocalPort() == 8080) Jetty.instance().accept(conn);
- //else if (conn.getLocalPort() == 443) Jetty.instance().accept(conn);
- //else if (conn.getLocalPort() == 80) Jetty.instance().accept(conn);
+ //else if (conn.getLocalPort() == 8099) GMail.handleRequest(conn);
else return false;
return true;
} finally {
private static final Auth auth = new Auth();
private static class Auth implements Login {
- public Account anonymous() { return null; }
- public Object login(String user, String pass, Class protocol) {
- //if (protocol == IMAP.class && user.endsWith("@gmail.com")) return GMail.getGMail(user, pass).getIMAP();
- return login(user, pass);
+ public Account anonymous() {
+ final Mailbox root =
+ FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT + "/user", true);
+ return new Account("anonymous", null, root.slash("anonymous", true)){
+ public Mailbox getMailbox(Class protocol) {
+ return super.getMailbox(protocol);
+ }
+ };
}
+ public Object login(String user, String pass, Class protocol) { return login(user, pass); }
public Account login(String user, String pass) {
- //if (user.indexOf("@gmail.com") != -1) return GMail.getGMail(user, pass);
if (!EtcPasswd.verify(user, pass)) return null;
final Mailbox root =
FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT + "/user", true);
return new Account(user, null, root.slash(user, true)){
public Mailbox getMailbox(Class protocol) {
- //if (protocol == IMAP.class) return super.getMailbox(protocol).slash("newmail", false).slash("pending", false);
- /*
- if (protocol == NNTP.class) {
- final Mailbox arch = new MailmanArchives();
- return new Mailbox.Default() {
- public void add(Message m) { throw new RuntimeException("not supported"); }
- public void add(Message m, int i) { throw new RuntimeException("not supported"); }
- public int uidValidity() { return 1; }
- public Mailbox.Iterator iterator() { return null; }
- public int uidNext() { return 0; }
- public String[] children() { return new String[] { "us" }; }
- public Mailbox slash(String name, boolean create) { return arch; }
- };
- } else {
- */
- return super.getMailbox(protocol);
- //}
+ return super.getMailbox(protocol);
}
};
}
public boolean ihave(String messageid);
public Article next();
public Article last();
- public boolean post(Message m);
+ public boolean postok();
+ public void post(Message m) throws IOException;
public Article article(String messageid, boolean head, boolean body);
public Article article(int messagenum, boolean head, boolean body);
public Group[] list();
private final Mailbox root;
private Mailbox current;
private int ptr = 0;
- public MailboxWrapper(Mailbox root) { this.root = root; }
+ private boolean post;
+ public MailboxWrapper(Mailbox root) { this(root, false); }
+ public MailboxWrapper(Mailbox root, boolean post) { this.root = root; this.post = post; }
+ public boolean postok() { return post; }
+ public void post(Message m) throws IOException { current.accept(m); }
+
public Group group(String s) {
ptr = 0;
Group g = getgroup(s);
}
public boolean ihave(String messageid) { /* FEATURE */ return false; }
- public boolean post(Message m) { /* FEATURE */ return false; }
public Article next() { return article(ptr++, false, false); }
public Article last() { return article(ptr--, false, false); }
String user = null;
String pass = null;
Account account = login.anonymous();
- this.api = account == null ? null : new MailboxWrapper(account.getMailbox(NNTP.class));
+ this.api = account == null ? null : new MailboxWrapper(account.getMailbox(NNTP.class), true);
for(String line = conn.readln(); line != null; line = conn.readln()) try {
Log.warn("[nntp-read]", line);
StringTokenizer st = new StringTokenizer(line, " ");
if (pass == null) { println("381 Password required"); continue; }
account = login.login(user, pass);
if (account == null) { println("502 Invalid"); continue; }
- this.api = new MailboxWrapper(account.getMailbox(NNTP.class));
+ Mailbox box = account.getMailbox(NNTP.class);
+ this.api = new MailboxWrapper(box, true);
println("281 Good to go");
continue;
}
// newgroup <groupname> [moderated] -- body of message is a description of the group
// rmgroup <groupname>
- /*
- boolean postok = api.post();
+ boolean postok = api.postok();
if (!postok) {
println("440 no posting allowed");
} else {
- */
- println("340 send the article");
- // FIME read the article here
- println("240 article posted ok");
- //}
+ println("340 send the article");
+ StringBuffer buf = new StringBuffer();
+ while(true) {
+ String s = conn.readln();
+ if (s == null) throw new RuntimeException("connection closed");
+ if (s.equals(".")) break;
+ if (s.startsWith(".")) s = s.substring(1);
+ buf.append(s + "\r\n");
+ }
+ String body = buf.toString();
+ try {
+ api.post(Message.newMessage(new Fountain.StringFountain(body)));
+ println("240 article posted ok");
+ } catch (Exception e) {
+ e.printStackTrace();
+ println("441 posting failed: " + e);
+ }
+ }
} else if (command.equals("XROVER")) {
// equivalent to "XHDR References"
String remotehost = null;
for(String command = conn.readln(); ; command = conn.readln()) try {
if (command == null) return;
- Log.warn(conn.getRemoteAddress()+"", command);
+ Log.warn("**"+conn.getRemoteAddress()+"**", command);
String c = command.toUpperCase();
if (c.startsWith("HELO")) {
remotehost = c.substring(5).trim();
command = command.substring(8).trim();
if(command.indexOf(' ') != -1) command = command.substring(0, command.indexOf(' '));
Address addr = new Address(command);
+ /*
+ Log.warn("**"+conn.getRemoteAddress()+"**",
+ "addr.isLocal(): " + addr.isLocal() + "\n" +
+ "conn.getRemoteAddress().isLoopbackAddress(): " + conn.getRemoteAddress().isLoopbackAddress() + "\n" +
+ "johnw: " + (from!=null&&from.toString().indexOf("johnw")!=-1) + "\n"
+ );
+ */
if (addr.isLocal()) {
// FEATURE: should check the address further and give 550 if undeliverable
conn.println("250 " + addr + " is on this machine; I will deliver it");
ret = new InetAddress[1];
try {
ret[0] = InetAddress.getByName(hostName);
+ if (ret[0].equals(IP.getIP(127,0,0,1)) || ret[0].isLoopbackAddress()) throw new UnknownHostException();
return ret;
} catch (UnknownHostException uhe) {
Log.warn(SMTP.class, "no MX hosts or A record for " + hostName);
mx = mx.substring(mx.indexOf(" ") + 1);
if (mx.charAt(mx.length() - 1) == '.') mx = mx.substring(0, mx.length() - 1);
InetAddress ia = InetAddress.getByName(mx);
- if (ia.equals(IP.getIP(127,0,0,1))) continue;
+ if (ia.equals(IP.getIP(127,0,0,1)) || ia.isLoopbackAddress()) continue;
ret[i++] = ia;
}
}
PrintWriter pw = new PrintWriter(response.getWriter());
pw.println("<html>");
if (top) {
- pw.println(" <frameset rows='10%,30%,*'>");
- pw.println(" <frame src='"+basename+"?frame=banner' marginwidth=0 marginheight=0 name=banner/>");
- pw.println(" <frame src='"+basename+"?frame=top' marginwidth=0 marginheight=0 name=top/>");
+ pw.println(" <frameset rows='30%,*'>");
+ //pw.println(" <frame src='"+basename+"?frame=banner' marginwidth=0 marginheight=0 name=banner/>");
+ //pw.println(" <frame src='"+basename+"?frame=top' marginwidth=0 marginheight=0 name=top/>");
+ pw.println(" <frame src='"+basename+"?frame=topright' marginwidth=0 marginheight=0 name=topright/>");
pw.println(" <frame src='"+basename+"?frame=bottom' marginwidth=0 marginheight=0 name='bottom'/>");
} else {
pw.println(" <frameset cols='150,*'>");
throws IOException {
PrintWriter pw = new PrintWriter(response.getWriter());
pw.println("<html>");
+ pw.println(" <head>");
+ pw.println(" <style>");
+ pw.println(" body { margin: 10px; }");
+ pw.println(" pre {");
+ pw.println(" font-family: monospace;");
+ pw.println(" background-color: #F0F0E0;");
+ pw.println(" color: rgb(0, 0, 0);");
+ pw.println(" padding: 5px;");
+ pw.println(" margin: 0px;");
+ pw.println(" overflow: auto;");
+ //pw.println(" width: 80%;");
+ //pw.println(" border-style: solid;");
+ //pw.println(" border-width: 1px;");
+ pw.println(" }");
+ pw.println(" </style>");
+ pw.println(" </head>");
pw.println(" <body>");
- pw.println(" <pre>");
if (request.getParameter("msgnum") != null) {
int target = Integer.parseInt(request.getParameter("msgnum"));
- for(Mailbox.Iterator it = mbox.iterator(); it.next();) {
- if (it.num() == target) {
- StringBuffer tgt = new StringBuffer();
- it.cur().getBody().getStream().transcribe(tgt);
- pw.println(tgt.toString());
+ Mailbox.Iterator it = mbox.iterator();
+ while(it.next())
+ if (it.num() == target)
break;
+ if (it.cur() != null) {
+ pw.println(" <table width=100% border=0 cellspacing=0 style='border: 1px black solid; background-color:#F0F0E0;'>");
+ pw.println(" <tr style='border: 1px black solid; font-family: monospace'><td style='padding: 5px'>");
+ Headers h = it.cur().headers;
+ pw.println(" Subject: " + it.cur().subject +"<br>");
+ pw.println(" From: " + it.cur().from +"<br>");
+ pw.println(" Date: " + it.cur().date +"<br>");
+ /*
+ for(java.util.Enumeration e = h.names(); e.hasMoreElements();) {
+ String key = (String)e.nextElement();
+ if (key==null || key.length()==0 || key.equals("from") ||
+ key.equals("to") || key.equals("subject") || key.equals("date")) continue;
+ key = Character.toUpperCase(key.charAt(0)) + key.substring(1);
+ String val = h.get(key);
+ for(int i=key.length(); i<15; i++)pw.print(" ");
+ pw.print(key+": ");
+ pw.println(val);
}
+ */
+ pw.print("</td></tr><tr><td style='border-top: 1px black; border-top-style: dotted;'><pre>");
+ StringBuffer tgt = new StringBuffer();
+ it.cur().getBody().getStream().transcribe(tgt);
+ pw.println(tgt.toString());
+ pw.println(" </pre></td></tr></table>");
}
}
- pw.println(" </pre>");
pw.println(" </body>");
pw.println("</html>");
pw.flush();
pw.println("<html>");
pw.println(" <head>");
pw.println(" <style>");
+ pw.println(" TH, TD, P, LI {");
+ pw.println(" font-family: helvetica, verdana, arial, sans-serif;");
+ pw.println(" font-size: 12px; ");
+ pw.println(" text-decoration:none; ");
+ pw.println(" }");
+ pw.println(" body { margin: 10px; }");
pw.println(" a:link { color: #000; text-decoration: none; }");
pw.println(" a:active { color: #f00; text-decoration: none; }");
pw.println(" a:visited { color: #777; text-decoration: none; }");
pw.println(" }");
pw.println(" function choose(who) {");
pw.println(" who.style.background = '#ffc';");
- pw.println(" if (chosen != null) chosen.style.background = '#aaa';");
+ pw.println(" if (chosen != null) chosen.style.background = '#ccc';");
pw.println(" parent.parent.bottom.location='"+basename+"?frame=bottom&msgnum='+who.id;");
pw.println(" chosen = who;");
pw.println(" }");
pw.println(" </script>");
- pw.println(" <table width=100% border=0 cellpadding=0 cellspacing=0>");
- boolean odd=false;
+ pw.println(" <div style='border: 1px black solid;'><table width=100% border=0 cellpadding=0 cellspacing=0>");
+ pw.println(" <tr><td style='padding: 4px' bgcolor=#eff7ff>");
+ pw.flush();
+ banner(request, response);
+ pw.println(" </td></tr>");
+ pw.println(" <tr><td>");
+ pw.println(" <table width=100% cellpadding=0 cellspacing=0 style='border-top: 1px black solid; cursor:pointer;'>");
+ boolean odd=true;
for(int i=0; i<messages.length; i++) {
odd = !odd;
String[] m = messages[i];
- pw.println(" <tr style='background: "+(odd?"#e8eef7":"white")+"' id='"+m[3]+"' "+
+ pw.println(" <tr style='cursor:pointer; background: "+(odd?"#e8eef7":"white")+"' id='"+m[3]+"' "+
"onmouseover='this.style.color=\"blue\"' "+
"onmouseout='this.style.color=\"black\"' "+
"onclick='choose(this);'>");
- pw.println("<td style='padding:5px; padding-bottom:2px'>"+m[0]+"</td>");
- pw.println("<td style='padding:5px; padding-bottom:2px'>"+m[1]+"</td>");
- pw.println("<td style='padding:5px; padding-bottom:2px'>"+m[2]+"</td>");
+ pw.println("<td style='cursor:pointer; padding:5px; padding-bottom:2px'>"+m[0]+"</td>");
+ pw.println("<td style='cursor:pointer; padding:5px; padding-bottom:2px'>"+m[1]+"</td>");
+ pw.println("<td style='cursor:pointer; padding:5px; padding-bottom:2px'>"+m[2]+"</td>");
pw.println("</tr>");
pw.println("<script> all["+i+"] = document.getElementById('"+i+"'); </script>");
- pw.println("<tr height=1 bgcolor=black><td colspan=3>");
- pw.println(" <img src=http://www.xwt.org/images/clearpixel.gif></td></tr>");
}
pw.println(" </table>");
+ pw.println(" </td></tr>");
+ pw.println(" </table></div>");
pw.println(" </body>");
pw.println("</html>");
pw.flush();