{"id":15563112,"url":"https://github.com/dsoprea/go-ext4","last_synced_at":"2025-10-07T11:31:00.530Z","repository":{"id":66219008,"uuid":"149095844","full_name":"dsoprea/go-ext4","owner":"dsoprea","description":"A pure Go implementation of an ext4 reader with journaling support that does not require the kernel nor privileged access.","archived":false,"fork":false,"pushed_at":"2024-02-06T22:41:58.000Z","size":1030,"stargazers_count":46,"open_issues_count":5,"forks_count":10,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-05T17:51:41.740Z","etag":null,"topics":["ext4","ext4-filesystem","go","golang"],"latest_commit_sha":null,"homepage":"https://godoc.org/github.com/dsoprea/go-ext4","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dsoprea.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-17T08:48:48.000Z","updated_at":"2024-12-26T19:40:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"d77cf6d2-2281-41a1-b418-baecbf22e2c0","html_url":"https://github.com/dsoprea/go-ext4","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsoprea%2Fgo-ext4","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsoprea%2Fgo-ext4/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsoprea%2Fgo-ext4/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsoprea%2Fgo-ext4/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dsoprea","download_url":"https://codeload.github.com/dsoprea/go-ext4/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235621547,"owners_count":19019520,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ext4","ext4-filesystem","go","golang"],"created_at":"2024-10-02T16:18:27.604Z","updated_at":"2025-10-07T11:30:59.561Z","avatar_url":"https://github.com/dsoprea.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/dsoprea/go-ext4.svg?branch=master)](https://travis-ci.org/dsoprea/go-ext4)\n[![Coverage Status](https://coveralls.io/repos/github/dsoprea/go-ext4/badge.svg?branch=master)](https://coveralls.io/github/dsoprea/go-ext4?branch=master)\n[![GoDoc](https://godoc.org/github.com/dsoprea/go-ext4?status.svg)](https://godoc.org/github.com/dsoprea/go-ext4)\n\n## Overview\n\nThis package allows you to browse an *ext4* filesystem directly. It does not use FUSE or touch the kernel, so no privileges are required.\n\nThis package also exposes the data in the journal (if one is available).\n\n\n## Example\n\nRecursively walk all of the files in the filesystem:\n\n```\ninodeNumber := InodeRootDirectory\n\nfilepath := path.Join(assetsPath, \"hierarchy_32.ext4\")\n\nf, err := os.Open(filepath)\nlog.PanicIf(err)\n\ndefer f.Close()\n\n_, err = f.Seek(Superblock0Offset, io.SeekStart)\nlog.PanicIf(err)\n\nsb, err := NewSuperblockWithReader(f)\nlog.PanicIf(err)\n\nbgdl, err := NewBlockGroupDescriptorListWithReadSeeker(f, sb)\nlog.PanicIf(err)\n\nbgd, err := bgdl.GetWithAbsoluteInode(inodeNumber)\nlog.PanicIf(err)\n\ndw, err := NewDirectoryWalk(f, bgd, inodeNumber)\nlog.PanicIf(err)\n\nallEntries := make([]string, 0)\n\nfor {\n\tfullPath, de, err := dw.Next()\n\tif err == io.EOF {\n\t\tbreak\n\t} else if err != nil {\n\t\tlog.Panic(err)\n\t}\n\n\tdescription := fmt.Sprintf(\"%s: %s\", fullPath, de.String())\n\tallEntries = append(allEntries, description)\n}\n\nsort.Strings(allEntries)\n\nfor _, entryDescription := range allEntries {\n\tfmt.Println(entryDescription)\n}\n\n// Output:\n//\n// directory1/fortune1: DirectoryEntry\u003cNAME=[fortune1] INODE=(15) TYPE=[regular]-(1)\u003e\n// directory1/fortune2: DirectoryEntry\u003cNAME=[fortune2] INODE=(14) TYPE=[regular]-(1)\u003e\n// directory1/fortune5: DirectoryEntry\u003cNAME=[fortune5] INODE=(20) TYPE=[regular]-(1)\u003e\n// directory1/fortune6: DirectoryEntry\u003cNAME=[fortune6] INODE=(21) TYPE=[regular]-(1)\u003e\n// directory1/subdirectory1/fortune3: DirectoryEntry\u003cNAME=[fortune3] INODE=(17) TYPE=[regular]-(1)\u003e\n// directory1/subdirectory1/fortune4: DirectoryEntry\u003cNAME=[fortune4] INODE=(18) TYPE=[regular]-(1)\u003e\n// directory1/subdirectory1: DirectoryEntry\u003cNAME=[subdirectory1] INODE=(16) TYPE=[directory]-(2)\u003e\n// directory1/subdirectory2/fortune7: DirectoryEntry\u003cNAME=[fortune7] INODE=(22) TYPE=[regular]-(1)\u003e\n// directory1/subdirectory2/fortune8: DirectoryEntry\u003cNAME=[fortune8] INODE=(23) TYPE=[regular]-(1)\u003e\n// directory1/subdirectory2: DirectoryEntry\u003cNAME=[subdirectory2] INODE=(19) TYPE=[directory]-(2)\u003e\n// directory1: DirectoryEntry\u003cNAME=[directory1] INODE=(13) TYPE=[directory]-(2)\u003e\n// directory2/fortune10: DirectoryEntry\u003cNAME=[fortune10] INODE=(26) TYPE=[regular]-(1)\u003e\n// directory2/fortune9: DirectoryEntry\u003cNAME=[fortune9] INODE=(25) TYPE=[regular]-(1)\u003e\n// directory2: DirectoryEntry\u003cNAME=[directory2] INODE=(24) TYPE=[directory]-(2)\u003e\n// lost+found: DirectoryEntry\u003cNAME=[lost+found] INODE=(11) TYPE=[directory]-(2)\u003e\n// thejungle.txt: DirectoryEntry\u003cNAME=[thejungle.txt] INODE=(12) TYPE=[regular]-(1)\u003e\n```\n\nThis example and others are documented [here](https://godoc.org/github.com/dsoprea/go-ext4#pkg-examples).\n\n\n## Notes\n\n- Modern filesystems are supported, including both 32-bit and 64-bit addressing. Obscure filesystem options may not be compatible. See the [compatibility assertions](https://github.com/dsoprea/go-ext4/blob/master/superblock.go) in `NewSuperblockWithReader`.\n  - 64-bit addressing should be fine, as the high addressing should likely be zero when 64-bit addressing is turned-off (which is primarily what our unit-tests test with). However, the available documentation is limited on the subject. It's specifically not clear which of the various high/low addresses are affected by the 64-bit mode.\n\n\n## To Do\n\n- Finish implementing checksum calculation and validation. Currently all checksums are readable but with no additional functionality.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsoprea%2Fgo-ext4","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdsoprea%2Fgo-ext4","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsoprea%2Fgo-ext4/lists"}