Example #1
0
func main() {

	bb := D.ReadN(os.Stdin, 256)

	fmt.Println("=== SECTOR ZERO ===\n")
	D.PrintRecords(D.Sector0, bb)
	fmt.Println("\n")

	rootInode := D.FindInt(D.Sector0, bb, "DD.DIR")
	PrintInode(rootInode, "/")
}
Example #2
0
func PrintInode(inode int, path string) {
	bb := ReadAtLen(inode*256, 256)

	fmt.Printf("\n========= INODE #%d %q =========\n\n", inode, path)
	D.PrintRecords(D.FileDescSector, bb)
	fmt.Println("\n")
	attrs := D.FindInt(D.FileDescSector, bb, "FD.ATT")
	size := D.FindInt(D.FileDescSector, bb, "FD.SIZ")

	var segments []Segment
	for i := 0; 16+5*i < 256-5+1; i++ {
		bb = ReadAtLen(inode*256+16+5*i, 256)
		at := D.FindInt(D.SegmentEntry, bb, "FDSL.A")
		segs := D.FindInt(D.SegmentEntry, bb, "FDSL.B")
		if segs == 0 {
			continue
		}

		// Grr. Some flawed disks let me this heuristic hack.
		if at > 1000000 || segs > 1000 {
			fmt.Printf("ERROR: FLAWED SEGMENT TABLE: %d %d\n", at, segs)
			break
		}

		segments = append(segments, Segment{at, segs})
		fmt.Printf("=== Segment %d ===\n", i)
		D.PrintRecords(D.SegmentEntry, bb)
	}
	fmt.Println("\n")

	if attrs&0x80 != 0 { // If is a DIR

		var subs []PairIS
		for _, p := range segments {
			fmt.Printf("=== Directory Segment at %d segs %d (inode %d path %q) ===\n", p.At, p.Segs, inode, path)

			if len(os.Args) > 1 {
				os.MkdirAll(FP.Join(os.Args[1], path), 0755)
			}

			segsize := p.Segs * 256
			if size < segsize {
				segsize, size = size, 0
			} else {
				size -= segsize
			}

			nth := 0
			for i := 0; i*32 < segsize; i++ {
				bb = ReadAtLen(p.At*256+i*32, 32)
				fd := D.FindInt(D.DirEntry, bb, "DIR.FD")
				if fd == 0 {
					continue
				}
				D.PrintRecords(D.DirEntry, bb)
				name := D.FindString(D.DirEntry, bb, "DIR.NM")
				// Grr. Some flawed disks led me to the "nth >= 2" heuristic hack.
				if name != "." && name != ".." && nth >= 2 {
					subName := path + "/" + name
					if path == "/" {
						subName = "/" + name
					}
					subs = append(subs, PairIS{fd, subName})
				}
				nth++
			}
		}
		for _, p := range subs {
			PrintInode(p.A, p.B)
		}

	} else { // IF is a FILE
		var contents []byte
		for _, p := range segments {
			fmt.Printf("=== File Segment at %d segs %d (inode %d path %q) ===\n", p.At, p.Segs, inode, path)

			segsize := p.Segs * 256
			if size < segsize {
				segsize, size = size, 0
			} else {
				size -= segsize
			}

			bb := ReadAtLen(p.At*256, segsize)
			contents = append(contents, bb...)
		}

		D.PrintModuleHeader(contents)

		if len(os.Args) > 1 {
			ioutil.WriteFile(FP.Join(os.Args[1], path), contents, 0666)
		}
	}
}