1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.net.nntp;
  17. import java.io.BufferedReader;
  18. import java.io.BufferedWriter;
  19. import java.io.IOException;
  20. import java.io.InputStreamReader;
  21. import java.io.OutputStreamWriter;
  22. import org.apache.commons.net.MalformedServerReplyException;
  23. import org.apache.commons.net.ProtocolCommandSupport;
  24. import org.apache.commons.net.ProtocolCommandListener;
  25. import org.apache.commons.net.SocketClient;
  26. /***
  27. * The NNTP class is not meant to be used by itself and is provided
  28. * only so that you may easily implement your own NNTP client if
  29. * you so desire. If you have no need to perform your own implementation,
  30. * you should use <a href="org.apache.commons.net.nntp.NNTPClient.html">NNTPClient</a>.
  31. * The NNTP class is made public to provide access to various NNTP constants
  32. * and to make it easier for adventurous programmers (or those with special
  33. * needs) to interact with the NNTP protocol and implement their own clients.
  34. * A set of methods with names corresponding to the NNTP command names are
  35. * provided to facilitate this interaction.
  36. * <p>
  37. * You should keep in mind that the NNTP server may choose to prematurely
  38. * close a connection if the client has been idle for longer than a
  39. * given time period or if the server is being shutdown by the operator or
  40. * some other reason. The NNTP class will detect a
  41. * premature NNTP server connection closing when it receives a
  42. * <a href="org.apache.commons.net.nntp.NNTPReply.html#SERVICE_DISCONTINUED">
  43. * NNTPReply.SERVICE_DISCONTINUED </a> response to a command.
  44. * When that occurs, the NNTP class method encountering that reply will throw
  45. * an <a href="org.apache.commons.net.nntp.NNTPConnectionClosedException.html">
  46. * NNTPConnectionClosedException </a>.
  47. * <code>NNTPConectionClosedException</code>
  48. * is a subclass of <code> IOException </code> and therefore need not be
  49. * caught separately, but if you are going to catch it separately, its
  50. * catch block must appear before the more general <code> IOException </code>
  51. * catch block. When you encounter an
  52. * <a href="org.apache.commons.net.nntp.NNTPConnectionClosedException.html">
  53. * NNTPConnectionClosedException </a>, you must disconnect the connection with
  54. * <a href="#disconnect"> disconnect() </a> to properly clean up the
  55. * system resources used by NNTP. Before disconnecting, you may check the
  56. * last reply code and text with
  57. * <a href="#getReplyCode"> getReplyCode </a> and
  58. * <a href="#getReplyString"> getReplyString </a>.
  59. * <p>
  60. * Rather than list it separately for each method, we mention here that
  61. * every method communicating with the server and throwing an IOException
  62. * can also throw a
  63. * <a href="org.apache.commons.net.MalformedServerReplyException.html">
  64. * MalformedServerReplyException </a>, which is a subclass
  65. * of IOException. A MalformedServerReplyException will be thrown when
  66. * the reply received from the server deviates enough from the protocol
  67. * specification that it cannot be interpreted in a useful manner despite
  68. * attempts to be as lenient as possible.
  69. * <p>
  70. * <p>
  71. * @author Daniel F. Savarese
  72. * @author Rory Winston
  73. * @author Ted Wise
  74. * @see NNTPClient
  75. * @see NNTPConnectionClosedException
  76. * @see org.apache.commons.net.MalformedServerReplyException
  77. ***/
  78. public class NNTP extends SocketClient
  79. {
  80. /*** The default NNTP port. Its value is 119 according to RFC 977. ***/
  81. public static final int DEFAULT_PORT = 119;
  82. // We have to ensure that the protocol communication is in ASCII
  83. // but we use ISO-8859-1 just in case 8-bit characters cross
  84. // the wire.
  85. private static final String __DEFAULT_ENCODING = "ISO-8859-1";
  86. private StringBuffer __commandBuffer;
  87. boolean _isAllowedToPost;
  88. int _replyCode;
  89. String _replyString;
  90. /**
  91. * Wraps {@link SocketClient#_input_}
  92. * to communicate with server. Initialized by {@link #_connectAction_}.
  93. * All server reads should be done through this variable.
  94. */
  95. protected BufferedReader _reader_;
  96. /**
  97. * Wraps {@link SocketClient#_output_}
  98. * to communicate with server. Initialized by {@link #_connectAction_}.
  99. * All server reads should be done through this variable.
  100. */
  101. protected BufferedWriter _writer_;
  102. /***
  103. * A ProtocolCommandSupport object used to manage the registering of
  104. * ProtocolCommandListeners and te firing of ProtocolCommandEvents.
  105. ***/
  106. protected ProtocolCommandSupport _commandSupport_;
  107. /***
  108. * The default NNTP constructor. Sets the default port to
  109. * <code>DEFAULT_PORT</code> and initializes internal data structures
  110. * for saving NNTP reply information.
  111. ***/
  112. public NNTP()
  113. {
  114. setDefaultPort(DEFAULT_PORT);
  115. __commandBuffer = new StringBuffer();
  116. _replyString = null;
  117. _reader_ = null;
  118. _writer_ = null;
  119. _isAllowedToPost = false;
  120. _commandSupport_ = new ProtocolCommandSupport(this);
  121. }
  122. private void __getReply() throws IOException
  123. {
  124. _replyString = _reader_.readLine();
  125. if (_replyString == null)
  126. throw new NNTPConnectionClosedException(
  127. "Connection closed without indication.");
  128. // In case we run into an anomaly we don't want fatal index exceptions
  129. // to be thrown.
  130. if (_replyString.length() < 3)
  131. throw new MalformedServerReplyException(
  132. "Truncated server reply: " + _replyString);
  133. try
  134. {
  135. _replyCode = Integer.parseInt(_replyString.substring(0, 3));
  136. }
  137. catch (NumberFormatException e)
  138. {
  139. throw new MalformedServerReplyException(
  140. "Could not parse response code.\nServer Reply: " + _replyString);
  141. }
  142. if (_commandSupport_.getListenerCount() > 0)
  143. _commandSupport_.fireReplyReceived(_replyCode, _replyString +
  144. SocketClient.NETASCII_EOL);
  145. if (_replyCode == NNTPReply.SERVICE_DISCONTINUED)
  146. throw new NNTPConnectionClosedException(
  147. "NNTP response 400 received. Server closed connection.");
  148. }
  149. /***
  150. * Initiates control connections and gets initial reply, determining
  151. * if the client is allowed to post to the server. Initializes
  152. * {@link #_reader_} and {@link #_writer_} to wrap
  153. * {@link SocketClient#_input_} and {@link SocketClient#_output_}.
  154. ***/
  155. protected void _connectAction_() throws IOException
  156. {
  157. super._connectAction_();
  158. _reader_ =
  159. new BufferedReader(new InputStreamReader(_input_,
  160. __DEFAULT_ENCODING));
  161. _writer_ =
  162. new BufferedWriter(new OutputStreamWriter(_output_,
  163. __DEFAULT_ENCODING));
  164. __getReply();
  165. _isAllowedToPost = (_replyCode == NNTPReply.SERVER_READY_POSTING_ALLOWED);
  166. }
  167. /***
  168. * Adds a ProtocolCommandListener. Delegates this task to
  169. * <a href="#_commandSupport_"> _commandSupport_ </a>.
  170. * <p>
  171. * @param listener The ProtocolCommandListener to add.
  172. ***/
  173. public void addProtocolCommandListener(ProtocolCommandListener listener)
  174. {
  175. _commandSupport_.addProtocolCommandListener(listener);
  176. }
  177. /***
  178. * Removes a ProtocolCommandListener. Delegates this task to
  179. * <a href="#_commandSupport_"> _commandSupport_ </a>.
  180. * <p>
  181. * @param listener The ProtocolCommandListener to remove.
  182. ***/
  183. public void removeProtocolCommandListener(ProtocolCommandListener listener)
  184. {
  185. _commandSupport_.removeProtocolCommandListener(listener);
  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. public void disconnect() throws IOException
  196. {
  197. super.disconnect();
  198. _reader_ = null;
  199. _writer_ = null;
  200. _replyString = null;
  201. _isAllowedToPost = false;
  202. }
  203. /***
  204. * Indicates whether or not the client is allowed to post articles to
  205. * the server it is currently connected to.
  206. * <p>
  207. * @return True if the client can post articles to the server, false
  208. * otherwise.
  209. ***/
  210. public boolean isAllowedToPost()
  211. {
  212. return _isAllowedToPost;
  213. }
  214. /***
  215. * Sends an NNTP command to the server, waits for a reply and returns the
  216. * numerical response code. After invocation, for more detailed
  217. * information, the actual reply text can be accessed by calling
  218. * <a href="#getReplyString"> getReplyString </a>.
  219. * <p>
  220. * @param command The text representation of the NNTP command to send.
  221. * @param args The arguments to the NNTP command. If this parameter is
  222. * set to null, then the command is sent with no argument.
  223. * @return The integer value of the NNTP reply code returned by the server
  224. * in response to the command.
  225. * @exception NNTPConnectionClosedException
  226. * If the NNTP server prematurely closes the connection as a result
  227. * of the client being idle or some other reason causing the server
  228. * to send NNTP reply code 400. This exception may be caught either
  229. * as an IOException or independently as itself.
  230. * @exception IOException If an I/O error occurs while either sending the
  231. * command or receiving the server reply.
  232. ***/
  233. public int sendCommand(String command, String args) throws IOException
  234. {
  235. String message;
  236. __commandBuffer.setLength(0);
  237. __commandBuffer.append(command);
  238. if (args != null)
  239. {
  240. __commandBuffer.append(' ');
  241. __commandBuffer.append(args);
  242. }
  243. __commandBuffer.append(SocketClient.NETASCII_EOL);
  244. _writer_.write(message = __commandBuffer.toString());
  245. _writer_.flush();
  246. if (_commandSupport_.getListenerCount() > 0)
  247. _commandSupport_.fireCommandSent(command, message);
  248. __getReply();
  249. return _replyCode;
  250. }
  251. /***
  252. * Sends an NNTP command to the server, waits for a reply and returns the
  253. * numerical response code. After invocation, for more detailed
  254. * information, the actual reply text can be accessed by calling
  255. * <a href="#getReplyString"> getReplyString </a>.
  256. * <p>
  257. * @param command The NNTPCommand constant corresponding to the NNTP command
  258. * to send.
  259. * @param args The arguments to the NNTP command. If this parameter is
  260. * set to null, then the command is sent with no argument.
  261. * @return The integer value of the NNTP reply code returned by the server
  262. * in response to the command.
  263. * in response to the command.
  264. * @exception NNTPConnectionClosedException
  265. * If the NNTP server prematurely closes the connection as a result
  266. * of the client being idle or some other reason causing the server
  267. * to send NNTP reply code 400. This exception may be caught either
  268. * as an IOException or independently as itself.
  269. * @exception IOException If an I/O error occurs while either sending the
  270. * command or receiving the server reply.
  271. ***/
  272. public int sendCommand(int command, String args) throws IOException
  273. {
  274. return sendCommand(NNTPCommand._commands[command], args);
  275. }
  276. /***
  277. * Sends an NNTP command with no arguments to the server, waits for a
  278. * reply and returns the numerical response code. After invocation, for
  279. * more detailed information, the actual reply text can be accessed by
  280. * calling <a href="#getReplyString"> getReplyString </a>.
  281. * <p>
  282. * @param command The text representation of the NNTP command to send.
  283. * @return The integer value of the NNTP reply code returned by the server
  284. * in response to the command.
  285. * in response to the command.
  286. * @exception NNTPConnectionClosedException
  287. * If the NNTP server prematurely closes the connection as a result
  288. * of the client being idle or some other reason causing the server
  289. * to send NNTP reply code 400. This exception may be caught either
  290. * as an IOException or independently as itself.
  291. * @exception IOException If an I/O error occurs while either sending the
  292. * command or receiving the server reply.
  293. ***/
  294. public int sendCommand(String command) throws IOException
  295. {
  296. return sendCommand(command, null);
  297. }
  298. /***
  299. * Sends an NNTP command with no arguments to the server, waits for a
  300. * reply and returns the numerical response code. After invocation, for
  301. * more detailed information, the actual reply text can be accessed by
  302. * calling <a href="#getReplyString"> getReplyString </a>.
  303. * <p>
  304. * @param command The NNTPCommand constant corresponding to the NNTP command
  305. * to send.
  306. * @return The integer value of the NNTP reply code returned by the server
  307. * in response to the command.
  308. * in response to the command.
  309. * @exception NNTPConnectionClosedException
  310. * If the NNTP server prematurely closes the connection as a result
  311. * of the client being idle or some other reason causing the server
  312. * to send NNTP reply code 400. This exception may be caught either
  313. * as an IOException or independently as itself.
  314. * @exception IOException If an I/O error occurs while either sending the
  315. * command or receiving the server reply.
  316. ***/
  317. public int sendCommand(int command) throws IOException
  318. {
  319. return sendCommand(command, null);
  320. }
  321. /***
  322. * Returns the integer value of the reply code of the last NNTP reply.
  323. * You will usually only use this method after you connect to the
  324. * NNTP server to check that the connection was successful since
  325. * <code> connect </code> is of type void.
  326. * <p>
  327. * @return The integer value of the reply code of the last NNTP reply.
  328. ***/
  329. public int getReplyCode()
  330. {
  331. return _replyCode;
  332. }
  333. /***
  334. * Fetches a reply from the NNTP server and returns the integer reply
  335. * code. After calling this method, the actual reply text can be accessed
  336. * from <a href="#getReplyString"> getReplyString </a>. Only use this
  337. * method if you are implementing your own NNTP client or if you need to
  338. * fetch a secondary response from the NNTP server.
  339. * <p>
  340. * @return The integer value of the reply code of the fetched NNTP reply.
  341. * in response to the command.
  342. * @exception NNTPConnectionClosedException
  343. * If the NNTP server prematurely closes the connection as a result
  344. * of the client being idle or some other reason causing the server
  345. * to send NNTP reply code 400. This exception may be caught either
  346. * as an IOException or independently as itself.
  347. * @exception IOException If an I/O error occurs while
  348. * receiving the server reply.
  349. ***/
  350. public int getReply() throws IOException
  351. {
  352. __getReply();
  353. return _replyCode;
  354. }
  355. /***
  356. * Returns the entire text of the last NNTP server response exactly
  357. * as it was received, not including the end of line marker.
  358. * <p>
  359. * @return The entire text from the last NNTP response as a String.
  360. ***/
  361. public String getReplyString()
  362. {
  363. return _replyString;
  364. }
  365. /***
  366. * A convenience method to send the NNTP ARTICLE command to the server,
  367. * receive the initial reply, and return the reply code.
  368. * <p>
  369. * @param messageId The message identifier of the requested article,
  370. * including the encapsulating < and > characters.
  371. * @return The reply code received from the server.
  372. * @exception NNTPConnectionClosedException
  373. * If the NNTP server prematurely closes the connection as a result
  374. * of the client being idle or some other reason causing the server
  375. * to send NNTP reply code 400. This exception may be caught either
  376. * as an IOException or independently as itself.
  377. * @exception IOException If an I/O error occurs while either sending the
  378. * command or receiving the server reply.
  379. ***/
  380. public int article(String messageId) throws IOException
  381. {
  382. return sendCommand(NNTPCommand.ARTICLE, messageId);
  383. }
  384. /***
  385. * A convenience method to send the NNTP ARTICLE command to the server,
  386. * receive the initial reply, and return the reply code.
  387. * <p>
  388. * @param articleNumber The number of the article to request from the
  389. * currently selected newsgroup.
  390. * @return The reply code received from the server.
  391. * @exception NNTPConnectionClosedException
  392. * If the NNTP server prematurely closes the connection as a result
  393. * of the client being idle or some other reason causing the server
  394. * to send NNTP reply code 400. This exception may be caught either
  395. * as an IOException or independently as itself.
  396. * @exception IOException If an I/O error occurs while either sending the
  397. * command or receiving the server reply.
  398. ***/
  399. public int article(int articleNumber) throws IOException
  400. {
  401. return sendCommand(NNTPCommand.ARTICLE, Integer.toString(articleNumber));
  402. }
  403. /***
  404. * A convenience method to send the NNTP ARTICLE command to the server,
  405. * receive the initial reply, and return the reply code.
  406. * <p>
  407. * @return The reply code received from the server.
  408. * @exception NNTPConnectionClosedException
  409. * If the NNTP server prematurely closes the connection as a result
  410. * of the client being idle or some other reason causing the server
  411. * to send NNTP reply code 400. This exception may be caught either
  412. * as an IOException or independently as itself.
  413. * @exception IOException If an I/O error occurs while either sending the
  414. * command or receiving the server reply.
  415. ***/
  416. public int article() throws IOException
  417. {
  418. return sendCommand(NNTPCommand.ARTICLE);
  419. }
  420. /***
  421. * A convenience method to send the NNTP BODY command to the server,
  422. * receive the initial reply, and return the reply code.
  423. * <p>
  424. * @param messageId The message identifier of the requested article,
  425. * including the encapsulating < and > characters.
  426. * @return The reply code received from the server.
  427. * @exception NNTPConnectionClosedException
  428. * If the NNTP server prematurely closes the connection as a result
  429. * of the client being idle or some other reason causing the server
  430. * to send NNTP reply code 400. This exception may be caught either
  431. * as an IOException or independently as itself.
  432. * @exception IOException If an I/O error occurs while either sending the
  433. * command or receiving the server reply.
  434. ***/
  435. public int body(String messageId) throws IOException
  436. {
  437. return sendCommand(NNTPCommand.BODY, messageId);
  438. }
  439. /***
  440. * A convenience method to send the NNTP BODY command to the server,
  441. * receive the initial reply, and return the reply code.
  442. * <p>
  443. * @param articleNumber The number of the article to request from the
  444. * currently selected newsgroup.
  445. * @return The reply code received from the server.
  446. * @exception NNTPConnectionClosedException
  447. * If the NNTP server prematurely closes the connection as a result
  448. * of the client being idle or some other reason causing the server
  449. * to send NNTP reply code 400. This exception may be caught either
  450. * as an IOException or independently as itself.
  451. * @exception IOException If an I/O error occurs while either sending the
  452. * command or receiving the server reply.
  453. ***/
  454. public int body(int articleNumber) throws IOException
  455. {
  456. return sendCommand(NNTPCommand.BODY, Integer.toString(articleNumber));
  457. }
  458. /***
  459. * A convenience method to send the NNTP BODY command to the server,
  460. * receive the initial reply, and return the reply code.
  461. * <p>
  462. * @return The reply code received from the server.
  463. * @exception NNTPConnectionClosedException
  464. * If the NNTP server prematurely closes the connection as a result
  465. * of the client being idle or some other reason causing the server
  466. * to send NNTP reply code 400. This exception may be caught either
  467. * as an IOException or independently as itself.
  468. * @exception IOException If an I/O error occurs while either sending the
  469. * command or receiving the server reply.
  470. ***/
  471. public int body() throws IOException
  472. {
  473. return sendCommand(NNTPCommand.BODY);
  474. }
  475. /***
  476. * A convenience method to send the NNTP HEAD command to the server,
  477. * receive the initial reply, and return the reply code.
  478. * <p>
  479. * @param messageId The message identifier of the requested article,
  480. * including the encapsulating < and > characters.
  481. * @return The reply code received from the server.
  482. * @exception NNTPConnectionClosedException
  483. * If the NNTP server prematurely closes the connection as a result
  484. * of the client being idle or some other reason causing the server
  485. * to send NNTP reply code 400. This exception may be caught either
  486. * as an IOException or independently as itself.
  487. * @exception IOException If an I/O error occurs while either sending the
  488. * command or receiving the server reply.
  489. ***/
  490. public int head(String messageId) throws IOException
  491. {
  492. return sendCommand(NNTPCommand.HEAD, messageId);
  493. }
  494. /***
  495. * A convenience method to send the NNTP HEAD command to the server,
  496. * receive the initial reply, and return the reply code.
  497. * <p>
  498. * @param articleNumber The number of the article to request from the
  499. * currently selected newsgroup.
  500. * @return The reply code received from the server.
  501. * @exception NNTPConnectionClosedException
  502. * If the NNTP server prematurely closes the connection as a result
  503. * of the client being idle or some other reason causing the server
  504. * to send NNTP reply code 400. This exception may be caught either
  505. * as an IOException or independently as itself.
  506. * @exception IOException If an I/O error occurs while either sending the
  507. * command or receiving the server reply.
  508. ***/
  509. public int head(int articleNumber) throws IOException
  510. {
  511. return sendCommand(NNTPCommand.HEAD, Integer.toString(articleNumber));
  512. }
  513. /***
  514. * A convenience method to send the NNTP HEAD command to the server,
  515. * receive the initial reply, and return the reply code.
  516. * <p>
  517. * @return The reply code received from the server.
  518. * @exception NNTPConnectionClosedException
  519. * If the NNTP server prematurely closes the connection as a result
  520. * of the client being idle or some other reason causing the server
  521. * to send NNTP reply code 400. This exception may be caught either
  522. * as an IOException or independently as itself.
  523. * @exception IOException If an I/O error occurs while either sending the
  524. * command or receiving the server reply.
  525. ***/
  526. public int head() throws IOException
  527. {
  528. return sendCommand(NNTPCommand.HEAD);
  529. }
  530. /***
  531. * A convenience method to send the NNTP STAT command to the server,
  532. * receive the initial reply, and return the reply code.
  533. * <p>
  534. * @param messageId The message identifier of the requested article,
  535. * including the encapsulating < and > characters.
  536. * @return The reply code received from the server.
  537. * @exception NNTPConnectionClosedException
  538. * If the NNTP server prematurely closes the connection as a result
  539. * of the client being idle or some other reason causing the server
  540. * to send NNTP reply code 400. This exception may be caught either
  541. * as an IOException or independently as itself.
  542. * @exception IOException If an I/O error occurs while either sending the
  543. * command or receiving the server reply.
  544. ***/
  545. public int stat(String messageId) throws IOException
  546. {
  547. return sendCommand(NNTPCommand.STAT, messageId);
  548. }
  549. /***
  550. * A convenience method to send the NNTP STAT command to the server,
  551. * receive the initial reply, and return the reply code.
  552. * <p>
  553. * @param articleNumber The number of the article to request from the
  554. * currently selected newsgroup.
  555. * @return The reply code received from the server.
  556. * @exception NNTPConnectionClosedException
  557. * If the NNTP server prematurely closes the connection as a result
  558. * of the client being idle or some other reason causing the server
  559. * to send NNTP reply code 400. This exception may be caught either
  560. * as an IOException or independently as itself.
  561. * @exception IOException If an I/O error occurs while either sending the
  562. * command or receiving the server reply.
  563. ***/
  564. public int stat(int articleNumber) throws IOException
  565. {
  566. return sendCommand(NNTPCommand.STAT, Integer.toString(articleNumber));
  567. }
  568. /***
  569. * A convenience method to send the NNTP STAT command to the server,
  570. * receive the initial reply, and return the reply code.
  571. * <p>
  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() throws IOException
  582. {
  583. return sendCommand(NNTPCommand.STAT);
  584. }
  585. /***
  586. * A convenience method to send the NNTP GROUP command to the server,
  587. * receive the reply, and return the reply code.
  588. * <p>
  589. * @param newsgroup The name of the newsgroup to select.
  590. * @return The reply code received from the server.
  591. * @exception NNTPConnectionClosedException
  592. * If the NNTP server prematurely closes the connection as a result
  593. * of the client being idle or some other reason causing the server
  594. * to send NNTP reply code 400. This exception may be caught either
  595. * as an IOException or independently as itself.
  596. * @exception IOException If an I/O error occurs while either sending the
  597. * command or receiving the server reply.
  598. ***/
  599. public int group(String newsgroup) throws IOException
  600. {
  601. return sendCommand(NNTPCommand.GROUP, newsgroup);
  602. }
  603. /***
  604. * A convenience method to send the NNTP HELP command to the server,
  605. * receive the reply, and return the reply code.
  606. * <p>
  607. * @return The reply code received from the server.
  608. * @exception NNTPConnectionClosedException
  609. * If the NNTP server prematurely closes the connection as a result
  610. * of the client being idle or some other reason causing the server
  611. * to send NNTP reply code 400. This exception may be caught either
  612. * as an IOException or independently as itself.
  613. * @exception IOException If an I/O error occurs while either sending the
  614. * command or receiving the server reply.
  615. ***/
  616. public int help() throws IOException
  617. {
  618. return sendCommand(NNTPCommand.HELP);
  619. }
  620. /***
  621. * A convenience method to send the NNTP IHAVE command to the server,
  622. * receive the reply, and return the reply code.
  623. * <p>
  624. * @param messageId The article identifier,
  625. * including the encapsulating < and > characters.
  626. * @return The reply code received from the server.
  627. * @exception NNTPConnectionClosedException
  628. * If the NNTP server prematurely closes the connection as a result
  629. * of the client being idle or some other reason causing the server
  630. * to send NNTP reply code 400. This exception may be caught either
  631. * as an IOException or independently as itself.
  632. * @exception IOException If an I/O error occurs while either sending the
  633. * command or receiving the server reply.
  634. ***/
  635. public int ihave(String messageId) throws IOException
  636. {
  637. return sendCommand(NNTPCommand.IHAVE, messageId);
  638. }
  639. /***
  640. * A convenience method to send the NNTP LAST command to the server,
  641. * receive the reply, and return the reply code.
  642. * <p>
  643. * @return The reply code received from the server.
  644. * @exception NNTPConnectionClosedException
  645. * If the NNTP server prematurely closes the connection as a result
  646. * of the client being idle or some other reason causing the server
  647. * to send NNTP reply code 400. This exception may be caught either
  648. * as an IOException or independently as itself.
  649. * @exception IOException If an I/O error occurs while either sending the
  650. * command or receiving the server reply.
  651. ***/
  652. public int last() throws IOException
  653. {
  654. return sendCommand(NNTPCommand.LAST);
  655. }
  656. /***
  657. * A convenience method to send the NNTP LIST command to the server,
  658. * receive the reply, and return the reply code.
  659. * <p>
  660. * @return The reply code received from the server.
  661. * @exception NNTPConnectionClosedException
  662. * If the NNTP server prematurely closes the connection as a result
  663. * of the client being idle or some other reason causing the server
  664. * to send NNTP reply code 400. This exception may be caught either
  665. * as an IOException or independently as itself.
  666. * @exception IOException If an I/O error occurs while either sending the
  667. * command or receiving the server reply.
  668. ***/
  669. public int list() throws IOException
  670. {
  671. return sendCommand(NNTPCommand.LIST);
  672. }
  673. /***
  674. * A convenience method to send the NNTP NEXT command to the server,
  675. * receive the reply, and return the reply code.
  676. * <p>
  677. * @return The reply code received from the server.
  678. * @exception NNTPConnectionClosedException
  679. * If the NNTP server prematurely closes the connection as a result
  680. * of the client being idle or some other reason causing the server
  681. * to send NNTP reply code 400. This exception may be caught either
  682. * as an IOException or independently as itself.
  683. * @exception IOException If an I/O error occurs while either sending the
  684. * command or receiving the server reply.
  685. ***/
  686. public int next() throws IOException
  687. {
  688. return sendCommand(NNTPCommand.NEXT);
  689. }
  690. /***
  691. * A convenience method to send the NNTP NEWGROUPS command to the server,
  692. * receive the reply, and return the reply code.
  693. * <p>
  694. * @param date The date after which to check for new groups.
  695. * Date format is YYMMDD
  696. * @param time The time after which to check for new groups.
  697. * Time format is HHMMSS using a 24-hour clock.
  698. * @param GMT True if the time is in GMT, false if local server time.
  699. * @param distributions Comma-separated distribution list to check for
  700. * new groups. Set to null if no distributions.
  701. * @return The reply code received from the server.
  702. * @exception NNTPConnectionClosedException
  703. * If the NNTP server prematurely closes the connection as a result
  704. * of the client being idle or some other reason causing the server
  705. * to send NNTP reply code 400. This exception may be caught either
  706. * as an IOException or independently as itself.
  707. * @exception IOException If an I/O error occurs while either sending the
  708. * command or receiving the server reply.
  709. ***/
  710. public int newgroups(String date, String time, boolean GMT,
  711. String distributions) throws IOException
  712. {
  713. StringBuffer buffer = new StringBuffer();
  714. buffer.append(date);
  715. buffer.append(' ');
  716. buffer.append(time);
  717. if (GMT)
  718. {
  719. buffer.append(' ');
  720. buffer.append("GMT");
  721. }
  722. if (distributions != null)
  723. {
  724. buffer.append(" <");
  725. buffer.append(distributions);
  726. buffer.append('>');
  727. }
  728. return sendCommand(NNTPCommand.NEWGROUPS, buffer.toString());
  729. }
  730. /***
  731. * A convenience method to send the NNTP NEWGROUPS command to the server,
  732. * receive the reply, and return the reply code.
  733. * <p>
  734. * @param newsgroups A comma-separated list of newsgroups to check for new
  735. * news.
  736. * @param date The date after which to check for new news.
  737. * Date format is YYMMDD
  738. * @param time The time after which to check for new news.
  739. * Time format is HHMMSS using a 24-hour clock.
  740. * @param GMT True if the time is in GMT, false if local server time.
  741. * @param distributions Comma-separated distribution list to check for
  742. * new news. Set to null if no distributions.
  743. * @return The reply code received from the server.
  744. * @exception NNTPConnectionClosedException
  745. * If the NNTP server prematurely closes the connection as a result
  746. * of the client being idle or some other reason causing the server
  747. * to send NNTP reply code 400. This exception may be caught either
  748. * as an IOException or independently as itself.
  749. * @exception IOException If an I/O error occurs while either sending the
  750. * command or receiving the server reply.
  751. ***/
  752. public int newnews(String newsgroups, String date, String time, boolean GMT,
  753. String distributions) throws IOException
  754. {
  755. StringBuffer buffer = new StringBuffer();
  756. buffer.append(newsgroups);
  757. buffer.append(' ');
  758. buffer.append(date);
  759. buffer.append(' ');
  760. buffer.append(time);
  761. if (GMT)
  762. {
  763. buffer.append(' ');
  764. buffer.append("GMT");
  765. }
  766. if (distributions != null)
  767. {
  768. buffer.append(" <");
  769. buffer.append(distributions);
  770. buffer.append('>');
  771. }
  772. return sendCommand(NNTPCommand.NEWNEWS, buffer.toString());
  773. }
  774. /***
  775. * A convenience method to send the NNTP POST command to the server,
  776. * receive the reply, and return the reply code.
  777. * <p>
  778. * @return The reply code received from the server.
  779. * @exception NNTPConnectionClosedException
  780. * If the NNTP server prematurely closes the connection as a result
  781. * of the client being idle or some other reason causing the server
  782. * to send NNTP reply code 400. This exception may be caught either
  783. * as an IOException or independently as itself.
  784. * @exception IOException If an I/O error occurs while either sending the
  785. * command or receiving the server reply.
  786. ***/
  787. public int post() throws IOException
  788. {
  789. return sendCommand(NNTPCommand.POST);
  790. }
  791. /***
  792. * A convenience method to send the NNTP QUIT command to the server,
  793. * receive the reply, and return the reply code.
  794. * <p>
  795. * @return The reply code received from the server.
  796. * @exception NNTPConnectionClosedException
  797. * If the NNTP server prematurely closes the connection as a result
  798. * of the client being idle or some other reason causing the server
  799. * to send NNTP reply code 400. This exception may be caught either
  800. * as an IOException or independently as itself.
  801. * @exception IOException If an I/O error occurs while either sending the
  802. * command or receiving the server reply.
  803. ***/
  804. public int quit() throws IOException
  805. {
  806. return sendCommand(NNTPCommand.QUIT);
  807. }
  808. /***
  809. * A convenience method to send the AUTHINFO USER command to the server,
  810. * receive the reply, and return the reply code. (See RFC 2980)
  811. * <p>
  812. * @param username A valid username.
  813. * @return The reply code received from the server. The server should
  814. * return a 381 or 281 for this command.
  815. * @exception NNTPConnectionClosedException
  816. * If the NNTP server prematurely closes the connection as a result
  817. * of the client being idle or some other reason causing the server
  818. * to send NNTP reply code 400. This exception may be caught either
  819. * as an IOException or independently as itself.
  820. * @exception IOException If an I/O error occurs while either sending the
  821. * command or receiving the server reply.
  822. ***/
  823. public int authinfoUser(String username) throws IOException {
  824. String userParameter = "USER " + username;
  825. return sendCommand(NNTPCommand.AUTHINFO, userParameter);
  826. }
  827. /***
  828. * A convenience method to send the AUTHINFO PASS command to the server,
  829. * receive the reply, and return the reply code. If this step is
  830. * required, it should immediately follow the AUTHINFO USER command
  831. * (See RFC 2980)
  832. * <p>
  833. * @param password a valid password.
  834. * @return The reply code received from the server. The server should
  835. * return a 281 or 502 for this command.
  836. * @exception NNTPConnectionClosedException
  837. * If the NNTP server prematurely closes the connection as a result
  838. * of the client being idle or some other reason causing the server
  839. * to send NNTP reply code 400. This exception may be caught either
  840. * as an IOException or independently as itself.
  841. * @exception IOException If an I/O error occurs while either sending the
  842. * command or receiving the server reply.
  843. ***/
  844. public int authinfoPass(String password) throws IOException {
  845. String passParameter = "PASS " + password;
  846. return sendCommand(NNTPCommand.AUTHINFO, passParameter);
  847. }
  848. /***
  849. * A convenience method to send the NNTP XOVER command to the server,
  850. * receive the reply, and return the reply code.
  851. * <p>
  852. * @param selectedArticles a String representation of the range of
  853. * article headers required. This may be an article number, or a
  854. * range of article numbers in the form "XXXX-YYYY", where XXXX
  855. * and YYYY are valid article numbers in the current group. It
  856. * also may be of the form "XXX-", meaning "return XXX and all
  857. * following articles" In this revision, the last format is not
  858. * possible (yet).
  859. * @return The reply code received from the server.
  860. * @exception NNTPConnectionClosedException
  861. * If the NNTP server prematurely closes the connection as a result
  862. * of the client being idle or some other reason causing the server
  863. * to send NNTP reply code 400. This exception may be caught either
  864. * as an IOException or independently as itself.
  865. * @exception IOException If an I/O error occurs while either sending the
  866. * command or receiving the server reply.
  867. ***/
  868. public int xover(String selectedArticles) throws IOException {
  869. return sendCommand(NNTPCommand.XOVER, selectedArticles);
  870. }
  871. /***
  872. * A convenience method to send the NNTP XHDR command to the server,
  873. * receive the reply, and return the reply code.
  874. * <p>
  875. * @param header a String naming a header line (e.g., "subject"). See
  876. * RFC-1036 for a list of valid header lines.
  877. * @param selectedArticles a String representation of the range of
  878. * article headers required. This may be an article number, or a
  879. * range of article numbers in the form "XXXX-YYYY", where XXXX
  880. * and YYYY are valid article numbers in the current group. It
  881. * also may be of the form "XXX-", meaning "return XXX and all
  882. * following articles" In this revision, the last format is not
  883. * possible (yet).
  884. * @return The reply code received from the server.
  885. * @exception 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. * @exception IOException If an I/O error occurs while either sending the
  891. * command or receiving the server reply.
  892. ***/
  893. public int xhdr(String header, String selectedArticles) throws IOException {
  894. StringBuffer command = new StringBuffer(header);
  895. command.append(" ");
  896. command.append(selectedArticles);
  897. return sendCommand(NNTPCommand.XHDR, command.toString());
  898. }
  899. /**
  900. * A convenience wrapper for the extended LIST command that takes
  901. * an argument, allowing us to selectively list multiple groups.
  902. * <p>
  903. * @param wildmat A wildmat (pseudo-regex) pattern. See RFC 2980 for
  904. * details.
  905. * @return the reply code received from the server.
  906. * @throws IOException
  907. */
  908. public int listActive(String wildmat) throws IOException {
  909. StringBuffer command = new StringBuffer("ACTIVE ");
  910. command.append(wildmat);
  911. return sendCommand(NNTPCommand.LIST, command.toString());
  912. }
  913. }
  914. /* Emacs configuration
  915. * Local variables: **
  916. * mode: java **
  917. * c-basic-offset: 4 **
  918. * indent-tabs-mode: nil **
  919. * End: **
  920. */