From c86f8a698c6ce355392cc41825d278e9f57f50a1 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 25 Aug 2022 14:08:27 +0530 Subject: [PATCH] @ ls works phew --- tools/cmd/at/main.go | 37 ++++++++++++++++++++++++++++++++++--- tools/cmd/at/template.go | 4 +--- tools/cmd/at/tty_io.go | 3 +++ tools/utils/types.go | 5 +++++ 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/tools/cmd/at/main.go b/tools/cmd/at/main.go index 4c85e72fd..a032e0861 100644 --- a/tools/cmd/at/main.go +++ b/tools/cmd/at/main.go @@ -66,8 +66,22 @@ func get_pubkey(encoded_key string) (encryption_version string, pubkey []byte, e return } +func wrap_in_escape_code(data []byte) []byte { + const prefix = "\x1bP@kitty-cmd" + const suffix = "\x1b\\" + ans := make([]byte, len(prefix)+len(data)+len(suffix)) + n := copy(ans, []byte(prefix)) + n += copy(ans[n:], data) + copy(ans[n:], []byte(suffix)) + return ans +} + func simple_serializer(rc *utils.RemoteControlCmd) (ans []byte, err error) { ans, err = json.Marshal(rc) + if err != nil { + return + } + ans = wrap_in_escape_code(ans) return } @@ -84,7 +98,14 @@ func create_serializer(password string, encoded_pubkey string, io_data *rc_io_da } io_data.serializer = func(rc *utils.RemoteControlCmd) (ans []byte, err error) { ec, err := crypto.Encrypt_cmd(rc, global_options.password, pubkey, encryption_version) + if err != nil { + return + } ans, err = json.Marshal(ec) + if err != nil { + return + } + ans = wrap_in_escape_code(ans) return } if io_data.timeout < 120*time.Second { @@ -159,6 +180,14 @@ func (self *rc_io_data) next_chunk(limit_size bool) (chunk []byte, err error) { return } +func single_rc_sender(rc *utils.RemoteControlCmd, serializer serializer_func) ([]byte, error) { + if rc.SingleSent() { + return make([]byte, 0), nil + } + rc.SetSingleSent() + return serializer(rc) +} + func get_response(do_io func(io_data *rc_io_data) ([]byte, error), io_data *rc_io_data) (ans *Response, err error) { serialized_response, err := do_io(io_data) if err != nil { @@ -166,9 +195,7 @@ func get_response(do_io func(io_data *rc_io_data) ([]byte, error), io_data *rc_i io_data.rc.Payload = nil io_data.rc.CancelAsync = true io_data.rc.NoResponse = true - io_data.next_block = func(rc *utils.RemoteControlCmd, serializer serializer_func) ([]byte, error) { - return serializer(rc) - } + io_data.next_block = single_rc_sender _, err = do_io(io_data) } return @@ -252,6 +279,10 @@ func get_password(password string, password_file string, password_env string, us q, err = os.ReadFile(password_file) if err == nil { ans = strings.TrimRight(string(q), " \n\t") + } else { + if errors.Is(err, os.ErrNotExist) { + err = nil + } } } if err != nil { diff --git a/tools/cmd/at/template.go b/tools/cmd/at/template.go index 7a99686d2..42103b3ee 100644 --- a/tools/cmd/at/template.go +++ b/tools/cmd/at/template.go @@ -62,9 +62,7 @@ func run_CMD_NAME(cmd *cobra.Command, args []string) (err error) { rc: rc, timeout: time.Duration(timeout * float64(time.Second)), string_response_is_err: STRING_RESPONSE_IS_ERROR, - next_block: func(rc *utils.RemoteControlCmd, serializer serializer_func) ([]byte, error) { - return serializer(rc) - }, + next_block: single_rc_sender, } err = create_payload_CMD_NAME(&io_data, args) if err != nil { diff --git a/tools/cmd/at/tty_io.go b/tools/cmd/at/tty_io.go index f50b1daed..9e82abcc4 100644 --- a/tools/cmd/at/tty_io.go +++ b/tools/cmd/at/tty_io.go @@ -74,6 +74,9 @@ func do_chunked_io(io_data *rc_io_data) (serialized_response []byte, err error) } err = loop.Run() + if err == nil { + loop.KillIfSignalled() + } return } diff --git a/tools/utils/types.go b/tools/utils/types.go index b41ff7782..22babb603 100644 --- a/tools/utils/types.go +++ b/tools/utils/types.go @@ -10,8 +10,13 @@ type RemoteControlCmd struct { Timestamp int64 `json:"timestamp,omitempty"` Password string `json:"password,omitempty"` CancelAsync bool `json:"cancel_async,omitempty"` + + single_sent bool } +func (self *RemoteControlCmd) SingleSent() bool { return self.single_sent } +func (self *RemoteControlCmd) SetSingleSent() { self.single_sent = true } + type EncryptedRemoteControlCmd struct { Version [3]int `json:"version"` IV string `json:"iv"`