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