gitlab.com/apertussolutions/u-root@v7.0.0+incompatible/pkg/cpio/cpio.go (about) 1 // Copyright 2013-2017 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 cpio implements utilities for reading and writing cpio archives. 6 // 7 // Currently, only newc-formatted cpio archives are supported through cpio.Newc. 8 // 9 // Reading from or writing to a file: 10 // 11 // f, err := os.Open(...) 12 // if err ... 13 // recReader := cpio.Newc.Reader(f) 14 // err := ForEachRecord(recReader, func(r cpio.Record) error { 15 // 16 // }) 17 // 18 // // Or... 19 // recWriter := cpio.Newc.Writer(f) 20 // 21 // 22 // Reading from or writing to an in-memory archive: 23 // 24 // a := cpio.InMemArchive() 25 // err := a.WriteRecord(...) 26 // 27 // recReader := a.Reader() // Reads from the "beginning." 28 // 29 // if a.Contains("bar/foo") { 30 // 31 // } 32 package cpio 33 34 import ( 35 "fmt" 36 "io" 37 "os" 38 "time" 39 40 "github.com/u-root/u-root/pkg/ls" 41 ) 42 43 var ( 44 formatMap = make(map[string]RecordFormat) 45 46 // Debug can be set e.g. to log.Printf to enable debug prints from 47 // marshaling/unmarshaling cpio archives. 48 Debug = func(string, ...interface{}) {} 49 ) 50 51 // Record represents a CPIO record, which represents a Unix file. 52 type Record struct { 53 // ReaderAt contains the content of this CPIO record. 54 io.ReaderAt 55 56 // Info is metadata describing the CPIO record. 57 Info 58 59 // metadata about this item's place in the file 60 RecPos int64 // Where in the file this record is 61 RecLen uint64 // How big the record is. 62 FilePos int64 // Where in the CPIO the file's contents are. 63 } 64 65 // String implements a fmt.Stringer for Record. 66 // 67 // String returns a string long-formatted like `ls` would format it. 68 func (r Record) String() string { 69 s := ls.LongStringer{ 70 Human: true, 71 Name: ls.NameStringer{}, 72 } 73 return s.FileString(LSInfoFromRecord(r)) 74 } 75 76 // Info holds metadata about files. 77 type Info struct { 78 Ino uint64 79 Mode uint64 80 UID uint64 81 GID uint64 82 NLink uint64 83 MTime uint64 84 FileSize uint64 85 Dev uint64 86 Major uint64 87 Minor uint64 88 Rmajor uint64 89 Rminor uint64 90 Name string 91 } 92 93 func (i Info) String() string { 94 return fmt.Sprintf("%s: Ino %d Mode %#o UID %d GID %d NLink %d MTime %v FileSize %d Major %d Minor %d Rmajor %d Rminor %d", 95 i.Name, 96 i.Ino, 97 i.Mode, 98 i.UID, 99 i.GID, 100 i.NLink, 101 time.Unix(int64(i.MTime), 0).UTC(), 102 i.FileSize, 103 i.Major, 104 i.Minor, 105 i.Rmajor, 106 i.Rminor) 107 } 108 109 // A RecordReader reads one record from an archive. 110 type RecordReader interface { 111 ReadRecord() (Record, error) 112 } 113 114 // A RecordWriter writes one record to an archive. 115 type RecordWriter interface { 116 WriteRecord(Record) error 117 } 118 119 // A RecordFormat gives readers and writers for dealing with archives from io 120 // objects. 121 // 122 // CPIO files have a number of records, of which newc is the most widely used 123 // today. 124 type RecordFormat interface { 125 Reader(r io.ReaderAt) RecordReader 126 Writer(w io.Writer) RecordWriter 127 } 128 129 // Format returns the RecordFormat with that name, if it exists. 130 func Format(name string) (RecordFormat, error) { 131 op, ok := formatMap[name] 132 if !ok { 133 return nil, fmt.Errorf("%q is not in cpio format map %v", name, formatMap) 134 } 135 return op, nil 136 } 137 138 func modeFromLinux(mode uint64) os.FileMode { 139 m := os.FileMode(mode & 0777) 140 switch mode & S_IFMT { 141 case S_IFBLK: 142 m |= os.ModeDevice 143 case S_IFCHR: 144 m |= os.ModeDevice | os.ModeCharDevice 145 case S_IFDIR: 146 m |= os.ModeDir 147 case S_IFIFO: 148 m |= os.ModeNamedPipe 149 case S_IFLNK: 150 m |= os.ModeSymlink 151 case S_IFREG: 152 // nothing to do 153 case S_IFSOCK: 154 m |= os.ModeSocket 155 } 156 if mode&S_ISGID != 0 { 157 m |= os.ModeSetgid 158 } 159 if mode&S_ISUID != 0 { 160 m |= os.ModeSetuid 161 } 162 if mode&S_ISVTX != 0 { 163 m |= os.ModeSticky 164 } 165 return m 166 }