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