package main import ( "fmt" "github.com/dballard/warren/cmd/warrend/conf" "github.com/dballard/warren/lib/warren" "log" "net" "os" "os/signal" "strings" "syscall" ) var cmdSock net.Listener type SockCommand struct { warren.Command Run func(cmd *SockCommand, c net.Conn, path string, args ...string) } func (cmd *SockCommand) GetName() string { return cmd.Name } func (cmd *SockCommand) GetSummary() string { return cmd.Summary } func (cmd *SockCommand) Exec(c net.Conn, path string, args []string) { cmd.Flag.Usage = func() { // helpFunc(c, c.Name) } cmd.Flag.Parse(args) cmd.Run(cmd, c, path, cmd.Flag.Args()...) } func sockCmdHandle(c net.Conn) { defer c.Close() fmt.Println("cmdHandle") data, err := warren.ReadStringz(c) if err != nil { fmt.Println(err) warren.WriteStringz(c, "read error:"+err.Error()) return } fmt.Println("cmdHandle got command:", string(data)) // BAD: TODO: handle quotes " // path|arg1|arg2|... args := strings.Split(data, "|") if len(args) < 2 { warren.WriteStringz(c, "Format error") return } // parse args var icmd = warren.GetCommand(args[1]) // get and run cmd if icmd == nil { warren.WriteStringz(c, "Unknown command "+args[1]) // usage ? return } icmd.(*SockCommand).Exec(c, args[0], args[2:]) } // determine if warrend is already running func checkRunning() bool { if pfile, err := os.Open(warren.WarrendPidFile); err == nil { // pid file exists var pid int n, err := fmt.Fscanf(pfile, "%d", &pid) if n == 0 || err != nil { // read error return false } // is there a runnign process with the pid? err = syscall.Kill(pid, 0) return err == nil } else { // pid file does not exist return false } } func initRunning() { // rm old sock os.Remove(warren.CmdSockAddr) // incase gone os.Mkdir(warren.WarrendRunDir, 0775) // drop down pid pidfile, err := os.Create(warren.WarrendPidFile) if err != nil { log.Fatal("Could not create pidfile: ", warren.WarrendPidFile, " : ", err) } pid := os.Getpid() fmt.Fprintf(pidfile, "%d", pid) pidfile.Close() cmdSock, err = net.Listen(warren.CmdSockType, warren.CmdSockAddr) if err != nil { fmt.Println(cmdSock) Shutdown() log.Fatal("Listen on sock error:", err) } } func Shutdown() { os.Remove(warren.WarrendPidFile) if cmdSock != nil { cmdSock.Close() } } func main() { if checkRunning() { log.Fatal("warrend instance already running") } go conf.Run() if cinit := <-conf.Init; !cinit { return } initRunning() warren.RegisterCommand(listCmd) warren.RegisterCommand(regCmd) warren.RegisterCommand(unregCmd) // Handle signals c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP, ) go func() { <-c Shutdown() }() fmt.Println("warrend starting and listening...") // Listen for { fd, err := cmdSock.Accept() fmt.Println("accept") if err != nil { Shutdown() log.Fatal("accpet error:", err) } go sockCmdHandle(fd) } Shutdown() }