summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go103
1 files changed, 103 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..d20f574
--- /dev/null
+++ b/main.go
@@ -0,0 +1,103 @@
+package main
+
+import (
+ "errors"
+ "flag"
+ "fmt"
+ "io"
+ "mime"
+ "mime/multipart"
+ "net/mail"
+ "os"
+ "strings"
+)
+
+func main() {
+ flag.Usage = func() {
+ fmt.Fprintf(flag.CommandLine.Output(), "Usage: mimeslicer <command> [options]\n\n")
+ fmt.Fprintf(flag.CommandLine.Output(), "Commands:\n")
+ os.Exit(0)
+ }
+
+ if len(os.Args) < 2 {
+ fmt.Println("Error: Command missing.")
+ flag.Usage()
+ }
+
+ inspectCmd := flag.NewFlagSet("inspect", flag.ExitOnError)
+ inspectCmdInputFile := inspectCmd.String("i", "", "input file")
+
+ switch os.Args[1] {
+ case "inspect":
+ inspectCmd.Parse(os.Args[2:])
+
+ if err := inspect(*inspectCmdInputFile); err != nil {
+ fmt.Printf("Error: %s", err.Error())
+ os.Exit(1)
+ }
+ case "-h", "--help", "help":
+ flag.Usage()
+ default:
+ fmt.Printf("Error: unknown command %q\n\n", os.Args[1])
+ flag.Usage()
+ }
+}
+
+func inspect(file string) error {
+ fd, err := os.Open(file)
+ if err != nil {
+ return err
+ }
+ defer fd.Close()
+
+ msg, err := mail.ReadMessage(fd)
+ if err != nil {
+ return err
+ }
+
+ for k, v := range msg.Header {
+ for _, val := range v {
+ fmt.Printf("%s: %s\n", k, val)
+ }
+ }
+
+ contentType := msg.Header.Get("Content-Type")
+ mediaType, params, err := mime.ParseMediaType(contentType)
+ if err != nil {
+ return errors.Join(err, errors.New("failed to parse mediate type from contentType"))
+ }
+
+ if !strings.HasPrefix(mediaType, "multipart/") {
+ return errors.New("expected multipler/ TOOD")
+ }
+
+ boundary, ok := params["boundary"]
+ if !ok {
+ return errors.New("Error: no boundary in Content-Type header for multipart media type")
+ }
+
+ mr := multipart.NewReader(msg.Body, boundary)
+
+ partIndex := 0
+ fmt.Printf("\nMIME body parts\n\n")
+
+ for {
+ part, err := mr.NextPart()
+ if err == io.EOF {
+ break
+ }
+
+ fmt.Printf("[%d]\n", partIndex)
+
+ fmt.Printf("Headers:\n")
+ for k, v := range part.Header {
+ for _, val := range v {
+ fmt.Printf(" %s: %s\n", k, val)
+ }
+ }
+
+ partIndex++
+ }
+
+ return nil
+}