// Store a zk tree in a zip archive. This won't be immediately useful to
// zip tools since even "directories" can contain data.
506135
func cmdZip(ctx context.Context, subFlags *flag.FlagSet, args []string) error {
	subFlags.Parse(args)
	if subFlags.NArg() < 2 {
		return fmt.Errorf("zip: need to specify source and destination paths")
	}

	dstPath := subFlags.Arg(subFlags.NArg() - 1)
	paths := subFlags.Args()[:len(args)-1]
	if !strings.HasSuffix(dstPath, ".zip") {
		return fmt.Errorf("zip: need to specify destination .zip path: %v", dstPath)
	}
	zipFile, err := os.Create(dstPath)
	if err != nil {
		return fmt.Errorf("zip: error %v", err)
	}

	wg := sync.WaitGroup{}
	items := make(chan *zkItem, 64)
	for _, arg := range paths {
		zkPath := fixZkPath(arg)
		children, err := zk2topo.ChildrenRecursive(ctx, zconn, zkPath)
		if err != nil {
			return fmt.Errorf("zip: error %v", err)
		}
		for _, child := range children {
			toAdd := path.Join(zkPath, child)
			wg.Add(1)
			go func() {
				data, stat, err := zconn.Get(ctx, toAdd)
				items <- &zkItem{toAdd, data, stat, err}
				wg.Done()
			}()
		}
	}
	go func() {
		wg.Wait()
		close(items)
	}()

	zipWriter := zip.NewWriter(zipFile)
	for item := range items {
		path, data, stat, err := item.path, item.data, item.stat, item.err
		if err != nil {
			return fmt.Errorf("zip: get failed: %v", err)
		}
		// Skip ephemerals - not sure why you would archive them.
		if stat.EphemeralOwner > 0 {
			continue
		}
		fi := &zip.FileHeader{Name: path, Method: zip.Deflate}
		fi.Modified = zk2topo.Time(stat.Mtime)
		f, err := zipWriter.CreateHeader(fi)
		if err != nil {
			return fmt.Errorf("zip: create failed: %v", err)
		}
		_, err = f.Write(data)
		if err != nil {
			return fmt.Errorf("zip: create failed: %v", err)
		}
	}
	err = zipWriter.Close()
	if err != nil {
		return fmt.Errorf("zip: close failed: %v", err)
	}
	zipFile.Close()
	return nil
}
212085
func (t *Tree) backup() {
	var tok token
	tok, t.read = t.read[len(t.read)-1], t.read[:len(t.read)-1]
	t.unread = append(t.unread, tok)
}
900087
func (tsz *TarSz) Archive(sources []string, destination string) error {
	err := tsz.CheckExt(destination)
	if err != nil {
		return fmt.Errorf("output %s", err.Error())
	}
	tsz.wrapWriter()
	return tsz.Tar.Archive(sources, destination)
}
1259134
func (s *LayerVersionContentInput) SetZipFile(v []byte) *LayerVersionContentInput {
	s.ZipFile = v
	return s
}
714221
func (z *ZipFile) Close() error {
	err := z.Writer.Close()
	// If the out writer supports io.Closer, Close it.
	if c, ok := z.out.(io.Closer); ok {
		c.Close()
	}
	return err
}
492675
func Unzip(srcPath, destPath string) error {
	// Open a zip archive for reading
	r, err := zip.OpenReader(srcPath)
	if err != nil {
		return err
	}
	defer r.Close()

	// Iterate through the files in the archive
	for _, f := range r.File {
		// Get files from archive
		rc, err := f.Open()
		if err != nil {
			return err
		}

		dir := filepath.Dir(f.Name)
		// Create directory before create file
		os.MkdirAll(destPath+"/"+dir, os.ModePerm)

		if f.FileInfo().IsDir() {
			continue
		}

		// Write data to file
		fw, _ := os.Create(filepath.Join(destPath, f.Name))
		if err != nil {
			return err
		}
		_, err = io.Copy(fw, rc)

		if fw != nil {
			fw.Close()
		}
		if err != nil {
			return err
		}
	}
	return nil
}
1235458
func newStore() *store {
	return &store{
		root: &node{
			static:    true,
			children:  make([]*node, 256),
			pchildren: make([]*node, 0),
			pindex:    -1,
			pnames:    []string{},
		},
	}
}
868780
func (v Simple) Archive(filePath string) error {
	err := archiveFile(v.folderFs, v.versionsFs, filePath, TagFilename)
	if err != nil {
		return err
	}

	file := filepath.Base(filePath)
	dir := filepath.Dir(filePath)

	// Glob according to the new file~timestamp.ext pattern.
	pattern := filepath.Join(dir, TagFilename(file, TimeGlob))
	newVersions, err := v.versionsFs.Glob(pattern)
	if err != nil {
		l.Warnln("globbing:", err, "for", pattern)
		return nil
	}

	// Also according to the old file.ext~timestamp pattern.
	pattern = filepath.Join(dir, file+"~"+TimeGlob)
	oldVersions, err := v.versionsFs.Glob(pattern)
	if err != nil {
		l.Warnln("globbing:", err, "for", pattern)
		return nil
	}

	// Use all the found filenames. "~" sorts after "." so all old pattern
	// files will be deleted before any new, which is as it should be.
	versions := util.UniqueStrings(append(oldVersions, newVersions...))

	if len(versions) > v.keep {
		for _, toRemove := range versions[:len(versions)-v.keep] {
			l.Debugln("cleaning out", toRemove)
			err = v.versionsFs.Remove(toRemove)
			if err != nil {
				l.Warnln("removing old version:", err)
			}
		}
	}

	return nil
}
407993
func (z *ZipFile) AddAll(dir string, includeCurrentFolder bool) error {
	dir = path.Clean(dir)
	return addAll(dir, dir, includeCurrentFolder, func(info os.FileInfo, file io.Reader, entryName string) (err error) {
		// Create a header based off of the fileinfo
		header, err := zip.FileInfoHeader(info)
		if err != nil {
			return err
		}

		// If it's a file, set the compression method to deflate (leave directories uncompressed)
		if !info.IsDir() {
			header.Method = zip.Deflate
		}

		// Set the header's name to what we want--it may not include the top folder
		header.Name = entryName

		// Add a trailing slash if the entry is a directory
		if info.IsDir() {
			header.Name += "/"
		}

		// Get a writer in the archive based on our header
		writer, err := z.Writer.CreateHeader(header)
		if err != nil {
			return err
		}

		// If we have a file to write (i.e., not a directory) then pipe the file into the archive writer
		if file != nil {
			if _, err := io.Copy(writer, file); err != nil {
				return err
			}
		}

		return nil
	})
}
257347
func (ta *TarringArchiver) Archive(deps []string, rootDir string, isol *isolated.Isolated, blacklist []string, isolated string) (IsolatedSummary, error) {
	parts, err := partitionDeps(deps, rootDir, blacklist)
	if err != nil {
		return IsolatedSummary{}, fmt.Errorf("partitioning deps: %v", err)
	}
	log.Printf("Expanded to the following items to be isolated:\n%s", parts)

	tracker := newUploadTracker(ta.checker, ta.uploader, isol)
	if err := tracker.UploadDeps(parts); err != nil {
		return IsolatedSummary{}, err
	}
	return tracker.Finalize(isolated)
}
705195
func (z *ZipArchive) Flush() error {
	if !z.isHasChanged || (z.ReadCloser == nil && !z.isHasWriter) {
		return nil
	}

	// Extract to tmp path and pack back.
	tmpPath := path.Join(os.TempDir(), "cae", path.Base(z.FileName))
	os.RemoveAll(tmpPath)
	defer os.RemoveAll(tmpPath)

	for _, f := range z.files {
		if strings.HasSuffix(f.Name, "/") {
			os.MkdirAll(path.Join(tmpPath, f.Name), os.ModePerm)
			continue
		}

		// Relative path inside zip temporary changed.
		f.tmpPath = path.Join(tmpPath, f.Name)
		if err := z.extractFile(f); err != nil {
			return err
		}
	}

	if z.isHasWriter {
		return packToWriter(tmpPath, z.writer, defaultPackFunc, true)
	}

	if err := PackTo(tmpPath, z.FileName); err != nil {
		return err
	}
	return z.Open(z.FileName, os.O_RDWR|os.O_TRUNC, z.Permission)
}
1041520
func (f *Function) ZipBytes() ([]byte, error) {
	if f.Zip == "" {
		f.Log.Debug("building zip")
		return f.BuildBytes()
	}

	f.Log.Debugf("reading zip %q", f.Zip)
	return ioutil.ReadFile(f.Zip)
}
771327
func (k *Store) Save() error {
	k.mu.Lock()
	defer k.mu.Unlock()

	// Short-circuit if we have no changes
	if len(k.log) == 0 {
		return nil
	}

	// firstly peek at version; open read/write to keep lock between check & write
	f, err := os.OpenFile(k.filename, os.O_RDWR|os.O_CREATE, 0664)
	if err != nil {
		return err
	}

	defer f.Close()

	// Only try to merge if > 0 bytes, ignore empty files (decoder will fail)
	if stat, _ := f.Stat(); stat.Size() > 0 {
		k.loadAndMergeReaderIfNeeded(f)
		// Now we overwrite the file
		f.Seek(0, os.SEEK_SET)
		f.Truncate(0)
	}

	k.version++

	enc := gob.NewEncoder(f)
	if err := enc.Encode(k.version); err != nil {
		return fmt.Errorf("Error while writing version data to %v: %v", k.filename, err)
	}
	if err := enc.Encode(k.db); err != nil {
		return fmt.Errorf("Error while writing new key/value data to %v: %v", k.filename, err)
	}
	// Clear log now that it's saved
	k.log = nil

	return nil
}
925667
func (k *Keyfile) Store() (err error) {
	if len(k.fname) > 0 {
		var f *os.File
		f, err = os.OpenFile(k.fname, os.O_CREATE|os.O_WRONLY, 0600)
		if err == nil {
			err = k.write(f)
			f.Close()
		}
	}
	return
}
922876
func Zipmap(keys, values cty.Value) (cty.Value, error) {
	return ZipmapFunc.Call([]cty.Value{keys, values})
}
734586
func (db *DB) ZPersist(key []byte) (int64, error) {
	if err := checkKeySize(key); err != nil {
		return 0, err
	}

	t := db.zsetBatch
	t.Lock()
	defer t.Unlock()

	n, err := db.rmExpire(t, ZSetType, key)
	if err != nil {
		return 0, err
	}

	err = t.Commit()
	return n, err
}
854425
func (zh *zipHandler) blobsFromDir(dirPath string, dirBlob blob.Ref) ([]*blobFile, error) {
	var list []*blobFile
	dr, err := schema.NewDirReader(context.TODO(), zh.fetcher, dirBlob)
	if err != nil {
		return nil, fmt.Errorf("Could not read dir blob %v: %v", dirBlob, err)
	}
	ent, err := dr.Readdir(context.TODO(), -1)
	if err != nil {
		return nil, fmt.Errorf("Could not read dir entries: %v", err)
	}
	for _, v := range ent {
		fullpath := path.Join(dirPath, v.FileName())
		switch v.CamliType() {
		case "file":
			list = append(list, &blobFile{v.BlobRef(), fullpath})
		case "directory":
			children, err := zh.blobsFromDir(fullpath, v.BlobRef())
			if err != nil {
				return nil, fmt.Errorf("Could not get list of blobs from %v: %v", v.BlobRef(), err)
			}
			list = append(list, children...)
		}
	}
	return list, nil
}