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(String encoding) { 131 setDefaultPort(DEFAULT_PORT); 132 _replyLines = new ArrayList<String>(); 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(String command, String args, boolean includeSpace) 149 throws IOException 150 { 151 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 String message; 165 _writer.write(message = __commandBuffer.toString()); 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(int command, String args, 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 String code = line.substring(0, 3); 213 _replyCode = Integer.parseInt(code); 214 } 215 catch (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(String command, 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(int command, 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(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(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 (String line : _replyLines) 461 { 462 buffer.append(line); 463 buffer.append(SocketClient.NETASCII_EOL); 464 } 465 466 _newReplyString = false; 467 468 return (_replyString = buffer.toString()); 469 } 470 471 472 /*** 473 * A convenience method to send the SMTP HELO command to the server, 474 * receive the reply, and return the reply code. 475 * <p> 476 * @param hostname The hostname of the sender. 477 * @return The reply code received from the server. 478 * @throws SMTPConnectionClosedException 479 * If the SMTP server prematurely closes the connection as a result 480 * of the client being idle or some other reason causing the server 481 * to send SMTP reply code 421. This exception may be caught either 482 * as an IOException or independently as itself. 483 * @throws IOException If an I/O error occurs while either sending the 484 * command or receiving the server reply. 485 ***/ 486 public int helo(String hostname) throws IOException 487 { 488 return sendCommand(SMTPCommand.HELO, hostname); 489 } 490 491 492 /*** 493 * A convenience method to send the SMTP MAIL command to the server, 494 * receive the reply, and return the reply code. 495 * <p> 496 * @param reversePath The reverese path. 497 * @return The reply code received from the server. 498 * @throws SMTPConnectionClosedException 499 * If the SMTP server prematurely closes the connection as a result 500 * of the client being idle or some other reason causing the server 501 * to send SMTP reply code 421. This exception may be caught either 502 * as an IOException or independently as itself. 503 * @throws IOException If an I/O error occurs while either sending the 504 * command or receiving the server reply. 505 ***/ 506 public int mail(String reversePath) throws IOException 507 { 508 return __sendCommand(SMTPCommand.MAIL, reversePath, false); 509 } 510 511 512 /*** 513 * A convenience method to send the SMTP RCPT command to the server, 514 * receive the reply, and return the reply code. 515 * <p> 516 * @param forwardPath The forward path. 517 * @return The reply code received from the server. 518 * @throws SMTPConnectionClosedException 519 * If the SMTP server prematurely closes the connection as a result 520 * of the client being idle or some other reason causing the server 521 * to send SMTP reply code 421. This exception may be caught either 522 * as an IOException or independently as itself. 523 * @throws IOException If an I/O error occurs while either sending the 524 * command or receiving the server reply. 525 ***/ 526 public int rcpt(String forwardPath) throws IOException 527 { 528 return __sendCommand(SMTPCommand.RCPT, forwardPath, false); 529 } 530 531 532 /*** 533 * A convenience method to send the SMTP DATA command to the server, 534 * receive the reply, and return the reply code. 535 * <p> 536 * @return The reply code received from the server. 537 * @throws SMTPConnectionClosedException 538 * If the SMTP server prematurely closes the connection as a result 539 * of the client being idle or some other reason causing the server 540 * to send SMTP reply code 421. This exception may be caught either 541 * as an IOException or independently as itself. 542 * @throws IOException If an I/O error occurs while either sending the 543 * command or receiving the server reply. 544 ***/ 545 public int data() throws IOException 546 { 547 return sendCommand(SMTPCommand.DATA); 548 } 549 550 551 /*** 552 * A convenience method to send the SMTP SEND command to the server, 553 * receive the reply, and return the reply code. 554 * <p> 555 * @param reversePath The reverese path. 556 * @return The reply code received from the server. 557 * @throws SMTPConnectionClosedException 558 * If the SMTP server prematurely closes the connection as a result 559 * of the client being idle or some other reason causing the server 560 * to send SMTP reply code 421. This exception may be caught either 561 * as an IOException or independently as itself. 562 * @throws IOException If an I/O error occurs while either sending the 563 * command or receiving the server reply. 564 ***/ 565 public int send(String reversePath) throws IOException 566 { 567 return sendCommand(SMTPCommand.SEND, reversePath); 568 } 569 570 571 /*** 572 * A convenience method to send the SMTP SOML command to the server, 573 * receive the reply, and return the reply code. 574 * <p> 575 * @param reversePath The reverese path. 576 * @return The reply code received from the server. 577 * @throws SMTPConnectionClosedException 578 * If the SMTP server prematurely closes the connection as a result 579 * of the client being idle or some other reason causing the server 580 * to send SMTP reply code 421. This exception may be caught either 581 * as an IOException or independently as itself. 582 * @throws IOException If an I/O error occurs while either sending the 583 * command or receiving the server reply. 584 ***/ 585 public int soml(String reversePath) throws IOException 586 { 587 return sendCommand(SMTPCommand.SOML, reversePath); 588 } 589 590 591 /*** 592 * A convenience method to send the SMTP SAML command to the server, 593 * receive the reply, and return the reply code. 594 * <p> 595 * @param reversePath The reverese path. 596 * @return The reply code received from the server. 597 * @throws SMTPConnectionClosedException 598 * If the SMTP server prematurely closes the connection as a result 599 * of the client being idle or some other reason causing the server 600 * to send SMTP reply code 421. This exception may be caught either 601 * as an IOException or independently as itself. 602 * @throws IOException If an I/O error occurs while either sending the 603 * command or receiving the server reply. 604 ***/ 605 public int saml(String reversePath) throws IOException 606 { 607 return sendCommand(SMTPCommand.SAML, reversePath); 608 } 609 610 611 /*** 612 * A convenience method to send the SMTP RSET command to the server, 613 * receive the reply, and return the reply code. 614 * <p> 615 * @return The reply code received from the server. 616 * @throws SMTPConnectionClosedException 617 * If the SMTP server prematurely closes the connection as a result 618 * of the client being idle or some other reason causing the server 619 * to send SMTP reply code 421. This exception may be caught either 620 * as an IOException or independently as itself. 621 * @throws IOException If an I/O error occurs while either sending the 622 * command or receiving the server reply. 623 ***/ 624 public int rset() throws IOException 625 { 626 return sendCommand(SMTPCommand.RSET); 627 } 628 629 630 /*** 631 * A convenience method to send the SMTP VRFY command to the server, 632 * receive the reply, and return the reply code. 633 * <p> 634 * @param user The user address to verify. 635 * @return The reply code received from the server. 636 * @throws SMTPConnectionClosedException 637 * If the SMTP server prematurely closes the connection as a result 638 * of the client being idle or some other reason causing the server 639 * to send SMTP reply code 421. This exception may be caught either 640 * as an IOException or independently as itself. 641 * @throws IOException If an I/O error occurs while either sending the 642 * command or receiving the server reply. 643 ***/ 644 public int vrfy(String user) throws IOException 645 { 646 return sendCommand(SMTPCommand.VRFY, user); 647 } 648 649 650 /*** 651 * A convenience method to send the SMTP VRFY command to the server, 652 * receive the reply, and return the reply code. 653 * <p> 654 * @param name The name to expand. 655 * @return The reply code received from the server. 656 * @throws SMTPConnectionClosedException 657 * If the SMTP server prematurely closes the connection as a result 658 * of the client being idle or some other reason causing the server 659 * to send SMTP reply code 421. This exception may be caught either 660 * as an IOException or independently as itself. 661 * @throws IOException If an I/O error occurs while either sending the 662 * command or receiving the server reply. 663 ***/ 664 public int expn(String name) throws IOException 665 { 666 return sendCommand(SMTPCommand.EXPN, name); 667 } 668 669 /*** 670 * A convenience method to send the SMTP HELP command to the server, 671 * receive the reply, and return the reply code. 672 * <p> 673 * @return The reply code received from the server. 674 * @throws SMTPConnectionClosedException 675 * If the SMTP server prematurely closes the connection as a result 676 * of the client being idle or some other reason causing the server 677 * to send SMTP reply code 421. This exception may be caught either 678 * as an IOException or independently as itself. 679 * @throws IOException If an I/O error occurs while either sending the 680 * command or receiving the server reply. 681 ***/ 682 public int help() throws IOException 683 { 684 return sendCommand(SMTPCommand.HELP); 685 } 686 687 /*** 688 * A convenience method to send the SMTP HELP command to the server, 689 * receive the reply, and return the reply code. 690 * <p> 691 * @param command The command name on which to request help. 692 * @return The reply code received from the server. 693 * @throws SMTPConnectionClosedException 694 * If the SMTP server prematurely closes the connection as a result 695 * of the client being idle or some other reason causing the server 696 * to send SMTP reply code 421. This exception may be caught either 697 * as an IOException or independently as itself. 698 * @throws IOException If an I/O error occurs while either sending the 699 * command or receiving the server reply. 700 ***/ 701 public int help(String command) throws IOException 702 { 703 return sendCommand(SMTPCommand.HELP, command); 704 } 705 706 /*** 707 * A convenience method to send the SMTP NOOP command to the server, 708 * receive the reply, and return the reply code. 709 * <p> 710 * @return The reply code received from the server. 711 * @throws SMTPConnectionClosedException 712 * If the SMTP server prematurely closes the connection as a result 713 * of the client being idle or some other reason causing the server 714 * to send SMTP reply code 421. This exception may be caught either 715 * as an IOException or independently as itself. 716 * @throws IOException If an I/O error occurs while either sending the 717 * command or receiving the server reply. 718 ***/ 719 public int noop() throws IOException 720 { 721 return sendCommand(SMTPCommand.NOOP); 722 } 723 724 725 /*** 726 * A convenience method to send the SMTP TURN command to the server, 727 * receive the reply, and return the reply code. 728 * <p> 729 * @return The reply code received from the server. 730 * @throws SMTPConnectionClosedException 731 * If the SMTP server prematurely closes the connection as a result 732 * of the client being idle or some other reason causing the server 733 * to send SMTP reply code 421. This exception may be caught either 734 * as an IOException or independently as itself. 735 * @throws IOException If an I/O error occurs while either sending the 736 * command or receiving the server reply. 737 ***/ 738 public int turn() throws IOException 739 { 740 return sendCommand(SMTPCommand.TURN); 741 } 742 743 744 /*** 745 * A convenience method to send the SMTP QUIT command to the server, 746 * receive the reply, and return the reply code. 747 * <p> 748 * @return The reply code received from the server. 749 * @throws SMTPConnectionClosedException 750 * If the SMTP server prematurely closes the connection as a result 751 * of the client being idle or some other reason causing the server 752 * to send SMTP reply code 421. This exception may be caught either 753 * as an IOException or independently as itself. 754 * @throws IOException If an I/O error occurs while either sending the 755 * command or receiving the server reply. 756 ***/ 757 public int quit() throws IOException 758 { 759 return sendCommand(SMTPCommand.QUIT); 760 } 761 762 /** 763 * Removes a ProtocolCommandListener. 764 * 765 * Delegates this incorrectly named method - removeProtocolCommandistener (note the missing "L")- to 766 * the correct method {@link SocketClient#removeProtocolCommandListener} 767 * @param listener The ProtocolCommandListener to remove 768 */ 769 public void removeProtocolCommandistener(org.apache.commons.net.ProtocolCommandListener listener){ 770 removeProtocolCommandListener(listener); 771 } 772 773 /** 774 * Provide command support to super-class 775 */ 776 @Override 777 protected ProtocolCommandSupport getCommandSupport() { 778 return _commandSupport_; 779 } 780} 781 782/* Emacs configuration 783 * Local variables: ** 784 * mode: java ** 785 * c-basic-offset: 4 ** 786 * indent-tabs-mode: nil ** 787 * End: ** 788 */