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 only so that you may easily implement your own NNTP client if you so desire. If you have no 035 * need to perform your own implementation, you should use {@link org.apache.commons.net.nntp.NNTPClient}. The NNTP class is made public to provide access to 036 * various NNTP constants and to make it easier for adventurous programmers (or those with special needs) to interact with the NNTP protocol and implement their 037 * own clients. A set of methods with names corresponding to the NNTP command names are provided to facilitate this interaction. 038 * <p> 039 * You should keep in mind that the NNTP server may choose to prematurely close a connection if the client has been idle for longer than a given time period or 040 * if the server is being shutdown by the operator or some other reason. The NNTP class will detect a premature NNTP server connection closing when it receives 041 * a {@link org.apache.commons.net.nntp.NNTPReply#SERVICE_DISCONTINUED NNTPReply.SERVICE_DISCONTINUED } response to a command. When that occurs, the NNTP class 042 * method encountering that reply will throw an {@link org.apache.commons.net.nntp.NNTPConnectionClosedException} . <code>NNTPConectionClosedException</code> is 043 * a subclass of <code>IOException</code> and therefore need not be caught separately, but if you are going to catch it separately, its catch block must 044 * appear before the more general <code>IOException</code> catch block. When you encounter an 045 * {@link org.apache.commons.net.nntp.NNTPConnectionClosedException} , you must disconnect the connection with {@link #disconnect disconnect() } to properly 046 * clean up the system resources used by NNTP. Before disconnecting, you may check the last reply code and text with {@link #getReplyCode getReplyCode } and 047 * {@link #getReplyString getReplyString }. 048 * </p> 049 * <p> 050 * Rather than list it separately for each method, we mention here that every method communicating with the server and throwing an IOException can also throw a 051 * {@link org.apache.commons.net.MalformedServerReplyException} , which is a subclass of IOException. A MalformedServerReplyException will be thrown when the 052 * reply received from the server deviates enough from the protocol specification that it cannot be interpreted in a useful manner despite attempts to be as 053 * lenient as possible. 054 * </p> 055 * 056 * @see NNTPClient 057 * @see NNTPConnectionClosedException 058 * @see org.apache.commons.net.MalformedServerReplyException 059 */ 060 061public class NNTP extends SocketClient { 062 /** The default NNTP port. Its value is 119 according to RFC 977. */ 063 public static final int DEFAULT_PORT = 119; 064 065 // We have to ensure that the protocol communication is in ASCII, 066 // but we use ISO-8859-1 just in case 8-bit characters cross 067 // the wire. 068 private static final Charset DEFAULT_ENCODING = StandardCharsets.ISO_8859_1; 069 070 boolean _isAllowedToPost; 071 private int replyCode; 072 private String replyString; 073 074 /** 075 * Wraps {@link SocketClient#_input_} to communicate with server. Initialized by {@link #_connectAction_}. All server reads should be done through this 076 * variable. 077 */ 078 protected BufferedReader _reader_; 079 080 /** 081 * Wraps {@link SocketClient#_output_} to communicate with server. Initialized by {@link #_connectAction_}. All server reads should be done through this 082 * variable. 083 */ 084 protected BufferedWriter _writer_; 085 086 /** 087 * A ProtocolCommandSupport object used to manage the registering of ProtocolCommandListeners and te firing of ProtocolCommandEvents. 088 */ 089 protected ProtocolCommandSupport _commandSupport_; 090 091 /** 092 * The default NNTP constructor. Sets the default port to <code>DEFAULT_PORT</code> and initializes internal data structures for saving NNTP reply 093 * information. 094 */ 095 public NNTP() { 096 setDefaultPort(DEFAULT_PORT); 097 replyString = null; 098 _reader_ = null; 099 _writer_ = null; 100 _isAllowedToPost = false; 101 _commandSupport_ = new ProtocolCommandSupport(this); 102 } 103 104 /** 105 * Initiates control connections and gets initial reply, determining if the client is allowed to post to the server. Initializes {@link #_reader_} and 106 * {@link #_writer_} to wrap {@link SocketClient#_input_} and {@link SocketClient#_output_}. 107 */ 108 @Override 109 protected void _connectAction_() throws IOException { 110 super._connectAction_(); 111 _reader_ = new CRLFLineReader(new InputStreamReader(_input_, DEFAULT_ENCODING)); 112 _writer_ = new BufferedWriter(new OutputStreamWriter(_output_, DEFAULT_ENCODING)); 113 getReply(); 114 115 _isAllowedToPost = replyCode == NNTPReply.SERVER_READY_POSTING_ALLOWED; 116 } 117 118 /** 119 * A convenience method to send the NNTP ARTICLE command to the server, receive the initial reply, and return the reply code. 120 * 121 * @return The reply code received from the server. 122 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 123 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 124 * independently as itself. 125 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 126 */ 127 public int article() throws IOException { 128 return sendCommand(NNTPCommand.ARTICLE); 129 } 130 131 /** 132 * @param a article number 133 * @return number 134 * @throws IOException on error 135 * @deprecated - for API compatibility only - DO NOT USE 136 */ 137 @Deprecated 138 public int article(final int a) throws IOException { 139 return article((long) a); 140 } 141 142 /** 143 * A convenience method to send the NNTP ARTICLE command to the server, receive the initial reply, and return the reply code. 144 * 145 * @param articleNumber The number of the article to request from the currently selected newsgroup. 146 * @return The reply code received from the server. 147 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 148 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 149 * independently as itself. 150 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 151 */ 152 public int article(final long articleNumber) throws IOException { 153 return sendCommand(NNTPCommand.ARTICLE, Long.toString(articleNumber)); 154 } 155 156 /** 157 * A convenience method to send the NNTP ARTICLE command to the server, receive the initial reply, and return the reply code. 158 * 159 * @param messageId The message identifier of the requested article, including the encapsulating < and > characters. 160 * @return The reply code received from the server. 161 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 162 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 163 * independently as itself. 164 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 165 */ 166 public int article(final String messageId) throws IOException { 167 return sendCommand(NNTPCommand.ARTICLE, messageId); 168 } 169 170 /** 171 * A convenience method to send the AUTHINFO PASS command to the server, receive the reply, and return the reply code. If this step is required, it should 172 * immediately follow the AUTHINFO USER command (See RFC 2980) 173 * 174 * @param password a valid password. 175 * @return The reply code received from the server. The server should return a 281 or 502 for this command. 176 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 177 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 178 * independently as itself. 179 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 180 */ 181 public int authinfoPass(final String password) throws IOException { 182 final String passParameter = "PASS " + password; 183 return sendCommand(NNTPCommand.AUTHINFO, passParameter); 184 } 185 186 /** 187 * A convenience method to send the AUTHINFO USER command to the server, receive the reply, and return the reply code. (See RFC 2980) 188 * 189 * @param user A valid user name. 190 * @return The reply code received from the server. The server should return a 381 or 281 for this command. 191 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 192 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 193 * independently as itself. 194 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 195 */ 196 public int authinfoUser(final String user) throws IOException { 197 final String userParameter = "USER " + user; 198 return sendCommand(NNTPCommand.AUTHINFO, userParameter); 199 } 200 201 /** 202 * A convenience method to send the NNTP BODY command to the server, receive the initial reply, and return the reply code. 203 * 204 * @return The reply code received from the server. 205 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 206 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 207 * independently as itself. 208 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 209 */ 210 public int body() throws IOException { 211 return sendCommand(NNTPCommand.BODY); 212 } 213 214 /** 215 * @param a article number 216 * @return number 217 * @throws IOException on error 218 * @deprecated - for API compatibility only - DO NOT USE 219 */ 220 @Deprecated 221 public int body(final int a) throws IOException { 222 return body((long) a); 223 } 224 225 /** 226 * A convenience method to send the NNTP BODY command to the server, receive the initial reply, and return the reply code. 227 * 228 * @param articleNumber The number of the article to request from the currently selected newsgroup. 229 * @return The reply code received from the server. 230 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 231 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 232 * independently as itself. 233 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 234 */ 235 public int body(final long articleNumber) throws IOException { 236 return sendCommand(NNTPCommand.BODY, Long.toString(articleNumber)); 237 } 238 239 /** 240 * A convenience method to send the NNTP BODY command to the server, receive the initial reply, and return the reply code. 241 * 242 * @param messageId The message identifier of the requested article, including the encapsulating < and > characters. 243 * @return The reply code received from the server. 244 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 245 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 246 * independently as itself. 247 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 248 */ 249 public int body(final String messageId) throws IOException { 250 return sendCommand(NNTPCommand.BODY, messageId); 251 } 252 253 /** 254 * Closes the connection to the NNTP server and sets to null some internal data so that the memory may be reclaimed by the garbage collector. The reply text 255 * and code information from the last command is voided so that the memory it used may be reclaimed. 256 * 257 * @throws IOException If an error occurs while disconnecting. 258 */ 259 @Override 260 public void disconnect() throws IOException { 261 super.disconnect(); 262 _reader_ = null; 263 _writer_ = null; 264 replyString = null; 265 _isAllowedToPost = false; 266 } 267 268 /** 269 * Provide command support to super-class 270 */ 271 @Override 272 protected ProtocolCommandSupport getCommandSupport() { 273 return _commandSupport_; 274 } 275 276 /** 277 * Fetches a reply from the NNTP server and returns the integer reply code. After calling this method, the actual reply text can be accessed from 278 * {@link #getReplyString getReplyString }. Only use this method if you are implementing your own NNTP client or if you need to fetch a secondary response 279 * from the NNTP server. 280 * 281 * @return The integer value of the reply code of the fetched NNTP reply. in response to the command. 282 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 283 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 284 * independently as itself. 285 * @throws IOException If an I/O error occurs while receiving the server reply. 286 */ 287 public int getReply() throws IOException { 288 replyString = _reader_.readLine(); 289 290 if (replyString == null) { 291 throw new NNTPConnectionClosedException("Connection closed without indication."); 292 } 293 294 // In case we run into an anomaly we don't want fatal index exceptions 295 // to be thrown. 296 if (replyString.length() < 3) { 297 throw new MalformedServerReplyException("Truncated server reply: " + replyString); 298 } 299 300 try { 301 replyCode = Integer.parseInt(replyString.substring(0, 3)); 302 } catch (final NumberFormatException e) { 303 throw new MalformedServerReplyException("Could not parse response code.\nServer Reply: " + replyString); 304 } 305 306 fireReplyReceived(replyCode, replyString + SocketClient.NETASCII_EOL); 307 308 if (replyCode == NNTPReply.SERVICE_DISCONTINUED) { 309 throw new NNTPConnectionClosedException("NNTP response 400 received. Server closed connection."); 310 } 311 return replyCode; 312 } 313 314 /** 315 * Returns the integer value of the reply code of the last NNTP reply. You will usually only use this method after you connect to the NNTP server to check 316 * that the connection was successful since <code>connect</code> is of type void. 317 * 318 * @return The integer value of the reply code of the last NNTP reply. 319 */ 320 public int getReplyCode() { 321 return replyCode; 322 } 323 324 /** 325 * Returns the entire text of the last NNTP server response exactly as it was received, not including the end of line marker. 326 * 327 * @return The entire text from the last NNTP response as a String. 328 */ 329 public String getReplyString() { 330 return replyString; 331 } 332 333 /** 334 * A convenience method to send the NNTP GROUP command to the server, receive the reply, and return the reply code. 335 * 336 * @param newsgroup The name of the newsgroup to select. 337 * @return The reply code received from the server. 338 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 339 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 340 * independently as itself. 341 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 342 */ 343 public int group(final String newsgroup) throws IOException { 344 return sendCommand(NNTPCommand.GROUP, newsgroup); 345 } 346 347 /** 348 * A convenience method to send the NNTP HEAD command to the server, receive the initial reply, and return the reply code. 349 * 350 * @return The reply code received from the server. 351 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 352 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 353 * independently as itself. 354 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 355 */ 356 public int head() throws IOException { 357 return sendCommand(NNTPCommand.HEAD); 358 } 359 360 /** 361 * @param a article number 362 * @return number 363 * @throws IOException on error 364 * @deprecated - for API compatibility only - DO NOT USE 365 */ 366 @Deprecated 367 public int head(final int a) throws IOException { 368 return head((long) a); 369 } 370 371 /** 372 * A convenience method to send the NNTP HEAD command to the server, receive the initial reply, and return the reply code. 373 * 374 * @param articleNumber The number of the article to request from the currently selected newsgroup. 375 * @return The reply code received from the server. 376 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 377 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 378 * independently as itself. 379 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 380 */ 381 public int head(final long articleNumber) throws IOException { 382 return sendCommand(NNTPCommand.HEAD, Long.toString(articleNumber)); 383 } 384 385 /** 386 * A convenience method to send the NNTP HEAD command to the server, receive the initial reply, and return the reply code. 387 * 388 * @param messageId The message identifier of the requested article, including the encapsulating < and > characters. 389 * @return The reply code received from the server. 390 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 391 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 392 * independently as itself. 393 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 394 */ 395 public int head(final String messageId) throws IOException { 396 return sendCommand(NNTPCommand.HEAD, messageId); 397 } 398 399 /** 400 * A convenience method to send the NNTP HELP command to the server, receive the reply, and return the reply code. 401 * 402 * @return The reply code received from the server. 403 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 404 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 405 * independently as itself. 406 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 407 */ 408 public int help() throws IOException { 409 return sendCommand(NNTPCommand.HELP); 410 } 411 412 /** 413 * A convenience method to send the NNTP IHAVE command to the server, receive the reply, and return the reply code. 414 * 415 * @param messageId The article identifier, including the encapsulating < and > characters. 416 * @return The reply code received from the server. 417 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 418 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 419 * independently as itself. 420 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 421 */ 422 public int ihave(final String messageId) throws IOException { 423 return sendCommand(NNTPCommand.IHAVE, messageId); 424 } 425 426 /** 427 * Indicates whether or not the client is allowed to post articles to the server it is currently connected to. 428 * 429 * @return True if the client can post articles to the server, false otherwise. 430 */ 431 public boolean isAllowedToPost() { 432 return _isAllowedToPost; 433 } 434 435 /** 436 * A convenience method to send the NNTP LAST command to the server, receive the reply, and return the reply code. 437 * 438 * @return The reply code received from the server. 439 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 440 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 441 * independently as itself. 442 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 443 */ 444 public int last() throws IOException { 445 return sendCommand(NNTPCommand.LAST); 446 } 447 448 /** 449 * A convenience method to send the NNTP LIST command to the server, receive the reply, and return the reply code. 450 * 451 * @return The reply code received from the server. 452 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 453 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 454 * independently as itself. 455 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 456 */ 457 public int list() throws IOException { 458 return sendCommand(NNTPCommand.LIST); 459 } 460 461 /** 462 * A convenience wrapper for the extended LIST command that takes an argument, allowing us to selectively list multiple groups. 463 * 464 * @param wildmat A wildmat (pseudo-regex) pattern. See RFC 2980 for details. 465 * @return the reply code received from the server. 466 * @throws IOException if the command fails 467 */ 468 public int listActive(final String wildmat) throws IOException { 469 final StringBuilder command = new StringBuilder("ACTIVE "); 470 command.append(wildmat); 471 return sendCommand(NNTPCommand.LIST, command.toString()); 472 } 473 474 /** 475 * A convenience method to send the "NEWGROUPS" command to the server, receive the reply, and return the reply code. 476 * 477 * @param date The date after which to check for new groups. Date format is YYMMDD 478 * @param time The time after which to check for new groups. Time format is HHMMSS using a 24-hour clock. 479 * @param GMT True if the time is in GMT, false if local server time. 480 * @param distributions Comma-separated distribution list to check for new groups. Set to null if no distributions. 481 * @return The reply code received from the server. 482 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 483 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 484 * independently as itself. 485 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 486 */ 487 public int newgroups(final String date, final String time, final boolean GMT, final String distributions) throws IOException { 488 final StringBuilder buffer = new StringBuilder(); 489 490 buffer.append(date); 491 buffer.append(' '); 492 buffer.append(time); 493 494 if (GMT) { 495 buffer.append(' '); 496 buffer.append("GMT"); 497 } 498 499 if (distributions != null) { 500 buffer.append(" <"); 501 buffer.append(distributions); 502 buffer.append('>'); 503 } 504 505 return sendCommand(NNTPCommand.NEWGROUPS, buffer.toString()); 506 } 507 508 /** 509 * A convenience method to send the "NEWNEWS" command to the server, receive the reply, and return the reply code. 510 * 511 * @param newsgroups A comma-separated list of newsgroups to check for new news. 512 * @param date The date after which to check for new news. Date format is YYMMDD 513 * @param time The time after which to check for new news. Time format is HHMMSS using a 24-hour clock. 514 * @param GMT True if the time is in GMT, false if local server time. 515 * @param distributions Comma-separated distribution list to check for new news. Set to null if no distributions. 516 * @return The reply code received from the server. 517 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 518 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 519 * independently as itself. 520 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 521 */ 522 public int newnews(final String newsgroups, final String date, final String time, final boolean GMT, final String distributions) throws IOException { 523 final StringBuilder buffer = new StringBuilder(); 524 525 buffer.append(newsgroups); 526 buffer.append(' '); 527 buffer.append(date); 528 buffer.append(' '); 529 buffer.append(time); 530 531 if (GMT) { 532 buffer.append(' '); 533 buffer.append("GMT"); 534 } 535 536 if (distributions != null) { 537 buffer.append(" <"); 538 buffer.append(distributions); 539 buffer.append('>'); 540 } 541 542 return sendCommand(NNTPCommand.NEWNEWS, buffer.toString()); 543 } 544 545 /** 546 * A convenience method to send the NNTP NEXT command to the server, receive the reply, and return the reply code. 547 * 548 * @return The reply code received from the server. 549 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 550 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 551 * independently as itself. 552 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 553 */ 554 public int next() throws IOException { 555 return sendCommand(NNTPCommand.NEXT); 556 } 557 558 /** 559 * A convenience method to send the NNTP POST command to the server, receive the reply, and return the reply code. 560 * 561 * @return The reply code received from the server. 562 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 563 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 564 * independently as itself. 565 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 566 */ 567 public int post() throws IOException { 568 return sendCommand(NNTPCommand.POST); 569 } 570 571 /** 572 * A convenience method to send the NNTP QUIT command to the server, receive the reply, and return the reply code. 573 * 574 * @return The reply code received from the server. 575 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 576 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 577 * independently as itself. 578 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 579 */ 580 public int quit() throws IOException { 581 return sendCommand(NNTPCommand.QUIT); 582 } 583 584 /** 585 * Sends an NNTP command with no arguments to the server, waits for a reply and returns the numerical response code. After invocation, for more detailed 586 * information, the actual reply text can be accessed by calling {@link #getReplyString getReplyString }. 587 * 588 * @param command The NNTPCommand constant corresponding to the NNTP command to send. 589 * @return The integer value of the NNTP reply code returned by the server in response to the command. in response to the command. 590 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 591 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 592 * independently as itself. 593 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 594 */ 595 public int sendCommand(final int command) throws IOException { 596 return sendCommand(command, null); 597 } 598 599 /** 600 * Sends an NNTP command to the server, waits for a reply and returns the numerical response code. After invocation, for more detailed information, the 601 * actual reply text can be accessed by calling {@link #getReplyString getReplyString }. 602 * 603 * @param command The NNTPCommand constant corresponding to the NNTP command to send. 604 * @param args The arguments to the NNTP command. If this parameter is set to null, then the command is sent with no argument. 605 * @return The integer value of the NNTP reply code returned by the server in response to the command. in response to the command. 606 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 607 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 608 * independently as itself. 609 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 610 */ 611 public int sendCommand(final int command, final String args) throws IOException { 612 return sendCommand(NNTPCommand.getCommand(command), args); 613 } 614 615 /** 616 * Sends an NNTP command with no arguments to the server, waits for a reply and returns the numerical response code. After invocation, for more detailed 617 * information, the actual reply text can be accessed by calling {@link #getReplyString getReplyString }. 618 * 619 * @param command The text representation of the NNTP command to send. 620 * @return The integer value of the NNTP reply code returned by the server in response to the command. in response to the command. 621 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 622 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 623 * independently as itself. 624 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 625 */ 626 public int sendCommand(final String command) throws IOException { 627 return sendCommand(command, null); 628 } 629 630 /** 631 * Sends an NNTP command to the server, waits for a reply and returns the numerical response code. After invocation, for more detailed information, the 632 * actual reply text can be accessed by calling {@link #getReplyString getReplyString }. 633 * 634 * @param command The text representation of the NNTP command to send. 635 * @param args The arguments to the NNTP command. If this parameter is set to null, then the command is sent with no argument. 636 * @return The integer value of the NNTP reply code returned by the server in response to the command. 637 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 638 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 639 * independently as itself. 640 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 641 */ 642 public int sendCommand(final String command, final String args) throws IOException { 643 final StringBuilder __commandBuffer = new StringBuilder(); 644 __commandBuffer.append(command); 645 646 if (args != null) { 647 __commandBuffer.append(' '); 648 __commandBuffer.append(args); 649 } 650 __commandBuffer.append(SocketClient.NETASCII_EOL); 651 652 final String message; 653 _writer_.write(message = __commandBuffer.toString()); 654 _writer_.flush(); 655 656 fireCommandSent(command, message); 657 658 return getReply(); 659 } 660 661 /** 662 * A convenience method to send the NNTP STAT command to the server, receive the initial reply, and return the reply code. 663 * 664 * @return The reply code received from the server. 665 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 666 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 667 * independently as itself. 668 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 669 */ 670 public int stat() throws IOException { 671 return sendCommand(NNTPCommand.STAT); 672 } 673 674 /** 675 * @param a article number 676 * @return number 677 * @throws IOException on error 678 * @deprecated - for API compatibility only - DO NOT USE 679 */ 680 @Deprecated 681 public int stat(final int a) throws IOException { 682 return stat((long) a); 683 } 684 685 /** 686 * A convenience method to send the NNTP STAT command to the server, receive the initial reply, and return the reply code. 687 * 688 * @param articleNumber The number of the article to request from the currently selected newsgroup. 689 * @return The reply code received from the server. 690 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 691 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 692 * independently as itself. 693 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 694 */ 695 public int stat(final long articleNumber) throws IOException { 696 return sendCommand(NNTPCommand.STAT, Long.toString(articleNumber)); 697 } 698 699 /** 700 * A convenience method to send the NNTP STAT command to the server, receive the initial reply, and return the reply code. 701 * 702 * @param messageId The message identifier of the requested article, including the encapsulating < and > characters. 703 * @return The reply code received from the server. 704 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 705 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 706 * independently as itself. 707 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 708 */ 709 public int stat(final String messageId) throws IOException { 710 return sendCommand(NNTPCommand.STAT, messageId); 711 } 712 713 /** 714 * A convenience method to send the NNTP XHDR command to the server, receive the reply, and return the reply code. 715 * 716 * @param header a String naming a header line (e.g., "subject"). See RFC-1036 for a list of valid header lines. 717 * @param selectedArticles a String representation of the range of article headers required. This may be an article number, or a range of article numbers in 718 * the form "XXXX-YYYY", where XXXX and YYYY are valid article numbers in the current group. It also may be of the form "XXX-", 719 * meaning "return XXX and all following articles" In this revision, the last format is not possible (yet). 720 * @return The reply code received from the server. 721 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 722 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 723 * independently as itself. 724 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 725 */ 726 public int xhdr(final String header, final String selectedArticles) throws IOException { 727 final StringBuilder command = new StringBuilder(header); 728 command.append(" "); 729 command.append(selectedArticles); 730 return sendCommand(NNTPCommand.XHDR, command.toString()); 731 } 732 733 /** 734 * A convenience method to send the NNTP XOVER command to the server, receive the reply, and return the reply code. 735 * 736 * @param selectedArticles a String representation of the range of article headers required. This may be an article number, or a range of article numbers in 737 * the form "XXXX-YYYY", where XXXX and YYYY are valid article numbers in the current group. It also may be of the form "XXX-", 738 * meaning "return XXX and all following articles" In this revision, the last format is not possible (yet). 739 * @return The reply code received from the server. 740 * @throws NNTPConnectionClosedException If the NNTP server prematurely closes the connection as a result of the client being idle or some other reason 741 * causing the server to send NNTP reply code 400. This exception may be caught either as an IOException or 742 * independently as itself. 743 * @throws IOException If an I/O error occurs while either sending the command or receiving the server reply. 744 */ 745 public int xover(final String selectedArticles) throws IOException { 746 return sendCommand(NNTPCommand.XOVER, selectedArticles); 747 } 748}