[csmaild-cvs] csmaild/src/Imap Connection.cs,1.3,1.4 Imap.csproj,1.4,1.5 Server.cs,1.4,1.5
Brought to you by:
tamc
From: <ta...@us...> - 2003-07-24 04:32:21
|
Update of /cvsroot/csmaild/csmaild/src/Imap In directory sc8-pr-cvs1:/tmp/cvs-serv32149/src/Imap Modified Files: Connection.cs Imap.csproj Server.cs Log Message: Long time, no commit. Upgraded to VS.NET 2003 Lots of code changes, still pre-pre-pre-alpha, so who's keeping track Index: Connection.cs =================================================================== RCS file: /cvsroot/csmaild/csmaild/src/Imap/Connection.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Connection.cs 11 Apr 2003 07:21:41 -0000 1.3 --- Connection.cs 24 Jul 2003 04:32:14 -0000 1.4 *************** *** 2,5 **** --- 2,6 ---- using System.Net.Sockets; using System.Text; + using Imap.Commands; using Imap.NetworkManager; *************** *** 9,18 **** /// The various states an ImapConnection can be in /// </summary> public enum ImapConnectionState : byte { ! NotAuthenticated, /// user is not authenticated, generally right after a connect ! Authenticated, /// user is authenticated, but no mailboxes are selected ! Selected, /// user has selected an active mailbox ! Logout /// not much of a state, but eh } --- 10,19 ---- /// The various states an ImapConnection can be in /// </summary> + [Flags()] public enum ImapConnectionState : byte { ! NotAuthenticated = 1, /// user is not authenticated, generally right after a connect ! Authenticated = 2, /// user is authenticated, but no mailboxes are selected ! Selected = 4 /// user has selected an active mailbox } *************** *** 22,27 **** public class ImapConnection { ! private Connection mConnection; ! private ImapConnectionState mState; public ImapConnectionState State --- 23,33 ---- public class ImapConnection { ! private Connection mConnection; // the underlying network connection ! private ImapConnectionState mState; // the state of this connection ! private ImapServer mServer; // what server we belong to ! ! private string mCurrentTag; // the current tag sent in the most recent command ! private ImapCommand mCurrentCommand; // the current command being processed ! private string mCurrentArguments; // the un-parsed arguments for the currently processing command public ImapConnectionState State *************** *** 45,56 **** } /// <summary> /// Creates a new ImapConnection object, starts in NotAuthenticated state /// </summary> /// <param name="client">The network connection for this</param> ! public ImapConnection(Connection con) { mConnection = con; mState = ImapConnectionState.NotAuthenticated; } } --- 51,186 ---- } + public ImapServer Server + { + get + { + return mServer; + } + } + /// <summary> /// Creates a new ImapConnection object, starts in NotAuthenticated state /// </summary> /// <param name="client">The network connection for this</param> ! public ImapConnection(ImapServer svr, Connection con) { + mServer = svr; mConnection = con; mState = ImapConnectionState.NotAuthenticated; + + mConnection.ReceivedLineEvent += new ReceivedLineDelegate(Connection_ReceivedLine); + mConnection.SentDataEvent += new SentDataDelegate(Connection_SentData); + + ReadCommand(); + } + + public void SendTaggedMessage(string msg) + { + SendTaggedMessage(mCurrentTag, msg); + } + public void SendTaggedMessage(string tag, string msg) + { + SendMessage(tag + " " + msg); + } + + public void SendUntaggedMessage(string msg) + { + SendMessage("* " + msg); + } + + public void SendContinueMessage(string msg) + { + SendMessage("+ " + msg); + } + + private void SendMessage(string msg) + { + mConnection.WriteLine(msg); + } + + public void ReadCommand() + { + mCurrentTag = string.Empty; + mCurrentArguments = string.Empty; + mCurrentCommand = null; + + mConnection.ReadLine(); + } + + private bool ParseAndValidate(string line) + { + // parse and validate tag + int idxTagEnd = line.IndexOf(' '); + if(idxTagEnd == -1) // this would mean that there isn't a space, just call it a missing tag + { + SendUntaggedMessage("BAD"); // missing tag + return false; + } + + mCurrentTag = line.Substring(0, idxTagEnd); + if(!CommandPart.ValidateTagCharacters(mCurrentTag)) // uh oh, bad client, bad client, no supper for you + { + SendTaggedMessage("BAD"); // tag contains invalid characters + return false; + } + + // parse and validate command + string cmd; + + int idxCommandEnd = line.IndexOf(' ', idxTagEnd+1); + if(idxCommandEnd == -1) // nothing after the command + { + cmd = line.Substring(idxTagEnd+1).ToUpper(); // one space past the tag til the end + mCurrentArguments = string.Empty; // no arguments + } + else + { + cmd = line.Substring(idxTagEnd+1, idxCommandEnd-idxTagEnd-1).ToUpper(); // one space past tag til the next space + mCurrentArguments = line.Substring(idxCommandEnd); // args will include the preceding space + } + + mCurrentCommand = (ImapCommand)Server.Commands[cmd]; + if(mCurrentCommand == null) + { + SendTaggedMessage("BAD"); // command not found + return false; + } + + mCurrentCommand.Initialize(mCurrentArguments, this); + + if(!mCurrentCommand.ValidateState()) + { + SendTaggedMessage("BAD state"); // cannot run this command in this state + return false; + } + + return true; + } + + private void Connection_ReceivedLine(Connection cnn, string line) + { + // this shouldn't ever be a problem, but what the heck, clock cycles are cheap ;) + if(cnn != mConnection) + throw new Exception("Fucked up, this is just fucked up!"); + + // this command will parse through the incoming line and make sure it's valid + if(ParseAndValidate(line)) + { + // good, leave the rest of the work up to the actual command handler + mCurrentCommand.Process(); + } + else + { + // move on + ReadCommand(); + } + } + + private void Connection_SentData(Connection con) + { + } + + public void Close() + { } } Index: Imap.csproj =================================================================== RCS file: /cvsroot/csmaild/csmaild/src/Imap/Imap.csproj,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Imap.csproj 11 Apr 2003 07:21:42 -0000 1.4 --- Imap.csproj 24 Jul 2003 04:32:14 -0000 1.5 *************** *** 2,7 **** <CSHARP ProjectType = "Local" ! ProductVersion = "7.0.9466" ! SchemaVersion = "1.0" ProjectGuid = "{B1B51646-3745-489A-B0A8-630013E5E44E}" > --- 2,7 ---- <CSHARP ProjectType = "Local" ! ProductVersion = "7.10.3077" ! SchemaVersion = "2.0" ProjectGuid = "{B1B51646-3745-489A-B0A8-630013E5E44E}" > *************** *** 17,21 **** --- 17,24 ---- DelaySign = "false" OutputType = "Library" + PreBuildEvent = "" + PostBuildEvent = "" RootNamespace = "Imap" + RunPostBuildEvent = "OnBuildSuccess" StartupObject = "" > *************** *** 31,34 **** --- 34,39 ---- FileAlignment = "4096" IncrementalBuild = "true" + NoStdLib = "false" + NoWarn = "" Optimize = "false" OutputPath = "bin\Debug\" *************** *** 49,52 **** --- 54,59 ---- FileAlignment = "4096" IncrementalBuild = "false" + NoStdLib = "false" + NoWarn = "" Optimize = "true" OutputPath = "bin\Release\" *************** *** 72,75 **** --- 79,87 ---- AssemblyName = "System.Xml" HintPath = "..\..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll" + /> + <Reference + Name = "Common" + Project = "{19D49838-BF7A-4432-9C84-F50AE399077B}" + Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" /> </References> Index: Server.cs =================================================================== RCS file: /cvsroot/csmaild/csmaild/src/Imap/Server.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Server.cs 11 Apr 2003 07:21:42 -0000 1.4 --- Server.cs 24 Jul 2003 04:32:14 -0000 1.5 *************** *** 3,107 **** using Imap.NetworkManager; using System.Collections; ! //using System.IO; //using System.Net.Sockets; //using System.Text; namespace Imap { ! public class Server { private NetworkManager.NetworkManager mNetwork; private Hashtable mImapConnections = new Hashtable(); private Hashtable mImapCommands = new Hashtable(); ! public Server() { mNetwork = new NetworkManager.NetworkManager(); mImapConnections = new Hashtable(); #region Register handlers ! mImapCommands.Add("APPEND", new AppendCommand()); ! mImapCommands.Add("AUTHENTICATE", new AuthenticateCommand()); ! mImapCommands.Add("CAPABILITY", new CapabilityCommand()); ! mImapCommands.Add("CHECK", new CheckCommand()); ! mImapCommands.Add("CLOSE", new CloseCommand()); ! mImapCommands.Add("COPY", new CopyCommand()); ! mImapCommands.Add("CREATE", new CreateCommand()); ! mImapCommands.Add("DELETE", new DeleteCommand()); ! mImapCommands.Add("EXAMINE", new ExamineCommand()); ! mImapCommands.Add("EXPUNGE", new ExpungeCommand()); ! mImapCommands.Add("FETCH", new FetchCommand()); ! mImapCommands.Add("LIST", new ListCommand()); ! mImapCommands.Add("LOGIN", new LoginCommand()); ! mImapCommands.Add("LOGOUT", new LogoutCommand()); ! mImapCommands.Add("LSUB", new LsubCommand()); ! mImapCommands.Add("NOOP", new NoopCommand()); ! mImapCommands.Add("RENAME", new RenameCommand()); ! mImapCommands.Add("SEARCH", new SearchCommand()); ! mImapCommands.Add("SELECT", new SelectCommand()); ! mImapCommands.Add("STARTTLS", new StarttlsCommand()); ! mImapCommands.Add("STATUS", new StatusCommand()); ! mImapCommands.Add("STORE", new StoreCommand()); ! mImapCommands.Add("SUBSCRIBE", new SubscribeCommand()); ! mImapCommands.Add("UID", new UidCommand()); ! mImapCommands.Add("UNSUBSCRIBE", new UnsubscribeCommand()); #endregion } ! public void Start() { ! Listener li = mNetwork.StartListener(143); // TODO: global configuration ! li.AcceptedConnection += new AcceptDelegate(NewConnectionHandler); } ! private void SendWelcomeMessage(Connection con) { ! con.WriteLine("* OK domain.tld IMAP4rev1 csmaild dev ready"); ! System.Console.WriteLine(con + " S: * OK domain.tld IMAP4rev1 csmaild.dev ready"); } ! private void NewConnectionHandler(Connection con) { ! mImapConnections.Add(con, new ImapConnection(con)); ! ! con.ConnectionClosedEvent += new ConnectionClosedDelegate(Connection_Closed); ! con.ReceivedLineEvent += new ReceivedLineDelegate(Connection_ReceivedLine); ! con.ReceivedBlockEvent += new ReceivedBlockDelegate(Connection_ReceivedBlock); ! con.SentDataEvent += new SentDataDelegate(Connection_SentData); ! ! SendWelcomeMessage(con); ! ! con.ReadLine(); } ! private void Connection_ReceivedLine(Connection con, string line) { ! System.Console.WriteLine(con + " C: " + line); ! ! line += " "; // to alleviate invalid input parsing ! ! int idxTag = line.IndexOf(' '); ! int idxCommand = line.IndexOf(' ', idxTag+1); ! ! string tag = line.Substring(0, idxTag); ! string cmd = line.Substring(idxTag+1, idxCommand-idxTag-1); ! string args = line.Substring(idxCommand+1); ! ! ImapCommand command = (ImapCommand)mImapCommands[cmd]; ! if(command != null) ! command.Process((ImapConnection)mImapConnections[con], tag); ! else ! ((ImapConnection)mImapConnections[con]).Connection.WriteLine(tag + " BAD"); ! ! con.ReadLine(); } ! private void Connection_ReceivedBlock(Connection con, byte[] block) { ! System.Console.WriteLine(con + " C: " + block); ! } ! private void Connection_SentData(Connection con) ! { } --- 3,97 ---- using Imap.NetworkManager; using System.Collections; ! using System.IO; ! //using System.Net.Sockets; //using System.Text; + using Common.MailstoreProviders; + namespace Imap { ! public class ImapServer { private NetworkManager.NetworkManager mNetwork; private Hashtable mImapConnections = new Hashtable(); private Hashtable mImapCommands = new Hashtable(); + private IMailstoreProvider mMailstoreProvider; ! public ImapServer(IMailstoreProvider provider) { mNetwork = new NetworkManager.NetworkManager(); mImapConnections = new Hashtable(); + mMailstoreProvider = provider; + #region Register handlers ! mImapCommands.Add("APPEND", new AppendCommand(this)); ! mImapCommands.Add("AUTHENTICATE", new AuthenticateCommand(this)); ! mImapCommands.Add("CAPABILITY", new CapabilityCommand(this)); ! mImapCommands.Add("CHECK", new CheckCommand(this)); ! mImapCommands.Add("CLOSE", new CloseCommand(this)); ! mImapCommands.Add("COPY", new CopyCommand(this)); ! mImapCommands.Add("CREATE", new CreateCommand(this)); ! mImapCommands.Add("DELETE", new DeleteCommand(this)); ! mImapCommands.Add("EXAMINE", new ExamineCommand(this)); ! mImapCommands.Add("EXPUNGE", new ExpungeCommand(this)); ! mImapCommands.Add("FETCH", new FetchCommand(this)); ! mImapCommands.Add("LIST", new ListCommand(this)); ! mImapCommands.Add("LOGIN", new LoginCommand(this)); ! mImapCommands.Add("LOGOUT", new LogoutCommand(this)); ! mImapCommands.Add("LSUB", new LsubCommand(this)); ! mImapCommands.Add("NOOP", new NoopCommand(this)); ! mImapCommands.Add("RENAME", new RenameCommand(this)); ! mImapCommands.Add("SEARCH", new SearchCommand(this)); ! mImapCommands.Add("SELECT", new SelectCommand(this)); ! mImapCommands.Add("STARTTLS", new StarttlsCommand(this)); ! mImapCommands.Add("STATUS", new StatusCommand(this)); ! mImapCommands.Add("STORE", new StoreCommand(this)); ! mImapCommands.Add("SUBSCRIBE", new SubscribeCommand(this)); ! mImapCommands.Add("UID", new UidCommand(this)); ! mImapCommands.Add("UNSUBSCRIBE", new UnsubscribeCommand(this)); #endregion } ! public string[] Capabilities { ! get ! { ! return new string[]{"IMAP4rev1", "STARTTLS", "LOGINDISABLED", "AUTH=PLAIN"}; ! } } ! public IMailstoreProvider MailstoreProvider { ! get ! { ! return mMailstoreProvider; ! } } ! public Hashtable Commands { ! get ! { ! return mImapCommands; ! } } ! public void Start() { ! Listener li = mNetwork.StartListener(143); // TODO: global configuration ! li.AcceptedConnection += new AcceptDelegate(NewConnectionHandler); } ! private void NewConnectionHandler(Connection con) { ! con.ConnectionClosedEvent += new ConnectionClosedDelegate(Connection_Closed); ! ImapConnection cnn = new ImapConnection(this, con); ! cnn.SendUntaggedMessage("OK domain.tld IMAP4rev1 csmaild dev ready"); ! ! mImapConnections.Add(con, cnn); ! } *************** *** 109,113 **** { mImapConnections.Remove(con); ! System.Console.WriteLine(con + " Closed"); } --- 99,103 ---- { mImapConnections.Remove(con); ! System.Diagnostics.Trace.WriteLine(con + " Closed"); } |