diff --git a/base/base.go b/base/base.go index a3437bcf..5e47f822 100644 --- a/base/base.go +++ b/base/base.go @@ -9,7 +9,6 @@ import ( _ "shylinux.com/x/icebergs/base/gdb" _ "shylinux.com/x/icebergs/base/lex" _ "shylinux.com/x/icebergs/base/log" - _ "shylinux.com/x/icebergs/base/yac" _ "shylinux.com/x/icebergs/base/mdb" diff --git a/base/base.shy b/base/base.shy index b10512cf..0aca33b1 100644 --- a/base/base.shy +++ b/base/base.shy @@ -1,4 +1,4 @@ -label "base" ` +label ` ctx cli web aaa lex yac gdb log tcp nfs ssh mdb diff --git a/base/gdb/event.go b/base/gdb/event.go index 740e7312..502ff358 100644 --- a/base/gdb/event.go +++ b/base/gdb/event.go @@ -7,12 +7,10 @@ import ( ) func _event_listen(m *ice.Message, event string, cmd string) { - h := m.Cmdx(mdb.INSERT, EVENT, "", mdb.HASH, EVENT, event) - m.Cmdy(mdb.INSERT, EVENT, kit.Keys(kit.MDB_HASH, h), mdb.LIST, ice.CMD, cmd) + m.Cmdy(mdb.INSERT, EVENT, "", mdb.ZONE, event, ice.CMD, cmd) } func _event_action(m *ice.Message, event string, arg ...string) { - m.Option(mdb.FIELDS, "time,id,cmd") - m.Cmd(mdb.SELECT, EVENT, kit.Keys(kit.MDB_HASH, kit.Hashs(event)), mdb.LIST).Table(func(index int, value map[string]string, head []string) { + mdb.ZoneSelect(m, event).Table(func(index int, value map[string]string, head []string) { m.Cmd(kit.Split(value[ice.CMD]), event, arg).Cost(EVENT, event, ice.ARG, arg) }) } @@ -20,32 +18,22 @@ func _event_action(m *ice.Message, event string, arg ...string) { const EVENT = "event" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - EVENT: {Name: EVENT, Help: "事件流", Value: kit.Data(kit.MDB_SHORT, EVENT)}, - }, - Commands: map[string]*ice.Command{ - EVENT: {Name: "event event id auto listen", Help: "事件流", Action: map[string]*ice.Action{ - LISTEN: {Name: "listen event cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) { - _event_listen(m, m.Option(EVENT), m.Option(ice.CMD)) - }}, - ACTION: {Name: "action event arg", Help: "触发", Hand: func(m *ice.Message, arg ...string) { - _event_action(m, m.Option(EVENT), arg[2:]...) - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, EVENT, "", mdb.HASH, EVENT, m.Option(EVENT)) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) == 0 { // 事件列表 - m.Fields(len(arg), "time,event,count") - m.Cmdy(mdb.SELECT, EVENT, "", mdb.HASH) - m.PushAction(ACTION, mdb.REMOVE) - return - } - - m.Fields(len(arg[1:]), "time,id,cmd") - m.Cmdy(mdb.SELECT, EVENT, kit.Keys(kit.MDB_HASH, kit.Hashs(arg[0])), mdb.LIST, kit.MDB_ID, arg[1:]) + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + EVENT: {Name: EVENT, Help: "事件流", Value: kit.Data( + kit.MDB_SHORT, EVENT, kit.MDB_FIELD, "time,id,cmd", + )}, + }, Commands: map[string]*ice.Command{ + EVENT: {Name: "event event id auto listen", Help: "事件流", Action: ice.MergeAction(map[string]*ice.Action{ + LISTEN: {Name: "listen event cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) { + _event_listen(m, m.Option(EVENT), m.Option(ice.CMD)) }}, - }, - }) + ACTION: {Name: "action event arg", Help: "触发", Hand: func(m *ice.Message, arg ...string) { + _event_action(m, m.Option(EVENT), arg[2:]...) + }}, + }, mdb.ZoneAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if mdb.ZoneSelect(m, arg...); len(arg) == 0 { + m.PushAction(ACTION, mdb.REMOVE) + } + }}, + }}) } diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go index 5bc427e3..f56258cc 100644 --- a/base/gdb/gdb.go +++ b/base/gdb/gdb.go @@ -5,8 +5,6 @@ import ( "time" ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/cli" - "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" ) @@ -34,8 +32,8 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { case s := <-f.s: m.Cmd(SIGNAL, ACTION, SIGNAL, s) - case <-f.t: - _timer_action(m.Spawn()) + // case <-f.t: + // m.Cmd(TIMER, ACTION) } } return true @@ -46,23 +44,18 @@ func (f *Frame) Close(m *ice.Message, arg ...string) bool { const GDB = "gdb" -var Index = &ice.Context{Name: GDB, Help: "事件模块", - Commands: map[string]*ice.Command{ - ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmd(nfs.SAVE, kit.Select(m.Conf(SIGNAL, kit.META_PATH), m.Conf(cli.RUNTIME, kit.Keys(cli.CONF, cli.CTX_PID))), - m.Conf(cli.RUNTIME, kit.Keys(cli.HOST, cli.PID))) - - m.Cmd(SIGNAL, LISTEN, SIGNAL, "3", kit.MDB_NAME, "退出", ice.CMD, "exit 0") - m.Cmd(SIGNAL, LISTEN, SIGNAL, "2", kit.MDB_NAME, "重启", ice.CMD, "exit 1") - m.Load() - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if f, ok := m.Target().Server().(*Frame); ok { - f.e <- true - } - m.Save(TIMER) - }}, - }, -} +var Index = &ice.Context{Name: GDB, Help: "事件模块", Commands: map[string]*ice.Command{ + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmd(SIGNAL, LISTEN, SIGNAL, "3", kit.MDB_NAME, "退出", ice.CMD, "exit 0") + m.Cmd(SIGNAL, LISTEN, SIGNAL, "2", kit.MDB_NAME, "重启", ice.CMD, "exit 1") + m.Load() + }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if f, ok := m.Target().Server().(*Frame); ok { + f.e <- true + } + m.Save() + }}, +}} func init() { ice.Index.Register(Index, &Frame{}, ROUTINE, SIGNAL, EVENT, TIMER) } diff --git a/base/gdb/routine.go b/base/gdb/routine.go index a609680f..501dfaf3 100644 --- a/base/gdb/routine.go +++ b/base/gdb/routine.go @@ -5,57 +5,35 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" - "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" ) -const ( - TASK_HASH = "task.hash" -) const ( INNER = "inner" ) const ROUTINE = "routine" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - ROUTINE: {Name: ROUTINE, Help: "协程池", Value: kit.Data()}, - }, - Commands: map[string]*ice.Command{ - ROUTINE: {Name: "routine hash auto prunes", Help: "协程池", Action: map[string]*ice.Action{ - mdb.CREATE: {Name: "create fileline status", Help: "创建", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.INSERT, ROUTINE, "", mdb.HASH, arg) - }}, - mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.MODIFY, ROUTINE, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), arg) - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, ROUTINE, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) - }}, - mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - m.Option(mdb.FIELDS, "time,hash,status,fileline") - m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, kit.MDB_STATUS, cli.ERROR) - m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, kit.MDB_STATUS, cli.STOP) - }}, - - INNER: {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) { - switch kit.Select("", arg, 0) { - case ice.RUN: - m.Cmdy(INNER, arg[1:]) - default: - ls := kit.Split(m.Option("fileline"), ":") - m.ProcessField(INNER, ice.RUN) - m.Option(ice.ARG, kit.Format([]string{path.Dir(ls[0]), path.Base(ls[0]), ls[1]})) - m.Cmdy(ctx.COMMAND, INNER) - } - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Fields(len(arg), "time,hash,status,fileline") - m.Cmdy(mdb.SELECT, ROUTINE, "", mdb.HASH, kit.MDB_HASH, arg) - m.PushAction(INNER, mdb.REMOVE) + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + ROUTINE: {Name: ROUTINE, Help: "协程池", Value: kit.Data( + kit.MDB_SHORT, "time,hash,status,fileline", + )}, + }, Commands: map[string]*ice.Command{ + ROUTINE: {Name: "routine hash auto prunes", Help: "协程池", Action: ice.MergeAction(map[string]*ice.Action{ + mdb.CREATE: {Name: "create fileline status", Help: "创建"}, + mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { + m.OptionFields(m.Config(kit.MDB_SHORT)) + m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, kit.MDB_STATUS, cli.STOP) + m.Cmdy(mdb.PRUNES, ROUTINE, "", mdb.HASH, kit.MDB_STATUS, cli.ERROR) }}, - }, - }) + INNER: {Name: "inner", Help: "源码", Hand: func(m *ice.Message, arg ...string) { + ls := kit.Split(m.Option("fileline"), ":") + m.ProcessCommand(INNER, []string{path.Dir(ls[0]), path.Base(ls[0]), ls[1]}, arg...) + }}, + }, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + mdb.HashSelect(m, arg...) + m.PushAction(INNER, mdb.REMOVE) + }}, + }}) } diff --git a/base/gdb/signal.go b/base/gdb/signal.go index 8e3e29b5..19dfcce9 100644 --- a/base/gdb/signal.go +++ b/base/gdb/signal.go @@ -7,8 +7,11 @@ import ( "syscall" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" + log "shylinux.com/x/toolkits/logs" ) func _signal_listen(m *ice.Message, s int, arg ...string) { @@ -17,10 +20,8 @@ func _signal_listen(m *ice.Message, s int, arg ...string) { signal.Notify(f.s, syscall.Signal(s)) } } -func _signal_action(m *ice.Message, s int) { - m.Option(mdb.FIELDS, "time,signal,name,cmd") - msg := m.Cmd(mdb.SELECT, SIGNAL, "", mdb.HASH, SIGNAL, s) - msg.Table(func(index int, value map[string]string, head []string) { +func _signal_action(m *ice.Message, arg ...string) { + mdb.HashSelect(m.Spawn(), arg...).Table(func(index int, value map[string]string, head []string) { m.Cmdy(kit.Split(value[ice.CMD])) }) } @@ -44,29 +45,32 @@ const ( const SIGNAL = "signal" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - SIGNAL: {Name: SIGNAL, Help: "信号器", Value: kit.Data( - kit.MDB_PATH, path.Join(ice.VAR_RUN, "ice.pid"), kit.MDB_SHORT, SIGNAL, - )}, - }, - Commands: map[string]*ice.Command{ - SIGNAL: {Name: "signal signal auto listen", Help: "信号器", Action: map[string]*ice.Action{ - LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) { - _signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...) - }}, - ACTION: {Name: "action signal", Help: "触发", Hand: func(m *ice.Message, arg ...string) { - _signal_action(m, kit.Int(m.Option(SIGNAL))) - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, SIGNAL, "", mdb.HASH, SIGNAL, m.Option(SIGNAL)) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Fields(len(arg), "time,signal,name,cmd") - m.Cmdy(mdb.SELECT, SIGNAL, "", mdb.HASH, SIGNAL, arg) - m.PushAction(ACTION, mdb.REMOVE) - m.Sort(SIGNAL) + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + SIGNAL: {Name: SIGNAL, Help: "信号器", Value: kit.Data( + kit.MDB_SHORT, SIGNAL, kit.MDB_FIELD, "time,signal,name,cmd", + kit.MDB_PATH, path.Join(ice.VAR_RUN, "ice.pid"), + )}, + }, Commands: map[string]*ice.Command{ + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if log.LogDisable { + return // 禁用日志 + } + m.Cmd(nfs.SAVE, kit.Select(m.Conf(SIGNAL, kit.META_PATH), m.Conf(cli.RUNTIME, kit.Keys(cli.CONF, cli.CTX_PID))), + m.Conf(cli.RUNTIME, kit.Keys(cli.HOST, cli.PID))) + + m.Cmd(SIGNAL, LISTEN, SIGNAL, "3", kit.MDB_NAME, "退出", ice.CMD, "exit 0") + m.Cmd(SIGNAL, LISTEN, SIGNAL, "2", kit.MDB_NAME, "重启", ice.CMD, "exit 1") + }}, + SIGNAL: {Name: "signal signal auto listen", Help: "信号器", Action: ice.MergeAction(map[string]*ice.Action{ + LISTEN: {Name: "listen signal name cmd", Help: "监听", Hand: func(m *ice.Message, arg ...string) { + _signal_listen(m, kit.Int(m.Option(SIGNAL)), arg...) }}, - }, - }) + ACTION: {Name: "action signal", Help: "触发", Hand: func(m *ice.Message, arg ...string) { + _signal_action(m, m.Option(SIGNAL)) + }}, + }, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + mdb.HashSelect(m, arg...).Sort(SIGNAL) + m.PushAction(ACTION, mdb.REMOVE) + }}, + }}) } diff --git a/base/gdb/timer.go b/base/gdb/timer.go index 4be71eb4..d1c54675 100644 --- a/base/gdb/timer.go +++ b/base/gdb/timer.go @@ -9,12 +9,9 @@ import ( kit "shylinux.com/x/toolkits" ) -func _timer_create(m *ice.Message, arg ...string) { - m.Cmdy(mdb.INSERT, TIMER, "", mdb.HASH, DELAY, "10ms", INTERVAL, "10m", ORDER, 1, NEXT, m.Time(m.Option(DELAY)), arg) -} func _timer_action(m *ice.Message, arg ...string) { now := time.Now().UnixNano() - m.Option(mdb.FIELDS, "time,hash,delay,interval,order,next,cmd") + m.OptionFields(m.Config(kit.MDB_FIELD)) m.Richs(TIMER, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { if value = kit.GetMeta(value); value[kit.MDB_STATUS] == cli.STOP { @@ -44,40 +41,31 @@ const ( const TIMER = "timer" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - TIMER: {Name: TIMER, Help: "定时器", Value: kit.Data(TICK, "10ms")}, - }, - Commands: map[string]*ice.Command{ - TIMER: {Name: "timer hash id auto create prunes", Help: "定时器", Action: map[string]*ice.Action{ - mdb.CREATE: {Name: "create delay=10ms interval=10s order=3 cmd=runtime", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - _timer_create(m, arg...) - }}, - mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.MODIFY, TIMER, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), arg) - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, TIMER, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) - }}, - mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - m.Option(mdb.FIELDS, "time,hash,delay,interval,order,next,cmd") - m.Cmdy(mdb.PRUNES, TIMER, "", mdb.HASH, ORDER, 0) - }}, - - ACTION: {Name: "action", Help: "执行", Hand: func(m *ice.Message, arg ...string) { - _timer_action(m, arg...) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) == 0 { - m.Fields(len(arg), "time,hash,delay,interval,order,next,cmd") - m.Cmdy(mdb.SELECT, TIMER, "", mdb.HASH, kit.MDB_HASH, arg) - m.PushAction(mdb.REMOVE) - return - } - - m.Fields(len(arg[1:]), "time,id,res") - m.Cmdy(mdb.SELECT, TIMER, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:]) + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + TIMER: {Name: TIMER, Help: "定时器", Value: kit.Data( + kit.MDB_FIELD, "time,hash,delay,interval,order,next,cmd", + TICK, "10ms", + )}, + }, Commands: map[string]*ice.Command{ + TIMER: {Name: "timer hash id auto create prunes", Help: "定时器", Action: ice.MergeAction(map[string]*ice.Action{ + mdb.CREATE: {Name: "create delay=10ms interval=10s order=3 cmd=runtime", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.INSERT, TIMER, "", mdb.HASH, DELAY, "10ms", INTERVAL, "10m", ORDER, 1, NEXT, m.Time(m.Option(DELAY)), arg) }}, - }, - }) + mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { + m.OptionFields(m.Config(kit.MDB_FIELD)) + m.Cmdy(mdb.PRUNES, TIMER, "", mdb.HASH, ORDER, 0) + }}, + ACTION: {Name: "action", Help: "执行", Hand: func(m *ice.Message, arg ...string) { + _timer_action(m, arg...) + }}, + }, mdb.ZoneAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) == 0 { + m.OptionFields(m.Config(kit.MDB_FIELD)) + defer m.PushAction(mdb.REMOVE) + } else { + m.OptionFields("time,id,res") + } + mdb.ZoneSelect(m, arg...) + }}, + }}) } diff --git a/base/lex/lex.go b/base/lex/lex.go index ab238758..8ebc7d64 100644 --- a/base/lex/lex.go +++ b/base/lex/lex.go @@ -2,32 +2,10 @@ package lex import ( ice "shylinux.com/x/icebergs" - kit "shylinux.com/x/toolkits" ) -func _lex_load(m *ice.Message) { - m.Richs(m.Prefix(MATRIX), "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { - value = kit.GetMeta(value) - - mat := NewMatrix(m, kit.Int(kit.Select("32", value[NLANG])), kit.Int(kit.Select("256", value[NCELL]))) - m.Grows(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { - mat.Train(m, kit.Format(value[NPAGE]), kit.Format(value[NHASH]), kit.Format(value[kit.MDB_TEXT])) - }) - value[MATRIX] = mat - }) -} - const LEX = "lex" -var Index = &ice.Context{Name: LEX, Help: "词法模块", - Commands: map[string]*ice.Command{ - ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - // _lex_load(m.Load()) - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - m.Save() - }}, - }, -} +var Index = &ice.Context{Name: LEX, Help: "词法模块"} func init() { ice.Index.Register(Index, nil) } diff --git a/base/lex/matrix.go b/base/lex/matrix.go index ce00f2dd..7f6f2a72 100644 --- a/base/lex/matrix.go +++ b/base/lex/matrix.go @@ -358,6 +358,17 @@ func (mat *Matrix) show(m *ice.Message) { m.Status(NLANG, mat.nlang, NCELL, mat.ncell, NPAGE, len(mat.page), NHASH, len(mat.hash)) } +func _lex_load(m *ice.Message) { + m.Richs(m.Prefix(MATRIX), "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { + value = kit.GetMeta(value) + + mat := NewMatrix(m, kit.Int(kit.Select("32", value[NLANG])), kit.Int(kit.Select("256", value[NCELL]))) + m.Grows(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { + mat.Train(m, kit.Format(value[NPAGE]), kit.Format(value[NHASH]), kit.Format(value[kit.MDB_TEXT])) + }) + value[MATRIX] = mat + }) +} const ( NLANG = "nlang" @@ -374,88 +385,88 @@ const ( const MATRIX = "matrix" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - MATRIX: {Name: MATRIX, Help: "魔方矩阵", Value: kit.Data()}, - }, - Commands: map[string]*ice.Command{ - MATRIX: {Name: "matrix hash npage text auto", Help: "魔方矩阵", Action: map[string]*ice.Action{ - mdb.CREATE: {Name: "create nlang=32 ncell=128", Help: "创建", Hand: func(m *ice.Message, arg ...string) { - mat := NewMatrix(m, kit.Int(kit.Select("32", m.Option(NLANG))), kit.Int(kit.Select("128", m.Option(NCELL)))) - h := m.Rich(m.Prefix(MATRIX), "", kit.Data(kit.MDB_TIME, m.Time(), MATRIX, mat, NLANG, mat.nlang, NCELL, mat.ncell)) - switch cb := m.Optionv(kit.Keycb(MATRIX)).(type) { - case func(string, *Matrix): - cb(h, mat) - } - m.Echo(h) - }}, - mdb.INSERT: {Name: "insert hash npage=num nhash=num text=123", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.Prefix(MATRIX), "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) { - value = kit.GetMeta(value) - - mat, _ := value[MATRIX].(*Matrix) - m.Echo("%d", mat.Train(m, m.Option(NPAGE), m.Option(NHASH), m.Option(kit.MDB_TEXT))) - m.Grow(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), kit.Dict( - kit.MDB_TIME, m.Time(), NPAGE, m.Option(NPAGE), NHASH, m.Option(NHASH), kit.MDB_TEXT, m.Option(kit.MDB_TEXT), - )) - - value[NPAGE] = len(mat.page) - value[NHASH] = len(mat.hash) - }) - }}, - mdb.REMOVE: {Name: "create", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, m.Prefix(MATRIX), "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) - }}, - PARSE: {Name: "parse hash npage text=123", Help: "解析", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.Prefix(MATRIX), "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) { - value = kit.GetMeta(value) - mat, _ := value[MATRIX].(*Matrix) - - stream := NewStream(bytes.NewBufferString(m.Option(kit.MDB_TEXT))) - hash, word := mat.Parse(m, m.Option(NPAGE), stream) - m.Push(NHASH, kit.Select(kit.Format("%d", hash), mat.word[hash])) - m.Push("word", string(word)) - m.Push("rest", string(stream.b[stream.P:])) - }) - m.ProcessInner() - }}, - "show": {Name: "show", Help: "矩阵", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.Prefix(MATRIX), "", kit.Select(m.Option(kit.MDB_HASH), arg, 0), func(key string, value map[string]interface{}) { - value = kit.GetMeta(value) - value[MATRIX].(*Matrix).show(m) - }) - m.ProcessInner() - }}, - }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表 - m.Fields(len(arg), "time,hash,npage,nhash") - m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), "", mdb.HASH) - m.PushAction(mdb.INSERT, "show", mdb.REMOVE) - return + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + MATRIX: {Name: MATRIX, Help: "魔方矩阵", Value: kit.Data()}, + }, Commands: map[string]*ice.Command{ + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + // _lex_load(m.Load()) + }}, + MATRIX: {Name: "matrix hash npage text auto", Help: "魔方矩阵", Action: map[string]*ice.Action{ + mdb.CREATE: {Name: "create nlang=32 ncell=128", Help: "创建", Hand: func(m *ice.Message, arg ...string) { + mat := NewMatrix(m, kit.Int(kit.Select("32", m.Option(NLANG))), kit.Int(kit.Select("128", m.Option(NCELL)))) + h := m.Rich(m.Prefix(MATRIX), "", kit.Data(kit.MDB_TIME, m.Time(), MATRIX, mat, NLANG, mat.nlang, NCELL, mat.ncell)) + switch cb := m.Optionv(kit.Keycb(MATRIX)).(type) { + case func(string, *Matrix): + cb(h, mat) } + m.Echo(h) + }}, + mdb.INSERT: {Name: "insert hash npage=num nhash=num text=123", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + m.Richs(m.Prefix(MATRIX), "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) { + value = kit.GetMeta(value) - if m.Action(mdb.INSERT, "show"); len(arg) == 1 { // 词法列表 - m.Fields(len(arg[1:]), "time,npage,nhash,text") - m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST) - m.PushAction(PARSE) - return - } + mat, _ := value[MATRIX].(*Matrix) + m.Echo("%d", mat.Train(m, m.Option(NPAGE), m.Option(NHASH), m.Option(kit.MDB_TEXT))) + m.Grow(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), kit.Dict( + kit.MDB_TIME, m.Time(), NPAGE, m.Option(NPAGE), NHASH, m.Option(NHASH), kit.MDB_TEXT, m.Option(kit.MDB_TEXT), + )) - m.Richs(m.Prefix(MATRIX), "", arg[0], func(key string, value map[string]interface{}) { + value[NPAGE] = len(mat.page) + value[NHASH] = len(mat.hash) + }) + }}, + mdb.REMOVE: {Name: "create", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.DELETE, m.Prefix(MATRIX), "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) + }}, + PARSE: {Name: "parse hash npage text=123", Help: "解析", Hand: func(m *ice.Message, arg ...string) { + m.Richs(m.Prefix(MATRIX), "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) { value = kit.GetMeta(value) mat, _ := value[MATRIX].(*Matrix) - if len(arg) == 2 { // 词法矩阵 - mat.show(m) - return - } - - hash, word := mat.Parse(m, arg[1], NewStream(bytes.NewBufferString(arg[2]))) - m.Push(kit.MDB_TIME, m.Time()) - m.Push(kit.MDB_HASH, mat.word[hash]) + stream := NewStream(bytes.NewBufferString(m.Option(kit.MDB_TEXT))) + hash, word := mat.Parse(m, m.Option(NPAGE), stream) + m.Push(NHASH, kit.Select(kit.Format("%d", hash), mat.word[hash])) m.Push("word", string(word)) + m.Push("rest", string(stream.b[stream.P:])) }) + m.ProcessInner() }}, - }, - }) + "show": {Name: "show", Help: "矩阵", Hand: func(m *ice.Message, arg ...string) { + m.Richs(m.Prefix(MATRIX), "", kit.Select(m.Option(kit.MDB_HASH), arg, 0), func(key string, value map[string]interface{}) { + value = kit.GetMeta(value) + value[MATRIX].(*Matrix).show(m) + }) + m.ProcessInner() + }}, + }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表 + m.Fields(len(arg), "time,hash,npage,nhash") + m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), "", mdb.HASH) + m.PushAction(mdb.INSERT, "show", mdb.REMOVE) + return + } + + if m.Action(mdb.INSERT, "show"); len(arg) == 1 { // 词法列表 + m.Fields(len(arg[1:]), "time,npage,nhash,text") + m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST) + m.PushAction(PARSE) + return + } + + m.Richs(m.Prefix(MATRIX), "", arg[0], func(key string, value map[string]interface{}) { + value = kit.GetMeta(value) + mat, _ := value[MATRIX].(*Matrix) + + if len(arg) == 2 { // 词法矩阵 + mat.show(m) + return + } + + hash, word := mat.Parse(m, arg[1], NewStream(bytes.NewBufferString(arg[2]))) + m.Push(kit.MDB_TIME, m.Time()) + m.Push(kit.MDB_HASH, mat.word[hash]) + m.Push("word", string(word)) + }) + }}, + }}) } diff --git a/base/log/log.go b/base/log/log.go index e1626e13..11bcfa17 100644 --- a/base/log/log.go +++ b/base/log/log.go @@ -6,6 +6,7 @@ import ( ice "shylinux.com/x/icebergs" kit "shylinux.com/x/toolkits" + log "shylinux.com/x/toolkits/logs" ) type Log struct { @@ -38,6 +39,9 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { file := kit.Select(BENCH, m.Conf(SHOW, kit.Keys(l.l, FILE))) view := m.Confm(VIEW, m.Conf(SHOW, kit.Keys(l.l, VIEW))) bio := m.Confv(FILE, kit.Keys(file, FILE)).(*bufio.Writer) + if bio == nil { + continue + } bio.WriteString(l.p) bio.WriteString(ice.SP) @@ -81,62 +85,61 @@ const ( SHOW = "show" ) -var Index = &ice.Context{Name: "log", Help: "日志模块", - Configs: map[string]*ice.Config{ - FILE: {Name: FILE, Help: "日志文件", Value: kit.Dict( - WATCH, kit.Dict(kit.MDB_PATH, path.Join(ice.VAR_LOG, "watch.log"), kit.MDB_LIST, []string{ - ice.LOG_CREATE, ice.LOG_REMOVE, - ice.LOG_INSERT, ice.LOG_DELETE, - ice.LOG_SELECT, ice.LOG_MODIFY, - ice.LOG_EXPORT, ice.LOG_IMPORT, - }), - BENCH, kit.Dict(kit.MDB_PATH, path.Join(ice.VAR_LOG, "bench.log"), kit.MDB_LIST, []string{}), - ERROR, kit.Dict(kit.MDB_PATH, path.Join(ice.VAR_LOG, "error.log"), kit.MDB_LIST, []string{ - ice.LOG_WARN, ice.LOG_ERROR, - }), - TRACE, kit.Dict(kit.MDB_PATH, path.Join(ice.VAR_LOG, "trace.log"), kit.MDB_LIST, []string{}), - )}, - VIEW: {Name: VIEW, Help: "日志格式", Value: kit.Dict( - GREEN, kit.Dict(PREFIX, "\033[32m", SUFFIX, "\033[0m", kit.MDB_LIST, []string{ - ice.LOG_START, ice.LOG_SERVE, - ice.LOG_CMDS, - }), - YELLOW, kit.Dict(PREFIX, "\033[33m", SUFFIX, "\033[0m", kit.MDB_LIST, []string{ - ice.LOG_AUTH, ice.LOG_COST, - }), - RED, kit.Dict(PREFIX, "\033[31m", SUFFIX, "\033[0m", kit.MDB_LIST, []string{ - ice.LOG_WARN, ice.LOG_CLOSE, - }), - )}, - SHOW: {Name: SHOW, Help: "日志分流", Value: kit.Dict()}, - }, - Commands: map[string]*ice.Command{ - ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Confm(VIEW, nil, func(key string, value map[string]interface{}) { - kit.Fetch(value[kit.MDB_LIST], func(index int, k string) { - m.Conf(SHOW, kit.Keys(k, VIEW), key) - }) +var Index = &ice.Context{Name: "log", Help: "日志模块", Configs: map[string]*ice.Config{ + FILE: {Name: FILE, Help: "日志文件", Value: kit.Dict( + WATCH, kit.Dict(kit.MDB_PATH, path.Join(ice.VAR_LOG, "watch.log"), kit.MDB_LIST, []string{ + ice.LOG_CREATE, ice.LOG_REMOVE, + ice.LOG_INSERT, ice.LOG_DELETE, + ice.LOG_SELECT, ice.LOG_MODIFY, + ice.LOG_EXPORT, ice.LOG_IMPORT, + }), + BENCH, kit.Dict(kit.MDB_PATH, path.Join(ice.VAR_LOG, "bench.log"), kit.MDB_LIST, []string{}), + ERROR, kit.Dict(kit.MDB_PATH, path.Join(ice.VAR_LOG, "error.log"), kit.MDB_LIST, []string{ + ice.LOG_WARN, ice.LOG_ERROR, + }), + TRACE, kit.Dict(kit.MDB_PATH, path.Join(ice.VAR_LOG, "trace.log"), kit.MDB_LIST, []string{}), + )}, + VIEW: {Name: VIEW, Help: "日志格式", Value: kit.Dict( + GREEN, kit.Dict(PREFIX, "\033[32m", SUFFIX, "\033[0m", kit.MDB_LIST, []string{ + ice.LOG_START, ice.LOG_SERVE, + ice.LOG_CMDS, + }), + YELLOW, kit.Dict(PREFIX, "\033[33m", SUFFIX, "\033[0m", kit.MDB_LIST, []string{ + ice.LOG_AUTH, ice.LOG_COST, + }), + RED, kit.Dict(PREFIX, "\033[31m", SUFFIX, "\033[0m", kit.MDB_LIST, []string{ + ice.LOG_WARN, ice.LOG_CLOSE, + }), + )}, + SHOW: {Name: SHOW, Help: "日志分流", Value: kit.Dict()}, +}, Commands: map[string]*ice.Command{ + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Confm(VIEW, nil, func(key string, value map[string]interface{}) { + kit.Fetch(value[kit.MDB_LIST], func(index int, k string) { + m.Conf(SHOW, kit.Keys(k, VIEW), key) }) - m.Confm(FILE, nil, func(key string, value map[string]interface{}) { - kit.Fetch(value[kit.MDB_LIST], func(index int, k string) { - m.Conf(SHOW, kit.Keys(k, FILE), key) - }) - // 日志文件 - if f, p, e := kit.Create(kit.Format(value[kit.MDB_PATH])); m.Assert(e) { - m.Cap(ice.CTX_STREAM, path.Base(p)) - value[FILE] = bufio.NewWriter(f) - m.Log_CREATE(kit.MDB_FILE, p) - } + }) + m.Confm(FILE, nil, func(key string, value map[string]interface{}) { + kit.Fetch(value[kit.MDB_LIST], func(index int, k string) { + m.Conf(SHOW, kit.Keys(k, FILE), key) }) - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if f, ok := m.Target().Server().(*Frame); ok { - // 关闭日志 - ice.Info.Log = nil - close(f.p) + if log.LogDisable { + return // 禁用日志 } - }}, - }, -} + // 日志文件 + if f, p, e := kit.Create(kit.Format(value[kit.MDB_PATH])); m.Assert(e) { + m.Cap(ice.CTX_STREAM, path.Base(p)) + value[FILE] = bufio.NewWriter(f) + m.Log_CREATE(kit.MDB_FILE, p) + } + }) + }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if f, ok := m.Target().Server().(*Frame); ok { // 关闭日志 + ice.Info.Log = nil + close(f.p) + } + }}, +}} func init() { ice.Index.Register(Index, &Frame{}) } diff --git a/base/nfs/cat.go b/base/nfs/cat.go index fa940102..aed33b8b 100644 --- a/base/nfs/cat.go +++ b/base/nfs/cat.go @@ -36,22 +36,18 @@ func _cat_right(m *ice.Message, name string) bool { case ice.USR: switch kit.Select("", ls, 1) { case "local": - if m.Warn(m.Option(ice.MSG_USERROLE) == aaa.VOID, ice.ErrNotRight, "of", name) { + if m.Warn(m.Option(ice.MSG_USERROLE) == aaa.VOID, ice.ErrNotRight, ice.OF, name) { return false } } case ice.ETC, ice.VAR: - if m.Warn(m.Option(ice.MSG_USERROLE) == aaa.VOID, ice.ErrNotRight, "of", name) { + if m.Warn(m.Option(ice.MSG_USERROLE) == aaa.VOID, ice.ErrNotRight, ice.OF, name) { return false } } return true } func _cat_find(m *ice.Message, name string) io.ReadCloser { - // if m.Option("content") != "" { - // return NewReadCloser(bytes.NewBufferString(m.Option("content"))) - // } - if f, e := os.Open(path.Join(m.Option(DIR_ROOT), name)); e == nil { return f } @@ -71,7 +67,7 @@ func _cat_find(m *ice.Message, name string) io.ReadCloser { } return NewReadCloser(bytes.NewBufferString(msg.Result())) } -func _cat_show(m *ice.Message, name string) { +func _cat_list(m *ice.Message, name string) { if !_cat_right(m, name) { return // 没有权限 } @@ -119,6 +115,7 @@ func _cat_show(m *ice.Message, name string) { const ( PATH = "path" FILE = "file" + LINE = "line" SIZE = "size" CAT_LOCAL = "cat_local" @@ -129,23 +126,26 @@ func init() { Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ CAT: {Name: CAT, Help: "文件", Value: kit.Data( kit.SSH_SOURCE, kit.Dict( - "sh", "true", "shy", "true", "py", "true", - "go", "true", "vim", "true", "js", "true", - "json", "true", "conf", "true", "yml", "true", - "makefile", "true", + "sh", ice.TRUE, "shy", ice.TRUE, "py", ice.TRUE, + "go", ice.TRUE, "vim", ice.TRUE, "js", ice.TRUE, + "json", ice.TRUE, "conf", ice.TRUE, "yml", ice.TRUE, + "makefile", ice.TRUE, "license", ice.TRUE, "md", ice.TRUE, ), )}, }, Commands: map[string]*ice.Command{ + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmd(mdb.RENDER, mdb.CREATE, CAT) + }}, CAT: {Name: "cat path auto", Help: "文件", Action: map[string]*ice.Action{ mdb.RENDER: {Name: "render type name text", Help: "渲染", Hand: func(m *ice.Message, arg ...string) { - _cat_show(m, path.Join(arg[2], arg[1])) + _cat_list(m, path.Join(arg[2], arg[1])) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 || strings.HasSuffix(arg[0], "/") { m.Cmdy(DIR, arg) - } else { - _cat_show(m, arg[0]) + return } + _cat_list(m, arg[0]) }}, }}) } diff --git a/base/nfs/dir.go b/base/nfs/dir.go index bc3c53fe..1797f6a8 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -3,23 +3,19 @@ package nfs import ( "bufio" "crypto/sha1" - "encoding/hex" - "fmt" "io/ioutil" "os" "path" "regexp" - "sort" "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" - "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" ) -func _dir_show(m *ice.Message, root string, name string, level int, deep bool, dir_type string, dir_reg *regexp.Regexp, fields []string) *ice.Message { +func _dir_list(m *ice.Message, root string, name string, level int, deep bool, dir_type string, dir_reg *regexp.Regexp, fields []string) *ice.Message { if !_cat_right(m, name) { return m // 没有权限 } @@ -66,7 +62,6 @@ func _dir_show(m *ice.Message, root string, name string, level int, deep bool, d } case "full": m.Push(field, path.Join(root, name, f.Name())+kit.Select("", "/", f.IsDir())) - case kit.MDB_PATH: m.Push(field, path.Join(name, f.Name())+kit.Select("", "/", f.IsDir())) case kit.MDB_FILE: @@ -74,9 +69,6 @@ func _dir_show(m *ice.Message, root string, name string, level int, deep bool, d case kit.MDB_NAME: m.Push(field, f.Name()) - case kit.MDB_LINK: - m.PushDownload(kit.MDB_LINK, kit.Select("", f.Name(), !f.IsDir()), path.Join(root, name, f.Name())) - case kit.MDB_SIZE: if f.IsDir() { if ls, e := ioutil.ReadDir(path.Join(root, name, f.Name())); e == nil { @@ -110,9 +102,9 @@ func _dir_show(m *ice.Message, root string, name string, level int, deep bool, d if d, e := ioutil.ReadDir(p); m.Assert(e) { meta := []string{} for _, v := range d { - meta = append(meta, fmt.Sprintf("%s%d%s", v.Name(), v.Size(), v.ModTime())) + meta = append(meta, kit.Format("%s%d%s", v.Name(), v.Size(), v.ModTime())) } - sort.Strings(meta) + kit.Sort(meta) h = sha1.Sum([]byte(strings.Join(meta, ""))) } } else { @@ -121,23 +113,24 @@ func _dir_show(m *ice.Message, root string, name string, level int, deep bool, d } } - m.Push(kit.MDB_HASH, kit.Select(hex.EncodeToString(h[:6]), hex.EncodeToString(h[:]), field == kit.MDB_HASH)) - case ctx.ACTION: - if !f.IsDir() && !m.IsCliUA() && m.Option(ice.MSG_USERROLE) != aaa.VOID { - m.PushButton(TRASH) - } else { - m.Push(field, "") - } + m.Push(kit.MDB_HASH, kit.Select(kit.Format(h[:6]), kit.Format(h[:]), field == kit.MDB_HASH)) + case kit.MDB_LINK: + m.PushDownload(kit.MDB_LINK, kit.Select("", f.Name(), !f.IsDir()), path.Join(root, name, f.Name())) case "show": - p := kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/local/"+path.Join(name, f.Name()), "pod", m.Option(ice.MSG_USERPOD)) + p := kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/share/local/"+path.Join(name, f.Name()), ice.POD, m.Option(ice.MSG_USERPOD)) switch kit.Ext(f.Name()) { - case "jpg": + case "jpg", "png": m.PushImages(field, p) case "mp4": m.PushVideos(field, p) default: m.Push(field, "") } + case kit.MDB_ACTION: + if m.IsCliUA() || m.Option(ice.MSG_USERROLE) == aaa.VOID { + break + } + m.PushButton(kit.Select("", TRASH, !f.IsDir())) default: m.Push(field, "") } @@ -145,17 +138,13 @@ func _dir_show(m *ice.Message, root string, name string, level int, deep bool, d } if f.IsDir() && deep { - _dir_show(m, root, path.Join(name, f.Name()), level+1, deep, dir_type, dir_reg, fields) + _dir_list(m, root, path.Join(name, f.Name()), level+1, deep, dir_type, dir_reg, fields) } } return m } func _dir_search(m *ice.Message, kind, name string) { - if kind == kit.MDB_FOREACH { - return - } - - msg := _dir_show(m.Spawn(), "./", "", 0, true, TYPE_BOTH, nil, strings.Split("time,type,name,text", ",")) + msg := _dir_list(m.Spawn(), "./", "", 0, true, TYPE_BOTH, nil, kit.Split("time,type,name")) msg.Table(func(index int, value map[string]string, head []string) { if !strings.Contains(value[kit.MDB_NAME], name) { return @@ -192,35 +181,35 @@ const ( const DIR = "dir" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - DIR: {Name: DIR, Help: "目录", Value: kit.Data()}, - }, - Commands: map[string]*ice.Command{ - DIR: {Name: "dir path field... auto upload", Help: "目录", Action: map[string]*ice.Action{ - mdb.SEARCH: {Name: "search type name", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { - _dir_search(m, arg[0], arg[1]) - }}, - mdb.RENDER: {Name: "render type name text", Help: "渲染", Hand: func(m *ice.Message, arg ...string) { - _dir_show(m, arg[2], arg[1], 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), - nil, kit.Split("time,size,type,path")) - }}, - mdb.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) { - m.Upload(m.Option(kit.MDB_PATH)) - }}, - TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(TRASH, m.Option(kit.MDB_PATH)) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) == 0 { - arg = append(arg, "") + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + DIR: {Name: DIR, Help: "目录", Value: kit.Data()}, + }, Commands: map[string]*ice.Command{ + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmd(mdb.SEARCH, mdb.CREATE, DIR) + m.Cmd(mdb.RENDER, mdb.CREATE, DIR) + }}, + DIR: {Name: "dir path field... auto upload", Help: "目录", Action: map[string]*ice.Action{ + mdb.SEARCH: {Name: "search type name", Help: "搜索", Hand: func(m *ice.Message, arg ...string) { + if arg[0] == kit.MDB_FOREACH { + return } - m.Debug("dir_root: %s", m.Option(DIR_ROOT)) - _dir_show(m, kit.Select("./", m.Option(DIR_ROOT)), arg[0], - 0, m.Options(DIR_DEEP), kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), kit.Regexp(m.Option(DIR_REG)), - kit.Split(kit.Select(kit.Select("time,path,size,action", m.Option(mdb.FIELDS)), strings.Join(arg[1:], ",")))) - m.SortTimeR(kit.MDB_TIME) + _dir_search(m, arg[0], arg[1]) }}, - }, - }) + mdb.RENDER: {Name: "render type name text", Help: "渲染", Hand: func(m *ice.Message, arg ...string) { + _dir_list(m, arg[2], arg[1], 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), + nil, kit.Split(kit.Select("time,size,type,path", m.OptionFields()))) + }}, + mdb.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) { + m.Upload(m.Option(kit.MDB_PATH)) + }}, + TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(TRASH, m.Option(kit.MDB_PATH)) + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + _dir_list(m, kit.Select("./", m.Option(DIR_ROOT)), kit.Select("", arg, 0), + 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), kit.Regexp(m.Option(DIR_REG)), + kit.Split(kit.Select(kit.Select("time,path,size,action", m.OptionFields()), kit.Join(kit.Slice(arg, 1))))) + m.SortTimeR(kit.MDB_TIME) + }}, + }}) } diff --git a/base/nfs/nfs.go b/base/nfs/nfs.go index 3ec3fccd..d07c9a6c 100644 --- a/base/nfs/nfs.go +++ b/base/nfs/nfs.go @@ -2,19 +2,8 @@ package nfs import ( ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/mdb" ) -var Index = &ice.Context{Name: "nfs", Help: "存储模块", Commands: map[string]*ice.Command{ - ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Load() - m.Cmd(mdb.RENDER, mdb.CREATE, CAT) - m.Cmd(mdb.SEARCH, mdb.CREATE, DIR) - m.Cmd(mdb.RENDER, mdb.CREATE, DIR) - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Save() - }}, -}} +var Index = &ice.Context{Name: "nfs", Help: "存储模块"} func init() { ice.Index.Register(Index, nil, CAT, DIR, TAIL, TRASH, SAVE, PUSH, COPY, LINK, DEFS) } diff --git a/base/nfs/save.go b/base/nfs/save.go index 7d12ad94..f1a54638 100644 --- a/base/nfs/save.go +++ b/base/nfs/save.go @@ -22,6 +22,11 @@ func _save_file(m *ice.Message, name string, text ...string) { m.Echo(p) } } +func _defs_file(m *ice.Message, name string, text ...string) { + if _, e := os.Stat(path.Join(m.Option(DIR_ROOT), name)); os.IsNotExist(e) { + _save_file(m, name, text...) + } +} func _push_file(m *ice.Message, name string, text ...string) { p := path.Join(m.Option(DIR_ROOT), name) if strings.Contains(p, "/") { @@ -65,42 +70,35 @@ func _link_file(m *ice.Message, name string, from string) { os.Link(from, name) m.Echo(name) } -func _defs_file(m *ice.Message, name string, text ...string) { - if _, e := os.Stat(path.Join(m.Option(DIR_ROOT), name)); os.IsNotExist(e) { - _save_file(m, name, text...) - } -} const SAVE = "save" +const DEFS = "defs" const PUSH = "push" const COPY = "copy" const LINK = "link" -const DEFS = "defs" func init() { - Index.Merge(&ice.Context{ - Commands: map[string]*ice.Command{ - SAVE: {Name: "save file text...", Help: "保存", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) == 1 { - arg = append(arg, m.Option(kit.MDB_CONTENT)) - } - _save_file(m, arg[0], arg[1:]...) - }}, - PUSH: {Name: "push file text...", Help: "追加", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) == 1 { - arg = append(arg, m.Option(kit.MDB_CONTENT)) - } - _push_file(m, arg[0], arg[1:]...) - }}, - COPY: {Name: "copy file from...", Help: "复制", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - _copy_file(m, arg[0], arg[1:]...) - }}, - LINK: {Name: "link file from", Help: "链接", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - _link_file(m, arg[0], arg[1]) - }}, - DEFS: {Name: "defs file text...", Help: "默认", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - _defs_file(m, arg[0], arg[1:]...) - }}, - }, - }) + Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ + SAVE: {Name: "save file text...", Help: "保存", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) == 1 { + arg = append(arg, m.Option(kit.MDB_CONTENT)) + } + _save_file(m, arg[0], arg[1:]...) + }}, + PUSH: {Name: "push file text...", Help: "追加", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) == 1 { + arg = append(arg, m.Option(kit.MDB_CONTENT)) + } + _push_file(m, arg[0], arg[1:]...) + }}, + DEFS: {Name: "defs file text...", Help: "默认", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + _defs_file(m, arg[0], arg[1:]...) + }}, + COPY: {Name: "copy file from...", Help: "复制", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + _copy_file(m, arg[0], arg[1:]...) + }}, + LINK: {Name: "link file from", Help: "链接", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + _link_file(m, arg[0], arg[1]) + }}, + }}) } diff --git a/base/nfs/tail.go b/base/nfs/tail.go index ec6976a8..188bc836 100644 --- a/base/nfs/tail.go +++ b/base/nfs/tail.go @@ -39,7 +39,9 @@ const TAIL = "tail" func init() { Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ - TAIL: {Name: TAIL, Help: "日志流", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)}, + TAIL: {Name: TAIL, Help: "日志流", Value: kit.Data( + kit.MDB_SHORT, kit.MDB_NAME, kit.MDB_FIELD, "time,id,file,text", + )}, }, Commands: map[string]*ice.Command{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Richs(TAIL, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { @@ -55,11 +57,8 @@ func init() { m.ProcessAgain() case kit.MDB_NAME: m.Push(arg[0], kit.Split(m.Option(FILE), "/")) - case "limit": - m.Push("limit", 10) - m.Push("limit", 20) - m.Push("limit", 30) - m.Push("limit", 50) + case kit.MDB_LIMIT: + m.Push(arg[0], kit.List("10", "20", "30", "50")) } }}, mdb.CREATE: {Name: "create file name", Help: "创建", Hand: func(m *ice.Message, arg ...string) { @@ -71,7 +70,7 @@ func init() { m.Option(mdb.CACHE_OFFEND, kit.Select("0", arg, 3)) m.Option(mdb.CACHE_LIMIT, kit.Select("10", arg, 2)) - m.Cmd(mdb.SELECT, TAIL, "", mdb.ZONE, arg).Table(func(index int, value map[string]string, head []string) { + mdb.ZoneSelect(m.Spawn(c), arg...).Table(func(index int, value map[string]string, head []string) { if strings.Contains(value[kit.MDB_TEXT], m.Option(mdb.CACHE_FILTER)) { m.Push("", value, head) } @@ -83,6 +82,5 @@ func init() { m.StatusTimeCountTotal(_tail_count(m, arg[0])) } }}, - }, - }) + }}) } diff --git a/base/nfs/trash.go b/base/nfs/trash.go index 19b5e200..9b85916d 100644 --- a/base/nfs/trash.go +++ b/base/nfs/trash.go @@ -29,41 +29,35 @@ func _trash_create(m *ice.Message, name string) { } } } -func _trash_prunes(m *ice.Message) { - m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) -} const TRASH = "trash" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - TRASH: {Name: TRASH, Help: "回收站", Value: kit.Data( - kit.MDB_SHORT, kit.MDB_FROM, kit.MDB_PATH, ice.VAR_TRASH, - )}, - }, - Commands: map[string]*ice.Command{ - TRASH: {Name: "trash file auto prunes", Help: "回收站", Action: map[string]*ice.Action{ - mdb.REVERT: {Name: "revert", Help: "恢复", Hand: func(m *ice.Message, arg ...string) { - os.Rename(m.Option(kit.MDB_FILE), m.Option(kit.MDB_FROM)) - m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - os.Remove(m.Option(kit.MDB_FILE)) - m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) - }}, - mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - _trash_prunes(m) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) == 0 { - m.Fields(len(arg), "time,hash,file,from") - m.Cmdy(mdb.SELECT, TRASH, "", mdb.HASH) - m.PushAction(mdb.REVERT, mdb.REMOVE) - return - } - _trash_create(m, arg[0]) + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + TRASH: {Name: TRASH, Help: "回收站", Value: kit.Data( + kit.MDB_SHORT, kit.MDB_FROM, kit.MDB_FIELD, "time,hash,file,from", + kit.MDB_PATH, ice.VAR_TRASH, + )}, + }, Commands: map[string]*ice.Command{ + TRASH: {Name: "trash file auto prunes", Help: "回收站", Action: ice.MergeAction(map[string]*ice.Action{ + mdb.REVERT: {Name: "revert", Help: "恢复", Hand: func(m *ice.Message, arg ...string) { + os.Rename(m.Option(kit.MDB_FILE), m.Option(kit.MDB_FROM)) + m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, m.OptionSimple(kit.MDB_HASH)) }}, - }, - }) + mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + os.Remove(m.Option(kit.MDB_FILE)) + m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, m.OptionSimple(kit.MDB_HASH)) + }}, + mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { + m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, m.OptionSimple(kit.MDB_HASH)) + }}, + }, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) == 0 { + mdb.HashSelect(m, arg...) + m.PushAction(mdb.REVERT, mdb.REMOVE) + return + } + _trash_create(m, arg[0]) + }}, + }}) } diff --git a/base/ssh/scripts.go b/base/ssh/scripts.go index 655cf92a..33662134 100644 --- a/base/ssh/scripts.go +++ b/base/ssh/scripts.go @@ -14,51 +14,29 @@ import ( "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" ) -func Render(msg *ice.Message, cmd string, args ...interface{}) string { +func Render(msg *ice.Message, cmd string, args ...interface{}) (res string) { switch arg := kit.Simple(args...); cmd { case ice.RENDER_VOID: + return res case ice.RENDER_RESULT: - // 转换结果 if len(arg) > 0 { msg.Resultv(arg) } - res := msg.Result() - - // 输出结果 - if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, ice.NL) { - fmt.Fprint(msg.O, ice.NL) - } - return res + res = msg.Result() default: - // 转换结果 - res := msg.Result() - if res == "" { + if res = msg.Result(); res == "" { res = msg.Table().Result() } - - // 输出结果 - if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, ice.NL) { - fmt.Fprint(msg.O, ice.NL) - } - return res } - return "" -} -func Script(m *ice.Message, name string) io.Reader { - if strings.Contains(m.Option(ice.MSG_SCRIPT), "/") { - name = path.Join(path.Dir(m.Option(ice.MSG_SCRIPT)), name) + if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, ice.NL) { + fmt.Fprint(msg.O, ice.NL) } - m.Option(ice.MSG_SCRIPT, name) - - // 远程文件 - if msg := m.Cmd("nfs.cat", name); msg.Result(0) != ice.ErrWarn { - return bytes.NewBuffer([]byte(msg.Result())) - } - return nil + return res } type Frame struct { @@ -68,10 +46,10 @@ type Frame struct { stdin io.Reader pipe io.Writer - count int - last string ps1 []string ps2 []string + res string + count int } func (f *Frame) prompt(m *ice.Message, list ...string) *Frame { @@ -105,33 +83,6 @@ func (f *Frame) printf(m *ice.Message, res string, arg ...interface{}) *Frame { } return f } -func (f *Frame) option(m *ice.Message, ls []string) []string { - ln := []string{} - m.Option(mdb.CACHE_LIMIT, 10) - for i := 0; i < len(ls); i++ { - if ls[i] == "--" { - ln = append(ln, ls[i+1:]...) - break - } - - if strings.HasPrefix(ls[i], "-") { - for j := i; j < len(ls); j++ { - if j == len(ls)-1 || strings.HasPrefix(ls[j+1], "-") { - if i < j { - m.Option(ls[i][1:], ls[i+1:j+1]) - } else { - m.Option(ls[i][1:], ice.TRUE) - } - i = j - break - } - } - } else { - ln = append(ln, ls[i]) - } - } - return ln -} func (f *Frame) change(m *ice.Message, ls []string) []string { if len(ls) == 1 && ls[0] == "~" { // 模块列表 ls = []string{ctx.CONTEXT} @@ -168,42 +119,22 @@ func (f *Frame) parse(m *ice.Message, line string) string { } for _, one := range kit.Split(line, ";", ";", ";") { - async, one := false, strings.TrimSpace(one) - if strings.TrimSuffix(one, "&") != one { - async, one = true, strings.TrimSuffix(one, "&") - } - + one = strings.TrimSpace(one) msg := m.Spawn(f.target) msg.Option("_cmd", one) - ls := kit.Split(one) - ls = f.alias(msg, ls) - ls = f.change(msg, ls) - ls = f.option(msg, ls) + ls := f.change(msg, f.alias(msg, kit.Split(one))) if len(ls) == 0 { continue } + msg.Cmdy(ls[0], ls[1:]) - if async { - msg.Go(func() { msg.Cmd(ls[0], ls[1:]) }) - continue - } else { - msg.Cmdy(ls[0], ls[1:]) - } - - if strings.HasPrefix(msg.Result(), ice.ErrWarn) && m.Option(ice.MSG_RENDER) == ice.RENDER_RAW { - fmt.Fprintf(msg.O, line) - continue - } - - // 渲染引擎 _args, _ := msg.Optionv(ice.MSG_ARGS).([]interface{}) - f.last = Render(msg, msg.Option(ice.MSG_OUTPUT), _args...) + f.res = Render(msg, msg.Option(ice.MSG_OUTPUT), _args...) } return "" } func (f *Frame) scan(m *ice.Message, h, line string) *Frame { - m.Option(kit.Keycb(RETURN), func() { f.close() }) f.ps1 = kit.Simple(m.Confv(PROMPT, kit.Keym(PS1))) f.ps2 = kit.Simple(m.Confv(PROMPT, kit.Keym(PS2))) ps := f.ps1 @@ -221,28 +152,25 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame { if len(bio.Text()) == 0 { if strings.Count(line, "`")%2 == 1 { - line += "\n" + line += ice.NL } continue // 空行 } - if strings.HasSuffix(bio.Text(), "\\") { line += bio.Text()[:len(bio.Text())-1] ps = f.ps2 continue // 续行 } if line += bio.Text(); strings.Count(line, "`")%2 == 1 { - line += "\n" + line += ice.NL ps = f.ps2 continue // 多行 } - if strings.HasPrefix(strings.TrimSpace(line), "#") { - line = "" + if line = kit.Split(line, "#", "#", "#")[0]; len(line) == 0 { continue // 注释 } if ps = f.ps1; f.stdout == os.Stdout { - // 清空格式 - f.printf(m, "\033[0m") + f.printf(m, "\033[0m") // 清空格式 } line = f.parse(m, line) } @@ -262,51 +190,44 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server return &Frame{} } func (f *Frame) Start(m *ice.Message, arg ...string) bool { - f.source, f.target = kit.Select(STDIO, arg, 0), m.Target() - - switch m.Cap(ice.CTX_STREAM, f.source) { + m.Optionv(FRAME, f) + switch f.source = kit.Select(STDIO, arg, 0); f.source { case STDIO: // 终端交互 + m.Cap(ice.CTX_STREAM, f.source) + f.target = m.Target() + r, w, _ := os.Pipe() m.Go(func() { io.Copy(w, os.Stdin) }) f.stdin, f.stdout = r, os.Stdout f.pipe = w - m.Option(ice.MSG_OPTS, ice.MSG_USERNAME) aaa.UserRoot(m) + m.Option(ice.MSG_OPTS, ice.MSG_USERNAME) - default: // 脚本文件 - f.target = m.Source() - - if strings.HasPrefix(f.source, "/dev") { - f.stdin, f.stdout = m.I, m.O - break - } - - buf := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS)) - defer func() { m.Echo(buf.String()) }() - - if s := Script(m, f.source); s != nil { - f.stdin, f.stdout = s, buf - break - } - - // 查找失败 - return true - } - - // 解析脚本 - if f.count = 1; f.source == STDIO { - m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, STDIO, kit.MDB_META, kit.MDB_NAME), STDIO) - m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, STDIO, kit.MDB_META, kit.MDB_TIME), m.Time()) + m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, STDIO, kit.Keym(kit.MDB_NAME)), STDIO) + m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, STDIO, kit.Keym(kit.MDB_TIME)), m.Time()) f.count = kit.Int(m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, STDIO, kit.Keym(kit.MDB_COUNT)))) + 1 f.scan(m, STDIO, "") - } else { - h := m.Cmdx(mdb.INSERT, SOURCE, "", mdb.HASH, kit.MDB_NAME, f.source) - m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, h, kit.Keym(kit.MDB_COUNT)), 0) - m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, h, kit.MDB_LIST), "") - f.scan(m, h, "") + default: // 脚本文件 + if strings.Contains(m.Option(ice.MSG_SCRIPT), "/") { + f.source = path.Join(path.Dir(m.Option(ice.MSG_SCRIPT)), f.source) + } + m.Option(ice.MSG_SCRIPT, f.source) + f.target = m.Source() + + if msg := m.Cmd(nfs.CAT, f.source); msg.Result(0) == ice.ErrWarn { + return true // 查找失败 + } else { + buf := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS)) + defer func() { m.Echo(buf.String()) }() + + f.stdin, f.stdout = bytes.NewBuffer([]byte(msg.Result())), buf + } + + f.count = 1 + f.scan(m, m.Cmdx(mdb.INSERT, SOURCE, "", mdb.HASH, kit.MDB_NAME, f.source), "") } return true } @@ -315,6 +236,7 @@ func (f *Frame) Close(m *ice.Message, arg ...string) bool { } const ( + FRAME = "frame" STDIO = "stdio" PS1 = "PS1" PS2 = "PS2" @@ -330,73 +252,50 @@ const ( ) func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - SOURCE: {Name: SOURCE, Help: "加载脚本", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)}, - PROMPT: {Name: PROMPT, Help: "命令提示", Value: kit.Data( - PS1, []interface{}{"\033[33;44m", kit.MDB_COUNT, "[", kit.MDB_TIME, "]", "\033[5m", TARGET, "\033[0m", "\033[44m", ">", "\033[0m ", "\033[?25h", "\033[32m"}, - PS2, []interface{}{kit.MDB_COUNT, " ", TARGET, "> "}, - )}, - }, - Commands: map[string]*ice.Command{ - SOURCE: {Name: "source hash id limit offend auto", Help: "脚本解析", Action: map[string]*ice.Action{ - mdb.REPEAT: {Name: "repeat", Help: "执行", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(SCREEN, m.Option(kit.MDB_TEXT)) - m.ProcessInner() - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) > 0 && kit.Ext(arg[0]) == "shy" { // 解析脚本 - m.Starts(strings.Replace(arg[0], ".", "_", -1), arg[0], arg[0:]...) - return - } - - if len(arg) == 0 { // 脚本列表 - m.Fields(len(arg), "time,hash,name,count") - m.Cmdy(mdb.SELECT, SOURCE, "", mdb.HASH) - m.Sort(kit.MDB_NAME) - return - } - - if m.Option(mdb.CACHE_OFFEND, kit.Select("0", arg, 3)); arg[0] == STDIO { - m.Option(mdb.CACHE_LIMIT, kit.Select("10", arg, 2)) - } else { - m.Option(mdb.CACHE_LIMIT, kit.Select("-1", arg, 2)) - } - - // 命令列表 - m.Fields(len(arg[1:]), "time,id,text") - m.Cmdy(mdb.SELECT, SOURCE, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:]) - m.PushAction(mdb.REPEAT) + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + SOURCE: {Name: SOURCE, Help: "加载脚本", Value: kit.Data()}, + PROMPT: {Name: PROMPT, Help: "命令提示", Value: kit.Data( + PS1, []interface{}{"\033[33;44m", kit.MDB_COUNT, "[", kit.MDB_TIME, "]", "\033[5m", TARGET, "\033[0m", "\033[44m", ">", "\033[0m ", "\033[?25h", "\033[32m"}, + PS2, []interface{}{kit.MDB_COUNT, " ", TARGET, "> "}, + )}, + }, Commands: map[string]*ice.Command{ + SOURCE: {Name: "source file", Help: "脚本解析", Action: ice.MergeAction(map[string]*ice.Action{ + mdb.REPEAT: {Name: "repeat", Help: "执行", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(SCREEN, m.Option(kit.MDB_TEXT)) + m.ProcessInner() }}, - TARGET: {Name: "target name run:button", Help: "当前模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - f := m.Target().Server().(*Frame) - m.Search(arg[0]+".", func(p *ice.Context, s *ice.Context, key string) { f.target = s }) - f.prompt(m) - }}, - PROMPT: {Name: "prompt arg run:button", Help: "命令提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - f := m.Target().Server().(*Frame) - f.ps1 = arg - f.prompt(m) - }}, - PRINTF: {Name: "printf run:button text:textarea", Help: "输出显示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - f := m.Target().Server().(*Frame) - f.printf(m, arg[0]) - }}, - SCREEN: {Name: "screen run:button text:textarea", Help: "输出命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - f := m.Target().Server().(*Frame) - for _, line := range kit.Split(arg[0], "\n", "\n", "\n") { - f.printf(m, line+"\n") - fmt.Fprintf(f.pipe, line+"\n") - m.Sleep("300ms") - } - m.Echo(f.last) - }}, - RETURN: {Name: "return", Help: "结束脚本", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - switch cb := m.Optionv(kit.Keycb(RETURN)).(type) { - case func(): - cb() - } - }}, - }, - }) + }, mdb.ZoneAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) > 0 && kit.Ext(arg[0]) == ice.SHY { + (&Frame{}).Start(m, arg...) + return // 脚本解析 + } + }}, + TARGET: {Name: "target name run:button", Help: "当前模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + f := m.Optionv(FRAME).(*Frame) + m.Search(arg[0]+ice.PT, func(p *ice.Context, s *ice.Context, key string) { f.target = s }) + f.prompt(m) + }}, + PROMPT: {Name: "prompt arg run:button", Help: "命令提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + f := m.Optionv(FRAME).(*Frame) + f.ps1 = arg + f.prompt(m) + }}, + PRINTF: {Name: "printf run:button text:textarea", Help: "输出显示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + f := m.Optionv(FRAME).(*Frame) + f.printf(m, arg[0]) + }}, + SCREEN: {Name: "screen run:button text:textarea", Help: "输出命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + f := m.Optionv(FRAME).(*Frame) + for _, line := range kit.Split(arg[0], ice.NL, ice.NL) { + fmt.Fprintf(f.pipe, line+ice.NL) + f.printf(m, line+ice.NL) + m.Sleep("300ms") + } + m.Echo(f.res) + }}, + RETURN: {Name: "return", Help: "结束脚本", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + f := m.Optionv(FRAME).(*Frame) + f.close() + }}, + }}) } diff --git a/base/ssh/ssh.go b/base/ssh/ssh.go index c5f317bb..70ac0381 100644 --- a/base/ssh/ssh.go +++ b/base/ssh/ssh.go @@ -6,20 +6,8 @@ import ( const SSH = "ssh" -var Index = &ice.Context{Name: SSH, Help: "终端模块", Commands: map[string]*ice.Command{ - ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Load() - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if f, ok := m.Target().Server().(*Frame); ok { - f.close() - } - m.Save() - }}, -}} +var Index = &ice.Context{Name: SSH, Help: "终端模块"} func init() { - ice.Index.Register(Index, &Frame{}, - SOURCE, TARGET, PROMPT, PRINTF, SCREEN, RETURN, - ) + ice.Index.Register(Index, &Frame{}, SOURCE, TARGET, PROMPT, PRINTF, SCREEN, RETURN) } diff --git a/base/ssh/ssh.shy b/base/ssh/ssh.shy index 4e3fac25..65c2d4a7 100644 --- a/base/ssh/ssh.shy +++ b/base/ssh/ssh.shy @@ -1,14 +1,4 @@ chapter "ssh" -refer ` -官网 http://www.openssh.com/ -文档 https://man.openbsd.org/ssh -源码 https://github.com/openssh/openssh-portable -` - -field "连接" ssh.connect -field "会话" ssh.session -field "服务" ssh.service -field "通道" ssh.channel field "脚本" ssh.source field "模块" ssh.target diff --git a/base/tcp/client.go b/base/tcp/client.go index d501dcad..f4ad9297 100644 --- a/base/tcp/client.go +++ b/base/tcp/client.go @@ -31,10 +31,36 @@ func (c *Conn) Write(b []byte) (int, error) { return n, e } func (c *Conn) Close() error { - // c.m.Cmd(mdb.MODIFY, CLIENT, "", mdb.HASH, kit.MDB_HASH, c.h, kit.MDB_STATUS, CLOSE, "nread", c.s.nr, "nwrite", c.s.nw) return c.Conn.Close() } +func _client_dial(m *ice.Message, arg ...string) { + c, e := net.Dial(TCP, m.Option(HOST)+":"+m.Option(PORT)) + + c = &Conn{m: m, s: &Stat{}, Conn: c} + if e == nil { + defer c.Close() + } + + switch cb := m.Optionv(kit.Keycb(DIAL)).(type) { + case func(net.Conn, error): + cb(c, e) + case func(net.Conn): + m.Assert(e) + cb(c) + case func(net.Conn, []byte, error): + b := make([]byte, ice.MOD_BUFS) + for { + n, e := c.Read(b) + if cb(c, b[:n], e); e != nil { + break + } + } + default: + c.Write([]byte("hello world\n")) + } +} + const ( OPEN = "open" CLOSE = "close" @@ -45,60 +71,31 @@ const ( const ( DIAL = "dial" ) - const CLIENT = "client" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - CLIENT: {Name: CLIENT, Help: "客户端", Value: kit.Data()}, - }, - Commands: map[string]*ice.Command{ - CLIENT: {Name: "client hash auto prunes", Help: "客户端", Action: map[string]*ice.Action{ - DIAL: {Name: "dial type name port=9010 host=", Help: "连接", Hand: func(m *ice.Message, arg ...string) { - c, e := net.Dial(TCP, m.Option(HOST)+":"+m.Option(PORT)) - h := m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, PORT, m.Option(PORT), HOST, m.Option(HOST), - kit.MDB_TYPE, m.Option(kit.MDB_TYPE), kit.MDB_NAME, m.Option(kit.MDB_NAME), - kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) - - c = &Conn{m: m, h: h, s: &Stat{}, Conn: c} - if e == nil { - defer c.Close() - } - - switch cb := m.Optionv(kit.Keycb(DIAL)).(type) { - case func(net.Conn, error): - cb(c, e) - case func(net.Conn): - m.Assert(e) - cb(c) - case func(net.Conn, []byte, error): - b := make([]byte, ice.MOD_BUFS) - for { - n, e := c.Read(b) - if cb(c, b[:n], e); e != nil { - break - } - } - default: - c.Write([]byte("hello world\n")) - } - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, CLIENT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) - }}, - mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, ERROR) - m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, CLOSE) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Fields(len(arg), "time,hash,status,type,name,host,port,error,nread,nwrite") - if m.Cmdy(mdb.SELECT, CLIENT, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 { - m.Table(func(index int, value map[string]string, head []string) { - m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == OPEN)) - }) - } + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + CLIENT: {Name: CLIENT, Help: "客户端", Value: kit.Data( + kit.MDB_FIELD, "time,hash,status,type,name,host,port,error,nread,nwrite", + )}, + }, Commands: map[string]*ice.Command{ + ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Richs(CLIENT, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { + kit.Value(value, kit.Keym(kit.MDB_STATUS), CLOSE) + }) + }}, + CLIENT: {Name: "client hash auto prunes", Help: "客户端", Action: ice.MergeAction(map[string]*ice.Action{ + DIAL: {Name: "dial type name port=9010 host=", Help: "连接", Hand: func(m *ice.Message, arg ...string) { + _client_dial(m, arg...) }}, - }, - }) + mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, ERROR) + m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, CLOSE) + }}, + }, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + mdb.HashSelect(m, arg...).Table(func(index int, value map[string]string, head []string) { + m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == OPEN)) + }) + }}, + }}) } diff --git a/base/tcp/host.go b/base/tcp/host.go index c3fbdaab..e8a4038f 100644 --- a/base/tcp/host.go +++ b/base/tcp/host.go @@ -28,20 +28,20 @@ func _host_list(m *ice.Message, name string) { m.Push(kit.MDB_INDEX, v.Index) m.Push(kit.MDB_NAME, v.Name) - m.Push(IP, ip[0]) - m.Push(MASK, ip[1]) - m.Push(HARD, v.HardwareAddr.String()) + m.Push(aaa.IP, ip[0]) + m.Push("mask", ip[1]) + m.Push("hard", v.HardwareAddr.String()) } } } } - if len(m.Appendv(IP)) == 0 { + if len(m.Appendv(aaa.IP)) == 0 { m.Push(kit.MDB_INDEX, -1) m.Push(kit.MDB_NAME, LOCALHOST) - m.Push(IP, "127.0.0.1") - m.Push(MASK, "255.0.0.0") - m.Push(HARD, "") + m.Push(aaa.IP, "127.0.0.1") + m.Push("mask", "255.0.0.0") + m.Push("hard", "") } } @@ -61,43 +61,37 @@ func _islocalhost(m *ice.Message, ip string) (ok bool) { func IsLocalHost(m *ice.Message, ip string) bool { return _islocalhost(m, ip) } func ReplaceLocalhost(m *ice.Message, url string) string { if strings.Contains(url, "://"+LOCALHOST) { - url = strings.Replace(url, "://"+LOCALHOST, "://"+m.Cmd(HOST, ice.OptionFields(IP)).Append(IP), 1) + url = strings.Replace(url, "://"+LOCALHOST, "://"+m.Cmd(HOST).Append(aaa.IP), 1) } return url } const ( - HOSTPORT = "hostport" - HOSTNAME = "hostname" - PROTOCOL = "protocol" - LOCALHOST = "localhost" - - HARD = "hard" - MASK = "mask" - IP = "ip" ) const HOST = "host" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - HOST: {Name: HOST, Help: "主机", Value: kit.Data( - aaa.BLACK, kit.Data(kit.MDB_SHORT, kit.MDB_TEXT), - aaa.WHITE, kit.Data(kit.MDB_SHORT, kit.MDB_TEXT), - )}, - }, - Commands: map[string]*ice.Command{ - HOST: {Name: "host name auto", Help: "主机", Action: map[string]*ice.Action{ - aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) { - m.Rich(HOST, kit.Keym(aaa.BLACK), kit.Dict(kit.MDB_TEXT, arg[0])) - }}, - aaa.WHITE: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) { - m.Rich(HOST, kit.Keym(aaa.WHITE), kit.Dict(kit.MDB_TEXT, arg[0])) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - _host_list(m, kit.Select("", arg, 0)) + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + HOST: {Name: HOST, Help: "主机", Value: kit.Data( + aaa.BLACK, kit.Data(kit.MDB_SHORT, kit.MDB_TEXT), + aaa.WHITE, kit.Data(kit.MDB_SHORT, kit.MDB_TEXT), + )}, + }, Commands: map[string]*ice.Command{ + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmd(HOST).Table(func(index int, value map[string]string, head []string) { + m.Cmd(HOST, aaa.WHITE, value[aaa.IP]) + }) + }}, + HOST: {Name: "host name auto", Help: "主机", Action: map[string]*ice.Action{ + aaa.BLACK: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) { + m.Rich(HOST, kit.Keym(aaa.BLACK), kit.Dict(kit.MDB_TEXT, arg[0])) }}, - }, - }) + aaa.WHITE: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) { + m.Rich(HOST, kit.Keym(aaa.WHITE), kit.Dict(kit.MDB_TEXT, arg[0])) + }}, + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + _host_list(m, kit.Select("", arg, 0)) + }}, + }}) } diff --git a/base/tcp/port.go b/base/tcp/port.go index e4c7d2c2..5c5fb980 100644 --- a/base/tcp/port.go +++ b/base/tcp/port.go @@ -12,35 +12,27 @@ import ( kit "shylinux.com/x/toolkits" ) -func _port_list(m *ice.Message, port string, dir string) { - if m.Option(nfs.DIR_ROOT, path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port)); port != "" { - m.Cmdy(nfs.DIR, dir) - return - } - - m.Cmd(nfs.DIR, "./").Table(func(index int, value map[string]string, head []string) { - m.Push(kit.MDB_TIME, value[kit.MDB_TIME]) - m.Push(PORT, path.Base(value[kit.MDB_PATH])) - m.Push(kit.MDB_SIZE, value[kit.MDB_SIZE]) - }) -} -func _port_right(m *ice.Message, begin string) string { - current := kit.Int(kit.Select(m.Conf(PORT, kit.Keym(CURRENT)), begin)) - end := kit.Int(m.Conf(PORT, kit.Keym(END))) +func _port_right(m *ice.Message, arg ...string) string { + current := kit.Int(kit.Select(m.Config(CURRENT), arg, 0)) + end := kit.Int(m.Config(END)) if current >= end { - current = kit.Int(m.Conf(PORT, kit.Keym(BEGIN))) + current = kit.Int(m.Config(BEGIN)) } for i := current; i < end; i++ { if c, e := net.Dial(TCP, kit.Format(":%d", i)); e == nil { m.Info("port exists %v", i) - defer c.Close() + c.Close() continue } + p := path.Join(m.Conf(cli.DAEMON, kit.META_PATH), kit.Format(i)) + if _, e := os.Stat(p); e == nil { + continue + } + os.MkdirAll(p, ice.MOD_DIR) m.Log_SELECT(PORT, i) - m.Conf(PORT, kit.Keym(CURRENT), i) - return kit.Format("%d", i) + return m.Config(CURRENT, i) } return "" } @@ -54,30 +46,25 @@ const ( const PORT = "port" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - PORT: {Name: PORT, Help: "端口", Value: kit.Data( - BEGIN, 10000, CURRENT, 10000, END, 20000, - )}, - }, - Commands: map[string]*ice.Command{ - PORT: {Name: "port port path auto", Help: "端口", Action: map[string]*ice.Action{ - aaa.RIGHT: {Name: "right [begin]", Help: "分配", Hand: func(m *ice.Message, arg ...string) { - port, p := kit.Select("", arg, 0), "" - for i := 0; i < 10; i++ { - port = _port_right(m, port) - p = path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port) - if _, e := os.Stat(p); e != nil && os.IsNotExist(e) { - os.MkdirAll(p, ice.MOD_DIR) - break - } - port = kit.Format(kit.Int(port) + 1) - } - m.Echo(port) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - _port_list(m, kit.Select("", arg, 0), kit.Select("", arg, 1)) + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + PORT: {Name: PORT, Help: "端口", Value: kit.Data(BEGIN, 10000, CURRENT, 10000, END, 20000)}, + }, Commands: map[string]*ice.Command{ + PORT: {Name: "port port path auto", Help: "端口", Action: map[string]*ice.Action{ + aaa.RIGHT: {Name: "right", Help: "分配", Hand: func(m *ice.Message, arg ...string) { + m.Echo(_port_right(m, arg...)) }}, - }, - }) + }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + if len(arg) == 0 { + m.Option(nfs.DIR_ROOT, m.Conf(cli.DAEMON, kit.META_PATH)) + m.Cmd(nfs.DIR, "./").Table(func(index int, value map[string]string, head []string) { + m.Push(kit.MDB_TIME, value[kit.MDB_TIME]) + m.Push(PORT, path.Base(value[kit.MDB_PATH])) + m.Push(kit.MDB_SIZE, value[kit.MDB_SIZE]) + }) + return + } + m.Option(nfs.DIR_ROOT, path.Join(m.Conf(cli.DAEMON, kit.META_PATH), arg[0])) + m.Cmdy(nfs.DIR, arg[1:]) + }}, + }}) } diff --git a/base/tcp/server.go b/base/tcp/server.go index 9b931db0..cd91f14d 100644 --- a/base/tcp/server.go +++ b/base/tcp/server.go @@ -26,81 +26,87 @@ func (l Listener) Close() error { return l.Listener.Close() } +func _server_listen(m *ice.Message, arg ...string) { + l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT)) + h := m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, arg, + kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) + + l = &Listener{m: m, h: h, s: &Stat{}, Listener: l} + if e == nil { + defer l.Close() + } + + switch cb := m.Optionv(kit.Keycb(LISTEN)).(type) { + case func(net.Listener, error): + cb(l, e) + case func(net.Listener): + m.Assert(e) + cb(l) + case func(net.Conn): + for { + if c, e := l.Accept(); e == nil { + cb(c) + } else { + break + } + } + case func(net.Conn, error): + for { + c, e := l.Accept() + if cb(c, e); e != nil { + break + } + } + default: + for { + c, e := l.Accept() + if e != nil { + break + } + + b := make([]byte, ice.MOD_BUFS) + if n, e := c.Read(b); e == nil { + m.Info("nonce", string(b[:n])) + c.Write(b[:n]) + } + c.Close() + } + } +} + +const ( + PROTOCOL = "protocol" + HOSTPORT = "hostport" + HOSTNAME = "hostname" +) const ( LISTEN = "listen" ) - const SERVER = "server" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - SERVER: {Name: SERVER, Help: "服务器", Value: kit.Data()}, - }, - Commands: map[string]*ice.Command{ - SERVER: {Name: "server hash auto prunes", Help: "服务器", Action: map[string]*ice.Action{ - LISTEN: {Name: "LISTEN type name port=9010 host=", Help: "监听", Hand: func(m *ice.Message, arg ...string) { - l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT)) - h := m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, arg, - kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) - - l = &Listener{m: m, h: h, s: &Stat{}, Listener: l} - if e == nil { - defer l.Close() - } - - switch cb := m.Optionv(kit.Keycb(LISTEN)).(type) { - case func(net.Listener, error): - cb(l, e) - case func(net.Listener): - m.Assert(e) - cb(l) - case func(net.Conn): - for { - c, e := l.Accept() - if e != nil { - break - } - cb(c) - } - case func(net.Conn, error): - for { - c, e := l.Accept() - if cb(c, e); e != nil { - break - } - } - default: - for { - c, e := l.Accept() - if e != nil { - break - } - - b := make([]byte, ice.MOD_BUFS) - if n, e := c.Read(b); e == nil { - m.Info("nonce", string(b[:n])) - c.Write(b[:n]) - } - c.Close() - } - } - }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, SERVER, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)) - }}, - mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, ERROR) - m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, CLOSE) - }}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Fields(len(arg), "time,hash,status,type,name,host,port,error,nconn") - if m.Cmdy(mdb.SELECT, SERVER, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 { - m.Table(func(index int, value map[string]string, head []string) { - m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == CLOSE)) - }) - } + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + SERVER: {Name: SERVER, Help: "服务器", Value: kit.Data( + kit.MDB_FIELD, "time,hash,status,type,name,host,port,error,nconn", + )}, + }, Commands: map[string]*ice.Command{ + ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Richs(SERVER, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { + kit.Value(value, kit.Keym(kit.MDB_STATUS), CLOSE) + }) + }}, + SERVER: {Name: "server hash auto prunes", Help: "服务器", Action: ice.MergeAction(map[string]*ice.Action{ + LISTEN: {Name: "LISTEN type name port=9030 host=", Help: "监听", Hand: func(m *ice.Message, arg ...string) { + _server_listen(m, arg...) }}, - }, - }) + mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, ERROR) + m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, CLOSE) + }}, + }, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + mdb.HashSelect(m, arg...).Table(func(index int, value map[string]string, head []string) { + m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == CLOSE)) + }) + }}, + }}) } diff --git a/base/tcp/tcp.go b/base/tcp/tcp.go index 780d8062..9a909e40 100644 --- a/base/tcp/tcp.go +++ b/base/tcp/tcp.go @@ -2,30 +2,10 @@ package tcp import ( ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/aaa" - kit "shylinux.com/x/toolkits" ) const TCP = "tcp" -var Index = &ice.Context{Name: TCP, Help: "通信模块", - Commands: map[string]*ice.Command{ - ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Load() - m.Cmd(HOST).Table(func(index int, value map[string]string, head []string) { - m.Cmd(HOST, aaa.WHITE, value[IP]) - }) - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Richs(CLIENT, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { - kit.Value(value, kit.Keym(kit.MDB_STATUS), CLOSE) - }) - m.Richs(SERVER, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { - kit.Value(value, kit.Keym(kit.MDB_STATUS), CLOSE) - }) - m.Save(PORT) - }}, - }, -} +var Index = &ice.Context{Name: TCP, Help: "通信模块"} func init() { ice.Index.Register(Index, nil, HOST, PORT, CLIENT, SERVER) } diff --git a/base/web/route.go b/base/web/route.go index f4e4028f..24cb3b5f 100644 --- a/base/web/route.go +++ b/base/web/route.go @@ -50,7 +50,7 @@ func _route_list(m *ice.Message) { m.Cmd(tcp.HOST).Table(func(index int, value map[string]string, head []string) { m.Push(kit.MDB_TYPE, MYSELF) m.Push(kit.SSH_ROUTE, ice.Info.NodeName) - m.PushAnchor(value[tcp.IP], kit.Format("%s://%s:%s", u.Scheme, value[tcp.IP], u.Port())) + m.PushAnchor(value[aaa.IP], kit.Format("%s://%s:%s", u.Scheme, value[aaa.IP], u.Port())) m.PushButton(tcp.START) }) diff --git a/base/web/serve.go b/base/web/serve.go index 16096d95..9b930621 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -72,7 +72,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { } // 文件接口 - if m.Conf(SERVE, kit.Keym("dump")) != ice.FALSE && ice.Dump(w, r.URL.Path, func(name string) { RenderType(w, name, "") }) { + if ice.Dump(w, r.URL.Path, func(name string) { RenderType(w, name, "") }) { return false } return true diff --git a/base/web/space.go b/base/web/space.go index 4e7de1dc..15b2fe49 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -221,7 +221,7 @@ func _space_search(m *ice.Message, kind, name, text string, arg ...string) { } m.Cmd(tcp.HOST).Table(func(index int, value map[string]string, head []string) { m.PushSearch(ice.CMD, SPACE, kit.MDB_TYPE, MYSELF, kit.MDB_NAME, value[kit.MDB_NAME], - kit.MDB_TEXT, kit.Format("http://%s:%s", value[tcp.IP], port)) + kit.MDB_TEXT, kit.Format("http://%s:%s", value[aaa.IP], port)) }) } } diff --git a/base/yac/matrix.go b/base/yac/matrix.go index 4511ee43..7beabbbd 100644 --- a/base/yac/matrix.go +++ b/base/yac/matrix.go @@ -309,6 +309,24 @@ func (mat *Matrix) show(m *ice.Message) { m.Status(NLANG, mat.nlang, NCELL, mat.ncell, NPAGE, len(mat.page), NHASH, len(mat.hash)) } +func _yac_load(m *ice.Message) { + m.Richs(m.Prefix(MATRIX), "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { + value = kit.GetMeta(value) + + mat := NewMatrix(m, kit.Int(kit.Select("32", value[NLANG])), kit.Int(kit.Select("32", value[NCELL]))) + m.Grows(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { + page := mat.index(m, NPAGE, kit.Format(value[NPAGE])) + hash := mat.index(m, NHASH, kit.Format(value[NHASH])) + if mat.mat[page] == nil { + mat.mat[page] = make([]*State, mat.ncell) + } + + mat.train(m, page, hash, kit.Simple(value[kit.MDB_TEXT]), 1) + }) + value[MATRIX] = mat + }) +} + type Rewrite func(m *ice.Message, nhash string, hash int, word []string, begin int, stream *lex.Stream) (int, []string) const ( @@ -326,100 +344,101 @@ const ( const MATRIX = "matrix" func init() { - Index.Merge(&ice.Context{ - Configs: map[string]*ice.Config{ - MATRIX: {Name: MATRIX, Help: "魔方矩阵", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)}, - }, - Commands: map[string]*ice.Command{ - MATRIX: {Name: "matrix name npage text auto", Help: "魔方矩阵", Action: map[string]*ice.Action{ - mdb.CREATE: {Name: "create name=shy nlang=32 ncell=32", Help: "创建", Hand: func(m *ice.Message, arg ...string) { - mat := NewMatrix(m, kit.Int(kit.Select("32", m.Option(NLANG))), kit.Int(kit.Select("32", m.Option(NCELL)))) - h := m.Rich(m.Prefix(MATRIX), "", kit.Data( - kit.MDB_TIME, m.Time(), kit.MDB_NAME, m.Option(kit.MDB_NAME), - MATRIX, mat, NLANG, mat.nlang, NCELL, mat.ncell, - )) - switch cb := m.Optionv(kit.Keycb(MATRIX)).(type) { - case func(string, *Matrix): - cb(h, mat) + Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ + MATRIX: {Name: MATRIX, Help: "魔方矩阵", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME)}, + }, Commands: map[string]*ice.Command{ + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + _yac_load(m) + }}, + MATRIX: {Name: "matrix name npage text auto", Help: "魔方矩阵", Action: map[string]*ice.Action{ + mdb.CREATE: {Name: "create name=shy nlang=32 ncell=32", Help: "创建", Hand: func(m *ice.Message, arg ...string) { + mat := NewMatrix(m, kit.Int(kit.Select("32", m.Option(NLANG))), kit.Int(kit.Select("32", m.Option(NCELL)))) + h := m.Rich(m.Prefix(MATRIX), "", kit.Data( + kit.MDB_TIME, m.Time(), kit.MDB_NAME, m.Option(kit.MDB_NAME), + MATRIX, mat, NLANG, mat.nlang, NCELL, mat.ncell, + )) + switch cb := m.Optionv(kit.Keycb(MATRIX)).(type) { + case func(string, *Matrix): + cb(h, mat) + } + m.Echo(h) + }}, + mdb.INSERT: {Name: "insert name=shy npage=num nhash=num text=123", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + m.Richs(m.Prefix(MATRIX), "", m.Option(kit.MDB_NAME), func(key string, value map[string]interface{}) { + value = kit.GetMeta(value) + + mat, _ := value[MATRIX].(*Matrix) + + page := mat.index(m, NPAGE, m.Option(NPAGE)) + hash := mat.index(m, NHASH, m.Option(NHASH)) + if len(mat.mat[page]) == 0 { + mat.mat[page] = make([]*State, mat.ncell) } - m.Echo(h) - }}, - mdb.INSERT: {Name: "insert name=shy npage=num nhash=num text=123", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.Prefix(MATRIX), "", m.Option(kit.MDB_NAME), func(key string, value map[string]interface{}) { - value = kit.GetMeta(value) - mat, _ := value[MATRIX].(*Matrix) + m.Option(kit.MDB_TEXT, strings.ReplaceAll(m.Option(kit.MDB_TEXT), "\\", "\\\\")) + text := kit.Split(m.Option(kit.MDB_TEXT), " ", " ", " ") + mat.train(m, page, hash, text, 1) + m.Grow(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), kit.Dict( + kit.MDB_TIME, m.Time(), NPAGE, m.Option(NPAGE), NHASH, m.Option(NHASH), kit.MDB_TEXT, text, + )) - page := mat.index(m, NPAGE, m.Option(NPAGE)) - hash := mat.index(m, NHASH, m.Option(NHASH)) - if len(mat.mat[page]) == 0 { - mat.mat[page] = make([]*State, mat.ncell) - } + value[NPAGE] = len(mat.page) + value[NHASH] = len(mat.hash) + }) + }}, + mdb.REMOVE: {Name: "create", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(mdb.DELETE, m.Prefix(MATRIX), "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)) + }}, + PARSE: {Name: "parse name npage text=123", Help: "解析", Hand: func(m *ice.Message, arg ...string) { + m.Richs(m.Prefix(MATRIX), "", m.Option(kit.MDB_NAME), func(key string, value map[string]interface{}) { + value = kit.GetMeta(value) + mat, _ := value[MATRIX].(*Matrix) - m.Option(kit.MDB_TEXT, strings.ReplaceAll(m.Option(kit.MDB_TEXT), "\\", "\\\\")) - text := kit.Split(m.Option(kit.MDB_TEXT), " ", " ", " ") - mat.train(m, page, hash, text, 1) - m.Grow(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), kit.Dict( - kit.MDB_TIME, m.Time(), NPAGE, m.Option(NPAGE), NHASH, m.Option(NHASH), kit.MDB_TEXT, text, - )) - - value[NPAGE] = len(mat.page) - value[NHASH] = len(mat.hash) - }) - }}, - mdb.REMOVE: {Name: "create", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(mdb.DELETE, m.Prefix(MATRIX), "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)) - }}, - PARSE: {Name: "parse name npage text=123", Help: "解析", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.Prefix(MATRIX), "", m.Option(kit.MDB_NAME), func(key string, value map[string]interface{}) { - value = kit.GetMeta(value) - mat, _ := value[MATRIX].(*Matrix) - - for stream := lex.NewStream(bytes.NewBufferString(m.Option(kit.MDB_TEXT))); stream.Scan(); { - hash, _ := mat.Parse(m, func(m *ice.Message, nhash string, hash int, word []string, begin int, stream *lex.Stream) (int, []string) { - switch cb := m.Optionv(kit.Keycb(MATRIX)).(type) { - case func(string, int, []string, int, *lex.Stream) (int, []string): - return cb(nhash, hash, word, begin, stream) - } - return hash, word - }, mat.index(m, NPAGE, m.Option(NPAGE)), stream, 1) - - if hash == 0 { - break + for stream := lex.NewStream(bytes.NewBufferString(m.Option(kit.MDB_TEXT))); stream.Scan(); { + hash, _ := mat.Parse(m, func(m *ice.Message, nhash string, hash int, word []string, begin int, stream *lex.Stream) (int, []string) { + switch cb := m.Optionv(kit.Keycb(MATRIX)).(type) { + case func(string, int, []string, int, *lex.Stream) (int, []string): + return cb(nhash, hash, word, begin, stream) } + return hash, word + }, mat.index(m, NPAGE, m.Option(NPAGE)), stream, 1) + + if hash == 0 { + break } - }) - m.ProcessInner() - }}, - "show": {Name: "show", Help: "矩阵", Hand: func(m *ice.Message, arg ...string) { - m.Richs(m.Prefix(MATRIX), "", kit.Select(m.Option(kit.MDB_NAME), arg, 0), func(key string, value map[string]interface{}) { - value = kit.GetMeta(value) - value[MATRIX].(*Matrix).show(m) - }) - m.ProcessInner() - }}, - }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - m.Option(mdb.CACHE_LIMIT, -1) - if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表 - m.Fields(len(arg), "time,name,npage,nhash") - m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), "", mdb.HASH) - m.PushAction(mdb.INSERT, "show", mdb.REMOVE) - return - } - - if m.Action(mdb.INSERT, "show"); len(arg) == 1 { // 词法列表 - m.Fields(len(arg[1:]), "time,npage,nhash,text") - m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, kit.Hashs(arg[0])), mdb.LIST) - m.PushAction(PARSE) - return - } - - // 词法矩阵 - m.Richs(m.Prefix(MATRIX), "", arg[0], func(key string, value map[string]interface{}) { + } + }) + m.ProcessInner() + }}, + "show": {Name: "show", Help: "矩阵", Hand: func(m *ice.Message, arg ...string) { + m.Richs(m.Prefix(MATRIX), "", kit.Select(m.Option(kit.MDB_NAME), arg, 0), func(key string, value map[string]interface{}) { value = kit.GetMeta(value) value[MATRIX].(*Matrix).show(m) }) + m.ProcessInner() }}, - }, + }, Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + m.Option(mdb.CACHE_LIMIT, -1) + if m.Action(mdb.CREATE); len(arg) == 0 { // 矩阵列表 + m.Fields(len(arg), "time,name,npage,nhash") + m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), "", mdb.HASH) + m.PushAction(mdb.INSERT, "show", mdb.REMOVE) + return + } + + if m.Action(mdb.INSERT, "show"); len(arg) == 1 { // 词法列表 + m.Fields(len(arg[1:]), "time,npage,nhash,text") + m.Cmdy(mdb.SELECT, m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, kit.Hashs(arg[0])), mdb.LIST) + m.PushAction(PARSE) + return + } + + // 词法矩阵 + m.Richs(m.Prefix(MATRIX), "", arg[0], func(key string, value map[string]interface{}) { + value = kit.GetMeta(value) + value[MATRIX].(*Matrix).show(m) + }) + }}, + }, }) } diff --git a/base/yac/yac.go b/base/yac/yac.go index 4f904022..ac3be183 100644 --- a/base/yac/yac.go +++ b/base/yac/yac.go @@ -2,38 +2,10 @@ package yac import ( ice "shylinux.com/x/icebergs" - kit "shylinux.com/x/toolkits" ) -func _yac_load(m *ice.Message) { - m.Richs(m.Prefix(MATRIX), "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { - value = kit.GetMeta(value) - - mat := NewMatrix(m, kit.Int(kit.Select("32", value[NLANG])), kit.Int(kit.Select("32", value[NCELL]))) - m.Grows(m.Prefix(MATRIX), kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { - page := mat.index(m, NPAGE, kit.Format(value[NPAGE])) - hash := mat.index(m, NHASH, kit.Format(value[NHASH])) - if mat.mat[page] == nil { - mat.mat[page] = make([]*State, mat.ncell) - } - - mat.train(m, page, hash, kit.Simple(value[kit.MDB_TEXT]), 1) - }) - value[MATRIX] = mat - }) -} - const YAC = "yac" -var Index = &ice.Context{Name: YAC, Help: "语法模块", - Commands: map[string]*ice.Command{ - ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - _yac_load(m.Load()) - }}, - ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { - m.Save() - }}, - }, -} +var Index = &ice.Context{Name: YAC, Help: "语法模块"} func init() { ice.Index.Register(Index, nil) } diff --git a/core/code/case.go b/core/code/case.go index f792ab04..72d57728 100644 --- a/core/code/case.go +++ b/core/code/case.go @@ -22,13 +22,6 @@ func init() { }}, mdb.INSERT: {Name: "insert zone name=hi cmd=POST,GET api arg:textarea res:textarea", Help: "添加"}, - ice.RUN: {Name: "run", Help: "运行", Hand: func(m *ice.Message, arg ...string) { - m.Option(web.SPIDE_HEADER, web.ContentType, web.ContentJSON) - m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(web.SPIDE, m.Option(ice.DEV), web.SPIDE_RAW, - m.Option(ice.CMD), m.Option(cli.API), web.SPIDE_DATA, m.Option(ice.ARG))))) - m.Info(`curl "` + m.Option(cli.API) + `" -H "Content-Type: application/json"` + ` -d '` + m.Option(ice.ARG) + `'`) - m.ProcessDisplay("/plugin/local/wiki/json.js") - }}, cli.CHECK: {Name: "check", Help: "检查", Hand: func(m *ice.Message, arg ...string) { if m.ProcessInner(); len(arg) > 0 { success := 0 @@ -60,17 +53,23 @@ func init() { } m.Echo(ice.OK) }}, + ice.RUN: {Name: "run", Help: "运行", Hand: func(m *ice.Message, arg ...string) { + m.Option(web.SPIDE_HEADER, web.ContentType, web.ContentJSON) + m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(web.SPIDE, m.Option(ice.DEV), web.SPIDE_RAW, + m.Option(ice.CMD), m.Option(cli.API), web.SPIDE_DATA, m.Option(ice.ARG))))) + m.Info(`curl "` + m.Option(cli.API) + `" -H "Content-Type: application/json"` + ` -d '` + m.Option(ice.ARG) + `'`) + m.ProcessDisplay("/plugin/local/wiki/json.js") + }}, }, mdb.ZoneAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { - m.Action(mdb.CREATE) m.Cmdy(web.SPIDE) + m.Action(mdb.CREATE) m.RenameAppend("client.name", "dev") m.RenameAppend("client.url", "address") return } - m.Fields(len(arg)-1, "time,zone,count", m.Config(kit.MDB_FIELD)) - if m.Cmdy(mdb.SELECT, m.PrefixKey(), "", mdb.ZONE, arg[1:]); len(arg) == 1 { + if mdb.ZoneSelect(m, arg[1:]...); len(arg) == 1 { m.Action(mdb.INSERT, mdb.EXPORT, mdb.IMPORT) m.PushAction(mdb.INSERT, cli.CHECK, mdb.REMOVE) } else { diff --git a/init.go b/init.go index 6f3b6c97..0823a2bd 100644 --- a/init.go +++ b/init.go @@ -77,7 +77,7 @@ var Index = &Context{Name: "ice", Help: "冰山模块", Caches: map[string]*Cach }}, INIT: {Name: "init", Help: "启动", Hand: func(m *Message, c *Context, cmd string, arg ...string) { m.root.Cmd(CTX_INIT) - m.Cmd("ssh.source", ETC_INIT_SHY, "init.shy", "启动配置") + m.Cmd("ssh.source", ETC_INIT_SHY) m.Cmdy(arg) }}, HELP: {Name: "help", Help: "帮助", Hand: func(m *Message, c *Context, cmd string, arg ...string) { @@ -85,7 +85,7 @@ var Index = &Context{Name: "ice", Help: "冰山模块", Caches: map[string]*Cach }}, EXIT: {Name: "exit", Help: "结束", Hand: func(m *Message, c *Context, cmd string, arg ...string) { m.root.Option(EXIT, kit.Select("0", arg, 0)) - m.Cmd("ssh.source", ETC_EXIT_SHY, "exit.shy", "退出配置") + m.Cmd("ssh.source", ETC_EXIT_SHY) m.root.Cmd(CTX_EXIT) }}, CTX_EXIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) { diff --git a/misc/ssh/ssh.shy b/misc/ssh/ssh.shy new file mode 100644 index 00000000..b47cc0b9 --- /dev/null +++ b/misc/ssh/ssh.shy @@ -0,0 +1,12 @@ +chapter "ssh" +refer ` +官网 http://www.openssh.com/ +文档 https://man.openbsd.org/ssh +源码 https://github.com/openssh/openssh-portable +` + +field "连接" ssh.connect +field "会话" ssh.session +field "服务" ssh.service +field "通道" ssh.channel +