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) }