github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/kbfstool/read.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "flag" 9 "fmt" 10 "io" 11 "os" 12 13 "github.com/keybase/client/go/kbfs/fsrpc" 14 "github.com/keybase/client/go/kbfs/libkbfs" 15 "golang.org/x/net/context" 16 ) 17 18 type nodeReader struct { 19 ctx context.Context 20 kbfsOps libkbfs.KBFSOps 21 node libkbfs.Node 22 off int64 23 verbose bool 24 } 25 26 var _ io.Reader = (*nodeReader)(nil) 27 28 func (nr *nodeReader) Read(p []byte) (n int, err error) { 29 if nr.verbose { 30 fmt.Fprintf(os.Stderr, "Reading up to %s at offset %d\n", byteCountStr(len(p)), nr.off) 31 } 32 33 n64, err := nr.kbfsOps.Read(nr.ctx, nr.node, p, nr.off) 34 nr.off += n64 35 n = int(n64) 36 if n64 == 0 && err == nil { 37 if nr.verbose { 38 fmt.Fprintf(os.Stderr, "EOF encountered\n") 39 } 40 err = io.EOF 41 } else if nr.verbose { 42 fmt.Fprintf(os.Stderr, "Read %s\n", byteCountStr(n)) 43 } 44 return 45 } 46 47 func readHelper(ctx context.Context, config libkbfs.Config, args []string) error { 48 flags := flag.NewFlagSet("kbfs read", flag.ContinueOnError) 49 verbose := flags.Bool("v", false, "Print extra status output.") 50 err := flags.Parse(args) 51 if err != nil { 52 return err 53 } 54 55 if flags.NArg() != 1 { 56 return errExactlyOnePath 57 } 58 59 filePathStr := flags.Arg(0) 60 p, err := fsrpc.NewPath(filePathStr) 61 if err != nil { 62 return err 63 } 64 65 if p.PathType != fsrpc.TLFPathType { 66 return fmt.Errorf("Cannot read %s", p) 67 } 68 69 if *verbose { 70 fmt.Fprintf(os.Stderr, "Looking up %s\n", p) 71 } 72 73 fileNode, err := p.GetFileNode(ctx, config) 74 if err != nil { 75 return err 76 } 77 78 nr := nodeReader{ 79 ctx: ctx, 80 kbfsOps: config.KBFSOps(), 81 node: fileNode, 82 off: 0, 83 verbose: *verbose, 84 } 85 86 _, err = io.Copy(os.Stdout, &nr) 87 if err != nil { 88 return err 89 } 90 91 return nil 92 } 93 94 func read(ctx context.Context, config libkbfs.Config, args []string) (exitStatus int) { 95 err := readHelper(ctx, config, args) 96 if err != nil { 97 printError("read", err) 98 exitStatus = 1 99 } 100 return 101 }