github.com/jlowellwofford/u-root@v1.0.0/xcmds/archive/decode.go (about)

     1  // Copyright 2013 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  // Archive archives files. The VTOC is at the front; we're not modeling tape drives or
     6  // streams as in tar and cpio. This will greatly speed up listing the archive,
     7  // modifying it, and so on. We think.
     8  // Why a new tool?
     9  package main
    10  
    11  import (
    12  	"fmt"
    13  	"io"
    14  	"os"
    15  	"syscall"
    16  )
    17  
    18  func doOneFile(f *os.File, v file) error {
    19  	var err error
    20  	s := v.Mode.String()
    21  	fmt.Printf("%v: mode %v", v.Name, s)
    22  	switch s[0] {
    23  	case 'd':
    24  		err = os.MkdirAll(v.Name, v.Mode)
    25  	case '-':
    26  		src := io.LimitReader(f, v.Size)
    27  		dst, err := os.OpenFile(v.Name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, v.Mode)
    28  		if err != nil {
    29  			return err
    30  		}
    31  		defer dst.Close()
    32  		if _, err := io.Copy(dst, src); err != nil {
    33  			return err
    34  		}
    35  	case 'L':
    36  		err = os.Symlink(v.Link, v.Name)
    37  	case 'D':
    38  		m := uint32(v.Mode.Perm())
    39  		switch v.Mode & (os.ModeDevice | os.ModeCharDevice) {
    40  		case os.ModeDevice:
    41  			m = m | syscall.S_IFBLK
    42  		default:
    43  			m = m | syscall.S_IFCHR
    44  		}
    45  		err = syscall.Mknod(v.Name, m, int(v.Dev))
    46  	default:
    47  		// It's not an error to do hae an archive we things we can't do.
    48  		//err = errors.New(fmt.Sprintf("Can't make %v", v))
    49  		fmt.Printf("Can' do %v yet", v)
    50  		return nil
    51  	}
    52  	if err != nil {
    53  		return err
    54  	}
    55  	return os.Lchown(v.Name, v.Uid, v.Gid)
    56  }
    57  
    58  func decode(files ...string) error {
    59  	for _, f := range files {
    60  		fd, vtoc, err := loadVTOC(f)
    61  		if err != nil {
    62  			fmt.Printf("%v", err)
    63  		}
    64  		for _, v := range vtoc {
    65  			if err := doOneFile(fd, v); err != nil {
    66  				return err
    67  			}
    68  			debug("%v", v)
    69  		}
    70  	}
    71  	return nil
    72  }