mirror of
https://shylinux.com/x/icebergs
synced 2025-04-28 18:22:02 +08:00
opt ssh
This commit is contained in:
parent
545ec26ea8
commit
f9302ca410
@ -8,22 +8,21 @@ import (
|
|||||||
|
|
||||||
ice "github.com/shylinux/icebergs"
|
ice "github.com/shylinux/icebergs"
|
||||||
"github.com/shylinux/icebergs/base/aaa"
|
"github.com/shylinux/icebergs/base/aaa"
|
||||||
|
"github.com/shylinux/icebergs/base/ctx"
|
||||||
"github.com/shylinux/icebergs/base/mdb"
|
"github.com/shylinux/icebergs/base/mdb"
|
||||||
"github.com/shylinux/icebergs/base/tcp"
|
"github.com/shylinux/icebergs/base/tcp"
|
||||||
kit "github.com/shylinux/toolkits"
|
kit "github.com/shylinux/toolkits"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Winsize struct{ Height, Width, x, y uint16 }
|
func _ssh_exec(m *ice.Message, cmd string, arg []string, env []string, input io.Reader, output io.Writer, 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)
|
||||||
c := exec.Command(cmd, arg...)
|
c := exec.Command(cmd, arg...)
|
||||||
// c.Env = env
|
// c.Env = env
|
||||||
|
|
||||||
c.Stdin = tty
|
c.Stdin = input
|
||||||
c.Stdout = tty
|
c.Stdout = output
|
||||||
c.Stderr = tty
|
c.Stderr = output
|
||||||
|
|
||||||
m.Assert(c.Start())
|
m.Assert(c.Start())
|
||||||
|
|
||||||
@ -41,7 +40,7 @@ func _ssh_watch(m *ice.Message, meta map[string]string, h string, input io.Reade
|
|||||||
bio := io.TeeReader(input, w)
|
bio := io.TeeReader(input, w)
|
||||||
m.Go(func() { io.Copy(output, r) })
|
m.Go(func() { io.Copy(output, r) })
|
||||||
|
|
||||||
i, buf := 0, make([]byte, 4096)
|
i, buf := 0, make([]byte, ice.MOD_BUFS)
|
||||||
m.Go(func() {
|
m.Go(func() {
|
||||||
for {
|
for {
|
||||||
n, e := bio.Read(buf[i:])
|
n, e := bio.Read(buf[i:])
|
||||||
@ -72,7 +71,7 @@ func init() {
|
|||||||
CHANNEL: {Name: "channel", Help: "通道", Value: kit.Data()},
|
CHANNEL: {Name: "channel", Help: "通道", Value: kit.Data()},
|
||||||
},
|
},
|
||||||
Commands: map[string]*ice.Command{
|
Commands: map[string]*ice.Command{
|
||||||
CHANNEL: {Name: "channel hash id auto prunes", Help: "通道", Action: map[string]*ice.Action{
|
CHANNEL: {Name: "channel hash id auto command prunes", Help: "通道", Action: map[string]*ice.Action{
|
||||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||||
m.Cmdy(mdb.DELETE, CHANNEL, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
m.Cmdy(mdb.DELETE, CHANNEL, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||||
}},
|
}},
|
||||||
@ -81,12 +80,24 @@ func init() {
|
|||||||
m.Cmdy(mdb.PRUNES, SERVICE, "", mdb.HASH, kit.MDB_STATUS, tcp.ERROR)
|
m.Cmdy(mdb.PRUNES, SERVICE, "", mdb.HASH, kit.MDB_STATUS, tcp.ERROR)
|
||||||
m.Cmdy(mdb.PRUNES, CHANNEL, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
|
m.Cmdy(mdb.PRUNES, CHANNEL, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
|
||||||
}},
|
}},
|
||||||
|
ctx.COMMAND: {Name: "command cmd=pwd", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
m.Cmdy(mdb.INSERT, CHANNEL, kit.Keys(kit.MDB_HASH, m.Option(kit.MDB_HASH)), mdb.LIST, kit.MDB_TYPE, CMD, kit.MDB_TEXT, m.Option(CMD))
|
||||||
|
m.Richs(CHANNEL, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
|
||||||
|
if w, ok := kit.Value(value, kit.Keym(INPUT)).(io.Writer); ok {
|
||||||
|
w.Write([]byte(m.Option(CMD) + "\n"))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
m.ProcessRefresh("300ms")
|
||||||
|
}},
|
||||||
|
"repeat": {Name: "repeat", Help: "执行", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
m.Cmdy(CHANNEL, kit.MDB_ACTION, ctx.COMMAND, CMD, m.Option("text"))
|
||||||
|
}},
|
||||||
}, 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.Fields(len(arg) == 0, "time,hash,status,username,hostport,tty,count")
|
m.Fields(len(arg) == 0, "time,hash,status,username,hostport,tty,count")
|
||||||
if m.Cmdy(mdb.SELECT, CHANNEL, "", mdb.HASH); len(arg) == 0 {
|
if m.Cmdy(mdb.SELECT, CHANNEL, "", mdb.HASH); len(arg) == 0 {
|
||||||
m.Table(func(index int, value map[string]string, head []string) {
|
m.Table(func(index int, value map[string]string, head []string) {
|
||||||
m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == tcp.CLOSE))
|
m.PushButton(kit.Select("", ctx.COMMAND, value[kit.MDB_STATUS] == tcp.OPEN), mdb.REMOVE)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -95,6 +106,7 @@ func init() {
|
|||||||
// 通道命令
|
// 通道命令
|
||||||
m.Fields(len(arg) == 1, "time,id,type,text")
|
m.Fields(len(arg) == 1, "time,id,type,text")
|
||||||
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:])
|
||||||
|
m.PushAction("repeat")
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package ssh
|
package ssh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@ -22,16 +21,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func _ssh_open(m *ice.Message, arg ...string) {
|
func _ssh_open(m *ice.Message, arg ...string) {
|
||||||
// 加载配置
|
|
||||||
if f, e := os.Open(m.Option("authfile")); e == nil {
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
var data interface{}
|
|
||||||
json.NewDecoder(f).Decode(&data)
|
|
||||||
|
|
||||||
kit.Fetch(data, func(key string, value interface{}) { m.Option(key, kit.Simple(value)) })
|
|
||||||
}
|
|
||||||
|
|
||||||
_ssh_dial(m, func(c net.Conn) {
|
_ssh_dial(m, func(c net.Conn) {
|
||||||
// 保存界面
|
// 保存界面
|
||||||
fd := int(os.Stdin.Fd())
|
fd := int(os.Stdin.Fd())
|
||||||
@ -44,13 +33,12 @@ func _ssh_open(m *ice.Message, arg ...string) {
|
|||||||
c.Write([]byte(fmt.Sprintf("height:%d,width:%d\n", h, w)))
|
c.Write([]byte(fmt.Sprintf("height:%d,width:%d\n", h, w)))
|
||||||
|
|
||||||
// 初始命令
|
// 初始命令
|
||||||
for _, item := range kit.Simple(m.Optionv("list")) {
|
for _, item := range kit.Simple(m.Optionv(kit.MDB_LIST)) {
|
||||||
m.Sleep("500ms")
|
m.Sleep("500ms")
|
||||||
c.Write([]byte(item + "\n"))
|
c.Write([]byte(item + "\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Go(func() { io.Copy(c, os.Stdin) })
|
m.Go(func() { io.Copy(c, os.Stdin) })
|
||||||
|
|
||||||
io.Copy(os.Stdout, c)
|
io.Copy(os.Stdout, c)
|
||||||
}, arg...)
|
}, arg...)
|
||||||
}
|
}
|
||||||
@ -64,67 +52,62 @@ func _ssh_dial(m *ice.Message, cb func(net.Conn), arg ...string) {
|
|||||||
os.Remove(p)
|
os.Remove(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
var client *ssh.Client
|
_ssh_conn(m, func(client *ssh.Client) {
|
||||||
if l, e := net.Listen("unix", p); m.Assert(e) {
|
if l, e := net.Listen("unix", p); m.Assert(e) {
|
||||||
defer func() { os.Remove(p) }()
|
defer func() { os.Remove(p) }()
|
||||||
defer l.Close()
|
defer l.Close()
|
||||||
|
|
||||||
m.Go(func() {
|
m.Go(func() {
|
||||||
for {
|
for {
|
||||||
c, e := l.Accept()
|
c, e := l.Accept()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
break
|
break
|
||||||
}
|
|
||||||
|
|
||||||
func(c net.Conn) {
|
|
||||||
w, h, _ := terminal.GetSize(int(os.Stdin.Fd()))
|
|
||||||
buf := make([]byte, ice.MOD_BUFS)
|
|
||||||
if n, e := c.Read(buf); m.Assert(e) {
|
|
||||||
fmt.Sscanf(string(buf[:n]), "height:%d,width:%d", &h, &w)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Go(func() {
|
func(c net.Conn) {
|
||||||
defer c.Close()
|
w, h, _ := terminal.GetSize(int(os.Stdin.Fd()))
|
||||||
|
buf := make([]byte, ice.MOD_BUFS)
|
||||||
session, e := client.NewSession()
|
if n, e := c.Read(buf); m.Assert(e) {
|
||||||
if e != nil {
|
fmt.Sscanf(string(buf[:n]), "height:%d,width:%d", &h, &w)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session.Stdin = c
|
m.Go(func() {
|
||||||
session.Stdout = c
|
defer c.Close()
|
||||||
session.Stderr = c
|
|
||||||
|
|
||||||
session.RequestPty(os.Getenv("TERM"), h, w, ssh.TerminalModes{
|
session, e := client.NewSession()
|
||||||
ssh.ECHO: 1,
|
if e != nil {
|
||||||
ssh.TTY_OP_ISPEED: 14400,
|
return
|
||||||
ssh.TTY_OP_OSPEED: 14400,
|
}
|
||||||
|
|
||||||
|
session.Stdin = c
|
||||||
|
session.Stdout = c
|
||||||
|
session.Stderr = c
|
||||||
|
|
||||||
|
session.RequestPty(os.Getenv("TERM"), h, w, ssh.TerminalModes{
|
||||||
|
ssh.ECHO: 1,
|
||||||
|
ssh.TTY_OP_ISPEED: 14400,
|
||||||
|
ssh.TTY_OP_OSPEED: 14400,
|
||||||
|
})
|
||||||
|
|
||||||
|
gdb.SignalNotify(m, 28, func() {
|
||||||
|
w, h, _ := terminal.GetSize(int(os.Stdin.Fd()))
|
||||||
|
session.WindowChange(h, w)
|
||||||
|
})
|
||||||
|
|
||||||
|
session.Shell()
|
||||||
|
session.Wait()
|
||||||
})
|
})
|
||||||
|
}(c)
|
||||||
gdb.SignalNotify(m, 28, func() {
|
}
|
||||||
w, h, _ := terminal.GetSize(int(os.Stdin.Fd()))
|
})
|
||||||
session.WindowChange(h, w)
|
}
|
||||||
})
|
|
||||||
|
|
||||||
session.Shell()
|
|
||||||
session.Wait()
|
|
||||||
})
|
|
||||||
}(c)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Option(kit.Keycb(tcp.DIAL), func(c net.Conn) {
|
|
||||||
client = _ssh_conn(m, c, m.Option(aaa.USERNAME), m.Option(tcp.HOST)+":"+m.Option(tcp.PORT))
|
|
||||||
|
|
||||||
if c, e := net.Dial("unix", p); e == nil {
|
if c, e := net.Dial("unix", p); e == nil {
|
||||||
cb(c) // 会话连接
|
cb(c) // 会话连接
|
||||||
}
|
}
|
||||||
})
|
}, arg...)
|
||||||
m.Cmdy(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, SSH, kit.MDB_NAME, m.Option(tcp.HOST),
|
|
||||||
tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST), arg)
|
|
||||||
}
|
}
|
||||||
func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) *ssh.Client {
|
func _ssh_conn(m *ice.Message, cb func(*ssh.Client), arg ...string) {
|
||||||
methods := []ssh.AuthMethod{}
|
methods := []ssh.AuthMethod{}
|
||||||
methods = append(methods, ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) (res []string, err error) {
|
methods = append(methods, ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) (res []string, err error) {
|
||||||
for _, q := range questions {
|
for _, q := range questions {
|
||||||
@ -146,22 +129,25 @@ func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) *ssh.Cl
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}))
|
}))
|
||||||
|
|
||||||
methods = append(methods, ssh.PublicKeysCallback(func() ([]ssh.Signer, error) {
|
methods = append(methods, ssh.PublicKeysCallback(func() ([]ssh.Signer, error) {
|
||||||
key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(os.Getenv(cli.HOME), m.Option("private")))))
|
key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(os.Getenv(cli.HOME), m.Option(PRIVATE)))))
|
||||||
return []ssh.Signer{key}, err
|
return []ssh.Signer{key}, err
|
||||||
}))
|
}))
|
||||||
methods = append(methods, ssh.PasswordCallback(func() (string, error) {
|
methods = append(methods, ssh.PasswordCallback(func() (string, error) {
|
||||||
return m.Option(aaa.PASSWORD), nil
|
return m.Option(aaa.PASSWORD), nil
|
||||||
}))
|
}))
|
||||||
|
|
||||||
c, chans, reqs, err := ssh.NewClientConn(conn, hostport, &ssh.ClientConfig{
|
m.Option(kit.Keycb(tcp.DIAL), func(c net.Conn) {
|
||||||
User: username, Auth: methods, BannerCallback: func(message string) error { return nil },
|
conn, chans, reqs, err := ssh.NewClientConn(c, m.Option(tcp.HOST)+":"+m.Option(tcp.PORT), &ssh.ClientConfig{
|
||||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil },
|
User: m.Option(aaa.USERNAME), Auth: methods, BannerCallback: func(message string) error { return nil },
|
||||||
})
|
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil },
|
||||||
|
})
|
||||||
|
|
||||||
m.Assert(err)
|
m.Assert(err)
|
||||||
return ssh.NewClient(c, chans, reqs)
|
cb(ssh.NewClient(conn, chans, reqs))
|
||||||
|
})
|
||||||
|
m.Cmdy(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, SSH, kit.MDB_NAME, m.Option(tcp.HOST),
|
||||||
|
tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST), arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
const CONNECT = "connect"
|
const CONNECT = "connect"
|
||||||
@ -175,59 +161,61 @@ func init() {
|
|||||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||||
m.Richs(CONNECT, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
m.Richs(CONNECT, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||||
if value = kit.GetMeta(value); kit.Value(value, kit.MDB_STATUS) == tcp.OPEN {
|
if value = kit.GetMeta(value); kit.Value(value, kit.MDB_STATUS) == tcp.OPEN {
|
||||||
m.Cmd(CONNECT, tcp.DIAL, aaa.USERNAME, value[aaa.USERNAME], value)
|
m.Cmd(CONNECT, tcp.DIAL, aaa.USERNAME, value[aaa.USERNAME], kit.MDB_HASH, key, value)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}},
|
}},
|
||||||
CONNECT: {Name: "connect hash auto dial prunes", Help: "连接", Action: map[string]*ice.Action{
|
CONNECT: {Name: "connect hash auto dial prunes", Help: "连接", Action: map[string]*ice.Action{
|
||||||
tcp.OPEN: {Name: "open authfile= username=shy password= verfiy= host=shylinux.com port=22 private=.ssh/id_rsa", Help: "终端", Hand: func(m *ice.Message, arg ...string) {
|
tcp.OPEN: {Name: "open authfile= username=shy password= verfiy= host=shylinux.com port=22 private=.ssh/id_rsa", Help: "终端", Hand: func(m *ice.Message, arg ...string) {
|
||||||
_ssh_open(m, arg...)
|
_ssh_open(m.OptionLoad(m.Option("authfile")), arg...)
|
||||||
m.Echo("exit %v:%v\n", m.Option(tcp.HOST), m.Option(tcp.PORT))
|
m.Echo("exit %v:%v\n", m.Option(tcp.HOST), m.Option(tcp.PORT))
|
||||||
}},
|
}},
|
||||||
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(kit.Keycb(tcp.DIAL), func(c net.Conn) {
|
m.Go(func() {
|
||||||
client := _ssh_conn(m, c, kit.Select("shy", m.Option(aaa.USERNAME)),
|
_ssh_conn(m, func(client *ssh.Client) {
|
||||||
kit.Select("shylinux.com", m.Option(tcp.HOST))+":"+kit.Select("22", m.Option(tcp.PORT)),
|
h := m.Option(kit.MDB_HASH)
|
||||||
)
|
if h == "" {
|
||||||
|
h = m.Rich(CONNECT, "", kit.Dict(
|
||||||
h := m.Rich(CONNECT, "", kit.Dict(
|
aaa.USERNAME, m.Option(aaa.USERNAME),
|
||||||
aaa.USERNAME, m.Option(aaa.USERNAME),
|
tcp.HOST, m.Option(tcp.HOST), tcp.PORT, m.Option(tcp.PORT),
|
||||||
tcp.HOST, m.Option(tcp.HOST), tcp.PORT, m.Option(tcp.PORT),
|
kit.MDB_STATUS, tcp.OPEN, CONNECT, client,
|
||||||
kit.MDB_STATUS, tcp.OPEN, CONNECT, client,
|
))
|
||||||
))
|
} else {
|
||||||
m.Cmd(CONNECT, SESSION, kit.MDB_HASH, h)
|
m.Conf(CONNECT, kit.Keys(kit.MDB_HASH, h, CONNECT), client)
|
||||||
m.Echo(h)
|
}
|
||||||
|
m.Cmd(CONNECT, SESSION, kit.MDB_HASH, h)
|
||||||
|
}, arg...)
|
||||||
})
|
})
|
||||||
|
m.ProcessRefresh("300ms")
|
||||||
m.Cmds(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, SSH, kit.MDB_NAME, m.Option(aaa.USERNAME),
|
|
||||||
tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST))
|
|
||||||
}},
|
}},
|
||||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||||
m.Cmdy(mdb.DELETE, CONNECT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
m.Cmdy(mdb.DELETE, CONNECT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||||
}},
|
}},
|
||||||
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
m.Option(mdb.FIELDS, "time,hash,status,username,host,port")
|
||||||
m.Cmdy(mdb.PRUNES, CONNECT, "", mdb.HASH, kit.MDB_STATUS, tcp.ERROR)
|
m.Cmdy(mdb.PRUNES, CONNECT, "", mdb.HASH, kit.MDB_STATUS, tcp.ERROR)
|
||||||
m.Cmdy(mdb.PRUNES, CONNECT, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
|
m.Cmdy(mdb.PRUNES, CONNECT, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
|
||||||
}},
|
}},
|
||||||
|
|
||||||
SESSION: {Name: "session hash", Help: "会话", Hand: func(m *ice.Message, arg ...string) {
|
SESSION: {Name: "session hash", Help: "会话", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
var client *ssh.Client
|
||||||
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{}) {
|
||||||
client, ok := value[CONNECT].(*ssh.Client)
|
client, _ = value[CONNECT].(*ssh.Client)
|
||||||
m.Assert(ok)
|
|
||||||
|
|
||||||
h := m.Rich(SESSION, "", kit.Data(kit.MDB_STATUS, tcp.OPEN, CONNECT, key))
|
|
||||||
|
|
||||||
if session, e := _ssh_session(m, h, client); m.Assert(e) {
|
|
||||||
session.Shell()
|
|
||||||
session.Wait()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
m.Debug("what %v", client)
|
||||||
|
|
||||||
|
h := m.Rich(SESSION, "", kit.Data(kit.MDB_STATUS, tcp.OPEN, CONNECT, m.Option(kit.MDB_HASH)))
|
||||||
|
if session, e := _ssh_session(m, h, client); m.Assert(e) {
|
||||||
|
session.Shell()
|
||||||
|
session.Wait()
|
||||||
|
}
|
||||||
|
m.Echo(h)
|
||||||
}},
|
}},
|
||||||
}, 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.Fields(len(arg) == 0, "time,hash,status,username,host,port")
|
m.Fields(len(arg) == 0, "time,hash,status,username,host,port")
|
||||||
if m.Cmdy(mdb.SELECT, CONNECT, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
|
if m.Cmdy(mdb.SELECT, CONNECT, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
|
||||||
m.Table(func(index int, value map[string]string, head []string) {
|
m.Table(func(index int, value map[string]string, head []string) {
|
||||||
m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == tcp.CLOSE))
|
m.PushButton(kit.Select("", SESSION, value[kit.MDB_STATUS] == tcp.OPEN), mdb.REMOVE)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
|
@ -17,14 +17,21 @@ import (
|
|||||||
kit "github.com/shylinux/toolkits"
|
kit "github.com/shylinux/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Render(msg *ice.Message, cmd string, args ...interface{}) {
|
func Render(msg *ice.Message, cmd string, args ...interface{}) string {
|
||||||
switch arg := kit.Simple(args...); cmd {
|
switch arg := kit.Simple(args...); cmd {
|
||||||
case ice.RENDER_VOID:
|
case ice.RENDER_VOID:
|
||||||
case ice.RENDER_RESULT:
|
case ice.RENDER_RESULT:
|
||||||
|
// 转换结果
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
msg.Resultv(arg)
|
msg.Resultv(arg)
|
||||||
}
|
}
|
||||||
fmt.Fprint(msg.O, msg.Result())
|
res := msg.Result()
|
||||||
|
|
||||||
|
// 输出结果
|
||||||
|
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, "\n") {
|
||||||
|
fmt.Fprint(msg.O, "\n")
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// 转换结果
|
// 转换结果
|
||||||
@ -37,7 +44,9 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) {
|
|||||||
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, "\n") {
|
if fmt.Fprint(msg.O, res); !strings.HasSuffix(res, "\n") {
|
||||||
fmt.Fprint(msg.O, "\n")
|
fmt.Fprint(msg.O, "\n")
|
||||||
}
|
}
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
func Script(m *ice.Message, name string) io.Reader {
|
func Script(m *ice.Message, name string) io.Reader {
|
||||||
if strings.Contains(m.Option(ice.MSG_SCRIPT), "/") {
|
if strings.Contains(m.Option(ice.MSG_SCRIPT), "/") {
|
||||||
@ -92,6 +101,7 @@ type Frame struct {
|
|||||||
pipe io.Writer
|
pipe io.Writer
|
||||||
|
|
||||||
count int
|
count int
|
||||||
|
last string
|
||||||
ps1 []string
|
ps1 []string
|
||||||
ps2 []string
|
ps2 []string
|
||||||
|
|
||||||
@ -223,7 +233,7 @@ func (f *Frame) parse(m *ice.Message, line string) string {
|
|||||||
|
|
||||||
// 渲染引擎
|
// 渲染引擎
|
||||||
_args, _ := msg.Optionv(ice.MSG_ARGS).([]interface{})
|
_args, _ := msg.Optionv(ice.MSG_ARGS).([]interface{})
|
||||||
Render(msg, msg.Option(ice.MSG_OUTPUT), _args...)
|
f.last = Render(msg, msg.Option(ice.MSG_OUTPUT), _args...)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -312,10 +322,16 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
|
|||||||
|
|
||||||
// 解析脚本
|
// 解析脚本
|
||||||
if f.count = 1; f.source == STDIO {
|
if f.count = 1; f.source == STDIO {
|
||||||
f.count = kit.Int(m.Conf(SOURCE, kit.Keys("hash.stdio.meta.count"))) + 1
|
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())
|
||||||
|
|
||||||
|
f.count = kit.Int(m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, STDIO, kit.Keym(kit.MDB_COUNT)))) + 1
|
||||||
f.scan(m, STDIO, "")
|
f.scan(m, STDIO, "")
|
||||||
} else {
|
} else {
|
||||||
h := m.Cmdx(mdb.INSERT, SOURCE, "", mdb.HASH, kit.MDB_NAME, f.source)
|
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, "")
|
f.scan(m, h, "")
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -349,7 +365,12 @@ func init() {
|
|||||||
)},
|
)},
|
||||||
},
|
},
|
||||||
Commands: map[string]*ice.Command{
|
Commands: map[string]*ice.Command{
|
||||||
SOURCE: {Name: "source hash id limit offend auto", Help: "脚本解析", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
SOURCE: {Name: "source hash id limit offend auto", Help: "脚本解析", Action: map[string]*ice.Action{
|
||||||
|
"repeat": {Name: "repeat", Help: "执行", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
m.Cmdy(SCREEN, m.Option("text"))
|
||||||
|
m.ProcessInner()
|
||||||
|
}},
|
||||||
|
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||||
if len(arg) > 0 && kit.Ext(arg[0]) == "shy" { // 解析脚本
|
if len(arg) > 0 && kit.Ext(arg[0]) == "shy" { // 解析脚本
|
||||||
m.Starts(strings.Replace(arg[0], ".", "_", -1), arg[0], arg[0:]...)
|
m.Starts(strings.Replace(arg[0], ".", "_", -1), arg[0], arg[0:]...)
|
||||||
return
|
return
|
||||||
@ -371,6 +392,7 @@ func init() {
|
|||||||
// 命令列表
|
// 命令列表
|
||||||
m.Fields(len(arg) == 1 || arg[1] == "", "time,id,text")
|
m.Fields(len(arg) == 1 || 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.Cmdy(mdb.SELECT, SOURCE, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
|
||||||
|
m.PushAction("repeat")
|
||||||
}},
|
}},
|
||||||
TARGET: {Name: "target name 执行:button", Help: "当前模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
TARGET: {Name: "target name 执行:button", Help: "当前模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||||
f := m.Target().Server().(*Frame)
|
f := m.Target().Server().(*Frame)
|
||||||
@ -396,7 +418,7 @@ func init() {
|
|||||||
fmt.Fprintf(f.pipe, line+"\n")
|
fmt.Fprintf(f.pipe, line+"\n")
|
||||||
m.Sleep("300ms")
|
m.Sleep("300ms")
|
||||||
}
|
}
|
||||||
m.Echo(arg[0])
|
m.Echo(f.last)
|
||||||
}},
|
}},
|
||||||
RETURN: {Name: "return", Help: "结束脚本", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
RETURN: {Name: "return", Help: "结束脚本", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||||
switch cb := m.Optionv(kit.Keycb(RETURN)).(type) {
|
switch cb := m.Optionv(kit.Keycb(RETURN)).(type) {
|
||||||
|
@ -70,7 +70,7 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig {
|
|||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
func _ssh_accept(m *ice.Message, h string, c net.Conn) {
|
func _ssh_accept(m *ice.Message, h string, c net.Conn) {
|
||||||
sc, chans, reqs, err := ssh.NewServerConn(c, _ssh_config(m, h))
|
conn, chans, reqs, err := ssh.NewServerConn(c, _ssh_config(m, h))
|
||||||
if m.Warn(err != nil, err) {
|
if m.Warn(err != nil, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ func _ssh_accept(m *ice.Message, h string, c net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func(channel ssh.Channel, requests <-chan *ssh.Request) {
|
func(channel ssh.Channel, requests <-chan *ssh.Request) {
|
||||||
m.Go(func() { _ssh_handle(m, sc.Permissions.Extensions, c, channel, requests) })
|
m.Go(func() { _ssh_handle(m, conn.Permissions.Extensions, c, channel, requests) })
|
||||||
}(channel, requests)
|
}(channel, requests)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ import (
|
|||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Winsize struct{ Height, Width, x, y uint16 }
|
||||||
|
|
||||||
func _ssh_size(fd uintptr, b []byte) {
|
func _ssh_size(fd uintptr, b []byte) {
|
||||||
w := binary.BigEndian.Uint32(b)
|
w := binary.BigEndian.Uint32(b)
|
||||||
h := binary.BigEndian.Uint32(b[4:])
|
h := binary.BigEndian.Uint32(b[4:])
|
||||||
|
@ -17,6 +17,8 @@ import (
|
|||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Winsize struct{ Height, Width, x, y uint16 }
|
||||||
|
|
||||||
func _ssh_size(fd uintptr, b []byte) {
|
func _ssh_size(fd uintptr, b []byte) {
|
||||||
w := binary.BigEndian.Uint32(b)
|
w := binary.BigEndian.Uint32(b)
|
||||||
h := binary.BigEndian.Uint32(b[4:])
|
h := binary.BigEndian.Uint32(b[4:])
|
||||||
@ -37,7 +39,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(), meta))
|
h := m.Rich(CHANNEL, "", kit.Data(kit.MDB_STATUS, tcp.OPEN, TTY, tty.Name(), INPUT, pty, OUTPUT, tty, meta))
|
||||||
meta[CHANNEL] = h
|
meta[CHANNEL] = h
|
||||||
|
|
||||||
for request := range requests {
|
for request := range requests {
|
||||||
@ -61,13 +63,13 @@ func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh
|
|||||||
list = append(list, env.Name+"="+env.Value)
|
list = append(list, env.Name+"="+env.Value)
|
||||||
|
|
||||||
case "exec":
|
case "exec":
|
||||||
_ssh_exec(m, shell, []string{"-c", string(request.Payload[4 : request.Payload[3]+4])}, list, channel, func() {
|
_ssh_exec(m, shell, []string{"-c", string(request.Payload[4 : request.Payload[3]+4])}, list, channel, channel, func() {
|
||||||
channel.Close()
|
channel.Close()
|
||||||
})
|
})
|
||||||
case "shell":
|
case "shell":
|
||||||
m.Go(func() { io.Copy(channel, pty) })
|
m.Go(func() { io.Copy(channel, pty) })
|
||||||
|
|
||||||
_ssh_exec(m, shell, nil, list, tty, func() {
|
_ssh_exec(m, shell, nil, list, tty, tty, func() {
|
||||||
defer m.Cmd(mdb.MODIFY, CHANNEL, "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, tcp.CLOSE)
|
defer m.Cmd(mdb.MODIFY, CHANNEL, "", mdb.HASH, kit.MDB_HASH, h, kit.MDB_STATUS, tcp.CLOSE)
|
||||||
_ssh_close(m, c, channel)
|
_ssh_close(m, c, channel)
|
||||||
})
|
})
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Winsize struct{ Height, Width, x, y uint16 }
|
||||||
|
|
||||||
func _ssh_size(fd uintptr, b []byte) {
|
func _ssh_size(fd uintptr, b []byte) {
|
||||||
}
|
}
|
||||||
func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh.Channel, requests <-chan *ssh.Request) {
|
func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh.Channel, requests <-chan *ssh.Request) {
|
||||||
|
@ -22,7 +22,7 @@ func _ssh_session(m *ice.Message, h string, client *ssh.Client) (*ssh.Session, e
|
|||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
|
|
||||||
m.Go(func() {
|
m.Go(func() {
|
||||||
buf := make([]byte, 4096)
|
buf := make([]byte, ice.MOD_BUFS)
|
||||||
for {
|
for {
|
||||||
n, e := out.Read(buf)
|
n, e := out.Read(buf)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
@ -36,8 +36,7 @@ func _ssh_session(m *ice.Message, h string, client *ssh.Client) (*ssh.Session, e
|
|||||||
})
|
})
|
||||||
|
|
||||||
m.Richs(SESSION, "", h, func(key string, value map[string]interface{}) {
|
m.Richs(SESSION, "", h, func(key string, value map[string]interface{}) {
|
||||||
kit.Value(value, kit.Keym(OUTPUT), out)
|
kit.Value(value, kit.Keym(OUTPUT), out, kit.Keym(INPUT), in)
|
||||||
kit.Value(value, kit.Keym(INPUT), in)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return session, nil
|
return session, nil
|
||||||
@ -68,6 +67,7 @@ func init() {
|
|||||||
m.Cmdy(mdb.DELETE, SESSION, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
m.Cmdy(mdb.DELETE, SESSION, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||||
}},
|
}},
|
||||||
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
m.Option(mdb.FIELDS, "time,hash,status,count,connect")
|
||||||
m.Cmdy(mdb.PRUNES, SESSION, "", mdb.HASH, kit.MDB_STATUS, tcp.ERROR)
|
m.Cmdy(mdb.PRUNES, SESSION, "", mdb.HASH, kit.MDB_STATUS, tcp.ERROR)
|
||||||
m.Cmdy(mdb.PRUNES, SESSION, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
|
m.Cmdy(mdb.PRUNES, SESSION, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
|
||||||
}},
|
}},
|
||||||
@ -75,18 +75,20 @@ func init() {
|
|||||||
m.Richs(SESSION, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
|
m.Richs(SESSION, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
|
||||||
if w, ok := kit.Value(value, kit.Keym(INPUT)).(io.Writer); ok {
|
if w, ok := kit.Value(value, kit.Keym(INPUT)).(io.Writer); ok {
|
||||||
m.Grow(SESSION, kit.Keys(kit.MDB_HASH, key), kit.Dict(kit.MDB_TYPE, CMD, kit.MDB_TEXT, m.Option(CMD)))
|
m.Grow(SESSION, kit.Keys(kit.MDB_HASH, key), kit.Dict(kit.MDB_TYPE, CMD, kit.MDB_TEXT, m.Option(CMD)))
|
||||||
n, e := w.Write([]byte(m.Option(CMD) + "\n"))
|
w.Write([]byte(m.Option(CMD) + "\n"))
|
||||||
m.Debug("%v %v", n, e)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
m.ProcessRefresh("300ms")
|
m.ProcessRefresh("300ms")
|
||||||
}},
|
}},
|
||||||
|
"repeat": {Name: "repeat", Help: "执行", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
m.Cmdy(SESSION, kit.MDB_ACTION, ctx.COMMAND, CMD, m.Option("text"))
|
||||||
|
}},
|
||||||
}, 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,count,connect")
|
m.Fields(len(arg) == 0, "time,hash,status,count,connect")
|
||||||
if m.Cmdy(mdb.SELECT, SESSION, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
|
if m.Cmdy(mdb.SELECT, SESSION, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
|
||||||
m.Table(func(index int, value map[string]string, head []string) {
|
m.Table(func(index int, value map[string]string, head []string) {
|
||||||
m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == tcp.CLOSE))
|
m.PushButton(kit.Select("", ctx.COMMAND, value[kit.MDB_STATUS] == tcp.OPEN), mdb.REMOVE)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -94,6 +96,9 @@ func init() {
|
|||||||
|
|
||||||
m.Fields(len(arg) == 1, "time,id,type,text")
|
m.Fields(len(arg) == 1, "time,id,type,text")
|
||||||
m.Cmdy(mdb.SELECT, SESSION, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
|
m.Cmdy(mdb.SELECT, SESSION, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
|
||||||
|
m.Table(func(index int, value map[string]string, head []string) {
|
||||||
|
m.PushButton(kit.Select("", "repeat", value["type"] == "cmd"))
|
||||||
|
})
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -11,24 +11,17 @@ const SSH = "ssh"
|
|||||||
var Index = &ice.Context{Name: SSH, Help: "终端模块", Commands: map[string]*ice.Command{
|
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) {
|
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||||
m.Load()
|
m.Load()
|
||||||
m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, STDIO, kit.MDB_META, kit.MDB_NAME), STDIO)
|
m.Richs(SESSION, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||||
m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, STDIO, kit.MDB_META, kit.MDB_TIME), m.Time())
|
kit.Value(value, kit.Keym(kit.MDB_STATUS), tcp.CLOSE)
|
||||||
|
})
|
||||||
|
m.Richs(CHANNEL, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||||
|
kit.Value(value, kit.Keym(kit.MDB_STATUS), tcp.CLOSE)
|
||||||
|
})
|
||||||
}},
|
}},
|
||||||
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) {
|
||||||
if _, ok := m.Target().Server().(*Frame); ok {
|
if _, ok := m.Target().Server().(*Frame); ok {
|
||||||
m.Done(true)
|
m.Done(true)
|
||||||
}
|
}
|
||||||
m.Richs(CHANNEL, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
|
||||||
kit.Value(value, kit.Keym(kit.MDB_STATUS), tcp.CLOSE)
|
|
||||||
})
|
|
||||||
m.Richs(SESSION, "", kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
|
||||||
kit.Value(value, kit.Keym(kit.MDB_STATUS), tcp.CLOSE)
|
|
||||||
})
|
|
||||||
|
|
||||||
m.Richs(SOURCE, "", STDIO, func(key string, value map[string]interface{}) {
|
|
||||||
m.Conf(SOURCE, kit.Keys(kit.MDB_HASH), "")
|
|
||||||
m.Conf(SOURCE, kit.Keys(kit.MDB_HASH, key), value)
|
|
||||||
})
|
|
||||||
m.Save()
|
m.Save()
|
||||||
}},
|
}},
|
||||||
}}
|
}}
|
||||||
@ -36,6 +29,6 @@ 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,
|
CONNECT, SESSION, SERVICE, CHANNEL,
|
||||||
SOURCE, TARGET, PROMPT, RETURN,
|
SOURCE, TARGET, PROMPT, PRINTF, SCREEN, RETURN,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,10 @@ refer `
|
|||||||
源码 https://github.com/openssh/openssh-portable
|
源码 https://github.com/openssh/openssh-portable
|
||||||
`
|
`
|
||||||
|
|
||||||
field "服务" ssh.service
|
|
||||||
field "通道" ssh.channel
|
|
||||||
field "连接" ssh.connect
|
field "连接" ssh.connect
|
||||||
field "会话" ssh.session
|
field "会话" ssh.session
|
||||||
|
field "服务" ssh.service
|
||||||
|
field "通道" ssh.channel
|
||||||
|
|
||||||
field "脚本" ssh.source
|
field "脚本" ssh.source
|
||||||
field "模块" ssh.target
|
field "模块" ssh.target
|
||||||
@ -16,4 +16,3 @@ field "提示" ssh.prompt
|
|||||||
field "输出" ssh.printf
|
field "输出" ssh.printf
|
||||||
field "屏显" ssh.screen
|
field "屏显" ssh.screen
|
||||||
|
|
||||||
|
|
||||||
|
13
misc.go
13
misc.go
@ -1,8 +1,10 @@
|
|||||||
package ice
|
package ice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -345,3 +347,14 @@ func (m *Message) Upload(dir string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) OptionFields(str string) { m.Option("fields", str) }
|
func (m *Message) OptionFields(str string) { m.Option("fields", str) }
|
||||||
|
func (m *Message) OptionLoad(file string) *Message {
|
||||||
|
if f, e := os.Open(file); e == nil {
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
var data interface{}
|
||||||
|
json.NewDecoder(f).Decode(&data)
|
||||||
|
|
||||||
|
kit.Fetch(data, func(key string, value interface{}) { m.Option(key, kit.Simple(value)) })
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
2
type.go
2
type.go
@ -116,7 +116,7 @@ func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Mess
|
|||||||
}
|
}
|
||||||
|
|
||||||
m.meta[MSG_DETAIL] = kit.Simple(key, arg)
|
m.meta[MSG_DETAIL] = kit.Simple(key, arg)
|
||||||
if m.Hand = true; len(arg) > 1 && arg[0] == "action" && cmd.Action != nil {
|
if m.Hand = true; len(arg) > 1 && arg[0] == kit.MDB_ACTION && cmd.Action != nil {
|
||||||
if h, ok := cmd.Action[arg[1]]; ok {
|
if h, ok := cmd.Action[arg[1]]; ok {
|
||||||
return c._hand(m, cmd, key, arg[1], h, arg[2:]...)
|
return c._hand(m, cmd, key, arg[1], h, arg[2:]...)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user