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