private object[] CreateMessageInfo(string file) { string[] array = Path.GetFileNameWithoutExtension(file).Split(new char[] { '_' }); if (array.Length == 3) { int num = (int)new FileInfo(file).Length; DateTime dateTime = DateTime.ParseExact(array[0], "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo); int num2 = Convert.ToInt32(array[1]); int num3 = Convert.ToInt32(array[2]); return new object[] { num2, num, num3, dateTime }; } DateTime dateTime2 = DateTime.ParseExact(array[0], "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo); int num4 = Convert.ToInt32(array[1]); int num5 = 0; int num6 = 0; using (FileStream fileStream = File.OpenRead(file)) { _InternalHeader internalHeader = new _InternalHeader(fileStream); num5 = (int)(fileStream.Length - fileStream.Position); num6 = (int)internalHeader.MessageFlags; } if (num5 == 0) { throw new Exception("CreateMessageInfo if(size == 0){, this should never happen !"); } return new object[] { num4, num5, num6, dateTime2 }; }
/// <summary> /// Gets specified message specified items. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param> /// <param name="e">MessageItems info.</param> public void GetMessageItems(string accessingUser,string folderOwnerUser,string folder,EmailMessageItems e) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'r' permission. There is builtin user system, skip ACL for it. *) Store message. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(e); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'r' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.r) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Get message string folderPath = API_Utlis.DirectoryExists(API_Utlis.PathFix(m_MailStorePath + "Mailboxes\\" + folderOwnerUser + "\\" + IMAP_Utils.Encode_IMAP_UTF7_String(folder))); string msgFile = API_Utlis.FileExists(API_Utlis.PathFix(folderPath + "\\" + e.MessageID + ".eml")); // Check if file exists if(msgFile != null){ if((e.MessageItems & (IMAP_MessageItems_enum.Header | IMAP_MessageItems_enum.Message)) != 0){ bool closeStream = true; // TODO: Change to FileAccess.Read in next versions FileStream fs = File.Open(msgFile,FileMode.Open,FileAccess.ReadWrite,FileShare.ReadWrite); // Just skip internal header _InternalHeader internalHeader = new _InternalHeader(fs); long initialPosition = fs.Position; if((e.MessageItems & IMAP_MessageItems_enum.Header) != 0){ fs.Position = initialPosition; e.Header = GetTopLines(fs,0); } if((e.MessageItems & IMAP_MessageItems_enum.Message) != 0){ fs.Position = initialPosition; e.MessageStream = fs; // Don't close stream, it will be closed by POP3/IMAP server when all done. closeStream = false; } if(closeStream){ fs.Dispose(); } } } else{ e.MessageExists = false; } }
/// <summary> /// Creates specified message cache record. /// </summary> /// <param name="file">File name of file which cache record to do.</param> /// <returns></returns> private object[] CreateMessageInfo(string file) { string[] fileParts = Path.GetFileNameWithoutExtension(file).Split('_'); if(fileParts.Length == 3){ // REMOVEME: ************************** // Size int size = (int)(new FileInfo(file)).Length; // Get INTERNALDATE,UID,FLAGS DateTime recieveDate = DateTime.ParseExact(fileParts[0],"yyyyMMddHHmmss",System.Globalization.DateTimeFormatInfo.InvariantInfo); int uid = Convert.ToInt32(fileParts[1]); int flags = Convert.ToInt32(fileParts[2]); return new object[]{uid,size,flags,recieveDate}; } else{ // Get INTERNALDATE,UID DateTime recieveDate = DateTime.ParseExact(fileParts[0],"yyyyMMddHHmmss",System.Globalization.DateTimeFormatInfo.InvariantInfo); int uid = Convert.ToInt32(fileParts[1]); int size = 0; int flags = 0; using(FileStream fs = File.OpenRead(file)){ _InternalHeader header = new _InternalHeader(fs); size = (int)(fs.Length - fs.Position); flags = (int)header.MessageFlags; } // REMOVE ME: This never should happen if(size == 0){ throw new Exception("CreateMessageInfo if(size == 0){, this should never happen !"); } return new object[]{uid,size,flags,recieveDate}; } }
/// <summary> /// Gets specified message specified items. /// </summary> /// <param name="accessingUser">User who accesses this method. /// User needs r permission to call this method or Exception is thrown. /// There is special user 'system' for which permission check is skipped.</param> /// <param name="folderOwnerUser">User who's folder it is.</param> /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param> /// <param name="e">MessageItems info.</param> public void GetMessageItems(string accessingUser,string folderOwnerUser,string folder,EmailMessageItems e) { /* Implementation notes: *) Validate values. Throw ArgumnetExcetion if invalid values. *) Ensure that user exists. *) Normalize folder. Remove '/' from folder start and end, ... . *) Do Shared Folders mapping. *) Ensure that folder exists. Throw Exception if don't. *) See if user has sufficient permissions. User requires 'r' permission. There is builtin user system, skip ACL for it. *) Store message. */ //--- Validate values -------------------// ArgsValidator.ValidateUserName(folderOwnerUser); ArgsValidator.ValidateFolder(folder); ArgsValidator.ValidateNotNull(e); //---------------------------------------// // Ensure that user exists. if(!UserExists(folderOwnerUser)){ throw new Exception("User '" + folderOwnerUser + "' doesn't exist !"); } // Normalize folder. Remove '/' from folder start and end. folder = API_Utlis.NormalizeFolder(folder); // Do Shared Folders mapping. string originalFolder = folder; SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder); if(mappedFolder.IsSharedFolder){ folderOwnerUser = mappedFolder.FolderOnwer; folder = mappedFolder.Folder; if(folderOwnerUser == "" || folder == ""){ throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !"); } } // Ensure that folder exists. Throw Exception if don't. if(!FolderExists(folderOwnerUser + "/" + folder)){ throw new Exception("Folder '" + folder + "' doesn't exist !"); } // See if user has sufficient permissions. User requires 'r' permission. // There is builtin user system, skip ACL for it. if(accessingUser.ToLower() != "system"){ IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser); if((acl & IMAP_ACL_Flags.r) == 0){ throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !"); } } //--- Get message string folderPath = API_Utlis.DirectoryExists(API_Utlis.PathFix(m_MailStorePath + "Mailboxes\\" + folderOwnerUser + "\\" + Core.Encode_IMAP_UTF7_String(folder))); string msgFile = API_Utlis.FileExists(API_Utlis.PathFix(folderPath + "\\" + e.MessageID + ".eml")); // Check if file exists if(msgFile != null){ if((e.MessageItems & (IMAP_MessageItems_enum.BodyStructure | IMAP_MessageItems_enum.Envelope)) != 0){ // Using OpenOrCreateFile ensures that multiple .info files constructions won't happen at same time. // This can happen if multiple sessions want same message at same time. using(FileStream fs = OpenOrCreateFile(API_Utlis.PathFix(folderPath + "\\" + e.MessageID + ".info"),10000)){ DataSet dsMessageInfo = new DataSet("dsMessageInfo"); dsMessageInfo.Tables.Add("MessageInfo"); dsMessageInfo.Tables["MessageInfo"].Columns.Add("ImapEnvelope"); dsMessageInfo.Tables["MessageInfo"].Columns.Add("ImapBody"); // Message info file doesn't exist, create it if(fs.Length == 0){ Mime m = null; try{ m = Mime.Parse(msgFile); } // Invalid message, parsing failed catch{ m = Mime.CreateSimple(new AddressList(),new AddressList(),"BAD Message","This is BAD message, mail server failed to parse it !",""); } DataRow dr = dsMessageInfo.Tables["MessageInfo"].NewRow(); dr["ImapEnvelope"] = IMAP_Envelope.ConstructEnvelope(m.MainEntity); dr["ImapBody"] = IMAP_BODY.ConstructBodyStructure(m,false); dsMessageInfo.Tables["MessageInfo"].Rows.Add(dr); dsMessageInfo.WriteXml(fs); } // Load message info else{ dsMessageInfo.ReadXml(fs); } e.Envelope = dsMessageInfo.Tables["MessageInfo"].Rows[0]["ImapEnvelope"].ToString(); // Remove word BODY, currently internal header adds it. e.BodyStructure = dsMessageInfo.Tables["MessageInfo"].Rows[0]["ImapBody"].ToString().Substring(5); } } if((e.MessageItems & (IMAP_MessageItems_enum.Header | IMAP_MessageItems_enum.Message)) != 0){ bool closeStream = true; // TODO: Cheage to FileAccess.Read in next versions FileStream fs = File.Open(msgFile,FileMode.Open,FileAccess.ReadWrite,FileShare.ReadWrite); // Just skip internal header _InternalHeader internalHeader = new _InternalHeader(fs); long initialPosition = fs.Position; if((e.MessageItems & IMAP_MessageItems_enum.Header) != 0){ fs.Position = initialPosition; e.Header = GetTopLines(fs,0); } if((e.MessageItems & IMAP_MessageItems_enum.Message) != 0){ fs.Position = initialPosition; e.MessageStream = fs; // Don't close stream, it will be closed by IMAP server when all done. closeStream = false; } if(closeStream){ fs.Dispose(); } } } else{ e.MessageExists = false; } }