Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/uu/shred/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,33 @@ shred-after-help = Delete FILE(s) if --remove (-u) is specified. The default is
In addition, file system backups and remote mirrors may contain copies of
the file that cannot be removed, and that will allow a shredded file to be
recovered later.

# Error messages
shred-missing-file-operand = missing file operand
shred-invalid-number-of-passes = invalid number of passes: {$passes}
shred-cannot-open-random-source = cannot open random source: {$source}
shred-invalid-file-size = invalid file size: {$size}
shred-no-such-file-or-directory = {$file}: No such file or directory
shred-not-a-file = {$file}: Not a file

# Option help text
shred-force-help = change permissions to allow writing if necessary
shred-iterations-help = overwrite N times instead of the default (3)
shred-size-help = shred this many bytes (suffixes like K, M, G accepted)
shred-deallocate-help = deallocate and remove file after overwriting
shred-remove-help = like -u but give control on HOW to delete; See below
shred-verbose-help = show progress
shred-exact-help = do not round file sizes up to the next full block;
this is the default for non-regular files
shred-zero-help = add a final overwrite with zeros to hide shredding
shred-random-source-help = take random bytes from FILE

# Verbose messages
shred-removing = {$file}: removing
shred-removed = {$file}: removed
shred-renamed-to = renamed to
shred-pass-progress = {$file}: pass
shred-couldnt-rename = {$file}: Couldn't rename to {$new_name}: {$error}
shred-failed-to-open-for-writing = {$file}: failed to open for writing
shred-file-write-pass-failed = {$file}: File write pass failed
shred-failed-to-remove-file = {$file}: failed to remove file
66 changes: 66 additions & 0 deletions src/uu/shred/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
shred-about = Écrase les FICHIER(s) spécifiés de manière répétée, afin de rendre plus difficile
même pour du matériel de sondage très coûteux de récupérer les données.
shred-usage = shred [OPTION]... FICHIER...
shred-after-help = Supprime le ou les FICHIER(s) si --remove (-u) est spécifié. Par défaut, les fichiers
ne sont pas supprimés car il est courant d'opérer sur des fichiers de périphérique comme /dev/hda,
et ces fichiers ne doivent généralement pas être supprimés.

ATTENTION : Notez que shred repose sur une hypothèse très importante : que le système
de fichiers écrase les données sur place. C'est la façon traditionnelle de procéder, mais
de nombreuses conceptions de systèmes de fichiers modernes ne satisfont pas cette hypothèse.
Voici des exemples de systèmes de fichiers sur lesquels shred n'est pas efficace, ou n'est pas
garanti d'être efficace dans tous les modes de système de fichiers :

- systèmes de fichiers structurés en journal ou en log, tels que ceux fournis avec
AIX et Solaris (et JFS, ReiserFS, XFS, Ext3, etc.)

- systèmes de fichiers qui écrivent des données redondantes et continuent même si certaines écritures
échouent, tels que les systèmes de fichiers basés sur RAID

- systèmes de fichiers qui font des instantanés, tels que le serveur NFS de Network Appliance

- systèmes de fichiers qui mettent en cache dans des emplacements temporaires, tels que NFS
version 3 clients

- systèmes de fichiers compressés

Dans le cas des systèmes de fichiers ext3, la clause de non-responsabilité ci-dessus s'applique (et shred est
donc d'efficacité limitée) seulement en mode data=journal, qui journalise les données de fichier
en plus des métadonnées seulement. Dans les modes data=ordered (par défaut) et
data=writeback, shred fonctionne comme d'habitude. Les modes de journal Ext3 peuvent être changés
en ajoutant l'option data=something aux options de montage pour un système de fichiers particulier
dans le fichier /etc/fstab, comme documenté dans la page de manuel mount (`man mount`).

De plus, les sauvegardes de système de fichiers et les miroirs distants peuvent contenir des copies
du fichier qui ne peuvent pas être supprimées, et qui permettront à un fichier détruit d'être
récupéré plus tard.

# Messages d'erreur
shred-missing-file-operand = opérande de fichier manquant
shred-invalid-number-of-passes = nombre de passes invalide : {$passes}
shred-cannot-open-random-source = impossible d'ouvrir la source aléatoire : {$source}
shred-invalid-file-size = taille de fichier invalide : {$size}
shred-no-such-file-or-directory = {$file} : Aucun fichier ou répertoire de ce type
shred-not-a-file = {$file} : N'est pas un fichier

# Texte d'aide des options
shred-force-help = modifier les permissions pour permettre l'écriture si nécessaire
shred-iterations-help = écraser N fois au lieu de la valeur par défaut (3)
shred-size-help = détruire ce nombre d'octets (suffixes comme K, M, G acceptés)
shred-deallocate-help = désallouer et supprimer le fichier après écrasement
shred-remove-help = comme -u mais donne le contrôle sur COMMENT supprimer ; Voir ci-dessous
shred-verbose-help = afficher le progrès
shred-exact-help = ne pas arrondir les tailles de fichier au bloc complet suivant ;
c'est la valeur par défaut pour les fichiers non réguliers
shred-zero-help = ajouter un écrasement final avec des zéros pour cacher la destruction
shred-random-source-help = prendre des octets aléatoires du FICHIER

# Messages verbeux
shred-removing = {$file} : suppression
shred-removed = {$file} : supprimé
shred-renamed-to = renommé en
shred-pass-progress = {$file}: passage
shred-couldnt-rename = {$file} : Impossible de renommer en {$new_name} : {$error}
shred-failed-to-open-for-writing = {$file} : impossible d'ouvrir pour l'écriture
shred-file-write-pass-failed = {$file} : Échec du passage d'écriture de fichier
shred-failed-to-remove-file = {$file} : impossible de supprimer le fichier
127 changes: 90 additions & 37 deletions src/uu/shred/src/shred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// spell-checker:ignore (words) wipesync prefill
// spell-checker:ignore (words) wipesync prefill couldnt

use clap::{Arg, ArgAction, Command};
#[cfg(unix)]
Expand All @@ -20,7 +20,8 @@
use uucore::parser::shortcut_value_parser::ShortcutValueParser;
use uucore::{format_usage, show_error, show_if_err};

use uucore::locale::get_message;
use std::collections::HashMap;
use uucore::locale::{get_message, get_message_with_args};

pub mod options {
pub const FORCE: &str = "force";
Expand Down Expand Up @@ -242,7 +243,10 @@
let matches = uu_app().try_get_matches_from(args)?;

if !matches.contains_id(options::FILE) {
return Err(UUsageError::new(1, "missing file operand"));
return Err(UUsageError::new(
1,
get_message("shred-missing-file-operand"),
));

Check warning on line 249 in src/uu/shred/src/shred.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/shred/src/shred.rs#L246-L249

Added lines #L246 - L249 were not covered by tests
}

let iterations = match matches.get_one::<String>(options::ITERATIONS) {
Expand All @@ -251,7 +255,10 @@
Err(_) => {
return Err(USimpleError::new(
1,
format!("invalid number of passes: {}", s.quote()),
get_message_with_args(
"shred-invalid-number-of-passes",
HashMap::from([("passes".to_string(), s.quote().to_string())]),
),

Check warning on line 261 in src/uu/shred/src/shred.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/shred/src/shred.rs#L258-L261

Added lines #L258 - L261 were not covered by tests
));
}
},
Expand All @@ -262,7 +269,10 @@
Some(filepath) => RandomSource::Read(File::open(filepath).map_err(|_| {
USimpleError::new(
1,
format!("cannot open random source: {}", filepath.quote()),
get_message_with_args(
"shred-cannot-open-random-source",
HashMap::from([("source".to_string(), filepath.quote().to_string())]),
),

Check warning on line 275 in src/uu/shred/src/shred.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/shred/src/shred.rs#L272-L275

Added lines #L272 - L275 were not covered by tests
)
})?),
None => RandomSource::System,
Expand Down Expand Up @@ -321,14 +331,14 @@
Arg::new(options::FORCE)
.long(options::FORCE)
.short('f')
.help("change permissions to allow writing if necessary")
.help(get_message("shred-force-help"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::ITERATIONS)
.long(options::ITERATIONS)
.short('n')
.help("overwrite N times instead of the default (3)")
.help(get_message("shred-iterations-help"))
.value_name("NUMBER")
.default_value("3"),
)
Expand All @@ -337,12 +347,12 @@
.long(options::SIZE)
.short('s')
.value_name("N")
.help("shred this many bytes (suffixes like K, M, G accepted)"),
.help(get_message("shred-size-help")),
)
.arg(
Arg::new(options::WIPESYNC)
.short('u')
.help("deallocate and remove file after overwriting")
.help(get_message("shred-deallocate-help"))
.action(ArgAction::SetTrue),
)
.arg(
Expand All @@ -357,37 +367,34 @@
.num_args(0..=1)
.require_equals(true)
.default_missing_value(options::remove::WIPESYNC)
.help("like -u but give control on HOW to delete; See below")
.help(get_message("shred-remove-help"))
.action(ArgAction::Set),
)
.arg(
Arg::new(options::VERBOSE)
.long(options::VERBOSE)
.short('v')
.help("show progress")
.help(get_message("shred-verbose-help"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::EXACT)
.long(options::EXACT)
.short('x')
.help(
"do not round file sizes up to the next full block;\n\
this is the default for non-regular files",
)
.help(get_message("shred-exact-help"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::ZERO)
.long(options::ZERO)
.short('z')
.help("add a final overwrite with zeros to hide shredding")
.help(get_message("shred-zero-help"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::RANDOM_SOURCE)
.long(options::RANDOM_SOURCE)
.help("take random bytes from FILE")
.help(get_message("shred-random-source-help"))
.value_hint(clap::ValueHint::FilePath)
.action(ArgAction::Set),
)
Expand All @@ -405,7 +412,13 @@
.and_then(|size| parse_size_u64(size.as_str()).ok())
.or_else(|| {
if let Some(size) = size_str_opt {
show_error!("invalid file size: {}", size.quote());
show_error!(
"{}",
get_message_with_args(
"shred-invalid-file-size",
HashMap::from([("size".to_string(), size.quote().to_string())])

Check warning on line 419 in src/uu/shred/src/shred.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/shred/src/shred.rs#L415-L419

Added lines #L415 - L419 were not covered by tests
)
);
// TODO: replace with our error management
std::process::exit(1);
}
Expand Down Expand Up @@ -439,13 +452,19 @@
if !path.exists() {
return Err(USimpleError::new(
1,
format!("{}: No such file or directory", path.maybe_quote()),
get_message_with_args(
"shred-no-such-file-or-directory",
HashMap::from([("file".to_string(), path.maybe_quote().to_string())]),
),

Check warning on line 458 in src/uu/shred/src/shred.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/shred/src/shred.rs#L455-L458

Added lines #L455 - L458 were not covered by tests
));
}
if !path.is_file() {
return Err(USimpleError::new(
1,
format!("{}: Not a file", path.maybe_quote()),
get_message_with_args(
"shred-not-a-file",
HashMap::from([("file".to_string(), path.maybe_quote().to_string())]),
),

Check warning on line 467 in src/uu/shred/src/shred.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/shred/src/shred.rs#L464-L467

Added lines #L464 - L467 were not covered by tests
));
}

Expand Down Expand Up @@ -518,7 +537,12 @@
.write(true)
.truncate(false)
.open(path)
.map_err_context(|| format!("{}: failed to open for writing", path.maybe_quote()))?;
.map_err_context(|| {
get_message_with_args(
"shred-failed-to-open-for-writing",
HashMap::from([("file".to_string(), path.maybe_quote().to_string())]),
)
})?;

let size = match size {
Some(size) => size,
Expand All @@ -528,23 +552,35 @@
for (i, pass_type) in pass_sequence.into_iter().enumerate() {
if verbose {
let pass_name = pass_name(&pass_type);
let msg = get_message_with_args(
"shred-pass-progress",
HashMap::from([("file".to_string(), path.maybe_quote().to_string())]),
);
show_error!(
"{}: pass {}/{total_passes} ({pass_name})...",
path.maybe_quote(),
i + 1,
"{} {}/{total_passes} ({pass_name})...",
msg,
(i + 1).to_string()
);
}
// size is an optional argument for exactly how many bytes we want to shred
// Ignore failed writes; just keep trying
show_if_err!(
do_pass(&mut file, &pass_type, exact, random_source, size)
.map_err_context(|| format!("{}: File write pass failed", path.maybe_quote()))
do_pass(&mut file, &pass_type, exact, random_source, size).map_err_context(|| {
get_message_with_args(
"shred-file-write-pass-failed",
HashMap::from([("file".to_string(), path.maybe_quote().to_string())]),

Check warning on line 571 in src/uu/shred/src/shred.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/shred/src/shred.rs#L569-L571

Added lines #L569 - L571 were not covered by tests
)
})

Check warning on line 573 in src/uu/shred/src/shred.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/shred/src/shred.rs#L573

Added line #L573 was not covered by tests
);
}

if remove_method != RemoveMethod::None {
do_remove(path, path_str, verbose, remove_method)
.map_err_context(|| format!("{}: failed to remove file", path.maybe_quote()))?;
do_remove(path, path_str, verbose, remove_method).map_err_context(|| {
get_message_with_args(
"shred-failed-to-remove-file",
HashMap::from([("file".to_string(), path.maybe_quote().to_string())]),

Check warning on line 581 in src/uu/shred/src/shred.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/shred/src/shred.rs#L579-L581

Added lines #L579 - L581 were not covered by tests
)
})?;

Check warning on line 583 in src/uu/shred/src/shred.rs

View check run for this annotation

Codecov / codecov/patch

src/uu/shred/src/shred.rs#L583

Added line #L583 was not covered by tests
}
Ok(())
}
Expand Down Expand Up @@ -615,9 +651,10 @@
Ok(()) => {
if verbose {
show_error!(
"{}: renamed to {}",
last_path.maybe_quote(),
new_path.display()
"{}: {} {}",
last_path.maybe_quote().to_string(),
get_message("shred-renamed-to",),
new_path.display().to_string()
);
}

Expand All @@ -634,11 +671,15 @@
break;
}
Err(e) => {
show_error!(
"{}: Couldn't rename to {}: {e}",
last_path.maybe_quote(),
new_path.quote(),
let msg = get_message_with_args(
"shred-couldnt-rename",
HashMap::from([
("file".to_string(), last_path.maybe_quote().to_string()),
("new_name".to_string(), new_path.quote().to_string()),
("error".to_string(), e.to_string()),
]),
);
show_error!("{}", msg);
// TODO: replace with our error management
std::process::exit(1);
}
Expand All @@ -656,7 +697,13 @@
remove_method: RemoveMethod,
) -> Result<(), io::Error> {
if verbose {
show_error!("{}: removing", orig_filename.maybe_quote());
show_error!(
"{}",
get_message_with_args(
"shred-removing",
HashMap::from([("file".to_string(), orig_filename.maybe_quote().to_string())])
)
);
}

let remove_path = if remove_method == RemoveMethod::Unlink {
Expand All @@ -670,7 +717,13 @@
}

if verbose {
show_error!("{}: removed", orig_filename.maybe_quote());
show_error!(
"{}",
get_message_with_args(
"shred-removed",
HashMap::from([("file".to_string(), orig_filename.maybe_quote().to_string())])
)
);
}

Ok(())
Expand Down
Loading
Loading