コード例 #1
0
ファイル: main.go プロジェクト: kr/hpush
func entar(w io.Writer, dir string, ww io.Writer) error {
	msg.Write(ww, msg.User, []byte("entar\n"))
	tw := tar.NewWriter(w)
	err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		hdr := new(tar.Header)
		hdr.Name = "./app" + path[len(dir):]
		hdr.Mode = int64(fi.Mode() & os.ModePerm)
		if fi.IsDir() {
			hdr.Typeflag = tar.TypeDir
		} else {
			hdr.Typeflag = tar.TypeReg
			hdr.Size = fi.Size()
		}
		if err = tw.WriteHeader(hdr); err != nil {
			return err
		}
		if !fi.IsDir() {
			var f *os.File
			f, err = os.Open(path)
			if err != nil {
				return err
			}
			_, err = io.Copy(tw, f)
		}
		return err
	})
	if err != nil {
		return err
	}
	return tw.Close()
}
コード例 #2
0
func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os.FileInfo) error {
	// convert whiteouts to AUFS format
	if fi.Mode()&os.ModeCharDevice != 0 && hdr.Devmajor == 0 && hdr.Devminor == 0 {
		// we just rename the file and make it normal
		hdr.Name = WhiteoutPrefix + hdr.Name
		hdr.Mode = 0600
		hdr.Typeflag = tar.TypeReg
	}

	if fi.Mode()&os.ModeDir != 0 {
		// convert opaque dirs to AUFS format by writing an empty file with the prefix
		opaque, err := system.Lgetxattr(path, "trusted.overlay.opaque")
		if err != nil {
			return err
		}
		if opaque != nil && len(opaque) == 1 && opaque[0] == 'y' {
			// create a header for the whiteout file
			// it should inherit some properties from the parent, but be a regular file
			*hdr = tar.Header{
				Typeflag:   tar.TypeReg,
				Mode:       hdr.Mode & int64(os.ModePerm),
				Name:       filepath.Join(hdr.Name, WhiteoutOpaqueDir),
				Size:       0,
				Uid:        hdr.Uid,
				Uname:      hdr.Uname,
				Gid:        hdr.Gid,
				Gname:      hdr.Gname,
				AccessTime: hdr.AccessTime,
				ChangeTime: hdr.ChangeTime,
			}
		}
	}

	return nil
}
コード例 #3
0
ファイル: compress.go プロジェクト: grubernaut/Golang-Tar
func sparseCompress() {
	err := os.Mkdir("sparse", 0777)
	tarfile, err := os.Create("sparse/sparse.tar")
	if err != nil {
		log.Fatalln(err)
	}
	defer tarfile.Close()
	var fileWriter io.WriteCloser = tarfile
	tfw := tar.NewWriter(fileWriter)
	defer tfw.Close()
	file, err := os.Open("sparse.img")
	defer file.Close()
	fileInfo, err := file.Stat()
	header := new(tar.Header)
	header.Name = file.Name()
	header.Size = fileInfo.Size()
	header.Mode = int64(fileInfo.Mode())
	header.ModTime = fileInfo.ModTime()
	header.Typeflag = tar.TypeGNUSparse

	err = tfw.WriteHeader(header)
	if err != nil {
		log.Fatalln(err)
	}
	_, err = io.Copy(tfw, file)

	if err != nil {
		log.Fatalln(err)
	}
}
コード例 #4
0
ファイル: untar_test.go プロジェクト: liyangdal/kurma
func TestUntarCreatesDeeperPathsIfNotMentioned(t *testing.T) {
	StartTest(t)
	defer FinishTest(t)

	// create a buffer and tar.Writer
	buffer := bytes.NewBufferString("")
	archive := tar.NewWriter(buffer)

	writeFile := func(name, contents string) {
		b := []byte(contents)
		header := new(tar.Header)
		header.Name = name
		header.Typeflag = tar.TypeReg
		header.Mode = 0644
		header.Mode |= c_ISREG
		header.ModTime = time.Now()
		header.Size = int64(len(b))

		TestExpectSuccess(t, archive.WriteHeader(header))
		_, err := archive.Write(b)
		TestExpectSuccess(t, err)
		TestExpectSuccess(t, archive.Flush())
	}

	// generate the mock tar... this will write to a file in a directory that
	// isn't already created within the tar
	writeFile("./a_directory/file", "foo")
	archive.Close()

	// create temp folder to extract to
	tempDir := TempDir(t)
	extractionPath := path.Join(tempDir, "pkg")
	err := os.MkdirAll(extractionPath, 0755)
	TestExpectSuccess(t, err)

	// extract
	r := bytes.NewReader(buffer.Bytes())
	u := NewUntar(r, extractionPath)
	u.AbsoluteRoot = tempDir
	TestExpectSuccess(t, u.Extract())

	fileExists := func(name string) {
		_, err := os.Stat(path.Join(tempDir, name))
		TestExpectSuccess(t, err)
	}

	fileContents := func(name, contents string) {
		b, err := ioutil.ReadFile(path.Join(tempDir, name))
		TestExpectSuccess(t, err)
		TestEqual(t, string(b), contents)
	}

	fileExists("./pkg/a_directory/file")
	fileContents("./pkg/a_directory/file", "foo")
}
コード例 #5
0
ファイル: main.go プロジェクト: Mic92/nix2aci
func writeHosts(tw *tar.Writer) error {
	etcheader := tar.Header{}
	etcheader.Name = "rootfs/etc/"
	etcheader.Mode = 0644
	etcheader.Typeflag = tar.TypeDir
	tw.WriteHeader(&etcheader)

	content := []byte("127.0.0.1 localhost\n::1 localhost\n")
	header := tar.Header{}
	header.Name = "rootfs/etc/hosts"
	header.Mode = 0644
	header.Typeflag = tar.TypeReg
	header.Size = int64(len(content))

	tw.WriteHeader(&header)
	if _, err := tw.Write(content); err != nil {
		return fmt.Errorf("cannot write manifest: %v", err)
	}
	return nil
}
コード例 #6
0
ファイル: ctar.go プロジェクト: surma-dump/ctar
func AddFileToTar(tw *tar.Writer, filepath string) os.Error {
	d, e := os.Stat(filepath)
	if e != nil {
		return e
	}

	h := tar.Header{
		Name:  filepath,
		Mode:  int64(d.Mode),
		Uid:   d.Uid,
		Gid:   d.Gid,
		Size:  int64(d.Size),
		Atime: int64(d.Atime_ns / 1e9),
		Ctime: int64(d.Ctime_ns / 1e9),
		Mtime: int64(d.Mtime_ns / 1e9),
	}

	if d.IsDirectory() {
		h.Typeflag = tar.TypeDir
	} else if d.IsRegular() {
		h.Typeflag = tar.TypeReg
	} else {
		fmt.Fprintf(os.Stderr, "Skipped non-regular file: \"%s\"\n", filepath)
		return nil
	}
	tw.WriteHeader(&h)

	if !d.IsDirectory() {
		f, e := os.Open(filepath, os.O_RDONLY, 0)
		if e != nil {
			return e
		}

		_, e = io.Copy(tw, f)
		f.Close()
		if e != nil {
			return e
		}
	}
	return nil
}
コード例 #7
0
ファイル: main.go プロジェクト: Mic92/nix2aci
func addPath(writer *tar.Writer, rootPath string, prefixLen int, dereferenceEtc bool) error {
	walkFn := func(source string, info os.FileInfo, err error) error {
		if err != nil {
			return fmt.Errorf("cannot read directory '%s': %v", rootPath, err)
		}
		header := tar.Header{}
		relPath := source[(prefixLen):]
		header.Name = path.Join("rootfs", relPath)
		header.ModTime = info.ModTime()
		header.Mode = int64(info.Mode().Perm())

		if info.Mode().IsRegular() ||
			(dereferenceEtc && info.Mode()&os.ModeSymlink != 0 && strings.HasPrefix(relPath, "etc/")) {
			header.Typeflag = tar.TypeReg
			header.Size = info.Size()
			if err := writer.WriteHeader(&header); err != nil {
				return fmt.Errorf("cannot write aci image entry header '%s': %v", source, err)
			}
			return addFile(writer, source)
		} else {
			if info.Mode()&os.ModeSymlink != 0 {
				target, err := os.Readlink(source)
				if err != nil {
					return fmt.Errorf("cannot read resolve symlink '%s', %v", target, err)
				}
				header.Linkname = target
				header.Typeflag = tar.TypeSymlink
			} else if info.Mode().IsDir() {
				header.Typeflag = tar.TypeDir
			} else {
				return fmt.Errorf("not implemented")
			}
			if err := writer.WriteHeader(&header); err != nil {
				return fmt.Errorf("cannot write aci image entry '%s': %v", source, err)
			}
		}
		return nil
	}
	return filepath.Walk(rootPath, walkFn)
}
コード例 #8
0
ファイル: tar.go プロジェクト: ClaudeXin/leanote
// Deal with files
func tarGzFile(srcFile string, recPath string, tw *tar.Writer, fi os.FileInfo) {
	if fi.IsDir() {
		//    	fmt.Println("??")
		// Create tar header
		hdr := new(tar.Header)
		// if last character of header name is '/' it also can be directory
		// but if you don't set Typeflag, error will occur when you untargz
		hdr.Name = recPath // + "/"
		//        fmt.Println(hdr.Name)
		hdr.Typeflag = tar.TypeDir
		//        hdr.Size = 0
		//hdr.Mode = 0755 | c_ISDIR
		//        hdr.Mode = int64(fi.Mode()) // 加这个会有错误!!!
		//        hdr.ModTime = fi.ModTime() // 加这个会有错误!!

		// Write hander
		err := tw.WriteHeader(hdr)
		if err != nil {
			panic(err)
		}
	} else {
		// File reader
		fr, err := os.Open(srcFile)
		if err != nil {
			panic(err)
		}
		defer fr.Close()

		// Create tar header
		hdr := new(tar.Header)
		hdr.Name = recPath
		//        fmt.Println(hdr.Name)
		hdr.Size = fi.Size()
		hdr.Mode = int64(fi.Mode())
		hdr.ModTime = fi.ModTime()

		// Write hander
		err = tw.WriteHeader(hdr)
		if err != nil {
			panic(err)
		}

		// Write file data
		_, err = io.Copy(tw, fr)
		if err != nil {
			panic(err)
		}
	}
}
コード例 #9
0
ファイル: compresser.go プロジェクト: jango2015/go-cms
// Deal with files
func tarGzFile(srcFile string, recPath string, tw *tar.Writer, fi os.FileInfo) error {
	//转换字符集
	recPath = Utf8ToGBK(recPath)

	if fi.IsDir() {
		// Create tar header
		hdr := new(tar.Header)
		// if last character of header name is '/' it also can be directory
		// but if you don't set Typeflag, error will occur when you untargz
		hdr.Name = recPath + "/"
		hdr.Typeflag = tar.TypeDir
		hdr.Size = 0
		//hdr.Mode = 0755 | c_ISDIR
		hdr.Mode = int64(fi.Mode())
		hdr.ModTime = fi.ModTime()

		// Write hander
		err := tw.WriteHeader(hdr)

		return err

	} else {
		// File reader
		fr, err := os.Open(srcFile)
		if err != nil {
			return err
		}
		defer fr.Close()

		// Create tar header
		hdr := new(tar.Header)
		hdr.Name = recPath
		hdr.Size = fi.Size()
		hdr.Mode = int64(fi.Mode())
		hdr.ModTime = fi.ModTime()

		// Write hander
		err = tw.WriteHeader(hdr)
		if err != nil {
			return err
		}

		// Write file data
		_, err = io.Copy(tw, fr)

		return err

	}
}
コード例 #10
0
ファイル: pop_posix.go プロジェクト: AlphaStaxLLC/rocket
func populateHeaderUnix(h *tar.Header, fi os.FileInfo, seen map[uint64]string) {
	st, ok := fi.Sys().(*syscall.Stat_t)
	if !ok {
		return
	}
	h.Uid = int(st.Uid)
	h.Gid = int(st.Gid)
	// If we have already seen this inode, generate a hardlink
	p, ok := seen[uint64(st.Ino)]
	if ok {
		h.Linkname = p
		h.Typeflag = tar.TypeLink
	} else {
		seen[uint64(st.Ino)] = h.Name
	}
}
コード例 #11
0
ファイル: main.go プロジェクト: Mic92/nix2aci
func writeManifest(tw *tar.Writer, manifest map[string]interface{}) error {
	buf, err := json.Marshal(manifest)
	if err != nil {
		return fmt.Errorf("cannot serialize manifest: %v", err)
	}
	header := tar.Header{}
	header.Name = "manifest"
	header.Mode = 0644
	header.Size = int64(len(buf))
	header.Typeflag = tar.TypeReg
	tw.WriteHeader(&header)
	if _, err := tw.Write(buf); err != nil {
		return fmt.Errorf("cannot write manifest: %v", err)
	}
	return nil
}
コード例 #12
0
ファイル: tarhelper.go プロジェクト: tgulacsi/aostor
// appends as link pointing at a previously written item
func AppendLink(tarfn string, info Info, src string, dst string) (err error) {
	//var (twp *tar.Writer; fh ReadWriteSeekCloser; pos uint64)
	if tw, fh, _, err := OpenForAppend(tarfn); err == nil {
		defer fh.Close()
		defer tw.Close()

		if err := writeInfo(tw, info); err == nil {
			hdr := new(tar.Header)
			hdr.Name = src
			hdr.Typeflag = tar.TypeSymlink
			hdr.Linkname = dst
			if err := tw.WriteHeader(hdr); err == nil {
				err = tw.Flush()
			}
		}
	}
	return
}
コード例 #13
0
ファイル: export_challenge.go プロジェクト: jenarvaezg/ctff
func TarGzWrite(_path string, tw *tar.Writer, fi os.FileInfo) {
	fr, err := os.Open(_path)
	handleError(err)
	defer fr.Close()

	h := new(tar.Header)
	h.Name = _path[len(ChallengesPath+"/"):]
	h.Size = fi.Size()
	h.Mode = int64(fi.Mode())
	h.ModTime = fi.ModTime()
	h.Typeflag = tar.TypeReg

	err = tw.WriteHeader(h)
	handleError(err)

	_, err = io.Copy(tw, fr)
	handleError(err)
}
コード例 #14
0
ファイル: tar_helper.go プロジェクト: hpcloud/fissile
// WriteToTarStream writes a byte array of data into a tar stream
func WriteToTarStream(stream *tar.Writer, data []byte, header tar.Header) error {
	if header.Mode == 0 {
		header.Mode = 0644
	}
	if header.Size == 0 {
		header.Size = int64(len(data))
	}
	if header.Typeflag == 0 {
		header.Typeflag = tar.TypeReg
	}
	if err := stream.WriteHeader(&header); err != nil {
		return err
	}
	if _, err := stream.Write(data); err != nil {
		return err
	}
	return nil
}
コード例 #15
0
ファイル: packer_2.go プロジェクト: ohlinux/golang-snippet-cn
// Deal with files
func tarGzFile(srcFile string, recPath string, tw *tar.Writer, fi os.FileInfo) {
	if fi.IsDir() {
		// Create tar header
		hdr := new(tar.Header)
		hdr.Name = recPath + "/"
		hdr.Typeflag = tar.TypeDir
		hdr.Size = 0
		//hdr.Mode = 0755 | c_ISDIR
		hdr.Mode = int64(fi.Mode())
		hdr.ModTime = fi.ModTime()

		// Write hander
		err := tw.WriteHeader(hdr)
		if err != nil {
			panic(err)
		}
	} else {
		// File reader
		fr, err := os.Open(srcFile)
		if err != nil {
			panic(err)
		}
		defer fr.Close()

		// Create tar header
		hdr := new(tar.Header)
		hdr.Name = recPath
		hdr.Size = fi.Size()
		hdr.Mode = int64(fi.Mode())
		hdr.ModTime = fi.ModTime()

		// Write hander
		err = tw.WriteHeader(hdr)
		if err != nil {
			panic(err)
		}

		// Write file data
		_, err = io.Copy(tw, fr)
		if err != nil {
			panic(err)
		}
	}
}
コード例 #16
0
ファイル: pop_posix.go プロジェクト: balagopalraj/clearlinux
func populateHeaderUnix(h *tar.Header, fi os.FileInfo, seen map[uint64]string) {
	st, ok := fi.Sys().(*syscall.Stat_t)
	if !ok {
		return
	}
	h.Uid = int(st.Uid)
	h.Gid = int(st.Gid)
	if st.Mode&syscall.S_IFMT == syscall.S_IFBLK || st.Mode&syscall.S_IFMT == syscall.S_IFCHR {
		h.Devminor = int64(C.my_minor(C.dev_t(st.Rdev)))
		h.Devmajor = int64(C.my_major(C.dev_t(st.Rdev)))
	}
	// If we have already seen this inode, generate a hardlink
	p, ok := seen[uint64(st.Ino)]
	if ok {
		h.Linkname = p
		h.Typeflag = tar.TypeLink
	} else {
		seen[uint64(st.Ino)] = h.Name
	}
}
コード例 #17
0
ファイル: export_challenge.go プロジェクト: jenarvaezg/ctff
func IterDirectory(dirPath string, tw *tar.Writer) {
	dir, err := os.Open(dirPath)
	handleError(err)
	defer dir.Close()
	dirStat, err := os.Stat(dirPath)
	handleError(err)
	fis, err := dir.Readdir(0)
	handleError(err)
	h := new(tar.Header)
	h.Name = dirPath[len(ChallengesPath+"/"):]
	h.Mode = 0600
	h.ModTime = dirStat.ModTime()
	h.Typeflag = tar.TypeDir
	err = tw.WriteHeader(h)
	handleError(err)
	for _, fi := range fis {
		curPath := dirPath + "/" + fi.Name()
		if fi.IsDir() {
			IterDirectory(curPath, tw)
		} else {
			TarGzWrite(curPath, tw, fi)
		}
	}
}
コード例 #18
0
ファイル: untar_test.go プロジェクト: HendiGood/util
func TestUntarWhitelist(t *testing.T) {
	StartTest(t)
	defer FinishTest(t)

	// create a buffer and tar.Writer
	buffer := bytes.NewBufferString("")
	archive := tar.NewWriter(buffer)

	writeDirectory := func(name string) {
		header := new(tar.Header)
		header.Name = name + "/"
		header.Typeflag = tar.TypeDir
		header.Mode = 0755
		header.Mode |= c_ISDIR
		header.ModTime = time.Now()
		TestExpectSuccess(t, archive.WriteHeader(header))
	}

	writeFile := func(name, contents string) {
		b := []byte(contents)
		header := new(tar.Header)
		header.Name = name
		header.Typeflag = tar.TypeReg
		header.Mode = 0644
		header.Mode |= c_ISREG
		header.ModTime = time.Now()
		header.Size = int64(len(b))

		TestExpectSuccess(t, archive.WriteHeader(header))
		_, err := archive.Write(b)
		TestExpectSuccess(t, err)
		TestExpectSuccess(t, archive.Flush())
	}

	writeDirectory(".")
	writeFile("./foo", "foo")
	writeFile("./foobar", "foobar")
	writeFile("./doesntexist", "foo")
	writeDirectory("./usr")
	writeDirectory("./usr/bin")
	writeFile("./usr/bin/bash", "bash")
	writeDirectory("./usr/bin/other")
	writeFile("./usr/bin/other/sh", "sh")
	writeDirectory("./usr/nope")
	writeFile("./usr/nope/not", "notthere")
	writeDirectory("./usr/justdir")
	writeFile("./usr/justdir/not", "notthere")
	writeDirectory("./etc")
	writeFile("./etc/not", "notthere")

	archive.Close()

	// create temp folder to extract to
	tempDir := TempDir(t)

	// extract
	r := bytes.NewReader(buffer.Bytes())
	u := NewUntar(r, tempDir)
	u.PathWhitelist = []string{
		"/foo",
		"/usr/bin/",
		"/usr/justdir",
	}
	TestExpectSuccess(t, u.Extract())

	fileExists := func(name string) {
		_, err := os.Stat(path.Join(tempDir, name))
		TestExpectSuccess(t, err)
	}

	fileNotExists := func(name string) {
		_, err := os.Stat(path.Join(tempDir, name))
		TestExpectError(t, err)
	}

	fileExists("/foo")
	fileExists("/usr/bin/bash")
	fileExists("/usr/bin/other/sh")
	fileExists("/usr/justdir")
	fileNotExists("/foobar")
	fileNotExists("/doesntexist")
	fileNotExists("/usr/nope/not")
	fileNotExists("/usr/justdir/not")
	fileNotExists("/etc/not")
}
コード例 #19
0
ファイル: create.go プロジェクト: akrennmair/rat
func createArchive() int {
	archive := tar.NewWriter(output)
	defer archive.Close()
	exit_value := 0

	for _, f := range fileList {
		err := filepath.Walk(f, func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return err
			}

			if verbose {
				fmt.Fprintf(os.Stderr, "%s\n", path)
			}

			var hdr tar.Header
			hdr.Name = path
			hdr.Size = info.Size()
			hdr.Mode = int64(info.Mode())
			hdr.ModTime = info.ModTime()

			// this is not portable:
			hdr.Uid = int(info.Sys().(*syscall.Stat_t).Uid)
			hdr.Gid = int(info.Sys().(*syscall.Stat_t).Gid)

			if user, err := user.LookupId(fmt.Sprintf("%d", hdr.Uid)); err == nil {
				hdr.Uname = user.Name
			}
			// TODO: lookup group, too.

			switch info.Mode() & os.ModeType {
			case 0:
				hdr.Typeflag = tar.TypeReg
			case os.ModeDir:
				hdr.Typeflag = tar.TypeDir
			case os.ModeSymlink:
				hdr.Typeflag = tar.TypeSymlink
				linkname, err := os.Readlink(path)
				if err != nil {
					fmt.Fprintf(os.Stderr, "Warning: can't readlink a symlink: %v\n", err)
					return nil
				} else {
					hdr.Linkname = linkname
				}
			case os.ModeNamedPipe:
				hdr.Typeflag = tar.TypeFifo
			case os.ModeSocket:
				fmt.Fprintf(os.Stderr, "Warning: can't tar a socket\n")
				return nil
			case os.ModeDevice:
				fmt.Fprintf(os.Stderr, "Warning: device files are currently unsupported\n")
				return nil
				/*
					if (info.Mode() & os.ModeCharDevice) != 0 {
						os.Typeflag = tar.TypeChar
					} else {
						os.Typeflag = tar.TypeBlock
					}
				*/
			}

			if err := archive.WriteHeader(&hdr); err != nil {
				fmt.Fprintf(os.Stderr, "Writing archive header for %s failed: %v\n", path, err)
				exit_value = 1
				return nil
			}
			defer archive.Flush()

			if hdr.Typeflag == tar.TypeReg {
				if f, err := os.Open(path); err != nil {
					fmt.Fprintf(os.Stderr, "Opening file %s failed: %v\n", path, err)
					exit_value = 1
					return nil
				} else {
					io.Copy(archive, f)
					f.Close()
				}
			}
			return nil
		})
		if err != nil {
			fmt.Fprintf(os.Stderr, "An error occured: %v\n", err)
			exit_value = 1
		}
	}

	return exit_value
}
コード例 #20
0
ファイル: untar_test.go プロジェクト: liyangdal/kurma
func TestUntarExtractOverwriting(t *testing.T) {
	StartTest(t)
	defer FinishTest(t)

	// create a buffer and tar.Writer
	buffer := bytes.NewBufferString("")
	archive := tar.NewWriter(buffer)

	writeDirectory := func(name string) {
		header := new(tar.Header)
		header.Name = name + "/"
		header.Typeflag = tar.TypeDir
		header.Mode = 0755
		header.Mode |= c_ISDIR
		header.ModTime = time.Now()
		TestExpectSuccess(t, archive.WriteHeader(header))
	}

	writeFile := func(name, contents string) {
		b := []byte(contents)
		header := new(tar.Header)
		header.Name = name
		header.Typeflag = tar.TypeReg
		header.Mode = 0644
		header.Mode |= c_ISREG
		header.ModTime = time.Now()
		header.Size = int64(len(b))

		TestExpectSuccess(t, archive.WriteHeader(header))
		_, err := archive.Write(b)
		TestExpectSuccess(t, err)
		TestExpectSuccess(t, archive.Flush())
	}

	writeSymlink := func(name, link string) {
		header := new(tar.Header)
		header.Name = name
		header.Linkname = link
		header.Typeflag = tar.TypeSymlink
		header.Mode = 0644
		header.Mode |= c_ISLNK
		header.ModTime = time.Now()
		TestExpectSuccess(t, archive.WriteHeader(header))
	}

	// create temp folder to extract to
	tempDir := TempDir(t)

	fileExists := func(name string) {
		_, err := os.Stat(path.Join(tempDir, name))
		TestExpectSuccess(t, err)
	}

	fileContents := func(name, contents string) {
		b, err := ioutil.ReadFile(path.Join(tempDir, name))
		TestExpectSuccess(t, err)
		TestEqual(t, string(b), contents)
	}

	fileSymlinks := func(name, link string) {
		l, err := os.Readlink(path.Join(tempDir, name))
		TestExpectSuccess(t, err)
		TestEqual(t, l, link)
	}

	// generate the mock tar
	writeDirectory(".")
	writeFile("./foo", "foo")
	writeDirectory("./usr")
	writeDirectory("./usr/bin")
	writeFile("./usr/bin/bash", "bash")
	writeSymlink("./usr/bin/sh", "bash")
	writeDirectory("./etc")
	writeFile("./etc/awesome", "awesome")
	writeFile("./var", "vvv")
	archive.Close()

	// extract
	r := bytes.NewReader(buffer.Bytes())
	u := NewUntar(r, tempDir)
	TestExpectSuccess(t, u.Extract())

	// validate the first tar
	fileExists("./foo")
	fileContents("./foo", "foo")
	fileExists("./usr")
	fileExists("./usr/bin")
	fileExists("./usr/bin/bash")
	fileContents("./usr/bin/bash", "bash")
	fileSymlinks("./usr/bin/sh", "bash")
	fileExists("./etc/awesome")
	fileContents("./etc/awesome", "awesome")
	fileExists("./var")
	fileContents("./var", "vvv")

	// create another tar and then extract it
	buffer2 := bytes.NewBufferString("")
	archive = tar.NewWriter(buffer2)

	// write the 2nd tar
	writeDirectory(".")
	writeFile("./foo", "bar")
	writeDirectory("./usr")
	writeDirectory("./usr/bin")
	writeFile("./usr/bin/zsh", "zsh")
	writeSymlink("./usr/bin/sh", "zsh")
	writeFile("./etc", "etc") // replace the directory with a file
	writeDirectory("./var")   // replace the file with a directory
	writeFile("./var/lib", "lll")
	archive.Close()

	// extract the 2nd tar
	r = bytes.NewReader(buffer2.Bytes())
	u = NewUntar(r, tempDir)
	TestExpectSuccess(t, u.Extract())

	// verify the contents were overwritten as expected
	fileContents("./foo", "bar")
	fileContents("./usr/bin/zsh", "zsh")
	fileSymlinks("./usr/bin/sh", "zsh")
	fileContents("./etc", "etc")
	fileContents("./var/lib", "lll")
}
コード例 #21
0
ファイル: untar_test.go プロジェクト: liyangdal/kurma
func TestUntarIDMappings(t *testing.T) {
	StartTest(t)
	defer FinishTest(t)

	// create a buffer and tar.Writer
	buffer := bytes.NewBufferString("")
	archive := tar.NewWriter(buffer)

	writeDirectoryWithOwners := func(name string, uid, gid int) {
		header := new(tar.Header)
		header.Name = name + "/"
		header.Typeflag = tar.TypeDir
		header.Mode = 0755
		header.Mode |= c_ISDIR
		header.ModTime = time.Now()
		header.Uid = uid
		header.Gid = gid
		TestExpectSuccess(t, archive.WriteHeader(header))
	}

	writeFileWithOwners := func(name, contents string, uid, gid int) {
		b := []byte(contents)
		header := new(tar.Header)
		header.Name = name
		header.Typeflag = tar.TypeReg
		header.Mode = 0644
		header.Mode |= c_ISREG
		header.ModTime = time.Now()
		header.Size = int64(len(b))
		header.Uid = uid
		header.Gid = gid

		TestExpectSuccess(t, archive.WriteHeader(header))
		_, err := archive.Write(b)
		TestExpectSuccess(t, err)
		TestExpectSuccess(t, archive.Flush())
	}

	writeDirectoryWithOwners(".", 0, 0)
	writeFileWithOwners("./foo", "foo", 0, 0)
	archive.Close()

	// setup our mapping func
	usr, err := user.Current()
	TestExpectSuccess(t, err)
	myUid, err := strconv.Atoi(usr.Uid)
	TestExpectSuccess(t, err)
	myGid, err := strconv.Atoi(usr.Gid)
	TestExpectSuccess(t, err)
	uidFuncCalled := false
	gidFuncCalled := false
	uidMappingFunc := func(uid int) (int, error) {
		uidFuncCalled = true
		TestEqual(t, uid, 0)
		return myUid, nil
	}
	gidMappingFunc := func(gid int) (int, error) {
		gidFuncCalled = true
		TestEqual(t, gid, 0)
		return myGid, nil
	}

	// extract
	tempDir := TempDir(t)
	r := bytes.NewReader(buffer.Bytes())
	u := NewUntar(r, tempDir)
	u.PreserveOwners = true
	u.OwnerMappingFunc = uidMappingFunc
	u.GroupMappingFunc = gidMappingFunc
	TestExpectSuccess(t, u.Extract())

	// verify it was called
	TestEqual(t, uidFuncCalled, true)
	TestEqual(t, gidFuncCalled, true)

	// verify the file
	stat, err := os.Stat(path.Join(tempDir, "foo"))
	TestExpectSuccess(t, err)
	sys := stat.Sys().(*syscall.Stat_t)
	TestEqual(t, sys.Uid, uint32(myUid))
	TestEqual(t, sys.Gid, uint32(myGid))
}
コード例 #22
0
ファイル: untar_test.go プロジェクト: liyangdal/kurma
func TestUntarExtractFollowingSymlinks(t *testing.T) {
	StartTest(t)
	defer FinishTest(t)

	// create a buffer and tar.Writer
	buffer := bytes.NewBufferString("")
	archive := tar.NewWriter(buffer)

	writeDirectory := func(name string) {
		header := new(tar.Header)
		header.Name = name + "/"
		header.Typeflag = tar.TypeDir
		header.Mode = 0755
		header.Mode |= c_ISDIR
		header.ModTime = time.Now()
		TestExpectSuccess(t, archive.WriteHeader(header))
	}

	writeFile := func(name, contents string) {
		b := []byte(contents)
		header := new(tar.Header)
		header.Name = name
		header.Typeflag = tar.TypeReg
		header.Mode = 0644
		header.Mode |= c_ISREG
		header.ModTime = time.Now()
		header.Size = int64(len(b))

		TestExpectSuccess(t, archive.WriteHeader(header))
		_, err := archive.Write(b)
		TestExpectSuccess(t, err)
		TestExpectSuccess(t, archive.Flush())
	}

	writeSymlink := func(name, link string) {
		header := new(tar.Header)
		header.Name = name
		header.Linkname = link
		header.Typeflag = tar.TypeSymlink
		header.Mode = 0644
		header.Mode |= c_ISLNK
		header.ModTime = time.Now()
		TestExpectSuccess(t, archive.WriteHeader(header))
	}

	// generate the mock tar
	writeDirectory(".")
	writeFile("./foo", "foo")
	writeDirectory("./usr")
	writeDirectory("./usr/bin")
	writeFile("./usr/bin/bash", "bash")
	writeSymlink("./usr/bin/sh", "bash")

	// now write a symlink that is an absolute path and then a file in it
	writeSymlink("./etc", "/realetc")
	writeFile("./etc/zz", "zz")
	archive.Close()

	// create temp folder to extract to
	tempDir := TempDir(t)
	extractionPath := path.Join(tempDir, "pkg")
	err := os.MkdirAll(extractionPath, 0755)
	TestExpectSuccess(t, err)
	err = os.MkdirAll(path.Join(tempDir, "realetc"), 0755)
	TestExpectSuccess(t, err)

	// extract
	r := bytes.NewReader(buffer.Bytes())
	u := NewUntar(r, extractionPath)
	u.AbsoluteRoot = tempDir
	TestExpectSuccess(t, u.Extract())

	fileExists := func(name string) {
		_, err := os.Stat(path.Join(tempDir, name))
		TestExpectSuccess(t, err)
	}

	fileContents := func(name, contents string) {
		b, err := ioutil.ReadFile(path.Join(tempDir, name))
		TestExpectSuccess(t, err)
		TestEqual(t, string(b), contents)
	}

	fileSymlinks := func(name, link string) {
		l, err := os.Readlink(path.Join(tempDir, name))
		TestExpectSuccess(t, err)
		TestEqual(t, l, link)
	}

	fileExists("./pkg/foo")
	fileContents("./pkg/foo", "foo")
	fileExists("./pkg/usr")
	fileExists("./pkg/usr/bin")
	fileExists("./pkg/usr/bin/bash")
	fileContents("./pkg/usr/bin/bash", "bash")
	fileSymlinks("./pkg/usr/bin/sh", "bash")

	// now validate the symlink and file in the symlinked dir that was outside
	// the symlink should still be absolute to /realetc
	// but the file should be in ./realetc/zz within the tempDir and not the
	// system's root... so Untar follows how it knows it should resolve and not
	// follow the real symlink
	fileSymlinks("./pkg/etc", "/realetc")
	fileExists("./realetc/zz")
	fileContents("./realetc/zz", "zz")
}