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