bugfixes
[org.ibex.mail.git] / src / org / ibex / mail / protocol / Connection.java
1 package org.ibex.mail.protocol;
2 import org.ibex.mail.*;
3 import org.ibex.util.*;
4 import org.ibex.mail.target.*;
5 import java.util.*;
6 import java.net.*;
7 import java.text.*;
8 import java.io.*;
9
10 /** central place for logging conversations */
11 public abstract class Connection {
12
13     protected Socket conn;
14     protected String vhost;
15     protected PrintWriter pw;
16     protected InputStream is;
17     protected PushbackReader r;
18     protected LineReader lr;
19
20     private static String convdir;
21     static {
22         try {
23             convdir = System.getProperty("ibex.mail.root", File.separatorChar + "var" + File.separatorChar + "org.ibex.mail");
24             convdir += File.separatorChar + "conversation";
25             new File(convdir).mkdirs();
26         } catch (Exception e) {
27             Log.warn(Connection.class, e);
28         }
29     }
30
31     public Connection(Socket conn, String vhost) throws IOException {
32         this.vhost = vhost;
33         this.conn = conn;
34         this.pw = new PrintWriter(new OutputStreamWriter(conn.getOutputStream()));
35         this.is = conn.getInputStream();
36         Reader isr = new InputStreamReader(is);
37         this.r = new PushbackReader(isr);
38         this.lr = new LineReader(isr);
39     }
40
41     protected abstract boolean handleRequest() throws IOException;
42
43     private String cid;
44     private StringBuffer inbound = new StringBuffer();
45     private PrintWriter conversation;
46
47     public final boolean handle() throws IOException {
48         cid = getConversation();
49         Log.setThreadAnnotation("[conversation " + cid + "] ");
50         InetSocketAddress remote = (InetSocketAddress)conn.getRemoteSocketAddress();
51         Log.info(this, "connection from "+remote.getHostName()+":"+remote.getPort()+" ("+remote.getAddress()+")");
52         conversation = new PrintWriter(new OutputStreamWriter(new FileOutputStream(convdir + File.separatorChar + cid + ".txt")));
53         boolean ret = false;
54         try {
55             ret = handleRequest();
56             Log.setThreadAnnotation("");
57         } finally {
58             conversation.close();
59         }
60         return ret;
61     }
62
63     protected void println(String s) throws IOException {
64         if (inbound.length() > 0) { conversation.println("C: " + inbound.toString()); inbound.setLength(0); } 
65         conversation.println("S: " + s);
66         conversation.flush();
67         pw.print(s);
68         pw.print("\r\n");
69         pw.flush();
70     }
71     protected void flush() throws IOException { pw.flush(); }
72     protected String readln() throws IOException {
73         String line = lr.readLine();
74         conversation.println("C: " + line);
75         conversation.flush();
76         return line;
77     }
78     public char getc() throws IOException {
79         int ret = r.read();
80         if (ret == -1) throw new EOFException();
81         if (ret == '\n') {
82             if (inbound.length() > 0) { conversation.println("C: " + inbound.toString()); inbound.setLength(0); } }
83         else if (ret != '\r') inbound.append((char)ret);
84         conversation.flush();
85         return (char)ret;
86     }
87     public  char peekc() throws IOException {
88         int ret = r.read();
89         if (ret == -1) throw new EOFException();
90         r.unread(ret);
91         return (char)ret;
92     }
93     public  void fill(byte[] b) throws IOException {
94         int num = 0;
95         while (num < b.length) {
96             int numread = is.read(b, num, b.length - num);
97             if (numread == -1) throw new EOFException();
98             num += numread;
99         }
100     }
101
102     private static String lastTime = null;
103     private static int lastCounter = 0;
104     static String getConversation() {
105         String time = new SimpleDateFormat("yy.MMM.dd-hh:mm:ss").format(new Date());
106         synchronized (SMTP.class) {
107             if (lastTime != null && lastTime.equals(time)) time += "." + (++lastCounter);
108             else lastTime = time;
109         }
110         return time;
111     }
112
113 }