diff --git a/etc/hi.sh b/etc/hi.sh index edf0d8d8..f77a68b7 100644 --- a/etc/hi.sh +++ b/etc/hi.sh @@ -5,6 +5,6 @@ alias $ cache alias & server alias * message -#~ssh -#@client no -#& +~root +~tcp +& diff --git a/src/context/cli/cli.go b/src/context/cli/cli.go index 4d4ecef4..3d02046d 100644 --- a/src/context/cli/cli.go +++ b/src/context/cli/cli.go @@ -24,15 +24,12 @@ type CLI struct { bios []*bufio.Reader out *os.File - index int history []map[string]string alias map[string]string + exit chan bool next string - loop int - target *ctx.Context - exit chan bool *ctx.Context } @@ -104,6 +101,7 @@ func (cli *CLI) parse() bool { // {{{ msg := &ctx.Message{Wait: make(chan bool)} msg.Context = cli.Context + msg.Target = cli.target r := rune(ls[0][0]) if !unicode.IsNumber(r) || !unicode.IsLetter(r) || r == '$' || r == '_' { @@ -131,8 +129,7 @@ func (cli *CLI) parse() bool { // {{{ } } - cli.Context.Messages <- msg - <-msg.Wait + cli.Post(msg) for _, v := range msg.Meta["result"] { cli.echo(v) @@ -159,18 +156,15 @@ func (cli *CLI) deal(msg *ctx.Message) bool { // {{{ } if _, ok := cli.Commands[detail[0]]; ok { - cli.loop = 0 cli.next = cli.Cmd(msg, detail...) } else if _, ok := cli.target.Commands[detail[0]]; ok { - cli.loop = 0 cli.target.Message = msg cli.next = cli.target.Cmd(msg, detail...) } else { cmd := exec.Command(detail[0], detail[1:]...) v, e := cmd.CombinedOutput() - if e != nil && cli.loop < 1 { - cli.next = cli.Conf("default") + " " + strings.Join(detail, " ") - cli.loop++ + if e != nil { + msg.Echo("%s\n", e) } msg.Echo(string(v)) log.Println(cli.Name, "command:", detail) @@ -178,10 +172,9 @@ func (cli *CLI) deal(msg *ctx.Message) bool { // {{{ } cli.history = append(cli.history, map[string]string{ "time": time.Now().Format("15:04:05"), - "index": fmt.Sprintf("%d", cli.index), + "index": fmt.Sprintf("%d", len(cli.history)), "cli": strings.Join(detail, " "), }) - cli.index++ return true } @@ -195,9 +188,13 @@ func (cli *CLI) echo(str string, arg ...interface{}) { // {{{ // }}} func (cli *CLI) Begin() bool { // {{{ - // cli.Conf("log", cli.Conf("log")) - for k, v := range cli.Configs { - cli.Conf(k, v.Value) + cli.history = make([]map[string]string, 0, 100) + cli.alias = make(map[string]string, 10) + cli.exit = make(chan bool) + cli.target = cli.Context + + if f, e := os.Open(cli.Conf("init.sh")); e == nil { + cli.push(f) } if cli.Conf("slient") != "yes" { @@ -206,37 +203,19 @@ func (cli *CLI) Begin() bool { // {{{ cli.echo("\n") } - cli.exit = make(chan bool) - cli.target = cli.Context - cli.history = make([]map[string]string, 0, 100) - cli.alias = make(map[string]string, 10) - - if f, e := os.Open(cli.Conf("init.sh")); e == nil { - cli.push(f) - } - return true } // }}} func (cli *CLI) Start() bool { // {{{ - cli.Begin() - go func() { for cli.parse() { } }() for { - select { - case cli.Message = <-cli.Messages: - cli.deal(cli.Message) - if cli.Message.Wait != nil { - cli.Message.Wait <- true - } - case <-cli.exit: - return true - } + msg := cli.Get() + msg.End(cli.deal(msg)) } return true @@ -261,10 +240,10 @@ func (cli *CLI) Spawn(c *ctx.Context, key string) ctx.Server { // {{{ var Index = &ctx.Context{Name: "cli", Help: "本地控制", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ - "开场白": &ctx.Config{"开场白", "你好,命令行", "开场白", nil}, - "结束语": &ctx.Config{"结束语", "再见,命令行", "结束语", nil}, - "mode": &ctx.Config{"mode", "local", "命令执行模式", nil}, - "io": &ctx.Config{"io", "stdout", "输入输出", func(c *ctx.Context, arg string) string { + "开场白": &ctx.Config{Name: "开场白", Value: "你好,命令行", Help: "开场白"}, + "结束语": &ctx.Config{Name: "结束语", Value: "再见,命令行", Help: "结束语"}, + "mode": &ctx.Config{Name: "mode", Value: "local", Help: "命令执行模式"}, + "io": &ctx.Config{Name: "io", Value: "stdout", Help: "输入输出", Hand: func(c *ctx.Context, arg string) string { cli := c.Server.(*CLI) // {{{ cli.out = os.Stdout cli.push(os.Stdin) @@ -272,25 +251,14 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制", return arg // }}} }}, - "slient": &ctx.Config{"slient", "yes", "静默启动", nil}, - "init.sh": &ctx.Config{"init.sh", "etc/hi.sh", "启动脚本", nil}, - "default": &ctx.Config{"default", "get", "默认命令", nil}, - "log": &ctx.Config{"log", "var/bench.log", "日志文件", func(c *ctx.Context, arg string) string { - if l, e := os.Create(arg); e == nil { // {{{ - log.SetOutput(l) - } else { - log.Println("log", arg, "create error") - } - return arg - // }}} - }}, - "PS1": &ctx.Config{"PS1", "etcvpn>", "命令行提示符", func(c *ctx.Context, arg string) string { - cli := c.Server.(*CLI) - self := c.Server.(*CLI) // {{{ + "slient": &ctx.Config{Name: "slient", Value: "yes", Help: "静默启动"}, + "init.sh": &ctx.Config{Name: "init.sh", Value: "etc/hi.sh", Help: "启动脚本"}, + "PS1": &ctx.Config{Name: "PS1", Value: "etcvpn>", Help: "命令行提示符", Hand: func(c *ctx.Context, arg string) string { + cli := c.Server.(*CLI) // {{{ if cli != nil && cli.target != nil { arg = cli.target.Name + ">" } - return fmt.Sprintf("%d[%s]\033[32m%s\033[0m ", self.index, time.Now().Format("15:04:05"), arg) + return fmt.Sprintf("%d[%s]\033[32m%s\033[0m ", len(cli.history), time.Now().Format("15:04:05"), arg) // }}} }}, }, @@ -423,19 +391,20 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制", return "" // }}} }}, - "message": &ctx.Command{"message [find|search name [switch]]|root|back|home", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { + "message": &ctx.Command{"message detail...", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { + msg.Meta["detail"] = arg[1:] + msg.Target.Post(msg) return "" }}, "server": &ctx.Command{"server start|stop|switch", "服务启动停止切换", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { - cli := c.Server.(*CLI) // {{{ + s := msg.Target // {{{ switch len(arg) { case 1: - go cli.target.Start() + return "server start" case 2: switch arg[1] { case "start": - go cli.target.Start() - msg.Echo("\n") + go s.Start() case "stop": case "switch": } @@ -443,7 +412,7 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制", return "" // }}} }}, - "context": &ctx.Command{"context [find|search name [switch]]|root|back|home", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { + "context": &ctx.Command{"context [spawn|fork|find|search name [switch]]|root|back|home", "查看上下文", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { cli := c.Server.(*CLI) // {{{ switch len(arg) { @@ -461,6 +430,10 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制", } case 2, 3, 4, 5: switch arg[1] { + case "fork": + msg.Target.Fork(arg[2]) + case "spawn": + msg.Target.Spawn(arg[2]) case "root": cli.target = cli.Context.Root case "back": @@ -471,9 +444,11 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制", cli.target = cli.Context case "find": cs := c.Root.Find(strings.Split(arg[2], ".")) - msg.Echo("%s: %s\n", cs.Name, cs.Help) - if len(arg) == 4 { - cli.target = cs + if cs != nil { + msg.Echo("%s: %s\n", cs.Name, cs.Help) + if len(arg) == 4 { + cli.target = cs + } } case "search": cs := c.Root.Search(arg[2]) @@ -495,13 +470,14 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制", } default: cs := c.Root.Find(strings.Split(arg[1], ".")) - msg.Echo("%s: %s\n", cs.Name, cs.Help) if cs != nil { - cli.target = cs + msg.Echo("%s: %s\n", cs.Name, cs.Help) + if cs != nil { + cli.target = cs + } } } } - msg.Echo("\ncurr: %s(%s)\n", cli.target.Name, cli.target.Help) return "" // }}} }}, diff --git a/src/context/ctx.go b/src/context/ctx.go index 3873ad49..a8a8a4a8 100644 --- a/src/context/ctx.go +++ b/src/context/ctx.go @@ -4,8 +4,10 @@ import ( // {{{ "errors" "fmt" "log" + "os" "runtime/debug" "strconv" + "strings" ) // }}} @@ -23,6 +25,7 @@ type Config struct { // {{{ Value string Help string Hand func(c *Context, arg string) string + Spawn bool } // }}} @@ -34,10 +37,12 @@ type Command struct { // {{{ // }}} type Message struct { // {{{ + Code int Meta map[string][]string Data map[string]interface{} Wait chan bool + Target *Context *Context } @@ -46,7 +51,7 @@ func (m *Message) Add(key string, value ...string) string { // {{{ m.Meta = make(map[string][]string) } if _, ok := m.Meta[key]; !ok { - m.Meta[key] = []string{} + m.Meta[key] = make([]string, 0, 3) } m.Meta[key] = append(m.Meta[key], value...) @@ -88,7 +93,7 @@ func (m *Message) Echo(str string, arg ...interface{}) string { // {{{ m.Meta = make(map[string][]string) } if _, ok := m.Meta["result"]; !ok { - m.Meta["result"] = []string{} + m.Meta["result"] = make([]string, 0, 3) } s := fmt.Sprintf(str, arg...) @@ -96,6 +101,15 @@ func (m *Message) Echo(str string, arg ...interface{}) string { // {{{ return s } +// }}} +func (m *Message) End(s bool) { // {{{ + log.Println(m.Name, "end", m.Code, ":", m.Meta["detail"]) + if m.Wait != nil { + m.Wait <- s + } + m.Wait = nil +} + // }}} // }}} type Server interface { // {{{ @@ -121,6 +135,7 @@ type Context struct { // {{{ Context *Context Contexts map[string]*Context + Auth string Index map[string]*Context Shadows map[string]*Context } @@ -128,237 +143,15 @@ type Context struct { // {{{ func (c *Context) Check(e error) bool { // {{{ if e != nil { log.Println(c.Name, "error:", e) - debug.PrintStack() + if c.Conf("debug") == "on" { + debug.PrintStack() + } panic(e) } return true } // }}} -func (c *Context) Find(name []string) *Context { // {{{ - if x, ok := c.Contexts[name[0]]; ok { - if len(name) == 1 { - return x - } - return x.Find(name[1:]) - } - - return nil -} - -// }}} -func (c *Context) Search(name string) []*Context { // {{{ - ps := make([]*Context, 0, 3) - - cs := []*Context{c.Root} - for i := 0; i < len(cs); i++ { - for _, v := range cs[i].Contexts { - cs = append(cs, v) - } - - if cs[i].Name == name { - ps = append(ps, cs[i]) - } - } - - return ps -} - -// }}} -func (c *Context) Register(s *Context, self Server) bool { // {{{ - if c.Contexts == nil { - c.Contexts = make(map[string]*Context) - } - if x, ok := c.Contexts[s.Name]; ok { - panic(errors.New(x.Name + "上下文已存在")) - } - - c.Contexts[s.Name] = s - s.Root = c.Root - s.Context = c - s.Server = self - return true -} - -// }}} -func (c *Context) Init(arg ...string) { // {{{ - if c.Root == nil { - c.Root = c - cs := []*Context{c} - for i := 0; i < len(cs); i++ { - for _, v := range cs[i].Contexts { - cs = append(cs, v) - } - cs[i].Init() - } - - cs = c.Search(arg[0]) - cs[0].Begin() - cs[0].Start() - } else { - for _, v := range c.Contexts { - v.Root = c.Root - v.Context = c - } - } -} - -// }}} -func (c *Context) Fork(key string) { // {{{ - cs := []*Context{new(Context)} - *cs[0] = *c - - for i := 0; i < len(cs); i++ { - cs[i].Name = cs[i].Name + key - cs[i].Messages = make(chan *Message, len(cs[i].Messages)) - cs[i].Context.Register(cs[i], cs[i].Server.Fork(cs[i], key)) - - for _, v := range cs[i].Contexts { - s := new(Context) - *s = *v - s.Context = cs[i] - cs = append(cs, s) - } - } -} - -// }}} -func (c *Context) Spawn(key string) *Context { // {{{ - s := new(Context) - s.Name = c.Name + key - s.Help = c.Help - - s.Caches = make(map[string]*Cache) - s.Configs = make(map[string]*Config) - s.Commands = make(map[string]*Command) - s.Messages = make(chan *Message, len(c.Messages)) - c.Register(s, c.Server.Spawn(s, key)) - log.Println(c.Name, "spawn", c.Contexts[s.Name].Name) - return s -} - -// }}} - -func (c *Context) Cap(arg ...string) string { // {{{ - switch len(arg) { - case 1: - if v, ok := c.Caches[arg[0]]; ok { - if v.Hand != nil { - v.Value = v.Hand(c, v.Value) - } - log.Println(c.Name, "cache:", arg) - return v.Value - } - - if c.Context != nil { - return c.Context.Cap(arg...) - } - case 2: - if v, ok := c.Caches[arg[0]]; ok { - v.Value = arg[1] - if v.Hand != nil { - v.Value = v.Hand(c, v.Value) - } - return v.Value - } - - if c.Context != nil { - return c.Context.Cap(arg...) - } - case 3: - if v, ok := c.Caches[arg[0]]; ok { - panic(errors.New(v.Name + "缓存项已存在")) - } - - c.Caches[arg[0]] = &Cache{arg[0], arg[1], arg[2], nil} - log.Println(c.Name, "cache:", arg) - return arg[1] - default: - panic(errors.New(arg[0] + "缓存项参数错误")) - } - - panic(errors.New(arg[0] + "缓存项不存在")) -} - -// }}} -func (c *Context) Conf(arg ...string) string { // {{{ - switch len(arg) { - case 1: - if v, ok := c.Configs[arg[0]]; ok { - if v.Hand != nil { - return v.Hand(c, v.Value) - } - return v.Value - } - - if c.Context != nil { - return c.Context.Conf(arg...) - } - case 2: - if v, ok := c.Configs[arg[0]]; ok { - v.Value = arg[1] - if v.Hand != nil { - v.Hand(c, v.Value) - } - log.Println(c.Name, "config:", arg) - return v.Value - } - - if c.Context != nil { - return c.Context.Conf(arg...) - } - case 4: - if v, ok := c.Configs[arg[0]]; ok { - panic(errors.New(v.Name + "配置项已存在")) - } - - c.Configs[arg[0]] = &Config{arg[1], arg[2], arg[3], nil} - log.Println(c.Name, "config:", arg) - return arg[2] - default: - panic(errors.New(arg[0] + "配置项参数错误")) - } - - panic(errors.New(arg[0] + "配置项不存在")) -} - -// }}} -func (c *Context) Confi(arg ...string) int { // {{{ - n, e := strconv.Atoi(c.Conf(arg...)) - c.Check(e) - return n -} - -// }}} -func (c *Context) Cmd(m *Message, arg ...string) string { // {{{ - if x, ok := c.Commands[arg[0]]; ok { - log.Println(c.Name, "command:", arg) - return x.Hand(c, m, arg...) - } - - if c.Context != nil { - return c.Context.Cmd(m, arg...) - } - - panic(errors.New(fmt.Sprintf(arg[0] + "命令项不存在"))) -} - -// }}} -func (c *Context) Post(m *Message) bool { // {{{ - if c.Messages == nil { - c.Messages = make(chan *Message, 10) - } - - c.Messages <- m - if m.Wait != nil { - return <-m.Wait - } - log.Println(c.Context.Name, "message", m.Meta["detail"]) - return true -} - -// }}} - func (c *Context) Add(arg ...string) { // {{{ switch arg[0] { case "context": @@ -522,22 +315,357 @@ func (c *Context) Del(arg ...string) { // {{{ } // }}} + +func (c *Context) Find(name []string) *Context { // {{{ + if x, ok := c.Contexts[name[0]]; ok { + log.Println(c.Name, "find:", x.Name) + if len(name) == 1 { + return x + } + return x.Find(name[1:]) + } + + log.Println(c.Name, "not find:", name[0]) + return nil +} + +// }}} +func (c *Context) Search(name string) []*Context { // {{{ + ps := make([]*Context, 0, 3) + + cs := []*Context{c} + for i := 0; i < len(cs); i++ { + for _, v := range cs[i].Contexts { + cs = append(cs, v) + } + + if strings.Contains(cs[i].Name, name) || strings.Contains(cs[i].Help, name) { + ps = append(ps, cs[i]) + log.Println(c.Name, "search:", i, cs[i].Name, "[match]") + } else { + log.Println(c.Name, "search:", i, cs[i].Name) + } + } + + return ps +} + +// }}} +func (c *Context) Register(s *Context, self Server) bool { // {{{ + if c.Contexts == nil { + c.Contexts = make(map[string]*Context) + } + + if x, ok := c.Contexts[s.Name]; ok { + panic(errors.New(c.Name + " 上下文已存在" + x.Name)) + } + + c.Contexts[s.Name] = s + s.Context = c + s.Root = c.Root + s.Server = self + + log.Println(c.Name, "register:", s.Name) + return true +} + +// }}} +func (c *Context) Init(arg ...string) { // {{{ + if c.Root != nil { + return + } + + root := c + for root.Context != nil { + root = root.Context + } + + if len(arg) > 0 { + root.Conf("log", arg[0]) + } else { + root.Conf("log", root.Conf("log")) + } + + if len(arg) > 1 { + root.Conf("init.sh", arg[1]) + } else { + root.Conf("init.sh", root.Conf("init.sh")) + } + + cs := []*Context{root} + + for i := 0; i < len(cs); i++ { + cs[i].Root = root + cs[i].Begin() + + for _, v := range cs[i].Contexts { + cs = append(cs, v) + } + } + + if len(arg) > 2 { + for _, v := range arg[2:] { + cs = root.Search(v) + for _, s := range cs { + log.Println(v, "match start:", s.Name) + go s.Start() + } + } + } else { + go root.Find(strings.Split(root.Conf("default"), ".")).Start() + } + + <-make(chan bool) +} + // }}} -var Index = &Context{Name: "ctx", Help: "根文", // {{{ - Caches: map[string]*Cache{}, +func (c *Context) Begin() bool { // {{{ + log.Println(c.Name, "init:") + for k, v := range c.Configs { + c.Conf(k, v.Value) + } + + if c.Server != nil && c.Server.Begin() { + c.Root.Capi("ncontext", 1) + return true + } + + return false +} + +// }}} +func (c *Context) Start() bool { // {{{ + if c.Server != nil && c.Cap("status") != "start" { + c.Cap("status", "status", "start", "服务状态") + defer c.Cap("status", "stop") + + c.Root.Capi("nserver", 1) + defer c.Root.Capi("nserver", -1) + + log.Println(c.Name, "start:") + c.Server.Start() + } + + return true +} + +// }}} +func (c *Context) Fork(key string) *Context { // {{{ + s := new(Context) + s.Name = c.Name + key + s.Help = c.Help + + s.Caches = c.Caches + s.Configs = c.Configs + s.Commands = c.Commands + log.Println(c.Name, "fork:", s.Name) + + if c.Messages != nil { + s.Messages = make(chan *Message, len(c.Messages)) + } + c.Context.Register(s, c.Server.Fork(s, key)) + s.Begin() + return s +} + +// }}} +func (c *Context) Spawn(key string) *Context { // {{{ + s := new(Context) + s.Name = c.Name + key + s.Help = c.Help + + s.Caches = make(map[string]*Cache) + s.Configs = make(map[string]*Config) + s.Commands = make(map[string]*Command) + log.Println(c.Name, "spawn:", s.Name) + + if c.Messages != nil { + s.Messages = make(chan *Message, len(c.Messages)) + } + c.Register(s, c.Server.Spawn(s, key)) + s.Begin() + return s +} + +// }}} +func (c *Context) Get() *Message { // {{{ + if c.Messages == nil { + c.Messages = make(chan *Message, c.Confi("MessageQueueSize")) + } + + select { + case msg := <-c.Messages: + log.Println(c.Name, "get", msg.Code, ":", msg.Meta["detail"]) + return msg + } + + return nil +} + +// }}} +func (c *Context) Post(m *Message) bool { // {{{ + if c.Messages == nil { + c.Messages = make(chan *Message, c.Confi("MessageQueueSize")) + } + + m.Code = c.Root.Capi("nmessage", 1) + log.Println(c.Name, "post", m.Code, ":", m.Meta["detail"]) + defer log.Println(c.Name, "done", m.Code, ":", m.Meta["detail"]) + + c.Messages <- m + if m.Wait != nil { + return <-m.Wait + } + return true +} + +// }}} + +func (c *Context) Cmd(m *Message, arg ...string) string { // {{{ + if x, ok := c.Commands[arg[0]]; ok { + log.Println(c.Name, "command:", arg) + return x.Hand(c, m, arg...) + } + + if c.Context != nil { + return c.Context.Cmd(m, arg...) + } + + panic(errors.New(fmt.Sprintf(arg[0] + "命令项不存在"))) +} + +// }}} +func (c *Context) Conf(arg ...string) string { // {{{ + switch len(arg) { + case 1: + if v, ok := c.Configs[arg[0]]; ok { + if v.Hand != nil { + return v.Hand(c, v.Value) + } + return v.Value + } + + if c.Context != nil { + return c.Context.Conf(arg...) + } + case 2: + if v, ok := c.Configs[arg[0]]; ok { + v.Value = arg[1] + if v.Hand != nil { + return v.Hand(c, v.Value) + } + log.Println(c.Name, "config:", arg) + return v.Value + } + + if c.Context != nil { + return c.Context.Conf(arg...) + } + case 4: + if v, ok := c.Configs[arg[0]]; ok { + panic(errors.New(v.Name + "配置项已存在")) + } + + c.Configs[arg[0]] = &Config{Name: arg[1], Value: arg[2], Help: arg[3]} + log.Println(c.Name, "config:", arg) + return arg[2] + default: + panic(errors.New(arg[0] + "配置项参数错误")) + } + + panic(errors.New(arg[0] + "配置项不存在")) +} + +// }}} +func (c *Context) Confi(arg ...string) int { // {{{ + n, e := strconv.Atoi(c.Conf(arg...)) + c.Check(e) + return n +} + +// }}} +func (c *Context) Cap(arg ...string) string { // {{{ + switch len(arg) { + case 1: + if v, ok := c.Caches[arg[0]]; ok { + if v.Hand != nil { + v.Value = v.Hand(c, v.Value) + } + log.Println(c.Name, "cache:", arg, v.Value) + return v.Value + } + + if c.Context != nil { + return c.Context.Cap(arg...) + } + case 2: + if v, ok := c.Caches[arg[0]]; ok { + v.Value = arg[1] + if v.Hand != nil { + v.Value = v.Hand(c, v.Value) + } + log.Println(c.Name, "cache:", arg) + return v.Value + } + + if c.Context != nil { + return c.Context.Cap(arg...) + } + case 4: + if v, ok := c.Caches[arg[0]]; ok { + panic(errors.New(v.Name + "缓存项已存在")) + } + + c.Caches[arg[0]] = &Cache{arg[1], arg[2], arg[3], nil} + log.Println(c.Name, "cache:", arg) + return arg[2] + default: + panic(errors.New(arg[0] + "缓存项参数错误")) + } + + panic(errors.New(arg[0] + "缓存项不存在")) +} + +// }}} +func (c *Context) Capi(key string, value int) int { // {{{ + n, e := strconv.Atoi(c.Cap(key)) + c.Check(e) + c.Cap(key, strconv.Itoa(n+value)) + return n +} + +// }}} +// }}} + +var Index = &Context{Name: "ctx", Help: "根上下文", + Caches: map[string]*Cache{ + "status": &Cache{Name: "status", Value: "stop", Help: "服务状态"}, + "nserver": &Cache{Name: "nserver", Value: "0", Help: "服务数量"}, + "ncontext": &Cache{Name: "ncontext", Value: "0", Help: "上下文数量"}, + "nmessage": &Cache{Name: "nmessage", Value: "0", Help: "消息发送数量"}, + }, Configs: map[string]*Config{ - "开场白": &Config{"开场白", "你好,上下文", "开场白", nil}, - "结束语": &Config{"结束语", "再见,上下文", "结束语", nil}, - "debug": &Config{"debug", "on", "调试模式", nil}, + "开场白": &Config{Name: "开场白", Value: "你好,上下文", Help: "开场白"}, + "结束语": &Config{Name: "结束语", Value: "再见,上下文", Help: "结束语"}, + + "MessageQueueSize": &Config{Name: "MessageQueueSize", Value: "10", Help: "默认消息队列长度"}, + + "cert": &Config{Name: "cert", Value: "etc/cert.pem", Help: "证书文件"}, + "key": &Config{Name: "key", Value: "etc/key.pem", Help: "私钥文件"}, + + "debug": &Config{Name: "debug", Value: "on", Help: "调试模式"}, + "default": &Config{Name: "default", Value: "cli", Help: "默认启动模块"}, + "init.sh": &Config{Name: "init.sh", Value: "etc/hi.sh", Help: "默认启动脚本"}, + "log": &Config{Name: "log", Value: "var/bench.log", Help: "默认日志文件", Hand: func(c *Context, arg string) string { + if l, e := os.Create(arg); e == nil { // {{{ + log.SetOutput(l) + } else { + log.Println("log", arg, "create error") + } + return arg + // }}} + }}, }, Commands: map[string]*Command{}, } - -// }}} - -func init() { // {{{ - Index.Root = Index -} - -// }}} diff --git a/src/context/ssh/ssh.go b/src/context/ssh/ssh.go index 766fa908..54fdf9f1 100644 --- a/src/context/ssh/ssh.go +++ b/src/context/ssh/ssh.go @@ -228,15 +228,11 @@ func (ssh *SSH) Spawn(c *ctx.Context, key string) ctx.Server { // {{{ // }}} var Index = &ctx.Context{Name: "ssh", Help: "远程控制", - Caches: map[string]*ctx.Cache{ - "status": &ctx.Cache{"status", "stop", "服务器状态", nil}, - }, + Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ - "master": &ctx.Config{"master", "yes", "主控或被控", nil}, - "client": &ctx.Config{"client", "yes", "连接或监听", nil}, - "address": &ctx.Config{"address", ":9090", "连接或监听的地址", nil}, - "cert": &ctx.Config{"cert", "etc/cert.pem", "证书文件", nil}, - "key": &ctx.Config{"key", "etc/key.pem", "私钥文件", nil}, + "master": &ctx.Config{Name: "master", Value: "yes", Help: "主控或被控"}, + "client": &ctx.Config{Name: "client", Value: "yes", Help: "连接或监听"}, + "address": &ctx.Config{Name: "address", Value: ":9090", Help: "连接或监听的地址"}, }, Commands: map[string]*ctx.Command{ "remote": &ctx.Command{"remote", "远程命令", func(c *ctx.Context, msg *ctx.Message, arg ...string) string { diff --git a/src/context/tcp/tcp.go b/src/context/tcp/tcp.go new file mode 100644 index 00000000..86555594 --- /dev/null +++ b/src/context/tcp/tcp.go @@ -0,0 +1,94 @@ +package tcp + +import ( + "context" + "fmt" + "log" + "net" + "time" +) + +type TCP struct { + listener net.Listener + conn net.Conn + + target *ctx.Context + *ctx.Context +} + +func (tcp *TCP) Begin() bool { + return true +} + +func (tcp *TCP) Start() bool { + log.Println(tcp.Name, "start:") + if tcp.Conf("address") == "" { + log.Println(tcp.Name, "start:") + for { + msg := tcp.Get() + arg := msg.Meta["detail"] + switch arg[0] { + case "listen": + s := tcp.Context.Spawn(arg[1]) + s.Conf("addresss", "address", arg[1], "监听地址") + go s.Start() + } + if msg.Wait != nil { + msg.Wait <- true + } + msg.End(true) + } + return true + } else { + if tcp.Conf("remote") == "" { + l, e := net.Listen("tcp", tcp.Conf("address")) + tcp.Check(e) + tcp.listener = l + + for { + c, e := l.Accept() + tcp.Check(e) + + s := tcp.Context.Spawn(c.RemoteAddr().String()) + s.Conf("remote", "remote", c.RemoteAddr().String(), "连接地址") + x := s.Server.(*TCP) + x.conn = c + go s.Start() + } + return true + } else { + for { + fmt.Fprintln(tcp.conn, "hello context world!\n") + time.Sleep(3 * time.Second) + } + } + + } +} + +func (tcp *TCP) Spawn(c *ctx.Context, key string) ctx.Server { + s := new(TCP) + s.Context = c + return s +} + +func (tcp *TCP) Fork(c *ctx.Context, key string) ctx.Server { + s := new(TCP) + s.Context = c + return s +} + +var Index = &ctx.Context{Name: "tcp", Help: "网络连接", + Caches: map[string]*ctx.Cache{}, + Configs: map[string]*ctx.Config{ + "address": &ctx.Config{Name: "address", Value: "", Help: "监听地址"}, + "remote": &ctx.Config{Name: "remote", Value: "", Help: "远程地址"}, + }, + Commands: map[string]*ctx.Command{}, +} + +func init() { + tcp := &TCP{} + tcp.Context = Index + ctx.Index.Register(Index, tcp) +} diff --git a/src/context/web/web.go b/src/context/web/web.go index 248d763e..3831d6b4 100644 --- a/src/context/web/web.go +++ b/src/context/web/web.go @@ -2,6 +2,7 @@ package web import ( "context" + "context/cli" "net/http" ) @@ -14,12 +15,6 @@ func (web *WEB) Begin() bool { return true } func (web *WEB) Start() bool { - if web.Cap("status") == "start" { - return true - } - web.Cap("status", "start") - defer web.Cap("status", "stop") - http.Handle("/", http.FileServer(http.Dir(web.Conf("path")))) http.ListenAndServe(web.Conf("address"), nil) return true @@ -33,17 +28,15 @@ func (web *WEB) Fork(c *ctx.Context, key string) ctx.Server { } var Index = &ctx.Context{Name: "web", Help: "网页服务", - Caches: map[string]*ctx.Cache{ - "status": &ctx.Cache{"status", "stop", "服务运行状态", nil}, - }, + Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ - "path": &ctx.Config{"path", "srv", "监听地址", nil}, - "address": &ctx.Config{"address", ":9494", "监听地址", nil}, + "path": &ctx.Config{Name: "path", Value: "srv", Help: "监听地址"}, + "address": &ctx.Config{Name: "address", Value: ":9494", Help: "监听地址"}, }, } func init() { web := &WEB{} web.Context = Index - ctx.Index.Register(Index, web) + cli.Index.Register(Index, web) } diff --git a/src/toolkit/bench.go b/src/toolkit/bench.go index 0ef248dd..6012ab1b 100644 --- a/src/toolkit/bench.go +++ b/src/toolkit/bench.go @@ -1,21 +1,14 @@ package main import ( - _ "context" - "context/cli" + "context" + _ "context/cli" _ "context/ssh" + _ "context/tcp" _ "context/web" "os" ) func main() { - if len(os.Args) > 1 { - cli.Index.Conf("log", os.Args[1]) - } - - if len(os.Args) > 2 { - cli.Index.Conf("init.sh", os.Args[2]) - } - - cli.Index.Start() + ctx.Index.Init(os.Args[1:]...) }