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