From 9947d64e810322dc5879f7fb834317331cef8766 Mon Sep 17 00:00:00 2001 From: Tadas Vilkeliskis Date: Mon, 2 Nov 2026 11:53:06 -0500 Subject: initial implementation on inspect command --- main.go | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 main.go 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 [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 +} -- cgit v1.2.3