commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Rory Winston" <Rory.Wins...@telewest.co.uk>
Subject RE: [net][patch] jdk 1.4 specific call in VMSFTPEntryParser.java
Date Thu, 07 Aug 2003 17:24:52 GMT
Hi,

I've cleaned up a bit (applied my changes to a fresh checkout) and generated
a diff file. I've taken out the XHDR addition for now, as XOVER seems to be
the preferred mechanism for this kind of thing. The functionality added is:

1. XOVER
2. Authentication via AUTHINFO USER + AUTHINFO PASS
3. LIST ACTIVE

I've also supplied a sample class, very quickly stitched together that shows
the new features in action. Hopefully this may be considered clean enough to
make a 1.1 release. I'd love to hear any feedback on these features. 

PS Does anyone else use the Eclipse feature "Check out as Java Project...."
from the Jakarta CVS repository? Great stuff :)

Cheers
Rory

(Patch file attached and copied/pasted in)

Index: src/java/examples/ExtendedNNTPOps.java
===================================================================
RCS file: src/java/examples/ExtendedNNTPOps.java
diff -N src/java/examples/ExtendedNNTPOps.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/java/examples/ExtendedNNTPOps.java	7 Aug 2003 17:14:30 -0000
@@ -0,0 +1,192 @@
+
+package examples;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+import org.apache.commons.net.io.DotTerminatedMessageReader;
+import org.apache.commons.net.nntp.NNTPClient;
+import org.apache.commons.net.nntp.NewsgroupInfo;
+
+/**
+ * @author root
+ *
+ * To change the template for this generated type comment go to
+ * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
+ */
+public class ExtendedNNTPOps {
+	
+	NNTPClient client;
+	
+	public ExtendedNNTPOps() {
+		client = new NNTPClient();
+		try {
+		client.connect("news.blueyonder.co.uk");
+		
+		// AUTHINFO USER/AUTHINFO PASS
+		boolean success = client.authenticate("foo", "bar");
+		if(success) 
+		{
+			System.out.println("Authentication succeeded");
+		}
+		else 
+		{
+			System.out.println("Authentication failed, error ="
+ client.getReplyString());
+		}
+	
+	    // XOVER
+	    NewsgroupInfo testGroup = new NewsgroupInfo();
+		client.selectNewsgroup("alt.test", testGroup);
+		int lowArticleNumber = testGroup.getFirstArticle();
+		int highArticleNumber = testGroup.getLastArticle();
+	    Article[] articles = getArticleInfo(lowArticleNumber,
highArticleNumber);
+	    
+	    for(int i =0; i < articles.length; ++i)
+	    {
+	    	System.out.println(articles[i].getSubject());	
+	    }
+	    
+	    // LIST ACTIVE 
+	    NewsgroupInfo[] fanGroups = client.listNewsgroups("alt.fan.*");
+	    for(int i = 0; i < fanGroups.length; ++i)
+	    {
+	    	System.out.println(fanGroups[i].getNewsgroup());
+	    }
+	    
+	    
+		}
+		catch(IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	private Article[] getArticleInfo(int lowArticleNumber, int
highArticleNumber) throws IOException 
+	{
+			ArrayList articles = new ArrayList();
+			Reader reader = null;
+			String theMessage;
+			char[] buffer = new char[128];
+
+			reader = (DotTerminatedMessageReader)
client.retrieveArticleInfo(lowArticleNumber, highArticleNumber);
+
+			if (reader != null) {
+				String theInfo = readerToString(reader);
+				StringTokenizer st = new
StringTokenizer(theInfo, "\n");
+
+				// Extract the article information
+				// Mandatory format (from NNTP RFC 2980) is
:
+				//
Subject\tAuthor\tDate\tID\tReference(s)\tByte Count\tLine Count
+				while (st.hasMoreTokens()) {
+					StringTokenizer stt = new
StringTokenizer(st.nextToken(), "\t");
+					Article article = new Article();
+
article.setArticleNumber(Integer.parseInt(stt.nextToken()));
+					article.setSubject(stt.nextToken());
+					article.setFrom(stt.nextToken());
+					article.setDate(stt.nextToken());
+
article.setArticleId(stt.nextToken());
+					article.addHeaderField("References",
stt.nextToken());
+					articles.add(article);
+				}
+			} else {
+				return null;
+			}
+			
+			return (Article[]) articles.toArray(new
Article[articles.size()]);
+		}
+		
+		private String readerToString(Reader reader) 
+		{
+			String temp;
+			StringBuffer sb = null;
+			BufferedReader bufReader = new
BufferedReader(reader);
+			boolean endOfHeader = false;
+			
+			sb = new StringBuffer();
+			try 
+			{
+				temp = bufReader.readLine();
+				while (temp != null) {
+					sb.append(temp);
+					sb.append("\n");
+					temp = bufReader.readLine();
+					}
+				} catch (IOException e) {
+					e.printStackTrace();
+					}
+			
+			return sb.toString();
+	}
+
+	public static void main(String[] args) {
+		ExtendedNNTPOps ops = new ExtendedNNTPOps();
+	}
+	
+}
+
+// simple class that encapsulates some basic info about an NNTP article
+	class Article {
+		
+		private int articleNumber;
+		private String subject;
+		private String date;
+		private String articleId;
+		
+		private String from;
+		private StringBuffer header;
+		
+		public Article() 
+		{
+			header = new StringBuffer();
+		}
+			
+		public void addHeaderField(String name, String val) {
+			header.append(name);
+			header.append(": ");
+			header.append(val);
+			header.append('\n');
+		}
+
+		public String getArticleId() {
+			return articleId;
+		}
+		
+		public int getArticleNumber() {
+			return articleNumber;
+		}
+		
+		public String getDate() {
+			return date;
+		}
+		
+		public String getFrom() {
+			return from;
+		}
+		
+		public String getSubject() {
+			return subject;
+		}
+	
+		public void setArticleId(String string) {
+			articleId = string;
+		}
+		
+		public void setArticleNumber(int i) {
+			articleNumber = i;
+		}
+		
+		public void setDate(String string) {
+			date = string;
+		}
+		
+		public void setFrom(String string) {
+			from = string;
+		}
+				
+		public void setSubject(String string) {
+			subject = string;
+		}
+	}
+
Index: src/java/org/apache/commons/net/nntp/NNTP.java
===================================================================
RCS file:
/home/cvspublic/jakarta-commons/net/src/java/org/apache/commons/net/nntp/NNT
P.java,v
retrieving revision 1.5
diff -u -r1.5 NNTP.java
--- src/java/org/apache/commons/net/nntp/NNTP.java	19 Apr 2003 20:49:13
-0000	1.5
+++ src/java/org/apache/commons/net/nntp/NNTP.java	7 Aug 2003 17:14:31
-0000
@@ -926,5 +926,81 @@
     {
         return sendCommand(NNTPCommand.QUIT);
     }
+    
+	/***
+		 * A convenience method to send the AUTHINFO USER command to
the server, 
+		 *  receive the reply, and return the reply code. (See RFC
2980)
+		 * <p>
+		 * @param username A valid username.
+		 * @return The reply code received from the server. The
server should return a
+		 * 	381 or 281 for this command. 
+		 * @exception NNTPConnectionClosedException
+		 *      If the NNTP server prematurely closes the connection
as a result
+		 *      of the client being idle or some other reason
causing the server
+		 *      to send NNTP reply code 400.  This exception may be
caught either
+		 *      as an IOException or independently as itself.
+		 * @exception IOException  If an I/O error occurs while
either sending the
+		 *      command or receiving the server reply.
+		 ***/
+		public int authinfoUser(String username) throws IOException
{
+			String userParameter = "USER " + username;
+			return sendCommand(NNTPCommand.AUTHINFO,
userParameter);
+		}
 
+	/***
+			 * 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 
+			 * immediately follow the AUTHINFO USER command (See
RFC 2980)
+			 * <p>
+			 * @param password a valid password.
+			 * @return The reply code received from the server.
The server should return a
+			 * 	281 or 502 for this command. 
+			 * @exception NNTPConnectionClosedException
+			 *      If the NNTP server prematurely closes the
connection as a result
+			 *      of the client being idle or some other
reason causing the server
+			 *      to send NNTP reply code 400.  This exception
may be caught either
+			 *      as an IOException or independently as
itself.
+			 * @exception IOException  If an I/O error occurs
while either sending the
+			 *      command or receiving the server reply.
+			 ***/
+		public int authinfoPass(String password) throws IOException
{
+			String passParameter = "PASS " + password;
+			return sendCommand(NNTPCommand.AUTHINFO,
passParameter);
+		}
+		
+	/***
+		 * A convenience method to send the NNTP XOVER command to
the server,
+		 * receive the reply, and return the reply code.
+		 * <p>
+		 * @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 the
+		 *  form "XXXX-YYYY", where XXXX and YYYY are valid article
numbers in the current group.
+		 *  It also may be of the form "XXX-", meaning "return XXX
and all following articles"
+		 *  In this revision, the last format is not possible (yet) 
+		 * @return The reply code received from the server.
+		 * @exception NNTPConnectionClosedException
+		 *      If the NNTP server prematurely closes the connection
as a result
+		 *      of the client being idle or some other reason
causing the server
+		 *      to send NNTP reply code 400.  This exception may be
caught either
+		 *      as an IOException or independently as itself.
+		 * @exception IOException  If an I/O error occurs while
either sending the
+		 *      command or receiving the server reply.
+		 ***/
+		public int xover(String selectedArticles) throws IOException
{
+			return sendCommand(NNTPCommand.XOVER,
selectedArticles);
+		}
+		
+		/**
+		 *  A convenience wrapper for the extended LIST command that
takes an argument, 
+		 * allowing us to selectively list multiple groups.
+		 * <p> 
+		 * @param wildmat A wildmat (pseudo-regex) pattern. See RFC
2980 for details.
+		 * @return the reply code received from the server.
+		 * @throws IOException
+		 */
+		public int listActive(String wildmat) throws IOException {
+			StringBuffer command = new StringBuffer("ACTIVE ");
+			command.append(wildmat);
+			return sendCommand(NNTPCommand.LIST,
command.toString());
+		}	
 }
Index: src/java/org/apache/commons/net/nntp/NNTPClient.java
===================================================================
RCS file:
/home/cvspublic/jakarta-commons/net/src/java/org/apache/commons/net/nntp/NNT
PClient.java,v
retrieving revision 1.4
diff -u -r1.4 NNTPClient.java
--- src/java/org/apache/commons/net/nntp/NNTPClient.java	19 Apr 2003
20:49:13 -0000	1.4
+++ src/java/org/apache/commons/net/nntp/NNTPClient.java	7 Aug 2003
17:14:31 -0000
@@ -959,6 +959,22 @@
 
         return __readNewsgroupListing();
     }
+    
+    /**
+     * An overloaded listNewsgroups() command that allows us to specify
with a pattern
+     * what groups we want to list. Wraps the LIST ACTIVE command.
+     * <p> 
+     * @param wildmat a pseudo-regex pattern (cf. RFC 2980)
+     * @return
+     * @throws IOException
+     */
+	public NewsgroupInfo[] listNewsgroups(String wildmat) throws
IOException 
+	{
+		if(!NNTPReply.isPositiveCompletion(listActive(wildmat)))
+			return null;
+			return __readNewsgroupListing();
+	}
+
 
 
     /***
@@ -1151,5 +1167,74 @@
     {
         return NNTPReply.isPositiveCompletion(quit());
     }
-
+    
+    /**
+     * Log into a news server by sending the AUTHINFO USER/AUTHINFO PASS
command
+     * sequence. This is usually sent in response to a 480 reply code from
the NNTP server.
+     * <p>
+     * @param username a valid username
+     * @param password the corresponding password
+     * @return True for successful login, false for a failure
+     * @throws IOException
+     */
+    
+	public boolean authenticate(String username, String password)
throws IOException 
+	{
+		int replyCode = authinfoUser(username);
+		
+		if (replyCode == NNTPReply.MORE_AUTH_INFO_REQUIRED) 
+		{
+			replyCode = authinfoPass(password);
+			
+			if (replyCode == NNTPReply.AUTHENTICATION_ACCEPTED) 
+			{
+				_isAllowedToPost = true;
+				return true;
+				}
+			}
+			return false;
+		}
+			
+			/***
+			 * Private implementation of XOVER functionality.  
+			 * 
+			 * See <a
href="org.apache.commons.nntp.NNTP.html#xover">
+			 * for legal agument formats. Alternatively, read
RFC 2980 :-) 
+			 * <p>
+			 * @param articleRange
+			 * @return Returns a DotTerminatedMessageReader if
successful, null otherwise
+			 * @exception IOException
+			 */
+			private Reader __retrieveArticleInfo(String
articleRange) throws IOException 
+			{
+					if
(!NNTPReply.isPositiveCompletion(xover(articleRange)))
+							return null;
+
+					return new
DotTerminatedMessageReader(_reader_);
+			}
+			
+			/**
+			 * Return article headers for a specified post.
+			 * <p>
+			 * @param articleNumber the article to retrieve
headers for
+			 * @return a DotTerminatedReader if successful, null
otherwise
+			 * @throws IOException
+			 */
+			public Reader retrieveArticleInfo(int articleNumber)
throws IOException 
+			{
+					return __retrieveArticleInfo(new
Integer(articleNumber).toString());
+			}
+			
+			/**
+			 *  Return article headers for all articles between
lowArticleNumber and highArticleNumber, inclusively.
+			 * <p>
+			 * @param lowArticleNumber 
+			 * @param highArticleNumber 
+			 * @return a DotTerminatedReader if successful, null
otherwise
+			 * @throws IOException
+			 */
+			public Reader retrieveArticleInfo(int
lowArticleNumber, int highArticleNumber) throws IOException 
+			{
+					return __retrieveArticleInfo(new
String(lowArticleNumber + "-" + highArticleNumber));
+			}
 }
Index: src/java/org/apache/commons/net/nntp/NNTPCommand.java
===================================================================
RCS file:
/home/cvspublic/jakarta-commons/net/src/java/org/apache/commons/net/nntp/NNT
PCommand.java,v
retrieving revision 1.3
diff -u -r1.3 NNTPCommand.java
--- src/java/org/apache/commons/net/nntp/NNTPCommand.java	26 Jan 2003
00:21:44 -0000	1.3
+++ src/java/org/apache/commons/net/nntp/NNTPCommand.java	7 Aug 2003
17:14:31 -0000
@@ -80,7 +80,8 @@
     public static final int QUIT = 12;
     public static final int SLAVE = 13;
     public static final int STAT = 14;
-
+    public static final int AUTHINFO = 15;
+    public static final int XOVER = 16;
 
     // Cannot be instantiated
     private NNTPCommand()
@@ -88,7 +89,8 @@
 
     static final String[] _commands = {
                                           "ARTICLE", "BODY", "GROUP",
"HEAD", "HELP", "IHAVE", "LAST", "LIST",
-                                          "NEWGROUPS", "NEWNEWS", "NEXT",
"POST", "QUIT", "SLAVE", "STAT"
+                                          "NEWGROUPS", "NEWNEWS", "NEXT",
"POST", "QUIT", "SLAVE", "STAT",
+                                          "AUTHINFO", "XOVER"
                                       };
 
 
Index: src/java/org/apache/commons/net/nntp/NNTPReply.java
===================================================================
RCS file:
/home/cvspublic/jakarta-commons/net/src/java/org/apache/commons/net/nntp/NNT
PReply.java,v
retrieving revision 1.3
diff -u -r1.3 NNTPReply.java
--- src/java/org/apache/commons/net/nntp/NNTPReply.java	26 Jan 2003 00:21:44
-0000	1.3
+++ src/java/org/apache/commons/net/nntp/NNTPReply.java	7 Aug 2003 17:14:31
-0000
@@ -85,9 +85,12 @@
     public static final int CODE_231 = 231;
     public static final int CODE_235 = 235;
     public static final int CODE_240 = 240;
+    public static final int CODE_281 = 281;
     public static final int CODE_335 = 335;
     public static final int CODE_340 = 340;
+    public static final int CODE_381 = 381;
     public static final int CODE_400 = 400;
+    public static final int CODE_408 = 408;
     public static final int CODE_411 = 411;
     public static final int CODE_412 = 412;
     public static final int CODE_420 = 420;
@@ -100,6 +103,7 @@
     public static final int CODE_437 = 437;
     public static final int CODE_440 = 440;
     public static final int CODE_441 = 441;
+    public static final int CODE_482 = 482;
     public static final int CODE_500 = 500;
     public static final int CODE_501 = 501;
     public static final int CODE_502 = 502;
@@ -120,10 +124,13 @@
     public static final int NEW_NEWSGROUP_LIST_FOLLOWS = CODE_231;
     public static final int ARTICLE_TRANSFERRED_OK = CODE_235;
     public static final int ARTICLE_POSTED_OK = CODE_240;
+    public static final int AUTHENTICATION_ACCEPTED = CODE_281;
     public static final int SEND_ARTICLE_TO_TRANSFER = CODE_335;
     public static final int SEND_ARTICLE_TO_POST = CODE_340;
+    public static final int MORE_AUTH_INFO_REQUIRED = CODE_381;
     public static final int SERVICE_DISCONTINUED = CODE_400;
     public static final int NO_SUCH_NEWSGROUP = CODE_411;
+    public static final int AUTHENTICATION_REQUIRED = CODE_408;
     public static final int NO_NEWSGROUP_SELECTED = CODE_412;
     public static final int NO_CURRENT_ARTICLE_SELECTED = CODE_420;
     public static final int NO_NEXT_ARTICLE = CODE_421;
@@ -135,6 +142,7 @@
     public static final int ARTICLE_REJECTED = CODE_437;
     public static final int POSTING_NOT_ALLOWED = CODE_440;
     public static final int POSTING_FAILED = CODE_441;
+    public static final int AUTHENTICATION_REJECTED = CODE_482;
     public static final int COMMAND_NOT_RECOGNIZED = CODE_500;
     public static final int COMMAND_SYNTAX_ERROR = CODE_501;
     public static final int PERMISSION_DENIED = CODE_502;






> -----Original Message-----
> From: Daniel F. Savarese [mailto:dfs@savarese.org]
> Sent: 06 August 2003 23:47
> To: Jakarta Commons Developers List
> Subject: Re: [net][patch] jdk 1.4 specific call in
> VMSFTPEntryParser.java
> 
> 
> 
> In message <85n0eno0nx.fsf@brekke.org>, Jeffrey D. Brekke writes:
> >I saw this and meant to ask about it.  Where can I find more info on
> >this?  I used emacs for quite a while and still do, but the
> >refactoring tools in eclipse are too attractive ;)  I still 
> like to use
> >emacs for quick editing and want to know more about these settings.
> 
> info emacs
> 
> I had noticed my default tab indentation settings were messing up the
> formatting in the files, but I'd forgotten the specifics of embedding
> the fromatting conventions in the file, so "info emacs" refreshed my
> memory.  It would probably be more appropriate for me to figure out
> in my java-mode-hook that I'm editing a jakarta-commons/net file and
> change my settings appropriately, but it was easier to add it to the
> file.
> 
> >Minimally clean up and post to the list for sure.  I'm not 
> against two
> >quick releases if there in enough to release.  So if things get
> >delayed in merging your changes, we can just follow up with a quick
> >1.2 release or something if it even comes to that.  Your additions
> >sound pretty valuable.  I know there has been some inqueries about
> >enhanced support for nntp.
> 
> +1
> 
> Users will sure appreciate those NNTP additions.
> 
> daniel
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 
> 


------------------------------------------------------------------------------
Live Life in Broadband
www.telewest.co.uk


The information transmitted is intended only for the person or entity to which
it is addressed and may contain confidential and/or privileged material.
Statements and opinions expressed in this e-mail may not represent those of
the company. Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by persons or entities
other than the intended recipient is prohibited. If you received this in
error, please contact the sender immediately and delete the material from any
computer.

==============================================================================

Mime
  • Unnamed multipart/mixed (inline, None, 0 bytes)
View raw message