github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/exp/efivarfs/efivarfs.go (about) 1 // Copyright 2014-2022 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 "bytes" 9 "flag" 10 "fmt" 11 "io" 12 "log" 13 "os" 14 "path/filepath" 15 "strings" 16 17 guid "github.com/google/uuid" 18 "github.com/mvdan/u-root-coreutils/pkg/efivarfs" 19 ) 20 21 var ( 22 flist = flag.Bool("list", false, "List all efivars") 23 fread = flag.String("read", "", "Read specified efivar. Variable must be of form -read Name-UUID") 24 fdelete = flag.String("delete", "", "Delete specified efivar. Variable must be of form -delete Name-UUID") 25 fwrite = flag.String("write", "", "Write to specified efivar. Variable must be of form -write Name-UUID OR Name\n"+ 26 "In the later case a UUID is being generated\n"+ 27 "This command is used with -content to specify the data being written to the efivar.") 28 fcontent = flag.String("content", "", "Path to file to write to efivar. Used with -write e.g. -write Foo -content bar.json") 29 ) 30 31 func main() { 32 flag.Parse() 33 34 if err := runpath(os.Stdout, efivarfs.DefaultVarFS, *flist, *fread, *fdelete, *fwrite, *fcontent); err != nil { 35 log.Fatalf("Operation failed: %v", err) 36 } 37 } 38 39 func runpath(out io.Writer, p string, list bool, read, delete, write, content string) error { 40 e, err := efivarfs.NewPath(p) 41 if err != nil { 42 return err 43 } 44 45 return run(out, e, list, read, delete, write, content) 46 } 47 48 func run(out io.Writer, e efivarfs.EFIVar, list bool, read, delete, write, content string) error { 49 if list { 50 l, err := efivarfs.SimpleListVariables(e) 51 if err != nil { 52 return fmt.Errorf("list failed: %w", err) 53 } 54 for _, s := range l { 55 fmt.Fprintln(out, s) 56 } 57 } 58 59 if read != "" { 60 attr, data, err := efivarfs.SimpleReadVariable(e, read) 61 if err != nil { 62 return fmt.Errorf("read failed: %w", err) 63 } 64 b, err := io.ReadAll(data) 65 if err != nil { 66 return fmt.Errorf("reading buffer failed: %w", err) 67 } 68 fmt.Fprintf(out, "Name: %s, Attributes: %d, Data: %s", read, attr, b) 69 } 70 71 if delete != "" { 72 if err := efivarfs.SimpleRemoveVariable(e, delete); err != nil { 73 return fmt.Errorf("delete failed: %w", err) 74 } 75 } 76 77 if write != "" { 78 if strings.ContainsAny(write, "-") { 79 v := strings.SplitN(write, "-", 2) 80 if _, err := guid.Parse(v[1]); err != nil { 81 return fmt.Errorf("%q malformed: Must be either Name-GUID or just Name: %w", v[1], os.ErrInvalid) 82 } 83 } 84 path, err := filepath.Abs(content) 85 if err != nil { 86 return fmt.Errorf("could not resolve path: %w", err) 87 } 88 b, err := os.ReadFile(path) 89 if err != nil { 90 return fmt.Errorf("failed to read file: %w", err) 91 } 92 if !strings.ContainsAny(write, "-") { 93 write = write + "-" + guid.New().String() 94 } 95 if err = efivarfs.SimpleWriteVariable(e, write, 7, bytes.NewBuffer(b)); err != nil { 96 return fmt.Errorf("write failed: %w", err) 97 } 98 } 99 return nil 100 }