// Unmarshal parses an identity. func Unmarshal(in []byte) (*Identity, error) { buf := sbuf.NewBufferFrom(in) id := &Identity{ private: new([ed25519.PrivateKeySize]byte), public: new([ed25519.PublicKeySize]byte), } _, err := io.ReadFull(buf, id.private[:]) if err != nil { return nil, ErrInvalidIdentity } _, err = io.ReadFull(buf, id.public[:]) if err != nil { return nil, ErrInvalidIdentity } if (buf.Len() % ed25519.PublicKeySize) != 0 { return nil, ErrInvalidIdentity } for { if buf.Len() == 0 { break } peer := new([ed25519.PublicKeySize]byte) io.ReadFull(buf, peer[:]) id.peers = append(id.peers, peer) } return id, nil }
// UnpackFiles decompresses and unarchives the gzipped tarball passed in // as data and uncompresses it to the top-level directory given. If // unpack is false, only file names will be listed. func UnpackFiles(in []byte, top string, unpack bool) error { buf := sbuf.NewBufferFrom(in) zbuf, err := gzip.NewReader(buf) if err != nil { return err } defer zbuf.Close() tr := tar.NewReader(zbuf) for { hdr, err := tr.Next() if err == io.EOF { return nil } else if err != nil { return err } if Verbose || !unpack { fmt.Println(hdr.Name) } if !unpack { continue } filePath := filepath.Clean(filepath.Join(top, hdr.Name)) switch hdr.Typeflag { case tar.TypeReg, tar.TypeRegA: file, err := os.Create(filePath) if err != nil { return err } _, err = io.Copy(file, tr) if err != nil { return err } err = file.Chmod(os.FileMode(hdr.Mode)) if err != nil { return err } case tar.TypeDir: err = os.MkdirAll(filePath, os.FileMode(hdr.Mode)) if err != nil { return err } } } }