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