forked from sorbits/go.enmime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mime-dump.go
146 lines (125 loc) · 2.86 KB
/
mime-dump.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package main
import (
"fmt"
"io"
"net/mail"
"os"
"path"
"strings"
"github.com/jhillyerd/go.enmime"
)
func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "Missing filename argument")
os.Exit(1)
}
reader, err := os.Open(os.Args[1])
if err != nil {
fmt.Fprintln(os.Stderr, "Failed to open file:", err)
os.Exit(1)
}
basename := path.Base(os.Args[1])
if err = dump(reader, basename); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func dump(reader io.Reader, name string) error {
// Read email using Go's net/mail
msg, err := mail.ReadMessage(reader)
if err != nil {
return fmt.Errorf("During mail.ReadMessage: %v", err)
}
// Parse message body with enmime
mime, err := enmime.ParseMIMEBody(msg)
if err != nil {
return fmt.Errorf("During enmime.ParseMIMEBody: %v", err)
}
h1(name)
h2("Header")
for k := range msg.Header {
switch strings.ToLower(k) {
case "from", "to", "bcc", "subject":
continue
}
fmt.Printf("%v: %v \n", k, mime.GetHeader(k))
}
h2("Envelope")
for _, hkey := range enmime.AddressHeaders {
addrlist, err := mime.AddressList(hkey)
if err != nil {
if err == mail.ErrHeaderNotPresent {
continue
}
panic(err)
}
fmt.Println("### " + hkey)
for _, addr := range addrlist {
fmt.Printf("%v <%v>\n", addr.Name, addr.Address)
}
}
fmt.Printf("### Subject\n %v\n", mime.GetHeader("Subject"))
h2("Body Text")
fmt.Println(mime.Text)
fmt.Println()
h2("Body HTML")
fmt.Println(mime.Html)
fmt.Println()
h2("Attachment List")
for _, a := range mime.Attachments {
fmt.Printf("- %v (%v)\n", a.FileName(), a.ContentType())
}
fmt.Println()
h2("MIME Part Tree")
if mime.Root == nil {
fmt.Println("Message was not MIME encoded")
} else {
printPart(mime.Root, " ")
}
return nil
}
func h1(content string) {
bar := strings.Repeat("-", len(content))
fmt.Printf("#%v\n%v\n\n", content, bar)
}
func h2(content string) {
fmt.Printf("##%v\n", content)
}
// printPart pretty prints the MIMEPart tree
func printPart(p enmime.MIMEPart, indent string) {
sibling := p.NextSibling()
child := p.FirstChild()
// Compute indent strings
myindent := indent + "`-- "
childindent := indent + " "
if sibling != nil {
myindent = indent + "|-- "
childindent = indent + "| "
}
if p.Parent() == nil {
// Root shouldn't be decorated, has no siblings
myindent = indent
childindent = indent
}
// Format and print this node
ctype := "MISSING TYPE"
if p.ContentType() != "" {
ctype = p.ContentType()
}
disposition := ""
if p.Disposition() != "" {
disposition = ", disposition: " + p.Disposition()
}
filename := ""
if p.FileName() != "" {
filename = ", filename: \"" + p.FileName() + "\""
}
fmt.Printf("%s%s%s%s\n", myindent, ctype, disposition, filename)
// Recurse
if child != nil {
printPart(child, childindent)
}
if sibling != nil {
printPart(sibling, indent)
}
}