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