github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/tools/vpdbootmanager/get.go (about)

     1  // Copyright 2017-2019 the u-root 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 main
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  	"os"
    11  
    12  	"github.com/mvdan/u-root-coreutils/pkg/vpd"
    13  )
    14  
    15  // NewGetter returns a new initialized Getter.
    16  func NewGetter() *Getter {
    17  	return &Getter{
    18  		R:   vpd.NewReader(),
    19  		Out: os.Stdout,
    20  	}
    21  }
    22  
    23  // Getter is the object that gets VPD variables.
    24  type Getter struct {
    25  	R   *vpd.Reader
    26  	Out io.Writer
    27  }
    28  
    29  // Print prints VPD variables. If `key` is an empty string, it will print all
    30  // the variables it finds. A variable can exist as both read-write and
    31  // read-only. In that case a "RO" or "RW" string will also be printed.
    32  func (g *Getter) Print(key string) error {
    33  	allVars := make(map[bool]map[string][]byte)
    34  	if key == "" {
    35  		// read-only variables first
    36  		rovars, err := g.R.GetAll(true)
    37  		if err != nil {
    38  			return fmt.Errorf("failed to read RO variables: %w", err)
    39  		}
    40  		allVars[true] = rovars
    41  
    42  		// then read-write variables
    43  		rwvars, err := g.R.GetAll(false)
    44  		if err != nil {
    45  			return fmt.Errorf("failed to read RW variables: %w", err)
    46  		}
    47  		allVars[false] = rwvars
    48  	} else {
    49  		// first the read-only var
    50  		value, errRO := g.R.Get(key, true)
    51  		if errRO == nil {
    52  			allVars[true] = map[string][]byte{key: value}
    53  		}
    54  		// then the read-write var
    55  		value, errRW := g.R.Get(key, false)
    56  		if errRW == nil {
    57  			allVars[false] = map[string][]byte{key: value}
    58  		}
    59  
    60  		if len(allVars[true])+len(allVars[false]) == 0 {
    61  			fmt.Fprintf(g.Out, "No variable named '%s' found\n", key)
    62  			// if the variable is simply not set, return without error,
    63  			if os.IsNotExist(errRO) && os.IsNotExist(errRW) {
    64  				return nil
    65  			}
    66  			// otherwise print one or both errors.
    67  			return fmt.Errorf("failed to read variable '%s': RO: %v, RW: %v", key, errRO, errRW)
    68  		}
    69  	}
    70  	for k, v := range allVars[true] {
    71  		fmt.Fprintf(g.Out, "%s(RO) => %s\n", k, v)
    72  	}
    73  	for k, v := range allVars[false] {
    74  		fmt.Fprintf(g.Out, "%s(RW) => %s\n", k, v)
    75  	}
    76  	return nil
    77  }