github.com/jlowellwofford/u-root@v1.0.0/cmds/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 // cpio operates on cpio files using a cpio package 6 // It only implements basic cpio options. 7 // 8 // 9 // Synopsis: 10 // cpio 11 // 12 // Description: 13 // 14 // Options: 15 // o: output an archive to stdout given a pattern 16 // i: output files from a stdin stream 17 // t: print table of contents 18 // -v: debug prints 19 // 20 // Bugs: in i mode, it can't use non-seekable stdin, i.e. a pipe. Yep, this sucks. 21 // But if we implement seek on such things, we have to do it by reading, which 22 // really sucks. It's doable, we'll do it if we have to, but for now I'd like 23 // to avoid the complexity. cpio is a 40 year old concept. If you want something 24 // better, see ../archive which has a VTOC and separates data from metadata (unlike cpio). 25 // We could test for ESPIPE and fix it that way ... later. 26 package main 27 28 import ( 29 "bufio" 30 "flag" 31 "fmt" 32 "io" 33 "log" 34 "os" 35 36 "github.com/u-root/u-root/pkg/cpio" 37 ) 38 39 var ( 40 debug = func(string, ...interface{}) {} 41 d = flag.Bool("v", false, "Debug prints") 42 format = flag.String("H", "newc", "format") 43 ) 44 45 func usage() { 46 log.Fatalf("Usage: cpio") 47 } 48 49 func main() { 50 flag.Parse() 51 if *d { 52 debug = log.Printf 53 } 54 55 a := flag.Args() 56 debug("Args %v", a) 57 if len(a) < 1 { 58 usage() 59 } 60 op := a[0] 61 62 archiver, err := cpio.Format(*format) 63 if err != nil { 64 log.Fatalf("Format %q not supported: %v", *format, err) 65 } 66 67 switch op { 68 case "i": 69 rr := archiver.Reader(os.Stdin) 70 for { 71 rec, err := rr.ReadRecord() 72 if err == io.EOF { 73 break 74 } 75 if err != nil { 76 log.Fatalf("error reading records: %v", err) 77 } 78 debug("Creating %s\n", rec) 79 if err := cpio.CreateFile(rec); err != nil { 80 log.Printf("Creating %q failed: %v", rec.Name, err) 81 } 82 } 83 84 case "o": 85 rw := archiver.Writer(os.Stdout) 86 scanner := bufio.NewScanner(os.Stdin) 87 88 for scanner.Scan() { 89 name := scanner.Text() 90 rec, err := cpio.GetRecord(name) 91 if err != nil { 92 log.Fatalf("Getting record of %q failed: %v", name, err) 93 } 94 if err := rw.WriteRecord(rec); err != nil { 95 log.Fatalf("Writing record %q failed: %v", name, err) 96 } 97 } 98 99 if err := scanner.Err(); err != nil { 100 log.Fatalf("Error reading stdin: %v", err) 101 } 102 if err := cpio.WriteTrailer(rw); err != nil { 103 log.Fatalf("Error writing trailer record: %v", err) 104 } 105 106 case "t": 107 rr := archiver.Reader(os.Stdin) 108 for { 109 rec, err := rr.ReadRecord() 110 if err == io.EOF { 111 break 112 } 113 if err != nil { 114 log.Fatalf("error reading records: %v", err) 115 } 116 fmt.Println(rec) 117 } 118 119 default: 120 usage() 121 } 122 }