chore(i18n): finish translating code comments and scripts to English
CI / Format and clippy (push) Successful in 1m57s
CI / Dependency audit (push) Successful in 13s
CI / Check desktop app (Linux) (push) Successful in 3m54s
CI / Tests (Linux) (push) Failing after 7m25s
Release / Create release (push) Successful in 6s
Release / CLI (linux-aarch64) (push) Successful in 1m48s
Release / CLI (linux-x86_64) (push) Successful in 2m39s
Release / Desktop app (linux-aarch64) (push) Successful in 10m9s
Release / Desktop app (linux-x86_64) (push) Successful in 12m20s
Release / Desktop app (windows) (push) Successful in 7m32s
Release / Build latest.json (push) Successful in 5s

Completes the English-only standardization for code, comments, scripts
and CI templates (UI/CLI-facing strings stay bilingual pt-BR/en,
untouched). Covers the remaining crates/, apps/gui/ui/ and
apps/gui/src-tauri/ comments, .gitea/ workflow and template comments,
.githooks/ hooks, and the scripts/ source comments for the files
already renamed in a prior commit (check.sh, generate-logo.py,
install-hooks.sh).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VAyr8d7HuAdUGB6aA5xmDD
This commit is contained in:
Lucas RayanandClaude Sonnet 5 committed 2026-10-30 20:43:02 -03:00
1 parent da212e6926
commit 6328220c60
129 files changed
+1961 -1834

No files matched your search

+28 -28
View File
@@ -1,7 +1,7 @@
//! APFS (volumes sem cifragem): lê o contêiner, o mapa de objetos e a árvore de arquivos de cada
//! volume; arquivos apagados vêm de duas fontes: as árvores dos instantâneos (snapshots) e os nós
//! antigos da árvore (copy-on-write) que ainda estão no disco. Volumes cifrados (FileVault) são
//! detectados e deixados para a varredura por assinatura.
//! APFS (unencrypted volumes): parses the container, object map, and file system tree of each
//! volume; deleted files are recovered from two sources: snapshot trees and older copy-on-write
//! B-tree nodes still resident on disk. Encrypted volumes (FileVault) are detected and left for
//! signature carving unless unlocked.
use super::{make_found, merge_extents, Ctx, NewFound, VolumeScan};
use crate::source::{read_vec, Source};
@@ -32,13 +32,13 @@ const T_CIB: u32 = 7;
const T_CHECKPOINT_MAP: u32 = 0x0C;
const SUBTYPE_FSTREE: u32 = 0x0E;
// tipos de registro da árvore de arquivos
// filesystem B-tree record types
const R_SNAP_METADATA: u8 = 1;
const R_INODE: u8 = 3;
const R_FILE_EXTENT: u8 = 8;
const R_DIR_REC: u8 = 9;
/// Soma de verificação Fletcher-64 do APFS (cobre o bloco menos os 8 bytes iniciais).
/// APFS Fletcher-64 checksum (covers the block excluding the leading 8 bytes).
pub fn fletcher64(data: &[u8]) -> u64 {
let (mut s1, mut s2) = (0u64, 0u64);
for w in data.chunks_exact(4) {
@@ -60,7 +60,7 @@ struct Apfs<'a> {
struct BNode {
flags: u16,
level: u16,
/// (chave, valor) por entrada
/// `(key, value)` slice pair for each node entry
entries: Vec<(Vec<u8>, Vec<u8>)>,
oid: u64,
xid: u64,
@@ -124,7 +124,7 @@ impl<'a> Apfs<'a> {
})
}
/// Todas as entradas de uma árvore física (mapa de objetos): filhos são endereços físicos.
/// Collects all entries from a physical B-tree (object map): child pointers are physical block addresses.
fn walk_physical(
&self,
root: u64,
@@ -156,7 +156,7 @@ impl<'a> Apfs<'a> {
}
}
/// Mapa de objetos: oid -> [(xid, paddr)] ordenado por xid.
/// Object map: `oid -> [(xid, paddr)]` sorted by transaction ID (`xid`).
fn omap(&self, omap_paddr: u64) -> HashMap<u64, Vec<(u64, u64)>> {
let mut m: HashMap<u64, Vec<(u64, u64)>> = HashMap::new();
let Some(ob) = self.checked_block(omap_paddr) else {
@@ -174,7 +174,7 @@ impl<'a> Apfs<'a> {
m
}
/// Endereço físico de um objeto ephemeral (spaceman), achado no mapa de checkpoint mais novo.
/// Physical block address of an ephemeral object (spaceman) from the latest checkpoint map.
fn ephemeral_paddr(&self, nx: &[u8], oid: u64) -> Option<u64> {
let desc_blocks = le32(nx, 104) as u64;
let desc_base = le64(nx, 112);
@@ -203,8 +203,8 @@ impl<'a> Apfs<'a> {
best.map(|(_, p)| p)
}
/// Mapa de espaço livre do contêiner: percorre o spaceman, os chunk-info blocks e os bitmaps
/// (bit 1 = bloco em uso).
/// Container free-space map: walks the spaceman, chunk-info blocks (CIBs), and allocation bitmaps
/// (bit 1 = allocated block).
fn free_map(&self, nx: &[u8]) -> Option<Vec<Extent>> {
let sm_oid = le64(nx, 152);
if sm_oid == 0 {
@@ -214,7 +214,7 @@ impl<'a> Apfs<'a> {
if le32(&sm, 24) & OBJ_TYPE_MASK != T_SPACEMAN {
return None;
}
// Com CABs (contêineres grandes) os endereços dos CIBs não ficam no spaceman.
// With CABs (large containers), CIB addresses live in chunk-info address blocks rather than inline in the spaceman.
if le32(&sm, 68) != 0 {
return None;
}
@@ -289,7 +289,7 @@ fn lookup(m: &HashMap<u64, Vec<(u64, u64)>>, oid: u64, max_xid: u64) -> Option<u
.map(|(_, p)| *p)
}
// ---------------------------------------------------------------- registros
// ---------------------------------------------------------------- records
#[derive(Clone, Debug, Default)]
struct Inode {
@@ -308,7 +308,7 @@ struct Inode {
#[derive(Clone, Debug, Default)]
struct FileRec {
inode: Inode,
names: BTreeMap<u64, String>, // pai -> nome
names: BTreeMap<u64, String>, // parent_id -> name
}
type Files = HashMap<u64, FileRec>;
@@ -327,7 +327,7 @@ fn add_record(files: &mut Files, extents: &mut Extents, k: &[u8], v: &[u8]) {
let mut ino = Inode {
parent: le64(v, 0),
private_id: le64(v, 8),
ctime: ns(le64(v, 16)), // criação
ctime: ns(le64(v, 16)), // creation timestamp
mtime: ns(le64(v, 24)),
atime: ns(le64(v, 40)),
mode: le16(v, 80),
@@ -338,7 +338,7 @@ fn add_record(files: &mut Files, extents: &mut Extents, k: &[u8], v: &[u8]) {
let flags = le64(v, 48);
ino.compressed = le32(v, 68) & 0x20 != 0;
let _ = flags;
// campos estendidos
// xfields (extended fields)
let xf = &v[92..];
if xf.len() >= 4 {
let n = le16(xf, 0) as usize;
@@ -383,7 +383,7 @@ fn add_record(files: &mut Files, extents: &mut Extents, k: &[u8], v: &[u8]) {
}
impl Apfs<'_> {
/// Percorre a árvore de arquivos a partir de uma raiz virtual.
/// Walks the filesystem B-tree starting from a virtual root OID.
fn walk_fstree(
&self,
root_oid: u64,
@@ -484,7 +484,7 @@ fn open_container<'a>(src: &'a dyn Source, base: u64) -> Option<(Apfs<'a>, Vec<u
bs,
blocks,
};
// O superbloco mais recente está na área de descritores de checkpoint.
// Find the latest valid container superblock in the checkpoint descriptor area.
let desc_blocks = le32(&b0, 104) as u64;
let desc_base = le64(&b0, 112);
let mut best = b0.clone();
@@ -548,7 +548,7 @@ pub fn scan(ctx: &mut Ctx, base: u64, part_len: u64) -> VolumeScan {
fn scan_volume(ctx: &mut Ctx, a: &Apfs, v: &Volume, allow_stale_scan: bool, res: &mut VolumeScan) {
let omap = a.omap(v.omap_paddr);
let current_xid = u64::MAX;
// Árvore atual.
// Current live filesystem tree.
let mut live: Files = HashMap::new();
let mut live_ext: Extents = HashMap::new();
let mut live_nodes: HashSet<u64> = HashSet::new();
@@ -556,7 +556,7 @@ fn scan_volume(ctx: &mut Ctx, a: &Apfs, v: &Volume, allow_stale_scan: bool, res:
live_nodes.insert(node);
add_record(&mut live, &mut live_ext, k, val);
});
// Instantâneos.
// Volume snapshots.
let mut stale: Files = HashMap::new();
let mut stale_ext: Extents = HashMap::new();
if v.snap_tree_oid != 0 {
@@ -583,7 +583,7 @@ fn scan_volume(ctx: &mut Ctx, a: &Apfs, v: &Volume, allow_stale_scan: bool, res:
}
} else {
for (_, val) in &n.entries {
// árvore de metadados de snapshot: filhos físicos ou virtuais
// snapshot metadata tree: physical or virtual child references
let c = le64(val, 0);
stack.push(lookup(&omap, c, current_xid).unwrap_or(c));
}
@@ -602,7 +602,7 @@ fn scan_volume(ctx: &mut Ctx, a: &Apfs, v: &Volume, allow_stale_scan: bool, res:
}
}
}
// Nós antigos da árvore de arquivos.
// Older evicted copy-on-write filesystem tree leaf nodes.
if allow_stale_scan {
let total = a.blocks;
for p in 0..total {
@@ -631,7 +631,7 @@ fn scan_volume(ctx: &mut Ctx, a: &Apfs, v: &Volume, allow_stale_scan: bool, res:
}
}
}
// Arquivos que só existem nas versões antigas.
// Files present only in older tree versions or snapshots.
let mut ids: Vec<&u64> = stale.keys().collect();
ids.sort();
let mut seen_first: HashSet<u64> = HashSet::new();
@@ -648,9 +648,9 @@ fn scan_volume(ctx: &mut Ctx, a: &Apfs, v: &Volume, allow_stale_scan: bool, res:
continue;
};
if ex.values().any(|e| e.2 != 0) {
continue; // extensão cifrada
continue; // encrypted extent
}
// nome e pasta: da entrada de diretório, senão do próprio inode
// file name and parent folder: prefer directory entry, fallback to inode xfield
let (name, parent) = match rec.names.iter().next() {
Some((p, n)) => (n.clone(), *p),
None => match &ino.name {
@@ -726,13 +726,13 @@ fn scan_volume(ctx: &mut Ctx, a: &Apfs, v: &Volume, allow_stale_scan: bool, res:
let _ = res;
}
/// Trechos livres (absolutos) do contêiner, segundo o spaceman.
/// Absolute free byte extents in the container according to the spaceman.
pub fn free_extents(src: &dyn Source, base: u64) -> Option<Vec<Extent>> {
let (a, nx) = open_container(src, base)?;
a.free_map(&nx)
}
/// Arquivos e pastas atuais do primeiro volume sem cifragem (caminho, tamanho, é pasta).
/// Live files and folders in the first unencrypted volume `(path, size, is_dir)`.
pub fn live_paths(src: &dyn Source, base: u64) -> Vec<(String, u64, bool)> {
let Some((a, nx)) = open_container(src, base) else {
return vec![];