diff --git a/etc/init.sh b/etc/init.sh index fed74915..cd2bd89e 100644 --- a/etc/init.sh +++ b/etc/init.sh @@ -1,34 +1,13 @@ # @debug on -# ~root aaa -# login root root -# - source etc/lex.sh ~root mdb open chat chat "chat:chat@/chat" mysql ~root aaa +login shy shy login root root -# ~root -# $nserver - -# -# login root 94ca7394d007fa189cc4be0a2625d716 root - -# ~root tcp -# listen ":9393" -# listen ":9394" ~root cli remote slaver listen ":9393" tcp - -# ~aaa -# login shy shy -# userinfo add context hi hello nice -# userinfo add command hi context -# ~web -# listen -# ~demo -# listen -# ~home spawn test +~root aaa diff --git a/src/context/aaa/aaa.go b/src/context/aaa/aaa.go index 15706151..10670d23 100644 --- a/src/context/aaa/aaa.go +++ b/src/context/aaa/aaa.go @@ -7,6 +7,7 @@ import ( // {{{ "crypto/md5" "encoding/hex" "math/rand" + "strconv" "time" "fmt" @@ -27,8 +28,10 @@ func (aaa *AAA) session(meta string) string { // {{{ // }}} -func (aaa *AAA) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { - c.Caches = map[string]*ctx.Cache{} +func (aaa *AAA) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ + c.Caches = map[string]*ctx.Cache{ + "sessid": &ctx.Cache{Name: "会话标识", Value: "", Help: "用户的会话标识"}, + } c.Configs = map[string]*ctx.Config{} s := new(AAA) @@ -36,7 +39,8 @@ func (aaa *AAA) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server return s } -func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { +// }}} +func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ aaa.Caches["group"] = &ctx.Cache{Name: "用户组", Value: m.Conf("rootname"), Help: "用户组"} aaa.Caches["username"] = &ctx.Cache{Name: "用户名", Value: m.Conf("rootname"), Help: "用户名"} aaa.Caches["password"] = &ctx.Cache{Name: "密码", Value: "", Help: "用户密码,加密存储", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string { @@ -46,16 +50,23 @@ func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { return hex.EncodeToString(bs[:]) } else { bs := md5.Sum([]byte(fmt.Sprintln("用户密码:%s", arg[0]))) - if x.Value != hex.EncodeToString(bs[:]) { - m.Assert("error:", "密码错误") - } + m.Assert(x.Value == hex.EncodeToString(bs[:]), "密码错误") } } return x.Value // }}} }} - aaa.Caches["sessid"] = &ctx.Cache{Name: "会话标识", Value: "", Help: "用户的会话标识"} - aaa.Caches["time"] = &ctx.Cache{Name: "登录时间", Value: "", Help: "用户登录时间"} + aaa.Caches["time"] = &ctx.Cache{Name: "登录时间", Value: fmt.Sprintf("%d", time.Now().Unix()), Help: "用户登录时间", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string { + if len(arg) > 0 { // {{{ + return x.Value + } + + n, e := strconv.Atoi(x.Value) + m.Assert(e) + + return time.Unix(int64(n), 0).Format("15:03:04") + // }}} + }} if len(arg) > 0 { m.Cap("username", arg[0]) @@ -64,21 +75,27 @@ func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { if len(arg) > 1 { m.Cap("group", arg[1]) } + m.Capi("nuser", 1) return aaa } -func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { +// }}} +func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { // {{{ return false } -func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { +// }}} +func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { // {{{ + m.Master = Index if m.Cap("username") != m.Conf("rootname") { return true } return false } +// }}} + var Index = &ctx.Context{Name: "aaa", Help: "认证中心", Caches: map[string]*ctx.Cache{ "nuser": &ctx.Cache{Name: "用户数量", Value: "0", Help: "用户数量"}, @@ -87,14 +104,14 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", "rootname": &ctx.Config{Name: "根用户名", Value: "root", Help: "根用户名"}, }, Commands: map[string]*ctx.Command{ - "login": &ctx.Command{Name: "login [sessid]|[[group] username password]]", Help: "", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { - m.Master = m.Target - aaa := m.Target.Server.(*AAA) // {{{ + "login": &ctx.Command{Name: "login [sessid]|[[group] username password]]", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + m.Master = m.Target // {{{ + aaa := m.Target.Server.(*AAA) switch len(arg) { case 0: m.Travel(m.Target, func(m *ctx.Message) bool { - m.Echo("%s(%s): %s\n", m.Target.Name, m.Cap("group"), m.Cap("sessid")) + m.Echo("%s(%s): %s\n", m.Target.Name, m.Cap("group"), m.Cap("time")) return true }) case 1: @@ -125,7 +142,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Cap("sessid", aaa.session(arg[0])) m.Cap("time", fmt.Sprintf("%d", time.Now().Unix())) } else { - m = msg + m.Target = msg.Target } m.Cap("password", arg[1]) diff --git a/src/context/cli/cli.go b/src/context/cli/cli.go index 683d0149..4f0604f1 100644 --- a/src/context/cli/cli.go +++ b/src/context/cli/cli.go @@ -30,6 +30,7 @@ type CLI struct { lex *ctx.Message target *ctx.Context + m *ctx.Message *ctx.Context } @@ -45,37 +46,18 @@ func (cli *CLI) push(f io.ReadCloser) { // {{{ cli.bios = append(cli.bios, cli.bio) } +// }}} +func (cli *CLI) echo(str string, arg ...interface{}) { // {{{ + if len(cli.ins) == 1 || cli.m.Conf("slient") != "yes" { + fmt.Fprintf(cli.out, str, arg...) + } +} + // }}} func (cli *CLI) parse(m *ctx.Message) bool { // {{{ - if false && len(cli.ins) == 1 && cli.Owner == nil { - if msg := m.Spawn(cli.Root).Find("aaa"); msg != nil { - - username := "" - fmt.Fprintf(cli.out, "username>") - fmt.Fscanln(cli.in, &username) - - password := "" - fmt.Fprintf(cli.out, "password>") - fmt.Fscanln(cli.in, &password) - - if msg.Cmd("login", username, password) == "" { - fmt.Fprintln(cli.out, "登录失败") - m.Cmd("exit") - cli.out.Close() - cli.in.Close() - return false - } - - m.Cap("username", msg.Cap("username")) - } - } - - if len(cli.ins) == 1 || m.Conf("slient") != "yes" { - cli.echo(m.Conf("PS1")) - } - line := "" if cli.next == "" { + cli.echo(m.Conf("PS1")) ls, e := cli.bio.ReadString('\n') if e == io.EOF { l := len(cli.ins) @@ -86,116 +68,96 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{ cli.bio = cli.bios[l-2] return true } - // cli.echo("\n%s\n", cli.Conf("结束语")) return false } m.Assert(e) line = ls - if len(cli.ins) > 1 && m.Conf("slient") != "yes" { + if len(cli.ins) > 1 { cli.echo(line) + cli.echo("\n") } if len(line) == 1 { - if len(cli.ins) == 1 { - line = cli.history[len(cli.history)-1]["cli"] - } else { + if len(cli.ins) > 1 { return true } + line = cli.history[len(cli.history)-1]["cli"] } } else { - line = cli.next - cli.next = "" + line, cli.next = cli.next, "" if m.Conf("slient") != "yes" { + cli.echo(m.Conf("PS1")) cli.echo(line) cli.echo("\n") } } -back: - line = strings.TrimSpace(line) if line[0] == '#' { return true } - ls := strings.Split(line, " ") - if cli.lex != nil { - msg := m.Spawn(cli.lex.Target) - msg.Cmd("split", line) - ls = msg.Meta["result"] - for i := 0; i < len(ls); i++ { - if ls[i][0] == '"' { - ls[i] = ls[i][1 : len(ls[i])-1] - } - } - if len(ls) == 0 { - return true - } - } msg := m.Spawn(cli.target) - msg.Wait = make(chan bool) + ls := []string{} + if cli.lex == nil { + ls = strings.Split(line, " ") - r := rune(ls[0][0]) - if !unicode.IsNumber(r) || !unicode.IsLetter(r) || r == '$' || r == '_' { - if _, ok := cli.alias[string(r)]; ok { - msg.Add("detail", ls[0][:1]) - if len(ls[0]) > 1 { - ls[0] = ls[0][1:] - } else { - if len(ls) > 1 { - ls = ls[1:] + r := rune(ls[0][0]) + if !unicode.IsNumber(r) || !unicode.IsLetter(r) || r == '$' || r == '_' { + if _, ok := cli.alias[string(r)]; ok { + if msg.Add("detail", ls[0][:1]); len(ls[0]) > 1 { + ls[0] = ls[0][1:] } else { - ls = nil + ls = ls[1:] } } } - } - for i := 0; i < len(ls); i++ { - if cli.lex == nil { + for i := 0; i < len(ls); i++ { ls[i] = strings.TrimSpace(ls[i]) + if ls[i][0] == '#' { + break + } + if ls[i] != "" { + msg.Add("detail", ls[i]) + } } + } else { + lex := m.Spawn(cli.lex.Target) + m.Assert(lex.Cmd("split", line)) - if ls[i][0] == '#' { - break - } - if ls[i] != "" { + ls = lex.Meta["result"] + for i := 0; i < len(ls); i++ { + if ls[i][0] == '"' && len(ls[i]) > 1 { + ls[i] = ls[i][1 : len(ls[i])-1] + } + if ls[i][0] == '#' { + break + } msg.Add("detail", ls[i]) } } - - ls = msg.Meta["detail"] - if n, e := strconv.Atoi(ls[0]); e == nil && 0 <= n && n < len(cli.history) && ls[0] != cli.history[n]["cli"] { - line = cli.history[n]["cli"] - msg.Meta["detail"] = nil - goto back + if len(ls) == 0 { + return true } + msg.Wait = make(chan bool) msg.Post(cli.Context) - for _, v := range msg.Meta["result"] { - cli.echo(v) - } + m.Capi("nhistory", 1) + cli.echo(strings.Join(msg.Meta["result"], "")) return true } // }}} -func (cli *CLI) echo(str string, arg ...interface{}) { // {{{ - // if len(cli.ins) == 1 || m.Conf("slient") != "yes" { - fmt.Fprintf(cli.out, str, arg...) - // } -} -// }}} - -func (cli *CLI) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { // {{{ +func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} - c.Owner = nil s := new(CLI) s.Context = c return s @@ -204,43 +166,64 @@ func (cli *CLI) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server // }}} func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ cli.Caches["username"] = &ctx.Cache{Name: "登录用户", Value: "", Help: "登录用户名"} - cli.Caches["nhistory"] = &ctx.Cache{Name: "历史命令数量", Value: "0", Help: "当前终端已经执行命令的数量", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string { - x.Value = fmt.Sprintf("%d", len(cli.history)) - return x.Value - }} + cli.Caches["nhistory"] = &ctx.Cache{Name: "历史命令数量", Value: "0", Help: "当前终端已经执行命令的数量"} - cli.Configs["lex"] = &ctx.Config{Name: "屏蔽脚本输出(yes/no)", Value: "", Help: "屏蔽脚本输出的信息,yes:屏蔽,no:不屏蔽", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { - if len(arg) > 0 { - cli, ok := m.Target.Server.(*CLI) - if !ok { - return "" + cli.Configs["slient"] = &ctx.Config{Name: "屏蔽脚本输出(yes/no)", Value: "yes", Help: "屏蔽脚本输出的信息,yes:屏蔽,no:不屏蔽"} + cli.Configs["default"] = &ctx.Config{Name: "默认的搜索起点(root/back/home)", Value: "home", Help: "模块搜索的默认起点,root:从根模块,back:从父模块,home:从当前模块"} + cli.Configs["PS1"] = &ctx.Config{Name: "命令行提示符(target/detail)", Value: "target", Help: "命令行提示符,target:显示当前模块,detail:显示详细信息", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { + if len(arg) > 0 { // {{{ + return arg[0] + } + + ps := make([]string, 0, 3) + + if cli, ok := m.Target.Server.(*CLI); ok && cli.target != nil { + ps = append(ps, m.Cap("nhistory")) + ps = append(ps, "[") + ps = append(ps, time.Now().Format("15:04:05")) + ps = append(ps, "]") + + switch x.Value { + case "detail": + ps = append(ps, "(") + ps = append(ps, m.Cap("ncontext")) + ps = append(ps, ",") + ps = append(ps, m.Cap("nmessage")) + ps = append(ps, ",") + ps = append(ps, m.Cap("nserver")) + ps = append(ps, ")") + case "target": } + ps = append(ps, "\033[32m") + ps = append(ps, cli.target.Name) + ps = append(ps, "\033[0m> ") + + } else { + ps = append(ps, "[") + ps = append(ps, time.Now().Format("15:04:05")) + ps = append(ps, "]") + + ps = append(ps, "\033[32m") + ps = append(ps, x.Value) + ps = append(ps, "\033[0m> ") + } + + return strings.Join(ps, "") + // }}} + }} + cli.Configs["lex"] = &ctx.Config{Name: "词法解析器", Value: "", Help: "命令行词法解析器", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { + if len(arg) > 0 { // {{{ + cli, ok := m.Target.Server.(*CLI) + m.Assert(ok, "模块类型错误") + cli.lex = m.Find(arg[0], m.Target.Root) - if cli.lex == nil { - return "" - } + m.Assert(cli.lex != nil, "词法解析模块不存在") cli.lex.Cmd("train", "[ \n\t]+", "1") + cli.lex.Cmd("train", "#[^\n]*\n", "1", "2") } - return "" - }} - cli.Configs["slient"] = &ctx.Config{Name: "屏蔽脚本输出(yes/no)", Value: "yes", Help: "屏蔽脚本输出的信息,yes:屏蔽,no:不屏蔽"} - cli.Configs["default"] = &ctx.Config{Name: "默认的搜索起点(root/back/home)", Value: "root", Help: "模块搜索的默认起点,root:从根模块,back:从父模块,home:从当前模块"} - cli.Configs["PS1"] = &ctx.Config{Name: "命令行提示符(target/detail)", Value: "target", Help: "命令行提示符,target:显示当前模块,detail:显示详细信息", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { - cli, ok := m.Target.Server.(*CLI) // {{{ - if ok && cli.target != nil { - // c = cli.target - switch x.Value { - case "target": - return fmt.Sprintf("%s[%s]\033[32m%s\033[0m> ", m.Cap("nhistory"), time.Now().Format("15:04:05"), cli.target.Name) - case "detail": - return fmt.Sprintf("%s[%s](%s,%s,%s)\033[32m%s\033[0m> ", m.Cap("nhistory"), time.Now().Format("15:04:05"), m.Cap("ncontext"), m.Cap("nmessage"), m.Cap("nserver"), m.Target.Name) - } - - } - - return fmt.Sprintf("[%s]\033[32m%s\033[0m ", time.Now().Format("15:04:05"), x.Value) + return x.Value // }}} }} @@ -248,6 +231,10 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ cli.Configs["init.sh"] = &ctx.Config{Name: "启动脚本", Value: arg[0], Help: "模块启动时自动运行的脚本"} } + cli.m = m + cli.Owner = nil + cli.Context.Master = cli.Context + cli.target = cli.Context cli.history = make([]map[string]string, 0, 100) cli.alias = map[string]string{ @@ -287,9 +274,28 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ } return true } else { + if msg := m.Find("aaa", m.Target.Root); false && msg != nil { + username := "" + cli.echo("username>") + fmt.Fscanln(cli.in, &username) + + password := "" + cli.echo("password>") + fmt.Fscanln(cli.in, &password) + + if msg.Cmd("login", username, password) == "" { + cli.echo("登录失败") + m.Cmd("exit") + cli.out.Close() + cli.in.Close() + return false + } + + m.Cap("username", msg.Cap("username")) + } + m.Log("info", "%s: slaver terminal", cli.Name) m.Log("info", "%s: open %s", cli.Name, m.Conf("init.sh")) - if f, e := os.Open(m.Conf("init.sh")); e == nil { cli.push(f) } @@ -339,7 +345,7 @@ func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{ m.Log("exit", "%s: release", cli.Name) } - return true + return false } // }}} @@ -352,7 +358,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", Commands: map[string]*ctx.Command{ "context": &ctx.Command{Name: "context [root|back|home] [[find|search] name] [list|show|spawn|start|switch|close][args]", Help: "查找并操作模块,\n查找起点root:根模块、back:父模块、home:本模块,\n查找方法find:路径匹配、search:模糊匹配,\n查找对象name:支持点分和正则,\n操作类型show:显示信息、switch:切换为当前、start:启动模块、spawn:分裂子模块,args:启动参数", Formats: map[string]int{"root": 0, "back": 0, "home": 0, "find": 1, "search": 1, "list": 0, "show": 0, "close": 0, "switch": 0, "start": 0, "spawn": 0}, - Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { cli, ok := m.Source.Server.(*CLI) // {{{ if !ok { cli, ok = c.Server.(*CLI) @@ -362,6 +368,16 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", } target := m.Target + switch cli.m.Conf("default") { + case "home": + target = m.Target + case "root": + target = m.Target.Root + case "back": + if target.Context != nil { + target = m.Target.Context + } + } if m.Has("home") { target = m.Target } @@ -445,7 +461,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", return "" // }}} }}, - "source": &ctx.Command{Name: "source file", Help: "运行脚本", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + "source": &ctx.Command{Name: "source file", Help: "运行脚本", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { cli := c.Server.(*CLI) // {{{ switch len(arg) { case 1: @@ -457,7 +473,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", return "" // }}} }}, - "alias": &ctx.Command{Name: "alias [short [long]]", Help: "查看日志", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + "alias": &ctx.Command{Name: "alias [short [long]]", Help: "查看日志", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { cli := c.Server.(*CLI) // {{{ switch len(arg) { case 0: @@ -479,7 +495,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", return "" // }}} }}, - "history": &ctx.Command{Name: "history number", Help: "查看日志", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + "history": &ctx.Command{Name: "history number", Help: "查看日志", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { cli := c.Server.(*CLI) // {{{ switch len(arg) { case 0: @@ -502,7 +518,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", }}, "remote": &ctx.Command{Name: "remote [send args...]|[[master|slaver] listen|dial address protocol]", Help: "建立远程连接", Formats: map[string]int{"send": -1, "master": 0, "slaver": 0, "listen": 1, "dial": 1}, - Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { if m.Has("send") { // {{{ cli := m.Target.Server.(*CLI) @@ -527,14 +543,14 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", if m.Has("master") { msg.Template = msg.Spawn(msg.Source).Add("option", "master") } - msg.Cmd(action, m.Get(action), m.Get(action), action, m.Get(action)) + msg.Cmd(action, m.Get(action)) return "" }}, // }}} "open": &ctx.Command{Name: "open [master|slaver] [script [log]]", Help: "建立远程连接", Options: map[string]string{"master": "主控终端", "slaver": "被控终端", "args": "启动参数", "io": "读写流"}, - Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { m.Start(fmt.Sprintf("PTS%d", m.Capi("nterm")), "管理终端", arg...) // {{{ return "" // }}} diff --git a/src/context/ctx.go b/src/context/ctx.go index d7bae479..54c42a0b 100644 --- a/src/context/ctx.go +++ b/src/context/ctx.go @@ -37,11 +37,11 @@ type Command struct { Formats map[string]int Options map[string]string Appends map[string]string - Hand func(c *Context, m *Message, key string, arg ...string) string + Hand func(m *Message, c *Context, key string, arg ...string) string } type Server interface { - Spawn(c *Context, m *Message, arg ...string) Server + Spawn(m *Message, c *Context, arg ...string) Server Begin(m *Message, arg ...string) Server Start(m *Message, arg ...string) bool Close(m *Message, arg ...string) bool @@ -68,8 +68,8 @@ type Context struct { Requests []*Message Master *Context - Owner *Context Group string + Owner *Context Index map[string]*Context Groups map[string]*Context } @@ -95,15 +95,27 @@ func (c *Context) Register(s *Context, x Server) *Context { // {{{ // }}} func (c *Context) Spawn(m *Message, name string, help string) *Context { // {{{ - s := &Context{Name: name, Help: help, Context: c, Owner: m.Source.Owner} - m.Log("spawn", "%s: %s", name, help) - m.Target = s - if m.Template != nil { + s := &Context{ + Name: name, + Help: help, + Context: c, + Master: m.Master, + Owner: m.Master.Owner, + } + + if s.Owner != nil { + s.Group = s.Owner.Name + m.Log("spawn", "%s: %s(%s:%s) %s", c.Name, name, s.Group, s.Owner.Name, help) + } else { + m.Log("spawn", "%s: %s %s", c.Name, name, help) + } + + if m.Target = s; m.Template != nil { m.Template.Source = s } if c.Server != nil { - c.Register(s, c.Server.Spawn(s, m, m.Meta["detail"]...)) + c.Register(s, c.Server.Spawn(m, s, m.Meta["detail"]...)) } else { c.Register(s, nil) } @@ -112,7 +124,7 @@ func (c *Context) Spawn(m *Message, name string, help string) *Context { // {{{ // }}} func (c *Context) Begin(m *Message) *Context { // {{{ - m.Log("begin", "%s: %d %v", c.Name, Pulse.Capi("ncontext", 1), m.Meta["detail"]) + m.Log("begin", "%s: %d %v", c.Name, m.Capi("ncontext", 1), m.Meta["detail"]) for k, x := range c.Configs { if x.Hand != nil { m.Conf(k, x.Value) @@ -137,10 +149,12 @@ func (c *Context) Start(m *Message) bool { // {{{ if m.Cap("status") != "start" && c.Server != nil { running := make(chan bool) go m.AssertOne(m, true, func(m *Message) { - m.Log(m.Cap("status", "start"), "%s: %d %v", c.Name, m.Root.Capi("nserver", 1), m.Meta["detail"]) + m.Log(m.Cap("status", "start"), "%s: %d %v", c.Name, m.Capi("nserver", 1), m.Meta["detail"]) running <- true - c.Requests = append(c.Requests, m) + if m != c.Requests[0] { + c.Requests = append(c.Requests, m) + } if c.Server.Start(m, m.Meta["detail"]...) { c.Close(m, m.Meta["detail"]...) } @@ -153,8 +167,8 @@ func (c *Context) Start(m *Message) bool { // {{{ // }}} func (c *Context) Close(m *Message, arg ...string) { // {{{ - if c.Server != nil && c.Server.Close(m, arg...) { - m.Log("close", "%s: %d %v", c.Name, m.Root.Capi("ncontext", -1)+1, arg) + if c.Server == nil || c.Server.Close(m, arg...) { + m.Log("close", "%s: %d %v", c.Name, m.Capi("ncontext", -1)+1, arg) delete(c.Context.contexts, c.Name) } return @@ -415,19 +429,65 @@ func (m *Message) Log(action, str string, arg ...interface{}) { // {{{ } } +// }}} +func (m *Message) Check(s *Context, arg ...string) bool { // {{{ + if s.Owner == nil { + return true + } + if m.Master.Owner == s.Owner { + return true + } + if m.Master.Owner == s.Root.Owner { + return true + } + + g, ok := s.Index[m.Master.Group] + if !ok || g == nil { + if g, ok = s.Index["void"]; !ok || g == nil { + if m.Master.Owner != nil { + m.Log("check", "%s(%s) not auth: %s(%s:%s)", s.Name, s.Owner.Name, m.Master.Name, m.Master.Group, m.Master.Owner.Name) + } else { + m.Log("check", "%s(%s) not auth: %s(void:void)", s.Name, s.Owner.Name, m.Master.Name) + } + return false + } + } + + if len(arg) < 2 { + return true + } + + switch arg[0] { + case "commands": + _, ok = g.Commands[arg[1]] + case "configs": + _, ok = g.Configs[arg[1]] + case "caches": + _, ok = g.Caches[arg[1]] + } + + if !ok { + if m.Master.Owner != nil { + m.Log("check", "%s(%s) %s:%s not auth: %s(%s:%s)", s.Name, s.Owner.Name, arg[0], arg[1], m.Master.Name, m.Master.Group, m.Master.Owner.Name) + } else { + m.Log("check", "%s(%s) %s:%s not auth: %s(void:void)", s.Name, s.Owner.Name, arg[0], arg[1], m.Master.Name) + } + return false + } + + return true +} + // }}} func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ switch e := e.(type) { + case error: case bool: if e { return true } case string: - if e != "error:" { - return true - } - case error: - if e == nil { + if e != "error: " { return true } default: @@ -441,7 +501,7 @@ func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ e = errors.New("error") } - m.Set("result", "error:", fmt.Sprintln(e)) + m.Set("result", "error: ", fmt.Sprintln(e)) panic(e) } @@ -451,8 +511,9 @@ func (m *Message) AssertOne(msg *Message, safe bool, hand ...func(msg *Message)) if e := recover(); e != nil { msg.Log("error", "error: %v", e) if msg.Conf("debug") == "on" && e != io.EOF { - fmt.Println(msg.Target.Name, "error:", e) + fmt.Printf("\n%s error: %v", msg.Target.Name, e) debug.PrintStack() + fmt.Printf("%s error: %v\n", msg.Target.Name, e) } if e == io.EOF { @@ -473,6 +534,7 @@ func (m *Message) AssertOne(msg *Message, safe bool, hand ...func(msg *Message)) } // }}} + func (m *Message) Spawn(c *Context, key ...string) *Message { // {{{ msg := &Message{ Code: m.Capi("nmessage", 1), @@ -498,8 +560,6 @@ func (m *Message) Spawn(c *Context, key ...string) *Message { // {{{ } msg.Source.Sessions[key[0]] = msg msg.Name = key[0] - - m.Log("spawn", "%d: %s.%s->%s.%d", msg.Code, msg.Source.Name, msg.Name, msg.Target.Name, msg.Index) return msg } @@ -511,29 +571,98 @@ func (m *Message) Reply(key ...string) *Message { // {{{ msg := m.Template msg.Time = time.Now() + if len(key) == 0 { return msg } - msg.Code = m.Capi("nmessage", 1) - - if m.Messages == nil { - m.Messages = make([]*Message, 0, 10) - } - m.Messages = append(m.Messages, msg) - if msg.Source.Sessions == nil { msg.Source.Sessions = make(map[string]*Message) } msg.Source.Sessions[key[0]] = msg msg.Name = key[0] - - m.Log("spawn", "%d: %s.%s->%s.%d", msg.Code, msg.Source.Name, msg.Name, msg.Target.Name, msg.Index) return msg } // }}} +func (m *Message) BackTrace(hand func(m *Message) bool) { // {{{ + target := m.Target + for s := target; s != nil; s = s.Context { + if m.Check(s) && !hand(m) { + break + } + } + m.Target = target +} + +// }}} +func (m *Message) Travel(c *Context, hand func(m *Message) bool) { // {{{ + target := m.Target + + cs := []*Context{c} + for i := 0; i < len(cs); i++ { + if m.Target = cs[i]; m.Check(cs[i]) && !hand(m) { + break + } + + for _, v := range cs[i].contexts { + cs = append(cs, v) + } + } + + m.Target = target +} + +// }}} +func (m *Message) Search(key string, begin ...*Context) []*Message { // {{{ + reg, e := regexp.Compile(key) + m.Assert(e) + + target := m.Target + if len(begin) > 0 { + target = begin[0] + } + + cs := make([]*Context, 0, 3) + m.Travel(target, func(m *Message) bool { + if reg.MatchString(m.Target.Name) || reg.FindString(m.Target.Help) != "" { + m.Log("search", "%s: %d match [%s]", m.Target.Name, len(cs)+1, key) + cs = append(cs, m.Target) + } + return true + }) + + ms := make([]*Message, len(cs)) + for i := 0; i < len(cs); i++ { + ms[i] = m.Spawn(cs[i]) + } + + return ms +} + +// }}} +func (m *Message) Find(name string, begin ...*Context) *Message { // {{{ + target := m.Target + if len(begin) > 0 { + target = begin[0] + } + + cs := target.contexts + for _, v := range strings.Split(name, ".") { + if x, ok := cs[v]; ok { + target, cs = x, x.contexts + } else { + m.Log("find", "%s: not find %s", target.Name, v) + return nil + } + } + m.Log("find", "%s: find %s", m.Target.Name, name) + return m.Spawn(target) +} + +// }}} + func (m *Message) Add(meta string, key string, value ...string) *Message { // {{{ if m.Meta == nil { m.Meta = make(map[string][]string) @@ -575,15 +704,15 @@ func (m *Message) Put(meta string, key string, value interface{}) *Message { // if m.Meta == nil { m.Meta = make(map[string][]string) } + if _, ok := m.Meta[meta]; !ok { + m.Meta[meta] = make([]string, 0, 3) + } if m.Data == nil { m.Data = make(map[string]interface{}) } switch meta { case "option", "append": - if _, ok := m.Meta[meta]; !ok { - m.Meta[meta] = make([]string, 0, 3) - } if _, ok := m.Data[key]; !ok { m.Meta[meta] = append(m.Meta[meta], key) } @@ -608,10 +737,8 @@ func (m *Message) Has(key string) bool { // {{{ // }}} func (m *Message) Get(key string) string { // {{{ - if meta, ok := m.Meta[key]; ok { - if len(meta) > 0 { - return meta[0] - } + if meta, ok := m.Meta[key]; ok && len(meta) > 0 { + return meta[0] } return "" } @@ -639,88 +766,6 @@ func (m *Message) End(s bool) { // {{{ // }}} -func (m *Message) BackTrace(hand func(m *Message) bool) { // {{{ - target := m.Target - for cs := target; cs != nil; cs = cs.Context { - if m.Check(cs) && !hand(m) { - break - } - } - m.Target = target -} - -// }}} -func (m *Message) Travel(c *Context, hand func(m *Message) bool) { // {{{ - target := m.Target - - cs := []*Context{c} - for i := 0; i < len(cs); i++ { - if m.Target = cs[i]; m.Check(cs[i]) && !hand(m) { - break - } - - for _, v := range cs[i].contexts { - cs = append(cs, v) - } - } - - m.Target = target -} - -// }}} -func (m *Message) Search(key string, begin ...*Context) []*Message { // {{{ - target := m.Target - if len(begin) > 0 { - target = begin[0] - } - - reg, e := regexp.Compile(key) - m.Assert(e) - - ms := make([]*Message, 0, 3) - m.Travel(target, func(m *Message) bool { - if reg.MatchString(m.Target.Name) || reg.FindString(m.Target.Help) != "" { - m.Log("search", "%s: %d match [%s]", m.Target.Name, len(ms)+1, key) - ms = append(ms, m.Spawn(m.Target)) - } - return true - }) - - for _, v := range ms { - v.Source = m.Target - } - - return ms -} - -// }}} -func (m *Message) Find(name string, begin ...*Context) *Message { // {{{ - target := m.Target - if len(begin) > 0 { - target = begin[0] - } - - cs := target.contexts - for _, v := range strings.Split(name, ".") { - if x, ok := cs[v]; ok { - cs = x.contexts - target = x - } else { - m.Log("find", "%s: not find %s", target.Name, v) - return nil - } - } - m.Log("find", "%s: find %s", m.Target.Name, name) - return m.Spawn(target) -} - -// }}} - -func (m *Message) Start(name string, help string, arg ...string) bool { // {{{ - return m.Set("detail", arg...).Target.Spawn(m, name, help).Begin(m).Start(m) -} - -// }}} func (m *Message) Exec(key string, arg ...string) string { // {{{ cs := []*Context{m.Target, m.Target.Master, m.Source, m.Source.Master} for _, c := range cs { @@ -728,43 +773,38 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{ continue } for s := c; s != nil; s = s.Context { - if x, ok := s.Commands[key]; ok { - if !m.Check(s, "commands", key) { - break - } - - success := false + if x, ok := s.Commands[key]; ok && m.Check(s, "commands", key) { m.AssertOne(m, true, func(m *Message) { m.Log("cmd", "%s: %s %v", s.Name, key, arg) if x.Options != nil { for _, v := range m.Meta["option"] { if _, ok := x.Options[v]; !ok { - panic(errors.New(fmt.Sprintf("未知参数:" + v))) + panic(errors.New(fmt.Sprintf("未知参数: %s", v))) } } } if x.Formats != nil { - for i, args := 0, arg; i < len(args); i++ { - n, ok := x.Formats[args[i]] + for i := 0; i < len(arg); i++ { + n, ok := x.Formats[arg[i]] if !ok { m.Add("option", "args", arg[i]) continue } if n < 0 { - n += len(args) - i + n += len(arg) - i } - m.Add("option", args[i], arg[i+1:i+1+n]...) + m.Add("option", arg[i], arg[i+1:i+1+n]...) i += n } arg = m.Meta["args"] } m.Meta["result"] = nil - ret := x.Hand(c, m, key, arg...) + ret := x.Hand(m, c, key, arg...) if ret != "" { m.Echo(ret) } @@ -772,7 +812,7 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{ if x.Appends != nil { for _, v := range m.Meta["append"] { if _, ok := x.Appends[v]; !ok { - panic(errors.New(fmt.Sprintf("未知参数:" + v))) + panic(errors.New(fmt.Sprintf("未知参数: %s", v))) } } } @@ -781,8 +821,6 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{ c.Requests = make([]*Message, 0, 10) } c.Requests = append(c.Requests, m) - - success = true }) return m.Get("result") @@ -792,14 +830,15 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{ m.AssertOne(m, true, func(m *Message) { m.Log("system", ": %s %v", key, arg) - cmd := exec.Command(key, arg...) - v, e := cmd.CombinedOutput() - if e != nil { - m.Echo("%s\n", e) - } else { + + m.Meta["result"] = nil + if v, e := exec.Command(key, arg...).CombinedOutput(); e == nil { m.Echo(string(v)) + } else { + m.Echo("%s\n", e) } }) + return "" } @@ -820,9 +859,7 @@ func (m *Message) Deal(pre func(msg *Message, arg ...string) bool, post func(msg return false } - m.AssertOne(msg, true, func(msg *Message) { - msg.Exec(msg.Meta["detail"][0], msg.Meta["detail"][1:]...) - }) + msg.Exec(msg.Meta["detail"][0], msg.Meta["detail"][1:]...) if post != nil && !post(msg, msg.Meta["result"]...) { return false @@ -847,72 +884,11 @@ func (m *Message) Post(s *Context) string { // {{{ // }}} -func (m *Message) Check(s *Context, arg ...string) bool { // {{{ - if s.Owner == nil { - return true - } - - if m.Master.Owner == s.Owner { - return true - } - if m.Master.Owner == s.Root.Owner { - return true - } - - g, ok := s.Index[m.Master.Group] - if !ok { - if g, ok = s.Index["void"]; !ok { - if m.Master.Owner != nil { - m.Log("check", "%s(%s:%s) not auth: %s(%s)", m.Master.Name, m.Master.Owner.Name, m.Master.Group, s.Name, s.Owner.Name) - } else { - m.Log("check", "%s() not auth: %s(%s)", m.Master.Name, s.Name, s.Owner.Name) - } - - return false - } - } - - if len(arg) < 2 { - return true - } - - switch arg[0] { - case "commands": - _, ok = g.Commands[arg[1]] - case "configs": - _, ok = g.Configs[arg[1]] - case "caches": - _, ok = g.Caches[arg[1]] - } - - if !ok { - if m.Master.Owner != nil { - m.Log("check", "%s(%s:%s) not auth: %s(%s) %s %s", m.Master.Name, m.Master.Owner.Name, m.Master.Group, s.Name, s.Owner.Name, g.Name, arg[1]) - } else { - m.Log("check", "%s() not auth: %s(%s) %s %s", m.Master.Name, s.Name, s.Owner.Name, g.Name, arg[1]) - } - return false - } - - return true -} - -// }}} - func (m *Message) Cmd(arg ...string) string { // {{{ m.Set("detail", arg...) if s := m.Target.Master; s != nil && s != m.Source.Master { - if s.Messages == nil { - panic(s.Name + " 没有开启消息处理") - } - - s.Messages <- m - if m.Wait != nil { - <-m.Wait - } - - return m.Get("result") + return m.Post(s) } return m.Exec(m.Meta["detail"][0], m.Meta["detail"][1:]...) @@ -920,37 +896,30 @@ func (m *Message) Cmd(arg ...string) string { // {{{ // }}} func (m *Message) Conf(key string, arg ...string) string { // {{{ + var hand func(m *Message, x *Config, arg ...string) string for s := m.Target; s != nil; s = s.Context { if x, ok := s.Configs[key]; ok { - if !m.Check(s, "configs", key) { - panic(errors.New(fmt.Sprintf("没有权限:" + key))) - } + m.Assert(m.Check(s, "configs", key)) switch len(arg) { + case 3: + if hand == nil { + hand = x.Hand + } + case 1: + m.Log("conf", "%s: %s %v", s.Name, key, arg) + + if x.Hand != nil { + x.Value = x.Hand(m, x, arg[0]) + } else { + x.Value = arg[0] + } + return x.Value case 0: if x.Hand != nil { return x.Hand(m, x) } return x.Value - case 1: - m.Log("conf", "%s: %s %v", s.Name, key, arg) - - x.Value = arg[0] - if x.Hand != nil { - x.Hand(m, x, x.Value) - } - return x.Value - case 3: - m.Log("conf", "%s: %s %v", s.Name, key, arg) - - if s == m.Target { - panic(errors.New(key + "配置项已存在")) - } - if m.Target.Configs == nil { - m.Target.Configs = make(map[string]*Config) - } - m.Target.Configs[key] = &Config{Name: arg[0], Value: arg[1], Help: arg[2], Hand: x.Hand} - return arg[1] default: panic(errors.New(key + "配置项参数错误")) } @@ -962,8 +931,8 @@ func (m *Message) Conf(key string, arg ...string) string { // {{{ if m.Target.Configs == nil { m.Target.Configs = make(map[string]*Config) } - m.Target.Configs[key] = &Config{Name: arg[0], Value: arg[1], Help: arg[2]} - return arg[1] + m.Target.Configs[key] = &Config{Name: arg[0], Value: arg[1], Help: arg[2], Hand: hand} + return m.Conf(key, arg[1]) } panic(errors.New(key + "配置项不存在")) @@ -971,31 +940,27 @@ func (m *Message) Conf(key string, arg ...string) string { // {{{ // }}} func (m *Message) Confi(key string, arg ...int) int { // {{{ + n, e := strconv.Atoi(m.Conf(key)) if len(arg) > 0 { - n, e := strconv.Atoi(m.Conf(key, fmt.Sprintf("%d", arg[0]))) - m.Assert(e) - return n + n, e = strconv.Atoi(m.Conf(key, fmt.Sprintf("%d", arg[0]))) } - n, e := strconv.Atoi(m.Conf(key)) m.Assert(e) return n } // }}} func (m *Message) Cap(key string, arg ...string) string { // {{{ + var hand func(m *Message, x *Cache, arg ...string) string for s := m.Target; s != nil; s = s.Context { if x, ok := s.Caches[key]; ok { - if !m.Check(s, "caches", key) { - panic(errors.New(fmt.Sprintf("没有权限:" + key))) - } + m.Assert(m.Check(s, "caches", key)) switch len(arg) { - case 0: - if x.Hand != nil { - x.Value = x.Hand(m, x) + case 3: + if hand == nil { + hand = x.Hand } - return x.Value case 1: if x.Hand != nil { x.Value = x.Hand(m, x, arg[0]) @@ -1003,28 +968,24 @@ func (m *Message) Cap(key string, arg ...string) string { // {{{ x.Value = arg[0] } return x.Value - case 3: - m.Log("cap", "%s: %s %v", m.Target.Name, key, arg) - if s == m.Target { - panic(errors.New(key + "缓存项已存在")) + case 0: + if x.Hand != nil { + return x.Hand(m, x) } - if m.Target.Caches == nil { - m.Target.Caches = make(map[string]*Cache) - } - m.Target.Caches[key] = &Cache{arg[0], arg[1], arg[2], x.Hand} - return arg[1] + return x.Value default: panic(errors.New(key + "缓存项参数错误")) } } } + if len(arg) == 3 { m.Log("cap", "%s: %s %v", m.Target.Name, key, arg) if m.Target.Caches == nil { m.Target.Caches = make(map[string]*Cache) } - m.Target.Caches[key] = &Cache{arg[0], arg[1], arg[2], nil} - return arg[1] + m.Target.Caches[key] = &Cache{Name: arg[0], Value: arg[1], Help: arg[2], Hand: hand} + return m.Cap(key, arg[1]) } panic(errors.New(key + "缓存项不存在")) @@ -1033,16 +994,22 @@ func (m *Message) Cap(key string, arg ...string) string { // {{{ // }}} func (m *Message) Capi(key string, arg ...int) int { // {{{ n, e := strconv.Atoi(m.Cap(key)) - m.Assert(e) if len(arg) > 0 { - n += arg[0] - m.Cap(key, strconv.Itoa(n)) + n, e = strconv.Atoi(m.Cap(key, fmt.Sprintf("%d", arg[0]+n))) } + + m.Assert(e) return n } // }}} +func (m *Message) Start(name string, help string, arg ...string) bool { // {{{ + return m.Set("detail", arg...).Target.Spawn(m, name, help).Begin(m).Start(m) +} + +// }}} + var Index = &Context{Name: "ctx", Help: "根模块", Caches: map[string]*Cache{ "nserver": &Cache{Name: "服务数量", Value: "0", Help: "显示已经启动运行模块的数量"}, @@ -1097,7 +1064,7 @@ var Index = &Context{Name: "ctx", Help: "根模块", Commands: map[string]*Command{ "userinfo": &Command{Name: "userinfo [add|del [context key name help]|[command|config|cache group name]]", Help: "查看模块的用户信息", Formats: map[string]int{"add": -1, "del": -1}, - Hand: func(c *Context, m *Message, key string, arg ...string) string { + Hand: func(m *Message, c *Context, key string, arg ...string) string { switch { // {{{ case m.Has("add"): m.Target.Add(m.Source.Group, m.Meta["add"]...) @@ -1133,7 +1100,7 @@ var Index = &Context{Name: "ctx", Help: "根模块", return "" // }}} }}, - "server": &Command{Name: "server [start|exit|switch][args]", Help: "服务启动停止切换", Hand: func(c *Context, m *Message, key string, arg ...string) string { + "server": &Command{Name: "server [start|exit|switch][args]", Help: "服务启动停止切换", Hand: func(m *Message, c *Context, key string, arg ...string) string { switch len(arg) { // {{{ case 0: m.Travel(m.Target.Root, func(m *Message) bool { @@ -1155,7 +1122,7 @@ var Index = &Context{Name: "ctx", Help: "根模块", return "" // }}} }}, - "message": &Command{Name: "message [index|home] [order]", Help: "查看消息", Hand: func(c *Context, m *Message, key string, arg ...string) string { + "message": &Command{Name: "message [index|home] [order]", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) string { switch len(arg) { // {{{ case 0: for k, v := range m.Target.Sessions { @@ -1223,7 +1190,7 @@ var Index = &Context{Name: "ctx", Help: "根模块", return "" // }}} }}, - "command": &Command{Name: "command [all] [key [name help]]", Help: "查看或修改命令", Hand: func(c *Context, m *Message, key string, arg ...string) string { + "command": &Command{Name: "command [all] [key [name help]]", Help: "查看或修改命令", Hand: func(m *Message, c *Context, key string, arg ...string) string { all := false // {{{ if len(arg) > 0 && arg[0] == "all" { arg = arg[1:] @@ -1261,7 +1228,7 @@ var Index = &Context{Name: "ctx", Help: "根模块", }}, "config": &Command{Name: "config [all] [[delete|void] key [value]|[name value help]]", Help: "删除、空值、查看、修改或添加配置", Formats: map[string]int{"all": 0, "delete": 0, "void": 0}, - Hand: func(c *Context, m *Message, key string, arg ...string) string { + Hand: func(m *Message, c *Context, key string, arg ...string) string { all := m.Has("all") // {{{ switch len(arg) { @@ -1315,7 +1282,7 @@ var Index = &Context{Name: "ctx", Help: "根模块", return "" // }}} }}, - "cache": &Command{Name: "cache [all] [[delete] key [value]|[name value help]]", Help: "删除、查看、修改或添加配置", Hand: func(c *Context, m *Message, key string, arg ...string) string { + "cache": &Command{Name: "cache [all] [[delete] key [value]|[name value help]]", Help: "删除、查看、修改或添加配置", Hand: func(m *Message, c *Context, key string, arg ...string) string { all := false // {{{ if len(arg) > 0 && arg[0] == "all" { arg = arg[1:] diff --git a/src/context/mdb/mdb.go b/src/context/mdb/mdb.go index 642469d2..58ba75eb 100644 --- a/src/context/mdb/mdb.go +++ b/src/context/mdb/mdb.go @@ -16,7 +16,7 @@ type MDB struct { *ctx.Context } -func (mdb *MDB) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { // {{{ +func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ c.Caches = map[string]*ctx.Cache{ "source": &ctx.Cache{Name: "数据库参数", Value: "", Help: "数据库参数"}, "driver": &ctx.Cache{Name: "数据库驱动", Value: "", Help: "数据库驱动"}, @@ -87,15 +87,15 @@ var Index = &ctx.Context{Name: "mdb", Help: "内存数据库", "driver": &ctx.Config{Name: "数据库驱动(mysql)", Value: "mysql", Help: "数据库驱动"}, }, Commands: map[string]*ctx.Command{ - "open": &ctx.Command{Name: "open name help [source [driver]]", Help: "打开数据库", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { - m.Target = m.Master // {{{ + "open": &ctx.Command{Name: "open name help [source [driver]]", Help: "打开数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + m.Master = m.Target // {{{ m.Start(arg[0], arg[1], arg[2:]...) return "" // }}} }}, "exec": &ctx.Command{Name: "exec sql [arg]", Help: "执行操作语句", Appends: map[string]string{"LastInsertId": "最后插入元组的标识", "RowsAffected": "修改元组的数量"}, - Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { mdb, ok := m.Target.Server.(*MDB) // {{{ m.Assert(ok, "目标模块类型错误") m.Assert(len(arg) > 0, "缺少参数") @@ -119,7 +119,7 @@ var Index = &ctx.Context{Name: "mdb", Help: "内存数据库", return "" // }}} }}, - "query": &ctx.Command{Name: "query sql [arg]", Help: "执行查询语句", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + "query": &ctx.Command{Name: "query sql [arg]", Help: "执行查询语句", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { mdb, ok := m.Target.Server.(*MDB) // {{{ m.Assert(ok, "目标模块类型错误") m.Assert(len(arg) > 0, "缺少参数") @@ -162,9 +162,13 @@ var Index = &ctx.Context{Name: "mdb", Help: "内存数据库", return "" // }}} }}, - "close": &ctx.Command{Name: "close name", Help: "关闭数据库", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { - msg := m.Find(arg[0], m.Master) // {{{ - msg.Target.Close(msg) + "close": &ctx.Command{Name: "close [name]", Help: "关闭数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + if len(arg) > 0 { // {{{ + msg := m.Find(arg[0], m.Master) + msg.Target.Close(msg) + } else { + m.Target.Close(m) + } return "" // }}} }}, diff --git a/src/context/ssh/ssh.go b/src/context/ssh/ssh.go index 2d5b1a86..28d9b3fa 100644 --- a/src/context/ssh/ssh.go +++ b/src/context/ssh/ssh.go @@ -17,7 +17,7 @@ func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool { return true } -func (ssh *SSH) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { +func (ssh *SSH) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} c.Commands = map[string]*ctx.Command{} diff --git a/src/context/tcp/tcp.go b/src/context/tcp/tcp.go index 2b9b2187..ab74b3e8 100644 --- a/src/context/tcp/tcp.go +++ b/src/context/tcp/tcp.go @@ -16,7 +16,7 @@ type TCP struct { *ctx.Context } -func (tcp *TCP) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { // {{{ +func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ c.Caches = map[string]*ctx.Cache{ "protocol": &ctx.Cache{Name: "protocol(tcp/tcp4/tcp6)", Value: m.Conf("protocol"), Help: "监听地址"}, "security": &ctx.Cache{Name: "security(true/false)", Value: m.Conf("security"), Help: "加密通信"}, @@ -106,7 +106,7 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接", "security": &ctx.Config{Name: "security(true/false)", Value: "false", Help: "加密通信"}, }, Commands: map[string]*ctx.Command{ - "listen": &ctx.Command{Name: "listen [address [security]]", Help: "监听连接", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + "listen": &ctx.Command{Name: "listen [address [security]]", Help: "监听连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { switch len(arg) { // {{{ case 0: m.Travel(m.Target, func(m *ctx.Message) bool { @@ -121,7 +121,7 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接", return "" // }}} }}, - "dial": &ctx.Command{Name: "dial [address [security]]", Help: "建立连接", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + "dial": &ctx.Command{Name: "dial [address [security]]", Help: "建立连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { switch len(arg) { // {{{ case 0: m.Travel(m.Target, func(m *ctx.Message) bool { @@ -136,14 +136,14 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络连接", return "" // }}} }}, - "send": &ctx.Command{Name: "send message", Help: "发送消息", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + "send": &ctx.Command{Name: "send message", Help: "发送消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { if tcp, ok := m.Target.Server.(*TCP); ok && tcp.Conn != nil { // {{{ tcp.Conn.Write([]byte(arg[0])) } return "" // }}} }}, - "recv": &ctx.Command{Name: "recv size", Help: "接收消息", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string { + "recv": &ctx.Command{Name: "recv size", Help: "接收消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { if tcp, ok := m.Target.Server.(*TCP); ok && tcp.Conn != nil { // {{{ size, e := strconv.Atoi(arg[0]) m.Assert(e)