1
0
forked from x/icebergs
This commit is contained in:
shaoying 2020-09-29 19:25:13 +08:00
parent 75f8a0ccec
commit aa94fbf78a
17 changed files with 250 additions and 334 deletions

View File

@ -16,18 +16,17 @@ func _file_name(m *ice.Message, arg ...string) string {
} }
func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) { func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) {
m.Log_INSERT(kit.MDB_PREFIX, prefix, arg[0], arg[1]) m.Log_INSERT(kit.MDB_KEY, path.Join(prefix, chain), arg[0], arg[1])
m.Echo(m.Rich(prefix, chain, kit.Data(arg))) m.Echo(m.Rich(prefix, chain, kit.Data(arg)))
} }
func _hash_delete(m *ice.Message, prefix, chain, field, value string) { func _hash_delete(m *ice.Message, prefix, chain, field, value string) {
m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) { m.Richs(prefix, chain, value, func(key string, val map[string]interface{}) {
m.Log_DELETE(kit.MDB_PREFIX, prefix, field, value, kit.MDB_VALUE, kit.Format(val)) m.Log_DELETE(kit.MDB_KEY, path.Join(prefix, chain), field, value, kit.MDB_VALUE, kit.Format(val))
m.Conf(prefix, kit.Keys(chain, kit.MDB_HASH, key), "") m.Conf(prefix, kit.Keys(chain, kit.MDB_HASH, key), "")
}) })
} }
func _hash_select(m *ice.Message, prefix, chain, field, value string) { func _hash_select(m *ice.Message, prefix, chain, field, value string) {
if field == kit.MDB_HASH && value == "random" { if field == kit.MDB_HASH && value == RANDOM {
value = kit.MDB_RANDOMS value = kit.MDB_RANDOMS
} }
fields := kit.Split(kit.Select("time,hash,type,name,text", m.Option(FIELDS))) fields := kit.Split(kit.Select("time,hash,type,name,text", m.Option(FIELDS)))
@ -56,7 +55,7 @@ func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg
} }
kit.Value(val, arg[i], arg[i+1]) kit.Value(val, arg[i], arg[i+1])
} }
m.Log_MODIFY(kit.MDB_PREFIX, prefix, field, value, arg) m.Log_MODIFY(kit.MDB_KEY, path.Join(prefix, chain), field, value, arg)
}) })
} }
func _hash_export(m *ice.Message, prefix, chain, file string) { func _hash_export(m *ice.Message, prefix, chain, file string) {
@ -68,7 +67,7 @@ func _hash_export(m *ice.Message, prefix, chain, file string) {
en.SetIndent("", " ") en.SetIndent("", " ")
en.Encode(m.Confv(prefix, kit.Keys(chain, HASH))) en.Encode(m.Confv(prefix, kit.Keys(chain, HASH)))
m.Log_EXPORT(kit.MDB_FILE, p) m.Log_EXPORT(kit.MDB_KEY, path.Join(prefix, chain), kit.MDB_FILE, p)
m.Echo(p) m.Echo(p)
} }
func _hash_import(m *ice.Message, prefix, chain, file string) { func _hash_import(m *ice.Message, prefix, chain, file string) {
@ -95,10 +94,11 @@ func _hash_import(m *ice.Message, prefix, chain, file string) {
} }
} }
m.Log_IMPORT(kit.MDB_PREFIX, prefix, kit.MDB_COUNT, count) m.Log_IMPORT(kit.MDB_KEY, path.Join(prefix, chain), kit.MDB_COUNT, count)
m.Echo("%d", count) m.Echo("%d", count)
} }
func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) { func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
fields := kit.Split(kit.Select("time,hash,type,name,text", m.Option(FIELDS)))
m.Richs(prefix, chain, kit.MDB_FOREACH, func(key string, val map[string]interface{}) { m.Richs(prefix, chain, kit.MDB_FOREACH, func(key string, val map[string]interface{}) {
if val[kit.MDB_META] != nil { if val[kit.MDB_META] != nil {
val = val[kit.MDB_META].(map[string]interface{}) val = val[kit.MDB_META].(map[string]interface{})
@ -108,8 +108,10 @@ func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
return return
} }
} }
_hash_delete(m, prefix, chain, kit.MDB_HASH, key) m.Push(key, val, fields)
m.Push(key, val) })
m.Table(func(index int, value map[string]string, head []string) {
_hash_delete(m, prefix, chain, kit.MDB_HASH, value[kit.MDB_HASH])
}) })
} }
func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) { func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) {
@ -132,7 +134,7 @@ func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) {
} }
func _list_insert(m *ice.Message, prefix, chain string, arg ...string) { func _list_insert(m *ice.Message, prefix, chain string, arg ...string) {
m.Log_INSERT(kit.MDB_PREFIX, prefix, arg[0], arg[1]) m.Log_INSERT(kit.MDB_KEY, path.Join(prefix, chain), arg[0], arg[1])
m.Echo("%d", m.Grow(prefix, chain, kit.Dict(arg))) m.Echo("%d", m.Grow(prefix, chain, kit.Dict(arg)))
} }
func _list_delete(m *ice.Message, prefix, chain, field, value string) { func _list_delete(m *ice.Message, prefix, chain, field, value string) {
@ -143,11 +145,10 @@ func _list_select(m *ice.Message, prefix, chain, field, value string) {
if val[kit.MDB_META] != nil { if val[kit.MDB_META] != nil {
val = val[kit.MDB_META].(map[string]interface{}) val = val[kit.MDB_META].(map[string]interface{})
} }
if m.Option(FIELDS) == DETAIL { if m.Option(FIELDS) == DETAIL {
m.Push(DETAIL, val) m.Push(DETAIL, val)
} else { } else {
m.Push(kit.Format(index), val, fields) m.Push("", val, fields)
} }
}) })
if m.Option(FIELDS) != DETAIL { if m.Option(FIELDS) != DETAIL {
@ -165,7 +166,7 @@ func _list_modify(m *ice.Message, prefix, chain string, field, value string, arg
} }
kit.Value(val, arg[i], arg[i+1]) kit.Value(val, arg[i], arg[i+1])
} }
m.Log_MODIFY(kit.MDB_PREFIX, prefix, field, value, arg) m.Log_MODIFY(kit.MDB_KEY, path.Join(prefix, chain), field, value, arg)
}) })
} }
func _list_export(m *ice.Message, prefix, chain, file string) { func _list_export(m *ice.Message, prefix, chain, file string) {
@ -178,10 +179,14 @@ func _list_export(m *ice.Message, prefix, chain, file string) {
count := 0 count := 0
head := kit.Split(m.Option(FIELDS)) head := kit.Split(m.Option(FIELDS))
m.Grows(prefix, chain, "", "", func(index int, value map[string]interface{}) { m.Grows(prefix, chain, "", "", func(index int, val map[string]interface{}) {
if val[kit.MDB_META] != nil {
val = val[kit.MDB_META].(map[string]interface{})
}
if index == 0 && len(head) == 0 { if index == 0 && len(head) == 0 {
// 输出表头 // 输出表头
for k := range value { for k := range val {
head = append(head, k) head = append(head, k)
} }
sort.Strings(head) sort.Strings(head)
@ -191,13 +196,13 @@ func _list_export(m *ice.Message, prefix, chain, file string) {
// 输出数据 // 输出数据
data := []string{} data := []string{}
for _, k := range head { for _, k := range head {
data = append(data, kit.Format(value[k])) data = append(data, kit.Format(val[k]))
} }
w.Write(data) w.Write(data)
count++ count++
}) })
m.Log_EXPORT(kit.MDB_FILE, p, kit.MDB_COUNT, count) m.Log_EXPORT(kit.MDB_KEY, path.Join(prefix, chain), kit.MDB_FILE, p, kit.MDB_COUNT, count)
m.Echo(p) m.Echo(p)
} }
func _list_import(m *ice.Message, prefix, chain, file string) { func _list_import(m *ice.Message, prefix, chain, file string) {
@ -218,9 +223,9 @@ func _list_import(m *ice.Message, prefix, chain, file string) {
data := kit.Dict() data := kit.Dict()
for i, k := range head { for i, k := range head {
if k == kit.MDB_EXTRA { if k == kit.MDB_EXTRA {
data[k] = kit.UnMarshal(line[i]) kit.Value(data, k, kit.UnMarshal(line[i]))
} else { } else {
data[k] = line[i] kit.Value(data, k, line[i])
} }
} }
@ -231,6 +236,8 @@ func _list_import(m *ice.Message, prefix, chain, file string) {
m.Log_IMPORT(kit.MDB_KEY, kit.Keys(prefix, chain), kit.MDB_COUNT, count) m.Log_IMPORT(kit.MDB_KEY, kit.Keys(prefix, chain), kit.MDB_COUNT, count)
m.Echo("%d", count) m.Echo("%d", count)
} }
func _list_prunes(m *ice.Message, prefix, chain string, arg ...string) {
}
func _list_inputs(m *ice.Message, prefix, chain string, field, value string) { func _list_inputs(m *ice.Message, prefix, chain string, field, value string) {
list := map[string]int{} list := map[string]int{}
m.Grows(prefix, chain, "", "", func(index int, val map[string]interface{}) { m.Grows(prefix, chain, "", "", func(index int, val map[string]interface{}) {
@ -254,7 +261,11 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) {
val = val[kit.MDB_META].(map[string]interface{}) val = val[kit.MDB_META].(map[string]interface{})
} }
if zone == "" { if zone == "" {
m.Push(key, val, fields) if m.Option(FIELDS) == DETAIL {
m.Push(DETAIL, val)
} else {
m.Push(key, val, fields)
}
return return
} }
@ -266,6 +277,8 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) {
switch cb := cb.(type) { switch cb := cb.(type) {
case func(string, map[string]interface{}, map[string]interface{}): case func(string, map[string]interface{}, map[string]interface{}):
cb(key, value, val) cb(key, value, val)
case func(string, map[string]interface{}):
cb(key, value)
default: default:
if m.Option(FIELDS) == DETAIL { if m.Option(FIELDS) == DETAIL {
m.Push(DETAIL, value) m.Push(DETAIL, value)
@ -300,14 +313,14 @@ func _zone_export(m *ice.Message, prefix, chain, file string) {
list := []string{} list := []string{}
for _, k := range fields { for _, k := range fields {
list = append(list, kit.Select(kit.Format(val[k]), kit.Format(value[k]))) list = append(list, kit.Select(kit.Format(kit.Value(val, k)), kit.Format(kit.Value(value, k))))
} }
w.Write(list) w.Write(list)
count++ count++
}) })
}) })
m.Log_EXPORT(kit.MDB_FILE, p, kit.MDB_COUNT, count) m.Log_EXPORT(kit.MDB_KEY, path.Join(prefix, chain), kit.MDB_FILE, p, kit.MDB_COUNT, count)
m.Echo(p) m.Echo(p)
} }
func _zone_import(m *ice.Message, prefix, chain, file string) { func _zone_import(m *ice.Message, prefix, chain, file string) {
@ -343,14 +356,14 @@ func _zone_import(m *ice.Message, prefix, chain, file string) {
} }
} }
if list[zone] == "" { if list[zone] == "" {
list[zone] = m.Rich(prefix, chain, kit.Dict(zkey, zone)) list[zone] = m.Rich(prefix, chain, kit.Data(zkey, zone))
} }
m.Grow(prefix, kit.Keys(chain, kit.MDB_HASH, list[zone]), data) m.Grow(prefix, kit.Keys(chain, kit.MDB_HASH, list[zone]), data)
count++ count++
} }
m.Log_IMPORT(kit.MDB_PREFIX, prefix, kit.MDB_COUNT, count) m.Log_IMPORT(kit.MDB_KEY, path.Join(prefix, chain), kit.MDB_COUNT, count)
m.Echo("%d", count) m.Echo("%d", count)
} }
@ -368,9 +381,7 @@ const (
const ( const (
FIELDS = "fields" FIELDS = "fields"
DETAIL = "detail" DETAIL = "detail"
RANDOM = "random"
INVITE = "invite"
COMMIT = "commit"
CREATE = "create" CREATE = "create"
INSERT = "insert" INSERT = "insert"
@ -383,87 +394,89 @@ const (
IMPORT = "import" IMPORT = "import"
PRUNES = "prunes" PRUNES = "prunes"
INPUTS = "inputs" INPUTS = "inputs"
SCRIPT = "script" INVITE = "invite"
COMMIT = "commit"
) )
var Index = &ice.Context{Name: "mdb", Help: "数据模块", const MDB = "mdb"
Commands: map[string]*ice.Command{
INSERT: {Name: "insert conf key type arg...", Help: "添加", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: map[string]*ice.Command{
switch arg[2] { INSERT: {Name: "insert conf key type arg...", Help: "添加", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
case HASH: switch arg[2] {
_hash_insert(m, arg[0], arg[1], arg[3:]...) case HASH:
case LIST: _hash_insert(m, arg[0], arg[1], arg[3:]...)
_list_insert(m, arg[0], arg[1], arg[3:]...) case LIST:
} _list_insert(m, arg[0], arg[1], arg[3:]...)
}}, }
DELETE: {Name: "delete conf key type field value", Help: "删除", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }},
switch arg[2] { DELETE: {Name: "delete conf key type field value", Help: "删除", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
case HASH: switch arg[2] {
_hash_delete(m, arg[0], arg[1], arg[3], arg[4]) case HASH:
case LIST: _hash_delete(m, arg[0], arg[1], arg[3], arg[4])
_list_delete(m, arg[0], arg[1], arg[3], arg[4]) case LIST:
} _list_delete(m, arg[0], arg[1], arg[3], arg[4])
}}, }
MODIFY: {Name: "modify conf key type field value arg...", Help: "编辑", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }},
switch arg[2] { MODIFY: {Name: "modify conf key type field value arg...", Help: "编辑", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
case HASH: switch arg[2] {
_hash_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...) case HASH:
case LIST: _hash_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...)
_list_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...) case LIST:
} _list_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...)
}}, }
SELECT: {Name: "select conf key type field value", Help: "数据查询", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }},
switch arg[2] { SELECT: {Name: "select conf key type field value", Help: "查询", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
case HASH: switch arg[2] {
_hash_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select(kit.MDB_FOREACH, arg, 4)) case HASH:
case LIST: _hash_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select(kit.MDB_FOREACH, arg, 4))
_list_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4)) case LIST:
case ZONE: _list_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4))
_zone_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4)) case ZONE:
} _zone_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4))
}}, }
EXPORT: {Name: "export conf key type file", Help: "导出数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }},
m.Option("cache.limit", -2) EXPORT: {Name: "export conf key type file", Help: "导出", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch file := _file_name(m, arg...); arg[2] { switch file := _file_name(m, arg...); arg[2] {
case HASH: case HASH:
_hash_export(m, arg[0], arg[1], file) _hash_export(m, arg[0], arg[1], file)
case LIST: case LIST:
_list_export(m, arg[0], arg[1], file) _list_export(m, arg[0], arg[1], file)
case ZONE: case ZONE:
_zone_export(m, arg[0], arg[1], file) _zone_export(m, arg[0], arg[1], file)
} }
}}, }},
IMPORT: {Name: "import conf key type file", Help: "导入数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { IMPORT: {Name: "import conf key type file", Help: "导入", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch file := _file_name(m, arg...); arg[2] { switch file := _file_name(m, arg...); arg[2] {
case HASH: case HASH:
_hash_import(m, arg[0], arg[1], file) _hash_import(m, arg[0], arg[1], file)
case LIST: case LIST:
_list_import(m, arg[0], arg[1], file) _list_import(m, arg[0], arg[1], file)
case ZONE: case ZONE:
_zone_import(m, arg[0], arg[1], file) _zone_import(m, arg[0], arg[1], file)
} }
}}, }},
PRUNES: {Name: "prunes conf key type [field value]...", Help: "清理数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { PRUNES: {Name: "prunes conf key type [field value]...", Help: "清理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[2] { switch arg[2] {
case HASH: case HASH:
_hash_prunes(m, arg[0], arg[1], arg[3:]...) _hash_prunes(m, arg[0], arg[1], arg[3:]...)
case LIST: case LIST:
} _list_prunes(m, arg[0], arg[1], arg[3:]...)
}}, }
INPUTS: {Name: "inputs conf key type field value", Help: "输入补全", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }},
switch arg[2] { INPUTS: {Name: "inputs conf key type field value", Help: "补全", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
case HASH: switch arg[2] {
_hash_inputs(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4)) case HASH:
case LIST: _hash_inputs(m, arg[0], arg[1], kit.Select("name", arg, 3), kit.Select("", arg, 4))
} case LIST:
}}, _hash_inputs(m, arg[0], arg[1], kit.Select("name", arg, 3), kit.Select("", arg, 4))
}, }
} }},
}}
func init() { func init() {
ice.Index.Register(Index, nil, ice.Index.Register(Index, nil,
INSERT, DELETE, MODIFY, SELECT, INSERT, DELETE, MODIFY, SELECT,
EXPORT, IMPORT, PRUNES, INPUTS, EXPORT, IMPORT, PRUNES, INPUTS,
PLUGIN, RENDER, SEARCH, ENGINE, PLUGIN, RENDER, ENGINE, SEARCH,
) )
} }

View File

@ -14,7 +14,7 @@ func init() {
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
PLUGIN: {Name: "plugin type name text", Help: "插件", Action: map[string]*ice.Action{ PLUGIN: {Name: "plugin type name text", Help: "插件", Action: map[string]*ice.Action{
CREATE: {Name: "create type [cmd [ctx]]", Help: "创建", Hand: func(m *ice.Message, arg ...string) { CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Rich(PLUGIN, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2))) m.Rich(PLUGIN, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -13,8 +13,8 @@ func init() {
RENDER: {Name: "render", Help: "渲染", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)}, RENDER: {Name: "render", Help: "渲染", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
RENDER: {Name: "render type name [text]", Help: "渲染", Action: map[string]*ice.Action{ RENDER: {Name: "render type name text", Help: "渲染", Action: map[string]*ice.Action{
CREATE: {Name: "create type [cmd [ctx]]", Help: "创建", Hand: func(m *ice.Message, arg ...string) { CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Rich(RENDER, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2))) m.Rich(RENDER, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -15,8 +15,8 @@ func init() {
SEARCH: {Name: "search", Help: "搜索", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)}, SEARCH: {Name: "search", Help: "搜索", Value: kit.Data(kit.MDB_SHORT, kit.MDB_TYPE)},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
SEARCH: {Name: "search type word [text]", Help: "搜索", Action: map[string]*ice.Action{ SEARCH: {Name: "search type word text", Help: "搜索", Action: map[string]*ice.Action{
CREATE: {Name: "create type [cmd [ctx]]", Help: "创建", Hand: func(m *ice.Message, arg ...string) { CREATE: {Name: "create type cmd ctx", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Rich(SEARCH, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2))) m.Rich(SEARCH, nil, kit.Dict(kit.MDB_TYPE, arg[0], kit.MDB_NAME, kit.Select(arg[0], arg, 1), kit.MDB_TEXT, kit.Select("", arg, 2)))
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {

View File

@ -14,12 +14,7 @@ import (
"strings" "strings"
) )
type Winsize struct { type Winsize struct{ Height, Width, x, y uint16 }
Height uint16
Width uint16
x uint16
y uint16
}
func _ssh_exec(m *ice.Message, cmd string, arg []string, env []string, tty io.ReadWriter, done func()) { func _ssh_exec(m *ice.Message, cmd string, arg []string, env []string, tty io.ReadWriter, done func()) {
m.Log_IMPORT(CMD, cmd, ARG, arg, ENV, env) m.Log_IMPORT(CMD, cmd, ARG, arg, ENV, env)
@ -58,7 +53,7 @@ func _ssh_watch(m *ice.Message, meta map[string]string, h string, input io.Reade
case '\r', '\n': case '\r', '\n':
cmd := strings.TrimSpace(string(buf[:i])) cmd := strings.TrimSpace(string(buf[:i]))
m.Log_IMPORT(aaa.HOSTNAME, meta[aaa.HOSTNAME], aaa.USERNAME, meta[aaa.USERNAME], CMD, cmd) m.Log_IMPORT(aaa.HOSTNAME, meta[aaa.HOSTNAME], aaa.USERNAME, meta[aaa.USERNAME], CMD, cmd)
m.Cmdy(mdb.INSERT, CHANNEL, kit.Keys(kit.MDB_HASH, h), mdb.LIST, CMD, cmd) m.Cmdy(mdb.INSERT, CHANNEL, kit.Keys(kit.MDB_HASH, h), mdb.LIST, kit.MDB_TYPE, CMD, kit.MDB_TEXT, cmd)
i = 0 i = 0
default: default:
if i += n; i >= 4096 { if i += n; i >= 4096 {
@ -83,12 +78,12 @@ func init() {
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
m.Option(mdb.FIELDS, "time,hash,status,tty,count") m.Option(mdb.FIELDS, "time,hash,status,username,hostname,hostport,tty,count")
m.Cmdy(mdb.SELECT, CHANNEL, "", mdb.HASH) m.Cmdy(mdb.SELECT, CHANNEL, "", mdb.HASH)
return return
} }
m.Option(mdb.FIELDS, kit.Select("time,id,cmd", mdb.DETAIL, len(arg) > 1)) m.Option(mdb.FIELDS, kit.Select("time,id,type,text", mdb.DETAIL, len(arg) > 1))
m.Cmdy(mdb.SELECT, CHANNEL, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:]) m.Cmdy(mdb.SELECT, CHANNEL, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
}}, }},
}, },

View File

@ -15,7 +15,7 @@ import (
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
func _ssh_conn(m *ice.Message, conn net.Conn, hostport, username string) (*ssh.Client, error) { func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) (*ssh.Client, error) {
key, e := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(os.Getenv("HOME"), m.Option("private"))))) key, e := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(os.Getenv("HOME"), m.Option("private")))))
m.Assert(e) m.Assert(e)
@ -46,9 +46,8 @@ func init() {
CONNECT: {Name: "connect hash auto 添加 清理", Help: "连接", Action: map[string]*ice.Action{ CONNECT: {Name: "connect hash auto 添加 清理", Help: "连接", Action: map[string]*ice.Action{
tcp.DIAL: {Name: "dial username=shy host=shylinux.com port=22 private=.ssh/id_rsa", Help: "添加", Hand: func(m *ice.Message, arg ...string) { tcp.DIAL: {Name: "dial username=shy host=shylinux.com port=22 private=.ssh/id_rsa", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Option(tcp.DIAL_CB, func(c net.Conn) { m.Option(tcp.DIAL_CB, func(c net.Conn) {
client, e := _ssh_conn(m, c, client, e := _ssh_conn(m, c, kit.Select("shy", m.Option(aaa.USERNAME)),
kit.Select(m.Option(tcp.HOST), "shylinux.com")+":"+kit.Select("22", m.Option(tcp.PORT)), kit.Select("shylinux.com", m.Option(tcp.HOST))+":"+kit.Select("22", m.Option(tcp.PORT)),
kit.Select("shy", m.Option(aaa.USERNAME)),
) )
m.Assert(e) m.Assert(e)
@ -60,9 +59,11 @@ func init() {
CONNECT, client, CONNECT, client,
)) ))
m.Cmd(CONNECT, SESSION, kit.MDB_HASH, h) m.Cmd(CONNECT, SESSION, kit.MDB_HASH, h)
m.Echo(h)
}) })
m.Cmds(tcp.CLIENT, tcp.DIAL, arg) m.Cmds(tcp.CLIENT, tcp.DIAL, arg)
m.Sleep("100ms")
}}, }},
SESSION: {Name: "session hash", Help: "会话", Hand: func(m *ice.Message, arg ...string) { SESSION: {Name: "session hash", Help: "会话", Hand: func(m *ice.Message, arg ...string) {
m.Richs(CONNECT, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) { m.Richs(CONNECT, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {

View File

@ -13,21 +13,26 @@ import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
"github.com/kr/pty"
"io" "io"
"net" "net"
"os" "os"
"path" "path"
"strings" "strings"
"github.com/kr/pty"
) )
func _ssh_meta(conn ssh.ConnMetadata) map[string]string {
return map[string]string{aaa.USERNAME: conn.User(), aaa.HOSTPORT: conn.RemoteAddr().String()}
}
func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig { func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig {
config := &ssh.ServerConfig{ config := &ssh.ServerConfig{
PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
meta, err := map[string]string{aaa.USERNAME: conn.User()}, errors.New(ice.ErrNotAuth) meta, err := _ssh_meta(conn), errors.New(ice.ErrNotAuth)
if tcp.IsLocalHost(m, strings.Split(conn.RemoteAddr().String(), ":")[0]) { if tcp.IsLocalHost(m, strings.Split(conn.RemoteAddr().String(), ":")[0]) {
m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User()) m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User())
err = nil err = nil // 本机用户
} else { } else {
m.Cmd(mdb.SELECT, SERVICE, kit.Keys(kit.MDB_HASH, h), mdb.LIST).Table(func(index int, value map[string]string, head []string) { m.Cmd(mdb.SELECT, SERVICE, kit.Keys(kit.MDB_HASH, h), mdb.LIST).Table(func(index int, value map[string]string, head []string) {
if !strings.HasPrefix(value[kit.MDB_NAME], conn.User()+"@") { if !strings.HasPrefix(value[kit.MDB_NAME], conn.User()+"@") {
@ -38,8 +43,8 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig {
if bytes.Compare(pub.Marshal(), key.Marshal()) == 0 { if bytes.Compare(pub.Marshal(), key.Marshal()) == 0 {
m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), aaa.HOSTNAME, value[kit.MDB_NAME]) m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), aaa.HOSTNAME, value[kit.MDB_NAME])
meta[aaa.USERNAME] = value[kit.MDB_NAME] meta[aaa.HOSTNAME] = kit.Select("", kit.Split(value[kit.MDB_NAME], "@"), 1)
err = nil err = nil // 认证成功
} }
} }
} }
@ -48,11 +53,11 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig {
return &ssh.Permissions{Extensions: meta}, err return &ssh.Permissions{Extensions: meta}, err
}, },
PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {
meta, err := map[string]string{aaa.USERNAME: conn.User()}, errors.New(ice.ErrNotAuth) meta, err := _ssh_meta(conn), errors.New(ice.ErrNotAuth)
m.Richs(aaa.USER, "", conn.User(), func(k string, value map[string]interface{}) { m.Richs(aaa.USER, "", conn.User(), func(k string, value map[string]interface{}) {
if string(password) == kit.Format(value[aaa.PASSWORD]) { if string(password) == kit.Format(value[aaa.PASSWORD]) {
m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), aaa.PASSWORD, strings.Repeat("*", len(kit.Format(value[aaa.PASSWORD])))) m.Log_AUTH(aaa.HOSTPORT, conn.RemoteAddr(), aaa.USERNAME, conn.User(), aaa.PASSWORD, strings.Repeat("*", len(kit.Format(value[aaa.PASSWORD]))))
err = nil err = nil // 密码登录
} }
}) })
return &ssh.Permissions{Extensions: meta}, err return &ssh.Permissions{Extensions: meta}, err
@ -101,7 +106,7 @@ func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh
} }
defer tty.Close() defer tty.Close()
h := m.Rich(CHANNEL, "", kit.Data(kit.MDB_STATUS, tcp.OPEN, TTY, tty.Name(), aaa.HOSTPORT, c.RemoteAddr().String())) h := m.Rich(CHANNEL, "", kit.Data(kit.MDB_STATUS, tcp.OPEN, TTY, tty.Name(), meta))
meta[CHANNEL] = h meta[CHANNEL] = h
for request := range requests { for request := range requests {
@ -150,20 +155,32 @@ func init() {
SERVICE: {Name: SERVICE, Help: "服务", Value: kit.Data( SERVICE: {Name: SERVICE, Help: "服务", Value: kit.Data(
"welcome", "\r\nwelcome to context world\r\n", "welcome", "\r\nwelcome to context world\r\n",
"goodbye", "\r\ngoodbye of context world\r\n", "goodbye", "\r\ngoodbye of context world\r\n",
kit.MDB_SHORT, tcp.PORT,
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
SERVICE: {Name: "service hash id auto 监听 清理", Help: "服务", Action: map[string]*ice.Action{ SERVICE: {Name: "service port id auto 监听 清理", Help: "服务", Action: map[string]*ice.Action{
tcp.LISTEN: {Name: "listen port=9030 private=.ssh/id_rsa", Help: "监听", Hand: func(m *ice.Message, arg ...string) { tcp.LISTEN: {Name: "listen port=9030 private=.ssh/id_rsa auth=.ssh/authorized_keys", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
h := m.Cmdx(mdb.INSERT, SERVICE, "", mdb.HASH, kit.MDB_STATUS, tcp.OPEN, arg) if m.Richs(SERVICE, "", m.Option(tcp.PORT), func(key string, value map[string]interface{}) {
kit.Value(value, "meta.status", tcp.OPEN)
}) == nil {
m.Cmd(mdb.INSERT, SERVICE, "", mdb.HASH, kit.MDB_STATUS, tcp.OPEN,
tcp.PORT, m.Option(tcp.PORT), "private", m.Option("private"), "auth", m.Option("auth"), arg)
m.Cmd(SERVICE, mdb.IMPORT, kit.MDB_FILE, m.Option("auth"))
}
m.Option(tcp.LISTEN_CB, func(c net.Conn) { m.Go(func() { _ssh_accept(m, h, c) }) }) m.Option(tcp.LISTEN_CB, func(c net.Conn) { m.Go(func() { _ssh_accept(m, kit.Hashs(m.Option(tcp.PORT)), c) }) })
m.Go(func() { m.Cmdy(tcp.SERVER, tcp.LISTEN, kit.MDB_NAME, SSH, tcp.PORT, m.Option(tcp.PORT)) }) m.Go(func() { m.Cmdy(tcp.SERVER, tcp.LISTEN, kit.MDB_NAME, SSH, tcp.PORT, m.Option(tcp.PORT)) })
}}, }},
mdb.INSERT: {Name: "insert text:textarea", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
ls := kit.Split(m.Option(kit.MDB_TEXT))
m.Cmdy(mdb.INSERT, SERVICE, kit.Keys(kit.MDB_HASH, kit.Hashs(m.Option(tcp.PORT))), mdb.LIST,
kit.MDB_TYPE, ls[0], kit.MDB_NAME, ls[len(ls)-1], kit.MDB_TEXT, strings.Join(ls[1:len(ls)-1], "+"))
}},
mdb.EXPORT: {Name: "export file=.ssh/authorized_keys", Help: "导出", Hand: func(m *ice.Message, arg ...string) { mdb.EXPORT: {Name: "export file=.ssh/authorized_keys", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
list := []string{} list := []string{}
m.Cmd(mdb.SELECT, SERVICE, kit.Keys(kit.MDB_HASH, m.Option(kit.MDB_HASH)), mdb.LIST).Table(func(index int, value map[string]string, head []string) { m.Cmd(mdb.SELECT, SERVICE, kit.Keys(kit.MDB_HASH, kit.Hashs(m.Option(tcp.PORT))), mdb.LIST).Table(func(index int, value map[string]string, head []string) {
list = append(list, fmt.Sprintf("%s %s %s", value[kit.MDB_TYPE], value[kit.MDB_TEXT], value[kit.MDB_NAME])) list = append(list, fmt.Sprintf("%s %s %s", value[kit.MDB_TYPE], value[kit.MDB_TEXT], value[kit.MDB_NAME]))
}) })
@ -175,7 +192,7 @@ func init() {
p := path.Join(os.Getenv("HOME"), m.Option(kit.MDB_FILE)) p := path.Join(os.Getenv("HOME"), m.Option(kit.MDB_FILE))
for _, pub := range strings.Split(m.Cmdx(nfs.CAT, p), "\n") { for _, pub := range strings.Split(m.Cmdx(nfs.CAT, p), "\n") {
if ls := kit.Split(pub); len(pub) > 10 { if ls := kit.Split(pub); len(pub) > 10 {
m.Cmd(mdb.INSERT, SERVICE, kit.Keys(kit.MDB_HASH, m.Option(kit.MDB_HASH)), mdb.LIST, m.Cmd(mdb.INSERT, SERVICE, kit.Keys(kit.MDB_HASH, kit.Hashs(m.Option(tcp.PORT))), mdb.LIST,
kit.MDB_TYPE, ls[0], kit.MDB_NAME, ls[len(ls)-1], kit.MDB_TEXT, strings.Join(ls[1:len(ls)-1], "+")) kit.MDB_TYPE, ls[0], kit.MDB_NAME, ls[len(ls)-1], kit.MDB_TEXT, strings.Join(ls[1:len(ls)-1], "+"))
} }
} }
@ -186,14 +203,14 @@ func init() {
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
m.Option(mdb.FIELDS, "time,hash,status,port,private,count") m.Option(mdb.FIELDS, "time,status,port,private,auth,count")
m.Cmdy(mdb.SELECT, SERVICE, "", mdb.HASH, kit.MDB_HASH, arg) m.Cmdy(mdb.SELECT, SERVICE, "", mdb.HASH)
m.PushAction("导入") m.PushAction("导入,添加,导出")
return return
} }
m.Option(mdb.FIELDS, kit.Select("time,id,type,name,text", mdb.DETAIL, len(arg) > 1)) m.Option(mdb.FIELDS, kit.Select("time,id,type,name,text", mdb.DETAIL, len(arg) > 1))
m.Cmdy(mdb.SELECT, SERVICE, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:]) m.Cmdy(mdb.SELECT, SERVICE, kit.Keys(kit.MDB_HASH, kit.Hashs(arg[0])), mdb.LIST, kit.MDB_ID, arg[1:])
}}, }},
}, },
}, nil) }, nil)

View File

@ -34,8 +34,7 @@ var Index = &ice.Context{Name: SSH, Help: "终端模块", Commands: map[string]*
func init() { func init() {
ice.Index.Register(Index, &Frame{}, ice.Index.Register(Index, &Frame{},
CONNECT, SESSION, SERVICE, CHANNEL,
SOURCE, TARGET, PROMPT, RETURN, SOURCE, TARGET, PROMPT, RETURN,
CONNECT, SESSION,
SERVICE, CHANNEL,
) )
} }

View File

@ -9,11 +9,3 @@ field "服务" ssh.service
field "通道" ssh.channel field "通道" ssh.channel
field "连接" ssh.connect field "连接" ssh.connect
field "会话" ssh.session field "会话" ssh.session
return
chapter "应用"
field "公钥" ssh.public
field "服务" ssh.listen
field "命令" ssh.command

View File

@ -1,94 +0,0 @@
package tcp
import (
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"bufio"
"net"
"net/url"
"strings"
)
func init() {
Index.Merge(&ice.Context{
Commands: map[string]*ice.Command{
"server": {Name: "server [tcp4|tcp6|udp4|udp6] addr", Help: "server", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
proto := "tcp4"
switch arg[0] {
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6":
proto, arg = arg[0], arg[1:]
}
if l, e := net.Listen(proto, arg[0]); m.Assert(e) {
m.Gos(m, func(m *ice.Message) {
// 启动服务
m.Logs(ice.LOG_LISTEN, "addr", l.Addr())
for {
if c, e := l.Accept(); m.Assert(e) {
m.Gos(m.Spawns(), func(msg *ice.Message) {
// 建立连接
msg.Logs(ice.LOG_ACCEPT, "addr", c.RemoteAddr())
msg.Option(ice.MSG_USERADDR, c.RemoteAddr())
msg.Option(ice.MSG_USERNAME, "")
msg.Option(ice.MSG_USERROLE, "")
switch msg.Cmdx("check", c.RemoteAddr().String()) {
case "local":
// 本机用户
msg.Option(ice.MSG_USERNAME, msg.Conf(cli.RUNTIME, "boot.username"))
msg.Option(ice.MSG_USERROLE, msg.Cmdx(aaa.ROLE, "check", msg.Option(ice.MSG_USERNAME)))
msg.Logs(ice.LOG_AUTH, "name", msg.Option(ice.MSG_USERNAME), "role", msg.Option(ice.MSG_USERROLE))
}
cmds := []string{}
buf := bufio.NewWriter(c)
for bio := bufio.NewScanner(c); bio.Scan(); {
text := bio.Text()
msg.Logs("scan", "len", len(text), "text", text)
if len(text) == 0 {
if len(cmds) > 0 {
msg.Cmd(aaa.ROLE, "right")
// 执行命令
res := msg.Cmd(cmds)
// 返回结果
for _, str := range res.Resultv() {
buf.WriteString("result:")
buf.WriteString(url.QueryEscape(str))
buf.WriteString("\n")
}
buf.WriteString("\n")
buf.Flush()
cmds = cmds[:0]
}
continue
}
// 解析请求
line := strings.SplitN(bio.Text(), ":", 2)
line[0], e = url.QueryUnescape(line[0])
m.Assert(e)
line[1], e = url.QueryUnescape(line[1])
m.Assert(e)
switch line[0] {
case "cmds", ice.MSG_DETAIL:
cmds = append(cmds, line[1])
default:
msg.Option(line[0], line[1])
}
}
msg.Logs(ice.LOG_FINISH, "addr", c.RemoteAddr())
})
}
}
m.Logs(ice.LOG_FINISH, "addr", l.Addr())
})
}
}},
},
}, nil)
}

View File

@ -8,6 +8,40 @@ import (
"net" "net"
) )
type Stat struct {
nc, nr, nw int
}
type Conn struct {
m *ice.Message
h string
s *Stat
net.Conn
}
func (c *Conn) Read(b []byte) (int, error) {
n, e := c.Conn.Read(b)
c.s.nr += n
c.m.Conf(CLIENT, kit.Keys(kit.MDB_HASH, c.h, kit.MDB_META, "nread"), c.s.nr)
return n, e
}
func (c *Conn) Write(b []byte) (int, error) {
n, e := c.Conn.Write(b)
c.s.nw += n
c.m.Conf(CLIENT, kit.Keys(kit.MDB_HASH, c.h, kit.MDB_META, "nwrite"), c.s.nw)
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()
}
const (
OPEN = "open"
CLOSE = "close"
ERROR = "error"
)
const ( const (
DIAL_CB = "dial.cb" DIAL_CB = "dial.cb"
DIAL = "dial" DIAL = "dial"
@ -22,12 +56,15 @@ func init() {
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
CLIENT: {Name: "client hash auto 连接 清理", Help: "客户端", Action: map[string]*ice.Action{ CLIENT: {Name: "client hash auto 连接 清理", Help: "客户端", Action: map[string]*ice.Action{
DIAL: {Name: "dial host=localhost port=9010", Help: "连接", Hand: func(m *ice.Message, arg ...string) { DIAL: {Name: "dial port=9010 host=", Help: "连接", Hand: func(m *ice.Message, arg ...string) {
c, e := net.Dial(TCP, m.Option(HOST)+":"+m.Option(PORT)) c, e := net.Dial(TCP, m.Option(HOST)+":"+m.Option(PORT))
h := m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, HOST, m.Option(HOST), PORT, m.Option(PORT), h := m.Option(kit.MDB_HASH)
kit.MDB_NAME, m.Option(kit.MDB_NAME), kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) if h == "" {
h = m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, HOST, m.Option(HOST), PORT, m.Option(PORT),
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{h: h, m: m, s: &Stat{}, Conn: c} c = &Conn{m: m, h: h, s: &Stat{}, Conn: c}
if e == nil { if e == nil {
defer c.Close() defer c.Close()
} }
@ -58,7 +95,7 @@ func init() {
m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, CLOSE) m.Cmdy(mdb.PRUNES, CLIENT, "", mdb.HASH, kit.MDB_STATUS, CLOSE)
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select(mdb.DETAIL, "time,hash,status,name,host,port,error,nread,nwrite", len(arg) == 0)) m.Option(mdb.FIELDS, kit.Select("time,hash,status,name,host,port,error,nread,nwrite", mdb.DETAIL, len(arg) > 0))
m.Cmdy(mdb.SELECT, CLIENT, "", mdb.HASH, kit.MDB_HASH, arg) m.Cmdy(mdb.SELECT, CLIENT, "", mdb.HASH, kit.MDB_HASH, arg)
m.PushAction("删除") m.PushAction("删除")
}}, }},

View File

@ -66,17 +66,17 @@ func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
HOST: {Name: HOST, Help: "主机", Value: kit.Data( HOST: {Name: HOST, Help: "主机", Value: kit.Data(
aaa.Black, kit.Dict(kit.MDB_SHORT, kit.MDB_TEXT), aaa.Black, kit.Data(kit.MDB_SHORT, kit.MDB_TEXT),
aaa.White, kit.Data(kit.MDB_SHORT, kit.MDB_TEXT), aaa.White, kit.Data(kit.MDB_SHORT, kit.MDB_TEXT),
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
HOST: {Name: "host name auto", Help: "主机", Action: map[string]*ice.Action{ HOST: {Name: "host name auto", Help: "主机", Action: map[string]*ice.Action{
aaa.White: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
m.Rich(HOST, kit.Keys("meta.white"), kit.Dict(kit.MDB_NAME, "", kit.MDB_TEXT, arg[0]))
}},
aaa.Black: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) { aaa.Black: {Name: "black", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) {
m.Rich(HOST, kit.Keys("meta.black"), kit.Dict(kit.MDB_NAME, "", kit.MDB_TEXT, arg[0])) m.Rich(HOST, kit.Keys("meta.black"), kit.Dict(kit.MDB_TEXT, arg[0]))
}},
aaa.White: {Name: "white", Help: "白名单", Hand: func(m *ice.Message, arg ...string) {
m.Rich(HOST, kit.Keys("meta.white"), kit.Dict(kit.MDB_TEXT, arg[0]))
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_host_list(m, kit.Select("", arg, 0)) _host_list(m, kit.Select("", arg, 0))

View File

@ -27,7 +27,7 @@ func _port_right(m *ice.Message, begin string) string {
} }
for i := current; i < end; i++ { for i := current; i < end; i++ {
if c, e := net.Dial("tcp", kit.Format(":%d", i)); e == nil { if c, e := net.Dial(TCP, kit.Format(":%d", i)); e == nil {
m.Info("port exists %v", i) m.Info("port exists %v", i)
defer c.Close() defer c.Close()
continue continue

View File

@ -9,38 +9,9 @@ import (
"strings" "strings"
) )
type Stat struct {
nc, nr, nw int
}
type Conn struct {
h string
m *ice.Message
s *Stat
net.Conn
}
func (c *Conn) Read(b []byte) (int, error) {
n, e := c.Conn.Read(b)
c.s.nr += n
c.m.Conf(CLIENT, kit.Keys(kit.MDB_HASH, c.h, kit.MDB_META, "nwrite"), c.s.nw)
return n, e
}
func (c *Conn) Write(b []byte) (int, error) {
n, e := c.Conn.Write(b)
c.s.nw += n
c.m.Conf(CLIENT, kit.Keys(kit.MDB_HASH, c.h, kit.MDB_META, "nread"), c.s.nr)
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()
}
type Listener struct { type Listener struct {
h string
m *ice.Message m *ice.Message
h string
s *Stat s *Stat
net.Listener net.Listener
@ -58,19 +29,13 @@ func (l Listener) Accept() (net.Conn, error) {
h := l.m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, HOST, ls[0], PORT, ls[1], h := l.m.Cmdx(mdb.INSERT, CLIENT, "", mdb.HASH, HOST, ls[0], PORT, ls[1],
kit.MDB_NAME, l.m.Option(kit.MDB_NAME), kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) kit.MDB_NAME, l.m.Option(kit.MDB_NAME), kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
c = &Conn{h: h, m: l.m, s: &Stat{}, Conn: c} return &Conn{m: l.m, h: h, s: &Stat{}, Conn: c}, e
return c, e
} }
func (l Listener) Close() error { func (l Listener) Close() error {
l.m.Cmd(mdb.MODIFY, SERVER, "", mdb.HASH, kit.MDB_HASH, l.h, kit.MDB_STATUS, CLOSE) l.m.Cmd(mdb.MODIFY, SERVER, "", mdb.HASH, kit.MDB_HASH, l.h, kit.MDB_STATUS, CLOSE)
return l.Listener.Close() return l.Listener.Close()
} }
const (
OPEN = "open"
CLOSE = "close"
ERROR = "error"
)
const ( const (
LISTEN_CB = "listen.cb" LISTEN_CB = "listen.cb"
LISTEN = "listen" LISTEN = "listen"
@ -85,14 +50,14 @@ func init() {
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
SERVER: {Name: "server hash auto 监听 清理", Help: "服务器", Action: map[string]*ice.Action{ SERVER: {Name: "server hash auto 监听 清理", Help: "服务器", Action: map[string]*ice.Action{
LISTEN: {Name: "LISTEN host=localhost port=9010", Help: "监听", Hand: func(m *ice.Message, arg ...string) { LISTEN: {Name: "LISTEN host= port=9010", Help: "监听", Hand: func(m *ice.Message, arg ...string) {
l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT)) l, e := net.Listen(TCP, m.Option(HOST)+":"+m.Option(PORT))
h := m.Option(kit.MDB_HASH) h := m.Option(kit.MDB_HASH)
if h == "" { if h == "" {
h = m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), HOST, m.Option(HOST), PORT, m.Option(PORT), kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e)) h = m.Cmdx(mdb.INSERT, SERVER, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), HOST, m.Option(HOST), PORT, m.Option(PORT), kit.MDB_STATUS, kit.Select(ERROR, OPEN, e == nil), kit.MDB_ERROR, kit.Format(e))
} }
l = &Listener{h: h, m: m, s: &Stat{}, Listener: l} l = &Listener{m: m, h: h, s: &Stat{}, Listener: l}
if e == nil { if e == nil {
defer l.Close() defer l.Close()
} }
@ -121,15 +86,15 @@ func init() {
default: default:
for { for {
c, e := l.Accept() c, e := l.Accept()
if e == nil { if e != nil {
b := make([]byte, 1024)
if n, e := c.Read(b); e == nil {
m.Info("nonce", string(b[:n]))
c.Write(b[:n])
}
} else {
break break
} }
b := make([]byte, 4096)
if n, e := c.Read(b); e == nil {
m.Info("nonce", string(b[:n]))
c.Write(b[:n])
}
c.Close() c.Close()
} }
} }
@ -142,7 +107,7 @@ func init() {
m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, CLOSE) m.Cmdy(mdb.PRUNES, SERVER, "", mdb.HASH, kit.MDB_STATUS, CLOSE)
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select(mdb.DETAIL, "time,hash,status,name,host,port,error,nconn", len(arg) == 0)) m.Option(mdb.FIELDS, kit.Select("time,hash,status,name,host,port,error,nconn", mdb.DETAIL, len(arg) > 0))
m.Cmdy(mdb.SELECT, SERVER, "", mdb.HASH, kit.MDB_HASH, arg) m.Cmdy(mdb.SELECT, SERVER, "", mdb.HASH, kit.MDB_HASH, arg)
m.PushAction("删除") m.PushAction("删除")
}}, }},

View File

@ -18,16 +18,10 @@ var Index = &ice.Context{Name: TCP, Help: "通信模块",
}}, }},
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { 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{}) { m.Richs(CLIENT, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
if value[kit.MDB_META] != nil { kit.Value(value, "meta.status", CLOSE)
value = value[kit.MDB_META].(map[string]interface{})
}
kit.Value(value, "status", CLOSE)
}) })
m.Richs(SERVER, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) { m.Richs(SERVER, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
if value[kit.MDB_META] != nil { kit.Value(value, "meta.status", CLOSE)
value = value[kit.MDB_META].(map[string]interface{})
}
kit.Value(value, "status", CLOSE)
}) })
m.Save() m.Save()
}}, }},

47
data.go
View File

@ -5,49 +5,46 @@ import (
"github.com/shylinux/toolkits/miss" "github.com/shylinux/toolkits/miss"
) )
func (m *Message) Richs(key string, chain interface{}, raw interface{}, cb interface{}) (res map[string]interface{}) { func (m *Message) Richs(prefix string, chain interface{}, raw interface{}, cb interface{}) (res map[string]interface{}) {
cache := m.Confm(key, chain) cache := m.Confm(prefix, chain)
if cache == nil { if cache == nil {
return nil return nil
} }
return miss.Richs(kit.Keys(key, chain), cache, raw, cb) return miss.Richs(kit.Keys(prefix, chain), cache, raw, cb)
} }
func (m *Message) Rich(key string, chain interface{}, data interface{}) string { func (m *Message) Rich(prefix string, chain interface{}, data interface{}) string {
cache := m.Confm(key, chain) cache := m.Confm(prefix, chain)
if cache == nil { if cache == nil {
cache = map[string]interface{}{} cache = kit.Data()
m.Confv(key, chain, cache) m.Confv(prefix, chain, cache)
} }
return miss.Rich(kit.Keys(key, chain), cache, data) return miss.Rich(kit.Keys(prefix, chain), cache, data)
} }
func (m *Message) Grow(key string, chain interface{}, data interface{}) int { func (m *Message) Grow(prefix string, chain interface{}, data interface{}) int {
cache := m.Confm(key, chain) cache := m.Confm(prefix, chain)
if cache == nil { if cache == nil {
cache = map[string]interface{}{} cache = kit.Data()
m.Confv(key, chain, cache) m.Confv(prefix, chain, cache)
} }
return miss.Grow(kit.Keys(key, chain), cache, data) return miss.Grow(kit.Keys(prefix, chain), cache, data)
} }
func (m *Message) Grows(key string, chain interface{}, match string, value string, cb interface{}) map[string]interface{} { func (m *Message) Grows(prefix string, chain interface{}, match string, value string, cb interface{}) map[string]interface{} {
cache := m.Confm(key, chain) cache := m.Confm(prefix, chain)
if cache == nil { if cache == nil {
return nil return nil
} }
begin := kit.Int(m.Option("cache.begin"))
limit := kit.Int(m.Option("cache.limit")) limit := kit.Int(m.Option("cache.limit"))
count := kit.Int(m.Option("cache.count", kit.Int(kit.Value(cache, "meta.count")))) if begin := kit.Int(m.Option("cache.begin")); begin != 0 && limit > 0 {
if limit == -2 { count := kit.Int(m.Option("cache.count", kit.Int(kit.Value(cache, "meta.count"))))
} else if limit == -1 {
} else if begin >= 0 || m.Option("cache.limit") == "" {
if begin > 0 { if begin > 0 {
begin -= 1 m.Option("cache.offend", count-begin-limit)
} else {
m.Option("cache.offend", -begin-limit)
} }
m.Option("cache.offend", count-begin-limit)
} else {
m.Option("cache.offend", -begin-limit)
} }
return miss.Grows(kit.Keys(key, chain), cache,
return miss.Grows(kit.Keys(prefix, chain), cache,
kit.Int(kit.Select("0", m.Option("cache.offend"))), kit.Int(kit.Select("0", m.Option("cache.offend"))),
kit.Int(kit.Select("10", m.Option("cache.limit"))), kit.Int(kit.Select("10", m.Option("cache.limit"))),
match, value, cb) match, value, cb)

View File

@ -201,7 +201,7 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
m.Cmdy(mdb.SELECT, SCRIPT, "", mdb.HASH) m.Cmdy(mdb.SELECT, SCRIPT, "", mdb.HASH)
}}, }},
mdb.SCRIPT: {Name: "script name", Help: "脚本", Hand: func(m *ice.Message, arg ...string) { "script": {Name: "script name", Help: "脚本", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(mdb.SELECT, SCRIPT, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)).Table(func(index int, value map[string]string, head []string) { m.Cmd(mdb.SELECT, SCRIPT, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)).Table(func(index int, value map[string]string, head []string) {
switch value[kit.MDB_TYPE] { switch value[kit.MDB_TYPE] {
case "shell": case "shell":