forked from x/ContextOS
Merge branch '0.4.0'
This commit is contained in:
commit
526b2336b6
@ -23,33 +23,31 @@ snippet c
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
_ "context/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type `toupper(substitute(expand("%:t"), ".go", "", ""))` struct {
|
type `toupper(substitute(expand("%:t"), ".go", "", ""))` struct {
|
||||||
*ctx.Context
|
*ctx.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server {
|
||||||
|
c.Caches = map[string]*ctx.Cache{}
|
||||||
|
c.Configs = map[string]*ctx.Config{}
|
||||||
|
|
||||||
|
s := new(`toupper(substitute(expand("%:t"), ".go", "", ""))`)
|
||||||
|
s.Context = c
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||||
return `Filename()`
|
return `Filename()`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Start(m *ctx.Message, arg ...string) bool {
|
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Start(m *ctx.Message, arg ...string) bool {
|
||||||
return true
|
return false
|
||||||
}
|
|
||||||
|
|
||||||
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server {
|
|
||||||
c.Caches = map[string]*ctx.Cache{}
|
|
||||||
c.Configs = map[string]*ctx.Config{}
|
|
||||||
c.Commands = map[string]*ctx.Command{}
|
|
||||||
|
|
||||||
s := new(`toupper(substitute(expand("%:t"), ".go", "", ""))`)
|
|
||||||
s.Context = c
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Exit(m *ctx.Message, arg ...string) bool {
|
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Exit(m *ctx.Message, arg ...string) bool {
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -65,22 +63,23 @@ snippet c
|
|||||||
ctx.Index.Register(Index, `Filename()`)
|
ctx.Index.Register(Index, `Filename()`)
|
||||||
}
|
}
|
||||||
snippet cmd
|
snippet cmd
|
||||||
"${1}": &ctx.Command{Name: "${2}", Help: "${3}", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"${1}": &ctx.Command{Name: "${2}", Help: "${3}", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
||||||
${4}
|
${4}
|
||||||
return ""
|
return ""
|
||||||
}},
|
}},
|
||||||
snippet conf
|
snippet conf
|
||||||
"${1}": &ctx.Config{Name: "${2}", Value: "${3}", Help: "${4}", Hand: func(c *ctx.Context, x *ctx.Config, arg ...string) string {
|
"${1}": &ctx.Config{Name: "${2}", Value: "${3}", Help: "${4}", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
${5}
|
${5}
|
||||||
|
return arg[0]
|
||||||
}
|
}
|
||||||
return x.Value
|
return x.Value
|
||||||
}},
|
}},
|
||||||
snippet cap
|
snippet cap
|
||||||
"${1}": &ctx.Cache{Name: "${2}", Value: "${3}", Help: "${4}", Hand: func(c *ctx.Context, x *ctx.Cache, arg ...string) string {
|
"${1}": &ctx.Cache{Name: "${2}", Value: "${3}", Help: "${4}", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string {
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
x.Value = arg[0]
|
|
||||||
${5}
|
${5}
|
||||||
|
return arg[0]
|
||||||
}
|
}
|
||||||
return x.Value
|
return x.Value
|
||||||
}},
|
}},
|
||||||
|
27
etc/init.sh
27
etc/init.sh
@ -1,19 +1,26 @@
|
|||||||
# @debug on
|
# ~lex source etc/lex.sh
|
||||||
~lex start
|
|
||||||
source etc/lex.sh
|
|
||||||
~cli @lex lex
|
~cli @lex lex
|
||||||
|
|
||||||
~mdb
|
~mdb open chat chat "chat:chat@/chat" mysql
|
||||||
open chat chat "chat:chat@/chat" mysql
|
|
||||||
~chat
|
~root aaa login root root
|
||||||
query "select * from userinfo"
|
|
||||||
|
@debug
|
||||||
|
~web spawn hi he ./
|
||||||
|
~web listen
|
||||||
|
route template /tpl ./usr/msg.tpl
|
||||||
|
route script /php ./usr/msg.php
|
||||||
|
route script /who who
|
||||||
|
~hi listen ./ ":9494"
|
||||||
|
master nice
|
||||||
|
pwd
|
||||||
|
|
||||||
|
# ~aaa login shy shy
|
||||||
|
|
||||||
return
|
return
|
||||||
~aaa
|
|
||||||
login root root
|
|
||||||
login shy shy
|
login shy shy
|
||||||
|
|
||||||
|
|
||||||
~root cli
|
~root cli
|
||||||
remote slaver listen ":9393" tcp
|
remote slaver listen ":9393" tcp
|
||||||
~root aaa
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
train [a-zA-Z][a-zA-Z0-9]*
|
|
||||||
train 0x[0-9]+
|
|
||||||
train [0-9]+
|
|
||||||
train "[^"]*"
|
|
||||||
train '[^']*'
|
|
||||||
train [~!@#$&*:]
|
|
@ -40,7 +40,7 @@ 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 { // {{{
|
func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||||
aaa.Caches["group"] = &ctx.Cache{Name: "用户组", Value: "", Help: "用户组"}
|
aaa.Caches["group"] = &ctx.Cache{Name: "用户组", Value: "", Help: "用户组"}
|
||||||
aaa.Caches["username"] = &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 {
|
aaa.Caches["password"] = &ctx.Cache{Name: "用户密码", Value: "", Help: "用户密码,加密存储", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string {
|
||||||
if len(arg) > 0 { // {{{
|
if len(arg) > 0 { // {{{
|
||||||
bs := md5.Sum([]byte(fmt.Sprintln("用户密码:%s", arg[0])))
|
bs := md5.Sum([]byte(fmt.Sprintln("用户密码:%s", arg[0])))
|
||||||
m.Assert(x.Value == "" || x.Value == hex.EncodeToString(bs[:]), "密码错误")
|
m.Assert(x.Value == "" || x.Value == hex.EncodeToString(bs[:]), "密码错误")
|
||||||
@ -51,11 +51,11 @@ func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
aaa.Caches["expire"] = &ctx.Cache{Name: "会话超时", Value: "", Help: "用户的会话标识"}
|
|
||||||
aaa.Caches["sessid"] = &ctx.Cache{Name: "会话标识", Value: "", Help: "用户的会话标识"}
|
aaa.Caches["sessid"] = &ctx.Cache{Name: "会话标识", Value: "", Help: "用户的会话标识"}
|
||||||
|
aaa.Caches["expire"] = &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 {
|
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 { // {{{
|
if len(arg) > 0 { // {{{
|
||||||
return x.Value
|
return arg[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
n, e := strconv.Atoi(x.Value)
|
n, e := strconv.Atoi(x.Value)
|
||||||
@ -64,7 +64,6 @@ func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
m.Log("info", "context %s", aaa.Context.Name)
|
|
||||||
aaa.Owner = aaa.Context
|
aaa.Owner = aaa.Context
|
||||||
return aaa
|
return aaa
|
||||||
}
|
}
|
||||||
@ -76,7 +75,8 @@ func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
m.Cap("sessid", aaa.session(arg[1]))
|
m.Cap("sessid", aaa.session(arg[1]))
|
||||||
m.Capi("nuser", 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]))
|
m.Log("info", m.Source, "login %s %s", m.Cap("group", arg[0]), m.Cap("username", arg[1]))
|
||||||
|
m.Cap("stream", m.Cap("username"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
@ -86,7 +86,7 @@ func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { // {{{
|
func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
if m.Target == aaa.Context && aaa.Owner == aaa.Context {
|
if m.Target == aaa.Context && aaa.Owner == aaa.Context {
|
||||||
if m.Cap("username") != m.Conf("rootname") {
|
if m.Cap("username") != m.Conf("rootname") {
|
||||||
m.Log("info", "%s(%s): logout %s", aaa.Name, m.Cap("group"), m.Cap("username"))
|
m.Log("info", nil, "logout %s", m.Cap("group"), m.Cap("username"))
|
||||||
m.Capi("nuser", -1)
|
m.Capi("nuser", -1)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.Source.Group, m.Source.Owner = m.Cap("group"), m.Target
|
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"))
|
m.Log("info", m.Source, "logon %s", m.Cap("group"), m.Cap("username"))
|
||||||
return m.Cap("username")
|
return m.Cap("username")
|
||||||
}
|
}
|
||||||
case 2, 3:
|
case 2, 3:
|
||||||
|
@ -7,7 +7,7 @@ import ( // {{{
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
@ -16,23 +16,22 @@ import ( // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
type CLI struct {
|
type CLI struct {
|
||||||
out io.WriteCloser
|
|
||||||
in io.ReadCloser
|
in io.ReadCloser
|
||||||
ins []io.ReadCloser
|
ins []io.ReadCloser
|
||||||
bio *bufio.Reader
|
bio *bufio.Reader
|
||||||
bios []*bufio.Reader
|
bios []*bufio.Reader
|
||||||
bufs [][]byte
|
bufs [][]byte
|
||||||
|
|
||||||
history []map[string]string
|
out io.WriteCloser
|
||||||
|
|
||||||
alias map[string]string
|
alias map[string]string
|
||||||
next string
|
next string
|
||||||
exit bool
|
exit bool
|
||||||
login *ctx.Context
|
|
||||||
lex *ctx.Message
|
|
||||||
|
|
||||||
temp *ctx.Context
|
lex *ctx.Message
|
||||||
target *ctx.Context
|
target *ctx.Context
|
||||||
m *ctx.Message
|
|
||||||
|
*ctx.Message
|
||||||
*ctx.Context
|
*ctx.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +49,7 @@ func (cli *CLI) push(f io.ReadCloser) { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (cli *CLI) echo(str string, arg ...interface{}) { // {{{
|
func (cli *CLI) echo(str string, arg ...interface{}) { // {{{
|
||||||
if len(cli.ins) == 1 || cli.m.Conf("slient") != "yes" {
|
if len(cli.ins) == 1 || cli.Conf("slient") != "yes" {
|
||||||
fmt.Fprintf(cli.out, str, arg...)
|
fmt.Fprintf(cli.out, str, arg...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,7 +83,6 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{
|
|||||||
if len(cli.ins) > 1 {
|
if len(cli.ins) > 1 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
line = cli.history[len(cli.history)-1]["cli"]
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
line, cli.next = cli.next, ""
|
line, cli.next = cli.next, ""
|
||||||
@ -116,9 +114,6 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg := m.Spawn(cli.target)
|
msg := m.Spawn(cli.target)
|
||||||
if cli.temp != nil {
|
|
||||||
msg.Target, cli.temp = cli.temp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < len(ls); i++ {
|
for i := 0; i < len(ls); i++ {
|
||||||
ls[i] = strings.TrimSpace(ls[i])
|
ls[i] = strings.TrimSpace(ls[i])
|
||||||
@ -129,13 +124,6 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{
|
|||||||
break
|
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 r := rune(ls[i][0]); r == '$' || r == '_' || (!unicode.IsNumber(r) && !unicode.IsLetter(r)) {
|
||||||
if c, ok := cli.alias[string(r)]; ok {
|
if c, ok := cli.alias[string(r)]; ok {
|
||||||
if msg.Add("detail", c); len(ls[i]) > 1 {
|
if msg.Add("detail", c); len(ls[i]) > 1 {
|
||||||
@ -146,15 +134,23 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cli.lex != nil && len(ls[i]) > 1 {
|
||||||
|
switch ls[i][0] {
|
||||||
|
case '"', '\'':
|
||||||
|
ls[i] = ls[i][1 : len(ls[i])-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
msg.Add("detail", ls[i])
|
msg.Add("detail", ls[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.Wait = make(chan bool)
|
if msg.Wait = make(chan bool); msg.Target.Master != cli.Context {
|
||||||
|
msg.Post(msg.Target.Master)
|
||||||
|
} else {
|
||||||
msg.Post(cli.Context)
|
msg.Post(cli.Context)
|
||||||
|
}
|
||||||
|
|
||||||
m.Capi("nhistory", 1)
|
|
||||||
cli.echo(strings.Join(msg.Meta["result"], ""))
|
cli.echo(strings.Join(msg.Meta["result"], ""))
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,8 +160,6 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
|||||||
c.Caches = map[string]*ctx.Cache{}
|
c.Caches = map[string]*ctx.Cache{}
|
||||||
c.Configs = map[string]*ctx.Config{}
|
c.Configs = map[string]*ctx.Config{}
|
||||||
|
|
||||||
cli.Owner = nil
|
|
||||||
|
|
||||||
s := new(CLI)
|
s := new(CLI)
|
||||||
s.Context = c
|
s.Context = c
|
||||||
return s
|
return s
|
||||||
@ -173,11 +167,7 @@ func (cli *CLI) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (cli *CLI) Begin(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: "当前终端已经执行命令的数量"}
|
|
||||||
|
|
||||||
cli.Configs["slient"] = &ctx.Config{Name: "屏蔽脚本输出(yes/no)", Value: "yes", Help: "屏蔽脚本输出的信息,yes:屏蔽,no:不屏蔽"}
|
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.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 { // {{{
|
if len(arg) > 0 { // {{{
|
||||||
return arg[0]
|
return arg[0]
|
||||||
@ -186,7 +176,6 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
ps := make([]string, 0, 3)
|
ps := make([]string, 0, 3)
|
||||||
|
|
||||||
if cli, ok := m.Target.Server.(*CLI); ok && cli.target != nil {
|
if cli, ok := m.Target.Server.(*CLI); ok && cli.target != nil {
|
||||||
ps = append(ps, m.Cap("nhistory"))
|
|
||||||
ps = append(ps, "[")
|
ps = append(ps, "[")
|
||||||
ps = append(ps, time.Now().Format("15:04:05"))
|
ps = append(ps, time.Now().Format("15:04:05"))
|
||||||
ps = append(ps, "]")
|
ps = append(ps, "]")
|
||||||
@ -225,11 +214,17 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
cli, ok := m.Target.Server.(*CLI)
|
cli, ok := m.Target.Server.(*CLI)
|
||||||
m.Assert(ok, "模块类型错误")
|
m.Assert(ok, "模块类型错误")
|
||||||
|
|
||||||
cli.lex = m.Find(arg[0], m.Target.Root)
|
lex := m.Find(arg[0], true)
|
||||||
m.Assert(cli.lex != nil, "词法解析模块不存在")
|
m.Assert(lex != nil, "词法解析模块不存在")
|
||||||
|
if lex.Cap("status") != "start" {
|
||||||
cli.lex.Cmd("train", "[ \n\t]+", "void", "void")
|
lex.Target.Start(lex)
|
||||||
cli.lex.Cmd("train", "#[^\n]*\n", "void", "void")
|
lex.Cmd("train", "'[^']*'")
|
||||||
|
lex.Cmd("train", "\"[^\"]*\"")
|
||||||
|
lex.Cmd("train", "[^ \t\n]+")
|
||||||
|
lex.Cmd("train", "[ \n\t]+", "void", "void")
|
||||||
|
lex.Cmd("train", "#[^\n]*\n", "void", "void")
|
||||||
|
}
|
||||||
|
cli.lex = lex
|
||||||
}
|
}
|
||||||
return x.Value
|
return x.Value
|
||||||
// }}}
|
// }}}
|
||||||
@ -239,19 +234,19 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
cli.Configs["init.sh"] = &ctx.Config{Name: "启动脚本", Value: arg[0], Help: "模块启动时自动运行的脚本"}
|
cli.Configs["init.sh"] = &ctx.Config{Name: "启动脚本", Value: arg[0], Help: "模块启动时自动运行的脚本"}
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.m = m
|
|
||||||
cli.Context.Master = cli.Context
|
cli.Context.Master = cli.Context
|
||||||
|
if cli.Context != Index {
|
||||||
|
cli.Owner = nil
|
||||||
|
}
|
||||||
|
|
||||||
cli.target = cli.Context
|
cli.target = cli.Context
|
||||||
cli.history = make([]map[string]string, 0, 100)
|
|
||||||
cli.alias = map[string]string{
|
cli.alias = map[string]string{
|
||||||
"~": "context",
|
"~": "context",
|
||||||
"!": "history",
|
"!": "command",
|
||||||
"@": "config",
|
"@": "config",
|
||||||
"$": "cache",
|
"$": "cache",
|
||||||
"&": "server",
|
"&": "server",
|
||||||
"*": "message",
|
"*": "message",
|
||||||
":": "command",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cli
|
return cli
|
||||||
@ -259,8 +254,7 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
m.Capi("nterm", 1)
|
cli.Message = m
|
||||||
defer m.Capi("nterm", -1)
|
|
||||||
|
|
||||||
if stream, ok := m.Data["io"]; ok {
|
if stream, ok := m.Data["io"]; ok {
|
||||||
io := stream.(io.ReadWriteCloser)
|
io := stream.(io.ReadWriteCloser)
|
||||||
@ -268,21 +262,21 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
cli.push(io)
|
cli.push(io)
|
||||||
|
|
||||||
if m.Has("master") {
|
if m.Has("master") {
|
||||||
m.Log("info", "%s: master terminal", cli.Name)
|
m.Log("info", nil, "master terminal")
|
||||||
if cli.bufs == nil {
|
if cli.bufs == nil {
|
||||||
cli.bufs = make([][]byte, 0, 10)
|
cli.bufs = make([][]byte, 0, 10)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
b := make([]byte, 128)
|
b := make([]byte, 128)
|
||||||
n, e := cli.bio.Read(b)
|
n, e := cli.bio.Read(b)
|
||||||
m.Log("info", "%s: read %d", cli.Name, n)
|
m.Log("info", nil, "read %d", n)
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
cli.bufs = append(cli.bufs, b)
|
cli.bufs = append(cli.bufs, b)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
if cli.Owner == nil {
|
if cli.Owner == nil {
|
||||||
if msg := m.Find("aaa", m.Target.Root); msg != nil {
|
if msg := m.Find("aaa", true); msg != nil {
|
||||||
username := ""
|
username := ""
|
||||||
cli.echo("username>")
|
cli.echo("username>")
|
||||||
fmt.Fscanln(cli.in, &username)
|
fmt.Fscanln(cli.in, &username)
|
||||||
@ -298,13 +292,11 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
cli.in.Close()
|
cli.in.Close()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Cap("username", msg.Cap("username"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Log("info", "%s: slaver terminal", cli.Name)
|
m.Log("info", nil, "slaver terminal")
|
||||||
m.Log("info", "%s: open %s", cli.Name, m.Conf("init.sh"))
|
m.Log("info", nil, "open %s", m.Conf("init.sh"))
|
||||||
if f, e := os.Open(m.Conf("init.sh")); e == nil {
|
if f, e := os.Open(m.Conf("init.sh")); e == nil {
|
||||||
cli.push(f)
|
cli.push(f)
|
||||||
}
|
}
|
||||||
@ -316,25 +308,35 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for m.Deal(nil, func(msg *ctx.Message, arg ...string) bool {
|
m.Capi("nterm", 1)
|
||||||
cli.history = append(cli.history, map[string]string{
|
defer m.Capi("nterm", -1)
|
||||||
"time": time.Now().Format("15:04:05"),
|
|
||||||
"index": fmt.Sprintf("%d", len(cli.history)),
|
m.Deal(nil, func(msg *ctx.Message, arg ...string) bool {
|
||||||
"cli": strings.Join(msg.Meta["detail"], " "),
|
if msg.Get("result") == "error: " {
|
||||||
|
msg.Log("system", nil, "%v", msg.Meta["detail"])
|
||||||
|
|
||||||
|
msg.Set("result")
|
||||||
|
msg.Set("append")
|
||||||
|
c := exec.Command(msg.Meta["detail"][0], msg.Meta["detail"][1:]...)
|
||||||
|
|
||||||
|
if len(cli.ins) == 1 {
|
||||||
|
c.Stdin, c.Stdout, c.Stderr = cli.in, cli.out, cli.out
|
||||||
|
msg.Assert(c.Start())
|
||||||
|
msg.Assert(c.Wait())
|
||||||
|
} else {
|
||||||
|
if out, e := c.CombinedOutput(); e == nil {
|
||||||
|
msg.Echo(string(out))
|
||||||
|
} else {
|
||||||
|
msg.Echo("error: ")
|
||||||
|
msg.Echo("%s\n", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cli.target = msg.Target
|
||||||
|
return cli.exit == false
|
||||||
})
|
})
|
||||||
|
|
||||||
if len(arg) > 0 {
|
|
||||||
// cli.next = arg[0]
|
|
||||||
// arg[0] = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if cli.exit == true {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}) {
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,7 +347,7 @@ func (cli *CLI) Close(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
return false
|
return false
|
||||||
|
|
||||||
case m.Target:
|
case m.Target:
|
||||||
m.Log("exit", "%s: release", cli.Name)
|
m.Log("exit", nil, "release")
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
@ -359,118 +361,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
},
|
},
|
||||||
Configs: map[string]*ctx.Config{},
|
Configs: map[string]*ctx.Config{},
|
||||||
Commands: map[string]*ctx.Command{
|
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(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
|
||||||
cli, ok := m.Source.Server.(*CLI) // {{{
|
|
||||||
if !ok {
|
|
||||||
cli, ok = c.Server.(*CLI)
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
if m.Has("root") {
|
|
||||||
target = m.Target.Root
|
|
||||||
}
|
|
||||||
if m.Has("back") && target.Context != nil {
|
|
||||||
target = m.Target.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
ms := []*ctx.Message{}
|
|
||||||
switch {
|
|
||||||
case m.Has("search"):
|
|
||||||
if s := m.Search(m.Get("search"), target); len(s) > 0 {
|
|
||||||
ms = append(ms, s...)
|
|
||||||
}
|
|
||||||
case m.Has("find"):
|
|
||||||
if msg := m.Find(m.Get("find"), target); msg != nil {
|
|
||||||
ms = append(ms, msg)
|
|
||||||
}
|
|
||||||
case m.Has("args"):
|
|
||||||
if s := m.Search(m.Get("args"), target); len(s) > 0 {
|
|
||||||
ms = append(ms, s...)
|
|
||||||
arg = arg[1:]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
default:
|
|
||||||
ms = append(ms, m.Spawn(target))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range ms {
|
|
||||||
switch {
|
|
||||||
case m.Has("spawn"):
|
|
||||||
v.Target.Spawn(v, arg[0], arg[1]).Begin(v)
|
|
||||||
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"):
|
|
||||||
v.Target.Close(v)
|
|
||||||
case m.Has("show"):
|
|
||||||
m.Echo("%s(%s): %s\n", v.Target.Name, v.Target.Owner.Name, v.Target.Help)
|
|
||||||
if len(v.Target.Requests) > 0 {
|
|
||||||
m.Echo("模块资源:\n")
|
|
||||||
for i, v := range v.Target.Requests {
|
|
||||||
m.Echo(" %d(%d): <- %s %s\n", i, v.Code, v.Source.Name, v.Meta["detail"])
|
|
||||||
for i, v := range v.Messages {
|
|
||||||
m.Echo(" %d(%d): -> %s %s\n", i, v.Code, v.Source.Name, v.Meta["detail"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(v.Target.Sessions) > 0 {
|
|
||||||
m.Echo("模块引用:\n")
|
|
||||||
for k, v := range v.Target.Sessions {
|
|
||||||
m.Echo(" %s(%d): -> %s %v\n", k, v.Code, v.Target.Name, v.Meta["detail"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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
|
|
||||||
m.Echo("%s: %s(%s)", target.Context.Name, target.Name, target.Help)
|
|
||||||
|
|
||||||
msg.Target = msg.Target.Owner
|
|
||||||
if msg.Target != nil && msg.Check(msg.Target, "caches", "username") && msg.Check(msg.Target, "caches", "group") {
|
|
||||||
m.Echo(" %s %s", msg.Cap("username"), msg.Cap("group"))
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Echo("\n")
|
|
||||||
msg.Target = target
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
case len(arg) > 0:
|
|
||||||
cli.next = strings.Join(arg, " ")
|
|
||||||
cli.temp = v.Target
|
|
||||||
default:
|
|
||||||
cli.target = v.Target
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"source": &ctx.Command{Name: "source file", Help: "运行脚本", Hand: func(m *ctx.Message, c *ctx.Context, 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) // {{{
|
cli := c.Server.(*CLI) // {{{
|
||||||
switch len(arg) {
|
switch len(arg) {
|
||||||
@ -511,27 +401,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"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:
|
|
||||||
for i, v := range cli.history {
|
|
||||||
m.Echo("%d %s %s\n", i, v["time"], v["cli"])
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
n, e := strconv.Atoi(arg[0])
|
|
||||||
if e == nil && 0 <= n && n < len(cli.history) {
|
|
||||||
cli.next = cli.history[n]["cli"]
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
n, e := strconv.Atoi(arg[0])
|
|
||||||
if e == nil && 0 <= n && n < len(cli.history) {
|
|
||||||
cli.history[n]["cli"] = strings.Join(arg[1:], " ")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"remote": &ctx.Command{Name: "remote [send args...]|[[master|slaver] listen|dial address protocol]", 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},
|
Formats: map[string]int{"send": -1, "master": 0, "slaver": 0, "listen": 1, "dial": 1},
|
||||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
||||||
@ -554,7 +423,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
if m.Has("listen") {
|
if m.Has("listen") {
|
||||||
action = "listen"
|
action = "listen"
|
||||||
}
|
}
|
||||||
msg := m.Find(m.Get("args"), m.Target.Root)
|
|
||||||
|
msg := m.Find(m.Get("args"), true)
|
||||||
|
|
||||||
if m.Has("master") {
|
if m.Has("master") {
|
||||||
msg.Template = msg.Spawn(msg.Source).Add("option", "master")
|
msg.Template = msg.Spawn(msg.Source).Add("option", "master")
|
||||||
@ -571,8 +441,20 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
|
"master": &ctx.Command{Name: "open [master|slaver] [script [log]]", Help: "建立远程连接",
|
||||||
|
Options: map[string]string{"master": "主控终端", "slaver": "被控终端", "args": "启动参数", "io": "读写流"},
|
||||||
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
||||||
|
cli, ok := c.Server.(*CLI) // {{{
|
||||||
|
m.Assert(ok, "模块类型错误")
|
||||||
|
m.Assert(m.Target != c, "模块是主控模块")
|
||||||
|
|
||||||
|
msg := m.Spawn(c)
|
||||||
|
msg.Start(fmt.Sprintf("PTS%d", cli.Capi("nterm")), arg[0], arg[1:]...)
|
||||||
|
m.Target.Master = msg.Target
|
||||||
|
return ""
|
||||||
|
// }}}
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
Messages: make(chan *ctx.Message, 10),
|
|
||||||
Index: map[string]*ctx.Context{
|
Index: map[string]*ctx.Context{
|
||||||
"void": &ctx.Context{Name: "void",
|
"void": &ctx.Context{Name: "void",
|
||||||
Commands: map[string]*ctx.Command{
|
Commands: map[string]*ctx.Command{
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -23,15 +23,6 @@ func (mdb *MDB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
|||||||
}
|
}
|
||||||
c.Configs = map[string]*ctx.Config{}
|
c.Configs = map[string]*ctx.Config{}
|
||||||
|
|
||||||
if len(arg) > 0 {
|
|
||||||
m.Cap("source", arg[0])
|
|
||||||
}
|
|
||||||
if len(arg) > 1 {
|
|
||||||
m.Cap("driver", arg[1])
|
|
||||||
} else {
|
|
||||||
m.Cap("driver", m.Conf("driver"))
|
|
||||||
}
|
|
||||||
|
|
||||||
s := new(MDB)
|
s := new(MDB)
|
||||||
s.Context = c
|
s.Context = c
|
||||||
return s
|
return s
|
||||||
@ -57,18 +48,19 @@ func (mdb *MDB) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m.Cap("stream", m.Cap("source"))
|
||||||
db, e := sql.Open(m.Cap("driver"), m.Cap("source"))
|
db, e := sql.Open(m.Cap("driver"), m.Cap("source"))
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
mdb.DB = db
|
mdb.DB = db
|
||||||
|
|
||||||
m.Log("info", "%s: %d open %s %s", mdb.Name, m.Capi("nsource", 1), m.Cap("driver"), m.Cap("source"))
|
m.Log("info", nil, "%d open %s %s", m.Capi("nsource", 1), m.Cap("driver"), m.Cap("source"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { // {{{
|
func (mdb *MDB) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
if mdb.DB != nil && m.Target == mdb.Context {
|
if mdb.DB != nil && m.Target == mdb.Context {
|
||||||
m.Log("info", "%s: %d close %s %s", mdb.Name, m.Capi("nsource", -1)+1, m.Cap("driver"), m.Cap("source"))
|
m.Log("info", nil, "%d close %s %s", m.Capi("nsource", -1)+1, m.Cap("driver"), m.Cap("source"))
|
||||||
mdb.DB.Close()
|
mdb.DB.Close()
|
||||||
mdb.DB = nil
|
mdb.DB = nil
|
||||||
return true
|
return true
|
||||||
@ -87,13 +79,15 @@ var Index = &ctx.Context{Name: "mdb", Help: "内存数据库",
|
|||||||
"driver": &ctx.Config{Name: "数据库驱动(mysql)", Value: "mysql", Help: "数据库驱动"},
|
"driver": &ctx.Config{Name: "数据库驱动(mysql)", Value: "mysql", Help: "数据库驱动"},
|
||||||
},
|
},
|
||||||
Commands: map[string]*ctx.Command{
|
Commands: map[string]*ctx.Command{
|
||||||
"open": &ctx.Command{Name: "open name help [source [driver]]", Help: "打开数据库", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
"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.Assert(len(arg) > 2, "缺少参数") // {{{
|
||||||
|
m.Master, m.Target = c, c
|
||||||
|
m.Cap("stream", m.Cap("nsource"))
|
||||||
m.Start(arg[0], arg[1], arg[2:]...)
|
m.Start(arg[0], arg[1], arg[2:]...)
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"exec": &ctx.Command{Name: "exec sql [arg]", Help: "执行操作语句",
|
"exec": &ctx.Command{Name: "exec sql [arg]", Help: "操作数据库",
|
||||||
Appends: map[string]string{"LastInsertId": "最后插入元组的标识", "RowsAffected": "修改元组的数量"},
|
Appends: map[string]string{"LastInsertId": "最后插入元组的标识", "RowsAffected": "修改元组的数量"},
|
||||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
||||||
mdb, ok := m.Target.Server.(*MDB) // {{{
|
mdb, ok := m.Target.Server.(*MDB) // {{{
|
||||||
@ -113,9 +107,10 @@ var Index = &ctx.Context{Name: "mdb", Help: "内存数据库",
|
|||||||
n, e := ret.RowsAffected()
|
n, e := ret.RowsAffected()
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
|
|
||||||
|
m.Echo("%d", id).Echo("%d", n)
|
||||||
m.Add("append", "LastInsertId", fmt.Sprintf("%d", id))
|
m.Add("append", "LastInsertId", fmt.Sprintf("%d", id))
|
||||||
m.Add("append", "RowsAffected", fmt.Sprintf("%d", n))
|
m.Add("append", "RowsAffected", fmt.Sprintf("%d", n))
|
||||||
m.Log("info", "%s: last(%d) rows(%d)", m.Target.Name, id, n)
|
m.Log("info", nil, "last(%d) rows(%d)", id, n)
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
@ -158,17 +153,7 @@ var Index = &ctx.Context{Name: "mdb", Help: "内存数据库",
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Log("info", "%s: cols(%d) rows(%d)", m.Target.Name, len(m.Meta["append"]), len(m.Meta[m.Meta["append"][0]]))
|
m.Log("info", nil, "rows(%d) cols(%d)", len(m.Meta[m.Meta["append"][0]]), len(m.Meta["append"]))
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"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 ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
|
@ -2,21 +2,12 @@ package ssh
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
_ "context/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SSH struct {
|
type SSH struct {
|
||||||
*ctx.Context
|
*ctx.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
|
||||||
return ssh
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ssh *SSH) Spawn(m *ctx.Message, c *ctx.Context, 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.Caches = map[string]*ctx.Cache{}
|
||||||
c.Configs = map[string]*ctx.Config{}
|
c.Configs = map[string]*ctx.Config{}
|
||||||
@ -27,8 +18,16 @@ func (ssh *SSH) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server {
|
||||||
|
return ssh
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool {
|
func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool {
|
||||||
return true
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var Index = &ctx.Context{Name: "ssh", Help: "加密终端",
|
var Index = &ctx.Context{Name: "ssh", Help: "加密终端",
|
||||||
|
@ -47,7 +47,7 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
tcp.Conn = c
|
tcp.Conn = c
|
||||||
|
|
||||||
m.Log("info", "%s: dial(%d) %v->%v", tcp.Name, m.Capi("nclient"), c.LocalAddr(), c.RemoteAddr())
|
m.Log("info", nil, "dial(%d) %v->%v", m.Capi("nclient"), c.LocalAddr(), c.RemoteAddr())
|
||||||
// m.Reply(c.LocalAddr().String()).Put("option", "io", c).Cmd("open")
|
// m.Reply(c.LocalAddr().String()).Put("option", "io", c).Cmd("open")
|
||||||
return false
|
return false
|
||||||
case "accept":
|
case "accept":
|
||||||
@ -58,15 +58,24 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
tcp.Listener = l
|
tcp.Listener = l
|
||||||
|
|
||||||
m.Log("info", "%s: listen(%d) %v", tcp.Name, m.Capi("nlisten"), l.Addr())
|
m.Log("info", nil, "listen(%d) %v", m.Capi("nlisten"), l.Addr())
|
||||||
|
|
||||||
for {
|
for {
|
||||||
c, e := l.Accept()
|
c, e := l.Accept()
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
|
|
||||||
msg := m.Spawn(tcp.Context.Context)
|
s, i := m.Target, 0
|
||||||
|
m.BackTrace(func(m *ctx.Message) bool {
|
||||||
|
s = m.Target
|
||||||
|
if i++; i == 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
msg := m.Spawn(s)
|
||||||
msg.Start(fmt.Sprintf("com%d", m.Capi("nclient", 1)), c.RemoteAddr().String(), "accept", c.RemoteAddr().String())
|
msg.Start(fmt.Sprintf("com%d", m.Capi("nclient", 1)), c.RemoteAddr().String(), "accept", c.RemoteAddr().String())
|
||||||
msg.Log("info", "%s: accept(%d) %v<-%v", tcp.Name, m.Capi("nclient"), c.LocalAddr(), c.RemoteAddr())
|
msg.Log("info", nil, "accept(%d) %v<-%v", m.Capi("nclient"), c.LocalAddr(), c.RemoteAddr())
|
||||||
|
|
||||||
if tcp, ok := msg.Target.Server.(*TCP); ok {
|
if tcp, ok := msg.Target.Server.(*TCP); ok {
|
||||||
tcp.Conn = c
|
tcp.Conn = c
|
||||||
@ -82,7 +91,7 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool { // {{{
|
func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
if tcp.Listener != nil {
|
if tcp.Listener != nil {
|
||||||
m.Log("info", "%s: close(%d) %v", tcp.Name, m.Capi("nlisten", -1)+1, tcp.Listener.Addr())
|
m.Log("info", nil, "close(%d) %v", m.Capi("nlisten", -1)+1, tcp.Listener.Addr())
|
||||||
tcp.Listener.Close()
|
tcp.Listener.Close()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -2,51 +2,60 @@ package web // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
import ( // {{{
|
import ( // {{{
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"bufio"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
type WEB struct {
|
|
||||||
Run bool
|
|
||||||
Master bool
|
|
||||||
|
|
||||||
*http.ServeMux
|
|
||||||
*http.Server
|
|
||||||
|
|
||||||
M *ctx.Message
|
|
||||||
*ctx.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
type MUX interface {
|
type MUX interface {
|
||||||
Handle(string, http.Handler)
|
Handle(string, http.Handler)
|
||||||
HandleFunc(string, func(http.ResponseWriter, *http.Request))
|
HandleFunc(string, func(http.ResponseWriter, *http.Request))
|
||||||
Trans(*ctx.Message, string, ...string)
|
Trans(*ctx.Message, string, func(*ctx.Message, *ctx.Context, string, ...string) string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (web *WEB) Trans(m *ctx.Message, key string, arg ...string) { // {{{
|
type WEB struct {
|
||||||
|
*http.ServeMux
|
||||||
|
*http.Server
|
||||||
|
|
||||||
|
*ctx.Message
|
||||||
|
*ctx.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.Context, string, ...string) string) { // {{{
|
||||||
web.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) {
|
web.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) {
|
||||||
m.Set("detail", key)
|
msg := m.Spawn(m.Target)
|
||||||
|
msg.Set("detail", key)
|
||||||
for k, v := range r.Form {
|
for k, v := range r.Form {
|
||||||
m.Add("option", k)
|
msg.Add("option", k)
|
||||||
m.Meta[k] = v
|
msg.Meta[k] = v
|
||||||
}
|
}
|
||||||
for _, v := range r.Cookies() {
|
for _, v := range r.Cookies() {
|
||||||
m.Add("option", v.Name, v.Value)
|
msg.Add("option", v.Name, v.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Cmd(arg...)
|
msg.Log("cmd", nil, "%s %v", key, msg.Meta["option"])
|
||||||
|
msg.Put("option", "request", r)
|
||||||
|
msg.Put("option", "response", w)
|
||||||
|
|
||||||
|
ret := hand(msg, msg.Target, key)
|
||||||
|
if ret != "" {
|
||||||
|
msg.Echo(ret)
|
||||||
|
}
|
||||||
|
|
||||||
header := w.Header()
|
header := w.Header()
|
||||||
for _, k := range m.Meta["append"] {
|
for _, k := range msg.Meta["append"] {
|
||||||
ce := &http.Cookie{Name: k, Value: m.Get(k)}
|
ce := &http.Cookie{Name: k, Value: msg.Get(k)}
|
||||||
header.Add("Set-Cookie", ce.String())
|
header.Add("Set-Cookie", ce.String())
|
||||||
}
|
}
|
||||||
for _, v := range m.Meta["result"] {
|
for _, v := range msg.Meta["result"] {
|
||||||
w.Write([]byte(v))
|
w.Write([]byte(v))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -54,21 +63,19 @@ func (web *WEB) Trans(m *ctx.Message, key string, arg ...string) { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{
|
func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{
|
||||||
if web.Master {
|
if web.Message != nil {
|
||||||
log.Println()
|
log.Println()
|
||||||
web.M.Log("info", "%s: %v %s %s", web.Name, r.RemoteAddr, r.Method, r.URL)
|
web.Log("cmd", nil, "%v %s %s", r.RemoteAddr, r.Method, r.URL)
|
||||||
defer log.Println()
|
defer log.Println()
|
||||||
|
|
||||||
if web.M.Conf("logheaders") == "yes" {
|
if web.Cap("logheaders") == "yes" {
|
||||||
for k, v := range r.Header {
|
for k, v := range r.Header {
|
||||||
log.Println(k+":", v[0])
|
log.Println(k+":", v[0])
|
||||||
}
|
}
|
||||||
log.Println()
|
log.Println()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
if web.Master {
|
|
||||||
if len(r.PostForm) > 0 {
|
if len(r.PostForm) > 0 {
|
||||||
for k, v := range r.PostForm {
|
for k, v := range r.PostForm {
|
||||||
log.Printf("%s: %s", k, v[0])
|
log.Printf("%s: %s", k, v[0])
|
||||||
@ -79,8 +86,8 @@ func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{
|
|||||||
|
|
||||||
web.ServeMux.ServeHTTP(w, r)
|
web.ServeMux.ServeHTTP(w, r)
|
||||||
|
|
||||||
if web.Master {
|
if web.Message != nil {
|
||||||
if web.M.Conf("logheaders") == "yes" {
|
if web.Cap("logheaders") == "yes" {
|
||||||
for k, v := range w.Header() {
|
for k, v := range w.Header() {
|
||||||
log.Println(k+":", v[0])
|
log.Println(k+":", v[0])
|
||||||
}
|
}
|
||||||
@ -90,79 +97,10 @@ func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|
||||||
web.Configs["logheaders"] = &ctx.Config{Name: "logheaders", Value: "yes", Help: "日志输出请求头"}
|
|
||||||
web.Configs["directory"] = &ctx.Config{Name: "directory", Value: "usr", Help: "服务目录"}
|
|
||||||
web.Configs["protocol"] = &ctx.Config{Name: "protocol", Value: "http", Help: "服务协议"}
|
|
||||||
web.Configs["address"] = &ctx.Config{Name: "address", Value: ":9393", Help: "监听地址"}
|
|
||||||
web.Configs["route"] = &ctx.Config{Name: "route", Value: "/" + web.Name + "/", Help: "请求路径"}
|
|
||||||
|
|
||||||
web.ServeMux = http.NewServeMux()
|
|
||||||
mux := m.Target.Server.(MUX)
|
|
||||||
for k, _ := range web.Commands {
|
|
||||||
if k[0] == '/' {
|
|
||||||
mux.Trans(m, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return web
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (web *WEB) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|
||||||
web.M = m
|
|
||||||
|
|
||||||
if !web.Run {
|
|
||||||
web.Run = true
|
|
||||||
|
|
||||||
if s, ok := m.Target.Context.Server.(MUX); ok {
|
|
||||||
if h, ok := m.Target.Server.(http.Handler); ok {
|
|
||||||
m.Log("info", "%s: route %s -> %s", web.Context.Context.Name, m.Conf("route"), web.Name)
|
|
||||||
s.Handle(m.Conf("route"), http.StripPrefix(path.Dir(m.Conf("route")), h))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.Conf("directory") != "" {
|
|
||||||
m.Log("info", "%s: directory [%s]", web.Name, m.Conf("directory"))
|
|
||||||
web.Handle("/", http.FileServer(http.Dir(m.Conf("directory"))))
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Set("detail", "slaver")
|
|
||||||
m.Travel(web.Context, func(m *ctx.Message) bool {
|
|
||||||
if m.Target != web.Context {
|
|
||||||
m.Target.Start(m)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if len(arg) > 0 && arg[0] == "slaver" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.Conf("address") == "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
web.Server = &http.Server{Addr: m.Conf("address"), Handler: web}
|
|
||||||
|
|
||||||
m.Log("info", "%s: protocol [%s]", web.Name, m.Conf("protocol"))
|
|
||||||
m.Log("info", "%s: address [%s]", web.Name, m.Conf("address"))
|
|
||||||
web.Master = true
|
|
||||||
|
|
||||||
if m.Conf("protocol") == "https" {
|
|
||||||
m.Log("info", "%s: cert [%s]", web.Name, m.Conf("cert"))
|
|
||||||
m.Log("info", "%s: key [%s]", web.Name, m.Conf("key"))
|
|
||||||
web.Server.ListenAndServeTLS(m.Conf("cert"), m.Conf("key"))
|
|
||||||
} else {
|
|
||||||
web.Server.ListenAndServe()
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (web *WEB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
|
func (web *WEB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{
|
||||||
c.Caches = map[string]*ctx.Cache{}
|
c.Caches = map[string]*ctx.Cache{
|
||||||
|
"directory": &ctx.Cache{Name: "directory", Value: "usr", Help: "服务目录"},
|
||||||
|
}
|
||||||
c.Configs = map[string]*ctx.Config{}
|
c.Configs = map[string]*ctx.Config{}
|
||||||
|
|
||||||
s := new(WEB)
|
s := new(WEB)
|
||||||
@ -171,51 +109,165 @@ func (web *WEB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (web *WEB) Close(m *ctx.Message, arg ...string) bool { // {{{
|
func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
||||||
|
if len(arg) > 0 {
|
||||||
|
m.Cap("directory", arg[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
web.Caches["route"] = &ctx.Cache{Name: "route", Value: "/" + web.Context.Name + "/", Help: "请求路径"}
|
||||||
|
web.Caches["register"] = &ctx.Cache{Name: "已初始化(yes/no)", Value: "no", Help: "模块是否已注册"}
|
||||||
|
web.Caches["master"] = &ctx.Cache{Name: "master(yes/no)", Value: "no", Help: "日志输出请求头"}
|
||||||
|
m.Cap("stream", m.Cap("route")+" -> "+m.Cap("directory"))
|
||||||
|
|
||||||
|
web.ServeMux = http.NewServeMux()
|
||||||
|
if mux, ok := m.Target.Server.(MUX); ok {
|
||||||
|
for k, x := range web.Commands {
|
||||||
|
if k[0] == '/' {
|
||||||
|
mux.Trans(m, k, x.Hand)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return web
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
func (web *WEB) Start(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
|
if len(arg) > 0 {
|
||||||
|
m.Cap("directory", arg[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
web.Message = m
|
||||||
|
m.Cap("master", "yes")
|
||||||
|
|
||||||
|
m.Travel(m.Target, func(m *ctx.Message) bool {
|
||||||
|
if h, ok := m.Target.Server.(http.Handler); ok && m.Cap("register") == "no" {
|
||||||
|
m.Cap("register", "yes")
|
||||||
|
|
||||||
|
p, i := m.Target, 0
|
||||||
|
m.BackTrace(func(m *ctx.Message) bool {
|
||||||
|
p = m.Target
|
||||||
|
if i++; i == 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
if s, ok := p.Server.(MUX); ok {
|
||||||
|
m.Log("info", p, "route %s -> %s", m.Cap("route"), m.Target.Name)
|
||||||
|
s.Handle(m.Cap("route"), http.StripPrefix(path.Dir(m.Cap("route")), h))
|
||||||
|
}
|
||||||
|
|
||||||
|
if s, ok := m.Target.Server.(MUX); ok && m.Cap("directory") != "" {
|
||||||
|
m.Log("info", nil, "dir / -> [%s]", m.Cap("directory"))
|
||||||
|
s.Handle("/", http.FileServer(http.Dir(m.Cap("directory"))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
web.Caches["address"] = &ctx.Cache{Name: "address", Value: ":9393", Help: "监听地址"}
|
||||||
|
web.Caches["protocol"] = &ctx.Cache{Name: "protocol", Value: "http", Help: "服务协议"}
|
||||||
|
if len(arg) > 1 {
|
||||||
|
m.Cap("address", arg[1])
|
||||||
|
}
|
||||||
|
if len(arg) > 2 {
|
||||||
|
m.Cap("protocol", arg[2])
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Cap("stream", m.Cap("address"))
|
||||||
|
m.Log("info", nil, "address [%s]", m.Cap("address"))
|
||||||
|
m.Log("info", nil, "protocol [%s]", m.Cap("protocol"))
|
||||||
|
web.Server = &http.Server{Addr: m.Cap("address"), Handler: web}
|
||||||
|
|
||||||
|
web.Caches["logheaders"] = &ctx.Cache{Name: "日志输出报文头(yes/no)", Value: "yes", Help: "日志输出请求头"}
|
||||||
|
|
||||||
|
if m.Cap("protocol") == "https" {
|
||||||
|
m.Log("info", nil, "key [%s]", m.Cap("key"))
|
||||||
|
m.Log("info", nil, "cert [%s]", m.Cap("cert"))
|
||||||
|
web.Server.ListenAndServeTLS(m.Cap("cert"), m.Cap("key"))
|
||||||
|
} else {
|
||||||
|
web.Server.ListenAndServe()
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
func (web *WEB) Close(m *ctx.Message, arg ...string) bool { // {{{
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
var Index = &ctx.Context{Name: "web", Help: "网页服务",
|
var Index = &ctx.Context{Name: "web", Help: "网页服务",
|
||||||
Caches: map[string]*ctx.Cache{},
|
Caches: map[string]*ctx.Cache{
|
||||||
|
"directory": &ctx.Cache{Name: "directory", Value: "usr", Help: "服务目录"},
|
||||||
|
},
|
||||||
Configs: map[string]*ctx.Config{},
|
Configs: map[string]*ctx.Config{},
|
||||||
Commands: map[string]*ctx.Command{
|
Commands: map[string]*ctx.Command{
|
||||||
"listen": &ctx.Command{Name: "listen [address [protocol [directory]]]", Help: "开启网页服务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
"listen": &ctx.Command{Name: "listen [directory [address [protocol]]]", Help: "开启网页服务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
||||||
if len(arg) > 0 { // {{{
|
m.Meta["detail"] = arg // {{{
|
||||||
m.Conf("address", arg[0])
|
m.Target.Start(m)
|
||||||
}
|
|
||||||
if len(arg) > 1 {
|
|
||||||
m.Conf("protocol", arg[1])
|
|
||||||
}
|
|
||||||
if len(arg) > 2 {
|
|
||||||
m.Conf("directory", arg[2])
|
|
||||||
}
|
|
||||||
go m.Target.Start(m)
|
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"content": &ctx.Command{Name: "content route template", Help: "添加响应", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
"route": &ctx.Command{Name: "route [directory|template|script] route string", Help: "添加响应", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
||||||
mux, ok := m.Target.Server.(MUX) // {{{
|
mux, ok := m.Target.Server.(MUX) // {{{
|
||||||
if !ok {
|
m.Assert(ok, "模块类型错误")
|
||||||
return ""
|
m.Assert(len(arg) == 3, "缺少参数")
|
||||||
|
|
||||||
|
switch arg[0] {
|
||||||
|
case "directory":
|
||||||
|
mux.Handle(arg[1], http.FileServer(http.Dir(arg[2])))
|
||||||
|
case "template":
|
||||||
|
mux.Trans(m, arg[1], func(m *ctx.Message, c *ctx.Context, key string, a ...string) string { // {{{
|
||||||
|
w := m.Data["response"].(http.ResponseWriter)
|
||||||
|
|
||||||
|
if _, e := os.Stat(arg[2]); e == nil {
|
||||||
|
template.Must(template.ParseGlob(arg[2])).Execute(w, m)
|
||||||
|
} else {
|
||||||
|
template.Must(template.New("temp").Parse(arg[2])).Execute(w, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
mux.HandleFunc(arg[0], func(w http.ResponseWriter, r *http.Request) {
|
return ""
|
||||||
if _, e := os.Stat(arg[1]); e == nil {
|
|
||||||
template.Must(template.ParseGlob(arg[1])).Execute(w, m.Target)
|
|
||||||
} else {
|
|
||||||
template.Must(template.New("temp").Parse(arg[1])).Execute(w, m.Target)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
// }}}
|
||||||
|
case "script":
|
||||||
|
cli := m.Find("cli", true) // {{{
|
||||||
|
lex := m.Find("lex", true)
|
||||||
|
mux.Trans(m, arg[1], func(m *ctx.Message, c *ctx.Context, key string, a ...string) string {
|
||||||
|
f, e := os.Open(arg[2])
|
||||||
|
line, bio := "", bufio.NewReader(f)
|
||||||
|
|
||||||
|
if e != nil {
|
||||||
|
line = arg[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
if line = strings.TrimSpace(line); line != "" {
|
||||||
|
lex.Cmd("split", line, "void")
|
||||||
|
cli.Wait = make(chan bool)
|
||||||
|
cli.Cmd(lex.Meta["result"]...)
|
||||||
|
m.Meta["result"] = cli.Meta["result"]
|
||||||
|
}
|
||||||
|
|
||||||
|
if line, e = bio.ReadString('\n'); e != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
})
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"/hi": &ctx.Command{Name: "/hi", Help: "添加响应", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
"/hi": &ctx.Command{Name: "/hi", Help: "添加响应", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) string {
|
||||||
m.Echo("hello\n")
|
|
||||||
m.Add("append", "hi", "hello")
|
m.Add("append", "hi", "hello")
|
||||||
m.Add("append", "hi", "hello")
|
return "hello"
|
||||||
return "hello\n"
|
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user