github.com/linuxboot/fiano@v1.2.0/pkg/visitors/cat.go (about)

     1  // Copyright 2018 the LinuxBoot Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package visitors
     6  
     7  import (
     8  	"io"
     9  	"os"
    10  
    11  	"github.com/linuxboot/fiano/pkg/uefi"
    12  )
    13  
    14  // Cat concatenates all RAW data sections from a file into a single byte slice.
    15  type Cat struct {
    16  	// Input
    17  	Predicate func(f uefi.Firmware) bool
    18  
    19  	// Output
    20  	io.Writer
    21  	Matches []uefi.Firmware
    22  }
    23  
    24  // Run wraps Visit and performs some setup and teardown tasks.
    25  func (v *Cat) Run(f uefi.Firmware) error {
    26  	// First run "find" to generate a list of matches to replace.
    27  	find := Find{
    28  		Predicate: v.Predicate,
    29  	}
    30  	if err := find.Run(f); err != nil {
    31  		return err
    32  	}
    33  
    34  	v.Matches = find.Matches
    35  	for _, m := range v.Matches {
    36  		if err := m.Apply(v); err != nil {
    37  			return err
    38  		}
    39  	}
    40  	return nil
    41  }
    42  
    43  // Visit applies the Extract visitor to any Firmware type.
    44  func (v *Cat) Visit(f uefi.Firmware) error {
    45  	switch f := f.(type) {
    46  
    47  	case *uefi.File:
    48  		return f.ApplyChildren(v)
    49  
    50  	case *uefi.Section:
    51  		if f.Header.Type == uefi.SectionTypeRaw {
    52  			// TODO: figure out how to compute how many bytes
    53  			// to throw away. We tried once and gave up.
    54  			// UEFI ... what can you say.
    55  			if _, err := v.Write(f.Buf()[4:]); err != nil {
    56  				return err
    57  			}
    58  		}
    59  		return f.ApplyChildren(v)
    60  
    61  	default:
    62  		// Must be applied to a File to have any effect.
    63  		return nil
    64  	}
    65  }
    66  
    67  func init() {
    68  	RegisterCLI("cat", "cat a file with a regexp that matches a GUID", 1, func(args []string) (uefi.Visitor, error) {
    69  		pred, err := FindFilePredicate(args[0])
    70  		if err != nil {
    71  			return nil, err
    72  		}
    73  		return &Cat{
    74  			Predicate: pred,
    75  			Writer:    os.Stdout,
    76  		}, nil
    77  	})
    78  }