Skip to content

Commit

Permalink
Merge pull request #39 from tierpod/issue_32
Browse files Browse the repository at this point in the history
Add *.eml files support
  • Loading branch information
tierpod authored Mar 9, 2024
2 parents 1169b44 + e5ac129 commit afd7675
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 46 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Support input formats:

* **.zip** file: zipped dmarc report in xml format

* **.eml** file: an electronic mail format or email saved in plain text - dovecot-report-converter
tries to extract .xml, .gz or .zip attachments from found eml files to `input.dir`

Support output formats:

* **html_static** output file is a HTML, generated from builtin template htmlStaticTmpl (consts.go).
Expand Down
31 changes: 31 additions & 0 deletions cmd/dmarc-report-converter/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,37 @@ func (c *filesConverter) ConvertWrite() error {
}

func (c *filesConverter) find() error {
emlFiles, err := filepath.Glob(filepath.Join(c.cfg.Input.Dir, "*.eml"))
if err != nil {
return err
}
if len(emlFiles) > 0 {
log.Printf("[INFO] files: found %d eml file(s), extract attachments to %v", len(emlFiles), c.cfg.Input.Dir)
for _, eml := range emlFiles {
br, err := os.Open(eml)
if err != nil {
log.Printf("[ERROR] files: unable to extract attachments from %v", eml)
continue
}

isSuccess, err := extractAttachment(br, c.cfg.Input.Dir)
if err != nil {
log.Printf("[ERROR] files: %v, skip", err)
continue
}

if isSuccess && c.cfg.Input.Delete {
log.Printf("[DEBUG] files: delete %v", eml)
err := os.Remove(eml)
if err != nil {
log.Printf("[ERROR] files: %v", err)
continue
}
}
br.Close()
}
}

files, err := filepath.Glob(filepath.Join(c.cfg.Input.Dir, "*.*"))
if err != nil {
return err
Expand Down
107 changes: 61 additions & 46 deletions cmd/dmarc-report-converter/imap.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,53 +86,10 @@ func fetchIMAPAttachments(cfg *config) error {
return fmt.Errorf("server didn't return message body")
}

// create a new mail reader
mr, err := mail.CreateReader(br)
isSuccess, err := extractAttachment(br, cfg.Input.Dir)
if err != nil {
return err
}

// process each message's part
isSuccess := false
for {
p, err := mr.NextPart()
if err == io.EOF {
break
} else if err != nil {
log.Printf("[ERROR] imap: can't read next part: %v, skip", err)
break
}

switch h := p.Header.(type) {
case *mail.AttachmentHeader:
// this is an attachment
filename, err := h.Filename()
if err != nil {
log.Printf("[ERROR] imap: %v, skip", err)
continue
}
log.Printf("[INFO] imap: found attachment: %v", filename)

outFile := filepath.Join(cfg.Input.Dir, filename)
log.Printf("[INFO] imap: save attachment to: %v", outFile)
f, err := os.Create(outFile)
if err != nil {
log.Printf("[ERROR] imap: %v, skip", err)
continue
}

_, err = io.Copy(f, p.Body)
if err != nil {
log.Printf("[ERROR] imap: %v, skip", err)
continue
}
err = f.Close()
if err != nil {
log.Printf("[ERROR] imap: %v, skip", err)
continue
}
isSuccess = true
}
log.Printf("[ERROR] imap: %v, skip", err)
continue
}

if isSuccess && cfg.Input.IMAP.Delete {
Expand Down Expand Up @@ -168,3 +125,61 @@ func fetchIMAPAttachments(cfg *config) error {

return nil
}

func extractAttachment(r io.Reader, inputDir string) (bool, error) {
// Create a new mail reader
mr, err := mail.CreateReader(r)
if err != nil {
return false, err
}

// process each message's part
isSuccess := false
for {
p, err := mr.NextPart()
if err == io.EOF {
break
} else if err != nil {
log.Printf("[ERROR] imap: can't read next part: %v, skip", err)
break
}

switch h := p.Header.(type) {
case *mail.AttachmentHeader:
// this is an attachment
filename, err := h.Filename()
if err != nil {
log.Printf("[ERROR] extractAttachment: %v, skip", err)
continue
}
if filename == "" {
log.Printf("[WARN] extractAttachment: found attachment with empty filename, skip")
continue
}

log.Printf("[INFO] extractAttachment: found attachment: %v", filename)

outFile := filepath.Join(inputDir, filename)
log.Printf("[INFO] extractAttachment: save attachment to: %v", outFile)
f, err := os.Create(outFile)
if err != nil {
log.Printf("[ERROR] extractAttachment: %v, skip", err)
continue
}

_, err = io.Copy(f, p.Body)
if err != nil {
log.Printf("[ERROR] extractAttachment: %v, skip", err)
continue
}
err = f.Close()
if err != nil {
log.Printf("[ERROR] extractAttachment: %v, skip", err)
continue
}
isSuccess = true
}
}

return isSuccess, err
}

0 comments on commit afd7675

Please sign in to comment.