// FromGGPK builds afs structure from ggpk file func FromGGPK(f *os.File) (root *Directory, err error) { // test if we can seek, also ensure we are at very beginning of file if _, err = f.Seek(0, 0); err != nil { return } // read GGPK sign rootNode, err := record.GGG(f) if err != nil { return } if rootNode.Header.Tag != "GGPK" { return root, errors.New("This file is not GGPK file") } // find root directory nodes, err := rootNode.Children(f) if err != nil { log.Fatalf("Cannot read root nodes from ggpk: %s", err) } var rootDirNode record.RecordHeader for _, n := range nodes { if n.Tag == "PDIR" { rootDirNode = n break } } if rootDirNode.Tag != "PDIR" { return root, errors.New("Cannot find root directory from ggpk") } // create afs root rootdir, err := record.ReadDir(f, rootDirNode) if err != nil { return } if rootdir.Name != "" { return root, errors.New("root dir name is not empty") } root = FromDirectoryRecord(rootDirNode, rootdir, 0) root.Path = "/" for _, e := range rootdir.Entries { if err = doEntry(f, e, root); err != nil { return } } sort.Sort(ByName(root.Files)) sort.Sort(ByPath(root.Subfolders)) return }
func doDir(h record.RecordHeader, f *os.File, path string) []byte { r, err := record.ReadDir(f, h) if err != nil { if path == "" { path = "ROOT" } fatalf("Cannot read directory in %s: %s", path, err) } fn := path + r.Name + "/" data := make([]byte, 0) for _, e := range r.Entries { data = append(data, doEntry(e, f, fn)...) } b(fn, r.Digest) c(r.Digest, data) return r.Digest }
func doDir(f *os.File, h record.RecordHeader, cur *Directory, t uint32) error { dir, err := record.ReadDir(f, h) if err != nil { return err } me := FromDirectoryRecord(h, dir, t) me.Path = cur.Path + me.Name + "/" cur.Subfolders = append(cur.Subfolders, me) for _, e := range dir.Entries { if err := doEntry(f, e, me); err != nil { return err } } sort.Sort(ByName(me.Files)) sort.Sort(ByPath(me.Subfolders)) return nil }