sophuwu.site > mailboxxer   
              77
            
             package main

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"io"
	"mime"
	"mime/multipart"
	"net/mail"
	"net/textproto"
	"strings"
)

type FileList map[string][]byte

func getfiles(files *FileList, parts interface{}) {
	var body io.Reader
	var head textproto.MIMEHeader
	switch part := parts.(type) {
	case *mail.Message:
		body = part.Body
		head = textproto.MIMEHeader(part.Header)
	case *multipart.Part:
		body = part
		head = part.Header
	}
	mediaType, params, _ := mime.ParseMediaType(head.Get("Content-Type"))

	if strings.HasPrefix(mediaType, "multipart/") {
		mr := multipart.NewReader(body, params["boundary"])
		var part *multipart.Part
		var err error
		for {
			if part, err = mr.NextPart(); err != nil {
				break
			}
			getfiles(files, part)
			part.Close()
		}
		return
	}
	content, _ := io.ReadAll(body)
	if head.Get("Content-Transfer-Encoding") == "base64" {
		content, _ = base64.StdEncoding.DecodeString(string(content))
	}
	if len(content) == 0 {
		return
	}
	name := "body.txt"
	if params["name"] != "" {
		name = params["name"]
	}
	if strings.Contains(mediaType, "html") {
		name = "index.html"
	}
	(*files)[name] = append((*files)[name], content...)
}

func EmlFiles(eml *mail.Message) FileList {
	s := ""
	for k := range eml.Header {
		s += fmt.Sprintf("%s: %s\n", k, eml.Header.Get(k))
	}
	files := make(FileList)
	files["header.txt"] = []byte(s)
	getfiles(&files, eml)
	return files
}

func GetFiles(b *bytes.Buffer) (FileList, error) {
	e, err := mail.ReadMessage(b)
	if err != nil {
		return nil, err
	}
	return EmlFiles(e), nil
}