diff options
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 103 |
1 files changed, 103 insertions, 0 deletions
@@ -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 +} |
