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 /** 096 * The encoding to use (user-settable). 097 * 098 * @since 3.1 (changed from private to protected) 099 */ 100 protected final String encoding; 101 102 /** 103 * A ProtocolCommandSupport object used to manage the registering of 104 * ProtocolCommandListeners and te firing of ProtocolCommandEvents. 105 */ 106 protected ProtocolCommandSupport _commandSupport_; 107 108 BufferedReader _reader; 109 BufferedWriter _writer; 110 111 private int _replyCode; 112 private final ArrayList<String> _replyLines; 113 private boolean _newReplyString; 114 private String _replyString; 115 116 /*** 117 * The default SMTP constructor. Sets the default port to 118 * <code>DEFAULT_PORT</code> and initializes internal data structures 119 * for saving SMTP reply information. 120 ***/ 121 public SMTP() 122 { 123 this(__DEFAULT_ENCODING); 124 } 125 126 /** 127 * Overloaded constructor where the user may specify a default encoding. 128 * @param encoding 129 * @since 2.0 130 */ 131 public SMTP(String encoding) { 132 setDefaultPort(DEFAULT_PORT); 133 _replyLines = new ArrayList<String>(); 134 _newReplyString = false; 135 _replyString = null; 136 _commandSupport_ = new ProtocolCommandSupport(this); 137 this.encoding = encoding; 138 } 139 140 /** 141 * Send a command to the server. May also be used to send text data. 142 * 143 * @param command the command to send (as a plain String) 144 * @param args the command arguments, may be {@code null} 145 * @param includeSpace if {@code true}, add a space between the command and its arguments 146 * @return the reply code 147 * @throws IOException 148 */ 149 private int __sendCommand(String command, String args, boolean includeSpace) 150 throws IOException 151 { 152 StringBuilder __commandBuffer = new StringBuilder(); 153 __commandBuffer.append(command); 154 155 if (args != null) 156 { 157 if (includeSpace) { 158 __commandBuffer.append(' '); 159 } 160 __commandBuffer.append(args); 161 } 162 163 __commandBuffer.append(SocketClient.NETASCII_EOL); 164 165 String message; 166 _writer.write(message = __commandBuffer.toString()); 167 _writer.flush(); 168 169 fireCommandSent(command, message); 170 171 __getReply(); 172 return _replyCode; 173 } 174 175 /** 176 * 177 * @param command the command to send (as an int defined in {@link SMPTCommand}) 178 * @param args the command arguments, may be {@code null} 179 * @param includeSpace if {@code true}, add a space between the command and its arguments 180 * @return the reply code 181 * @throws IOException 182 */ 183 private int __sendCommand(int command, String args, boolean includeSpace) 184 throws IOException 185 { 186 return __sendCommand(SMTPCommand.getCommand(command), args, includeSpace); 187 } 188 189 private void __getReply() throws IOException 190 { 191 int length; 192 193 _newReplyString = true; 194 _replyLines.clear(); 195 196 String line = _reader.readLine(); 197 198 if (line == null) { 199 throw new SMTPConnectionClosedException( 200 "Connection closed without indication."); 201 } 202 203 // In case we run into an anomaly we don't want fatal index exceptions 204 // to be thrown. 205 length = line.length(); 206 if (length < 3) { 207 throw new MalformedServerReplyException( 208 "Truncated server reply: " + line); 209 } 210 211 try 212 { 213 String code = line.substring(0, 3); 214 _replyCode = Integer.parseInt(code); 215 } 216 catch (NumberFormatException e) 217 { 218 throw new MalformedServerReplyException( 219 "Could not parse response code.\nServer Reply: " + line); 220 } 221 222 _replyLines.add(line); 223 224 // Get extra lines if message continues. 225 if (length > 3 && line.charAt(3) == '-') 226 { 227 do 228 { 229 line = _reader.readLine(); 230 231 if (line == null) { 232 throw new SMTPConnectionClosedException( 233 "Connection closed without indication."); 234 } 235 236 _replyLines.add(line); 237 238 // The length() check handles problems that could arise from readLine() 239 // returning too soon after encountering a naked CR or some other 240 // anomaly. 241 } 242 while (!(line.length() >= 4 && line.charAt(3) != '-' && 243 Character.isDigit(line.charAt(0)))); 244 // This is too strong a condition because a non-conforming server 245 // could screw things up like ftp.funet.fi does for FTP 246 // line.startsWith(code))); 247 } 248 249 fireReplyReceived(_replyCode, getReplyString()); 250 251 if (_replyCode == SMTPReply.SERVICE_NOT_AVAILABLE) { 252 throw new SMTPConnectionClosedException( 253 "SMTP response 421 received. Server closed connection."); 254 } 255 } 256 257 /*** Initiates control connections and gets initial reply. ***/ 258 @Override 259 protected void _connectAction_() throws IOException 260 { 261 super._connectAction_(); 262 _reader = 263 new CRLFLineReader(new InputStreamReader(_input_, 264 encoding)); 265 _writer = 266 new BufferedWriter(new OutputStreamWriter(_output_, 267 encoding)); 268 __getReply(); 269 270 } 271 272 273 /*** 274 * Closes the connection to the SMTP server and sets to null 275 * some internal data so that the memory may be reclaimed by the 276 * garbage collector. The reply text and code information from the 277 * last command is voided so that the memory it used may be reclaimed. 278 * <p> 279 * @exception IOException If an error occurs while disconnecting. 280 ***/ 281 @Override 282 public void disconnect() throws IOException 283 { 284 super.disconnect(); 285 _reader = null; 286 _writer = null; 287 _replyString = null; 288 _replyLines.clear(); 289 _newReplyString = false; 290 } 291 292 293 /*** 294 * Sends an SMTP command to the server, waits for a reply and returns the 295 * numerical response code. After invocation, for more detailed 296 * information, the actual reply text can be accessed by calling 297 * {@link #getReplyString getReplyString } or 298 * {@link #getReplyStrings getReplyStrings }. 299 * <p> 300 * @param command The text representation of the SMTP command to send. 301 * @param args The arguments to the SMTP command. If this parameter is 302 * set to null, then the command is sent with no argument. 303 * @return The integer value of the SMTP reply code returned by the server 304 * in response to the command. 305 * @exception SMTPConnectionClosedException 306 * If the SMTP server prematurely closes the connection as a result 307 * of the client being idle or some other reason causing the server 308 * to send SMTP reply code 421. This exception may be caught either 309 * as an IOException or independently as itself. 310 * @exception IOException If an I/O error occurs while either sending the 311 * command or receiving the server reply. 312 ***/ 313 public int sendCommand(String command, String args) throws IOException 314 { 315 return __sendCommand(command, args, true); 316 } 317 318 319 /*** 320 * Sends an SMTP command to the server, waits for a reply and returns the 321 * numerical response code. After invocation, for more detailed 322 * information, the actual reply text can be accessed by calling 323 * {@link #getReplyString getReplyString } or 324 * {@link #getReplyStrings getReplyStrings }. 325 * <p> 326 * @param command The SMTPCommand constant corresponding to the SMTP command 327 * to send. 328 * @param args The arguments to the SMTP command. If this parameter is 329 * set to null, then the command is sent with no argument. 330 * @return The integer value of the SMTP reply code returned by the server 331 * in response to the command. 332 * @exception SMTPConnectionClosedException 333 * If the SMTP server prematurely closes the connection as a result 334 * of the client being idle or some other reason causing the server 335 * to send SMTP reply code 421. This exception may be caught either 336 * as an IOException or independently as itself. 337 * @exception IOException If an I/O error occurs while either sending the 338 * command or receiving the server reply. 339 ***/ 340 public int sendCommand(int command, String args) throws IOException 341 { 342 return sendCommand(SMTPCommand.getCommand(command), args); 343 } 344 345 346 /*** 347 * Sends an SMTP command with no arguments to the server, waits for a 348 * reply and returns the numerical response code. After invocation, for 349 * more detailed information, the actual reply text can be accessed by 350 * calling {@link #getReplyString getReplyString } or 351 * {@link #getReplyStrings getReplyStrings }. 352 * <p> 353 * @param command The text representation of the SMTP command to send. 354 * @return The integer value of the SMTP reply code returned by the server 355 * in response to the command. 356 * @exception SMTPConnectionClosedException 357 * If the SMTP server prematurely closes the connection as a result 358 * of the client being idle or some other reason causing the server 359 * to send SMTP reply code 421. This exception may be caught either 360 * as an IOException or independently as itself. 361 * @exception IOException If an I/O error occurs while either sending the 362 * command or receiving the server reply. 363 ***/ 364 public int sendCommand(String command) throws IOException 365 { 366 return sendCommand(command, null); 367 } 368 369 370 /*** 371 * Sends an SMTP command with no arguments to the server, waits for a 372 * reply and returns the numerical response code. After invocation, for 373 * more detailed information, the actual reply text can be accessed by 374 * calling {@link #getReplyString getReplyString } or 375 * {@link #getReplyStrings getReplyStrings }. 376 * <p> 377 * @param command The SMTPCommand constant corresponding to the SMTP command 378 * to send. 379 * @return The integer value of the SMTP reply code returned by the server 380 * in response to the command. 381 * @exception SMTPConnectionClosedException 382 * If the SMTP server prematurely closes the connection as a result 383 * of the client being idle or some other reason causing the server 384 * to send SMTP reply code 421. This exception may be caught either 385 * as an IOException or independently as itself. 386 * @exception IOException If an I/O error occurs while either sending the 387 * command or receiving the server reply. 388 ***/ 389 public int sendCommand(int command) throws IOException 390 { 391 return sendCommand(command, null); 392 } 393 394 395 /*** 396 * Returns the integer value of the reply code of the last SMTP reply. 397 * You will usually only use this method after you connect to the 398 * SMTP server to check that the connection was successful since 399 * <code> connect </code> is of type void. 400 * <p> 401 * @return The integer value of the reply code of the last SMTP reply. 402 ***/ 403 public int getReplyCode() 404 { 405 return _replyCode; 406 } 407 408 /*** 409 * Fetches a reply from the SMTP server and returns the integer reply 410 * code. After calling this method, the actual reply text can be accessed 411 * from either calling {@link #getReplyString getReplyString } or 412 * {@link #getReplyStrings getReplyStrings }. Only use this 413 * method if you are implementing your own SMTP client or if you need to 414 * fetch a secondary response from the SMTP server. 415 * <p> 416 * @return The integer value of the reply code of the fetched SMTP reply. 417 * @exception SMTPConnectionClosedException 418 * If the SMTP server prematurely closes the connection as a result 419 * of the client being idle or some other reason causing the server 420 * to send SMTP reply code 421. This exception may be caught either 421 * as an IOException or independently as itself. 422 * @exception IOException If an I/O error occurs while receiving the 423 * server reply. 424 ***/ 425 public int getReply() throws IOException 426 { 427 __getReply(); 428 return _replyCode; 429 } 430 431 432 /*** 433 * Returns the lines of text from the last SMTP server response as an array 434 * of strings, one entry per line. The end of line markers of each are 435 * stripped from each line. 436 * <p> 437 * @return The lines of text from the last SMTP response as an array. 438 ***/ 439 public String[] getReplyStrings() 440 { 441 return _replyLines.toArray(new String[_replyLines.size()]); 442 } 443 444 /*** 445 * Returns the entire text of the last SMTP server response exactly 446 * as it was received, including all end of line markers in NETASCII 447 * format. 448 * <p> 449 * @return The entire text from the last SMTP response as a String. 450 ***/ 451 public String getReplyString() 452 { 453 StringBuilder buffer; 454 455 if (!_newReplyString) { 456 return _replyString; 457 } 458 459 buffer = new StringBuilder(); 460 461 for (String line : _replyLines) 462 { 463 buffer.append(line); 464 buffer.append(SocketClient.NETASCII_EOL); 465 } 466 467 _newReplyString = false; 468 469 return (_replyString = buffer.toString()); 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 * @exception 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 * @exception IOException If an I/O error occurs while either sending the 485 * command or receiving the server reply. 486 ***/ 487 public int helo(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 * @exception 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 * @exception IOException If an I/O error occurs while either sending the 505 * command or receiving the server reply. 506 ***/ 507 public int mail(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 * @exception 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 * @exception IOException If an I/O error occurs while either sending the 525 * command or receiving the server reply. 526 ***/ 527 public int rcpt(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 * @exception 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 * @exception 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 * @exception 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 * @exception IOException If an I/O error occurs while either sending the 564 * command or receiving the server reply. 565 ***/ 566 public int send(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 * @exception 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 * @exception IOException If an I/O error occurs while either sending the 584 * command or receiving the server reply. 585 ***/ 586 public int soml(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 * @exception 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 * @exception IOException If an I/O error occurs while either sending the 604 * command or receiving the server reply. 605 ***/ 606 public int saml(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 * @exception 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 * @exception 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 * @exception 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 * @exception IOException If an I/O error occurs while either sending the 643 * command or receiving the server reply. 644 ***/ 645 public int vrfy(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 * @exception 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 * @exception IOException If an I/O error occurs while either sending the 663 * command or receiving the server reply. 664 ***/ 665 public int expn(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 * @exception 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 * @exception 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 * @exception 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 * @exception IOException If an I/O error occurs while either sending the 700 * command or receiving the server reply. 701 ***/ 702 public int help(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 * @exception 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 * @exception 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 * @exception 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 * @exception 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 * @exception 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 * @exception 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(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 */