private static void assignPathsRecursively(SquashFragmentTable fragTable,
			SquashDirectoryTable dirTable, SquashDirectoryTableEntry entry, SquashInode[] inodes,
			GFile parentDir, FileSystemIndexHelper<SquashedFile> fsih, TaskMonitor monitor)
			throws CancelledException, IOException {

		// Check if the user cancelled the load
		monitor.checkCancelled();

		// Validate the inode number of the current entry
		if (entry == null || entry.getInodeNumber() < 1 || entry.getInodeNumber() > inodes.length) {
			throw new IOException(
				"Entry found with invalid inode number: " + entry.getInodeNumber());
		}

		// Get the inode for the current entry
		SquashInode inode = inodes[entry.getInodeNumber()];

		// If the inode is a directory, recurse downward. Otherwise, just store the file
		if (inode.isDir()) {

			// Treat as directory inode
			SquashBasicDirectoryInode dirInode = (SquashBasicDirectoryInode) inode;
			// Create and store a "file" representing the current directory
			SquashedFile squashedDirFile = new SquashedFile(dirInode, null);
			GFile dirGFile = fsih.storeFileWithParent(entry.getFileName(), parentDir,
				inode.getNumber(), true, -1, squashedDirFile);

			// Get the directory headers for the current inode and process each entry within them
			List<SquashDirectoryTableHeader> headers = dirTable.getHeaders(dirInode);
			for (SquashDirectoryTableHeader header : headers) {

				// For each sub-directory, recurse downward and add each file/directory encountered
				List<SquashDirectoryTableEntry> entries = header.getEntries();
				for (SquashDirectoryTableEntry currentEntry : entries) {
					assignPathsRecursively(fragTable, dirTable, currentEntry, inodes, dirGFile,
						fsih, monitor);
				}
			}
		}
		else if (inode.isFile()) {

			// Treat as file inode
			SquashBasicFileInode fileInode = (SquashBasicFileInode) inode;

			SquashFragment fragment = fragTable.getFragment(fileInode.getFragmentIndex());

			// Store the current file
			fsih.storeFileWithParent(entry.getFileName(), parentDir, fileInode.getNumber(), false,
				fileInode.getFileSize(), new SquashedFile(fileInode, fragment));
		}
		else if (inode.isSymLink()) {

			// Treat as symbolic link inode
			SquashSymlinkInode symLinkInode = (SquashSymlinkInode) inode;

			fsih.storeSymlinkWithParent(entry.getFileName(), parentDir, symLinkInode.getNumber(),
				symLinkInode.getPath(), 0, new SquashedFile(symLinkInode, null));
		}
		else {
			Msg.info(SquashUtils.class,
				"Inode #" + inode.getNumber() + " is not a file or directory. Skipping...");
		}
	}
Recursively assign paths to each of the inodes
@param dirTable The processed directory table of the archive
@param entry The directory table entry currently being processed
@param inodes An array of inodes within the archive
@param parentDir The parent of the current entry
@param fsih An index helper
@param monitor Monitor to allow the user to cancel the load
@throws CancelledException Archive load was cancelled
@throws IOException Entry found with an invalid inode number
Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/squashfs/SquashUtils.java