1 21 22 package org.armedbear.j.mail; 23 24 import java.io.BufferedReader ; 25 import java.io.BufferedWriter ; 26 import java.io.IOException ; 27 import java.io.InputStreamReader ; 28 import java.io.OutputStreamWriter ; 29 import java.io.Writer ; 30 import java.net.ConnectException ; 31 import java.net.InetAddress ; 32 import java.net.NoRouteToHostException ; 33 import java.net.Socket ; 34 import java.net.UnknownHostException ; 35 import java.util.List ; 36 import org.armedbear.j.Debug; 37 import org.armedbear.j.Editor; 38 import org.armedbear.j.File; 39 import org.armedbear.j.FastStringBuffer; 40 import org.armedbear.j.Log; 41 import org.armedbear.j.MessageDialog; 42 import org.armedbear.j.Property; 43 import org.armedbear.j.Utilities; 44 45 public final class SmtpSession extends Writer 46 { 47 private static final int DEFAULT_PORT = 25; 48 49 private boolean echo = false; 50 private String hostName; 51 private int port; 52 private Socket socket; 53 private BufferedReader reader; 54 private BufferedWriter writer; 55 private boolean connected; 56 private String errorText; 57 58 private SmtpSession(String hostName) 59 { 60 this.hostName = hostName; 61 this.port = DEFAULT_PORT; 62 } 63 64 private SmtpSession(String hostName, int port) 65 { 66 this.hostName = hostName; 67 this.port = port; 68 } 69 70 public final void setEcho(boolean b) 71 { 72 echo = b; 73 } 74 75 public static SmtpSession getDefaultSession() 77 { 78 return getSession(Editor.preferences().getStringProperty(Property.SMTP)); 79 } 80 81 public static SmtpSession getSession(String server) 83 { 84 if (server == null) 85 return null; 86 SmtpSession session = null; 87 int index = server.indexOf(':'); 89 if (index < 0) { 90 session = new SmtpSession(server); 91 } else { 92 try { 93 int port = Integer.parseInt(server.substring(index + 1)); 94 String hostName = server.substring(0, index); 95 session = new SmtpSession(hostName, port); 96 } 97 catch (NumberFormatException e) { 98 Log.error(e); 99 FastStringBuffer sb = new FastStringBuffer(); 100 sb.append("Unable to parse SMTP server name \""); 101 sb.append(server); 102 sb.append('"'); 103 MessageDialog.showMessageDialog(sb.toString(), "Error"); 104 return null; 105 } 106 } 107 Debug.assertTrue(session != null); 108 session.setEcho(true); 109 if (!session.connect()) 110 return null; 111 session.setEcho(false); 112 return session; 113 } 114 115 public final String getErrorText() 116 { 117 return errorText; 118 } 119 120 public boolean sendMessage(SendMail sm, File messageFile) 121 { 122 List addressees = sm.getAddressees(); 123 if (addressees == null || addressees.size() == 0) 124 return false; 125 if (!connect()) 126 return false; 127 try { 128 setEcho(true); 129 FastStringBuffer sb = new FastStringBuffer("mail from:<"); 130 sb.append(sm.getFromAddress()); 131 sb.append('>'); 132 writeLine(sb.toString()); 133 if (getResponse() != 250) 134 return false; 135 for (int i = 0; i < addressees.size(); i++) { 136 String addressee = (String ) addressees.get(i); 137 String addr = sm.getAddress(addressee); 138 if (addr == null) { 139 errorText = "Invalid addressee \"" + addressee + "\""; 140 return false; 141 } 142 sb.setText("rcpt to:<"); 143 sb.append(addr); 144 sb.append('>'); 145 writeLine(sb.toString()); 146 if (getResponse() != 250) { 147 errorText = "Address not accepted \"" + addr + "\""; 148 return false; 149 } 150 } 151 writeLine("data"); 152 if (getResponse() != 354) 153 return false; 154 setEcho(false); 155 BufferedReader messageFileReader = new BufferedReader (new InputStreamReader (messageFile.getInputStream())); 156 String s; 157 while ((s = messageFileReader.readLine()) != null) 158 writeLine(s); 159 setEcho(true); 160 writeLine("."); 161 if (getResponse() != 250) 162 return false; 163 quit(); 164 } 165 catch (Throwable t) { 166 Log.error(t); 167 } 168 finally { 169 setEcho(false); 170 disconnect(); 171 } 172 AddressBook addressBook = AddressBook.getGlobalAddressBook(); 174 for (int i = 0; i < addressees.size(); i++) { 175 String addressee = (String ) addressees.get(i); 176 MailAddress a = MailAddress.parseAddress(addressee); 177 if (a != null) { 178 addressBook.maybeAddMailAddress(a); 179 addressBook.promote(a); 180 } 181 } 182 AddressBook.saveGlobalAddressBook(); 183 return true; 184 } 185 186 public boolean connect() 187 { 188 if (connected) 189 return true; 190 Log.debug("connecting to port " + port + " on " + hostName + " ..."); 191 try { 192 socket = new Socket (hostName, port); 193 } 194 catch (UnknownHostException e) { 195 errorText = "Unknown SMTP server " + hostName; 196 return false; 197 } 198 catch (NoRouteToHostException e) { 199 errorText = "No route to SMTP server " + hostName; 200 return false; 201 } 202 catch (ConnectException e) { 203 errorText = "Connection refused by SMTP server " + hostName; 204 return false; 205 } 206 catch (IOException e) { 207 Log.error(e); 208 errorText = e.toString(); 209 return false; 210 } 211 try { 212 reader = 213 new BufferedReader (new InputStreamReader (socket.getInputStream())); 214 writer = 215 new BufferedWriter (new OutputStreamWriter (socket.getOutputStream())); 216 getResponse(); 217 writeLine("HELO " + InetAddress.getLocalHost().getHostAddress()); 218 if (getResponse() == 250) { 219 connected = true; 220 return true; 221 } 222 } 223 catch (IOException e) { 224 Log.error(e); 225 } 226 return false; 227 } 228 229 public void quit() 230 { 231 setEcho(true); 232 writeLine("QUIT"); 233 getResponse(); 234 setEcho(false); 235 disconnect(); 236 } 237 238 public synchronized void disconnect() 239 { 240 if (connected) { 241 try { 242 socket.close(); 243 } 244 catch (IOException e) { 245 Log.error(e); 246 } 247 socket = null; 248 reader = null; 249 writer = null; 250 connected = false; 251 } 252 } 253 254 public int getResponse() 255 { 256 while (true) { 257 String s = readLine(); 258 if (s == null) 259 break; 260 if (s.length() < 4) 261 break; 262 if (s.charAt(3) == ' ') { 263 try { 264 return Utilities.parseInt(s); 265 } 266 catch (NumberFormatException e) { 267 Log.error(e); 268 } 269 break; 270 } 271 } 272 return 0; 273 } 274 275 private String readLine() 276 { 277 try { 278 String s = reader.readLine(); 279 if (echo && s != null) 280 Log.debug("<== " + s); 281 return s; 282 } 283 catch (IOException e) { 284 Log.error(e); 285 return null; 286 } 287 } 288 289 public void write(int c) throws IOException 290 { 291 writer.write(c); 292 } 293 294 public void write(char[] chars) throws IOException 295 { 296 writer.write(chars); 297 } 298 299 public void write(char[] chars, int offset, int length) throws IOException 300 { 301 writer.write(chars, offset, length); 302 } 303 304 public void write(String s) throws IOException 305 { 306 writer.write(s); 307 } 308 309 public void write(String s, int offset, int length) throws IOException 310 { 311 writer.write(s, offset, length); 312 } 313 314 public void flush() throws IOException 315 { 316 writer.flush(); 317 } 318 319 public void close() throws IOException 320 { 321 writer.close(); 322 } 323 324 public boolean writeLine(String s) 325 { 326 if (echo) 327 Log.debug("==> " + s); 328 try { 329 writer.write(s); 330 writer.write("\r\n"); 331 writer.flush(); 332 return true; 333 } 334 catch (IOException e) { 335 Log.error(e); 336 return false; 337 } 338 } 339 } 340 | Popular Tags |