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