imap init
This commit is contained in:
parent
77efe9973d
commit
ec84451b4d
@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
using MailServer.Misc;
|
||||||
|
|
||||||
namespace MailServer.IMAP.Server
|
namespace MailServer.IMAP.Server
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
346
MailServer/IMAP/Server/FetchHelper/FetchHelper.cs
Normal file
346
MailServer/IMAP/Server/FetchHelper/FetchHelper.cs
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using MailServer.Misc.MIME;
|
||||||
|
using MailServer.Misc.Mail;
|
||||||
|
|
||||||
|
namespace MailServer.IMAP.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// FETCH command helper methods.
|
||||||
|
/// </summary>
|
||||||
|
internal class FetchHelper
|
||||||
|
{
|
||||||
|
#region method ParseHeaderFields
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns requested header fields lines.
|
||||||
|
/// Note: Header terminator blank line is included.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fieldsStr">Header fields to get.</param>
|
||||||
|
/// <param name="entity">Entity which header field lines to get.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static byte[] ParseHeaderFields(string fieldsStr, MIME_Entity entity)
|
||||||
|
{
|
||||||
|
return ParseHeaderFields(fieldsStr, System.Text.Encoding.Default.GetBytes(entity.Header.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns requested header fields lines.
|
||||||
|
/// Note: Header terminator blank line is included.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fieldsStr">Header fields to get.</param>
|
||||||
|
/// <param name="data">Message data.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static byte[] ParseHeaderFields(string fieldsStr, byte[] data)
|
||||||
|
{
|
||||||
|
fieldsStr = fieldsStr.Trim();
|
||||||
|
if (fieldsStr.StartsWith("("))
|
||||||
|
{
|
||||||
|
fieldsStr = fieldsStr.Substring(1, fieldsStr.Length - 1);
|
||||||
|
}
|
||||||
|
if (fieldsStr.EndsWith(")"))
|
||||||
|
{
|
||||||
|
fieldsStr = fieldsStr.Substring(0, fieldsStr.Length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
string retVal = "";
|
||||||
|
|
||||||
|
string[] fields = fieldsStr.Split(' ');
|
||||||
|
using (MemoryStream mStrm = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
TextReader r = new StreamReader(mStrm);
|
||||||
|
string line = r.ReadLine();
|
||||||
|
|
||||||
|
bool fieldFound = false;
|
||||||
|
// Loop all header lines
|
||||||
|
while (line != null)
|
||||||
|
{
|
||||||
|
// End of header
|
||||||
|
if (line.Length == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field continues
|
||||||
|
if (fieldFound && line.StartsWith("\t"))
|
||||||
|
{
|
||||||
|
retVal += line + "\r\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fieldFound = false;
|
||||||
|
|
||||||
|
// Check if wanted field
|
||||||
|
foreach (string field in fields)
|
||||||
|
{
|
||||||
|
if (line.Trim().ToLower().StartsWith(field.Trim().ToLower()))
|
||||||
|
{
|
||||||
|
retVal += line + "\r\n";
|
||||||
|
fieldFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line = r.ReadLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add header terminating blank line
|
||||||
|
retVal += "\r\n";
|
||||||
|
|
||||||
|
return System.Text.Encoding.ASCII.GetBytes(retVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region method ParseHeaderFieldsNot
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns header fields lines except requested.
|
||||||
|
/// Note: Header terminator blank line is included.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fieldsStr">Header fields to skip.</param>
|
||||||
|
/// <param name="entity">Entity which header field lines to get.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static byte[] ParseHeaderFieldsNot(string fieldsStr, MIME_Entity entity)
|
||||||
|
{
|
||||||
|
return ParseHeaderFieldsNot(fieldsStr, System.Text.Encoding.Default.GetBytes(entity.Header.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns header fields lines except requested.
|
||||||
|
/// Note: Header terminator blank line is included.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fieldsStr">Header fields to skip.</param>
|
||||||
|
/// <param name="data">Message data.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static byte[] ParseHeaderFieldsNot(string fieldsStr, byte[] data)
|
||||||
|
{
|
||||||
|
fieldsStr = fieldsStr.Trim();
|
||||||
|
if (fieldsStr.StartsWith("("))
|
||||||
|
{
|
||||||
|
fieldsStr = fieldsStr.Substring(1, fieldsStr.Length - 1);
|
||||||
|
}
|
||||||
|
if (fieldsStr.EndsWith(")"))
|
||||||
|
{
|
||||||
|
fieldsStr = fieldsStr.Substring(0, fieldsStr.Length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
string retVal = "";
|
||||||
|
|
||||||
|
string[] fields = fieldsStr.Split(' ');
|
||||||
|
using (MemoryStream mStrm = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
TextReader r = new StreamReader(mStrm);
|
||||||
|
string line = r.ReadLine();
|
||||||
|
|
||||||
|
bool fieldFound = false;
|
||||||
|
// Loop all header lines
|
||||||
|
while (line != null)
|
||||||
|
{
|
||||||
|
// End of header
|
||||||
|
if (line.Length == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filed continues
|
||||||
|
if (fieldFound && line.StartsWith("\t"))
|
||||||
|
{
|
||||||
|
retVal += line + "\r\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fieldFound = false;
|
||||||
|
|
||||||
|
// Check if wanted field
|
||||||
|
foreach (string field in fields)
|
||||||
|
{
|
||||||
|
if (line.Trim().ToLower().StartsWith(field.Trim().ToLower()))
|
||||||
|
{
|
||||||
|
fieldFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fieldFound)
|
||||||
|
{
|
||||||
|
retVal += line + "\r\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
line = r.ReadLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return System.Text.Encoding.ASCII.GetBytes(retVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region static method GetMimeEntity
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets specified mime entity. Returns null if specified mime entity doesn't exist.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">Mail message.</param>
|
||||||
|
/// <param name="mimeEntitySpecifier">Mime entity specifier. Nested mime entities are pointed by '.'.
|
||||||
|
/// For example: 1,1.1,2.1, ... .</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static MIME_Entity GetMimeEntity(Mail_Message message, string mimeEntitySpecifier)
|
||||||
|
{
|
||||||
|
// TODO: nested rfc 822 message
|
||||||
|
|
||||||
|
// For single part message there is only one entity with value 1.
|
||||||
|
// Example:
|
||||||
|
// header
|
||||||
|
// entity -> 1
|
||||||
|
|
||||||
|
// For multipart message, entity counting starts from MainEntity.ChildEntities
|
||||||
|
// Example:
|
||||||
|
// header
|
||||||
|
// multipart/mixed
|
||||||
|
// text/plain -> 1
|
||||||
|
// application/pdf -> 2
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// Single part
|
||||||
|
if (message.ContentType == null || message.ContentType.Type.ToLower() != "multipart")
|
||||||
|
{
|
||||||
|
if (Convert.ToInt32(mimeEntitySpecifier) == 1)
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// multipart
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
MIME_Entity currentEntity = message;
|
||||||
|
|
||||||
|
string[] parts = mimeEntitySpecifier.Split('.');
|
||||||
|
for(int i=0;i<parts.Length;i++){
|
||||||
|
int partSpecifier = Convert.ToInt32(parts[i]) - 1; // Enitites are zero base, mimeEntitySpecifier is 1 based.
|
||||||
|
|
||||||
|
currentEntity
|
||||||
|
|
||||||
|
// Last mime part.
|
||||||
|
if(i == (parts.Length - 1)){
|
||||||
|
}
|
||||||
|
// Not a last mime part.
|
||||||
|
else{
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
MIME_Entity entity = message;
|
||||||
|
string[] parts = mimeEntitySpecifier.Split('.');
|
||||||
|
foreach (string part in parts)
|
||||||
|
{
|
||||||
|
int mEntryNo = Convert.ToInt32(part) - 1; // Enitites are zero base, mimeEntitySpecifier is 1 based.
|
||||||
|
if (entity.Body is MIME_b_Multipart)
|
||||||
|
{
|
||||||
|
MIME_b_Multipart multipart = (MIME_b_Multipart)entity.Body;
|
||||||
|
if (mEntryNo > -1 && mEntryNo < multipart.BodyParts.Count)
|
||||||
|
{
|
||||||
|
entity = multipart.BodyParts[mEntryNo];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region static method GetMimeEntityHeader
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets specified mime entity header.
|
||||||
|
/// Note: Header terminator blank line is included.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">Mime entity.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static byte[] GetMimeEntityHeader(MIME_Entity entity)
|
||||||
|
{
|
||||||
|
return System.Text.Encoding.ASCII.GetBytes(entity.Header.ToString() + "\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets requested mime entity header. Returns null if specified mime entity doesn't exist.
|
||||||
|
/// Note: Header terminator blank line is included.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">Mail message.</param>
|
||||||
|
/// <param name="mimeEntitySpecifier">Mime entity specifier. Nested mime entities are pointed by '.'.
|
||||||
|
/// For example: 1,1.1,2.1, ... .</param>
|
||||||
|
/// <returns>Returns requested mime entity data or NULL if requested entry doesn't exist.</returns>
|
||||||
|
public static byte[] GetMimeEntityHeader(Mail_Message message, string mimeEntitySpecifier)
|
||||||
|
{
|
||||||
|
MIME_Entity mEntry = GetMimeEntity(message, mimeEntitySpecifier);
|
||||||
|
if (mEntry != null)
|
||||||
|
{
|
||||||
|
return GetMimeEntityHeader(mEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region static method GetMimeEntityData
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets requested mime entity data. Returns null if specified mime entity doesn't exist.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">Mail message.</param>
|
||||||
|
/// <param name="mimeEntitySpecifier">Mime entity specifier. Nested mime entities are pointed by '.'.
|
||||||
|
/// For example: 1,1.1,2.1, ... .</param>
|
||||||
|
/// <returns>Returns requested mime entity data or NULL if requested entry doesn't exist.</returns>
|
||||||
|
public static byte[] GetMimeEntityData(Mail_Message message, string mimeEntitySpecifier)
|
||||||
|
{
|
||||||
|
MIME_Entity entity = GetMimeEntity(message, mimeEntitySpecifier);
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
if (entity.Body is MIME_b_SinglepartBase)
|
||||||
|
{
|
||||||
|
return ((MIME_b_SinglepartBase)entity.Body).EncodedData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region static method Escape
|
||||||
|
|
||||||
|
private static string Escape(string text)
|
||||||
|
{
|
||||||
|
text = text.Replace("\\", "\\\\");
|
||||||
|
text = text.Replace("\"", "\\\"");
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
38
MailServer/IMAP/Server/IMAP_MessageItems_enum.cs
Normal file
38
MailServer/IMAP/Server/IMAP_MessageItems_enum.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MailServer.IMAP.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies message itmes.
|
||||||
|
/// </summary>
|
||||||
|
public enum IMAP_MessageItems_enum
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// None.
|
||||||
|
/// </summary>
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Message main header.
|
||||||
|
/// </summary>
|
||||||
|
Header = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IMAP ENVELOPE structure.
|
||||||
|
/// </summary>
|
||||||
|
Envelope = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IMAP BODYSTRUCTURE structure.
|
||||||
|
/// </summary>
|
||||||
|
BodyStructure = 8,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Full message.
|
||||||
|
/// </summary>
|
||||||
|
Message = 16,
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
using MailServer.Misc;
|
||||||
|
|
||||||
namespace MailServer.IMAP.Server
|
namespace MailServer.IMAP.Server
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
using MailServer.Misc;
|
||||||
|
|
||||||
namespace MailServer.IMAP.Server
|
namespace MailServer.IMAP.Server
|
||||||
{
|
{
|
||||||
public partial class IMAP_Server
|
public partial class IMAP_Server
|
||||||
|
@ -3,6 +3,9 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
using MailServer.Misc.Auth;
|
||||||
|
using MailServer.Misc.SocketServer;
|
||||||
|
|
||||||
namespace MailServer.IMAP.Server
|
namespace MailServer.IMAP.Server
|
||||||
{
|
{
|
||||||
public partial class IMAP_Server
|
public partial class IMAP_Server
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Net;
|
||||||
using System.Linq;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using MailServer.Misc;
|
||||||
|
using MailServer.Misc.SocketServer;
|
||||||
|
|
||||||
namespace MailServer.IMAP.Server
|
namespace MailServer.IMAP.Server
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using MailServer.Misc.SocketServer;
|
using MailServer.Misc.SocketServer;
|
||||||
|
using MailServer.Misc.Auth;
|
||||||
using MailServer.Misc;
|
using MailServer.Misc;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ using System.Text;
|
|||||||
using MailServer.Misc.SocketServer;
|
using MailServer.Misc.SocketServer;
|
||||||
using MailServer.Misc;
|
using MailServer.Misc;
|
||||||
using MailServer.Misc.Auth;
|
using MailServer.Misc.Auth;
|
||||||
|
using MailServer.Misc.Mail;
|
||||||
|
using MailServer.Misc.MIME;
|
||||||
|
|
||||||
|
|
||||||
namespace MailServer.IMAP.Server
|
namespace MailServer.IMAP.Server
|
||||||
@ -2974,7 +2976,7 @@ namespace MailServer.IMAP.Server
|
|||||||
SearchGroup searchCriteria = new SearchGroup();
|
SearchGroup searchCriteria = new SearchGroup();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
searchCriteria.Parse(new Misc.StringReader(argsText));
|
searchCriteria.Parse(new StringReader(argsText));
|
||||||
}
|
}
|
||||||
catch (Exception x)
|
catch (Exception x)
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,246 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MailServer.IMAP.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides data to event GetMessageItems.
|
||||||
|
/// </summary>
|
||||||
|
public class IMAP_eArgs_MessageItems
|
||||||
|
{
|
||||||
|
private IMAP_Session m_pSession = null;
|
||||||
|
private IMAP_Message m_pMessageInfo = null;
|
||||||
|
private IMAP_MessageItems_enum m_MessageItems = IMAP_MessageItems_enum.Message;
|
||||||
|
private bool m_CloseMessageStream = true;
|
||||||
|
private Stream m_MessageStream = null;
|
||||||
|
private long m_MessageStartOffset = 0;
|
||||||
|
private byte[] m_Header = null;
|
||||||
|
private string m_Envelope = null;
|
||||||
|
private string m_BodyStructure = null;
|
||||||
|
private bool m_MessageExists = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="session">Reference to current IMAP session.</param>
|
||||||
|
/// <param name="messageInfo">Message info what message items to get.</param>
|
||||||
|
/// <param name="messageItems">Specifies message items what must be filled.</param>
|
||||||
|
public IMAP_eArgs_MessageItems(IMAP_Session session, IMAP_Message messageInfo, IMAP_MessageItems_enum messageItems)
|
||||||
|
{
|
||||||
|
m_pSession = session;
|
||||||
|
m_pMessageInfo = messageInfo;
|
||||||
|
m_MessageItems = messageItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default deconstructor.
|
||||||
|
/// </summary>
|
||||||
|
~IMAP_eArgs_MessageItems()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region method Dispose
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (m_CloseMessageStream && m_MessageStream != null)
|
||||||
|
{
|
||||||
|
m_MessageStream.Dispose();
|
||||||
|
m_MessageStream = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region internal method Validate
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks that all required data items are provided, if not throws exception.
|
||||||
|
/// </summary>
|
||||||
|
internal void Validate()
|
||||||
|
{
|
||||||
|
if ((m_MessageItems & IMAP_MessageItems_enum.BodyStructure) != 0 && m_BodyStructure == null)
|
||||||
|
{
|
||||||
|
throw new Exception("IMAP BODYSTRUCTURE is required, but not provided to IMAP server component !");
|
||||||
|
}
|
||||||
|
if ((m_MessageItems & IMAP_MessageItems_enum.Envelope) != 0 && m_Envelope == null)
|
||||||
|
{
|
||||||
|
throw new Exception("IMAP ENVELOPE is required, but not provided to IMAP server component !");
|
||||||
|
}
|
||||||
|
if ((m_MessageItems & IMAP_MessageItems_enum.Header) != 0 && m_Header == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Message header is required, but not provided to IMAP server component !");
|
||||||
|
}
|
||||||
|
if ((m_MessageItems & IMAP_MessageItems_enum.Message) != 0 && m_MessageStream == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Full message is required, but not provided to IMAP server component !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties Implementation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets reference to current IMAP session.
|
||||||
|
/// </summary>
|
||||||
|
public IMAP_Session Session
|
||||||
|
{
|
||||||
|
get { return m_pSession; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets message info what message items to get.
|
||||||
|
/// </summary>
|
||||||
|
public IMAP_Message MessageInfo
|
||||||
|
{
|
||||||
|
get { return m_pMessageInfo; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets what message items must be filled.
|
||||||
|
/// </summary>
|
||||||
|
public IMAP_MessageItems_enum MessageItems
|
||||||
|
{
|
||||||
|
get { return m_MessageItems; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets if message stream is closed automatically if all actions on it are completed.
|
||||||
|
/// Default value is true.
|
||||||
|
/// </summary>
|
||||||
|
public bool CloseMessageStream
|
||||||
|
{
|
||||||
|
get { return m_CloseMessageStream; }
|
||||||
|
|
||||||
|
set { m_CloseMessageStream = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets message stream. When setting this property Stream position must be where message begins.
|
||||||
|
/// Fill this property only if IMAP_MessageItems_enum.Message flag is specified.
|
||||||
|
/// </summary>
|
||||||
|
public Stream MessageStream
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (m_MessageStream != null)
|
||||||
|
{
|
||||||
|
m_MessageStream.Position = m_MessageStartOffset;
|
||||||
|
}
|
||||||
|
return m_MessageStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("Property MessageStream value can't be null !");
|
||||||
|
}
|
||||||
|
if (!value.CanSeek)
|
||||||
|
{
|
||||||
|
throw new Exception("Stream must support seeking !");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_MessageStream = value;
|
||||||
|
m_MessageStartOffset = m_MessageStream.Position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets message size in bytes.
|
||||||
|
/// </summary>
|
||||||
|
public long MessageSize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (m_MessageStream == null)
|
||||||
|
{
|
||||||
|
throw new Exception("You must set MessageStream property first to use this property !");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return m_MessageStream.Length - m_MessageStream.Position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets message main header.
|
||||||
|
/// Fill this property only if IMAP_MessageItems_enum.Header flag is specified.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] Header
|
||||||
|
{
|
||||||
|
get { return m_Header; }
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("Property Header value can't be null !");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Header = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets IMAP ENVELOPE string.
|
||||||
|
/// Fill this property only if IMAP_MessageItems_enum.Envelope flag is specified.
|
||||||
|
/// </summary>
|
||||||
|
public string Envelope
|
||||||
|
{
|
||||||
|
get { return m_Envelope; }
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("Property Envelope value can't be null !");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Envelope = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets IMAP BODYSTRUCTURE string.
|
||||||
|
/// Fill this property only if IMAP_MessageItems_enum.BodyStructure flag is specified.
|
||||||
|
/// </summary>
|
||||||
|
public string BodyStructure
|
||||||
|
{
|
||||||
|
get { return m_BodyStructure; }
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("Property BodyStructure value can't be null !");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_BodyStructure = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets if message exists. Set this false, if message actually doesn't exist any more.
|
||||||
|
/// </summary>
|
||||||
|
public bool MessageExists
|
||||||
|
{
|
||||||
|
get { return m_MessageExists; }
|
||||||
|
|
||||||
|
set { m_MessageExists = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MailServer.IMAP.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides data for IMAP events.
|
||||||
|
/// </summary>
|
||||||
|
public class Mailbox_EventArgs
|
||||||
|
{
|
||||||
|
private string m_Folder = "";
|
||||||
|
private string m_NewFolder = "";
|
||||||
|
private string m_Error = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folder"></param>
|
||||||
|
public Mailbox_EventArgs(string folder)
|
||||||
|
{
|
||||||
|
m_Folder = folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Folder rename constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folder"></param>
|
||||||
|
/// <param name="newFolder"></param>
|
||||||
|
public Mailbox_EventArgs(string folder, string newFolder)
|
||||||
|
{
|
||||||
|
m_Folder = folder;
|
||||||
|
m_NewFolder = newFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties Implementation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets folder.
|
||||||
|
/// </summary>
|
||||||
|
public string Folder
|
||||||
|
{
|
||||||
|
get { return m_Folder; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets new folder name, this is available for rename only.
|
||||||
|
/// </summary>
|
||||||
|
public string NewFolder
|
||||||
|
{
|
||||||
|
get { return m_NewFolder; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets custom error text, which is returned to client.
|
||||||
|
/// </summary>
|
||||||
|
public string ErrorText
|
||||||
|
{
|
||||||
|
get { return m_Error; }
|
||||||
|
|
||||||
|
set { m_Error = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
114
MailServer/IMAP/Server/Message_EventArgs/Message_EventArgs.cs
Normal file
114
MailServer/IMAP/Server/Message_EventArgs/Message_EventArgs.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MailServer.IMAP.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides data for message related events.
|
||||||
|
/// </summary>
|
||||||
|
public class Message_EventArgs
|
||||||
|
{
|
||||||
|
private IMAP_Message m_pMessage = null;
|
||||||
|
private string m_Folder = "";
|
||||||
|
private string m_CopyLocation = "";
|
||||||
|
private byte[] m_MessageData = null;
|
||||||
|
private bool m_HeadersOnly = false;
|
||||||
|
private string m_ErrorText = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folder">IMAP folder which message is.</param>
|
||||||
|
/// <param name="msg"></param>
|
||||||
|
public Message_EventArgs(string folder, IMAP_Message msg)
|
||||||
|
{
|
||||||
|
m_Folder = folder;
|
||||||
|
m_pMessage = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copy constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folder">IMAP folder which message is.</param>
|
||||||
|
/// <param name="msg"></param>
|
||||||
|
/// <param name="copyLocation"></param>
|
||||||
|
public Message_EventArgs(string folder, IMAP_Message msg, string copyLocation)
|
||||||
|
{
|
||||||
|
m_Folder = folder;
|
||||||
|
m_pMessage = msg;
|
||||||
|
m_CopyLocation = copyLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GetMessage constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folder">IMAP folder which message is.</param>
|
||||||
|
/// <param name="msg"></param>
|
||||||
|
/// <param name="headersOnly">Specifies if messages headers or full message is needed.</param>
|
||||||
|
public Message_EventArgs(string folder, IMAP_Message msg, bool headersOnly)
|
||||||
|
{
|
||||||
|
m_Folder = folder;
|
||||||
|
m_pMessage = msg;
|
||||||
|
m_HeadersOnly = headersOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties Implementation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets IMAP folder.
|
||||||
|
/// </summary>
|
||||||
|
public string Folder
|
||||||
|
{
|
||||||
|
get { return m_Folder; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets IMAP message info.
|
||||||
|
/// </summary>
|
||||||
|
public IMAP_Message Message
|
||||||
|
{
|
||||||
|
get { return m_pMessage; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets message new location. NOTE: this is available for copy command only.
|
||||||
|
/// </summary>
|
||||||
|
public string CopyLocation
|
||||||
|
{
|
||||||
|
get { return m_CopyLocation; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets message data. NOTE: this is available for GetMessage and StoreMessage event only.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] MessageData
|
||||||
|
{
|
||||||
|
get { return m_MessageData; }
|
||||||
|
|
||||||
|
set { m_MessageData = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets if message headers or full message wanted. NOTE: this is available for GetMessage event only.
|
||||||
|
/// </summary>
|
||||||
|
public bool HeadersOnly
|
||||||
|
{
|
||||||
|
get { return m_HeadersOnly; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets custom error text, which is returned to client.
|
||||||
|
/// </summary>
|
||||||
|
public string ErrorText
|
||||||
|
{
|
||||||
|
get { return m_ErrorText; }
|
||||||
|
|
||||||
|
set { m_ErrorText = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace MailServer.IMAP.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for SharedRootFolders_EventArgs.
|
||||||
|
/// </summary>
|
||||||
|
public class SharedRootFolders_EventArgs
|
||||||
|
{
|
||||||
|
private IMAP_Session m_pSession = null;
|
||||||
|
private string[] m_SharedRootFolders = null;
|
||||||
|
private string[] m_PublicRootFolders = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default constructor.
|
||||||
|
/// </summary>
|
||||||
|
public SharedRootFolders_EventArgs(IMAP_Session session)
|
||||||
|
{
|
||||||
|
m_pSession = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Properties Implementation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets reference to smtp session.
|
||||||
|
/// </summary>
|
||||||
|
public IMAP_Session Session
|
||||||
|
{
|
||||||
|
get { return m_pSession; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets users shared root folders. Ususaly there is only one root folder 'Shared Folders'.
|
||||||
|
/// </summary>
|
||||||
|
public string[] SharedRootFolders
|
||||||
|
{
|
||||||
|
get { return m_SharedRootFolders; }
|
||||||
|
|
||||||
|
set { m_SharedRootFolders = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets public root folders. Ususaly there is only one root folder 'Public Folders'.
|
||||||
|
/// </summary>
|
||||||
|
public string[] PublicRootFolders
|
||||||
|
{
|
||||||
|
get { return m_PublicRootFolders; }
|
||||||
|
|
||||||
|
set { m_PublicRootFolders = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
namespace MailServer
|
using MailServer.IMAP.Server;
|
||||||
|
|
||||||
|
namespace MailServer
|
||||||
{
|
{
|
||||||
partial class Service1
|
partial class IMAP_s
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Erforderliche Designervariable.
|
/// Erforderliche Designervariable.
|
||||||
@ -29,7 +31,8 @@
|
|||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
components = new System.ComponentModel.Container();
|
components = new System.ComponentModel.Container();
|
||||||
this.ServiceName = "Service1";
|
this.ServiceName = "IMAP_Server";
|
||||||
|
this.server = new IMAP_Server();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
60
MailServer/IMAP_s.cs
Normal file
60
MailServer/IMAP_s.cs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.ServiceProcess;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using MailServer.IMAP.Server;
|
||||||
|
|
||||||
|
namespace MailServer
|
||||||
|
{
|
||||||
|
public partial class IMAP_s : ServiceBase
|
||||||
|
{
|
||||||
|
private IMAP_Server server;
|
||||||
|
|
||||||
|
public IMAP_s()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
putEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putEvents()
|
||||||
|
{
|
||||||
|
this.server.AuthUser += new AuthUserEventHandler(server_AuthUser);
|
||||||
|
this.server.CopyMessage += new MessageEventHandler(server_CopyMessage);
|
||||||
|
this.server.CreateFolder += new FolderEventHandler(server_CreateFolder);
|
||||||
|
this.server.DeleteFolder += new FolderEventHandler(server_DeleteFolder);
|
||||||
|
this.server.DeleteFolderACL += new DeleteFolderACLEventHandler(server_DeleteFolderACL);
|
||||||
|
this.server.DeleteMessage += new MessageEventHandler(server_DeleteMessage);
|
||||||
|
this.server.GetFolderACL += new GetFolderACLEventHandler(server_GetFolderACL);
|
||||||
|
this.server.GetFolders += new FoldersEventHandler(server_GetFolders);
|
||||||
|
this.server.GetMessageItems += new MessagesItemsEventHandler(server_GetMessageItems);
|
||||||
|
this.server.GetMessagesInfo += new MessagesEventHandler(server_GetMessagesInfo);
|
||||||
|
this.server.GetSharedRootFolders += new SharedRootFoldersEventHandler(server_GetSharedRootFolders);
|
||||||
|
this.server.GetSubscribedFolders += new FoldersEventHandler(server_GetSubscribedFolders);
|
||||||
|
this.server.GetUserACL += new GetUserACLEventHandler(server_GetUserACL);
|
||||||
|
this.server.GetUserQuota += new GetUserQuotaHandler(server_GetUserQuota);
|
||||||
|
this.server.RenameFolder += new FolderEventHandler(server_RenameFolder);
|
||||||
|
this.server.SessionLog += new Misc.LogEventHandler(server_SessionLog);
|
||||||
|
this.server.SetFolderACL += new SetFolderACLEventHandler(server_SetFolderACL);
|
||||||
|
this.server.StoreMessage += new MessageEventHandler(server_StoreMessage);
|
||||||
|
this.server.StoreMessageFlags += new MessageEventHandler(server_StoreMessageFlags);
|
||||||
|
this.server.SubscribeFolder += new FolderEventHandler(server_SubscribeFolder);
|
||||||
|
this.server.SysError += new Misc.ErrorEventHandler(server_SysError);
|
||||||
|
this.server.UnSubscribeFolder += new FolderEventHandler(server_UnSubscribeFolder);
|
||||||
|
this.server.ValidateIPAddress += new Misc.ValidateIPHandler(server_ValidateIPAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnStart(string[] args)
|
||||||
|
{
|
||||||
|
this.server.StartServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnStop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -49,15 +49,18 @@
|
|||||||
<Compile Include="IMAP\IMAP_SequenceSet.cs" />
|
<Compile Include="IMAP\IMAP_SequenceSet.cs" />
|
||||||
<Compile Include="IMAP\IMAP_Utils.cs" />
|
<Compile Include="IMAP\IMAP_Utils.cs" />
|
||||||
<Compile Include="IMAP\Server\AuthUser_EventArgs\AuthUser_EventArgs.cs" />
|
<Compile Include="IMAP\Server\AuthUser_EventArgs\AuthUser_EventArgs.cs" />
|
||||||
|
<Compile Include="IMAP\Server\FetchHelper\FetchHelper.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_DELETEACL_eArgs\IMAP_DELETEACL_eArgs.cs" />
|
<Compile Include="IMAP\Server\IMAP_DELETEACL_eArgs\IMAP_DELETEACL_eArgs.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_eArgs_GetMessagesInfo\IMAP_eArgs_GetMessagesInfo.cs" />
|
<Compile Include="IMAP\Server\IMAP_eArgs_GetMessagesInfo\IMAP_eArgs_GetMessagesInfo.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_eArgs_GetQuota\IMAP_eArgs_GetQuota.cs" />
|
<Compile Include="IMAP\Server\IMAP_eArgs_GetQuota\IMAP_eArgs_GetQuota.cs" />
|
||||||
|
<Compile Include="IMAP\Server\IMAP_eArgs_MessageItems\IMAP_eArgs_MessageItems.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_Folders\IMAP_Folders.cs" />
|
<Compile Include="IMAP\Server\IMAP_Folders\IMAP_Folders.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_Folder\IMAP_Folder.cs" />
|
<Compile Include="IMAP\Server\IMAP_Folder\IMAP_Folder.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_GETACL_eArgs\IMAP_GETACL_eArgs.cs" />
|
<Compile Include="IMAP\Server\IMAP_GETACL_eArgs\IMAP_GETACL_eArgs.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_GetUserACL_eArgs\IMAP_GetUserACL_eArgs.cs" />
|
<Compile Include="IMAP\Server\IMAP_GetUserACL_eArgs\IMAP_GetUserACL_eArgs.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_MessageCollection\IMAP_MessageCollection.cs" />
|
<Compile Include="IMAP\Server\IMAP_MessageCollection\IMAP_MessageCollection.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_MessageFlags.cs" />
|
<Compile Include="IMAP\Server\IMAP_MessageFlags.cs" />
|
||||||
|
<Compile Include="IMAP\Server\IMAP_MessageItems_enum.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_Message\IMAP_Message.cs" />
|
<Compile Include="IMAP\Server\IMAP_Message\IMAP_Message.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_SelectedFolder\IMAP_SelectedFolder.cs" />
|
<Compile Include="IMAP\Server\IMAP_SelectedFolder\IMAP_SelectedFolder.cs" />
|
||||||
<Compile Include="IMAP\Server\IMAP_Session\IMAP_Session.cs" />
|
<Compile Include="IMAP\Server\IMAP_Session\IMAP_Session.cs" />
|
||||||
@ -78,11 +81,15 @@
|
|||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="IMAP\Server\IMAP_SETACL_eArgs\IMAP_SETACL_eArgs.cs" />
|
<Compile Include="IMAP\Server\IMAP_SETACL_eArgs\IMAP_SETACL_eArgs.cs" />
|
||||||
|
<Compile Include="IMAP\Server\Mailbox_EventArgs\Mailbox_EventArgs.cs" />
|
||||||
|
<Compile Include="IMAP\Server\Message_EventArgs\Message_EventArgs.cs" />
|
||||||
<Compile Include="IMAP\Server\SearchGroup\SearchGroup.cs" />
|
<Compile Include="IMAP\Server\SearchGroup\SearchGroup.cs" />
|
||||||
<Compile Include="IMAP\Server\SearchKey\SearchKey.cs" />
|
<Compile Include="IMAP\Server\SearchKey\SearchKey.cs" />
|
||||||
<Compile Include="IMAP\Server\SharedRootFolders_EventArgs\SharedRootFolders_EventArgs.cs" />
|
<Compile Include="IMAP\Server\SharedRootFolders_EventArgs\SharedRootFolders_EventArgs.cs" />
|
||||||
<Compile Include="Misc\AsyncOP.cs" />
|
<Compile Include="Misc\AsyncOP.cs" />
|
||||||
<Compile Include="Misc\Auth\AuthHelper\AuthHelper.cs" />
|
<Compile Include="Misc\Auth\AuthHelper\AuthHelper.cs" />
|
||||||
|
<Compile Include="Misc\Auth\SaslAuthTypes.cs" />
|
||||||
|
<Compile Include="Misc\Core\ValidateIP_EventArgs.cs" />
|
||||||
<Compile Include="Misc\EventArgs.cs" />
|
<Compile Include="Misc\EventArgs.cs" />
|
||||||
<Compile Include="Misc\IO\Base64Stream\Base64Stream.cs" />
|
<Compile Include="Misc\IO\Base64Stream\Base64Stream.cs" />
|
||||||
<Compile Include="Misc\IO\Base64\Base64.cs" />
|
<Compile Include="Misc\IO\Base64\Base64.cs" />
|
||||||
@ -113,12 +120,25 @@
|
|||||||
<Compile Include="Misc\IO\DataSizeExceededException.cs" />
|
<Compile Include="Misc\IO\DataSizeExceededException.cs" />
|
||||||
<Compile Include="Misc\IO\IncompleteDataException.cs" />
|
<Compile Include="Misc\IO\IncompleteDataException.cs" />
|
||||||
<Compile Include="Misc\IO\LineSizeExceededException.cs" />
|
<Compile Include="Misc\IO\LineSizeExceededException.cs" />
|
||||||
<Compile Include="Misc\IO\OuotedPrintableStream\QuotedPrintableStream.cs" />
|
<Compile Include="Misc\IO\QuotedPrintableStream\QuotedPrintableStream.cs" />
|
||||||
<Compile Include="Misc\IO\ReadWriteControlledStream.cs" />
|
<Compile Include="Misc\IO\ReadWriteControlledStream.cs" />
|
||||||
<Compile Include="Misc\IO\SizeExceededAction.cs" />
|
<Compile Include="Misc\IO\SizeExceededAction.cs" />
|
||||||
<Compile Include="Misc\IO\SmartStream\SmartStream.cs" />
|
<Compile Include="Misc\IO\SmartStream\SmartStream.cs" />
|
||||||
<Compile Include="Misc\IPBindInfo\IPBindInfo.cs" />
|
<Compile Include="Misc\IPBindInfo\IPBindInfo.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_h_AddressList.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_h_DispositionNotificationOptions.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_h_Mailbox.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_h_MailboxList.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_h_Received.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_h_ReturnPath.cs" />
|
||||||
<Compile Include="Misc\Mail\Mail_Message\Mail_Message.cs" />
|
<Compile Include="Misc\Mail\Mail_Message\Mail_Message.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_t_Address.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_t_AddressList.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_t_Group.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_t_Mailbox.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_t_MailboxList.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_t_TcpInfo.cs" />
|
||||||
|
<Compile Include="Misc\Mail\Mail_Utils.cs" />
|
||||||
<Compile Include="Misc\MIME\MIME_b.cs" />
|
<Compile Include="Misc\MIME\MIME_b.cs" />
|
||||||
<Compile Include="Misc\MIME\MIME_b_Application.cs" />
|
<Compile Include="Misc\MIME\MIME_b_Application.cs" />
|
||||||
<Compile Include="Misc\MIME\MIME_b_Audio.cs" />
|
<Compile Include="Misc\MIME\MIME_b_Audio.cs" />
|
||||||
@ -162,7 +182,7 @@
|
|||||||
<Compile Include="Misc\MIME\MIME_Utils.cs" />
|
<Compile Include="Misc\MIME\MIME_Utils.cs" />
|
||||||
<Compile Include="Misc\Net_Utils\Net_Utils.cs" />
|
<Compile Include="Misc\Net_Utils\Net_Utils.cs" />
|
||||||
<Compile Include="Misc\ParseException.cs" />
|
<Compile Include="Misc\ParseException.cs" />
|
||||||
<Compile Include="Misc\SaslAuthTypes.cs" />
|
<Compile Include="Misc\SocketBufferedWriter.cs" />
|
||||||
<Compile Include="Misc\SocketServer\Log_EventArgs\Log_EventArgs.cs" />
|
<Compile Include="Misc\SocketServer\Log_EventArgs\Log_EventArgs.cs" />
|
||||||
<Compile Include="Misc\SocketServer\ReadExecption\ReadExecption.cs" />
|
<Compile Include="Misc\SocketServer\ReadExecption\ReadExecption.cs" />
|
||||||
<Compile Include="Misc\SocketServer\SocketCallBackResult.cs" />
|
<Compile Include="Misc\SocketServer\SocketCallBackResult.cs" />
|
||||||
@ -203,7 +223,7 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Misc\SSLMode.cs" />
|
<Compile Include="Misc\SSLMode.cs" />
|
||||||
<Compile Include="Misc\StreamLineReader\StreamLineReader.cs" />
|
<Compile Include="Misc\StreamLineReader\StreamLineReader.cs" />
|
||||||
<Compile Include="Misc\StringReader\StringReader.cs" />
|
<Compile Include="Types\StringReader\StringReader.cs" />
|
||||||
<Compile Include="Misc\TextUtils\TextUtils.cs" />
|
<Compile Include="Misc\TextUtils\TextUtils.cs" />
|
||||||
<Compile Include="Misc\TimerEx\TimerEx.cs">
|
<Compile Include="Misc\TimerEx\TimerEx.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace MailServer.Misc
|
namespace MailServer.Misc.Auth
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SASL authentications
|
/// SASL authentications
|
@ -555,7 +555,7 @@ namespace MailServer.Misc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data">Data which to encode.</param>
|
/// <param name="data">Data which to encode.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Obsolete("Use MIME_Utils.QuotedPrintableDecode instead of it")]
|
//[Obsolete("Use MIME_Utils.QuotedPrintableDecode instead of it")]
|
||||||
public static byte[] QuotedPrintableDecode(byte[] data)
|
public static byte[] QuotedPrintableDecode(byte[] data)
|
||||||
{
|
{
|
||||||
/* RFC 2045 6.7. Quoted-Printable Content-Transfer-Encoding
|
/* RFC 2045 6.7. Quoted-Printable Content-Transfer-Encoding
|
||||||
@ -678,7 +678,7 @@ namespace MailServer.Misc
|
|||||||
/// <param name="encoding">Input string encoding.</param>
|
/// <param name="encoding">Input string encoding.</param>
|
||||||
/// <param name="data">String which to encode.</param>
|
/// <param name="data">String which to encode.</param>
|
||||||
/// <returns>Returns decoded string.</returns>
|
/// <returns>Returns decoded string.</returns>
|
||||||
[Obsolete("Use MIME_Utils.QDecode instead of it")]
|
//[Obsolete("Use MIME_Utils.QDecode instead of it")]
|
||||||
public static string QDecode(System.Text.Encoding encoding, string data)
|
public static string QDecode(System.Text.Encoding encoding, string data)
|
||||||
{
|
{
|
||||||
return encoding.GetString(QuotedPrintableDecode(System.Text.Encoding.ASCII.GetBytes(data.Replace("_", " "))));
|
return encoding.GetString(QuotedPrintableDecode(System.Text.Encoding.ASCII.GetBytes(data.Replace("_", " "))));
|
||||||
@ -1042,7 +1042,7 @@ namespace MailServer.Misc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Obsolete("Use Net_Utils.IsAscii instead of it")]
|
//[Obsolete("Use Net_Utils.IsAscii instead of it")]
|
||||||
public static bool IsAscii(string data)
|
public static bool IsAscii(string data)
|
||||||
{
|
{
|
||||||
foreach (char c in data)
|
foreach (char c in data)
|
||||||
@ -1318,7 +1318,7 @@ namespace MailServer.Misc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hexData">Hex data.</param>
|
/// <param name="hexData">Hex data.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Obsolete("Use Net_Utils.FromHex instead of it")]
|
//[Obsolete("Use Net_Utils.FromHex instead of it")]
|
||||||
public static byte[] FromHex(byte[] hexData)
|
public static byte[] FromHex(byte[] hexData)
|
||||||
{
|
{
|
||||||
if (hexData.Length < 2 || (hexData.Length / (double)2 != Math.Floor(hexData.Length / (double)2)))
|
if (hexData.Length < 2 || (hexData.Length / (double)2 != Math.Floor(hexData.Length / (double)2)))
|
||||||
|
88
MailServer/Misc/Core/ValidateIP_EventArgs.cs
Normal file
88
MailServer/Misc/Core/ValidateIP_EventArgs.cs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace MailServer.Misc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides data for the ValidateIPAddress event for servers.
|
||||||
|
/// </summary>
|
||||||
|
public class ValidateIP_EventArgs
|
||||||
|
{
|
||||||
|
private IPEndPoint m_pLocalEndPoint = null;
|
||||||
|
private IPEndPoint m_pRemoteEndPoint = null;
|
||||||
|
private bool m_Validated = true;
|
||||||
|
private object m_SessionTag = null;
|
||||||
|
private string m_ErrorText = "";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="localEndPoint">Server IP.</param>
|
||||||
|
/// <param name="remoteEndPoint">Connected client IP.</param>
|
||||||
|
public ValidateIP_EventArgs(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint)
|
||||||
|
{
|
||||||
|
m_pLocalEndPoint = localEndPoint;
|
||||||
|
m_pRemoteEndPoint = remoteEndPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Properties Implementation
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IP address of computer, which is sending mail to here.
|
||||||
|
/// </summary>
|
||||||
|
public string ConnectedIP
|
||||||
|
{
|
||||||
|
get { return m_pRemoteEndPoint.Address.ToString(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets local endpoint.
|
||||||
|
/// </summary>
|
||||||
|
public IPEndPoint LocalEndPoint
|
||||||
|
{
|
||||||
|
get { return m_pLocalEndPoint; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets remote endpoint.
|
||||||
|
/// </summary>
|
||||||
|
public IPEndPoint RemoteEndPoint
|
||||||
|
{
|
||||||
|
get { return m_pRemoteEndPoint; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets if IP is allowed access.
|
||||||
|
/// </summary>
|
||||||
|
public bool Validated
|
||||||
|
{
|
||||||
|
get { return m_Validated; }
|
||||||
|
|
||||||
|
set { m_Validated = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets user data what is stored to session.Tag property.
|
||||||
|
/// </summary>
|
||||||
|
public object SessionTag
|
||||||
|
{
|
||||||
|
get { return m_SessionTag; }
|
||||||
|
|
||||||
|
set { m_SessionTag = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets error text what is sent to connected socket. NOTE: This is only used if Validated = false.
|
||||||
|
/// </summary>
|
||||||
|
public string ErrorText
|
||||||
|
{
|
||||||
|
get { return m_ErrorText; }
|
||||||
|
|
||||||
|
set { m_ErrorText = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using MailServer.Misc.IO;
|
||||||
|
|
||||||
namespace MailServer.Misc
|
namespace MailServer.Misc
|
||||||
{
|
{
|
||||||
|
95
MailServer/Misc/SocketBufferedWriter.cs
Normal file
95
MailServer/Misc/SocketBufferedWriter.cs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using MailServer.Misc.SocketServer;
|
||||||
|
|
||||||
|
namespace MailServer.Misc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implements buffered writer for socket.
|
||||||
|
/// </summary>
|
||||||
|
//[Obsolete("Get rid of it.")]
|
||||||
|
public class SocketBufferedWriter
|
||||||
|
{
|
||||||
|
private SocketEx m_pSocket = null;
|
||||||
|
private int m_BufferSize = 8000;
|
||||||
|
private byte[] m_Buffer = null;
|
||||||
|
private int m_AvailableInBuffer = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="socket">Socket where to write data.</param>
|
||||||
|
public SocketBufferedWriter(SocketEx socket)
|
||||||
|
{
|
||||||
|
m_pSocket = socket;
|
||||||
|
|
||||||
|
m_Buffer = new byte[m_BufferSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region method Flush
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Forces to send all data in buffer to destination host.
|
||||||
|
/// </summary>
|
||||||
|
public void Flush()
|
||||||
|
{
|
||||||
|
if (m_AvailableInBuffer > 0)
|
||||||
|
{
|
||||||
|
m_pSocket.Write(m_Buffer, 0, m_AvailableInBuffer);
|
||||||
|
m_AvailableInBuffer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region method Write
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queues specified data to write buffer. If write buffer is full, buffered data will be sent to detination host.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Data to queue.</param>
|
||||||
|
public void Write(string data)
|
||||||
|
{
|
||||||
|
Write(System.Text.Encoding.UTF8.GetBytes(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queues specified data to write buffer. If write buffer is full, buffered data will be sent to detination host.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Data to queue.</param>
|
||||||
|
public void Write(byte[] data)
|
||||||
|
{
|
||||||
|
// There is no room to accomodate data to buffer
|
||||||
|
if ((m_AvailableInBuffer + data.Length) > m_BufferSize)
|
||||||
|
{
|
||||||
|
// Send buffer data
|
||||||
|
m_pSocket.Write(m_Buffer, 0, m_AvailableInBuffer);
|
||||||
|
m_AvailableInBuffer = 0;
|
||||||
|
|
||||||
|
// Store new data to buffer
|
||||||
|
if (data.Length < m_BufferSize)
|
||||||
|
{
|
||||||
|
Array.Copy(data, m_Buffer, data.Length);
|
||||||
|
m_AvailableInBuffer = data.Length;
|
||||||
|
}
|
||||||
|
// Buffer is smaller than data, send it directly
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_pSocket.Write(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Store data to buffer
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array.Copy(data, 0, m_Buffer, m_AvailableInBuffer, data.Length);
|
||||||
|
m_AvailableInBuffer += data.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@ namespace MailServer.Misc.SocketServer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class implements extended socket, provides usefull methods for reading and writing data to socket.
|
/// This class implements extended socket, provides usefull methods for reading and writing data to socket.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Obsolete("Use TCP_Client or TCP_Server instead.")]
|
//[Obsolete("Use TCP_Client or TCP_Server instead.")]
|
||||||
public partial class SocketEx : IDisposable
|
public partial class SocketEx : IDisposable
|
||||||
{
|
{
|
||||||
private Socket m_pSocket = null;
|
private Socket m_pSocket = null;
|
||||||
|
@ -7,7 +7,7 @@ namespace MailServer.Misc.SocketServer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is base class for Socket and Session based servers.
|
/// This is base class for Socket and Session based servers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Obsolete("Use TCP_Server class instead")]
|
//[Obsolete("Use TCP_Server class instead")]
|
||||||
public abstract partial class SocketServer : System.ComponentModel.Component
|
public abstract partial class SocketServer : System.ComponentModel.Component
|
||||||
{
|
{
|
||||||
private List<SocketServerSession> m_pSessions = null;
|
private List<SocketServerSession> m_pSessions = null;
|
||||||
|
@ -6,7 +6,7 @@ namespace MailServer.Misc.SocketServer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is base class for SocketServer sessions.
|
/// This is base class for SocketServer sessions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Obsolete("Use TCP_Server class instead")]
|
//[Obsolete("Use TCP_Server class instead")]
|
||||||
public abstract partial class SocketServerSession
|
public abstract partial class SocketServerSession
|
||||||
{
|
{
|
||||||
private string m_SessionID = "";
|
private string m_SessionID = "";
|
||||||
|
@ -12,4 +12,11 @@ namespace MailServer.Misc
|
|||||||
/// <param name="sender">Delegate caller.</param>
|
/// <param name="sender">Delegate caller.</param>
|
||||||
/// <param name="e">Event data.</param>
|
/// <param name="e">Event data.</param>
|
||||||
public delegate void ErrorEventHandler(object sender, Error_EventArgs e);
|
public delegate void ErrorEventHandler(object sender, Error_EventArgs e);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the method that will handle the <see href="LumiSoftMailServerSMTPSMTP_ServerValidateIPAddressFieldOrEvent.html">SMTP_Server.ValidateIPAddress</see> and <see href="LumiSoftMailServerPOP3POP3_ServerValidateIPAddressFieldOrEvent.html">POP3_Server.ValidateIPAddress</see>event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The source of the event. </param>
|
||||||
|
/// <param name="e">A <see href="LumiSoftMailServerValidateIP_EventArgs.html">ValidateIP_EventArgs</see> that contains the event data.</param>
|
||||||
|
public delegate void ValidateIPHandler(object sender, ValidateIP_EventArgs e);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ namespace MailServer
|
|||||||
ServiceBase[] ServicesToRun;
|
ServiceBase[] ServicesToRun;
|
||||||
ServicesToRun = new ServiceBase[]
|
ServicesToRun = new ServiceBase[]
|
||||||
{
|
{
|
||||||
new Service1()
|
new IMAP_s()
|
||||||
};
|
};
|
||||||
ServiceBase.Run(ServicesToRun);
|
ServiceBase.Run(ServicesToRun);
|
||||||
/*
|
/*
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Data;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.ServiceProcess;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MailServer
|
|
||||||
{
|
|
||||||
public partial class Service1 : ServiceBase
|
|
||||||
{
|
|
||||||
public Service1()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnStart(string[] args)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnStop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace MailServer.Misc
|
using MailServer.Misc;
|
||||||
|
|
||||||
|
namespace MailServer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// String reader.
|
/// String reader.
|
Loading…
Reference in New Issue
Block a user