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