// uncompressGUI uncompresses the tar.bz2 Juju GUI archive provided in r.
// The sourceDir directory included in the tar archive is copied to targetDir.
320635
func uncompressGUI(r io.Reader, sourceDir, targetDir string) error {
	tempDir, err := ioutil.TempDir(filepath.Join(targetDir, ".."), "gui")
	if err != nil {
		return errors.Annotate(err, "cannot create Juju GUI temporary directory")
	}
	defer os.Remove(tempDir)
	tr := tar.NewReader(bzip2.NewReader(r))
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			break
		}
		if err != nil {
			return errors.Annotate(err, "cannot parse archive")
		}
		if hdr.Name != sourceDir && !strings.HasPrefix(hdr.Name, sourceDir+"/") {
			continue
		}
		path := filepath.Join(tempDir, hdr.Name)
		info := hdr.FileInfo()
		if info.IsDir() {
			if err := os.MkdirAll(path, info.Mode()); err != nil {
				return errors.Annotate(err, "cannot create directory")
			}
			continue
		}
		f, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())
		if err != nil {
			return errors.Annotate(err, "cannot open file")
		}
		defer f.Close()
		if _, err := io.Copy(f, tr); err != nil {
			return errors.Annotate(err, "cannot copy file content")
		}
	}
	if err := os.Rename(filepath.Join(tempDir, sourceDir), targetDir); err != nil {
		return errors.Annotate(err, "cannot rename Juju GUI root directory")
	}
	return nil
}
101191
func (t *Tar) Unarchive(source, destination string) error {
	if !fileExists(destination) && t.MkdirAll {
		err := mkdir(destination, 0755)
		if err != nil {
			return fmt.Errorf("preparing destination: %v", err)
		}
	}

	// if the files in the archive do not all share a common
	// root, then make sure we extract to a single subfolder
	// rather than potentially littering the destination...
	if t.ImplicitTopLevelFolder {
		var err error
		destination, err = t.addTopLevelFolder(source, destination)
		if err != nil {
			return fmt.Errorf("scanning source archive: %v", err)
		}
	}

	file, err := os.Open(source)
	if err != nil {
		return fmt.Errorf("opening source archive: %v", err)
	}
	defer file.Close()

	err = t.Open(file, 0)
	if err != nil {
		return fmt.Errorf("opening tar archive for reading: %v", err)
	}
	defer t.Close()

	for {
		err := t.untarNext(destination)
		if err == io.EOF {
			break
		}
		if err != nil {
			if t.ContinueOnError {
				log.Printf("[ERROR] Reading file in tar archive: %v", err)
				continue
			}
			return fmt.Errorf("reading file in tar archive: %v", err)
		}
	}

	return nil
}
1039602
func (tsz *TarSz) Unarchive(source, destination string) error {
	tsz.wrapReader()
	return tsz.Tar.Unarchive(source, destination)
}
165324
func ReadGUIArchive(dataDir string) (*coretools.GUIArchive, error) {
	dir := SharedGUIDir(dataDir)
	toolsData, err := ioutil.ReadFile(path.Join(dir, guiArchiveFile))
	if err != nil {
		if os.IsNotExist(err) {
			return nil, errors.NotFoundf("GUI metadata")
		}
		return nil, fmt.Errorf("cannot read GUI metadata in directory %q: %v", dir, err)
	}
	var gui coretools.GUIArchive
	if err := json.Unmarshal(toolsData, &gui); err != nil {
		return nil, fmt.Errorf("invalid GUI metadata in directory %q: %v", dir, err)
	}
	return &gui, nil
}
468301
func (archiver *Archiver) UntarPath(src, dst string) error {
	tarArchive, err := archiver.SrcDriver.Open(src)
	if err != nil {
		return err
	}
	defer tarArchive.Close()
	options := &archive.TarOptions{
		UIDMaps: archiver.IDMapping.UIDs(),
		GIDMaps: archiver.IDMapping.GIDs(),
	}
	return archiver.Untar(tarArchive, dst, options)
}
13710
func Unpack(decompressedArchive io.Reader, dest string, options *TarOptions) error {
	tr := tar.NewReader(decompressedArchive)
	trBuf := pools.BufioReader32KPool.Get(nil)
	defer pools.BufioReader32KPool.Put(trBuf)

	var dirs []*tar.Header
	idMapping := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
	rootIDs := idMapping.RootPair()
	whiteoutConverter := getWhiteoutConverter(options.WhiteoutFormat, options.InUserNS)

	// Iterate through the files in the archive.
loop:
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			// end of tar archive
			break
		}
		if err != nil {
			return err
		}

		// Normalize name, for safety and for a simple is-root check
		// This keeps "../" as-is, but normalizes "/../" to "/". Or Windows:
		// This keeps "..\" as-is, but normalizes "\..\" to "\".
		hdr.Name = filepath.Clean(hdr.Name)

		for _, exclude := range options.ExcludePatterns {
			if strings.HasPrefix(hdr.Name, exclude) {
				continue loop
			}
		}

		// After calling filepath.Clean(hdr.Name) above, hdr.Name will now be in
		// the filepath format for the OS on which the daemon is running. Hence
		// the check for a slash-suffix MUST be done in an OS-agnostic way.
		if !strings.HasSuffix(hdr.Name, string(os.PathSeparator)) {
			// Not the root directory, ensure that the parent directory exists
			parent := filepath.Dir(hdr.Name)
			parentPath := filepath.Join(dest, parent)
			if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
				err = idtools.MkdirAllAndChownNew(parentPath, 0777, rootIDs)
				if err != nil {
					return err
				}
			}
		}

		path := filepath.Join(dest, hdr.Name)
		rel, err := filepath.Rel(dest, path)
		if err != nil {
			return err
		}
		if strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
			return breakoutError(fmt.Errorf("%q is outside of %q", hdr.Name, dest))
		}

		// If path exits we almost always just want to remove and replace it
		// The only exception is when it is a directory *and* the file from
		// the layer is also a directory. Then we want to merge them (i.e.
		// just apply the metadata from the layer).
		if fi, err := os.Lstat(path); err == nil {
			if options.NoOverwriteDirNonDir && fi.IsDir() && hdr.Typeflag != tar.TypeDir {
				// If NoOverwriteDirNonDir is true then we cannot replace
				// an existing directory with a non-directory from the archive.
				return fmt.Errorf("cannot overwrite directory %q with non-directory %q", path, dest)
			}

			if options.NoOverwriteDirNonDir && !fi.IsDir() && hdr.Typeflag == tar.TypeDir {
				// If NoOverwriteDirNonDir is true then we cannot replace
				// an existing non-directory with a directory from the archive.
				return fmt.Errorf("cannot overwrite non-directory %q with directory %q", path, dest)
			}

			if fi.IsDir() && hdr.Name == "." {
				continue
			}

			if !(fi.IsDir() && hdr.Typeflag == tar.TypeDir) {
				if err := os.RemoveAll(path); err != nil {
					return err
				}
			}
		}
		trBuf.Reset(tr)

		if err := remapIDs(idMapping, hdr); err != nil {
			return err
		}

		if whiteoutConverter != nil {
			writeFile, err := whiteoutConverter.ConvertRead(hdr, path)
			if err != nil {
				return err
			}
			if !writeFile {
				continue
			}
		}

		if err := createTarFile(path, dest, hdr, trBuf, !options.NoLchown, options.ChownOpts, options.InUserNS); err != nil {
			return err
		}

		// Directory mtimes must be handled at the end to avoid further
		// file creation in them to modify the directory mtime
		if hdr.Typeflag == tar.TypeDir {
			dirs = append(dirs, hdr)
		}
	}

	for _, hdr := range dirs {
		path := filepath.Join(dest, hdr.Name)

		if err := system.Chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil {
			return err
		}
	}
	return nil
}
558942
func (z *Dec) GobDecode(buf []byte) error {
	if len(buf) == 0 {
		return fmt.Errorf("Dec.GobDecode: no data")
	}
	b := buf[len(buf)-1]
	if b != decGobVersion {
		return fmt.Errorf("Dec.GobDecode: encoding version %d not supported", b)
	}
	l := len(buf) - scaleSize - 1
	err := z.UnscaledBig().GobDecode(buf[:l])
	if err != nil {
		return err
	}
	z.SetScale(scale(buf[l : l+scaleSize]))
	return nil
}
1023088
func UnzipPath(sourcePath string, log Log) (string, error) {
	unzipPath := fmt.Sprintf("%s.unzipped", sourcePath)
	err := unzipOver(sourcePath, unzipPath, log)
	if err != nil {
		return "", err
	}
	return unzipPath, nil
}
1322583
func (tbz2 *TarBz2) Unarchive(source, destination string) error {
	tbz2.wrapReader()
	return tbz2.Tar.Unarchive(source, destination)
}
536609
func (p *PublicKey) SerializeUncompressed() []byte {
	b := make([]byte, 0, PubKeyBytesLenUncompressed)
	b = append(b, pubkeyUncompressed)
	b = paddedAppend(32, b, p.X.Bytes())
	return paddedAppend(32, b, p.Y.Bytes())
}
1325599
func (p *Profile) WriteUncompressed(w io.Writer) error {
	_, err := w.Write(serialize(p))
	return err
}
1239933
func untarHandler(tarArchive io.Reader, dest string, options *TarOptions, decompress bool) error {
	if tarArchive == nil {
		return fmt.Errorf("Empty archive")
	}
	dest = filepath.Clean(dest)
	if options == nil {
		options = &TarOptions{}
	}
	if options.ExcludePatterns == nil {
		options.ExcludePatterns = []string{}
	}

	r := tarArchive
	if decompress {
		decompressedArchive, err := DecompressStream(tarArchive)
		if err != nil {
			return err
		}
		defer decompressedArchive.Close()
		r = decompressedArchive
	}

	return Unpack(r, dest, options)
}
162776
func (f *Fetcher) uncompress(r io.Reader, opts FetchOptions) (io.ReadCloser, error) {
	switch opts.Compression {
	case "":
		return ioutil.NopCloser(r), nil
	case "gzip":
		return gzip.NewReader(r)
	default:
		return nil, configErrors.ErrCompressionInvalid
	}
}
264306
func (e *Engine) Unbox(ctx context.Context, ct, nonce []byte,
	privKP *EncryptionKeyPair, pubKey []byte) (*secure.Secret, error) {

	privKey, err := e.Unseal(ctx, privKP.Private, privKP.PNonce)
	if err != nil {
		return nil, err
	}
	defer privKey.Destroy()

	nonceb := [24]byte{}
	copy(nonceb[:], nonce)

	// Get a pointer to the underlying private key in memory
	privkb := (*[32]byte)(unsafe.Pointer(&privKey.Buffer()[0]))

	pubkb := [32]byte{}
	copy(pubkb[:], pubKey)

	err = ctxutil.ErrIfDone(ctx)
	if err != nil {
		return nil, err
	}

	pt, success := box.Open([]byte{}, ct, &nonceb, &pubkb, privkb)
	if !success {
		return nil, errors.New("Failed to decrypt ciphertext")
	}

	return e.guard.Secret(pt)
}
754806
func (bz *Bz2) Compress(in io.Reader, out io.Writer) error {
	w, err := bzip2.NewWriter(out, &bzip2.WriterConfig{
		Level: bz.CompressionLevel,
	})
	if err != nil {
		return err
	}
	defer w.Close()
	_, err = io.Copy(w, in)
	return err
}
10237
func NewGui(mode OutputMode) (*Gui, error) {
	if err := termbox.Init(); err != nil {
		return nil, err
	}

	g := &Gui{}

	g.outputMode = mode
	termbox.SetOutputMode(termbox.OutputMode(mode))

	g.tbEvents = make(chan termbox.Event, 20)
	g.userEvents = make(chan userEvent, 20)

	g.maxX, g.maxY = termbox.Size()

	g.BgColor, g.FgColor = ColorDefault, ColorDefault
	g.SelBgColor, g.SelFgColor = ColorDefault, ColorDefault

	return g, nil
}
29136
func CompressStream(dest io.Writer, compression Compression) (io.WriteCloser, error) {
	switch compression {
	case Uncompressed:
		return &writeCloserWrapper{dest, nil}, nil
	case Gzip:
		return gzip.NewWriter(dest), nil
	default:
		return nil, fmt.Errorf("unsupported compression format %s", (&compression).Extension())
	}
}