001 package com.croftsoft.core.net.news; 002 003 import java.net.*; 004 import java.io.*; 005 import java.util.*; 006 007 import com.croftsoft.core.util.log.Log; 008 import com.croftsoft.core.lang.NullArgumentException; 009 010 /********************************************************************* 011 * Implements NNTP as given by RFC 977. 012 * 013 * @see 014 * "Common NNTP Extensions (AUTHINFO), 015 * <a target="blank" 016 * href="http://www.mibsoftware.com/userkt/nntpext/0032.htm"> 017 * http://www.mibsoftware.com/userkt/nntpext/0032.htm</a>" 018 * 019 * @author 020 * <a href="https://www.croftsoft.com/">David Wallace Croft</A> 021 * @version 022 * 2001-08-03 023 * @since 024 * 1997-05-10 025 *********************************************************************/ 026 027 public class NntpSocket extends Socket 028 implements NntpConstants 029 ////////////////////////////////////////////////////////////////////// 030 ////////////////////////////////////////////////////////////////////// 031 { 032 033 private BufferedReader bufferedReader; 034 035 private PrintStream printStream; 036 037 private String responseCode; 038 039 private Vector response_text; 040 041 private boolean postingAllowed; 042 043 // private Vector newsgroup_Vector; 044 045 private Log log; 046 047 ////////////////////////////////////////////////////////////////////// 048 ////////////////////////////////////////////////////////////////////// 049 050 /********************************************************************* 051 * Be sure to call command_QUIT() when done. 052 *********************************************************************/ 053 public NntpSocket ( 054 String nntpServerHost, 055 Log log ) 056 throws IOException 057 ////////////////////////////////////////////////////////////////////// 058 { 059 super ( nntpServerHost, NNTP_PORT ); 060 061 this.log = log; 062 063 setSoLinger ( true, 30 ); // timeout after 30 seconds 064 065 bufferedReader = new BufferedReader ( 066 new InputStreamReader ( getInputStream ( ) ) ); 067 068 printStream = new PrintStream ( getOutputStream ( ) ); 069 070 responseCode = bufferedReader.readLine ( ); 071 072 record ( responseCode ); 073 074 if ( responseCode.startsWith ( "200" ) ) 075 { 076 postingAllowed = true; 077 } 078 else if ( !responseCode.startsWith ( "201" ) ) 079 { 080 throw new IOException ( "Connection failed: " + responseCode ); 081 } 082 } 083 084 ////////////////////////////////////////////////////////////////////// 085 ////////////////////////////////////////////////////////////////////// 086 087 public BufferedReader getBufferedReader ( ) 088 ////////////////////////////////////////////////////////////////////// 089 { 090 return bufferedReader; 091 } 092 093 /********************************************************************* 094 * Returns the response code for the last command. 095 *********************************************************************/ 096 public String getResponseCode ( ) { return responseCode; } 097 098 /********************************************************************* 099 * Returns the response text, a Vector of String, for the last command. 100 *********************************************************************/ 101 public Vector response_text ( ) { return response_text; } 102 103 /********************************************************************* 104 * Returns true if posting to this server is allowed. 105 *********************************************************************/ 106 public boolean getPostingAllowed ( ) { return postingAllowed; } 107 108 /********************************************************************* 109 * Returns a Vector of Newsgroup. 110 *********************************************************************/ 111 // public Vector newsgroup_Vector ( ) { return newsgroup_Vector; } 112 113 ////////////////////////////////////////////////////////////////////// 114 ////////////////////////////////////////////////////////////////////// 115 116 /********************************************************************* 117 * Loads the response_text from the NNTPSocket InputStream. 118 * Decodes it as well. 119 *********************************************************************/ 120 public synchronized Vector load_response_text ( ) 121 throws IOException 122 ////////////////////////////////////////////////////////////////////// 123 { 124 response_text = new Vector ( ); 125 126 String line; 127 128 int count = 0; 129 130 while ( ( line = bufferedReader.readLine ( ) ) != null ) 131 { 132 if ( line.equals ( "." ) ) break; 133 134 line = NntpLib.decodeLine ( line ); 135 136 response_text.addElement ( line ); 137 138 if ( ( ++count % 1000 ) == 0 ) System.out.print ( "." ); 139 140 } 141 142 System.out.println ( "\n" + count + " newsgroups" ); 143 144 return response_text; 145 } 146 147 /********************************************************************* 148 * Sends command + CR_LF to the server. 149 * Returns the responseCode. 150 *********************************************************************/ 151 public synchronized String command ( String command ) 152 throws IOException 153 ////////////////////////////////////////////////////////////////////// 154 { 155 printStream.print ( command + CR_LF ); 156 157 record ( command + CR_LF ); 158 159 responseCode = bufferedReader.readLine ( ); 160 161 record ( responseCode ); 162 163 return responseCode; 164 } 165 166 /********************************************************************* 167 *********************************************************************/ 168 /* 169 public synchronized String command_GROUP ( String group_name ) 170 throws IOException 171 ////////////////////////////////////////////////////////////////////// 172 { 173 responseCode = command ( COMMAND_GROUP + " " + group_name ); 174 175 if ( responseCode.startsWith ( "211" ) ) 176 { 177 178 StringTokenizer st = new StringTokenizer ( responseCode ); 179 180 try 181 { 182 st.nextToken ( ); 183 int estimated_articles = Integer.parseInt ( st.nextToken ( ) ); 184 int first_article = Integer.parseInt ( st.nextToken ( ) ); 185 int last_article = Integer.parseInt ( st.nextToken ( ) ); 186 String new_group_name = st.nextToken ( ); 187 188 if ( newsgroup_Vector != null ) 189 { 190 Enumeration e = newsgroup_Vector.elements ( ); 191 192 while ( e.hasMoreElements ( ) ) 193 { 194 Newsgroup newsgroup = ( Newsgroup ) e.nextElement ( ); 195 196 if ( newsgroup.getGroupName ( ).equals ( new_group_name ) ) 197 { 198 newsgroup_Vector.removeElement ( newsgroup ); 199 200 break; 201 } 202 } 203 } else newsgroup_Vector = new Vector ( ); 204 newsgroup_Vector.insertElementAt ( new Newsgroup ( 205 estimated_articles, first_article, last_article, 206 new_group_name ), 0 ); 207 } catch ( Exception e ) { e.printStackTrace ( ); } 208 } 209 return responseCode; 210 } 211 */ 212 213 /********************************************************************* 214 * Loads the newsgroup_Vector. Returns the responseCode. 215 *********************************************************************/ 216 /* 217 public synchronized String command_LIST ( ) throws IOException { 218 ////////////////////////////////////////////////////////////////////// 219 newsgroup_Vector = new Vector ( ); 220 responseCode = command ( COMMAND_LIST ); 221 if ( responseCode.startsWith ( "2" ) ) { 222 try { load_response_text ( ); } 223 catch ( IOException e ) { e.printStackTrace ( ); } 224 Enumeration e = response_text.elements ( ); 225 while ( e.hasMoreElements ( ) ) { 226 String line = ( String ) e.nextElement ( ); 227 StringTokenizer st = new StringTokenizer ( line ); 228 try { 229 while ( st.hasMoreTokens ( ) ) { 230 String group_name = st.nextToken ( ); 231 int last_article = Integer.parseInt ( st.nextToken ( ) ); 232 int first_article = Integer.parseInt ( st.nextToken ( ) ); 233 boolean posting_ok 234 = st.nextToken ( ).equalsIgnoreCase ( "y" ); 235 newsgroup_Vector.addElement ( new Newsgroup ( 236 group_name, last_article, first_article, posting_ok ) ); 237 } 238 } catch ( Exception ex ) { ex.printStackTrace ( ); } 239 } 240 } 241 return responseCode; 242 } 243 */ 244 245 /********************************************************************* 246 * Sends COMMAND_QUIT and then closes the NNTPSocket. 247 *********************************************************************/ 248 public synchronized String command_QUIT ( ) throws IOException { 249 ////////////////////////////////////////////////////////////////////// 250 responseCode = command ( COMMAND_QUIT ); 251 close ( ); 252 return responseCode; 253 } 254 255 ////////////////////////////////////////////////////////////////////// 256 ////////////////////////////////////////////////////////////////////// 257 258 public Log getLog ( ) { return log; } 259 260 public void setLog ( Log log ) { this.log = log; } 261 262 ////////////////////////////////////////////////////////////////////// 263 ////////////////////////////////////////////////////////////////////// 264 265 private void record ( String entry ) 266 ////////////////////////////////////////////////////////////////////// 267 { 268 Log log = this.log; 269 270 if ( log != null ) 271 { 272 log.record ( entry ); 273 } 274 } 275 276 ////////////////////////////////////////////////////////////////////// 277 ////////////////////////////////////////////////////////////////////// 278 }