dotgnu-libs-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-libs-commits] CVS: dotgnu-base/DotGNU/Net/Nntp Nntp.cs,NONE,1.1


From: Peter Minten <address@hidden>
Subject: [Dotgnu-libs-commits] CVS: dotgnu-base/DotGNU/Net/Nntp Nntp.cs,NONE,1.1
Date: Sat, 07 Sep 2002 06:42:40 -0400

Update of /cvsroot/dotgnu-libs/dotgnu-base/DotGNU/Net/Nntp
In directory subversions:/tmp/cvs-serv27271/DotGNU/Net/Nntp

Added Files:
        Nntp.cs 
Log Message:
Added class by Haran Shivanan


--- NEW FILE ---
/*
 * Nntp.cs - A class that encapsulates the NNTP protocol for DotGNU-Base
 *
 * Copyright (C) 2002 Haran Shivanan 
 *
 * Contributed by Haran Shivanan <address@hidden>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


/*
The NNTP implementation is based on rfc977
*/

namespace DotGNU.Net.Nntp
{

using System.Net.Sockets;
using System;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Collections;

class Nntp
{
        /*
        Check if the 3 digit response code returned from the server
        signifies that a long response is to follow.
        If not, an error has probably occured
        */
        Socket socket;
        static char[] SplitArray={' '};
        private static bool IsLongResponse(String code)
        {
                String[] 
LongResponses={"100","215","220","221","222","224","230","231","282"};
                foreach(String c in LongResponses)
                        if (c==code)return true;
                return false;
        }
        
        /*
        Parse out the response code from the string.
        Example:
        xxx Response text returned by server

        */
        private static String GetResponseCode(String s)
        {
                int pos=s.IndexOf(" ");
                if (pos<=0)return "";
                return s.Substring(0,pos);
        }

        /*Receive all the data that the server has to give us.
        
          TODO: This function needs to be changed.
          It should probably read data a line at a time (since
          NNTP servers only send single line responses anyway)
          If the server sends exactly 1024 bytes of data,the 
          loop will continue and the function will wait until 
          more data comes, though none may be sent.
        */
        private String ReceiveData()
        {
                String buffer="";
                byte[] bbuf= new byte[1024];
                char[] cbuf= new char[1024];
                int charsread=0,total=0;
                String tmpstr;
                ASCIIEncoding encoding=new ASCIIEncoding();
                do
                {
                        int 
br=socket.Receive(bbuf,0,bbuf.Length,SocketFlags.None);
                        charsread=encoding.GetChars(bbuf,0,br,cbuf,0);
                        tmpstr=new String(cbuf);
                        tmpstr=tmpstr.Substring(0,charsread);
                        buffer=buffer+tmpstr;
                        total+=br;
                        if (br<1024)break;
                }while(true);
                return buffer;
        }

        private byte[] GetBytes(String msg)
        {
                byte[] b=new byte[msg.Length];
                for(int i=0;i<msg.Length;i++)
                {
                        b[i]=(byte)msg[i];
                }
                return b;
        }
        private void SendData(String buffer)
        {
                socket.Send(GetBytes(buffer),buffer.Length,SocketFlags.None);
        }

        /*
        Read from the server until we see \n.\n
        This signifies the end of a long response
        */
        private String GetLongResponse()
        {
                String buffer="";
                do
                {
                        buffer=buffer+ReceiveData();
                }while (!(buffer[buffer.Length-3]=='.' &&
                         buffer[buffer.Length-4]=='\n')
                           );
                return buffer.Substring(0,buffer.Length-3);
        }
        public String IssueCommand(String command)
        {
                SendData(command+"\n");
                return ReceiveData();
        }
        public String IssueCommandLong(String command)
        {
                SendData(command+"\n");
                String result=ReceiveData();
                String code=GetResponseCode(result);
                if (!IsLongResponse(code))
                        throw new Exception("Unable to get text");
                return GetLongResponse();
        }
        
        /*Go to a specific newsgroup
          Throw an exception if the group doesnt exist.
          
          Return an array of 3 integers.
          1:Estimated number of articles in the group
          2:First article number in the grouop
          3:Last Article number in the group
        */
        public int[] Group(String group)
        {
                String result=IssueCommand("GROUP "+group);             
                if (GetResponseCode(result)!="211")
                        throw new Exception("Group Error");
                int []int_responses={-1,-1,-1};
                String[] str_responses=result.Split(SplitArray,5);
                if (str_responses.Length>=5)
                {
                        int_responses[0]=int.Parse(str_responses[1]);
                        int_responses[1]=int.Parse(str_responses[2]);
                        int_responses[2]=int.Parse(str_responses[3]);
                }
                return int_responses;
        }
    
        
        public String List()
        {
                String result=IssueCommand("LIST");
                String code=GetResponseCode(result);
                if (!IsLongResponse(code))
                        throw new Exception("Unable to get group list");
                return GetLongResponse();
        }
        
        
        
        /*The Article(),Body(),Head() and Stat() functions take
        one string parameter which could be either just an
        an article number or the article's      message id enclosed 
        by angular braces: <address@hidden>
        Note that msg ids are unique for a given articles while
        article numbers are specific to a given news server.
        */
        
        //Gets the header,a blank line, then the article body
        public String Article(String article)
        {
                String result=IssueCommand("ARTICLE " +article);
                String code=GetResponseCode(result);
                if (!IsLongResponse(code))
                        throw new Exception("Unable to get article");
                return GetLongResponse();
        }
        public String Article(int article)
        {
                return Article(article.ToString());
        }

        //Gets just the body of the article
        public String Body(String article)
        {
                String result=IssueCommand("BODY " +article);
                String code=GetResponseCode(result);
                if (!IsLongResponse(code))
                        throw new Exception("Unable to get article body");
                return GetLongResponse();
        }
        public String Body(int article)
        {
                return Body(article.ToString());
        }
        
        //Gets just the header of the article
        public String Head(String article)
        {
                String result=IssueCommand("HEAD " +article);
                String code=GetResponseCode(result);
                if (!IsLongResponse(code))
                        throw new Exception("Unable to get article header");
                return GetLongResponse();
        }       
        public String Head(int article)
        {
                return Head(article.ToString());
        }
        
        //This function returns the Msg-ID of the article for which
        //Stat was called.
        //This function is as far as I can see, useless except maybe
        //to determine if an article exists or not.
        //But if you wanted to do that, you could as well call
        //Article() or Head() and catch the exception...
        public String Stat(String article)
        {
                String result=IssueCommand("STAT "+article);
                String[] str_responses=result.Split(SplitArray,4);
                if (str_responses.Length<4)
                        throw new Exception("Invalid STAT response");
                if (str_responses[0]!="223")
                        throw new Exception("Unable to find article for stat");
                return str_responses[2];
                
        }
        public String Stat(int article)
        {
                return Stat(article.ToString());
        }
        /*Register yourself with the server.
          An exception is thrown if anything goes wrong
        */
        private void Authinfo(String user,String password)
        {
                String result=IssueCommand("authinfo user "+user);
                String code=GetResponseCode(result);
                if (code=="381")
                {
                        if (password=="")
                                throw new Exception("Password Required");
                        result=IssueCommand("authinfo pass "+password);
                        code=GetResponseCode(result);
                        if (code!="281")
                                throw new Exception("Invalid Password");
                }
        }
        
        
        /*Connect through an HTTP proxy that supports the CONNECT command*/
        private void TunnelThroughProxy(String proxyserver,int proxyport,
                                                                        String 
newsserver,int newsport)
        {
                IPAddress proxy_ip=IPAddress.Parse(proxyserver);
                socket.Connect(new IPEndPoint(proxy_ip,proxyport));
                SendData("CONNECT "+newsserver+":"+newsport+" HTTP/1.0\n\n");
                ReceiveData();//Get the Connection message
                ReceiveData();//Get the welcome message
        }
        
        public String NewGroups(DateTime dt)
        {
                //TODO:
                return "";
        }
        
        public String NewNews(String group,DateTime dt)
        {
                //TODO:
                return "";
        }
        
        /*Constructors*/
        public Nntp(String server,int port,String user,String password,
                                String proxyserver,int proxyport)
        {
                socket = new 
Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
                if (proxyserver!="")
                        TunnelThroughProxy(proxyserver,proxyport,server,port);
                if (user!="")
                        Authinfo(user,password);
        }
        public Nntp(String server,int port)
        {
                IPAddress ip = IPAddress.Parse(server);
                socket = new 
Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
                socket.Connect(new IPEndPoint(ip,port));
                ReceiveData();//Get the welcome message
        }

        
        public static void Main(String []argv)
        {
                NNTP nntp= new NNTP("news.cis.dfn.de",119,
                "shivanan", //user name
                "xxxxxxxx", //and password
                "144.16.245.184",//my proxy server
                3128);           //and proxy port
                
                int[] i=nntp.Group("comp.compilers");
                Console.Write(i[0]+":"+i[1]+":"+i[2]+"\n");
                int last=i[2]; //Last article number in the group

                for(int j=5;j>0;j--)
                        try
                        {
                                Console.Write(nntp.Article(last-j));
                                Console.Write("\n<----End of Article--->\n");
                        }
                        catch (Exception e)
                        {
                                Console.Write("Unable to get article 
"+(last-j)+"\n");
                        }
                
        }

}//class Nntp
}//namespace DotGNU.Net.Nntp




reply via email to

[Prev in Thread] Current Thread [Next in Thread]