Core.cs
上传用户:horngjaan
上传日期:2009-12-12
资源大小:2882k
文件大小:12k
- using System;
- using System.IO;
- using System.Net;
- using System.Net.Sockets;
- using System.ComponentModel;
- using System.ComponentModel.Design;
- using System.Collections;
- using System.Text;
- namespace LumiSoft.MailServer
- {
- #region public enum ReadReplyCode
- /// <summary>
- /// Reply reading return codes.
- /// </summary>
- public enum ReadReplyCode
- {
- /// <summary>
- /// Read completed successfully.
- /// </summary>
- Ok = 0,
- /// <summary>
- /// Read timed out.
- /// </summary>
- TimeOut = 1,
- /// <summary>
- /// Maximum allowed lenght exceeded.
- /// </summary>
- LenghtExceeded = 2,
- /// <summary>
- /// UnKnown error, eception raised.
- /// </summary>
- UnKnownError = 3,
- }
- #endregion
- #region enum AuthType
- /// <summary>
- /// Authentication type.
- /// </summary>
- public enum AuthType
- {
- /// <summary>
- ///
- /// </summary>
- Plain = 0,
- /// <summary>
- /// Not implemented.
- /// </summary>
- LOGIN = 2,
- /// <summary>
- ///
- /// </summary>
- APOP = 1,
- }
- #endregion
- /// <summary>
- /// Contains utility functions.
- /// </summary>
- public class Core
- {
- // public Core()
- // {
- // }
- #region function ParseIP_from_EndPoint
- /// <summary>
- ///
- /// </summary>
- /// <param name="endpoint"></param>
- /// <returns></returns>
- public static string ParseIP_from_EndPoint(string endpoint)
- {
- string retVal = endpoint;
- int index = endpoint.IndexOf(":");
- if(index > 1){
- retVal = endpoint.Substring(0,index);
- }
- return retVal;
- }
- #endregion
- #region function ReadReplyFromSocket
- /// <summary>
- /// Reads reply from socket.
- /// </summary>
- /// <param name="socket"></param>
- /// <param name="replyData">Data that has been readen from socket.</param>
- /// <param name="addData">Data that has will be written at the beginning of read data. This param may be null.</param>
- /// <param name="maxLenght">Maximum lenght of data which may read.</param>
- /// <param name="cmdIdleTimeOut">Command idle time out in milliseconds.</param>
- /// <param name="terminator">Terminator string which terminates reading. eg 'rn'.</param>
- /// <param name="removeFromEnd">Removes following string from reply.NOTE: removes only if ReadReplyCode is Ok.</param>
- /// <param name="retIfLenExceeded">If true, returns function if maximum length is exceeded.If false, chuck data.</param>
- /// <returns>Return reply code.</returns>
- public static ReadReplyCode ReadReplyFromSocket(Socket socket,out MemoryStream replyData,byte[] addData,int maxLenght,int cmdIdleTimeOut,string terminator,string removeFromEnd,bool retIfLenExceeded)
- {
- ReadReplyCode replyCode = ReadReplyCode.Ok;
- replyData = null;
- try
- {
- // Create memory stream, where to store data.
- MemoryStream strm = new MemoryStream();
- // Write additional data to the beginning of stream, if any specified.
- if(addData != null){
- strm.Write(addData,0,addData.Length);
- }
- int lastDataTime = Environment.TickCount;
- while(true){
- if(socket.Available > 0){
- // If maximum lenght is exceeded and there is enough data for terminator, clear stream.
- // NOTE: we may not clear stream if there isn't enough data for terminator, beacuse
- // some part of terminator may be in stream.
- if(replyCode == ReadReplyCode.LenghtExceeded && socket.Available >= terminator.Length){
- strm.SetLength(0);
- }
- //--- Read data from socket and write to stream --//
- byte[] buf_Return = new byte[socket.Available];
- int received = socket.Receive(buf_Return);
- strm.Seek(0,SeekOrigin.End);
- strm.Write(buf_Return,0,received);
- //------------------------------------------------//
- //---- Check if maximum length is exceeded ------------------------------//
- if(replyCode != ReadReplyCode.LenghtExceeded && strm.Length > maxLenght){
- replyCode = ReadReplyCode.LenghtExceeded;
- if(retIfLenExceeded){
- break;
- }
- }
- //-----------------------------------------------------------------------//
-
- //----- Check for terminator ---------------------------------------//
- if(strm.Length >= terminator.Length){
- byte[] bufComp = new byte[terminator.Length];
- strm.Position = strm.Length - terminator.Length;
- strm.Read(bufComp,0,bufComp.Length);
- string strCompare = System.Text.Encoding.ASCII.GetString(bufComp);
-
- // check for terminator.
- if(socket.Available == 0 && strCompare.IndexOf(terminator) > -1){
- break;
- }
- }
- //--------------------------------------------------------------------//
-
- // reset last data time
- lastDataTime = Environment.TickCount;
- }
-
- //---- Idle and time out stuff ----------------------------------------//
- if(socket.Available == 0){
- if(Environment.TickCount > lastDataTime + cmdIdleTimeOut){
- replyCode = ReadReplyCode.TimeOut;
- break;
- }
- System.Threading.Thread.Sleep(30);
- }
- //-----------------------------------------------------------//
- }
- // If reply is ok then remove chars if any specified by 'removeFromEnd'.
- // Remove specified char's from end.
- if(replyCode == ReadReplyCode.Ok && removeFromEnd.Length > 0){
- strm.SetLength(strm.Length - removeFromEnd.Length);
- }
-
- replyData = strm;
- }
- catch(Exception x)
- {
- replyCode = ReadReplyCode.UnKnownError;
- }
- return replyCode;
- }
- #endregion
- #region function ReadLineFromSocket
- /// <summary>
- /// Reads line from socket. Line terminator is {CRLF} and maxLenght = 1024.
- /// </summary>
- /// <param name="socket">Referance to socket.</param>
- /// <param name="reply">Data that has been readen from socket.</param>
- /// <param name="cmdTimeOut">Command idle time out in milliseconds.</param>
- /// <returns></returns>
- public static ReadReplyCode ReadLineFromSocket(Socket socket,out string reply,int cmdTimeOut)
- {
- ReadReplyCode replyCode = ReadReplyCode.Ok;
- reply = "";
- try
- {
- MemoryStream strm = null;
- replyCode = ReadReplyFromSocket(socket,out strm,null,1024,cmdTimeOut,"rn","rn",true);
- if(replyCode == ReadReplyCode.Ok){
- byte[] byte_reply = strm.ToArray();
- reply = System.Text.Encoding.ASCII.GetString(byte_reply);
- strm.Close();
- }
- }
- catch(Exception x)
- {
- replyCode = ReadReplyCode.UnKnownError;
- }
- return replyCode;
- }
- #endregion
- #region function ParseEmailFromPath
- /// <summary>
- /// Parses email address from forward-path or reverse-path.
- /// </summary>
- /// <param name="path"></param>
- /// <returns>Returns email address, or empty string if parse failed.</returns>
- public static string ParseEmailFromPath(string path)
- {
- //<path> ::= "<" [ <a-d-l> ":" ] <mailbox> ">"
- string email = "";
- try
- {
- // "Ivx iv" <abc@ls.ee> or <abc@ls.ee>
- if(path.IndexOf('<') != -1 && path.IndexOf('>') != -1){
- int index1 = path.IndexOf('<')+1;
- int index2 = path.IndexOf('>');
- email = path.Substring(index1,index2-index1);
- }
- // abc@ls.ee
- else{
- email = path;
- }
- email = email.Trim();
- }
- catch{
- }
-
- return email;
- }
- #endregion
- #region function GetArgsText
- /// <summary>
- /// Gets argument part of command text.
- /// </summary>
- /// <param name="input">Input srting from where to remove value.</param>
- /// <param name="cmdTxtToRemove">Command text which to remove.</param>
- /// <returns></returns>
- public static string GetArgsText(string input,string cmdTxtToRemove)
- {
- string buff = input.Trim();
- if(buff.Length >= cmdTxtToRemove.Length){
- buff = buff.Substring(cmdTxtToRemove.Length);
- }
- buff = buff.Trim();
- return buff;
- }
- #endregion
- #region fucntion GetParams
- /// <summary>
- /// Parses parameters.
- /// </summary>
- /// <param name="argsText">Arguments text.</param>
- /// <param name="paramNames">Known parameter list.</param>
- /// <returns>Returns array of parameters.</returns>
- public static string[] GetParams(string argsText,string[] paramNames)
- {
- //--- Remove continues spaces ---------//
- // eg, aaa= 5 would be aaa=5
- while(true){
- if(argsText.IndexOf(" ") == -1){
- break;
- }
- argsText = argsText.Replace(" "," ");
- }
- //--------------------------------------//
- string argsTextUpper = argsText.ToUpper();
-
- //--- Try to remove spcaes between parameter name and value----------------------------------//
- // eg. FROM: aaa would be FROM:aaa
- foreach(string paramName in paramNames){
- int startPos = 0;
- // Argument text contains parameter
- while(argsTextUpper.IndexOf(paramName,startPos) > -1){
- int iEndOfParam = argsTextUpper.IndexOf(paramName,startPos) + paramName.Length - 1;
- startPos = iEndOfParam;
- // Check if next char is ' ' and param follows.
- if((argsText.Length > iEndOfParam+1) && argsText.Substring(iEndOfParam+1,1) == " "){
- argsText = argsText.Remove(iEndOfParam+1,1);
- argsTextUpper = argsTextUpper.Remove(iEndOfParam+1,1);
- }
- }
- }
- //--------------------------------------------------------------------------------------------//
-
- return argsText.Split(new char[]{' '});
- }
- #endregion
- #region function GetHostName
- /// <summary>
- ///
- /// </summary>
- /// <param name="IP"></param>
- /// <returns></returns>
- public static string GetHostName(string IP)
- {
- try
- {
- return System.Net.Dns.GetHostByAddress(IP).HostName;
- }
- catch(Exception x)
- {
- return "UnkownHost";
- }
- }
- #endregion
- #region function GetDateTimeNow
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public static string GetDateTimeNow()
- {
- // System.Globalization.DateTimeFormatInfo dFormat = System.Globalization.CultureInfo.CreateSpecificCulture("en-US").DateTimeFormat;
- // return DateTime.Now.ToString(dFormat.RFC1123Pattern,dFormat);
- return DateTime.Now.ToUniversalTime().ToString("r");
- }
- #endregion
- #region function DoPeriodHandling
- /// <summary>
- /// Does period handling.
- /// </summary>
- /// <param name="data"></param>
- /// <param name="add_Remove"></param>
- /// <returns></returns>
- public static MemoryStream DoPeriodHandling(byte[] data,bool add_Remove)
- {
- using(MemoryStream strm = new MemoryStream(data)){
- return DoPeriodHandling(strm,add_Remove);
- }
- }
- /// <summary>
- /// Does period handling.
- /// </summary>
- /// <param name="strm">Input stream.</param>
- /// <param name="add_Remove">If true add periods, else removes periods.</param>
- /// <returns></returns>
- public static MemoryStream DoPeriodHandling(Stream strm,bool add_Remove)
- {
- MemoryStream mhStrm = new MemoryStream();
- strm.Position = 0;
- StreamReader reader = new StreamReader(strm);
- string line = reader.ReadLine();
- // Loop through all lines
- while(line != null){
- if(line.StartsWith(".")){
- /* Add period Rfc 281 4.5.2
- - Before sending a line of mail text, the SMTP client checks the
- first character of the line. If it is a period, one additional
- period is inserted at the beginning of the line.
- */
- if(add_Remove){
- line = "." + line;
- }
- /* Remove period Rfc 281 4.5.2
- If the first character is a period , the first characteris deleted.
- */
- else if(line.Length > 1){
- line = line.Substring(1);
- }
- }
- byte[] data = System.Text.Encoding.ASCII.GetBytes(line + "rn");
- mhStrm.Write(data,0,data.Length);
- // Read next line
- line = reader.ReadLine();
- }
- reader.Close();
- mhStrm.Position = 0;
- return mhStrm;
- }
- #endregion
- #region function IsNumber
- /// <summary>
- /// Checks if specified string is number(long).
- /// </summary>
- /// <param name="str"></param>
- /// <returns></returns>
- public static bool IsNumber(string str)
- {
- try
- {
- Convert.ToInt64(str);
- return true;
- }
- catch{
- return false;
- }
- }
- #endregion
- }
- }