001 /* 002 * Copyright 2001-2005 The Apache Software Foundation 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.apache.commons.net.smtp; 017 018 import java.io.BufferedReader; 019 import java.io.BufferedWriter; 020 import java.io.IOException; 021 import java.io.InputStreamReader; 022 import java.io.OutputStreamWriter; 023 import java.util.Enumeration; 024 import java.util.Vector; 025 import org.apache.commons.net.MalformedServerReplyException; 026 import org.apache.commons.net.ProtocolCommandListener; 027 import org.apache.commons.net.ProtocolCommandSupport; 028 import org.apache.commons.net.SocketClient; 029 030 /*** 031 * SMTP provides the basic the functionality necessary to implement your 032 * own SMTP client. To derive the full benefits of the SMTP class requires 033 * some knowledge of the FTP protocol defined in RFC 821. However, there 034 * is no reason why you should have to use the SMTP class. The 035 * {@link org.apache.commons.net.smtp.SMTPClient} class, 036 * derived from SMTP, 037 * implements all the functionality required of an SMTP client. The 038 * SMTP class is made public to provide access to various SMTP constants 039 * and to make it easier for adventurous programmers (or those with 040 * special needs) to interact with the SMTP protocol and implement their 041 * own clients. A set of methods with names corresponding to the SMTP 042 * command names are provided to facilitate this interaction. 043 * <p> 044 * You should keep in mind that the SMTP server may choose to prematurely 045 * close a connection for various reasons. The SMTP class will detect a 046 * premature SMTP server connection closing when it receives a 047 * {@link org.apache.commons.net.smtp.SMTPReply#SERVICE_NOT_AVAILABLE SMTPReply.SERVICE_NOT_AVAILABLE } 048 * response to a command. 049 * When that occurs, the SMTP class method encountering that reply will throw 050 * an {@link org.apache.commons.net.smtp.SMTPConnectionClosedException} 051 * . 052 * <code>SMTPConectionClosedException</code> 053 * is a subclass of <code> IOException </code> and therefore need not be 054 * caught separately, but if you are going to catch it separately, its 055 * catch block must appear before the more general <code> IOException </code> 056 * catch block. When you encounter an 057 * {@link org.apache.commons.net.smtp.SMTPConnectionClosedException} 058 * , you must disconnect the connection with 059 * {@link org.apache.commons.net.SocketClient#disconnect disconnect() } 060 * to properly clean up the system resources used by SMTP. Before 061 * disconnecting, you may check the 062 * last reply code and text with 063 * {@link #getReplyCode getReplyCode }, 064 * {@link #getReplyString getReplyString }, 065 * and {@link #getReplyStrings getReplyStrings}. 066 * <p> 067 * Rather than list it separately for each method, we mention here that 068 * every method communicating with the server and throwing an IOException 069 * can also throw a 070 * {@link org.apache.commons.net.MalformedServerReplyException} 071 * , which is a subclass 072 * of IOException. A MalformedServerReplyException will be thrown when 073 * the reply received from the server deviates enough from the protocol 074 * specification that it cannot be interpreted in a useful manner despite 075 * attempts to be as lenient as possible. 076 * <p> 077 * <p> 078 * @author Daniel F. Savarese 079 * @see SMTPClient 080 * @see SMTPConnectionClosedException 081 * @see org.apache.commons.net.MalformedServerReplyException 082 ***/ 083 084 public class SMTP extends SocketClient 085 { 086 /*** The default SMTP port (25). ***/ 087 public static final int DEFAULT_PORT = 25; 088 089 // We have to ensure that the protocol communication is in ASCII 090 // but we use ISO-8859-1 just in case 8-bit characters cross 091 // the wire. 092 private static final String __DEFAULT_ENCODING = "ISO-8859-1"; 093 094 private StringBuffer __commandBuffer; 095 096 BufferedReader _reader; 097 BufferedWriter _writer; 098 int _replyCode; 099 Vector _replyLines; 100 boolean _newReplyString; 101 String _replyString; 102 103 /*** 104 * A ProtocolCommandSupport object used to manage the registering of 105 * ProtocolCommandListeners and te firing of ProtocolCommandEvents. 106 ***/ 107 protected ProtocolCommandSupport _commandSupport_; 108 109 /*** 110 * The default SMTP constructor. Sets the default port to 111 * <code>DEFAULT_PORT</code> and initializes internal data structures 112 * for saving SMTP reply information. 113 ***/ 114 public SMTP() 115 { 116 setDefaultPort(DEFAULT_PORT); 117 __commandBuffer = new StringBuffer(); 118 _replyLines = new Vector(); 119 _newReplyString = false; 120 _replyString = null; 121 _commandSupport_ = new ProtocolCommandSupport(this); 122 } 123 124 private int __sendCommand(String command, String args, boolean includeSpace) 125 throws IOException 126 { 127 String message; 128 129 __commandBuffer.setLength(0); 130 __commandBuffer.append(command); 131 132 if (args != null) 133 { 134 if (includeSpace) 135 __commandBuffer.append(' '); 136 __commandBuffer.append(args); 137 } 138 139 __commandBuffer.append(SocketClient.NETASCII_EOL); 140 141 _writer.write(message = __commandBuffer.toString()); 142 _writer.flush(); 143 144 if (_commandSupport_.getListenerCount() > 0) 145 _commandSupport_.fireCommandSent(command, message); 146 147 __getReply(); 148 return _replyCode; 149 } 150 151 private int __sendCommand(int command, String args, boolean includeSpace) 152 throws IOException 153 { 154 return __sendCommand(SMTPCommand._commands[command], args, includeSpace); 155 } 156 157 private void __getReply() throws IOException 158 { 159 int length; 160 161 _newReplyString = true; 162 _replyLines.setSize(0); 163 164 String line = _reader.readLine(); 165 166 if (line == null) 167 throw new SMTPConnectionClosedException( 168 "Connection closed without indication."); 169 170 // In case we run into an anomaly we don't want fatal index exceptions 171 // to be thrown. 172 length = line.length(); 173 if (length < 3) 174 throw new MalformedServerReplyException( 175 "Truncated server reply: " + line); 176 177 try 178 { 179 String code = line.substring(0, 3); 180 _replyCode = Integer.parseInt(code); 181 } 182 catch (NumberFormatException e) 183 { 184 throw new MalformedServerReplyException( 185 "Could not parse response code.\nServer Reply: " + line); 186 } 187 188 _replyLines.addElement(line); 189 190 // Get extra lines if message continues. 191 if (length > 3 && line.charAt(3) == '-') 192 { 193 do 194 { 195 line = _reader.readLine(); 196 197 if (line == null) 198 throw new SMTPConnectionClosedException( 199 "Connection closed without indication."); 200 201 _replyLines.addElement(line); 202 203 // The length() check handles problems that could arise from readLine() 204 // returning too soon after encountering a naked CR or some other 205 // anomaly. 206 } 207 while (!(line.length() >= 4 && line.charAt(3) != '-' && 208 Character.isDigit(line.charAt(0)))); 209 // This is too strong a condition because a non-conforming server 210 // could screw things up like ftp.funet.fi does for FTP 211 // line.startsWith(code))); 212 } 213 214 if (_commandSupport_.getListenerCount() > 0) 215 _commandSupport_.fireReplyReceived(_replyCode, getReplyString()); 216 217 if (_replyCode == SMTPReply.SERVICE_NOT_AVAILABLE) 218 throw new SMTPConnectionClosedException( 219 "SMTP response 421 received. Server closed connection."); 220 } 221 222 /*** Initiates control connections and gets initial reply. ***/ 223 protected void _connectAction_() throws IOException 224 { 225 super._connectAction_(); 226 _reader = 227 new BufferedReader(new InputStreamReader(_input_, 228 __DEFAULT_ENCODING)); 229 _writer = 230 new BufferedWriter(new OutputStreamWriter(_output_, 231 __DEFAULT_ENCODING)); 232 __getReply(); 233 } 234 235 236 /*** 237 * Adds a ProtocolCommandListener. Delegates this task to 238 * {@link #_commandSupport_ _commandSupport_ }. 239 * <p> 240 * @param listener The ProtocolCommandListener to add. 241 ***/ 242 public void addProtocolCommandListener(ProtocolCommandListener listener) 243 { 244 _commandSupport_.addProtocolCommandListener(listener); 245 } 246 247 /*** 248 * Removes a ProtocolCommandListener. Delegates this task to 249 * {@link #_commandSupport_ _commandSupport_ }. 250 * <p> 251 * @param listener The ProtocolCommandListener to remove. 252 ***/ 253 public void removeProtocolCommandistener(ProtocolCommandListener listener) 254 { 255 _commandSupport_.removeProtocolCommandListener(listener); 256 } 257 258 259 /*** 260 * Closes the connection to the SMTP server and sets to null 261 * some internal data so that the memory may be reclaimed by the 262 * garbage collector. The reply text and code information from the 263 * last command is voided so that the memory it used may be reclaimed. 264 * <p> 265 * @exception IOException If an error occurs while disconnecting. 266 ***/ 267 public void disconnect() throws IOException 268 { 269 super.disconnect(); 270 _reader = null; 271 _writer = null; 272 _replyString = null; 273 _replyLines.setSize(0); 274 _newReplyString = false; 275 } 276 277 278 /*** 279 * Sends an SMTP command to the server, waits for a reply and returns the 280 * numerical response code. After invocation, for more detailed 281 * information, the actual reply text can be accessed by calling 282 * {@link #getReplyString getReplyString } or 283 * {@link #getReplyStrings getReplyStrings }. 284 * <p> 285 * @param command The text representation of the SMTP command to send. 286 * @param args The arguments to the SMTP command. If this parameter is 287 * set to null, then the command is sent with no argument. 288 * @return The integer value of the SMTP reply code returned by the server 289 * in response to the command. 290 * @exception SMTPConnectionClosedException 291 * If the SMTP server prematurely closes the connection as a result 292 * of the client being idle or some other reason causing the server 293 * to send SMTP reply code 421. This exception may be caught either 294 * as an IOException or independently as itself. 295 * @exception IOException If an I/O error occurs while either sending the 296 * command or receiving the server reply. 297 ***/ 298 public int sendCommand(String command, String args) throws IOException 299 { 300 return __sendCommand(command, args, true); 301 } 302 303 304 /*** 305 * Sends an SMTP command to the server, waits for a reply and returns the 306 * numerical response code. After invocation, for more detailed 307 * information, the actual reply text can be accessed by calling 308 * {@link #getReplyString getReplyString } or 309 * {@link #getReplyStrings getReplyStrings }. 310 * <p> 311 * @param command The SMTPCommand constant corresponding to the SMTP command 312 * to send. 313 * @param args The arguments to the SMTP command. If this parameter is 314 * set to null, then the command is sent with no argument. 315 * @return The integer value of the SMTP reply code returned by the server 316 * in response to the command. 317 * @exception SMTPConnectionClosedException 318 * If the SMTP server prematurely closes the connection as a result 319 * of the client being idle or some other reason causing the server 320 * to send SMTP reply code 421. This exception may be caught either 321 * as an IOException or independently as itself. 322 * @exception IOException If an I/O error occurs while either sending the 323 * command or receiving the server reply. 324 ***/ 325 public int sendCommand(int command, String args) throws IOException 326 { 327 return sendCommand(SMTPCommand._commands[command], args); 328 } 329 330 331 /*** 332 * Sends an SMTP command with no arguments to the server, waits for a 333 * reply and returns the numerical response code. After invocation, for 334 * more detailed information, the actual reply text can be accessed by 335 * calling {@link #getReplyString getReplyString } or 336 * {@link #getReplyStrings getReplyStrings }. 337 * <p> 338 * @param command The text representation of the SMTP command to send. 339 * @return The integer value of the SMTP reply code returned by the server 340 * in response to the command. 341 * @exception SMTPConnectionClosedException 342 * If the SMTP server prematurely closes the connection as a result 343 * of the client being idle or some other reason causing the server 344 * to send SMTP reply code 421. This exception may be caught either 345 * as an IOException or independently as itself. 346 * @exception IOException If an I/O error occurs while either sending the 347 * command or receiving the server reply. 348 ***/ 349 public int sendCommand(String command) throws IOException 350 { 351 return sendCommand(command, null); 352 } 353 354 355 /*** 356 * Sends an SMTP command with no arguments to the server, waits for a 357 * reply and returns the numerical response code. After invocation, for 358 * more detailed information, the actual reply text can be accessed by 359 * calling {@link #getReplyString getReplyString } or 360 * {@link #getReplyStrings getReplyStrings }. 361 * <p> 362 * @param command The SMTPCommand constant corresponding to the SMTP command 363 * to send. 364 * @return The integer value of the SMTP reply code returned by the server 365 * in response to the command. 366 * @exception SMTPConnectionClosedException 367 * If the SMTP server prematurely closes the connection as a result 368 * of the client being idle or some other reason causing the server 369 * to send SMTP reply code 421. This exception may be caught either 370 * as an IOException or independently as itself. 371 * @exception IOException If an I/O error occurs while either sending the 372 * command or receiving the server reply. 373 ***/ 374 public int sendCommand(int command) throws IOException 375 { 376 return sendCommand(command, null); 377 } 378 379 380 /*** 381 * Returns the integer value of the reply code of the last SMTP reply. 382 * You will usually only use this method after you connect to the 383 * SMTP server to check that the connection was successful since 384 * <code> connect </code> is of type void. 385 * <p> 386 * @return The integer value of the reply code of the last SMTP reply. 387 ***/ 388 public int getReplyCode() 389 { 390 return _replyCode; 391 } 392 393 /*** 394 * Fetches a reply from the SMTP server and returns the integer reply 395 * code. After calling this method, the actual reply text can be accessed 396 * from either calling {@link #getReplyString getReplyString } or 397 * {@link #getReplyStrings getReplyStrings }. Only use this 398 * method if you are implementing your own SMTP client or if you need to 399 * fetch a secondary response from the SMTP server. 400 * <p> 401 * @return The integer value of the reply code of the fetched SMTP reply. 402 * @exception SMTPConnectionClosedException 403 * If the SMTP server prematurely closes the connection as a result 404 * of the client being idle or some other reason causing the server 405 * to send SMTP reply code 421. This exception may be caught either 406 * as an IOException or independently as itself. 407 * @exception IOException If an I/O error occurs while receiving the 408 * server reply. 409 ***/ 410 public int getReply() throws IOException 411 { 412 __getReply(); 413 return _replyCode; 414 } 415 416 417 /*** 418 * Returns the lines of text from the last SMTP server response as an array 419 * of strings, one entry per line. The end of line markers of each are 420 * stripped from each line. 421 * <p> 422 * @return The lines of text from the last SMTP response as an array. 423 ***/ 424 public String[] getReplyStrings() 425 { 426 String[] lines; 427 lines = new String[_replyLines.size()]; 428 _replyLines.copyInto(lines); 429 return lines; 430 } 431 432 /*** 433 * Returns the entire text of the last SMTP server response exactly 434 * as it was received, including all end of line markers in NETASCII 435 * format. 436 * <p> 437 * @return The entire text from the last SMTP response as a String. 438 ***/ 439 public String getReplyString() 440 { 441 Enumeration en; 442 StringBuffer buffer; 443 444 if (!_newReplyString) 445 return _replyString; 446 447 buffer = new StringBuffer(256); 448 en = _replyLines.elements(); 449 while (en.hasMoreElements()) 450 { 451 buffer.append((String)en.nextElement()); 452 buffer.append(SocketClient.NETASCII_EOL); 453 } 454 455 _newReplyString = false; 456 457 return (_replyString = buffer.toString()); 458 } 459 460 461 /*** 462 * A convenience method to send the SMTP HELO command to the server, 463 * receive the reply, and return the reply code. 464 * <p> 465 * @param hostname The hostname of the sender. 466 * @return The reply code received from the server. 467 * @exception SMTPConnectionClosedException 468 * If the SMTP server prematurely closes the connection as a result 469 * of the client being idle or some other reason causing the server 470 * to send SMTP reply code 421. This exception may be caught either 471 * as an IOException or independently as itself. 472 * @exception IOException If an I/O error occurs while either sending the 473 * command or receiving the server reply. 474 ***/ 475 public int helo(String hostname) throws IOException 476 { 477 return sendCommand(SMTPCommand.HELO, hostname); 478 } 479 480 481 /*** 482 * A convenience method to send the SMTP MAIL command to the server, 483 * receive the reply, and return the reply code. 484 * <p> 485 * @param reversePath The reverese path. 486 * @return The reply code received from the server. 487 * @exception SMTPConnectionClosedException 488 * If the SMTP server prematurely closes the connection as a result 489 * of the client being idle or some other reason causing the server 490 * to send SMTP reply code 421. This exception may be caught either 491 * as an IOException or independently as itself. 492 * @exception IOException If an I/O error occurs while either sending the 493 * command or receiving the server reply. 494 ***/ 495 public int mail(String reversePath) throws IOException 496 { 497 return __sendCommand(SMTPCommand.MAIL, reversePath, false); 498 } 499 500 501 /*** 502 * A convenience method to send the SMTP RCPT command to the server, 503 * receive the reply, and return the reply code. 504 * <p> 505 * @param forwardPath The forward path. 506 * @return The reply code received from the server. 507 * @exception SMTPConnectionClosedException 508 * If the SMTP server prematurely closes the connection as a result 509 * of the client being idle or some other reason causing the server 510 * to send SMTP reply code 421. This exception may be caught either 511 * as an IOException or independently as itself. 512 * @exception IOException If an I/O error occurs while either sending the 513 * command or receiving the server reply. 514 ***/ 515 public int rcpt(String forwardPath) throws IOException 516 { 517 return __sendCommand(SMTPCommand.RCPT, forwardPath, false); 518 } 519 520 521 /*** 522 * A convenience method to send the SMTP DATA command to the server, 523 * receive the reply, and return the reply code. 524 * <p> 525 * @return The reply code received from the server. 526 * @exception SMTPConnectionClosedException 527 * If the SMTP server prematurely closes the connection as a result 528 * of the client being idle or some other reason causing the server 529 * to send SMTP reply code 421. This exception may be caught either 530 * as an IOException or independently as itself. 531 * @exception IOException If an I/O error occurs while either sending the 532 * command or receiving the server reply. 533 ***/ 534 public int data() throws IOException 535 { 536 return sendCommand(SMTPCommand.DATA); 537 } 538 539 540 /*** 541 * A convenience method to send the SMTP SEND command to the server, 542 * receive the reply, and return the reply code. 543 * <p> 544 * @param reversePath The reverese path. 545 * @return The reply code received from the server. 546 * @exception SMTPConnectionClosedException 547 * If the SMTP server prematurely closes the connection as a result 548 * of the client being idle or some other reason causing the server 549 * to send SMTP reply code 421. This exception may be caught either 550 * as an IOException or independently as itself. 551 * @exception IOException If an I/O error occurs while either sending the 552 * command or receiving the server reply. 553 ***/ 554 public int send(String reversePath) throws IOException 555 { 556 return sendCommand(SMTPCommand.SEND, reversePath); 557 } 558 559 560 /*** 561 * A convenience method to send the SMTP SOML command to the server, 562 * receive the reply, and return the reply code. 563 * <p> 564 * @param reversePath The reverese path. 565 * @return The reply code received from the server. 566 * @exception SMTPConnectionClosedException 567 * If the SMTP server prematurely closes the connection as a result 568 * of the client being idle or some other reason causing the server 569 * to send SMTP reply code 421. This exception may be caught either 570 * as an IOException or independently as itself. 571 * @exception IOException If an I/O error occurs while either sending the 572 * command or receiving the server reply. 573 ***/ 574 public int soml(String reversePath) throws IOException 575 { 576 return sendCommand(SMTPCommand.SOML, reversePath); 577 } 578 579 580 /*** 581 * A convenience method to send the SMTP SAML command to the server, 582 * receive the reply, and return the reply code. 583 * <p> 584 * @param reversePath The reverese path. 585 * @return The reply code received from the server. 586 * @exception SMTPConnectionClosedException 587 * If the SMTP server prematurely closes the connection as a result 588 * of the client being idle or some other reason causing the server 589 * to send SMTP reply code 421. This exception may be caught either 590 * as an IOException or independently as itself. 591 * @exception IOException If an I/O error occurs while either sending the 592 * command or receiving the server reply. 593 ***/ 594 public int saml(String reversePath) throws IOException 595 { 596 return sendCommand(SMTPCommand.SAML, reversePath); 597 } 598 599 600 /*** 601 * A convenience method to send the SMTP RSET command to the server, 602 * receive the reply, and return the reply code. 603 * <p> 604 * @return The reply code received from the server. 605 * @exception SMTPConnectionClosedException 606 * If the SMTP server prematurely closes the connection as a result 607 * of the client being idle or some other reason causing the server 608 * to send SMTP reply code 421. This exception may be caught either 609 * as an IOException or independently as itself. 610 * @exception IOException If an I/O error occurs while either sending the 611 * command or receiving the server reply. 612 ***/ 613 public int rset() throws IOException 614 { 615 return sendCommand(SMTPCommand.RSET); 616 } 617 618 619 /*** 620 * A convenience method to send the SMTP VRFY command to the server, 621 * receive the reply, and return the reply code. 622 * <p> 623 * @param user The user address to verify. 624 * @return The reply code received from the server. 625 * @exception SMTPConnectionClosedException 626 * If the SMTP server prematurely closes the connection as a result 627 * of the client being idle or some other reason causing the server 628 * to send SMTP reply code 421. This exception may be caught either 629 * as an IOException or independently as itself. 630 * @exception IOException If an I/O error occurs while either sending the 631 * command or receiving the server reply. 632 ***/ 633 public int vrfy(String user) throws IOException 634 { 635 return sendCommand(SMTPCommand.VRFY, user); 636 } 637 638 639 /*** 640 * A convenience method to send the SMTP VRFY command to the server, 641 * receive the reply, and return the reply code. 642 * <p> 643 * @param name The name to expand. 644 * @return The reply code received from the server. 645 * @exception SMTPConnectionClosedException 646 * If the SMTP server prematurely closes the connection as a result 647 * of the client being idle or some other reason causing the server 648 * to send SMTP reply code 421. This exception may be caught either 649 * as an IOException or independently as itself. 650 * @exception IOException If an I/O error occurs while either sending the 651 * command or receiving the server reply. 652 ***/ 653 public int expn(String name) throws IOException 654 { 655 return sendCommand(SMTPCommand.EXPN, name); 656 } 657 658 /*** 659 * A convenience method to send the SMTP HELP command to the server, 660 * receive the reply, and return the reply code. 661 * <p> 662 * @return The reply code received from the server. 663 * @exception SMTPConnectionClosedException 664 * If the SMTP server prematurely closes the connection as a result 665 * of the client being idle or some other reason causing the server 666 * to send SMTP reply code 421. This exception may be caught either 667 * as an IOException or independently as itself. 668 * @exception IOException If an I/O error occurs while either sending the 669 * command or receiving the server reply. 670 ***/ 671 public int help() throws IOException 672 { 673 return sendCommand(SMTPCommand.HELP); 674 } 675 676 /*** 677 * A convenience method to send the SMTP HELP command to the server, 678 * receive the reply, and return the reply code. 679 * <p> 680 * @param command The command name on which to request help. 681 * @return The reply code received from the server. 682 * @exception SMTPConnectionClosedException 683 * If the SMTP server prematurely closes the connection as a result 684 * of the client being idle or some other reason causing the server 685 * to send SMTP reply code 421. This exception may be caught either 686 * as an IOException or independently as itself. 687 * @exception IOException If an I/O error occurs while either sending the 688 * command or receiving the server reply. 689 ***/ 690 public int help(String command) throws IOException 691 { 692 return sendCommand(SMTPCommand.HELP, command); 693 } 694 695 /*** 696 * A convenience method to send the SMTP NOOP command to the server, 697 * receive the reply, and return the reply code. 698 * <p> 699 * @return The reply code received from the server. 700 * @exception SMTPConnectionClosedException 701 * If the SMTP server prematurely closes the connection as a result 702 * of the client being idle or some other reason causing the server 703 * to send SMTP reply code 421. This exception may be caught either 704 * as an IOException or independently as itself. 705 * @exception IOException If an I/O error occurs while either sending the 706 * command or receiving the server reply. 707 ***/ 708 public int noop() throws IOException 709 { 710 return sendCommand(SMTPCommand.NOOP); 711 } 712 713 714 /*** 715 * A convenience method to send the SMTP TURN command to the server, 716 * receive the reply, and return the reply code. 717 * <p> 718 * @return The reply code received from the server. 719 * @exception SMTPConnectionClosedException 720 * If the SMTP server prematurely closes the connection as a result 721 * of the client being idle or some other reason causing the server 722 * to send SMTP reply code 421. This exception may be caught either 723 * as an IOException or independently as itself. 724 * @exception IOException If an I/O error occurs while either sending the 725 * command or receiving the server reply. 726 ***/ 727 public int turn() throws IOException 728 { 729 return sendCommand(SMTPCommand.TURN); 730 } 731 732 733 /*** 734 * A convenience method to send the SMTP QUIT command to the server, 735 * receive the reply, and return the reply code. 736 * <p> 737 * @return The reply code received from the server. 738 * @exception SMTPConnectionClosedException 739 * If the SMTP server prematurely closes the connection as a result 740 * of the client being idle or some other reason causing the server 741 * to send SMTP reply code 421. This exception may be caught either 742 * as an IOException or independently as itself. 743 * @exception IOException If an I/O error occurs while either sending the 744 * command or receiving the server reply. 745 ***/ 746 public int quit() throws IOException 747 { 748 return sendCommand(SMTPCommand.QUIT); 749 } 750 751 } 752 753 /* Emacs configuration 754 * Local variables: ** 755 * mode: java ** 756 * c-basic-offset: 4 ** 757 * indent-tabs-mode: nil ** 758 * End: ** 759 */