| /* |
| * Copyright 2004,2005 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| package org.apache.axis2.transport.mail.server; |
| |
| import org.apache.axis2.context.ConfigurationContext; |
| import org.apache.axis2.transport.mail.Constants; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| |
| import javax.mail.Authenticator; |
| import javax.mail.Message; |
| import javax.mail.MessagingException; |
| import javax.mail.PasswordAuthentication; |
| import javax.mail.Session; |
| import javax.mail.internet.MimeMessage; |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.io.OutputStreamWriter; |
| import java.net.Socket; |
| import java.util.ArrayList; |
| import java.util.Properties; |
| |
| public class SMTPWorker extends Thread { |
| private BufferedReader reader = null; |
| private BufferedWriter writer = null; |
| private boolean transmitionEnd = false; |
| private String temp = ""; |
| private Storage st = null; |
| boolean runThread = true; |
| private ArrayList receivers = new ArrayList(); |
| private MimeMessage mail = null; |
| private static final Log log = LogFactory.getLog(SMTPWorker.class); |
| private boolean dataWriting = false; |
| private ConfigurationContext configurationContext = null; |
| private boolean bodyData = false; |
| private boolean actAsMailet = false; |
| |
| public SMTPWorker(Socket socket, Storage st) { |
| doWork(socket, st, null); |
| } |
| |
| public SMTPWorker(Socket socket, Storage st, ConfigurationContext configurationContext) { |
| doWork(socket, st, configurationContext); |
| } |
| |
| private void doWork(Socket socket, Storage st, ConfigurationContext configurationContext) { |
| try { |
| this.st = st; |
| |
| if (configurationContext == null) { |
| actAsMailet = false; |
| } else { |
| this.configurationContext = configurationContext; |
| actAsMailet = true; |
| } |
| |
| // get the streams from the socket and save in instance variables. |
| reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); |
| writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); |
| } catch (IOException ex) { |
| log.info(ex.getMessage()); |
| } |
| } |
| |
| // transmission is over. setting to exit |
| private void exitWorker() throws IOException { |
| reader.close(); |
| writer.close(); |
| runThread = false; |
| } |
| |
| // initializing the client by sending the initial message. |
| private void initializeClient() throws IOException { |
| if (writer != null) { |
| send("220 SMTP Server IS UP"); |
| } |
| } |
| |
| private String processInput(String input) { |
| if (input == null) { |
| return Constants.COMMAND_UNKNOWN; |
| } |
| |
| if ((mail != null) && transmitionEnd) { |
| return Constants.COMMAND_TRANSMISSION_END; |
| } |
| |
| if (input.startsWith("MAIL")) { |
| mail = new MimeMessage(Session.getInstance(new Properties(), new Authenticator() { |
| protected PasswordAuthentication getPasswordAuthentication() { |
| return null; |
| } |
| })); |
| |
| int start = input.indexOf("<") + 1; |
| int end; |
| |
| if (start <= 0) { |
| start = input.indexOf("FROM:") + 5; |
| end = input.length(); |
| } else { |
| end = input.indexOf(">"); |
| } |
| |
| String from = input.substring(start, end); |
| |
| if ((from != null) && from.trim().length() != 0) { |
| |
| // TODO this is an ugly hack to get the from address in. There |
| // should be a better way to do this. |
| MailAddress mailFrom[] = new MailAddress[1]; |
| |
| mailFrom[0] = new MailAddress(from); |
| |
| try { |
| mail.addFrom(mailFrom); |
| } catch (MessagingException e) { |
| log.info(e.getMessage()); |
| } |
| } |
| |
| return Constants.MAIL_OK; |
| } |
| |
| if (input.startsWith("HELO")) { |
| return Constants.HELO_REPLY; |
| } else if (input.startsWith("RCPT")) { |
| |
| int start = input.indexOf("<") + 1; |
| int end; |
| |
| if (start <= 0) { |
| start = input.indexOf("TO:") + 3; |
| /* |
| * if(!input.endsWith(domain)){ System.out.println("ERROR: wrong |
| * donmain name"); return Constants.RCPT_ERROR; } |
| */ |
| } else { |
| |
| /* |
| * if(!input.endsWith(domain + ">")){ System.out.println("ERROR: |
| * wrong donmain name"); return Constants.RCPT_ERROR; } |
| */ |
| } |
| |
| end = input.indexOf(">"); |
| |
| String toStr = input.substring(start, end); |
| |
| try { |
| mail.addRecipient(Message.RecipientType.TO, new MailAddress(toStr)); |
| receivers.add(toStr); |
| } catch (MessagingException e) { |
| log.info(e.getMessage()); |
| } |
| |
| return Constants.RCPT_OK; |
| } else if (input.equalsIgnoreCase("DATA")) { |
| dataWriting = true; |
| |
| return Constants.DATA_START_SUCCESS; |
| } else if (input.equalsIgnoreCase("QUIT")) { |
| dataWriting = true; |
| transmitionEnd = true; |
| |
| return Constants.COMMAND_TRANSMISSION_END; |
| } else if (input.equals(".")) { |
| dataWriting = false; |
| |
| return Constants.DATA_END_SUCCESS; |
| } else if (input.length() == 0 && !bodyData) { |
| bodyData = true; |
| |
| return null; |
| } else if ((mail != null) && dataWriting) { |
| try { |
| if (bodyData) { |
| temp += input; |
| mail.setContent(temp, "text/xml"); //Since this is for axis2 :-) |
| } else { |
| mail.addHeaderLine(input); |
| } |
| } catch (MessagingException e) { |
| log.info(e.getMessage()); |
| } |
| |
| return null; |
| } else { |
| return Constants.COMMAND_UNKNOWN; |
| } |
| } |
| |
| // running the thread |
| public void run() { |
| try { |
| |
| // do initial transmission. |
| initializeClient(); |
| |
| // analyze all the inputs from client and work accordingly. |
| while (runThread) { |
| String input = null; |
| |
| // get client input |
| input = reader.readLine(); |
| |
| String retString = processInput(input); |
| |
| if (Constants.COMMAND_EXIT.equals(retString)) { |
| exitWorker(); |
| } else { |
| if (retString != null) { |
| send(retString); // Send the reply |
| } |
| |
| if ((mail != null) && transmitionEnd) { |
| exitWorker(); |
| } |
| } |
| } |
| |
| for (int idx = 0; idx < receivers.size(); idx++) { |
| try { |
| MailSorter mSort = null; |
| |
| if (actAsMailet) { |
| mSort = new MailSorter(this.st, this.configurationContext); |
| } else { |
| mSort = new MailSorter(this.st, null); |
| } |
| |
| mSort.sort((String) receivers.get(idx), new MimeMessage(mail)); |
| } catch (MessagingException e1) { |
| log.info(e1.getMessage()); |
| |
| // e1.printStackTrace(); |
| } |
| } |
| |
| // |
| } catch (IOException e) { |
| log.info("ERROR: CLIENT CLOSED THE SOCKET"); |
| } |
| } |
| |
| private void send(String s) throws IOException { |
| writer.write(s); |
| writer.newLine(); |
| writer.flush(); |
| } |
| } |