From d6a85730a2adf85ac7fa5a57da8da55b8fffc92a Mon Sep 17 00:00:00 2001 From: shaoying Date: Fri, 8 Dec 2017 08:45:26 +0800 Subject: [PATCH 1/2] =?UTF-8?q?mac=20pro=20lex&aaa=20=E6=95=B4=E7=90=86?= =?UTF-8?q?=E4=BA=86=E8=AF=8D=E6=B3=95=E8=A7=A3=E6=9E=90=E5=92=8C=E8=AE=A4?= =?UTF-8?q?=E8=AF=81=E4=B8=AD=E5=BF=83=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- etc/init.sh | 12 +++- etc/lex.sh | 18 ++--- src/context/cli/cli.go | 145 +++++++++++++++++++++++------------------ src/context/ctx.go | 7 +- 4 files changed, 100 insertions(+), 82 deletions(-) diff --git a/etc/init.sh b/etc/init.sh index cd2bd89e..a3950cdf 100644 --- a/etc/init.sh +++ b/etc/init.sh @@ -1,12 +1,18 @@ # @debug on +~lex start source etc/lex.sh +~cli @lex lex -~root mdb +~mdb open chat chat "chat:chat@/chat" mysql +~chat +query "select * from userinfo" -~root aaa -login shy shy +return +~aaa login root root +login shy shy + ~root cli remote slaver listen ":9393" tcp diff --git a/etc/lex.sh b/etc/lex.sh index 4e927176..c8aef5ed 100644 --- a/etc/lex.sh +++ b/etc/lex.sh @@ -1,12 +1,6 @@ -~root lex -server start -train [a-zA-Z][a-zA-Z0-9]* 2 2 -train 0x[0-9]+ 3 2 -train [0-9]+ 3 2 -train "[^"]*" 4 2 -train '[^']*' 4 2 -train [~!@#$&*:] 4 2 - -~root cli -@lex lex - +train [a-zA-Z][a-zA-Z0-9]* +train 0x[0-9]+ +train [0-9]+ +train "[^"]*" +train '[^']*' +train [~!@#$&*:] diff --git a/src/context/cli/cli.go b/src/context/cli/cli.go index 4f0604f1..92486f82 100644 --- a/src/context/cli/cli.go +++ b/src/context/cli/cli.go @@ -1,8 +1,9 @@ package cli // {{{ // }}} import ( // {{{ - "bufio" "context" + + "bufio" "fmt" "io" "os" @@ -29,6 +30,7 @@ type CLI struct { login *ctx.Context lex *ctx.Message + temp *ctx.Context target *ctx.Context m *ctx.Message *ctx.Context @@ -95,52 +97,56 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{ } line = strings.TrimSpace(line) - if line[0] == '#' { + if len(line) == 0 || line[0] == '#' { + return true + } + + ls := []string{} + if cli.lex == nil { + ls = strings.Split(line, " ") + } else { + lex := m.Spawn(cli.lex.Target) + m.Assert(lex.Cmd("split", line, "void")) + + ls = lex.Meta["result"] + } + + if len(ls) == 0 { return true } msg := m.Spawn(cli.target) - ls := []string{} - if cli.lex == nil { - ls = strings.Split(line, " ") + if cli.temp != nil { + msg.Target, cli.temp = cli.temp, nil + } - 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:] + for i := 0; i < len(ls); i++ { + ls[i] = strings.TrimSpace(ls[i]) + if ls[i] == "" { + continue + } + if ls[i][0] == '#' { + break + } + + if cli.lex != nil && len(ls[i]) > 1 { + switch ls[i][0] { + case '"', '\'': + ls[i] = ls[i][1 : len(ls[i])-1] + } + } + + if r := rune(ls[i][0]); r == '$' || r == '_' || (!unicode.IsNumber(r) && !unicode.IsLetter(r)) { + if c, ok := cli.alias[string(r)]; ok { + if msg.Add("detail", c); len(ls[i]) > 1 { + ls[i] = ls[i][1:] } else { - ls = ls[1:] + continue } } } - 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)) - - 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]) - } - } - if len(ls) == 0 { - return true + msg.Add("detail", ls[i]) } msg.Wait = make(chan bool) @@ -158,6 +164,8 @@ 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{} + cli.Owner = nil + s := new(CLI) s.Context = c return s @@ -169,7 +177,7 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ cli.Caches["nhistory"] = &ctx.Cache{Name: "历史命令数量", Value: "0", Help: "当前终端已经执行命令的数量"} 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["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 { if len(arg) > 0 { // {{{ return arg[0] @@ -220,8 +228,8 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ cli.lex = m.Find(arg[0], m.Target.Root) m.Assert(cli.lex != nil, "词法解析模块不存在") - cli.lex.Cmd("train", "[ \n\t]+", "1") - cli.lex.Cmd("train", "#[^\n]*\n", "1", "2") + cli.lex.Cmd("train", "[ \n\t]+", "void", "void") + cli.lex.Cmd("train", "#[^\n]*\n", "void", "void") } return x.Value // }}} @@ -232,7 +240,6 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ } cli.m = m - cli.Owner = nil cli.Context.Master = cli.Context cli.target = cli.Context @@ -274,24 +281,26 @@ 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) + if cli.Owner == nil { + if msg := m.Find("aaa", m.Target.Root); msg != nil { + username := "" + cli.echo("username>") + fmt.Fscanln(cli.in, &username) - password := "" - cli.echo("password>") - fmt.Fscanln(cli.in, &password) + 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 + 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.Cap("username", msg.Cap("username")) } m.Log("info", "%s: slaver terminal", cli.Name) @@ -307,13 +316,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{ } } - for m.Deal(func(msg *ctx.Message, arg ...string) bool { - if a, ok := cli.alias[arg[0]]; ok { - arg[0] = a - } - return true - - }, func(msg *ctx.Message, arg ...string) bool { + for m.Deal(nil, func(msg *ctx.Message, arg ...string) bool { cli.history = append(cli.history, map[string]string{ "time": time.Now().Format("15:04:05"), "index": fmt.Sprintf("%d", len(cli.history)), @@ -416,6 +419,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", cli.target = v.Target case m.Has("start"): v.Set("detail", arg...).Target.Start(v) + cli.target = v.Target case m.Has("switch"): cli.target = v.Target case m.Has("close"): @@ -437,7 +441,10 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", m.Echo(" %s(%d): -> %s %v\n", k, v.Code, v.Target.Name, v.Meta["detail"]) } } - case m.Has("list") || cli.target == v.Target: + case m.Has("list") || len(m.Meta["detail"]) == 1 || (len(arg) == 0 && cli.target == v.Target): + if len(m.Meta["detail"]) == 1 { + v.Target = cli.target + } m.Travel(v.Target, func(msg *ctx.Message) bool { if msg.Target.Context != nil { target := msg.Target @@ -453,6 +460,9 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", } return true }) + case len(arg) > 0: + cli.next = strings.Join(arg, " ") + cli.temp = v.Target default: cli.target = v.Target return "" @@ -473,6 +483,12 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", return "" // }}} }}, + "return": &ctx.Command{Name: "return", Help: "运行脚本", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string { + cli := c.Server.(*CLI) // {{{ + cli.bio.Discard(cli.bio.Buffered()) + return "" + // }}} + }}, "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) { @@ -555,7 +571,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端", return "" // }}} }}, - "void": &ctx.Command{Name: "", Help: "", Hand: nil}, }, Messages: make(chan *ctx.Message, 10), Index: map[string]*ctx.Context{ diff --git a/src/context/ctx.go b/src/context/ctx.go index 54c42a0b..68dcd973 100644 --- a/src/context/ctx.go +++ b/src/context/ctx.go @@ -131,6 +131,7 @@ func (c *Context) Begin(m *Message) *Context { // {{{ } } + c.Owner = m.Master.Owner c.Requests = []*Message{m} if c.Server != nil { @@ -513,7 +514,7 @@ func (m *Message) AssertOne(msg *Message, safe bool, hand ...func(msg *Message)) if msg.Conf("debug") == "on" && e != io.EOF { fmt.Printf("\n%s error: %v", msg.Target.Name, e) debug.PrintStack() - fmt.Printf("%s error: %v\n", msg.Target.Name, e) + fmt.Printf("%s error: %v\n\n", msg.Target.Name, e) } if e == io.EOF { @@ -804,7 +805,7 @@ func (m *Message) Exec(key string, arg ...string) string { // {{{ } m.Meta["result"] = nil - ret := x.Hand(m, c, key, arg...) + ret := x.Hand(m, s, key, arg...) if ret != "" { m.Echo(ret) } @@ -1113,6 +1114,7 @@ var Index = &Context{Name: "ctx", Help: "根模块", default: switch arg[0] { case "start": + m.Meta = nil m.Set("detail", arg[1:]...).Target.Start(m) case "stop": m.Set("detail", arg[1:]...).Target.Close(m) @@ -1373,6 +1375,7 @@ func Start(args ...string) { Pulse.Conf("root", args[3]) } + Index.Owner = Index.contexts["aaa"] for _, m := range Pulse.Search("") { m.Target.Begin(m) } From 7d5942bd42e2267f096b2be40f43086f3ef3a8f7 Mon Sep 17 00:00:00 2001 From: shaoying Date: Fri, 8 Dec 2017 08:48:21 +0800 Subject: [PATCH 2/2] mac syn 0.2.0 --- src/context/aaa/aaa.go | 117 ++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 66 deletions(-) diff --git a/src/context/aaa/aaa.go b/src/context/aaa/aaa.go index 10670d23..82de6024 100644 --- a/src/context/aaa/aaa.go +++ b/src/context/aaa/aaa.go @@ -2,15 +2,14 @@ package aaa // {{{ // }}} import ( // {{{ "context" - _ "context/cli" "crypto/md5" "encoding/hex" "math/rand" - "strconv" - "time" "fmt" + "strconv" + "time" ) // }}} @@ -29,9 +28,7 @@ func (aaa *AAA) session(meta string) string { // {{{ // }}} 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.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} s := new(AAA) @@ -41,21 +38,21 @@ func (aaa *AAA) Spawn(m *ctx.Message, c *ctx.Context, 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["group"] = &ctx.Cache{Name: "用户组", Value: "", Help: "用户组"} + aaa.Caches["username"] = &ctx.Cache{Name: "用户名", Value: "", Help: "用户名"} aaa.Caches["password"] = &ctx.Cache{Name: "密码", Value: "", Help: "用户密码,加密存储", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string { if len(arg) > 0 { // {{{ - if x.Value == "" { - bs := md5.Sum([]byte(fmt.Sprintln("用户密码:%s", arg[0]))) - return hex.EncodeToString(bs[:]) - } else { - bs := md5.Sum([]byte(fmt.Sprintln("用户密码:%s", arg[0]))) - m.Assert(x.Value == hex.EncodeToString(bs[:]), "密码错误") - } + bs := md5.Sum([]byte(fmt.Sprintln("用户密码:%s", arg[0]))) + m.Assert(x.Value == "" || x.Value == hex.EncodeToString(bs[:]), "密码错误") + m.Cap("expire", fmt.Sprintf("%d", time.Now().Unix()+int64(m.Confi("expire")))) + return hex.EncodeToString(bs[:]) } return x.Value // }}} }} + + aaa.Caches["expire"] = &ctx.Cache{Name: "会话超时", Value: "", Help: "用户的会话标识"} + aaa.Caches["sessid"] = &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 @@ -63,34 +60,38 @@ func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ 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]) - m.Cap("group", arg[0]) - } - if len(arg) > 1 { - m.Cap("group", arg[1]) - } - m.Capi("nuser", 1) - + m.Log("info", "context %s", aaa.Context.Name) + aaa.Owner = aaa.Context return aaa } // }}} func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { // {{{ + if len(arg) > 1 { + if m.Cap("sessid") == "" { + m.Cap("sessid", aaa.session(arg[1])) + m.Capi("nuser", 1) + } + m.Log("info", "%s(%s): login %s", m.Source.Name, m.Cap("group", arg[0]), m.Cap("username", arg[1])) + } + return false } // }}} func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { // {{{ - m.Master = Index - if m.Cap("username") != m.Conf("rootname") { - return true + if m.Target == aaa.Context && aaa.Owner == aaa.Context { + if m.Cap("username") != m.Conf("rootname") { + m.Log("info", "%s(%s): logout %s", aaa.Name, m.Cap("group"), m.Cap("username")) + m.Capi("nuser", -1) + return true + } } + return false } @@ -102,62 +103,48 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", }, Configs: map[string]*ctx.Config{ "rootname": &ctx.Config{Name: "根用户名", Value: "root", Help: "根用户名"}, + "expire": &ctx.Config{Name: "会话超时(s)", Value: "120", Help: "会话超时"}, }, Commands: map[string]*ctx.Command{ "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) + m.Target, m.Master = c, c // {{{ + aaa := c.Server.(*AAA) switch len(arg) { case 0: - m.Travel(m.Target, func(m *ctx.Message) bool { + m.Travel(c, func(m *ctx.Message) bool { m.Echo("%s(%s): %s\n", m.Target.Name, m.Cap("group"), m.Cap("time")) return true }) case 1: - target := m.Target if s, ok := aaa.sessions[arg[0]]; ok { - m.Target = s - m.Source.Owner = s - m.Log("info", "%s: logon %s", aaa.Name, m.Cap("username")) + if m.Target = s; int64(m.Capi("expire")) < time.Now().Unix() { + s.Close(m) + return "" + } + + m.Source.Group, m.Source.Owner = m.Cap("group"), m.Target + m.Log("info", "%s(%s): logon %s", m.Source.Name, m.Cap("group"), m.Cap("username")) return m.Cap("username") } - m.Target = target - case 2: - if arg[0] == m.Conf("rootname") { - m.Cap("password", arg[1]) - m.Source.Owner = aaa.Context - m.Travel(m.Target.Root, func(m *ctx.Message) bool { - if m.Target.Owner == nil { - m.Target.Owner = aaa.Context - } - return true - }) - return "" + case 2, 3: + group, username, password := arg[0], arg[0], arg[1] + if len(arg) == 3 { + username, password = arg[1], arg[2] } - source := m.Source - if msg := m.Find(arg[0]); msg == nil { - m.Start(arg[0], arg[0], arg[0]) - m.Cap("sessid", aaa.session(arg[0])) - m.Cap("time", fmt.Sprintf("%d", time.Now().Unix())) + if username == m.Conf("rootname") { + m.Set("detail", group, username).Target.Start(m) + } else if msg := m.Find(username); msg == nil { + m.Start(username, group, group, username) } else { m.Target = msg.Target } - m.Cap("password", arg[1]) - m.Log("info", "%s: login", m.Target.Name) + m.Cap("password", password) + m.Source.Group, m.Source.Owner = m.Cap("group"), m.Target aaa.sessions[m.Cap("sessid")] = m.Target - - m.Target.Owner = m.Target - source.Owner = m.Target - source.Group = m.Cap("group") - - m.Log("info", "%s: login", source.Name) return m.Cap("sessid") - - case 3: - m.Start(arg[0], arg[0], arg[0]) } return "" // }}} @@ -165,9 +152,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", }, Index: map[string]*ctx.Context{ "void": &ctx.Context{Name: "void", - Commands: map[string]*ctx.Command{ - "login": &ctx.Command{}, - }, + Commands: map[string]*ctx.Command{"login": &ctx.Command{}}, }, }, }