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.nntp;
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
026 import org.apache.commons.net.MalformedServerReplyException;
027 import org.apache.commons.net.ProtocolCommandListener;
028 import org.apache.commons.net.ProtocolCommandSupport;
029 import org.apache.commons.net.SocketClient;
030
031 /***
032 * The NNTP class is not meant to be used by itself and is provided
033 * only so that you may easily implement your own NNTP client if
034 * you so desire. If you have no need to perform your own implementation,
035 * you should use {@link org.apache.commons.net.nntp.NNTPClient}.
036 * The NNTP class is made public to provide access to various NNTP constants
037 * and to make it easier for adventurous programmers (or those with special
038 * needs) to interact with the NNTP protocol and implement their own clients.
039 * A set of methods with names corresponding to the NNTP command names are
040 * provided to facilitate this interaction.
041 * <p>
042 * You should keep in mind that the NNTP server may choose to prematurely
043 * close a connection if the client has been idle for longer than a
044 * given time period or if the server is being shutdown by the operator or
045 * some other reason. The NNTP class will detect a
046 * premature NNTP server connection closing when it receives a
047 * {@link org.apache.commons.net.nntp.NNTPReply#SERVICE_DISCONTINUED NNTPReply.SERVICE_DISCONTINUED }
048 * response to a command.
049 * When that occurs, the NNTP class method encountering that reply will throw
050 * an {@link org.apache.commons.net.nntp.NNTPConnectionClosedException}
051 * .
052 * <code>NNTPConectionClosedException</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.nntp.NNTPConnectionClosedException}
058 * , you must disconnect the connection with
059 * {@link #disconnect disconnect() } to properly clean up the
060 * system resources used by NNTP. Before disconnecting, you may check the
061 * last reply code and text with
062 * {@link #getReplyCode getReplyCode } and
063 * {@link #getReplyString getReplyString }.
064 * <p>
065 * Rather than list it separately for each method, we mention here that
066 * every method communicating with the server and throwing an IOException
067 * can also throw a
068 * {@link org.apache.commons.net.MalformedServerReplyException}
069 * , which is a subclass
070 * of IOException. A MalformedServerReplyException will be thrown when
071 * the reply received from the server deviates enough from the protocol
072 * specification that it cannot be interpreted in a useful manner despite
073 * attempts to be as lenient as possible.
074 * <p>
075 * <p>
076 * @author Daniel F. Savarese
077 * @author Rory Winston
078 * @author Ted Wise
079 * @see NNTPClient
080 * @see NNTPConnectionClosedException
081 * @see org.apache.commons.net.MalformedServerReplyException
082 ***/
083
084 public class NNTP extends SocketClient
085 {
086 /*** The default NNTP port. Its value is 119 according to RFC 977. ***/
087 public static final int DEFAULT_PORT = 119;
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 private StringBuffer __commandBuffer;
095
096 boolean _isAllowedToPost;
097 int _replyCode;
098 String _replyString;
099
100 /**
101 * Wraps {@link SocketClient#_input_}
102 * to communicate with server. Initialized by {@link #_connectAction_}.
103 * All server reads should be done through this variable.
104 */
105 protected BufferedReader _reader_;
106
107 /**
108 * Wraps {@link SocketClient#_output_}
109 * to communicate with server. Initialized by {@link #_connectAction_}.
110 * All server reads should be done through this variable.
111 */
112 protected BufferedWriter _writer_;
113
114 /***
115 * A ProtocolCommandSupport object used to manage the registering of
116 * ProtocolCommandListeners and te firing of ProtocolCommandEvents.
117 ***/
118 protected ProtocolCommandSupport _commandSupport_;
119
120 /***
121 * The default NNTP constructor. Sets the default port to
122 * <code>DEFAULT_PORT</code> and initializes internal data structures
123 * for saving NNTP reply information.
124 ***/
125 public NNTP()
126 {
127 setDefaultPort(DEFAULT_PORT);
128 __commandBuffer = new StringBuffer();
129 _replyString = null;
130 _reader_ = null;
131 _writer_ = null;
132 _isAllowedToPost = false;
133 _commandSupport_ = new ProtocolCommandSupport(this);
134 }
135
136 private void __getReply() throws IOException
137 {
138 _replyString = _reader_.readLine();
139
140 if (_replyString == null)
141 throw new NNTPConnectionClosedException(
142 "Connection closed without indication.");
143
144 // In case we run into an anomaly we don't want fatal index exceptions
145 // to be thrown.
146 if (_replyString.length() < 3)
147 throw new MalformedServerReplyException(
148 "Truncated server reply: " + _replyString);
149 try
150 {
151 _replyCode = Integer.parseInt(_replyString.substring(0, 3));
152 }
153 catch (NumberFormatException e)
154 {
155 throw new MalformedServerReplyException(
156 "Could not parse response code.\nServer Reply: " + _replyString);
157 }
158
159 if (_commandSupport_.getListenerCount() > 0)
160 _commandSupport_.fireReplyReceived(_replyCode, _replyString +
161 SocketClient.NETASCII_EOL);
162
163 if (_replyCode == NNTPReply.SERVICE_DISCONTINUED)
164 throw new NNTPConnectionClosedException(
165 "NNTP response 400 received. Server closed connection.");
166 }
167
168 /***
169 * Initiates control connections and gets initial reply, determining
170 * if the client is allowed to post to the server. Initializes
171 * {@link #_reader_} and {@link #_writer_} to wrap
172 * {@link SocketClient#_input_} and {@link SocketClient#_output_}.
173 ***/
174 @Override
175 protected void _connectAction_() throws IOException
176 {
177 super._connectAction_();
178 _reader_ =
179 new BufferedReader(new InputStreamReader(_input_,
180 __DEFAULT_ENCODING));
181 _writer_ =
182 new BufferedWriter(new OutputStreamWriter(_output_,
183 __DEFAULT_ENCODING));
184 __getReply();
185
186 _isAllowedToPost = (_replyCode == NNTPReply.SERVER_READY_POSTING_ALLOWED);
187 }
188
189 /***
190 * Adds a ProtocolCommandListener. Delegates this task to
191 * {@link #_commandSupport_ _commandSupport_ }.
192 * <p>
193 * @param listener The ProtocolCommandListener to add.
194 ***/
195 public void addProtocolCommandListener(ProtocolCommandListener listener)
196 {
197 _commandSupport_.addProtocolCommandListener(listener);
198 }
199
200 /***
201 * Removes a ProtocolCommandListener. Delegates this task to
202 * {@link #_commandSupport_ _commandSupport_ }.
203 * <p>
204 * @param listener The ProtocolCommandListener to remove.
205 ***/
206 public void removeProtocolCommandListener(ProtocolCommandListener listener)
207 {
208 _commandSupport_.removeProtocolCommandListener(listener);
209 }
210
211 /***
212 * Closes the connection to the NNTP server and sets to null
213 * some internal data so that the memory may be reclaimed by the
214 * garbage collector. The reply text and code information from the
215 * last command is voided so that the memory it used may be reclaimed.
216 * <p>
217 * @exception IOException If an error occurs while disconnecting.
218 ***/
219 @Override
220 public void disconnect() throws IOException
221 {
222 super.disconnect();
223 _reader_ = null;
224 _writer_ = null;
225 _replyString = null;
226 _isAllowedToPost = false;
227 }
228
229
230 /***
231 * Indicates whether or not the client is allowed to post articles to
232 * the server it is currently connected to.
233 * <p>
234 * @return True if the client can post articles to the server, false
235 * otherwise.
236 ***/
237 public boolean isAllowedToPost()
238 {
239 return _isAllowedToPost;
240 }
241
242
243 /***
244 * Sends an NNTP command to the server, waits for a reply and returns the
245 * numerical response code. After invocation, for more detailed
246 * information, the actual reply text can be accessed by calling
247 * {@link #getReplyString getReplyString }.
248 * <p>
249 * @param command The text representation of the NNTP command to send.
250 * @param args The arguments to the NNTP command. If this parameter is
251 * set to null, then the command is sent with no argument.
252 * @return The integer value of the NNTP reply code returned by the server
253 * in response to the command.
254 * @exception NNTPConnectionClosedException
255 * If the NNTP server prematurely closes the connection as a result
256 * of the client being idle or some other reason causing the server
257 * to send NNTP reply code 400. This exception may be caught either
258 * as an IOException or independently as itself.
259 * @exception IOException If an I/O error occurs while either sending the
260 * command or receiving the server reply.
261 ***/
262 public int sendCommand(String command, String args) throws IOException
263 {
264 String message;
265
266 __commandBuffer.setLength(0);
267 __commandBuffer.append(command);
268
269 if (args != null)
270 {
271 __commandBuffer.append(' ');
272 __commandBuffer.append(args);
273 }
274 __commandBuffer.append(SocketClient.NETASCII_EOL);
275
276 _writer_.write(message = __commandBuffer.toString());
277 _writer_.flush();
278
279 if (_commandSupport_.getListenerCount() > 0)
280 _commandSupport_.fireCommandSent(command, message);
281
282 __getReply();
283 return _replyCode;
284 }
285
286
287 /***
288 * Sends an NNTP 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 }.
292 * <p>
293 * @param command The NNTPCommand constant corresponding to the NNTP command
294 * to send.
295 * @param args The arguments to the NNTP command. If this parameter is
296 * set to null, then the command is sent with no argument.
297 * @return The integer value of the NNTP reply code returned by the server
298 * in response to the command.
299 * in response to the command.
300 * @exception NNTPConnectionClosedException
301 * If the NNTP server prematurely closes the connection as a result
302 * of the client being idle or some other reason causing the server
303 * to send NNTP reply code 400. 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 {
310 return sendCommand(NNTPCommand._commands[command], args);
311 }
312
313
314 /***
315 * Sends an NNTP command with no arguments to the server, waits for a
316 * reply and returns the numerical response code. After invocation, for
317 * more detailed information, the actual reply text can be accessed by
318 * calling {@link #getReplyString getReplyString }.
319 * <p>
320 * @param command The text representation of the NNTP command to send.
321 * @return The integer value of the NNTP reply code returned by the server
322 * in response to the command.
323 * in response to the command.
324 * @exception NNTPConnectionClosedException
325 * If the NNTP server prematurely closes the connection as a result
326 * of the client being idle or some other reason causing the server
327 * to send NNTP reply code 400. This exception may be caught either
328 * as an IOException or independently as itself.
329 * @exception IOException If an I/O error occurs while either sending the
330 * command or receiving the server reply.
331 ***/
332 public int sendCommand(String command) throws IOException
333 {
334 return sendCommand(command, null);
335 }
336
337
338 /***
339 * Sends an NNTP command with no arguments to the server, waits for a
340 * reply and returns the numerical response code. After invocation, for
341 * more detailed information, the actual reply text can be accessed by
342 * calling {@link #getReplyString getReplyString }.
343 * <p>
344 * @param command The NNTPCommand constant corresponding to the NNTP command
345 * to send.
346 * @return The integer value of the NNTP reply code returned by the server
347 * in response to the command.
348 * in response to the command.
349 * @exception NNTPConnectionClosedException
350 * If the NNTP server prematurely closes the connection as a result
351 * of the client being idle or some other reason causing the server
352 * to send NNTP reply code 400. This exception may be caught either
353 * as an IOException or independently as itself.
354 * @exception IOException If an I/O error occurs while either sending the
355 * command or receiving the server reply.
356 ***/
357 public int sendCommand(int command) throws IOException
358 {
359 return sendCommand(command, null);
360 }
361
362
363 /***
364 * Returns the integer value of the reply code of the last NNTP reply.
365 * You will usually only use this method after you connect to the
366 * NNTP server to check that the connection was successful since
367 * <code> connect </code> is of type void.
368 * <p>
369 * @return The integer value of the reply code of the last NNTP reply.
370 ***/
371 public int getReplyCode()
372 {
373 return _replyCode;
374 }
375
376 /***
377 * Fetches a reply from the NNTP server and returns the integer reply
378 * code. After calling this method, the actual reply text can be accessed
379 * from {@link #getReplyString getReplyString }. Only use this
380 * method if you are implementing your own NNTP client or if you need to
381 * fetch a secondary response from the NNTP server.
382 * <p>
383 * @return The integer value of the reply code of the fetched NNTP reply.
384 * in response to the command.
385 * @exception NNTPConnectionClosedException
386 * If the NNTP server prematurely closes the connection as a result
387 * of the client being idle or some other reason causing the server
388 * to send NNTP reply code 400. This exception may be caught either
389 * as an IOException or independently as itself.
390 * @exception IOException If an I/O error occurs while
391 * receiving the server reply.
392 ***/
393 public int getReply() throws IOException
394 {
395 __getReply();
396 return _replyCode;
397 }
398
399
400 /***
401 * Returns the entire text of the last NNTP server response exactly
402 * as it was received, not including the end of line marker.
403 * <p>
404 * @return The entire text from the last NNTP response as a String.
405 ***/
406 public String getReplyString()
407 {
408 return _replyString;
409 }
410
411
412 /***
413 * A convenience method to send the NNTP ARTICLE command to the server,
414 * receive the initial reply, and return the reply code.
415 * <p>
416 * @param messageId The message identifier of the requested article,
417 * including the encapsulating < and > characters.
418 * @return The reply code received from the server.
419 * @exception NNTPConnectionClosedException
420 * If the NNTP server prematurely closes the connection as a result
421 * of the client being idle or some other reason causing the server
422 * to send NNTP reply code 400. This exception may be caught either
423 * as an IOException or independently as itself.
424 * @exception IOException If an I/O error occurs while either sending the
425 * command or receiving the server reply.
426 ***/
427 public int article(String messageId) throws IOException
428 {
429 return sendCommand(NNTPCommand.ARTICLE, messageId);
430 }
431
432 /***
433 * A convenience method to send the NNTP ARTICLE command to the server,
434 * receive the initial reply, and return the reply code.
435 * <p>
436 * @param articleNumber The number of the article to request from the
437 * currently selected newsgroup.
438 * @return The reply code received from the server.
439 * @exception NNTPConnectionClosedException
440 * If the NNTP server prematurely closes the connection as a result
441 * of the client being idle or some other reason causing the server
442 * to send NNTP reply code 400. This exception may be caught either
443 * as an IOException or independently as itself.
444 * @exception IOException If an I/O error occurs while either sending the
445 * command or receiving the server reply.
446 ***/
447 public int article(int articleNumber) throws IOException
448 {
449 return sendCommand(NNTPCommand.ARTICLE, Integer.toString(articleNumber));
450 }
451
452 /***
453 * A convenience method to send the NNTP ARTICLE command to the server,
454 * receive the initial reply, and return the reply code.
455 * <p>
456 * @return The reply code received from the server.
457 * @exception NNTPConnectionClosedException
458 * If the NNTP server prematurely closes the connection as a result
459 * of the client being idle or some other reason causing the server
460 * to send NNTP reply code 400. This exception may be caught either
461 * as an IOException or independently as itself.
462 * @exception IOException If an I/O error occurs while either sending the
463 * command or receiving the server reply.
464 ***/
465 public int article() throws IOException
466 {
467 return sendCommand(NNTPCommand.ARTICLE);
468 }
469
470
471
472 /***
473 * A convenience method to send the NNTP BODY command to the server,
474 * receive the initial reply, and return the reply code.
475 * <p>
476 * @param messageId The message identifier of the requested article,
477 * including the encapsulating < and > characters.
478 * @return The reply code received from the server.
479 * @exception NNTPConnectionClosedException
480 * If the NNTP server prematurely closes the connection as a result
481 * of the client being idle or some other reason causing the server
482 * to send NNTP reply code 400. 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 body(String messageId) throws IOException
488 {
489 return sendCommand(NNTPCommand.BODY, messageId);
490 }
491
492 /***
493 * A convenience method to send the NNTP BODY command to the server,
494 * receive the initial reply, and return the reply code.
495 * <p>
496 * @param articleNumber The number of the article to request from the
497 * currently selected newsgroup.
498 * @return The reply code received from the server.
499 * @exception NNTPConnectionClosedException
500 * If the NNTP server prematurely closes the connection as a result
501 * of the client being idle or some other reason causing the server
502 * to send NNTP reply code 400. 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 body(int articleNumber) throws IOException
508 {
509 return sendCommand(NNTPCommand.BODY, Integer.toString(articleNumber));
510 }
511
512 /***
513 * A convenience method to send the NNTP BODY command to the server,
514 * receive the initial reply, and return the reply code.
515 * <p>
516 * @return The reply code received from the server.
517 * @exception NNTPConnectionClosedException
518 * If the NNTP server prematurely closes the connection as a result
519 * of the client being idle or some other reason causing the server
520 * to send NNTP reply code 400. This exception may be caught either
521 * as an IOException or independently as itself.
522 * @exception IOException If an I/O error occurs while either sending the
523 * command or receiving the server reply.
524 ***/
525 public int body() throws IOException
526 {
527 return sendCommand(NNTPCommand.BODY);
528 }
529
530
531
532 /***
533 * A convenience method to send the NNTP HEAD command to the server,
534 * receive the initial reply, and return the reply code.
535 * <p>
536 * @param messageId The message identifier of the requested article,
537 * including the encapsulating < and > characters.
538 * @return The reply code received from the server.
539 * @exception NNTPConnectionClosedException
540 * If the NNTP server prematurely closes the connection as a result
541 * of the client being idle or some other reason causing the server
542 * to send NNTP reply code 400. This exception may be caught either
543 * as an IOException or independently as itself.
544 * @exception IOException If an I/O error occurs while either sending the
545 * command or receiving the server reply.
546 ***/
547 public int head(String messageId) throws IOException
548 {
549 return sendCommand(NNTPCommand.HEAD, messageId);
550 }
551
552 /***
553 * A convenience method to send the NNTP HEAD command to the server,
554 * receive the initial reply, and return the reply code.
555 * <p>
556 * @param articleNumber The number of the article to request from the
557 * currently selected newsgroup.
558 * @return The reply code received from the server.
559 * @exception NNTPConnectionClosedException
560 * If the NNTP server prematurely closes the connection as a result
561 * of the client being idle or some other reason causing the server
562 * to send NNTP reply code 400. This exception may be caught either
563 * as an IOException or independently as itself.
564 * @exception IOException If an I/O error occurs while either sending the
565 * command or receiving the server reply.
566 ***/
567 public int head(int articleNumber) throws IOException
568 {
569 return sendCommand(NNTPCommand.HEAD, Integer.toString(articleNumber));
570 }
571
572 /***
573 * A convenience method to send the NNTP HEAD command to the server,
574 * receive the initial reply, and return the reply code.
575 * <p>
576 * @return The reply code received from the server.
577 * @exception NNTPConnectionClosedException
578 * If the NNTP server prematurely closes the connection as a result
579 * of the client being idle or some other reason causing the server
580 * to send NNTP reply code 400. This exception may be caught either
581 * as an IOException or independently as itself.
582 * @exception IOException If an I/O error occurs while either sending the
583 * command or receiving the server reply.
584 ***/
585 public int head() throws IOException
586 {
587 return sendCommand(NNTPCommand.HEAD);
588 }
589
590
591
592 /***
593 * A convenience method to send the NNTP STAT command to the server,
594 * receive the initial reply, and return the reply code.
595 * <p>
596 * @param messageId The message identifier of the requested article,
597 * including the encapsulating < and > characters.
598 * @return The reply code received from the server.
599 * @exception NNTPConnectionClosedException
600 * If the NNTP server prematurely closes the connection as a result
601 * of the client being idle or some other reason causing the server
602 * to send NNTP reply code 400. This exception may be caught either
603 * as an IOException or independently as itself.
604 * @exception IOException If an I/O error occurs while either sending the
605 * command or receiving the server reply.
606 ***/
607 public int stat(String messageId) throws IOException
608 {
609 return sendCommand(NNTPCommand.STAT, messageId);
610 }
611
612 /***
613 * A convenience method to send the NNTP STAT command to the server,
614 * receive the initial reply, and return the reply code.
615 * <p>
616 * @param articleNumber The number of the article to request from the
617 * currently selected newsgroup.
618 * @return The reply code received from the server.
619 * @exception NNTPConnectionClosedException
620 * If the NNTP server prematurely closes the connection as a result
621 * of the client being idle or some other reason causing the server
622 * to send NNTP reply code 400. This exception may be caught either
623 * as an IOException or independently as itself.
624 * @exception IOException If an I/O error occurs while either sending the
625 * command or receiving the server reply.
626 ***/
627 public int stat(int articleNumber) throws IOException
628 {
629 return sendCommand(NNTPCommand.STAT, Integer.toString(articleNumber));
630 }
631
632 /***
633 * A convenience method to send the NNTP STAT command to the server,
634 * receive the initial reply, and return the reply code.
635 * <p>
636 * @return The reply code received from the server.
637 * @exception NNTPConnectionClosedException
638 * If the NNTP server prematurely closes the connection as a result
639 * of the client being idle or some other reason causing the server
640 * to send NNTP reply code 400. 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 stat() throws IOException
646 {
647 return sendCommand(NNTPCommand.STAT);
648 }
649
650
651 /***
652 * A convenience method to send the NNTP GROUP command to the server,
653 * receive the reply, and return the reply code.
654 * <p>
655 * @param newsgroup The name of the newsgroup to select.
656 * @return The reply code received from the server.
657 * @exception NNTPConnectionClosedException
658 * If the NNTP server prematurely closes the connection as a result
659 * of the client being idle or some other reason causing the server
660 * to send NNTP reply code 400. 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 group(String newsgroup) throws IOException
666 {
667 return sendCommand(NNTPCommand.GROUP, newsgroup);
668 }
669
670
671 /***
672 * A convenience method to send the NNTP HELP command to the server,
673 * receive the reply, and return the reply code.
674 * <p>
675 * @return The reply code received from the server.
676 * @exception NNTPConnectionClosedException
677 * If the NNTP server prematurely closes the connection as a result
678 * of the client being idle or some other reason causing the server
679 * to send NNTP reply code 400. This exception may be caught either
680 * as an IOException or independently as itself.
681 * @exception IOException If an I/O error occurs while either sending the
682 * command or receiving the server reply.
683 ***/
684 public int help() throws IOException
685 {
686 return sendCommand(NNTPCommand.HELP);
687 }
688
689
690 /***
691 * A convenience method to send the NNTP IHAVE command to the server,
692 * receive the reply, and return the reply code.
693 * <p>
694 * @param messageId The article identifier,
695 * including the encapsulating < and > characters.
696 * @return The reply code received from the server.
697 * @exception NNTPConnectionClosedException
698 * If the NNTP server prematurely closes the connection as a result
699 * of the client being idle or some other reason causing the server
700 * to send NNTP reply code 400. This exception may be caught either
701 * as an IOException or independently as itself.
702 * @exception IOException If an I/O error occurs while either sending the
703 * command or receiving the server reply.
704 ***/
705 public int ihave(String messageId) throws IOException
706 {
707 return sendCommand(NNTPCommand.IHAVE, messageId);
708 }
709
710
711 /***
712 * A convenience method to send the NNTP LAST command to the server,
713 * receive the reply, and return the reply code.
714 * <p>
715 * @return The reply code received from the server.
716 * @exception NNTPConnectionClosedException
717 * If the NNTP server prematurely closes the connection as a result
718 * of the client being idle or some other reason causing the server
719 * to send NNTP reply code 400. This exception may be caught either
720 * as an IOException or independently as itself.
721 * @exception IOException If an I/O error occurs while either sending the
722 * command or receiving the server reply.
723 ***/
724 public int last() throws IOException
725 {
726 return sendCommand(NNTPCommand.LAST);
727 }
728
729
730
731 /***
732 * A convenience method to send the NNTP LIST command to the server,
733 * receive the reply, and return the reply code.
734 * <p>
735 * @return The reply code received from the server.
736 * @exception NNTPConnectionClosedException
737 * If the NNTP server prematurely closes the connection as a result
738 * of the client being idle or some other reason causing the server
739 * to send NNTP reply code 400. This exception may be caught either
740 * as an IOException or independently as itself.
741 * @exception IOException If an I/O error occurs while either sending the
742 * command or receiving the server reply.
743 ***/
744 public int list() throws IOException
745 {
746 return sendCommand(NNTPCommand.LIST);
747 }
748
749
750
751 /***
752 * A convenience method to send the NNTP NEXT command to the server,
753 * receive the reply, and return the reply code.
754 * <p>
755 * @return The reply code received from the server.
756 * @exception NNTPConnectionClosedException
757 * If the NNTP server prematurely closes the connection as a result
758 * of the client being idle or some other reason causing the server
759 * to send NNTP reply code 400. This exception may be caught either
760 * as an IOException or independently as itself.
761 * @exception IOException If an I/O error occurs while either sending the
762 * command or receiving the server reply.
763 ***/
764 public int next() throws IOException
765 {
766 return sendCommand(NNTPCommand.NEXT);
767 }
768
769
770 /***
771 * A convenience method to send the NNTP NEWGROUPS command to the server,
772 * receive the reply, and return the reply code.
773 * <p>
774 * @param date The date after which to check for new groups.
775 * Date format is YYMMDD
776 * @param time The time after which to check for new groups.
777 * Time format is HHMMSS using a 24-hour clock.
778 * @param GMT True if the time is in GMT, false if local server time.
779 * @param distributions Comma-separated distribution list to check for
780 * new groups. Set to null if no distributions.
781 * @return The reply code received from the server.
782 * @exception NNTPConnectionClosedException
783 * If the NNTP server prematurely closes the connection as a result
784 * of the client being idle or some other reason causing the server
785 * to send NNTP reply code 400. This exception may be caught either
786 * as an IOException or independently as itself.
787 * @exception IOException If an I/O error occurs while either sending the
788 * command or receiving the server reply.
789 ***/
790 public int newgroups(String date, String time, boolean GMT,
791 String distributions) throws IOException
792 {
793 StringBuffer buffer = new StringBuffer();
794
795 buffer.append(date);
796 buffer.append(' ');
797 buffer.append(time);
798
799 if (GMT)
800 {
801 buffer.append(' ');
802 buffer.append("GMT");
803 }
804
805 if (distributions != null)
806 {
807 buffer.append(" <");
808 buffer.append(distributions);
809 buffer.append('>');
810 }
811
812 return sendCommand(NNTPCommand.NEWGROUPS, buffer.toString());
813 }
814
815
816 /***
817 * A convenience method to send the NNTP NEWGROUPS command to the server,
818 * receive the reply, and return the reply code.
819 * <p>
820 * @param newsgroups A comma-separated list of newsgroups to check for new
821 * news.
822 * @param date The date after which to check for new news.
823 * Date format is YYMMDD
824 * @param time The time after which to check for new news.
825 * Time format is HHMMSS using a 24-hour clock.
826 * @param GMT True if the time is in GMT, false if local server time.
827 * @param distributions Comma-separated distribution list to check for
828 * new news. Set to null if no distributions.
829 * @return The reply code received from the server.
830 * @exception NNTPConnectionClosedException
831 * If the NNTP server prematurely closes the connection as a result
832 * of the client being idle or some other reason causing the server
833 * to send NNTP reply code 400. This exception may be caught either
834 * as an IOException or independently as itself.
835 * @exception IOException If an I/O error occurs while either sending the
836 * command or receiving the server reply.
837 ***/
838 public int newnews(String newsgroups, String date, String time, boolean GMT,
839 String distributions) throws IOException
840 {
841 StringBuffer buffer = new StringBuffer();
842
843 buffer.append(newsgroups);
844 buffer.append(' ');
845 buffer.append(date);
846 buffer.append(' ');
847 buffer.append(time);
848
849 if (GMT)
850 {
851 buffer.append(' ');
852 buffer.append("GMT");
853 }
854
855 if (distributions != null)
856 {
857 buffer.append(" <");
858 buffer.append(distributions);
859 buffer.append('>');
860 }
861
862 return sendCommand(NNTPCommand.NEWNEWS, buffer.toString());
863 }
864
865
866
867 /***
868 * A convenience method to send the NNTP POST command to the server,
869 * receive the reply, and return the reply code.
870 * <p>
871 * @return The reply code received from the server.
872 * @exception NNTPConnectionClosedException
873 * If the NNTP server prematurely closes the connection as a result
874 * of the client being idle or some other reason causing the server
875 * to send NNTP reply code 400. This exception may be caught either
876 * as an IOException or independently as itself.
877 * @exception IOException If an I/O error occurs while either sending the
878 * command or receiving the server reply.
879 ***/
880 public int post() throws IOException
881 {
882 return sendCommand(NNTPCommand.POST);
883 }
884
885
886
887 /***
888 * A convenience method to send the NNTP QUIT command to the server,
889 * receive the reply, and return the reply code.
890 * <p>
891 * @return The reply code received from the server.
892 * @exception NNTPConnectionClosedException
893 * If the NNTP server prematurely closes the connection as a result
894 * of the client being idle or some other reason causing the server
895 * to send NNTP reply code 400. This exception may be caught either
896 * as an IOException or independently as itself.
897 * @exception IOException If an I/O error occurs while either sending the
898 * command or receiving the server reply.
899 ***/
900 public int quit() throws IOException
901 {
902 return sendCommand(NNTPCommand.QUIT);
903 }
904
905 /***
906 * A convenience method to send the AUTHINFO USER command to the server,
907 * receive the reply, and return the reply code. (See RFC 2980)
908 * <p>
909 * @param username A valid username.
910 * @return The reply code received from the server. The server should
911 * return a 381 or 281 for this command.
912 * @exception NNTPConnectionClosedException
913 * If the NNTP server prematurely closes the connection as a result
914 * of the client being idle or some other reason causing the server
915 * to send NNTP reply code 400. This exception may be caught either
916 * as an IOException or independently as itself.
917 * @exception IOException If an I/O error occurs while either sending the
918 * command or receiving the server reply.
919 ***/
920 public int authinfoUser(String username) throws IOException {
921 String userParameter = "USER " + username;
922 return sendCommand(NNTPCommand.AUTHINFO, userParameter);
923 }
924
925 /***
926 * A convenience method to send the AUTHINFO PASS command to the server,
927 * receive the reply, and return the reply code. If this step is
928 * required, it should immediately follow the AUTHINFO USER command
929 * (See RFC 2980)
930 * <p>
931 * @param password a valid password.
932 * @return The reply code received from the server. The server should
933 * return a 281 or 502 for this command.
934 * @exception NNTPConnectionClosedException
935 * If the NNTP server prematurely closes the connection as a result
936 * of the client being idle or some other reason causing the server
937 * to send NNTP reply code 400. This exception may be caught either
938 * as an IOException or independently as itself.
939 * @exception IOException If an I/O error occurs while either sending the
940 * command or receiving the server reply.
941 ***/
942 public int authinfoPass(String password) throws IOException {
943 String passParameter = "PASS " + password;
944 return sendCommand(NNTPCommand.AUTHINFO, passParameter);
945 }
946
947 /***
948 * A convenience method to send the NNTP XOVER command to the server,
949 * receive the reply, and return the reply code.
950 * <p>
951 * @param selectedArticles a String representation of the range of
952 * article headers required. This may be an article number, or a
953 * range of article numbers in the form "XXXX-YYYY", where XXXX
954 * and YYYY are valid article numbers in the current group. It
955 * also may be of the form "XXX-", meaning "return XXX and all
956 * following articles" In this revision, the last format is not
957 * possible (yet).
958 * @return The reply code received from the server.
959 * @exception NNTPConnectionClosedException
960 * If the NNTP server prematurely closes the connection as a result
961 * of the client being idle or some other reason causing the server
962 * to send NNTP reply code 400. This exception may be caught either
963 * as an IOException or independently as itself.
964 * @exception IOException If an I/O error occurs while either sending the
965 * command or receiving the server reply.
966 ***/
967 public int xover(String selectedArticles) throws IOException {
968 return sendCommand(NNTPCommand.XOVER, selectedArticles);
969 }
970
971 /***
972 * A convenience method to send the NNTP XHDR command to the server,
973 * receive the reply, and return the reply code.
974 * <p>
975 * @param header a String naming a header line (e.g., "subject"). See
976 * RFC-1036 for a list of valid header lines.
977 * @param selectedArticles a String representation of the range of
978 * article headers required. This may be an article number, or a
979 * range of article numbers in the form "XXXX-YYYY", where XXXX
980 * and YYYY are valid article numbers in the current group. It
981 * also may be of the form "XXX-", meaning "return XXX and all
982 * following articles" In this revision, the last format is not
983 * possible (yet).
984 * @return The reply code received from the server.
985 * @exception NNTPConnectionClosedException
986 * If the NNTP server prematurely closes the connection as a result
987 * of the client being idle or some other reason causing the server
988 * to send NNTP reply code 400. This exception may be caught either
989 * as an IOException or independently as itself.
990 * @exception IOException If an I/O error occurs while either sending the
991 * command or receiving the server reply.
992 ***/
993 public int xhdr(String header, String selectedArticles) throws IOException {
994 StringBuffer command = new StringBuffer(header);
995 command.append(" ");
996 command.append(selectedArticles);
997 return sendCommand(NNTPCommand.XHDR, command.toString());
998 }
999
1000 /**
1001 * A convenience wrapper for the extended LIST command that takes
1002 * an argument, allowing us to selectively list multiple groups.
1003 * <p>
1004 * @param wildmat A wildmat (pseudo-regex) pattern. See RFC 2980 for
1005 * details.
1006 * @return the reply code received from the server.
1007 * @throws IOException
1008 */
1009 public int listActive(String wildmat) throws IOException {
1010 StringBuffer command = new StringBuffer("ACTIVE ");
1011 command.append(wildmat);
1012 return sendCommand(NNTPCommand.LIST, command.toString());
1013 }
1014 }
1015
1016 /* Emacs configuration
1017 * Local variables: **
1018 * mode: java **
1019 * c-basic-offset: 4 **
1020 * indent-tabs-mode: nil **
1021 * End: **
1022 */