go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/fsutil/stream.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package fsutil 5 6 import ( 7 "archive/tar" 8 "bufio" 9 "bytes" 10 "fmt" 11 "io" 12 "os" 13 14 "github.com/rs/zerolog/log" 15 ) 16 17 // StreamFileAsTar task t 18 func StreamFileAsTar( 19 path string, // file path 20 stat os.FileInfo, // stat of the file 21 fileReader io.ReadCloser, // raw file byte stream 22 writer io.WriteCloser, // tar output stream 23 ) { 24 // close all open connection 25 defer fileReader.Close() 26 27 // stream content into the pipe 28 tw := tar.NewWriter(writer) 29 bufReader := bufio.NewReader(fileReader) 30 defer tw.Close() 31 defer writer.Close() 32 33 // send tar header 34 hdr := &tar.Header{ 35 Name: path, 36 Mode: int64(stat.Mode()), 37 Size: stat.Size(), 38 } 39 if err := tw.WriteHeader(hdr); err != nil { 40 fmt.Print(err) 41 writer.Close() 42 } 43 44 // copy file content 45 if _, err := io.Copy(writer, bufReader); err != nil { 46 fmt.Print(err) 47 writer.Close() 48 } 49 } 50 51 func ExtractFileFromTarStream(path string, tarReader io.Reader) (*bufio.Reader, error) { 52 log.Debug().Str("path", path).Msg("fsutil> extract file from tar") 53 var fileBuffer bytes.Buffer 54 bufWriter := bufio.NewWriter(&fileBuffer) 55 56 // read stream tar, extract on the fly and put it on stdout 57 tr := tar.NewReader(tarReader) 58 for { 59 h, err := tr.Next() 60 if err == io.EOF { 61 break 62 } 63 if err != nil { 64 return nil, err 65 } 66 // log.Debug().Msgf("File %s, Size: %d", h.Name, h.Size) 67 if h.Name == path { 68 log.Debug().Str("path", path).Msg("fsutil> found file") 69 if _, err := io.CopyN(bufWriter, tr, h.Size); err != nil { 70 return nil, err 71 } 72 } 73 } 74 75 bufWriter.Flush() 76 return bufio.NewReader(&fileBuffer), nil 77 }