// Extracts binary contents from mime and saves them to given location. // Inserts <content-ID, saved file name> pairs to the dictionary. private static void SaveAttachments(Entity mimeEntity, string savePath, Dictionary <string, string> savedFiles) { if (mimeEntity.IsMultipart) { foreach (Entity part in ((Multipart)mimeEntity.Body).BodyParts) { ContentTypeField contentType = part.Header.GetField(MimeField.ContentType) as ContentTypeField; if (contentType == null) { continue; } if (part.Body is MimeMessage) { SaveAttachments((MimeMessage)part.Body, savePath, savedFiles); } else if (part.IsMultipart) { SaveAttachments((Entity)part, savePath, savedFiles); } else if (!(part.Body is ITextBody)) { string fileName; if (contentType.Parameters.Contains("name")) { string name = contentType.Parameters["name"].ToString(); if (IsValidFileName(name)) { fileName = name; } else { fileName = Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + ".attachment"; } } else { fileName = Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + ".attachment"; } string filePath = Path.Combine(savePath, fileName); FileStream outFileStream = new FileStream(filePath, FileMode.Create); BinaryReader rdr = ((IBinaryBody)part.Body).Reader; byte[] buf = new byte[1024]; int bytesRead = 0; while ((bytesRead = rdr.Read(buf, 0, buf.Length)) > 0) { outFileStream.Write(buf, 0, bytesRead); } outFileStream.Flush(); outFileStream.Close(); MimeField contentIdField = part.Header.GetField("Content-ID"); string key = (contentIdField != null) ? contentIdField.Body.Trim('"', '<', '>', ' ') : fileName; if (!savedFiles.ContainsKey(key)) { savedFiles.Add(key, filePath); } } } } }
// Extracts binary contents from mime and saves them to given location. // Inserts <content-ID, saved file path> pairs to the dictionary. private static void SaveAttachments(Entity mimeEntity, string savePath, Dictionary <string, string> savedFiles) { if (mimeEntity.IsMultipart) { foreach (Entity part in ((Multipart)mimeEntity.Body).BodyParts) { ContentTypeField contentType = part.Header.GetField(MimeField.ContentType) as ContentTypeField; if (contentType == null) { continue; } if (part.Body is MimeMessage) { SaveAttachments((MimeMessage)part.Body, savePath, savedFiles); } else if (part.IsMultipart) { SaveAttachments((Entity)part, savePath, savedFiles); } else { MimeField contentDispositionField = part.Header.GetField("Content-Disposition"); if (contentDispositionField == null) { continue; } if (!contentDispositionField.Body.StartsWith("attachment")) { continue; } string fileName; Match fileNameMatch = Regex.Match(contentDispositionField.Body, "filename=\"?([^<>\"]+)"); if (fileNameMatch.Success) { string name = fileNameMatch.Groups[1].Value.Trim(' ', '"', '<', '>'); name = Decoder.DecodeSingleLine(name); if (IsValidFileName(name)) { fileName = name; } else { fileName = Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + ".attachment"; } } else if (contentType.Parameters.Contains("name")) { string name = contentType.Parameters["name"].ToString(); if (IsValidFileName(name)) { fileName = name; } else { fileName = Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + ".attachment"; } } else { fileName = Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + ".attachment"; } string filePath = Path.Combine(savePath, fileName); if (part.Body is ITextBody) { try { string parsedText = ParseTextBody(part); File.WriteAllText(filePath, parsedText); savedFiles.Add(fileName, filePath); } catch (Exception e) { Trace.WriteLine("SaveAttachments: " + e.Message); } } else { try { FileStream outFileStream = new FileStream(filePath, FileMode.Create); BinaryReader rdr = ((IBinaryBody)part.Body).Reader; byte[] buf = new byte[1024]; int bytesRead = 0; while ((bytesRead = rdr.Read(buf, 0, buf.Length)) > 0) { outFileStream.Write(buf, 0, bytesRead); } outFileStream.Flush(); outFileStream.Close(); savedFiles.Add(fileName, filePath); } catch (Exception e) { Trace.WriteLine("SaveAttachments: " + e.Message); } } } } } }