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