main.go (1566B)
1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "net" 7 "os" 8 "os/signal" 9 "syscall" 10 ) 11 12 type Flags struct { 13 Groups string 14 HostName string 15 Listen string 16 StdErr string 17 } 18 19 func ParseArgs() (*Flags, []string) { 20 var flags Flags 21 22 name, _ := os.Hostname() 23 24 flag.StringVar(&flags.Groups, "groups", "/etc/postfix/user_groups", "User group list") 25 flag.StringVar(&flags.HostName, "hostname", name, "E-Mail hostname") 26 flag.StringVar(&flags.Listen, "listen", "-", "listen socket path") 27 flag.StringVar(&flags.StdErr, "std-err", name, "Redirect errors to filepath") 28 29 flag.Parse() 30 31 return &flags, flag.Args() 32 } 33 34 func handleSignal(c <-chan os.Signal, listenner net.Listener) { 35 for v := range c { 36 switch v { 37 case syscall.SIGINT: 38 _ = listenner.Close() 39 default: 40 } 41 } 42 } 43 44 func exitOnErr(err error) { 45 if err != nil { 46 fmt.Fprintln(os.Stderr, err.Error()) 47 os.Exit(1) 48 } 49 } 50 51 func main() { 52 flags, groups := ParseArgs() 53 54 if flags.StdErr != "" { 55 f, _ := os.OpenFile(flags.StdErr, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0666) 56 os.Stderr = f 57 defer f.Close() 58 } 59 60 srv := &Server{ 61 HostName: flags.HostName, 62 GroupsFile: flags.Groups, 63 Groups: groups, 64 } 65 66 if flags.Listen == "-" { 67 srv.HandleConn(os.Stdout, os.Stdin) 68 69 return 70 } 71 72 listenner, err := net.Listen("unix", flags.Listen) 73 exitOnErr(err) 74 defer os.Remove(flags.Listen) 75 76 err = os.Chmod(flags.Listen, os.ModePerm) 77 exitOnErr(err) 78 79 c := make(chan os.Signal, 1) 80 signal.Notify(c, syscall.SIGHUP, syscall.SIGINT) 81 go handleSignal(c, listenner) 82 83 err = ServeUnixSocket(listenner, srv) 84 exitOnErr(err) 85 }