| 1582 | 1 package goodjava.mail; | 
|  | 2 | 
|  | 3 import java.io.Reader; | 
|  | 4 import java.io.InputStreamReader; | 
|  | 5 import java.io.Writer; | 
|  | 6 import java.io.OutputStreamWriter; | 
|  | 7 import java.io.IOException; | 
|  | 8 import java.net.Socket; | 
| 1583 | 9 import java.util.Map; | 
|  | 10 import goodjava.util.GoodUtils; | 
| 1582 | 11 | 
|  | 12 | 
|  | 13 public class Smtp { | 
|  | 14 	private final char[] buf = new char[1000]; | 
|  | 15 	private final Socket socket; | 
|  | 16 	private final Reader reader; | 
|  | 17 	private final Writer writer; | 
|  | 18 	public final String ehlo; | 
|  | 19 | 
| 1829 | 20 	public Smtp(Socket socket,String helo) throws IOException, MailException { | 
| 1582 | 21 		this.socket = socket; | 
|  | 22 		this.reader = new InputStreamReader(socket.getInputStream()); | 
|  | 23 		this.writer = new OutputStreamWriter(socket.getOutputStream()); | 
|  | 24 		String s = read(); | 
|  | 25 		if( !s.startsWith("220") ) | 
| 1584 | 26 			throw new MailException(s); | 
| 1829 | 27 		write( "EHLO " + helo + "\r\n" ); | 
| 1582 | 28 		ehlo = read(); | 
|  | 29 		if( !ehlo.startsWith("250") ) | 
| 1584 | 30 			throw new MailException(ehlo); | 
| 1582 | 31 	} | 
|  | 32 | 
| 1830 | 33 	public Smtp(Socket socket) throws IOException, MailException { | 
|  | 34 		this(socket,"GoodJava"); | 
|  | 35 	} | 
|  | 36 | 
| 1584 | 37 	public String authenticate(String username,String password) throws IOException, MailException { | 
| 1583 | 38 		String s = "\0" + username + "\0" + password; | 
|  | 39 		s = GoodUtils.base64Encode(s); | 
|  | 40 		write( "AUTH PLAIN " + s + "\r\n" ); | 
|  | 41 		String r = read(); | 
|  | 42 		if( !r.startsWith("235") ) | 
| 1584 | 43 			throw new MailException(r); | 
| 1583 | 44 		return r; | 
|  | 45 	} | 
|  | 46 | 
| 1584 | 47 	public void send(Message msg) throws IOException, MailException { | 
| 1583 | 48 		for( Map.Entry<String,String> entry : msg.headers.entrySet() ) { | 
|  | 49 			String name = entry.getKey(); | 
|  | 50 			String value = entry.getValue(); | 
|  | 51 			if( name.equalsIgnoreCase("from") ) { | 
|  | 52 				from(value); | 
|  | 53 			} | 
| 1686 | 54 		} | 
|  | 55 		for( Map.Entry<String,String> entry : msg.headers.entrySet() ) { | 
|  | 56 			String name = entry.getKey(); | 
|  | 57 			String value = entry.getValue(); | 
| 1583 | 58 			if( name.equalsIgnoreCase("to") | 
|  | 59 				|| name.equalsIgnoreCase("cc") | 
|  | 60 				|| name.equalsIgnoreCase("bcc") | 
|  | 61 			) { | 
|  | 62 				for( String s : value.split(",") ) { | 
|  | 63 					to(s); | 
|  | 64 				} | 
|  | 65 			} | 
|  | 66 		} | 
|  | 67 		data( msg.toText() ); | 
|  | 68 	} | 
|  | 69 | 
| 1584 | 70 	public void close() throws IOException, MailException { | 
| 1582 | 71 		write( "QUIT\r\n" ); | 
|  | 72 		String s = read(); | 
|  | 73 		if( !s.startsWith("221") ) | 
| 1584 | 74 			throw new MailException(s); | 
| 1582 | 75 		socket.close(); | 
|  | 76 	} | 
|  | 77 | 
| 1584 | 78 	public String from(String address) throws IOException, MailException { | 
| 1582 | 79 		write( "MAIL FROM: " + address + "\r\n" ); | 
|  | 80 		String r = read(); | 
|  | 81 		if( !r.startsWith("250") ) | 
| 1584 | 82 			throw new MailException(r); | 
| 1582 | 83 		return r; | 
|  | 84 	} | 
|  | 85 | 
| 1584 | 86 	public String to(String address) throws IOException, MailException { | 
| 1582 | 87 		write( "RCPT TO: " + address + "\r\n" ); | 
|  | 88 		String r = read(); | 
|  | 89 		if( !r.startsWith("250") ) | 
| 1584 | 90 			throw new MailException(r); | 
| 1582 | 91 		return r; | 
|  | 92 	} | 
|  | 93 | 
| 1584 | 94 	public String data(String text) throws IOException, MailException { | 
| 1582 | 95 		if( !text.endsWith("\r\n") ) | 
| 1584 | 96 			throw new MailException("text must end with \\r\\n"); | 
| 1582 | 97 		text = text.replace("\r\n.","\r\n.."); | 
|  | 98 		write( "DATA\r\n" ); | 
|  | 99 		String r = read(); | 
|  | 100 		if( !r.startsWith("354") ) | 
| 1584 | 101 			throw new MailException(r); | 
| 1582 | 102 		write( text + ".\r\n" ); | 
|  | 103 		r = read(); | 
|  | 104 		if( !r.startsWith("250") ) | 
| 1584 | 105 			throw new MailException(r); | 
| 1582 | 106 		return r; | 
|  | 107 	} | 
|  | 108 | 
|  | 109 	private String read() throws IOException { | 
|  | 110 		int n = reader.read(buf); | 
|  | 111 		return new String(buf,0,n); | 
|  | 112 	} | 
|  | 113 | 
|  | 114 	private void write(String s) throws IOException { | 
|  | 115 		writer.write(s); | 
|  | 116 		writer.flush(); | 
|  | 117 	} | 
|  | 118 } |