diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 57432dcf..2d58f592 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -199,7 +199,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", return fmt.Sprintf("%s%d", x.Value, m.Capi("nshell", 1)) // }}} }}, - "cli_help": &ctx.Config{Name: "cli_help", Value: "shell", Help: "模块文档"}, + "cli_help": &ctx.Config{Name: "cli_help", Value: "shell", Help: "模块文档"}, + "cmd_timeout": &ctx.Config{Name: "cmd_timeout", Value: "3s", Help: "系统命令超时"}, "time_format": &ctx.Config{Name: "time_format", Value: "2006-01-02 15:04:05", Help: "时间格式"}, "time_unit": &ctx.Config{Name: "time_unit", Value: "1000", Help: "时间倍数"}, @@ -672,7 +673,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", "cmd": &ctx.Command{Name: "cmd word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if cli, ok := m.Target().Server.(*CLI); m.Assert(ok) { // {{{ detail := []string{} - if a, ok := cli.alias[arg[0]]; ok { detail = append(detail, a...) detail = append(detail, arg[1:]...) @@ -688,10 +688,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", }() } - routes := strings.Split(detail[0], ".") msg := m - if len(routes) > 1 { - + if routes := strings.Split(detail[0], "."); len(routes) > 1 { route := strings.Join(routes[:len(routes)-1], ".") if msg = m.Find(route, false); msg == nil { msg = m.Find(route, true) @@ -704,64 +702,62 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", detail[0] = routes[len(routes)-1] } else { msg = m.Spawn(cli.target) - } - m.Capi("ps_count", 1) - m.Capi("last_msg", 0, msg.Code()) if msg.Cmd(detail); msg.Hand { cli.target = msg.Target() m.Cap("ps_target", cli.target.Name) } else { - msg.Hand = true - msg.Log("system", "%v", msg.Meta["detail"]) - - msg.Set("result").Set("append") - c := exec.Command(msg.Meta["detail"][0], msg.Meta["detail"][1:]...) - - if false { - c.Stdin, c.Stdout, c.Stderr = os.Stdin, os.Stdout, os.Stderr - if e := c.Start(); e != nil { - msg.Echo("error: ") - msg.Echo("%s\n", e) - } else if e := c.Wait(); e != nil { - msg.Echo("error: ") - m.Echo("%s\n", e) - } - } else { - if out, e := c.CombinedOutput(); e != nil { - msg.Echo("error: ") - msg.Echo("%s\n", e) - } else { - msg.Echo(string(out)) - } - } + msg.Copy(m, "target").Detail(-1, "system") + msg.Cmd() } m.Copy(msg, "result").Copy(msg, "append") + m.Capi("last_msg", 0, msg.Code()) + m.Capi("ps_count", 1) } // }}} }}, - "system": &ctx.Command{Name: "system word", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - cmd := exec.Command(arg[0], arg[1:]...) + "system": &ctx.Command{ + Name: "system [cmd_combine true|false] [cmd_timeout time] word...", + Help: "调用系统命令, cmd_combine: 非交互式命令, cmd_timeout: 命令超时, word: 命令", + Form: map[string]int{"cmd_combine": 1, "cmd_timeout": 1}, + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + system := map[string]bool{"vi": true} // {{{ + ui, ok := system[arg[0]] + if ui = ok && ui; m.Option("cmd_combine") != "" { + ui = !m.Options("cmd_combine") + } - if false { - cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr - if e := cmd.Start(); e != nil { - m.Echo("error: ") - m.Echo("%s\n", e) - } else if e := cmd.Wait(); e != nil { - m.Echo("error: ") - m.Echo("%s\n", e) - } - } else { - if out, e := cmd.CombinedOutput(); e != nil { - m.Echo("error: ") - m.Echo("%s\n", e) + if cmd := exec.Command(arg[0], arg[1:]...); ui { + cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr + if e := cmd.Start(); e != nil { + m.Echo("error: ").Echo("%s\n", e) + } else if e := cmd.Wait(); e != nil { + m.Echo("error: ").Echo("%s\n", e) + } } else { - m.Echo(string(out)) + wait := make(chan bool, 1) + go func() { + if out, e := cmd.CombinedOutput(); e != nil { + m.Echo("error: ").Echo("%s\n", e) + } else { + m.Echo(string(out)) + } + wait <- true + }() + + d, e := time.ParseDuration(m.Confx("cmd_timeout")) + m.Assert(e) + + select { + case <-time.After(d): + cmd.Process.Kill() + m.Echo("%s: timeout", arg[0]) + case <-wait: + } } - } - }}, + // }}} + }}, "login": &ctx.Command{Name: "login username password", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { m.Sess("aaa", false).Cmd("login", arg[0], arg[1]) }}, diff --git a/src/contexts/tcp/tcp.go b/src/contexts/tcp/tcp.go index 27350b7d..643d0154 100644 --- a/src/contexts/tcp/tcp.go +++ b/src/contexts/tcp/tcp.go @@ -7,6 +7,7 @@ import ( // {{{ "fmt" "net" "strconv" + "strings" ) // }}} @@ -22,6 +23,8 @@ func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server "protocol": &ctx.Cache{Name: "网络协议(tcp/tcp4/tcp6)", Value: m.Conf("protocol"), Help: "网络协议"}, "security": &ctx.Cache{Name: "加密通信(true/false)", Value: m.Conf("security"), Help: "加密通信"}, "address": &ctx.Cache{Name: "网络地址", Value: "", Help: "网络地址"}, + "nrecv": &ctx.Cache{Name: "nrecv", Value: "0", Help: "网络地址"}, + "nsend": &ctx.Cache{Name: "nsend", Value: "0", Help: "网络地址"}, } c.Configs = map[string]*ctx.Config{} @@ -32,23 +35,14 @@ func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server // }}} func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ - if tcp.Context == Index { - Pulse = m - } return tcp } // }}} func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ - if len(arg) > 1 { - m.Cap("address", arg[1]) - } - if len(arg) > 2 { - m.Cap("security", arg[2]) - } - if len(arg) > 3 { - m.Cap("protocol", arg[3]) - } + m.Cap("address", m.Confx("address", arg, 1)) + m.Cap("security", m.Confx("security", arg, 2)) + m.Cap("protocol", m.Confx("protocol", arg, 3)) switch arg[0] { case "dial": @@ -66,7 +60,7 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ tcp.Conn = c } - m.Log("info", "%s dial %s", Pulse.Cap("nclient"), + m.Log("info", "%s dial %s", m.Cap("nclient"), m.Append("stream", m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), tcp.RemoteAddr())))) m.Put("append", "io", tcp.Conn).Back(m) return false @@ -75,7 +69,7 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ m.Assert(e) tcp.Conn = c - m.Log("info", "%s accept %s", Pulse.Cap("nclient"), + m.Log("info", "%s accept %s", m.Cap("nclient"), m.Append("stream", m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr())))) m.Put("append", "io", tcp.Conn).Back(m) return false @@ -94,7 +88,7 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ tcp.Listener = l } - m.Log("info", "%d listen %v", Pulse.Capi("nlisten"), m.Cap("stream", fmt.Sprintf("%s", tcp.Addr()))) + m.Log("info", "%d listen %v", m.Capi("nlisten"), m.Cap("stream", fmt.Sprintf("%s", tcp.Addr()))) } for { @@ -111,15 +105,16 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ // }}} func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool { // {{{ + return false switch tcp.Context { case m.Target(): if tcp.Listener != nil { - m.Log("info", "%d close %v", Pulse.Capi("nlisten", -1)+1, m.Cap("stream")) + m.Log("info", "%d close %v", m.Capi("nlisten", -1)+1, m.Cap("stream")) tcp.Listener.Close() tcp.Listener = nil } if tcp.Conn != nil { - m.Log("info", "%d close %v", Pulse.Capi("nclient", -1)+1, m.Cap("stream")) + m.Log("info", "%d close %v", m.Capi("nclient", -1)+1, m.Cap("stream")) tcp.Conn.Close() tcp.Conn = nil } @@ -139,45 +134,50 @@ func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool { // {{{ // }}} -var Pulse *ctx.Message var Index = &ctx.Context{Name: "tcp", Help: "网络中心", Caches: map[string]*ctx.Cache{ - "nlisten": &ctx.Cache{Name: "监听数量", Value: "0", Help: "监听数量"}, - "nclient": &ctx.Cache{Name: "连接数量", Value: "0", Help: "连接数量"}, + "nlisten": &ctx.Cache{Name: "nlisten", Value: "0", Help: "监听数量"}, + "nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"}, }, Configs: map[string]*ctx.Config{ - "security": &ctx.Config{Name: "加密通信(true/false)", Value: "false", Help: "加密通信"}, - "protocol": &ctx.Config{Name: "网络协议(tcp/tcp4/tcp6)", Value: "tcp4", Help: "网络协议"}, + "address": &ctx.Config{Name: "address", Value: ":9090", Help: "加密通信"}, + "security": &ctx.Config{Name: "security(true/false)", Value: "false", Help: "加密通信"}, + "protocol": &ctx.Config{Name: "protocol(tcp/tcp4/tcp6)", Value: "tcp4", Help: "网络协议"}, }, Commands: map[string]*ctx.Command{ "listen": &ctx.Command{Name: "listen address [security [protocol]]", Help: "网络监听", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Start(fmt.Sprintf("pub%d", Pulse.Capi("nlisten", 1)), "网络监听", m.Meta["detail"]...) + m.Start(fmt.Sprintf("pub%d", m.Capi("nlisten", 1)), "网络监听", m.Meta["detail"]...) }}, "accept": &ctx.Command{Name: "accept address [security [protocol]]", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Start(fmt.Sprintf("com%d", Pulse.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...) + m.Start(fmt.Sprintf("com%d", m.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...) }}, "dial": &ctx.Command{Name: "dial address [security [protocol]]", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Start(fmt.Sprintf("com%d", Pulse.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...) + m.Start(fmt.Sprintf("com%d", m.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...) }}, "send": &ctx.Command{Name: "send message", Help: "发送消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - tcp, ok := m.Target().Server.(*TCP) - m.Assert(ok && tcp.Conn != nil) - tcp.Conn.Write([]byte(arg[0])) + if tcp, ok := m.Target().Server.(*TCP); m.Assert(ok) && tcp.Conn != nil { + tcp.Conn.Write([]byte(arg[0])) + m.Capi("nsend", len(arg[0])) + } }}, "recv": &ctx.Command{Name: "recv size", Help: "接收消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - tcp, ok := m.Target().Server.(*TCP) - m.Assert(ok && tcp.Conn != nil) - size, e := strconv.Atoi(arg[0]) - m.Assert(e) + if tcp, ok := m.Target().Server.(*TCP); m.Assert(ok) && tcp.Conn != nil { + size, e := strconv.Atoi(arg[0]) + m.Assert(e) - buf := make([]byte, size) - tcp.Conn.Read(buf) - m.Echo(string(buf)) + buf := make([]byte, size) + n, e := tcp.Conn.Read(buf) + m.Assert(e) + buf = buf[:n] + + m.Echo(string(buf)) + m.Capi("nrecv", n) + } }}, "ifconfig": &ctx.Command{Name: "ifconfig", Help: "接收消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { @@ -187,9 +187,26 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络中心", ips, e := v.Addrs() m.Assert(e) for _, x := range ips { - m.Echo("%d %s %v %v\n", v.Index, v.Name, v.HardwareAddr, x.String()) + ip := x.String() + if !strings.Contains(ip, ":") && len(ip) > 0 && len(v.HardwareAddr) > 0 { + m.Add("append", "index", v.Index) + m.Add("append", "name", v.Name) + m.Add("append", "hard", v.HardwareAddr) + m.Add("append", "ip", ip) + } } } + + m.Table(func(maps map[string]string, list []string, line int) bool { + for i, v := range list { + m.Echo("%s", v) + if i < len(list)-1 { + m.Echo("\t") + } + } + m.Echo("\n") + return true + }) }}, }, Index: map[string]*ctx.Context{