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

+35 -35
View File
@@ -1,10 +1,10 @@
//! ext2/3/4: arquivos apagados com nome, por três caminhos que se completam:
//! ext2/3/4: recovers deleted files with names via three complementary techniques:
//!
//! 1. inodes com `dtime` cujo mapa de extents ainda tem sobras legíveis;
//! 2. cópias antigas do inode guardadas no diário (jbd2), de antes da exclusão;
//! 3. entradas de diretório "escondidas" na folga do `rec_len` (dão o nome).
//! 1. deleted inodes (`dtime != 0`) whose extent tree or block pointers still have remnants;
//! 2. pre-deletion inode copies preserved in the jbd2 journal;
//! 3. unlinked directory entries hidden inside `rec_len` slack space (recovering filenames).
//!
//! Também devolve o mapa de blocos livres, para o carving varrer só o que está livre.
//! Also returns the free-block map so file carving only scans unallocated blocks.
use super::{make_found, merge_extents, Ctx, NewFound, VolumeScan};
use crate::signatures;
@@ -103,7 +103,7 @@ struct Ext<'a> {
journal_inum: u32,
}
/// Sequência de (bloco lógico, bloco físico, quantidade, não-inicializado).
/// Sequence of `(logical_block, physical_block, block_count, is_uninitialized)`.
type ExtentList = Vec<(u64, u64, u64, bool)>;
impl<'a> Ext<'a> {
@@ -201,7 +201,7 @@ impl<'a> Ext<'a> {
Inode::parse(&self.inode_bytes(ino)?)
}
/// Extents de uma árvore ext4 (raiz em `node`, 60 bytes ou um bloco).
/// Collects extents from an ext4 extent tree (`node` is the 60-byte `i_block` root or a block).
fn walk_extent_node(
&self,
node: &[u8],
@@ -248,7 +248,7 @@ impl<'a> Ext<'a> {
true
}
/// Blocos de um inode ext2/3 (mapa de blocos clássico).
/// Collects data blocks from an ext2/3 indirect block map.
fn block_map(&self, blk: &[u8; 60], max_blocks: u64) -> ExtentList {
let mut v: Vec<u64> = vec![];
let ptr = |i: usize| le32(blk, i * 4) as u64;
@@ -308,7 +308,7 @@ impl<'a> Ext<'a> {
out
}
/// Extents do arquivo (ordenados pelo bloco lógico), cortados em `size` bytes.
/// Returns file byte extents (ordered by logical block) truncated to `size` bytes.
fn file_extents(&self, ino: &Inode, size: u64) -> Vec<Extent> {
let need = size.div_ceil(self.bs);
let mut list: ExtentList = vec![];
@@ -351,7 +351,7 @@ impl<'a> Ext<'a> {
out
}
/// Mapa de blocos livres (bitmap), em extents absolutos.
/// Free-block map (from block bitmaps) as absolute byte extents.
fn free_map(&self, ctx: &Ctx) -> (Vec<Extent>, Vec<bool>) {
let mut free: Vec<Extent> = vec![];
let mut allocated_all: Vec<bool> = vec![];
@@ -418,7 +418,7 @@ struct DirEnt {
live: bool,
}
/// Lê as entradas de um bloco de diretório, inclusive as escondidas na folga.
/// Parses directory entries in a directory block, including unlinked entries in `rec_len` slack.
fn parse_dir_block(b: &[u8], max_ino: u64, out: &mut Vec<DirEnt>) {
let mut off = 0usize;
while off + 8 <= b.len() {
@@ -437,11 +437,11 @@ fn parse_dir_block(b: &[u8], max_ino: u64, out: &mut Vec<DirEnt>) {
live: true,
});
}
// Folga: entradas apagadas ficam coladas depois do fim "real" desta.
// Slack space: unlinked entries remain tucked right after the active entry's true length.
let mut s = off + if ino != 0 || nlen > 0 { real } else { 8 };
let end = off + rec;
if ino == 0 {
s = end; // entrada nula: sem folga confiável
s = end; // zeroed entry: no reliable slack to scan
}
while s + 8 <= end {
let dino = le32(b, s) as u64;
@@ -472,9 +472,9 @@ fn parse_dir_block(b: &[u8], max_ino: u64, out: &mut Vec<DirEnt>) {
}
struct Names {
/// inode -> (pasta, nome) de entradas vivas.
/// `inode -> (parent_dir, name)` from live directory entries.
live: HashMap<u64, (String, String)>,
/// inode -> (pasta, nome) de entradas apagadas (mais recente por varredura).
/// `inode -> (parent_dir, name)` from unlinked slack directory entries.
dead: HashMap<u64, (String, String)>,
}
@@ -531,9 +531,9 @@ fn walk_dirs(ext: &Ext, ctx: &Ctx) -> Names {
names
}
// ---------------------------------------------------------------- diário
// ---------------------------------------------------------------- journal
/// Cópias de inodes guardadas no diário: inode -> lista (ordem do diário) de registros brutos.
/// Inode copies found in the jbd2 journal: `inode_num -> Vec<raw_inode_bytes>` in journal order.
fn journal_inodes(ext: &Ext, ctx: &Ctx) -> HashMap<u64, Vec<Vec<u8>>> {
let mut out: HashMap<u64, Vec<Vec<u8>>> = HashMap::new();
if ext.journal_inum == 0 {
@@ -543,7 +543,7 @@ fn journal_inodes(ext: &Ext, ctx: &Ctx) -> HashMap<u64, Vec<Vec<u8>>> {
return out;
};
let jext = ext.file_extents(&jino, jino.size.min(1 << 30));
// Blocos físicos do diário em ordem lógica.
// Physical blocks of the journal in logical sequence.
let mut jblocks: Vec<u64> = vec![];
for e in &jext {
if e.sparse {
@@ -576,9 +576,9 @@ fn journal_inodes(ext: &Ext, ctx: &Ctx) -> HashMap<u64, Vec<Vec<u8>>> {
8 + if is64 { 4 } else { 0 }
};
let have_csum = csum_v2 || csum_v3;
// Tabela de inodes: faixa de blocos de cada grupo.
// Inode table block ranges for each block group.
let itable_blocks = (ext.ipg * ext.inode_size).div_ceil(ext.bs);
let mut tables: Vec<(u64, u64, u64)> = vec![]; // (início, fim, primeiro inode)
let mut tables: Vec<(u64, u64, u64)> = vec![]; // (start_block, end_block, first_inode_num)
for (g, gr) in ext.groups.iter().enumerate() {
tables.push((
gr.inode_table,
@@ -588,9 +588,9 @@ fn journal_inodes(ext: &Ext, ctx: &Ctx) -> HashMap<u64, Vec<Vec<u8>>> {
}
let n = jblocks.len();
let first = (be32(&jsb, 20) as usize).clamp(1, n);
let mut seqs: Vec<(u32, usize)> = vec![]; // (sequência, índice do descritor)
let mut seqs: Vec<(u32, usize)> = vec![]; // (commit_sequence, descriptor_index)
let mut idx = first;
// Varredura física: qualquer bloco que seja descritor, em ordem do diário.
// Scan journal blocks for descriptor blocks in sequence order.
while idx < n {
if idx % 4096 == 4095 && (ctx.cancelled)() {
break;
@@ -664,7 +664,7 @@ fn journal_inodes(ext: &Ext, ctx: &Ctx) -> HashMap<u64, Vec<Vec<u8>>> {
out
}
// -------------------------------------------------------------- varredura
// -------------------------------------------------------------- scan
pub fn scan(ctx: &mut Ctx, base: u64, part_len: u64) -> VolumeScan {
let mut res = VolumeScan::default();
@@ -680,7 +680,7 @@ pub fn scan(ctx: &mut Ctx, base: u64, part_len: u64) -> VolumeScan {
let mut emitted: HashSet<u64> = HashSet::new();
let mut seen_extents: HashSet<(u64, u64)> = HashSet::new();
// 1) Inodes apagados na tabela atual.
// 1) Deleted inodes in the current inode table.
let total = ext.groups.len() as u64;
for (g, gr) in ext.groups.iter().enumerate() {
if g % 16 == 15 && (ctx.cancelled)() {
@@ -711,7 +711,7 @@ pub fn scan(ctx: &mut Ctx, base: u64, part_len: u64) -> VolumeScan {
if !deleted || !ino.is_reg() {
continue;
}
// Melhor fonte: a cópia do diário anterior à exclusão; senão o que sobrou no inode.
// Best source: pre-deletion copy from the journal; fallback to remnants in the current inode.
let mut cand: Option<(Inode, &str)> = None;
if let Some(snaps) = journal.get(&ino_no) {
for raw in snaps.iter().rev() {
@@ -749,13 +749,13 @@ pub fn scan(ctx: &mut Ctx, base: u64, part_len: u64) -> VolumeScan {
}
}
// 2) Inodes que só existem no diário (liberados e já reaproveitados/zerados).
// 2) Inodes only preserved in the journal (already zeroed in the main inode table).
for (ino_no, snaps) in &journal {
if emitted.contains(ino_no) || names.live.contains_key(ino_no) || *ino_no < 11 {
continue;
}
let cur = ext.read_inode(*ino_no);
// Se o inode atual está vivo e é outro arquivo, não mexe.
// Skip if the inode is currently live in the filesystem.
if cur
.as_ref()
.map(|c| c.dtime == 0 && c.links > 0 && c.mode != 0)
@@ -805,7 +805,7 @@ fn emit_inode(
if ino.flags & EXT4_EXTENTS_FL != 0 {
let mut list: ExtentList = vec![];
if !ext.walk_extent_node(&ino.block, 5, &mut list, true) {
// Sobras de extent em inode truncado: cabeçalho zerado, registros ainda lá.
// Extent remnants in a truncated inode: header count was zeroed, but extent entries remain.
list = remnant_extents(ext, &ino.block);
}
if list.is_empty() {
@@ -834,7 +834,7 @@ fn emit_inode(
if !seen.insert((first.0, first.1)) {
return false;
}
// Quantos blocos de dados continuam livres? Reaproveitados => baixa confiança.
// Check how many data blocks are still unallocated; reallocated blocks lower confidence.
let mut reused = 0u64;
let mut total_blocks = 0u64;
for e in extents.iter().filter(|e| !e.sparse) {
@@ -859,7 +859,7 @@ fn emit_inode(
));
}
if estimated {
// Tamanho desconhecido: tenta achar o fim real pelo conteúdo.
// Unknown exact size (zeroed on deletion): try to refine size via format structure.
if let Some(h) = extents
.iter()
.find(|e| !e.sparse)
@@ -932,7 +932,7 @@ fn layout_from_list(ext: &Ext, list: &ExtentList, size: u64) -> Vec<Extent> {
out
}
/// Lê registros de extent deixados em i_block depois que o cabeçalho foi zerado.
/// Reads leftover extent records from `i_block` after `eh_entries` was zeroed on deletion.
fn remnant_extents(ext: &Ext, block: &[u8; 60]) -> ExtentList {
let mut out: ExtentList = vec![];
if le16(block, 0) != EXT_MAGIC || le16(block, 6) != 0 {
@@ -958,8 +958,8 @@ fn remnant_extents(ext: &Ext, block: &[u8; 60]) -> ExtentList {
out
}
/// Quão coerente é a estrutura do volume: fração das entradas de diretório cujo inode confere
/// com o tipo declarado. Serve para escolher parâmetros de RAID sem metadados.
/// Measures filesystem structural coherence: fraction of directory entries whose target inode
/// matches the declared file type. Used to score candidate metadata-less RAID parameters.
pub fn consistency_score(src: &dyn Source, base: u64) -> Option<f64> {
let ext = Ext::open(src, base)?;
let mut queue = vec![2u64];
@@ -988,8 +988,8 @@ pub fn consistency_score(src: &dyn Source, base: u64) -> Option<f64> {
o += ext.bs;
}
}
// A entrada "." de um diretório aponta para ele mesmo: só confere se inode e bloco
// vieram do lugar certo.
// A directory's "." entry points to itself: only matches if both the inode table and
// directory data block were mapped from the right RAID stripe.
dots_total += 1;
if ents.iter().any(|e| e.live && e.name == "." && e.ino == d) {
dots_ok += 1;