From 873df67d1f1fba4f52fdb07682c450943a1c6e41 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sat, 11 Dec 2021 22:11:01 -0800 Subject: [PATCH] Directly read/write files from ITD --- api/fs.go | 35 ++++++++++++++--------------- cmd/itctl/filesystem/read.go | 42 +++++++++++++++++------------------ cmd/itctl/filesystem/write.go | 36 +++++++++++++++--------------- socket.go | 41 ++++++++++++++++++++++++---------- 4 files changed, 85 insertions(+), 69 deletions(-) diff --git a/api/fs.go b/api/fs.go index 82dd2c1..2833c08 100644 --- a/api/fs.go +++ b/api/fs.go @@ -66,27 +66,26 @@ func (c *Client) ReadDir(path string) ([]types.FileInfo, error) { return out, nil } -func (c *Client) ReadFile(path string) (string, error) { - res, err := c.request(types.Request{ - Type: types.ReqTypeFS, - Data: types.ReqDataFS{ - Type: types.FSTypeRead, - Files: []string{path}, - }, - }) - if err != nil { - return "", err - } - return res.Value.(string), nil -} - -func (c *Client) WriteFile(path, data string) error { +func (c *Client) ReadFile(localPath, remotePath string) error { _, err := c.request(types.Request{ Type: types.ReqTypeFS, Data: types.ReqDataFS{ - Type: types.FSTypeWrite, - Files: []string{path}, - Data: data, + Type: types.FSTypeRead, + Files: []string{localPath, remotePath}, + }, + }) + if err != nil { + return err + } + return nil +} + +func (c *Client) WriteFile(localPath, remotePath string) error { + _, err := c.request(types.Request{ + Type: types.ReqTypeFS, + Data: types.ReqDataFS{ + Type: types.FSTypeWrite, + Files: []string{remotePath, localPath}, }, }) if err != nil { diff --git a/cmd/itctl/filesystem/read.go b/cmd/itctl/filesystem/read.go index 7efd624..6abab1c 100644 --- a/cmd/itctl/filesystem/read.go +++ b/cmd/itctl/filesystem/read.go @@ -19,8 +19,9 @@ package filesystem import ( + "io" + "io/ioutil" "os" - "time" "github.com/rs/zerolog/log" "github.com/spf13/cobra" @@ -38,33 +39,32 @@ var readCmd = &cobra.Command{ log.Fatal().Msg("Command read requires two arguments") } - start := time.Now() + var tmpFile *os.File + var path string + var err error + if args[1] == "-" { + tmpFile, err = ioutil.TempFile("/tmp", "itctl.*") + if err != nil { + log.Fatal().Err(err).Msg("Error creating temporary file") + } + path = tmpFile.Name() + } else { + path = args[1] + } + client := viper.Get("client").(*api.Client) - data, err := client.ReadFile(args[0]) + err = client.ReadFile(path, args[0]) if err != nil { - log.Fatal().Err(err).Msg("Error moving file or directory") + log.Fatal().Err(err).Msg("Error reading remote file") } - var suffix string - var out *os.File if args[1] == "-" { - out = os.Stdout - suffix = "\n" - } else { - out, err = os.Create(args[1]) - if err != nil { - log.Fatal().Err(err).Msg("Error opening local file") - } + io.Copy(os.Stdout, tmpFile) + os.Stdout.WriteString("\n") + tmpFile.Close() + os.Remove(path) } - - n, err := out.WriteString(data) - if err != nil { - log.Fatal().Err(err).Msg("Error writing to local file") - } - out.WriteString(suffix) - - log.Info().Msgf("Read %d bytes in %s", n, time.Since(start)) }, } diff --git a/cmd/itctl/filesystem/write.go b/cmd/itctl/filesystem/write.go index 730c0dc..3a64128 100644 --- a/cmd/itctl/filesystem/write.go +++ b/cmd/itctl/filesystem/write.go @@ -20,8 +20,8 @@ package filesystem import ( "io" + "io/ioutil" "os" - "time" "github.com/rs/zerolog/log" "github.com/spf13/cobra" @@ -39,31 +39,31 @@ var writeCmd = &cobra.Command{ log.Fatal().Msg("Command write requires two arguments") } - start := time.Now() - client := viper.Get("client").(*api.Client) - - var in *os.File + var tmpFile *os.File + var path string + var err error if args[0] == "-" { - in = os.Stdin - } else { - fl, err := os.Open(args[0]) + tmpFile, err = ioutil.TempFile("/tmp", "itctl.*") if err != nil { - log.Fatal().Err(err).Msg("Error opening local file") + log.Fatal().Err(err).Msg("Error creating temporary file") } - in = fl + path = tmpFile.Name() + } else { + path = args[0] } - data, err := io.ReadAll(in) + client := viper.Get("client").(*api.Client) + + if args[0] == "-" { + io.Copy(tmpFile, os.Stdin) + defer tmpFile.Close() + defer os.Remove(path) + } + + err = client.WriteFile(path, args[1]) if err != nil { log.Fatal().Err(err).Msg("Error moving file or directory") } - - err = client.WriteFile(args[1], string(data)) - if err != nil { - log.Fatal().Err(err).Msg("Error writing to remote file") - } - - log.Info().Msgf("Wrote %d bytes in %s", len(data), time.Since(start)) }, } diff --git a/socket.go b/socket.go index c076b8d..25152ee 100644 --- a/socket.go +++ b/socket.go @@ -535,39 +535,56 @@ func handleConnection(conn net.Conn, dev *infinitime.Device, fs *blefs.FS) { Value: out, }) case types.FSTypeWrite: - if len(reqData.Files) != 1 { + if len(reqData.Files) != 2 { connErr(conn, req.Type, nil, "Write FS command requires a path to the file to write") break } - file, err := fs.Create(reqData.Files[0], uint32(len(reqData.Data))) + + localFile, err := os.Open(reqData.Files[1]) if err != nil { - connErr(conn, req.Type, err, "Error creating file") + connErr(conn, req.Type, err, "Error opening local file") break } - _, err = file.WriteString(reqData.Data) + defer localFile.Close() + + localInfo, err := localFile.Stat() if err != nil { - connErr(conn, req.Type, err, "Error writing to file") + connErr(conn, req.Type, err, "Error getting local file information") break } + + remoteFile, err := fs.Create(reqData.Files[0], uint32(localInfo.Size())) + if err != nil { + connErr(conn, req.Type, err, "Error creating remote file") + break + } + defer remoteFile.Close() + + io.Copy(remoteFile, localFile) + json.NewEncoder(conn).Encode(types.Response{Type: req.Type}) case types.FSTypeRead: - if len(reqData.Files) != 1 { + fmt.Println(scanner.Text(), reqData) + if len(reqData.Files) != 2 { connErr(conn, req.Type, nil, "Read FS command requires a path to the file to read") break } - file, err := fs.Open(reqData.Files[0]) + localFile, err := os.Create(reqData.Files[0]) if err != nil { - connErr(conn, req.Type, err, "Error opening file") + connErr(conn, req.Type, err, "Error creating local file") break } - data, err := io.ReadAll(file) + + remoteFile, err := fs.Open(reqData.Files[1]) if err != nil { - connErr(conn, req.Type, err, "Error reading from file") + connErr(conn, req.Type, err, "Error opening remote file") break } + + io.Copy(localFile, remoteFile) + json.NewEncoder(conn).Encode(types.Response{ - Type: req.Type, - Value: string(data), + Type: req.Type, }) } case types.ReqTypeCancel: