package main import ( "flag" "fmt" "io" "os" "os/exec" "strconv" "text/tabwriter" ) import ( "mailq-inspector/parser" ) var settings = make(map[string]string) func main() { parseArguments() if settings["interactive"] == "false" { showQueue() } if settings["interactive"] == "true" { interactiveShell() } fmt.Printf("I am done.\n") } func parseArguments() { mailqCommandPtr := flag.String("mailqCommand", "mailq", "Command to use for getting mailq output") mailqCommandArgsPtr := flag.String("mailqCommandArgs", "", "Optional arguments to pass to mailqCommand") interactivePtr := flag.Bool("interactive", false, "Set to true for shell mode") flag.Parse() settings["mailqCommand"] = *mailqCommandPtr settings["mailqCommandArgs"] = *mailqCommandArgsPtr settings["interactive"] = strconv.FormatBool(*interactivePtr) } func interactiveShell() { } func showQueue() { entries, err := fetchQueueEntries() if err != nil { fmt.Printf("Could not fetch queue entries: %s\n", err.Error()) os.Exit(1) } pagerReader, pagerWriter := io.Pipe() pagerDone := make(chan bool) go launchPager(pagerReader, pagerDone) printQueueEntries(entries, pagerWriter) pagerWriter.Close() // Wait for pager to be closed before continuing the main program <-pagerDone } func fetchQueueEntries() ([]parser.QEntry, error) { var entries []parser.QEntry var err error if settings["mailqCommandArgs"] == "" { entries, err = readFromCmd(exec.Command(settings["mailqCommand"])) } else { entries, err = readFromCmd(exec.Command(settings["mailqCommand"], settings["mailqCommandArgs"])) } return entries, err } func printQueueEntries(entries []parser.QEntry, writer io.Writer) { tabWriter := tabwriter.NewWriter(writer, 2, 2, 1, ' ', tabwriter.TabIndent) fmt.Fprintf(tabWriter, "| %s\t| %s\t| %s\t| %s\t| %s\t| %s\t| %s\t| %s\t| \n", "Date", "Id", "Status", "Size", "Sender", "#", "First Recipient", "Reason") for _, entry := range entries { _, writeError := fmt.Fprintf(tabWriter, "| %s\t| %s\t| %s\t| %d\t| %s\t| {%d}\t| %s\t| %s\t \n", entry.Date.Format(parser.SortableDateFormat), entry.Id, entry.Status, entry.Size, entry.Sender, len(entry.Recipients), entry.Recipients[0], entry.Reason) if writeError != nil { // A writeError is expected once the reader was closed // This happens when the pager application got terminated break } } tabWriter.Flush() } func launchPager(reader *io.PipeReader, pagerDone chan<- bool) { cmd := exec.Command("less", "--chop-long-lines") cmd.Stdin = reader cmd.Stdout = os.Stdout if err := cmd.Start(); err != nil { fmt.Printf("Error launching pager: %s\n", err.Error()) } if err := cmd.Wait(); err != nil { fmt.Printf("Error terminating pager: %s\n", err.Error()) } else { reader.Close() pagerDone <- true } } func readFromCmd(cmd *exec.Cmd) ([]parser.QEntry, error) { stdout, err := cmd.StdoutPipe() if err != nil { return nil, err } if err := cmd.Start(); err != nil { return nil, err } result, resultError := parser.ParseMailQ(stdout) if err := cmd.Wait(); err != nil { return nil, err } return result, resultError }