Exemple #1
0
        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
			};
        }
Exemple #2
0
        /// <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;
			}
        }
Exemple #3
0
		/// <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;
            }
        }