mailq-inspector/mailq/parser.go

74 lines
2.4 KiB
Go
Raw Normal View History

2019-01-01 15:46:35 +01:00
package mailq
2018-12-29 01:42:50 +01:00
import (
2018-12-29 18:09:44 +01:00
"bufio"
"errors"
2018-12-31 17:16:32 +01:00
"io"
2018-12-29 18:09:44 +01:00
"regexp"
"strconv"
"strings"
"time"
2018-12-29 01:42:50 +01:00
)
2019-01-01 16:05:25 +01:00
func ParseFromReader(dataSource io.Reader) (MailQ, error) {
2018-12-29 18:09:44 +01:00
const dateFormat = "2006 Mon Jan _2 15:04:05"
var messageIdStart = regexp.MustCompile("^[0-9A-Za-z]+[*!]? ")
2018-12-29 22:02:23 +01:00
scanner := bufio.NewScanner(dataSource)
2018-12-31 17:16:32 +01:00
var line string
scanner.Scan()
line = scanner.Text()
if strings.HasPrefix(line, "Mail queue is empty") {
2018-12-29 18:09:44 +01:00
// If mail queue is empty, there is nothing to do
return NewQueue(), nil
2018-12-29 18:09:44 +01:00
} else if strings.HasPrefix(line, "-Queue ID-") == false {
// Abort if input does not look like output from mailq(1)
return NewQueue(), errors.New("Sorry, this does not look like output from mailq(1).")
2018-12-29 18:09:44 +01:00
}
queue := NewQueue()
2018-12-29 18:16:54 +01:00
var currentMail QEntry
2018-12-29 18:09:44 +01:00
for scanner.Scan() {
// Read input line by line
line := scanner.Text()
fields := strings.Fields(line)
if strings.HasPrefix(line, "--") {
// Handle the summary line at the end of mailq output
break
} else if messageIdStart.MatchString(line) {
// Handle line starting next mail in queue
messageId := fields[0]
if strings.HasSuffix(messageId, "*") {
currentMail.Status = "active"
2018-12-29 18:09:44 +01:00
} else if strings.HasSuffix(messageId, "!") {
currentMail.Status = "hold"
2018-12-29 18:09:44 +01:00
} else {
currentMail.Status = "deferred"
2018-12-29 18:09:44 +01:00
}
dateString := strconv.Itoa(time.Now().Year()) + " " + strings.Join(fields[2:6], " ")
mailDate, _ := time.Parse(dateFormat, dateString)
currentMail.Id = strings.TrimRight(messageId, "*!")
currentMail.Size, _ = strconv.Atoi(fields[1])
currentMail.Date = mailDate
currentMail.Sender = fields[6]
2018-12-29 18:09:44 +01:00
continue
} else if strings.HasPrefix(line, "(") && strings.HasSuffix(line, ")") {
// Handle reason for deferred status (if deferred at all, may be missing)
currentMail.Reason = strings.Trim(strings.TrimSpace(line), "()")
2018-12-29 18:09:44 +01:00
continue
} else if len(fields) == 1 {
// Handle line with one of the mail recipients
currentMail.Recipients = append(currentMail.Recipients, fields[0])
2018-12-29 18:09:44 +01:00
continue
} else if len(fields) == 0 {
// If the next line is empty, make sure to push current mail to list
// and create a new struct for the next mail to process
queue.AddEntry(currentMail)
2018-12-29 18:16:54 +01:00
currentMail = QEntry{}
2018-12-29 18:09:44 +01:00
}
}
if scanner.Err() != nil {
// If the scanner failed, let our caller know.
return NewQueue(), errors.New("Something went wrong with reading from stdin. Sorry!")
2018-12-29 18:09:44 +01:00
}
2018-12-31 17:16:32 +01:00
return queue, nil
2018-12-29 01:42:50 +01:00
}