aboutsummaryrefslogtreecommitdiff
path: root/main.go
blob: fc6c8af6b1d6ddb2afe892d0f02aa7569aba093d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package main

import (
	"flag"
	"fmt"
	"net"
	"os"
	"os/signal"
	"syscall"
)

type Flags struct {
	Groups   string
	HostName string
	Listen   string
	StdErr   string
}

func ParseArgs() (*Flags, []string) {
	var flags Flags

	name, _ := os.Hostname()

	flag.StringVar(&flags.Groups, "groups", "/etc/postfix/user_groups", "User group list")
	flag.StringVar(&flags.HostName, "hostname", name, "E-Mail hostname")
	flag.StringVar(&flags.Listen, "listen", "-", "listen socket path")
	flag.StringVar(&flags.StdErr, "std-err", name, "Redirect errors to filepath")

	flag.Parse()

	return &flags, flag.Args()
}

func handleSignal(c <-chan os.Signal, listenner net.Listener) {
	for v := range c {
		switch v {
		case syscall.SIGINT:
			_ = listenner.Close()
		default:
		}
	}
}

func exitOnErr(err error) {
	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(1)
	}
}

func main() {
	flags, groups := ParseArgs()

	if flags.StdErr != "" {
		f, _ := os.OpenFile(flags.StdErr, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0666)
		os.Stderr = f
		defer f.Close()
	}

	srv := &Server{
		HostName:   flags.HostName,
		GroupsFile: flags.Groups,
		Groups:     groups,
	}

	if flags.Listen == "-" {
		srv.HandleConn(os.Stdout, os.Stdin)

		return
	}

	listenner, err := net.Listen("unix", flags.Listen)
	exitOnErr(err)
	defer os.Remove(flags.Listen)

	err = os.Chmod(flags.Listen, os.ModePerm)
	exitOnErr(err)

	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGHUP, syscall.SIGINT)
	go handleSignal(c, listenner)

	err = ServeUnixSocket(listenner, srv)
	exitOnErr(err)
}