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  }