cpio

package module
v0.0.0-...-925f952 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2018 License: BSD-3-Clause Imports: 11 Imported by: 0

README

go-cpio GoDoc Build Status Go Report Card

This package provides a Go native implementation of the CPIO archive file format.

Currently, only the SVR4 (New ASCII) format is supported, both with and without checksums.

// Create a buffer to write our archive to.
buf := new(bytes.Buffer)

// Create a new cpio archive.
w := cpio.NewWriter(buf)

// Add some files to the archive.
var files = []struct {
  Name, Body string
}{
  {"readme.txt", "This archive contains some text files."},
  {"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},
  {"todo.txt", "Get animal handling license."},
}
for _, file := range files {
  hdr := &cpio.Header{
    Name: file.Name,
    Mode: 0600,
    Size: int64(len(file.Body)),
  }
  if err := w.WriteHeader(hdr); err != nil {
    log.Fatalln(err)
  }
  if _, err := w.Write([]byte(file.Body)); err != nil {
    log.Fatalln(err)
  }
}
// Make sure to check the error on Close.
if err := w.Close(); err != nil {
  log.Fatalln(err)
}

// Open the cpio archive for reading.
b := bytes.NewReader(buf.Bytes())
r := cpio.NewReader(b)

// Iterate through the files in the archive.
for {
  hdr, err := r.Next()
  if err == io.EOF {
    // end of cpio archive
    break
  }
  if err != nil {
    log.Fatalln(err)
  }
  fmt.Printf("Contents of %s:\n", hdr.Name)
  if _, err := io.Copy(os.Stdout, r); err != nil {
    log.Fatalln(err)
  }
  fmt.Println()
}

Documentation

Overview

Package cpio implements access to CPIO archives. Currently, only the SVR4 (New ASCII) format is supported, both with and without checksums.

References:

https://www.freebsd.org/cgi/man.cgi?query=cpio&sektion=5
Example
// Create a buffer to write our archive to.
buf := new(bytes.Buffer)

// Create a new cpio archive.
w := cpio.NewWriter(buf)

// Add some files to the archive.
var files = []struct {
	Name, Body string
}{
	{"readme.txt", "This archive contains some text files."},
	{"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},
	{"todo.txt", "Get animal handling license."},
}
for _, file := range files {
	hdr := &cpio.Header{
		Name: file.Name,
		Mode: 0600,
		Size: int64(len(file.Body)),
	}
	if err := w.WriteHeader(hdr); err != nil {
		log.Fatalln(err)
	}
	if _, err := w.Write([]byte(file.Body)); err != nil {
		log.Fatalln(err)
	}
}
// Make sure to check the error on Close.
if err := w.Close(); err != nil {
	log.Fatalln(err)
}

// Open the cpio archive for reading.
b := bytes.NewReader(buf.Bytes())
r := cpio.NewReader(b)

// Iterate through the files in the archive.
for {
	hdr, err := r.Next()
	if err == io.EOF {
		// end of cpio archive
		break
	}
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Printf("Contents of %s:\n", hdr.Name)
	if _, err := io.Copy(os.Stdout, r); err != nil {
		log.Fatalln(err)
	}
	fmt.Println()
}
Output:

Contents of readme.txt:
This archive contains some text files.
Contents of gopher.txt:
Gopher names:
George
Geoffrey
Gonzo
Contents of todo.txt:
Get animal handling license.

Index

Examples

Constants

View Source
const (
	ModeSetuid     = 04000   // Set uid
	ModeSetgid     = 02000   // Set gid
	ModeSticky     = 01000   // Save text (sticky bit)
	ModeDir        = 040000  // Directory
	ModeNamedPipe  = 010000  // FIFO
	ModeRegular    = 0100000 // Regular file
	ModeSymlink    = 0120000 // Symbolic link
	ModeDevice     = 060000  // Block special file
	ModeCharDevice = 020000  // Character special file
	ModeSocket     = 0140000 // Socket

	ModeType = 0170000 // Mask for the type bits
	ModePerm = 0777    // Unix permission bits
)

Mode constants from the cpio spec.

Variables

View Source
var (
	ErrWriteTooLong    = errors.New("cpio: write too long")
	ErrWriteAfterClose = errors.New("cpio: write after close")
)
View Source
var (
	ErrHeader = errors.New("cpio: invalid cpio header")
)

Functions

func NewHash

func NewHash() hash.Hash32

NewHash returns a new hash.Hash32 computing the SVR4 checksum.

Example
// Open the cpio archive for reading.
f, err := os.Open("testdata/test_svr4_crc.cpio")
if err != nil {
	log.Fatal(err)
}
defer f.Close()
r := NewReader(f)

// create a Hash
h := NewHash()

// Iterate through the files in the archive.
for {
	hdr, err := r.Next()
	if err == io.EOF {
		// end of cpio archive
		return
	}
	if err != nil {
		log.Fatal(err)
	}

	// skip symlinks, directories, etc.
	if !hdr.Mode.IsRegular() {
		continue
	}

	// read file into hash
	h.Reset()
	_, err = io.CopyN(h, r, hdr.Size)
	if err != nil {
		log.Fatal(err)
	}

	// check hash matches header checksum
	sum := Checksum(h.Sum32())
	if sum == hdr.Checksum {
		fmt.Printf("Checksum OK: %v (%v)\n", hdr.Name, hdr.Checksum)
	} else {
		fmt.Printf("Checksum FAIL: %v - expected %v, got %v\n", hdr.Name, hdr.Checksum, sum)
	}
}
Output:

Checksum OK: gophers.txt (00000C98)
Checksum OK: readme.txt (00000E3D)
Checksum OK: todo.txt (00000A52)

Types

type Checksum

type Checksum uint32

Checksum is the sum of all bytes in the file data. This sum is computed treating all bytes as unsigned values and using unsigned arithmetic. Only the least-significant 32 bits of the sum are stored. Use NewHash to compute the actual checksum of an archived file.

func (Checksum) String

func (c Checksum) String() string

type FileMode

type FileMode int64

A FileMode represents a file's mode and permission bits.

func (FileMode) IsDir

func (m FileMode) IsDir() bool

IsDir reports whether m describes a directory. That is, it tests for the ModeDir bit being set in m.

func (FileMode) IsRegular

func (m FileMode) IsRegular() bool

IsRegular reports whether m describes a regular file. That is, it tests for the ModeRegular bit being set in m.

func (FileMode) Perm

func (m FileMode) Perm() FileMode

Perm returns the Unix permission bits in m.

func (FileMode) String

func (m FileMode) String() string
type Header struct {
	DeviceID int
	Inode    int64     // inode number
	Mode     FileMode  // permission and mode bits
	UID      int       // user id of the owner
	GID      int       // group id of the owner
	Links    int       // number of inbound links
	ModTime  time.Time // modified time
	Size     int64     // size in bytes
	Name     string    // filename
	Linkname string    // target name of link
	Checksum Checksum  // computed checksum
	// contains filtered or unexported fields
}

A Header represents a single header in a CPIO archive.

func FileInfoHeader

func FileInfoHeader(fi os.FileInfo, link string) (*Header, error)

FileInfoHeader creates a partially-populated Header from fi. If fi describes a symlink, FileInfoHeader records link as the link target. If fi describes a directory, a slash is appended to the name. Because os.FileInfo's Name method returns only the base name of the file it describes, it may be necessary to modify the Name field of the returned header to provide the full path name of the file.

func (*Header) FileInfo

func (h *Header) FileInfo() os.FileInfo

FileInfo returns an os.FileInfo for the Header.

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

A Reader provides sequential access to the contents of a CPIO archive. A CPIO archive consists of a sequence of files. The Next method advances to the next file in the archive (including the first), and then it can be treated as an io.Reader to access the file's data.

func NewReader

func NewReader(r io.Reader) *Reader

NewReader creates a new Reader reading from r.

func (*Reader) Next

func (r *Reader) Next() (*Header, error)

Next advances to the next entry in the CPIO archive. io.EOF is returned at the end of the input.

func (*Reader) Read

func (r *Reader) Read(p []byte) (n int, err error)

Read reads from the current entry in the CPIO archive. It returns 0, io.EOF when it reaches the end of that entry, until Next is called to advance to the next entry.

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

A Writer provides sequential writing of a CPIO archive. A CPIO archive consists of a sequence of files. Call WriteHeader to begin a new file, and then call Write to supply that file's data, writing at most hdr.Size bytes in total.

func NewWriter

func NewWriter(w io.Writer) *Writer

NewWriter creates a new Writer writing to w.

func (*Writer) Close

func (w *Writer) Close() error

Close closes the CPIO archive, flushing any unwritten data to the underlying writer.

func (*Writer) Flush

func (w *Writer) Flush() error

Flush finishes writing the current file (optional).

func (*Writer) Write

func (w *Writer) Write(p []byte) (n int, err error)

Write writes to the current entry in the CPIO archive. Write returns the error ErrWriteTooLong if more than hdr.Size bytes are written after WriteHeader.

func (*Writer) WriteHeader

func (w *Writer) WriteHeader(hdr *Header) (err error)

WriteHeader writes hdr and prepares to accept the file's contents. WriteHeader calls Flush if it is not the first header. Calling after a Close will return ErrWriteAfterClose.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL