1 18 19 26 27 package org.apache.tools.mail; 28 29 import java.io.IOException ; 30 import java.io.PrintStream ; 31 import java.io.BufferedOutputStream ; 32 import java.io.OutputStream ; 33 import java.net.Socket ; 34 import java.net.InetAddress ; 35 import java.util.Vector ; 36 import java.util.Enumeration ; 37 38 94 public class MailMessage { 95 96 97 public static final String DEFAULT_HOST = "localhost"; 98 99 100 public static final int DEFAULT_PORT = 25; 101 102 103 private String host; 104 105 106 private int port = DEFAULT_PORT; 107 108 109 private String from; 110 111 112 private Vector replyto; 113 114 115 private Vector to; 116 117 118 private Vector cc; 119 120 121 private Vector headersKeys; 122 private Vector headersValues; 123 124 private MailPrintStream out; 125 126 private SmtpResponseReader in; 127 128 private Socket socket; 129 private static final int OK_READY = 220; 130 private static final int OK_HELO = 250; 131 private static final int OK_FROM = 250; 132 private static final int OK_RCPT_1 = 250; 133 private static final int OK_RCPT_2 = 251; 134 private static final int OK_DATA = 354; 135 private static final int OK_DOT = 250; 136 private static final int OK_QUIT = 221; 137 138 144 public MailMessage() throws IOException { 145 this(DEFAULT_HOST, DEFAULT_PORT); 146 } 147 148 155 public MailMessage(String host) throws IOException { 156 this(host, DEFAULT_PORT); 157 } 158 159 167 public MailMessage(String host, int port) throws IOException { 168 this.port = port; 169 this.host = host; 170 replyto = new Vector (); 171 to = new Vector (); 172 cc = new Vector (); 173 headersKeys = new Vector (); 174 headersValues = new Vector (); 175 connect(); 176 sendHelo(); 177 } 178 179 184 public void setPort(int port) { 185 this.port = port; 186 } 187 188 194 public void from(String from) throws IOException { 195 sendFrom(from); 196 this.from = from; 197 } 198 199 206 public void replyto(String rto) { 207 this.replyto.addElement(rto); 208 } 209 210 217 public void to(String to) throws IOException { 218 sendRcpt(to); 219 this.to.addElement(to); 220 } 221 222 229 public void cc(String cc) throws IOException { 230 sendRcpt(cc); 231 this.cc.addElement(cc); 232 } 233 234 241 public void bcc(String bcc) throws IOException { 242 sendRcpt(bcc); 243 } 245 246 251 public void setSubject(String subj) { 252 setHeader("Subject", subj); 253 } 254 255 261 public void setHeader(String name, String value) { 262 headersKeys.add(name); 264 headersValues.add(value); 265 } 266 267 277 public PrintStream getPrintStream() throws IOException { 278 setFromHeader(); 279 setReplyToHeader(); 280 setToHeader(); 281 setCcHeader(); 282 setHeader("X-Mailer", "org.apache.tools.mail.MailMessage (ant.apache.org)"); 283 sendData(); 284 flushHeaders(); 285 return out; 286 } 287 288 289 void setFromHeader() { 292 setHeader("From", from); 293 } 294 295 void setReplyToHeader() { 297 if (!replyto.isEmpty()) { 298 setHeader("Reply-To", vectorToList(replyto)); 299 } 300 } 301 302 void setToHeader() { 303 if (!to.isEmpty()) { 304 setHeader("To", vectorToList(to)); 305 } 306 } 307 308 void setCcHeader() { 309 if (!cc.isEmpty()) { 310 setHeader("Cc", vectorToList(cc)); 311 } 312 } 313 314 String vectorToList(Vector v) { 315 StringBuffer buf = new StringBuffer (); 316 Enumeration e = v.elements(); 317 while (e.hasMoreElements()) { 318 buf.append(e.nextElement()); 319 if (e.hasMoreElements()) { 320 buf.append(", "); 321 } 322 } 323 return buf.toString(); 324 } 325 326 void flushHeaders() throws IOException { 327 for (int i = 0; i < headersKeys.size(); i++) { 332 String name = (String ) headersKeys.elementAt(i); 333 String value = (String ) headersValues.elementAt(i); 334 out.println(name + ": " + value); 335 } 336 out.println(); 337 out.flush(); 338 } 339 340 346 public void sendAndClose() throws IOException { 347 try { 348 sendDot(); 349 sendQuit(); 350 } finally { 351 disconnect(); 352 } 353 } 354 355 static String sanitizeAddress(String s) { 358 int paramDepth = 0; 359 int start = 0; 360 int end = 0; 361 int len = s.length(); 362 363 for (int i = 0; i < len; i++) { 364 char c = s.charAt(i); 365 if (c == '(') { 366 paramDepth++; 367 if (start == 0) { 368 end = i; } 370 } else if (c == ')') { 371 paramDepth--; 372 if (end == 0) { 373 start = i + 1; } 375 } else if (paramDepth == 0 && c == '<') { 376 start = i + 1; 377 } else if (paramDepth == 0 && c == '>') { 378 end = i; 379 } 380 } 381 382 if (end == 0) { 383 end = len; 384 } 385 386 return s.substring(start, end); 387 } 388 389 391 void connect() throws IOException { 392 socket = new Socket (host, port); 393 out = new MailPrintStream( 394 new BufferedOutputStream ( 395 socket.getOutputStream())); 396 in = new SmtpResponseReader(socket.getInputStream()); 397 getReady(); 398 } 399 400 void getReady() throws IOException { 401 String response = in.getResponse(); 402 int[] ok = {OK_READY}; 403 if (!isResponseOK(response, ok)) { 404 throw new IOException ( 405 "Didn't get introduction from server: " + response); 406 } 407 } 408 void sendHelo() throws IOException { 409 String local = InetAddress.getLocalHost().getHostName(); 410 int[] ok = {OK_HELO}; 411 send("HELO " + local, ok); 412 } 413 void sendFrom(String from) throws IOException { 414 int[] ok = {OK_FROM}; 415 send("MAIL FROM: " + "<" + sanitizeAddress(from) + ">", ok); 416 } 417 void sendRcpt(String rcpt) throws IOException { 418 int[] ok = {OK_RCPT_1, OK_RCPT_2}; 419 send("RCPT TO: " + "<" + sanitizeAddress(rcpt) + ">", ok); 420 } 421 422 void sendData() throws IOException { 423 int[] ok = {OK_DATA}; 424 send("DATA", ok); 425 } 426 427 void sendDot() throws IOException { 428 int[] ok = {OK_DOT}; 429 send("\r\n.", ok); } 431 432 void sendQuit() throws IOException { 433 int[] ok = {OK_QUIT}; 434 try { 435 send("QUIT", ok); 436 } catch (IOException e) { 437 throw new ErrorInQuitException(e); 438 } 439 } 440 441 void send(String msg, int[] ok) throws IOException { 442 out.rawPrint(msg + "\r\n"); String response = in.getResponse(); 444 if (!isResponseOK(response, ok)) { 445 throw new IOException ("Unexpected reply to command: " 446 + msg + ": " + response); 447 } 448 } 449 450 boolean isResponseOK(String response, int[] ok) { 451 for (int i = 0; i < ok.length; i++) { 453 if (response.startsWith("" + ok[i])) { 454 return true; 455 } 456 } 457 return false; 458 } 459 460 void disconnect() throws IOException { 461 if (out != null) { 462 out.close(); 463 } 464 if (in != null) { 465 try { 466 in.close(); 467 } catch (IOException e) { 468 } 470 } 471 if (socket != null) { 472 try { 473 socket.close(); 474 } catch (IOException e) { 475 } 477 } 478 } 479 } 480 481 485 class MailPrintStream extends PrintStream { 486 487 private int lastChar; 488 489 public MailPrintStream(OutputStream out) { 490 super(out, true); } 492 493 public void write(int b) { 496 if (b == '\n' && lastChar != '\r') { 497 rawWrite('\r'); rawWrite(b); 499 } else if (b == '.' && lastChar == '\n') { 500 rawWrite('.'); rawWrite(b); 502 } else { 503 rawWrite(b); 504 } 505 lastChar = b; 506 } 507 508 public void write(byte[] buf, int off, int len) { 509 for (int i = 0; i < len; i++) { 510 write(buf[off + i]); 511 } 512 } 513 514 void rawWrite(int b) { 515 super.write(b); 516 } 517 518 void rawPrint(String s) { 519 int len = s.length(); 520 for (int i = 0; i < len; i++) { 521 rawWrite(s.charAt(i)); 522 } 523 } 524 } 525 526 | Popular Tags |