From faed551a3555fbce794e1e276714e4c0d40abb91 Mon Sep 17 00:00:00 2001 From: shylinux Date: Sun, 14 May 2023 16:01:25 +0800 Subject: [PATCH] add readelf.go --- base/cli/readelf.go | 86 +++++++++++++++++++++++++++++++++ base/web/option.go | 9 ++-- base/web/render.go | 25 +++++----- base/web/space.go | 7 +-- core/chat/macos/applications.go | 3 -- core/chat/macos/desktop.css | 2 +- core/chat/macos/desktop.js | 5 +- core/chat/macos/menu.js | 2 +- core/code/compile.go | 5 ++ core/code/go.go | 4 ++ core/code/xterm.go | 10 ++-- misc/git/service.go | 3 ++ misc/websocket/websocket.go | 14 ++++-- misc/xterm/iterm.go | 9 +++- 14 files changed, 148 insertions(+), 36 deletions(-) create mode 100644 base/cli/readelf.go diff --git a/base/cli/readelf.go b/base/cli/readelf.go new file mode 100644 index 00000000..3625f567 --- /dev/null +++ b/base/cli/readelf.go @@ -0,0 +1,86 @@ +package cli + +import ( + "bytes" + "encoding/binary" + "strings" + + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/nfs" + kit "shylinux.com/x/toolkits" +) + +type elf struct { + EI_CLASS int + EI_DATA int + EI_VERSION int + e_type uint16 + e_machine uint16 + e_version uint32 + e_entry uint64 + e_phoff uint64 + e_shoff uint64 + e_flags uint32 + e_ehsize uint16 + e_phentsize uint16 + e_phnum uint16 + e_shentsize uint16 + e_shnum uint16 + e_shstrndx uint16 +} + +func read2(buf []byte, offset int) (uint16, int) { + return binary.LittleEndian.Uint16(buf[offset : offset+2]), offset + 2 +} +func read4(buf []byte, offset int) (uint32, int) { + return binary.LittleEndian.Uint32(buf[offset : offset+4]), offset + 4 +} +func read8(buf []byte, offset int) (uint64, int) { + return binary.LittleEndian.Uint64(buf[offset : offset+8]), offset + 8 +} +func readelf(buf []byte) (elf elf) { + i := 16 + elf.EI_CLASS = int(buf[4]) + elf.EI_DATA = int(buf[5]) + elf.EI_VERSION = int(buf[6]) + elf.e_type, i = read2(buf, i) + elf.e_machine, i = read2(buf, i) + elf.e_version, i = read4(buf, i) + elf.e_entry, i = read8(buf, i) + elf.e_phoff, i = read8(buf, i) + elf.e_shoff, i = read8(buf, i) + elf.e_flags, i = read4(buf, i) + elf.e_ehsize, i = read2(buf, i) + elf.e_phentsize, i = read2(buf, i) + elf.e_phnum, i = read2(buf, i) + elf.e_shentsize, i = read2(buf, i) + elf.e_shnum, i = read2(buf, i) + elf.e_shstrndx, i = read2(buf, i) + return elf +} + +func init() { + Index.MergeCommands(ice.Commands{ + "readelf": {Name: "readelf path=usr/publish/ice.linux.amd64 auto", Hand: func(m *ice.Message, arg ...string) { + if len(arg) == 0 || strings.HasSuffix(arg[0], nfs.PS) { + m.Cmdy(nfs.DIR, arg) + return + } + if f, e := nfs.OpenFile(m, arg[0]); !m.Warn(e) { + defer f.Close() + buf := make([]byte, 1024) + n, e := f.Read(buf) + if m.Warn(e) { + return + } + if bytes.Equal(buf[:4], []byte{0x7f, 0x45, 0x4c, 0x46}) { + m.Echo("elf %#v", readelf(buf)) + } + for i := 0; i < n; i++ { + kit.If(i%16 == 0, func() { m.Push("addr", kit.Format("%04x", i)) }) + m.Push(kit.Format("%02x", i%16), kit.Format("%02x", buf[i])) + } + } + }}, + }) +} diff --git a/base/web/option.go b/base/web/option.go index 63a33fd4..fbe0f3cd 100644 --- a/base/web/option.go +++ b/base/web/option.go @@ -81,14 +81,13 @@ func PushNotice(m *ice.Message, arg ...ice.Any) { } else if m.Option(ice.MSG_USERPOD) == "" { m.Cmd(SPACE, m.Option(ice.MSG_DAEMON), arg, ice.Maps{ice.MSG_OPTION: "", ice.MSG_OPTS: ""}) } else { - m.Cmd(Prefix(SPIDE), ice.OPS, MergeURL2(m, P(SHARE, TOAST, m.Option(ice.MSG_DAEMON))), ice.ARG, kit.Format(arg)) + m.Cmd(SPACE, kit.Keys(m.Option("__target"), m.Option(ice.MSG_DAEMON)), arg, ice.Maps{ice.MSG_OPTION: "", ice.MSG_OPTS: ""}) } } -func PushNoticeGrow(m *ice.Message, arg ...ice.Any) { PushNotice(m, kit.List("grow", arg)...) } func PushNoticeToast(m *ice.Message, arg ...ice.Any) { PushNotice(m, kit.List("toast", arg)...) } -func PushStream(m *ice.Message) *ice.Message { - m.ProcessHold() - return m.Options(cli.CMD_OUTPUT, file.NewWriteCloser(func(buf []byte) { PushNoticeGrow(m, string(buf)) }, func() { PushNoticeToast(m, "done") })) +func PushNoticeGrow(m *ice.Message, arg ...ice.Any) { PushNotice(m, kit.List("grow", arg)...) } +func PushStream(m *ice.Message) { + m.Options(cli.CMD_OUTPUT, file.NewWriteCloser(func(buf []byte) { PushNoticeGrow(m, string(buf)) }, func() { PushNoticeToast(m, "done") })).ProcessHold() } func Toast(m *ice.Message, text string, arg ...ice.Any) { // [title [duration [progress]]] diff --git a/base/web/render.go b/base/web/render.go index ab11d4fb..ecdbc8f3 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -153,16 +153,17 @@ const ( VIEW = "view" CHAT = "chat" - TEAM_PLAN = "web.team.plan" - WIKI_WORD = "web.wiki.word" - WIKI_DRAW = "web.wiki.draw" - WIKI_FEEL = "web.wiki.feel" - CODE_INNER = "web.code.inner" - CODE_VIMER = "web.code.vimer" - CODE_XTERM = "web.code.xterm" - CODE_COMPILE = "web.code.compile" - CODE_GIT_STATUS = "web.code.git.status" - CODE_GIT_REPOS = "web.code.git.repos" - CHAT_FAVOR = "web.chat.favor" - CHAT_IFRAME = "web.chat.iframe" + TEAM_PLAN = "web.team.plan" + WIKI_WORD = "web.wiki.word" + WIKI_DRAW = "web.wiki.draw" + WIKI_FEEL = "web.wiki.feel" + CODE_INNER = "web.code.inner" + CODE_VIMER = "web.code.vimer" + CODE_XTERM = "web.code.xterm" + CODE_COMPILE = "web.code.compile" + CODE_GIT_SERVICE = "web.code.git.service" + CODE_GIT_STATUS = "web.code.git.status" + CODE_GIT_REPOS = "web.code.git.repos" + CHAT_FAVOR = "web.chat.favor" + CHAT_IFRAME = "web.chat.iframe" ) diff --git a/base/web/space.go b/base/web/space.go index fe6bb9bd..fd4e2f61 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -122,11 +122,8 @@ func _space_exec(m *ice.Message, source, target []string, c *websocket.Conn) { case cli.PWD: m.Push(mdb.LINK, m.MergePod(kit.Select("", source, -1))) default: - kit.If(aaa.Right(m, m.Detailv()), func() { - m.TryCatch(m, true, func(_ *ice.Message) { - m = m.Cmd() - }) - }) + m.Option("__target", kit.Reverse(kit.Simple(source))) + kit.If(aaa.Right(m, m.Detailv()), func() { m.TryCatch(m, true, func(_ *ice.Message) { m = m.Cmd() }) }) } defer m.Cost(kit.Format("%v->%v %v %v", source, target, m.Detailv(), m.FormatSize())) _space_echo(m.Set(ice.MSG_OPTS).Options(log.DEBUG, m.Option(log.DEBUG)), []string{}, kit.Reverse(kit.Simple(source)), c) diff --git a/core/chat/macos/applications.go b/core/chat/macos/applications.go index 5743d331..1be6ab2d 100644 --- a/core/chat/macos/applications.go +++ b/core/chat/macos/applications.go @@ -28,9 +28,6 @@ func init() { AppInstall(m, "Photos", web.WIKI_FEEL) AppInstall(m, "Books", web.WIKI_WORD) AppInstall(m, "", web.CODE_VIMER) - AppInstall(m, "", web.DREAM, mdb.ICON, "usr/icons/Mission Control.png") - AppInstall(m, "", web.CODE_GIT_REPOS, mdb.ICON, "usr/icons/git.jpg") - AppInstall(m, "", web.CODE_COMPILE, mdb.ICON, "usr/icons/go.png") }}, code.INSTALL: {Hand: func(m *ice.Message, arg ...string) { AppInstall(m, arg[0], arg[1], arg[2:]...) }}, }, CmdHashAction("index,args"))}, diff --git a/core/chat/macos/desktop.css b/core/chat/macos/desktop.css index f2981fdc..89230d2b 100644 --- a/core/chat/macos/desktop.css +++ b/core/chat/macos/desktop.css @@ -45,7 +45,7 @@ fieldset.macos.desktop>div.output>div.desktop>fieldset>div.output>fieldset>div.a fieldset.macos.menu>div.output>div.item { padding:0 5px; float:right; cursor:pointer; } fieldset.macos.menu>div.output>div.item.avatar>img { height:25px; } fieldset.macos.menu>div.output>div.menu { float:left; padding:0 20px; cursor:pointer; } -fieldset.macos.menu>div.output>div.tabs { float:left; } +fieldset.macos.menu>div.output>div.tabs { float:left; font-style:italic; } fieldset.macos.menu>div.output>div.tabs.select { background-color:transparent; color:white; } fieldset.macos.dock>div.output { height:80px; display:flex; overflow:auto; } fieldset.macos.dock>div.output>div.space { background-color:#ececec36; margin:10px; height:calc(100% - 20px); width:2px; } diff --git a/core/chat/macos/desktop.js b/core/chat/macos/desktop.js index c4da7c2a..4a954fb1 100644 --- a/core/chat/macos/desktop.js +++ b/core/chat/macos/desktop.js @@ -21,9 +21,12 @@ Volcanos(chat.ONIMPORT, { }) }, _searchs: function(can) { can.onappend.plugin(can, {index: "web.chat.macos.searchs"}, function(sub) { can.ui.searchs = sub can.page.style(can, sub._target, html.LEFT, can.ConfWidth()/4, html.TOP, can.ConfHeight()/4), sub.onimport.size(sub, can.ConfHeight()/2, can.ConfWidth()/2, true) - sub.onexport.record = function(sub, value, key, item) { + sub.onexport.record = function(sub, value, key, item, event) { if (item.cmd == ctx.COMMAND) { can.onimport._window(can, {index: can.core.Keys(item.type, item.name.split(lex.SP)[0])}) } if (item.type == nfs.FILE) { can.onimport._window(can, {index: web.CODE_VIMER, args: can.misc.SplitPath(can, item.text) }) } + if (item.type == ice.CMD) { can.onimport._window(can, {index: item.name, args: can.base.Obj(item.text) }) } + if (can.base.isIn(item.type, web.LINK, web.WORKER, web.SERVER, web.GATEWAY)) { can.onimport._window(can, {index: web.CHAT_IFRAME, args: [item.text]}), can.onkeymap.prevent(event) } + if (item.type == ssh.SHELL) { can.onimport._window(can, {index: web.CODE_XTERM, args: [item.text]}) } }, can.ConfHeight() < 800 && can.onmotion.delay(can, function() { can.onmotion.hidden(can, sub._target) }) can.onmotion.hidden(can, sub._target) }) }, diff --git a/core/chat/macos/menu.js b/core/chat/macos/menu.js index 39687d54..6e351ce7 100644 --- a/core/chat/macos/menu.js +++ b/core/chat/macos/menu.js @@ -4,6 +4,6 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.page.Append(can, can._o ].concat(msg.Table(function(item) { return {view: [html.ITEM], list: [{img: can.page.drawText(can, item.name||item.index, 25, 0, 20)}], onclick: function(event) { can.sup.onexport.record(can, item) }} }), [ - {view: [html.MENU, "", location.hostname], onclick: function(event) { can.sup.onexport.record(can, html.DESKTOP) }}, + {view: [html.MENU, "", can.user.mod.isPod? can.misc.ParseURL(can)[ice.POD]: location.hostname], onclick: function(event) { can.sup.onexport.record(can, html.DESKTOP) }}, {view: [html.MENU, "", "+"], onclick: function(event) { can.sup.onexport.record(can, mdb.CREATE) }}, ])) }}) diff --git a/core/code/compile.go b/core/code/compile.go index 975e45a7..21ff359a 100644 --- a/core/code/compile.go +++ b/core/code/compile.go @@ -42,6 +42,11 @@ func init() { Index.MergeCommands(ice.Commands{ COMPILE: {Name: "compile arch=amd64,386,arm,arm64,mipsle os=linux,darwin,windows src=src/main.go@key run binpack webpack devpack install", Help: "编译", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { cli.IsAlpine(m, GO, "go git") }}, + mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { + mdb.IsSearchForEach(m, arg, func() []string { + return []string{ice.CMD, m.CommandKey(), kit.Format(kit.Simple(runtime.GOARCH, runtime.GOOS))} + }) + }}, mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { switch arg[0] { case SERVICE: diff --git a/core/code/go.go b/core/code/go.go index f92e5ab3..0ce04c96 100644 --- a/core/code/go.go +++ b/core/code/go.go @@ -105,6 +105,10 @@ func init() { ProcessXterm(m, "ish", "", arg[1]) } else if arg[1] == "misc/xterm/iterm.go" { ProcessXterm(m, "ish", "", arg[1]) + } else if cmd := ctx.GetFileCmd(path.Join(arg[2], arg[1])); cmd != "" { + ctx.ProcessCommand(m, cmd, kit.Simple()) + } else if msg := m.Cmd(yac.STACK, path.Join(arg[2], arg[1])); msg.Option("__index") != "" { + ctx.ProcessCommand(m, msg.Option("__index"), kit.Simple()) } else { ctx.ProcessCommand(m, yac.STACK, kit.Simple(path.Join(arg[2], arg[1]))) } diff --git a/core/code/xterm.go b/core/code/xterm.go index f9d71a42..b6d93a90 100644 --- a/core/code/xterm.go +++ b/core/code/xterm.go @@ -23,7 +23,7 @@ func _xterm_get(m *ice.Message, h string) xterm.XTerm { mdb.HashModify(m, mdb.TIME, m.Time(), cli.DAEMON, m.Option(ice.MSG_DAEMON)) return mdb.HashSelectTarget(m, h, func(value ice.Maps) ice.Any { text := strings.Split(value[mdb.TEXT], lex.NL) - ls := kit.Split(strings.Split(kit.Select(nfs.SH, value[mdb.TYPE]), " # ")[0]) + ls := kit.Split(strings.Split(kit.Select(ISH, value[mdb.TYPE]), " # ")[0]) kit.If(value[nfs.PATH] != "" && !strings.HasSuffix(value[nfs.PATH], nfs.PS), func() { value[nfs.PATH] = path.Dir(value[nfs.PATH]) }) term, e := xterm.Command(m, value[nfs.PATH], kit.Select(ls[0], cli.SystemFind(m, ls[0])), ls[1:]...) if m.Warn(e) { @@ -57,7 +57,8 @@ func _xterm_get(m *ice.Message, h string) xterm.XTerm { func _xterm_echo(m *ice.Message, h string, str string) { m.Options(ice.MSG_DAEMON, mdb.HashSelectField(m, h, cli.DAEMON)) // m.Option(ice.LOG_DISABLE, ice.TRUE) - m.Debug("what ---%o--- ---[%v]---", []byte(str), str) + // m.Debug("what ---%o--- ---[%v]---", []byte(str), str) + m.Debug("what ---%o---", []byte(str)) web.PushNoticeGrow(m, h, str) } func _xterm_cmds(m *ice.Message, h string, cmd string, arg ...ice.Any) { @@ -78,7 +79,7 @@ func init() { return []string{ssh.SHELL, SH, "/bin/sh"} } }) - mdb.IsSearchForEach(m, arg, func() []string { return []string{ssh.SHELL, "ice", "/bin/ish"} }) + mdb.IsSearchForEach(m, arg, func() []string { return []string{ssh.SHELL, ISH, "/bin/ish"} }) }}, mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { switch mdb.HashInputs(m, arg); arg[0] { @@ -110,7 +111,8 @@ func init() { }}, web.INPUT: {Hand: func(m *ice.Message, arg ...string) { if b, e := base64.StdEncoding.DecodeString(strings.Join(arg, "")); !m.Warn(e) { - m.Debug("what ---%o--- ---[%v]---", b, string(b)) + // m.Debug("what ---%o--- ---[%v]---", b, string(b)) + m.Debug("what ---%o---", b) _xterm_get(m, "").Write(string(b)) } }}, diff --git a/misc/git/service.go b/misc/git/service.go index 41ab442e..443bffc6 100644 --- a/misc/git/service.go +++ b/misc/git/service.go @@ -123,6 +123,9 @@ func init() { ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(nfs.DIR, ice.USR_LOCAL_REPOS, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) }) }}, + mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { + mdb.IsSearchForEach(m, arg, func() []string { return []string{ice.CMD, m.PrefixKey()} }) + }}, mdb.CREATE: {Name: "create name*=demo", Hand: func(m *ice.Message, arg ...string) { _repos_init(m, _service_path(m, m.Option(mdb.NAME))) _repos_insert(m, _service_path(m, m.Option(mdb.NAME))) diff --git a/misc/websocket/websocket.go b/misc/websocket/websocket.go index 256abb93..09ee359b 100644 --- a/misc/websocket/websocket.go +++ b/misc/websocket/websocket.go @@ -6,16 +6,24 @@ import ( "net/url" ice "shylinux.com/x/icebergs" + "shylinux.com/x/toolkits/task" "shylinux.com/x/websocket" ) -type Conn struct{ *websocket.Conn } +type Conn struct { + *websocket.Conn + lock task.Lock +} +func (c *Conn) WriteMessage(messageType int, data []byte) error { + defer c.lock.Lock()() + return c.Conn.WriteMessage(messageType, data) +} func Upgrade(w http.ResponseWriter, r *http.Request) (*Conn, error) { conn, e := websocket.Upgrade(w, r, nil, ice.MOD_BUFS, ice.MOD_BUFS) - return &Conn{conn}, e + return &Conn{Conn: conn}, e } func NewClient(c net.Conn, u *url.URL) (*Conn, error) { conn, _, e := websocket.NewClient(c, u, nil, ice.MOD_BUFS, ice.MOD_BUFS) - return &Conn{conn}, e + return &Conn{Conn: conn}, e } diff --git a/misc/xterm/iterm.go b/misc/xterm/iterm.go index 2a1557bb..74f6c4f7 100644 --- a/misc/xterm/iterm.go +++ b/misc/xterm/iterm.go @@ -271,10 +271,17 @@ func (s iterm) exec(m *ice.Message, res string) string { s.w.Write([]byte(res)) r, w, _ := os.Pipe() res, s.pipe = "", w + env := kit.EnvList( + "TERM", "xterm", + "LINES", m.Option("rows"), + "COLUMNS", m.Option("cols"), + "SHELL", "/bin/ish", + "USER", m.Option(ice.MSG_USERNAME), + ) m.Cmd(cli.SYSTEM, arg, kit.Dict(cli.CMD_INPUT, r, cli.CMD_OUTPUT, nfs.Pipe(m, func(buf []byte) { s.w.Write(bytes.ReplaceAll(buf, []byte(lex.NL), []byte(CRNL))) end = bytes.HasSuffix(buf, []byte(lex.NL)) - }), cli.CMD_ENV, kit.EnvList("TERM", "xterm", "LINES", m.Option("rows"), "COLUMNS", m.Option("cols"), "SHELL", "/bin/ish", "USER", m.Option(ice.MSG_USERNAME)))) + }), cli.CMD_ENV, env)) } else { kit.If(msg.Result() == "", func() { msg.TableEcho() }) res += strings.ReplaceAll(msg.Result(), lex.NL, CRNL)