github.com/linuxboot/fiano@v1.2.0/pkg/visitors/dump.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  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"os"
    12  
    13  	"github.com/linuxboot/fiano/pkg/uefi"
    14  )
    15  
    16  // Dump a firmware file using a GUID or a name
    17  type Dump struct {
    18  	// Input
    19  	Predicate func(f uefi.Firmware) bool
    20  
    21  	// Output
    22  	// The file is written to this writer.
    23  	W io.Writer
    24  }
    25  
    26  // Run just calls the visitor
    27  func (v *Dump) Run(f uefi.Firmware) error {
    28  	return f.Apply(v)
    29  }
    30  
    31  // Visit uses find to dump a file to W.
    32  func (v *Dump) Visit(f uefi.Firmware) error {
    33  	// First run "find" to generate a list to dump
    34  	find := Find{
    35  		Predicate: v.Predicate,
    36  	}
    37  	if err := find.Run(f); err != nil {
    38  		return err
    39  	}
    40  
    41  	// There must only be one match.
    42  	if numMatch := len(find.Matches); numMatch > 1 {
    43  		return fmt.Errorf("more than one match, only one match allowed! got %v", find.Matches)
    44  	} else if numMatch == 0 {
    45  		return errors.New("no matches found")
    46  	}
    47  
    48  	m := find.Matches[0]
    49  	// TODO: We may need to call assemble here before dumping as the buffer may be empty
    50  	_, err := v.W.Write(m.Buf())
    51  	return err
    52  }
    53  
    54  func init() {
    55  	RegisterCLI("dump", "dump a firmware file", 2, func(args []string) (uefi.Visitor, error) {
    56  		pred, err := FindFilePredicate(args[0])
    57  		if err != nil {
    58  			return nil, err
    59  		}
    60  
    61  		file, err := os.OpenFile(args[1], os.O_RDWR|os.O_CREATE, 0755)
    62  		if err != nil {
    63  			return nil, err
    64  		}
    65  
    66  		// Find all the matching files and replace their inner PE32s.
    67  		return &Dump{
    68  			Predicate: pred,
    69  			W:         file,
    70  		}, nil
    71  	})
    72  }