davmail/src/java/davmail/pop/PopConnection.java

215 lines
8.8 KiB
Java

package davmail.pop;
import davmail.AbstractConnection;
import davmail.DavGatewayTray;
import davmail.exchange.ExchangeSession;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;
import java.io.IOException;
/**
* Dav Gateway pop connection implementation
*/
public class PopConnection extends AbstractConnection {
protected static final int INITIAL = 0;
protected static final int USER = 1;
protected static final int AUTHENTICATED = 2;
private List<ExchangeSession.Message> messages;
// Initialize the streams and start the thread
public PopConnection(Socket clientSocket) {
super(clientSocket);
}
public long getTotalMessagesLength() {
int result = 0;
for (ExchangeSession.Message message : messages) {
result += message.size;
}
return result;
}
public void printList() throws IOException {
int i = 1;
for (ExchangeSession.Message message : messages) {
sendClient(i++ + " " + message.size);
}
sendClient(".");
}
public void printUidList() throws IOException {
int i = 1;
for (ExchangeSession.Message message : messages) {
sendClient(i++ + " " + message.uid);
}
sendClient(".");
}
public void run() {
String line;
StringTokenizer tokens;
try {
sendOK("DavMail POP ready at " + new Date());
for (; ;) {
line = readClient();
// unable to read line, connection closed ?
if (line == null) {
break;
}
tokens = new StringTokenizer(line);
if (tokens.hasMoreTokens()) {
String command = tokens.nextToken();
if ("QUIT".equalsIgnoreCase(command)) {
// delete messages before quit
session.purgeOldestTrashMessages();
sendOK("Bye");
break;
} else if ("USER".equalsIgnoreCase(command)) {
userName = null;
password = null;
session = null;
if (tokens.hasMoreTokens()) {
userName = tokens.nextToken();
sendOK("USER : " + userName);
state = USER;
} else {
sendERR("invalid syntax");
state = INITIAL;
}
} else if ("PASS".equalsIgnoreCase(command)) {
if (state != USER) {
sendERR("invalid state");
state = INITIAL;
} else if (!tokens.hasMoreTokens()) {
sendERR("invalid syntax");
} else {
password = tokens.nextToken();
try {
session = new ExchangeSession();
session.login(userName, password);
messages = session.getAllMessages();
sendOK("PASS");
state = AUTHENTICATED;
} catch (UnknownHostException e) {
DavGatewayTray.error("Connection failed",e);
sendERR("Connection failed : "+e+" "+e.getMessage());
// close connection
break;
} catch (Exception e) {
DavGatewayTray.error("Authentication failed",e);
sendERR("authentication failed : "+e+" "+e.getMessage());
}
}
} else if ("CAPA".equalsIgnoreCase(command)) {
sendERR("unknown command");
} else if (state != AUTHENTICATED) {
sendERR("invalid state not authenticated");
} else {
if ("STAT".equalsIgnoreCase(command)) {
sendOK(messages.size() + " " +
getTotalMessagesLength());
} else if ("LIST".equalsIgnoreCase(command)) {
sendOK(messages.size() +
" messages (" + getTotalMessagesLength() +
" octets)");
printList();
} else if ("UIDL".equalsIgnoreCase(command)) {
sendOK(messages.size() +
" messages (" + getTotalMessagesLength() +
" octets)");
printUidList();
} else if ("RETR".equalsIgnoreCase(command)) {
if (tokens.hasMoreTokens()) {
try {
int messageNumber = Integer.valueOf(tokens.
nextToken()) - 1;
sendOK("");
messages.get(messageNumber).write(os);
sendClient("");
sendClient(".");
} catch (Exception e) {
DavGatewayTray.error("Error retreiving message",e);
sendERR("error retreiving message " + e.getMessage());
}
} else {
sendERR("invalid message number");
}
} else if ("DELE".equalsIgnoreCase(command)) {
if (tokens.hasMoreTokens()) {
try {
int messageNumber = Integer.valueOf(tokens.
nextToken()) - 1;
messages.get(messageNumber).delete();
sendOK("DELETE");
} catch (Exception e) {
DavGatewayTray.error("Error deleting message",e);
sendERR("error deleting message");
}
} else {
sendERR("invalid message number");
}
} else if ("TOP".equalsIgnoreCase(command)) {
try {
int firstMessage = Integer.valueOf(tokens.
nextToken()) - 1;
int lastMessage = Integer.valueOf(tokens.
nextToken()) - 1;
for (int i = firstMessage; i <= lastMessage; i++) {
messages.get(i).printHeaders(os);
sendClient("");
sendClient(".");
}
sendOK("TOP");
} catch (Exception e) {
sendERR("error retreiving top of messages");
}
} else if ("RSET".equalsIgnoreCase(command)) {
sendOK("RSET");
} else {
sendERR("unknown command");
}
}
} else {
sendERR("unknown command");
}
os.flush();
}
} catch (IOException e) {
DavGatewayTray.error("Exception handling client",e);
} finally {
try {
client.close();
} catch (IOException e2) {
DavGatewayTray.debug("Exception closing client",e2);
}
try {
if (session != null) {
session.close();
}
} catch (IOException e3) {
DavGatewayTray.debug("Exception closing gateway",e3);
}
}
DavGatewayTray.resetIcon();
}
public void sendOK(String message) throws IOException {
sendClient("+OK ", message);
}
public void sendERR(String message) throws IOException {
sendClient("-ERR ", message);
}
}