Exemple #1
0
func normalizeBuildpackArchive(inputFile *os.File, outputFile *os.File) (err error) {
	stats, err := inputFile.Stat()
	if err != nil {
		return
	}

	reader, err := zip.NewReader(inputFile, stats.Size())
	if err != nil {
		return
	}

	contents := reader.File

	parentPath, hasBuildpack := findBuildpackPath(contents)

	if !hasBuildpack {
		return errors.New("Zip archive does not contain a buildpack")
	}

	writer := zip.NewWriter(outputFile)

	for _, file := range contents {
		name := file.Name
		if parentPath == "." || strings.HasPrefix(name, parentPath) {
			var (
				r      io.ReadCloser
				w      io.Writer
				header *zip.FileHeader
			)

			fileInfo := file.FileInfo()
			header, err = zip.FileInfoHeader(fileInfo)
			header.Name = strings.Replace(name, parentPath+"/", "", 1)

			r, err = file.Open()
			if err != nil {
				return
			}

			w, err = writer.CreateHeader(header)
			if err != nil {
				return
			}

			io.Copy(w, r)
			err = r.Close()
			if err != nil {
				return
			}
		}
	}

	writer.Close()
	outputFile.Seek(0, 0)
	return
}
/*
   Helper. Recursively zip the contents of a directory tree using the zip.Writer.

   Filters so it only includes .rel files

   Note: this will not work if there are symbolic links in the src directory tree.
   (because Readdir does not follow links.)
*/
func zipSrcDirTree2(w *zip.Writer, directoryPath string, relativeDirName string) (err error) {

	var dir *os.File
	var filesInDir []os.FileInfo
	dir, err = gos.Open(directoryPath)
	filesInDir, err = dir.Readdir(0)
	if err != nil {
		return
	}
	err = dir.Close()

	for _, fileInfo := range filesInDir {
		if fileInfo.IsDir() {
			subItemPath := directoryPath + "/" + fileInfo.Name()
			subItemRelativePath := relativeDirName + "/" + fileInfo.Name()
			err = zipSrcDirTree2(w, subItemPath, subItemRelativePath)
			if err != nil {
				return
			}
		} else { // plain old file to be added.
			if strings.HasSuffix(fileInfo.Name(), ".rel") || strings.HasSuffix(fileInfo.Name(), ".txt") || strings.HasSuffix(fileInfo.Name(), ".html") || strings.HasSuffix(fileInfo.Name(), ".htm") || strings.HasSuffix(fileInfo.Name(), ".css") {
				subItemPath := directoryPath + "/" + fileInfo.Name()
				subItemRelativePath := relativeDirName + "/" + fileInfo.Name()

				var fh *zip.FileHeader
				fh, err = zip.FileInfoHeader(fileInfo)
				if err != nil {
					return
				}
				fh.Name = subItemRelativePath

				var zw io.Writer
				zw, err = w.CreateHeader(fh)
				if err != nil {
					return
				}
				var f *os.File
				f, err = gos.Open(subItemPath)
				if err != nil {
					return
				}

				_, err = io.Copy(zw, f)
				err = f.Close()
				if err != nil {
					return
				}
			}
		}
	}

	return
}
Exemple #3
0
func packFile(srcFile string, recPath string, zw *zip.Writer, fi os.FileInfo) (err error) {
	if fi.IsDir() {
		// Create zip header
		fh := new(zip.FileHeader)
		fh.Name = recPath + "/"
		fh.UncompressedSize = 0

		_, err = zw.CreateHeader(fh)
	} else {
		// Create zip header
		fh := new(zip.FileHeader)
		fh.Name = recPath
		fh.UncompressedSize = uint32(fi.Size())
		fh.SetMode(fi.Mode())
		var fw io.Writer
		fw, err = zw.CreateHeader(fh)
		if err != nil {
			return err
		}

		var f *os.File
		f, err = os.Open(srcFile)
		if err != nil {
			return err
		}
		_, err = io.Copy(fw, f)
	}
	return err
}
Exemple #4
0
// CreateNW creates a node-webkit .nw file
func (p Package) CreateNW(zw *zip.Writer, templates Templates, myapp io.Reader, includes string) error {
	// Add in a couple of package defaults
	p.Main = "index.html"
	p.EnvVar = nw.EnvVar

	if w, err := zw.Create("package.json"); err != nil {
		return err
	} else {
		if _, err := p.writeJsonTo(w); err != nil {
			return err
		}
	}

	filenameTemplates := map[string]string{
		"index.html": templates.IndexHtml,
		"client.js":  templates.ClientJs,
		"script.js":  templates.ScriptJs}
	for filename, str := range filenameTemplates {
		if w, err := zw.Create(filename); err != nil {
			return err
		} else {
			if t, err := template.New(filename).Parse(str); err != nil {
				return err
			} else {
				if err := t.Execute(w, p); err != nil {
					return err
				}
			}
		}
	}

	if includes != "" {
		if err := copyIncludes(zw, includes); err != nil {
			return err
		}
	}

	binHeader := zip.FileHeader{Name: p.Bin}
	binHeader.SetMode(0755) // Make it executable
	if w, err := zw.CreateHeader(&binHeader); err != nil {
		return err
	} else {
		if _, err := io.Copy(w, myapp); err != nil {
			return err
		}
	}

	return nil
}
Exemple #5
0
func makezipfile(w io.Writer, contents zdata) {
	const dirname = "test/"
	z := zip.NewWriter(w)
	for k, v := range contents {
		header := zip.FileHeader{
			Name:   dirname + k,
			Method: zip.Store,
		}
		header.SetModTime(time.Now())
		out, _ := z.CreateHeader(&header)
		// this should check the number of bytes written, and loop
		out.Write([]byte(v))
	}
	z.Close()
}
Exemple #6
0
Fichier : zip.go Projet : 40a/cbfs
func doZipDocs(w http.ResponseWriter, req *http.Request,
	path string) {

	quit := make(chan bool)
	defer close(quit)
	ch := make(chan *namedFile)
	cherr := make(chan error)

	go pathGenerator(path, ch, cherr, quit)
	go logErrors("zip", cherr)

	w.Header().Set("Content-Disposition",
		fmt.Sprintf("attachment; filename=%q", archiveFilename(path, "zip")))
	w.Header().Set("Content-Type", "application/zip")
	w.WriteHeader(200)

	zw := zip.NewWriter(w)
	for nf := range ch {
		if nf.err != nil {
			log.Printf("Error on %v: %v", nf.name, nf.err)
			continue
		}

		fh := zip.FileHeader{
			Name:             nf.name,
			Method:           zip.Deflate,
			UncompressedSize: uint32(nf.meta.Length),
			Comment:          nf.meta.OID,
		}
		fh.SetModTime(nf.meta.Modified)

		zf, err := zw.CreateHeader(&fh)
		if err != nil {
			log.Printf("Error making zip file: %v", err)
			// Client will get a broken zip file
			return
		}

		err = copyBlob(zf, nf.meta.OID)
		if err != nil {
			log.Printf("Error copying blob for %v: %v",
				nf.name, err)
			// Client will get a broken zip file
			return
		}
	}
	zw.Close()
}
Exemple #7
0
// zipInputFiles deterministically builds a zip archive out of input files and
// writes it to the writer. Files are written in the order given.
func zipInputFiles(files []File, w io.Writer, log logging.Logger) error {
	writer := zip.NewWriter(w)
	defer writer.Close()

	// Reports zipping progress to the log each second.
	lastReport := time.Time{}
	progress := func(count int) {
		if time.Since(lastReport) > time.Second {
			lastReport = time.Now()
			log.Infof("Zipping files: %d files left", len(files)-count)
		}
	}

	for i, in := range files {
		progress(i)

		// Intentionally do not add timestamp or file mode to make zip archive
		// deterministic. See also zip.FileInfoHeader() implementation.
		fh := zip.FileHeader{
			Name:   in.Name(),
			Method: zip.Deflate,
		}

		mode := os.FileMode(0600)
		if in.Executable() {
			mode |= 0100
		}
		if in.Symlink() {
			mode |= os.ModeSymlink
		}
		fh.SetMode(mode)

		dst, err := writer.CreateHeader(&fh)
		if err != nil {
			return err
		}
		if in.Symlink() {
			err = zipSymlinkFile(dst, in)
		} else {
			err = zipRegularFile(dst, in)
		}
		if err != nil {
			return err
		}
	}

	return nil
}
Exemple #8
0
// Zipper zips file contents at a path. Helper to prepare zipped data for upload
// to S3.
func Zipper(zipPath string) (*bytes.Buffer, error) {
	f, err := os.Open(zipPath)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	buffer := bytes.NewBuffer(nil)
	w := zip.NewWriter(buffer)
	fh := zip.FileHeader{}
	fh.Name = filepath.Base(zipPath)
	fh.SetMode(0755)

	// Add some files to the archive.
	var files = []struct {
		Name       string
		FileHandle *os.File
		Header     *zip.FileHeader
	}{
		{fh.Name, f, &fh},
	}

	// Loop through all files listed above
	// Can be created using file.Name or a custom file.Header for flexibility.
	// To set permissions you need to use the file.Header construct.
	for _, file := range files {
		var zf io.Writer
		if file.Header == nil {
			zf, err = w.Create(file.Name)
		} else {
			zf, err = w.CreateHeader(file.Header)
		}
		if err != nil {
			return nil, err
		}

		if _, err := io.Copy(zf, f); err != nil {
			return nil, err
		}
	}

	if err := w.Close(); err != nil {
		return nil, err
	}
	return buffer, nil
}
Exemple #9
0
func (zwp *ZipWriterPool) GetWriter(fileIndex int64) (io.WriteCloser, error) {
	file := zwp.container.Files[fileIndex]

	fh := zip.FileHeader{
		Name:               file.Path,
		UncompressedSize64: uint64(file.Size),
		Method:             zip.Deflate,
	}
	fh.SetMode(os.FileMode(file.Mode))
	fh.SetModTime(time.Now())

	w, err := zwp.zw.CreateHeader(&fh)
	if err != nil {
		return nil, errors.Wrap(err, 1)
	}

	return &nopWriteCloser{w}, nil
}
func processZipTimestampField(data []byte, file *zip.FileHeader) error {
	if !file.Mode().IsDir() && !file.Mode().IsRegular() {
		return nil
	}

	var tsField ZipTimestampField
	err := binary.Read(bytes.NewReader(data), binary.LittleEndian, &tsField)
	if err != nil {
		return err
	}

	if (tsField.Flags & 1) == 1 {
		modTime := time.Unix(int64(tsField.ModTime), 0)
		acTime := time.Now()
		return os.Chtimes(file.Name, acTime, modTime)
	}

	return nil
}
Exemple #11
0
// create is for internal use. It allows non-payload files to be written.
func (w *Writer) create(name string) (io.Writer, error) {
	// save checksums in case there is an active writer
	_ = w.Checksum()

	ck := new(Checksum)
	w.t.manifest[name] = ck
	w.checksum = ck

	header := zip.FileHeader{
		Name:   w.t.dirname + name,
		Method: zip.Store,
	}
	header.SetModTime(time.Now())
	out, err := w.z.CreateHeader(&header)

	w.hw = util.NewHashWriter(out)

	return w.hw, err
}
func dozip(archiveFile string, dir string) {
	// file
	file := create(archiveFile)
	defer file.Close()
	// zip
	zipWriter := zip.NewWriter(file)
	defer zipWriter.Close()
	//
	walk := func(path string, fileInfo os.FileInfo, err error) error {
		if err != nil {
			fail("Failed to traverse directory structure %v", err)
		}
		if fileInfo.Mode().IsDir() {
			return nil
		}
		print(path)
		fileToWrite := open(path)
		//
		var fileHeader *zip.FileHeader
		fileHeader, err = zip.FileInfoHeader(fileInfo)
		if err != nil {
			fail("Failed to create file info header %v", err)
		}
		fileHeader.Name = path
		//
		var w io.Writer
		w, err = zipWriter.CreateHeader(fileHeader)
		if err != nil {
			fail("Failed to create zip writer %v", err)
		}
		_, err = io.Copy(w, fileToWrite)
		if err != nil {
			fail("Failed to copy (zip writer) %v", err)
		}
		return nil
	}
	//
	err := filepath.Walk(dir, walk)
	if err != nil {
		fail("Failed to traverse directory %v %v", dir, err)
	}
}
Exemple #13
0
// Deal with file
func zipFile(srcFile string, recPath string, zw *zip.Writer, fi os.FileInfo) {
	if fi.IsDir() {
		// Create zip header
		fh := new(zip.FileHeader)
		fh.Name = recPath + "/"
		fh.UncompressedSize = 0

		_, err := zw.CreateHeader(fh)
		handleError(err)
	} else {
		// Create zip header
		fh := new(zip.FileHeader)
		fh.Name = recPath
		fh.UncompressedSize = uint32(fi.Size())
		fw, err := zw.CreateHeader(fh)
		handleError(err)

		// Read file data
		buf := make([]byte, fi.Size())
		f, err := os.Open(srcFile)
		handleError(err)
		_, err = f.Read(buf)
		handleError(err)

		// Write file data to zip
		_, err = fw.Write(buf)
		handleError(err)
	}
}
func createZipFileEntry(archive *zip.Writer, fh *zip.FileHeader) error {
	fh.Method = zip.Deflate
	fw, err := archive.CreateHeader(fh)
	if err != nil {
		return err
	}

	file, err := os.Open(fh.Name)
	if err != nil {
		return err
	}

	_, err = io.Copy(fw, file)
	file.Close()
	if err != nil {
		return err
	}
	return nil
}
			tmpDir, err = ioutil.TempDir(os.TempDir(), "unzip_contents")
			Expect(err).NotTo(HaveOccurred())

			prevDir, err = os.Getwd()
			Expect(err).NotTo(HaveOccurred())
			Expect(os.Chdir(tmpDir)).To(Succeed())

			tmpFile, err = ioutil.TempFile("", "zipfile")
			Expect(err).NotTo(HaveOccurred())
			defer tmpFile.Close()

			zipWriter := zip.NewWriter(tmpFile)
			defer zipWriter.Close()

			var (
				header *zip.FileHeader
			)

			header = &zip.FileHeader{Name: "aaa"}
			header.SetMode(os.FileMode(0644))
			_, err = zipWriter.CreateHeader(header)
			Expect(err).NotTo(HaveOccurred())

			header = &zip.FileHeader{Name: "bbb/1.txt"}
			header.SetMode(os.FileMode(0640))
			_, err = zipWriter.CreateHeader(header)
			Expect(err).NotTo(HaveOccurred())

			header = &zip.FileHeader{Name: "bbb/2.txt"}
			header.SetMode(os.FileMode(0600))
			_, err = zipWriter.CreateHeader(header)
Exemple #16
0
// zipFiles adds files transferred through the channel to zip (writer)
func zipFiles(dest io.Writer, skipOnError, unsafeArchFn bool, files <-chan ArchFileItem) (err error) {
	if dfh, ok := dest.(syncer); ok {
		defer func() {
			if e := dfh.Sync(); e != nil && err == nil && strings.Index(e.Error(), "invalid argument") < 0 {
				err = e
			}
		}()
	}
	zfh := zip.NewWriter(dest)
	defer func() {
		if e := zfh.Close(); e != nil && err == nil {
			err = e
		}
	}()
	var (
		fi         os.FileInfo
		zi         *zip.FileHeader
		w          io.Writer
		errs       []error
		openedHere bool
	)
	appendErr := func(err error) {
		if err == nil || err.Error() == "" {
			return
		}
		if errs == nil {
			errs = []error{err}
		}
	}

	for item := range files {
		openedHere = false
		if item.File == nil {
			if item.Filename == "" {
				continue
			}
			openedHere = true
			if item.File, err = os.Open(item.Filename); err != nil {
				err = fmt.Errorf("Zip cannot open %q: %v", item.Filename, err)
				if !skipOnError {
					return err
				}
				appendErr(err)
				continue
			}
		}
		if fi, err = item.File.Stat(); err != nil {
			if openedHere {
				_ = item.File.Close()
			}
			err = fmt.Errorf("error stating %s: %s", item.File, err)
		} else if fi == nil {
			err = fmt.Errorf("nil stat of %#v", item.File)
		}
		if err != nil {
			if !skipOnError {
				return err
			}
			appendErr(err)
			continue
		}
		logger.Debug("msg", "ZipFiles", "fi", fi)
		if zi, err = zip.FileInfoHeader(fi); err != nil {
			if openedHere {
				_ = item.File.Close()
			}
			err = fmt.Errorf("cannot convert stat %s to header: %s", item.File, err)
			if !skipOnError {
				return err
			}
			appendErr(err)
			continue
		}
		if item.Archive != "" {
			zi.Name = item.Archive
		} else if unsafeArchFn {
			zi.Name = unsafeFn(zi.Name, true)
		}
		if w, err = zfh.CreateHeader(zi); err != nil {
			if openedHere {
				_ = item.File.Close()
			}
			err = fmt.Errorf("error creating header for %q: %v", zi.Name, err)
			if !skipOnError {
				return err
			}
			appendErr(err)
			continue
		}
		logger.Debug("msg", "zipping", "arch", item.Archive, "name", zi.Name)
		_, err = io.Copy(w, item.File)
		if openedHere {
			_ = item.File.Close()
		}
		if err != nil {
			err = fmt.Errorf("error writing %s to zipfile: %s", item.File, err)
			logger.Warn("msg", "write to zip", "error", err)
			if !skipOnError {
				return err
			}
			appendErr(err)
			continue
		}
	}
	if errs == nil || len(errs) == 0 {
		return nil
	}
	sarr := make([]string, 0, len(errs))
	for _, err = range errs {
		sarr = append(sarr, err.Error())
	}
	return errors.New(strings.Join(sarr, "\n"))
}
Exemple #17
0
func CompressZip(archiveWriter io.Writer, container *tlc.Container, pool wsync.Pool, consumer *state.Consumer) (*archiver.CompressResult, error) {
	var err error
	var uncompressedSize int64
	var compressedSize int64

	archiveCounter := counter.NewWriter(archiveWriter)

	zipWriter := zip.NewWriter(archiveCounter)
	defer zipWriter.Close()
	defer func() {
		if zipWriter != nil {
			if zErr := zipWriter.Close(); err == nil && zErr != nil {
				err = errors.Wrap(zErr, 1)
			}
		}
	}()

	for _, dir := range container.Dirs {
		fh := zip.FileHeader{
			Name: dir.Path + "/",
		}
		fh.SetMode(os.FileMode(dir.Mode))
		fh.SetModTime(time.Now())

		_, hErr := zipWriter.CreateHeader(&fh)
		if hErr != nil {
			return nil, errors.Wrap(hErr, 1)
		}
	}

	for fileIndex, file := range container.Files {
		fh := zip.FileHeader{
			Name:               file.Path,
			UncompressedSize64: uint64(file.Size),
			Method:             zip.Deflate,
		}
		fh.SetMode(os.FileMode(file.Mode))
		fh.SetModTime(time.Now())

		entryWriter, eErr := zipWriter.CreateHeader(&fh)
		if eErr != nil {
			return nil, errors.Wrap(eErr, 1)
		}

		entryReader, eErr := pool.GetReader(int64(fileIndex))
		if eErr != nil {
			return nil, errors.Wrap(eErr, 1)
		}

		copiedBytes, eErr := io.Copy(entryWriter, entryReader)
		if eErr != nil {
			return nil, errors.Wrap(eErr, 1)
		}

		uncompressedSize += copiedBytes
	}

	for _, symlink := range container.Symlinks {
		fh := zip.FileHeader{
			Name: symlink.Path,
		}
		fh.SetMode(os.FileMode(symlink.Mode))

		entryWriter, eErr := zipWriter.CreateHeader(&fh)
		if eErr != nil {
			return nil, errors.Wrap(eErr, 1)
		}

		entryWriter.Write([]byte(symlink.Dest))
	}

	err = zipWriter.Close()
	if err != nil {
		return nil, errors.Wrap(err, 1)
	}
	zipWriter = nil

	compressedSize = archiveCounter.Count()

	return &archiver.CompressResult{
		UncompressedSize: uncompressedSize,
		CompressedSize:   compressedSize,
	}, nil
}
func createZipDirectoryEntry(archive *zip.Writer, fh *zip.FileHeader) error {
	fh.Name += "/"
	_, err := archive.CreateHeader(fh)
	return err
}