1 17 package gnu.mail.providers.smtp; 18 import java.io.*; 19 20 import java.net.*; 21 import java.util.Hashtable ; 22 import java.util.Vector ; 23 import javax.mail.*; 24 import javax.mail.event.TransportEvent ; 25 import javax.mail.internet.*; 26 import gnu.mail.util.*; 27 28 54 public class SMTPTransport 55 extends Transport 56 { 57 58 62 private final static String CRLF = "\r\n"; 64 private static int deliveryStatus; 65 private static String localHostName; 66 67 private MimeMessage mimeMessage; 68 private Address[] addresses; 69 private Vector validSentAddrList; 71 private Vector validUnsentAddrList; 73 private Vector invalidAddrList; 75 private Hashtable extMap; 76 private boolean noAuth; 77 private String name; 78 private BufferedReader serverInput; 79 private CRLFOutputStream serverOutput; 80 private String lastServerResponse; 81 private Socket socket; 82 83 84 88 94 public SMTPTransport(Session session, URLName urlName) 95 { 96 super(session, urlName); 97 validSentAddrList = new Vector (2); 98 validUnsentAddrList = new Vector (2); 99 invalidAddrList = new Vector (); 100 } 102 103 104 112 public synchronized void sendMessage(Message message, 113 Address[] addresses) 114 throws MessagingException, SendFailedException 115 { 116 117 String ehlo; 119 120 mimeMessage = (MimeMessage) message; 122 this.addresses = addresses; 123 124 readServerResponse(); 126 127 ehlo = session.getProperty("mail.smtp.ehlo"); 129 if (ehlo != null && ehlo.toUpperCase().equals("FALSE")) { 130 helo(getLocalHost()); 131 } 132 else if (ehlo(getLocalHost()) == false) { 133 helo(getLocalHost()); 134 } 135 136 mailFrom(); 138 rcptTo(); 139 140 try { 142 mimeMessage.writeTo(data()); 143 } 144 catch (IOException ioe) { 145 throw new MessagingException("Unable to send message", ioe); 146 } 147 finishData(); 148 149 notifyTransportListeners(); 150 151 } 152 153 154 159 public synchronized void connect() 160 throws MessagingException 161 { 162 163 String host; 165 String user; 166 String port; 167 168 host = session.getProperty("mail.smtp.host"); 170 user = session.getProperty("mail.smtp.user"); 171 port = session.getProperty("mail.smtp.port"); 172 173 if (host == null) { 175 throw new MessagingException("No SMTP host has been " + 176 "set (mail.smtp.host)"); 177 } 178 179 if (port != null) { 182 int connectPort = Integer.parseInt(port); 183 connect(host, connectPort, user, null); 184 } 185 else { 186 connect(host, user, null); 187 } 188 189 } 190 191 196 202 public synchronized void close() 203 throws MessagingException 204 { 205 207 if (isConnected()) { 209 closeConnection(); 210 } 211 212 super.close(); 213 214 } 215 216 217 222 public synchronized boolean isConnected() 223 { 224 return super.isConnected(); 225 } 226 227 228 232 242 protected boolean protocolConnect(String host, int port, String user, 243 String password) 244 throws MessagingException 245 { 246 247 int connectPort; 248 249 try { 250 if (port == -1) { 251 connectPort = 25; 252 } 253 else { 254 connectPort = port; 255 } 256 257 openServer(host, connectPort); 259 260 262 } 263 catch (Exception e) { 264 throw new MessagingException("Unable to connect", e); 265 } 266 267 return true; 269 } 270 271 272 private void openServer(String host, int port) 273 throws MessagingException 274 { 275 276 String timeout; 278 279 try { 281 socket = new Socket(host, port); 282 } 283 catch (IOException ioe) { 284 throw new MessagingException("Unable to open server", ioe); 285 } 286 287 timeout = session.getProperty("mail.smtp.timeout"); 289 if (timeout != null) { 290 try { 291 socket.setSoTimeout(Integer.parseInt(timeout)); 292 } 293 catch (SocketException se) { 294 throw new MessagingException("Unable to open server", se); 295 } 296 } 297 298 try { 299 InputStream sin = socket.getInputStream(); 300 OutputStream sout = socket.getOutputStream(); 301 serverInput = new BufferedReader(new InputStreamReader(sin)); 302 serverOutput = new CRLFOutputStream(sout); 303 } 304 catch (IOException ioe) { 305 throw new MessagingException("Unable to open server", ioe); 306 } 307 308 } 309 310 311 312 private void notifyTransportListeners() 313 { 314 Address[] validSentAddr = new Address[validSentAddrList.size()]; 315 validSentAddrList.copyInto(validSentAddr); 316 Address[] validUnsentAddr = new Address[validUnsentAddrList.size()]; 317 validUnsentAddrList.copyInto(validUnsentAddr); 318 Address[] invalidAddr = new Address[invalidAddrList.size()]; 319 invalidAddrList.copyInto(invalidAddr); 320 321 notifyTransportListeners(deliveryStatus, validSentAddr, validUnsentAddr, 322 invalidAddr, mimeMessage); 323 } 324 325 326 private void closeConnection() 327 { 328 try { 329 simpleCommand("QUIT"); 330 331 serverOutput.close(); 333 serverInput.close(); 334 socket.close(); 335 } 336 catch (Throwable t) { 339 } 340 341 } 342 343 344 352 private String getLocalHost() 353 { 354 355 360 if (localHostName != null) { 362 return localHostName; 363 } 364 365 localHostName = session.getProperty("mail.smtp.localhost"); 367 if (localHostName != null) { 368 return localHostName; 369 } 370 371 try { 373 localHostName = InetAddress.getLocalHost().getHostName(); 374 return localHostName; 375 } 376 catch (UnknownHostException e) { 377 } 379 380 return ""; 382 } 383 384 385 393 private boolean isNotLastLine(String value) 394 { 395 396 if (value.charAt(3) == ' ') { 398 return false; 399 } 400 401 return true; 402 } 403 404 409 420 private boolean ehlo(String domain) 421 throws MessagingException 422 { 423 424 String command = "EHLO " + domain; 425 426 int response = simpleCommand(command); 427 428 if (response != 250) { 429 return false; 430 } 431 432 return true; 433 } 434 435 436 443 private void helo(String domain) 444 throws MessagingException 445 { 446 447 int response; 449 String command; 450 451 command = "HELO " + domain; 453 454 response = simpleCommand(command); 456 457 } 458 459 460 466 private void mailFrom() 467 throws SendFailedException, MessagingException 468 { 469 470 Address from; 471 String addressFromProperty; 472 String mailFrom; 473 int response; 474 475 addressFromProperty = session.getProperty("mail.smtp.from"); 476 if (addressFromProperty != null) { 477 from = new InternetAddress(addressFromProperty); 478 } 479 else if ((from = mimeMessage.getFrom()[0]) != null) { 480 from = mimeMessage.getFrom()[0]; 481 } 482 else { 483 deliveryStatus = TransportEvent.MESSAGE_NOT_DELIVERED; 484 throw new SendFailedException("No valid message sender specified"); 485 } 486 487 mailFrom = "MAIL FROM: <" + from + ">"; 488 response = simpleCommand(mailFrom); 489 490 if (response != 250) { 491 deliveryStatus = TransportEvent.MESSAGE_NOT_DELIVERED; 492 throw new SendFailedException("Sender " + from + " was rejected: " 493 + response); 494 } 495 496 } 497 498 499 506 private void rcptTo() 507 throws SendFailedException, MessagingException 508 { 509 510 for (int i = 0; i < addresses.length; i++) { 512 513 String rcptTo = "RCPT TO: <" + addresses[i] + ">"; 514 int response = simpleCommand(rcptTo); 515 516 if (response == 250) { 517 validSentAddrList.insertElementAt(addresses[i], 0); 518 } 519 else { 520 invalidAddrList.insertElementAt(addresses[i], 0); 521 } 522 } 523 524 if (validSentAddrList.size() == 0) { 525 deliveryStatus = TransportEvent.MESSAGE_NOT_DELIVERED; 526 throw new SendFailedException("No valid mail recipients specified"); 527 } 528 529 } 530 531 532 private OutputStream data() 533 throws MessagingException 534 { 535 536 int response = simpleCommand("DATA"); 537 538 return new SMTPOutputStream(serverOutput); 539 } 540 541 542 547 private void finishData() 548 throws MessagingException 549 { 550 551 String dataEnd = "\r\n.\r\n"; 552 553 int response = simpleCommand(dataEnd); 554 555 556 if (response != 250) { 557 560 int size = validSentAddrList.size(); 561 validUnsentAddrList.ensureCapacity(size); 562 for (int i = 0; i < size; i++) { 563 validUnsentAddrList.addElement(validSentAddrList.elementAt(i)); 564 } 565 566 569 validSentAddrList.removeAllElements(); 570 571 deliveryStatus = TransportEvent.MESSAGE_NOT_DELIVERED; 572 } 573 else { 574 if (invalidAddrList.size() == 0) { 575 deliveryStatus = TransportEvent.MESSAGE_DELIVERED; 576 } 577 else { 578 deliveryStatus = TransportEvent.MESSAGE_PARTIALLY_DELIVERED; 579 } 580 } 581 582 } 583 584 585 private String normalizeAddress(String address) 586 { 587 return null; } 589 590 591 private int readServerResponse() 592 throws MessagingException 593 { 594 595 600 String code; 602 boolean end; 603 604 606 try { 607 lastServerResponse = serverInput.readLine(); 608 while (isNotLastLine(lastServerResponse)) { 609 lastServerResponse = serverInput.readLine(); 610 } 611 } 612 catch (IOException ioe) { 613 throw new MessagingException("Unable to read server response", ioe); 614 } 615 616 Session.log("SMTP< " + lastServerResponse); 617 code = lastServerResponse.substring(0, 3); 618 619 return Integer.parseInt(code); 621 } 622 623 624 632 private int simpleCommand(String command) 633 throws MessagingException 634 { 635 636 sendCommand(command); 638 639 return readServerResponse(); 641 } 642 643 644 650 private void sendCommand(String command) 651 throws MessagingException 652 { 653 try { 654 serverOutput.write((command + CRLF).getBytes()); 655 } 656 catch (IOException e) { 657 throw new MessagingException("Problem writing to server", e); 658 } 659 660 Session.log("SMTP> " + command); 661 662 } 663 664 669 674 675 } 676 677 | Popular Tags |