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