mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
l10n: port chcon to translation + add french
This commit is contained in:
parent
a769fc7904
commit
298ff72ffb
4 changed files with 281 additions and 100 deletions
|
@ -3,3 +3,56 @@ chcon-about = Change the SELinux security context of each FILE to CONTEXT.
|
||||||
chcon-usage = chcon [OPTION]... CONTEXT FILE...
|
chcon-usage = chcon [OPTION]... CONTEXT FILE...
|
||||||
chcon [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...
|
chcon [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...
|
||||||
chcon [OPTION]... --reference=RFILE FILE...
|
chcon [OPTION]... --reference=RFILE FILE...
|
||||||
|
|
||||||
|
# Help messages
|
||||||
|
chcon-help-help = Print help information.
|
||||||
|
chcon-help-dereference = Affect the referent of each symbolic link (this is the default), rather than the symbolic link itself.
|
||||||
|
chcon-help-no-dereference = Affect symbolic links instead of any referenced file.
|
||||||
|
chcon-help-preserve-root = Fail to operate recursively on '/'.
|
||||||
|
chcon-help-no-preserve-root = Do not treat '/' specially (the default).
|
||||||
|
chcon-help-reference = Use security context of RFILE, rather than specifying a CONTEXT value.
|
||||||
|
chcon-help-user = Set user USER in the target security context.
|
||||||
|
chcon-help-role = Set role ROLE in the target security context.
|
||||||
|
chcon-help-type = Set type TYPE in the target security context.
|
||||||
|
chcon-help-range = Set range RANGE in the target security context.
|
||||||
|
chcon-help-recursive = Operate on files and directories recursively.
|
||||||
|
chcon-help-follow-arg-dir-symlink = If a command line argument is a symbolic link to a directory, traverse it. Only valid when -R is specified.
|
||||||
|
chcon-help-follow-dir-symlinks = Traverse every symbolic link to a directory encountered. Only valid when -R is specified.
|
||||||
|
chcon-help-no-follow-symlinks = Do not traverse any symbolic links (default). Only valid when -R is specified.
|
||||||
|
chcon-help-verbose = Output a diagnostic for every file processed.
|
||||||
|
|
||||||
|
# Error messages - basic validation
|
||||||
|
chcon-error-no-context-specified = No context is specified
|
||||||
|
chcon-error-no-files-specified = No files are specified
|
||||||
|
chcon-error-data-out-of-range = Data is out of range
|
||||||
|
chcon-error-operation-failed = { $operation } failed
|
||||||
|
chcon-error-operation-failed-on = { $operation } failed on { $operand }
|
||||||
|
|
||||||
|
# Error messages - argument validation
|
||||||
|
chcon-error-invalid-context = Invalid security context '{ $context }'.
|
||||||
|
chcon-error-recursive-no-dereference-require-p = '--recursive' with '--no-dereference' require '-P'
|
||||||
|
chcon-error-recursive-dereference-require-h-or-l = '--recursive' with '--dereference' require either '-H' or '-L'
|
||||||
|
|
||||||
|
# Operation strings for error context
|
||||||
|
chcon-op-getting-security-context = Getting security context
|
||||||
|
chcon-op-file-name-validation = File name validation
|
||||||
|
chcon-op-getting-meta-data = Getting meta data
|
||||||
|
chcon-op-modifying-root-path = Modifying root path
|
||||||
|
chcon-op-accessing = Accessing
|
||||||
|
chcon-op-reading-directory = Reading directory
|
||||||
|
chcon-op-reading-cyclic-directory = Reading cyclic directory
|
||||||
|
chcon-op-applying-partial-context = Applying partial security context to unlabeled file
|
||||||
|
chcon-op-creating-security-context = Creating security context
|
||||||
|
chcon-op-setting-security-context-user = Setting security context user
|
||||||
|
chcon-op-setting-security-context = Setting security context
|
||||||
|
|
||||||
|
# Verbose output
|
||||||
|
chcon-verbose-changing-context = { $util_name }: changing security context of { $file }
|
||||||
|
|
||||||
|
# Warning messages
|
||||||
|
chcon-warning-dangerous-recursive-root = It is dangerous to operate recursively on '/'. Use --{ $option } to override this failsafe.
|
||||||
|
chcon-warning-dangerous-recursive-dir = It is dangerous to operate recursively on { $dir } (same as '/'). Use --{ $option } to override this failsafe.
|
||||||
|
chcon-warning-circular-directory = Circular directory structure.
|
||||||
|
This almost certainly means that you have a corrupted file system.
|
||||||
|
NOTIFY YOUR SYSTEM MANAGER.
|
||||||
|
The following directory is part of the cycle { $file }.
|
||||||
|
|
58
src/uu/chcon/locales/fr-FR.ftl
Normal file
58
src/uu/chcon/locales/fr-FR.ftl
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
chcon-about = Changer le contexte de sécurité SELinux de chaque FICHIER vers CONTEXTE.
|
||||||
|
Avec --reference, changer le contexte de sécurité de chaque FICHIER vers celui de RFICHIER.
|
||||||
|
chcon-usage = chcon [OPTION]... CONTEXTE FICHIER...
|
||||||
|
chcon [OPTION]... [-u UTILISATEUR] [-r RÔLE] [-l PLAGE] [-t TYPE] FICHIER...
|
||||||
|
chcon [OPTION]... --reference=RFICHIER FICHIER...
|
||||||
|
|
||||||
|
# Messages d'aide
|
||||||
|
chcon-help-help = Afficher les informations d'aide.
|
||||||
|
chcon-help-dereference = Affecter la cible de chaque lien symbolique (par défaut), plutôt que le lien symbolique lui-même.
|
||||||
|
chcon-help-no-dereference = Affecter les liens symboliques au lieu de tout fichier référencé.
|
||||||
|
chcon-help-preserve-root = Échouer lors de l'opération récursive sur '/'.
|
||||||
|
chcon-help-no-preserve-root = Ne pas traiter '/' spécialement (par défaut).
|
||||||
|
chcon-help-reference = Utiliser le contexte de sécurité de RFICHIER, plutôt que de spécifier une valeur CONTEXTE.
|
||||||
|
chcon-help-user = Définir l'utilisateur UTILISATEUR dans le contexte de sécurité cible.
|
||||||
|
chcon-help-role = Définir le rôle RÔLE dans le contexte de sécurité cible.
|
||||||
|
chcon-help-type = Définir le type TYPE dans le contexte de sécurité cible.
|
||||||
|
chcon-help-range = Définir la plage PLAGE dans le contexte de sécurité cible.
|
||||||
|
chcon-help-recursive = Opérer sur les fichiers et répertoires de manière récursive.
|
||||||
|
chcon-help-follow-arg-dir-symlink = Si un argument de ligne de commande est un lien symbolique vers un répertoire, le traverser. Valide uniquement quand -R est spécifié.
|
||||||
|
chcon-help-follow-dir-symlinks = Traverser chaque lien symbolique vers un répertoire rencontré. Valide uniquement quand -R est spécifié.
|
||||||
|
chcon-help-no-follow-symlinks = Ne traverser aucun lien symbolique (par défaut). Valide uniquement quand -R est spécifié.
|
||||||
|
chcon-help-verbose = Afficher un diagnostic pour chaque fichier traité.
|
||||||
|
|
||||||
|
# Messages d'erreur - validation de base
|
||||||
|
chcon-error-no-context-specified = Aucun contexte n'est spécifié
|
||||||
|
chcon-error-no-files-specified = Aucun fichier n'est spécifié
|
||||||
|
chcon-error-data-out-of-range = Données hors limites
|
||||||
|
chcon-error-operation-failed = { $operation } a échoué
|
||||||
|
chcon-error-operation-failed-on = { $operation } a échoué sur { $operand }
|
||||||
|
|
||||||
|
# Messages d'erreur - validation des arguments
|
||||||
|
chcon-error-invalid-context = Contexte de sécurité invalide '{ $context }'.
|
||||||
|
chcon-error-recursive-no-dereference-require-p = '--recursive' avec '--no-dereference' nécessite '-P'
|
||||||
|
chcon-error-recursive-dereference-require-h-or-l = '--recursive' avec '--dereference' nécessite soit '-H' soit '-L'
|
||||||
|
|
||||||
|
# Chaînes d'opération pour le contexte d'erreur
|
||||||
|
chcon-op-getting-security-context = Obtention du contexte de sécurité
|
||||||
|
chcon-op-file-name-validation = Validation du nom de fichier
|
||||||
|
chcon-op-getting-meta-data = Obtention des métadonnées
|
||||||
|
chcon-op-modifying-root-path = Modification du chemin racine
|
||||||
|
chcon-op-accessing = Accès
|
||||||
|
chcon-op-reading-directory = Lecture du répertoire
|
||||||
|
chcon-op-reading-cyclic-directory = Lecture du répertoire cyclique
|
||||||
|
chcon-op-applying-partial-context = Application d'un contexte de sécurité partiel à un fichier non étiqueté
|
||||||
|
chcon-op-creating-security-context = Création du contexte de sécurité
|
||||||
|
chcon-op-setting-security-context-user = Définition de l'utilisateur du contexte de sécurité
|
||||||
|
chcon-op-setting-security-context = Définition du contexte de sécurité
|
||||||
|
|
||||||
|
# Sortie détaillée
|
||||||
|
chcon-verbose-changing-context = { $util_name } : changement du contexte de sécurité de { $file }
|
||||||
|
|
||||||
|
# Messages d'avertissement
|
||||||
|
chcon-warning-dangerous-recursive-root = Il est dangereux d'opérer récursivement sur '/'. Utilisez --{ $option } pour outrepasser cette protection.
|
||||||
|
chcon-warning-dangerous-recursive-dir = Il est dangereux d'opérer récursivement sur { $dir } (identique à '/'). Utilisez --{ $option } pour outrepasser cette protection.
|
||||||
|
chcon-warning-circular-directory = Structure de répertoire circulaire.
|
||||||
|
Cela signifie presque certainement que vous avez un système de fichiers corrompu.
|
||||||
|
NOTIFIEZ VOTRE ADMINISTRATEUR SYSTÈME.
|
||||||
|
Le répertoire suivant fait partie du cycle { $file }.
|
|
@ -14,6 +14,7 @@ use clap::{Arg, ArgAction, Command};
|
||||||
use selinux::{OpaqueSecurityContext, SecurityContext};
|
use selinux::{OpaqueSecurityContext, SecurityContext};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::ffi::{CStr, CString, OsStr, OsString};
|
use std::ffi::{CStr, CString, OsStr, OsString};
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -24,7 +25,7 @@ mod fts;
|
||||||
|
|
||||||
use errors::*;
|
use errors::*;
|
||||||
|
|
||||||
use uucore::locale::get_message;
|
use uucore::locale::{get_message, get_message_with_args};
|
||||||
|
|
||||||
pub mod options {
|
pub mod options {
|
||||||
pub static HELP: &str = "help";
|
pub static HELP: &str = "help";
|
||||||
|
@ -78,10 +79,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
|
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
let err = io::Error::from_raw_os_error(libc::ENODATA);
|
let err = io::Error::from_raw_os_error(libc::ENODATA);
|
||||||
Err(Error::from_io1("Getting security context", reference, err))
|
Err(Error::from_io1(
|
||||||
|
get_message("chcon-op-getting-security-context"),
|
||||||
|
reference,
|
||||||
|
err,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(r) => Err(Error::from_selinux("Getting security context", r)),
|
Err(r) => Err(Error::from_selinux(
|
||||||
|
get_message("chcon-op-getting-security-context"),
|
||||||
|
r,
|
||||||
|
)),
|
||||||
};
|
};
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
@ -103,7 +111,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
Err(_r) => {
|
Err(_r) => {
|
||||||
return Err(USimpleError::new(
|
return Err(USimpleError::new(
|
||||||
libc::EXIT_FAILURE,
|
libc::EXIT_FAILURE,
|
||||||
format!("Invalid security context {}.", context.quote()),
|
get_message_with_args(
|
||||||
|
"chcon-error-invalid-context",
|
||||||
|
HashMap::from([("context".to_string(), context.quote().to_string())]),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -111,7 +122,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
if SecurityContext::from_c_str(&c_context, false).check() == Some(false) {
|
if SecurityContext::from_c_str(&c_context, false).check() == Some(false) {
|
||||||
return Err(USimpleError::new(
|
return Err(USimpleError::new(
|
||||||
libc::EXIT_FAILURE,
|
libc::EXIT_FAILURE,
|
||||||
format!("Invalid security context {}.", context.quote()),
|
get_message_with_args(
|
||||||
|
"chcon-error-invalid-context",
|
||||||
|
HashMap::from([("context".to_string(), context.quote().to_string())]),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,37 +172,34 @@ pub fn uu_app() -> Command {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::HELP)
|
Arg::new(options::HELP)
|
||||||
.long(options::HELP)
|
.long(options::HELP)
|
||||||
.help("Print help information.")
|
.help(get_message("chcon-help-help"))
|
||||||
.action(ArgAction::Help),
|
.action(ArgAction::Help),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::dereference::DEREFERENCE)
|
Arg::new(options::dereference::DEREFERENCE)
|
||||||
.long(options::dereference::DEREFERENCE)
|
.long(options::dereference::DEREFERENCE)
|
||||||
.overrides_with(options::dereference::NO_DEREFERENCE)
|
.overrides_with(options::dereference::NO_DEREFERENCE)
|
||||||
.help(
|
.help(get_message("chcon-help-dereference"))
|
||||||
"Affect the referent of each symbolic link (this is the default), \
|
|
||||||
rather than the symbolic link itself.",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::dereference::NO_DEREFERENCE)
|
Arg::new(options::dereference::NO_DEREFERENCE)
|
||||||
.short('h')
|
.short('h')
|
||||||
.long(options::dereference::NO_DEREFERENCE)
|
.long(options::dereference::NO_DEREFERENCE)
|
||||||
.help("Affect symbolic links instead of any referenced file.")
|
.help(get_message("chcon-help-no-dereference"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::preserve_root::PRESERVE_ROOT)
|
Arg::new(options::preserve_root::PRESERVE_ROOT)
|
||||||
.long(options::preserve_root::PRESERVE_ROOT)
|
.long(options::preserve_root::PRESERVE_ROOT)
|
||||||
.overrides_with(options::preserve_root::NO_PRESERVE_ROOT)
|
.overrides_with(options::preserve_root::NO_PRESERVE_ROOT)
|
||||||
.help("Fail to operate recursively on '/'.")
|
.help(get_message("chcon-help-preserve-root"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::preserve_root::NO_PRESERVE_ROOT)
|
Arg::new(options::preserve_root::NO_PRESERVE_ROOT)
|
||||||
.long(options::preserve_root::NO_PRESERVE_ROOT)
|
.long(options::preserve_root::NO_PRESERVE_ROOT)
|
||||||
.help("Do not treat '/' specially (the default).")
|
.help(get_message("chcon-help-no-preserve-root"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -197,10 +208,7 @@ pub fn uu_app() -> Command {
|
||||||
.value_name("RFILE")
|
.value_name("RFILE")
|
||||||
.value_hint(clap::ValueHint::FilePath)
|
.value_hint(clap::ValueHint::FilePath)
|
||||||
.conflicts_with_all([options::USER, options::ROLE, options::TYPE, options::RANGE])
|
.conflicts_with_all([options::USER, options::ROLE, options::TYPE, options::RANGE])
|
||||||
.help(
|
.help(get_message("chcon-help-reference"))
|
||||||
"Use security context of RFILE, rather than specifying \
|
|
||||||
a CONTEXT value.",
|
|
||||||
)
|
|
||||||
.value_parser(ValueParser::os_string()),
|
.value_parser(ValueParser::os_string()),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -209,7 +217,7 @@ pub fn uu_app() -> Command {
|
||||||
.long(options::USER)
|
.long(options::USER)
|
||||||
.value_name("USER")
|
.value_name("USER")
|
||||||
.value_hint(clap::ValueHint::Username)
|
.value_hint(clap::ValueHint::Username)
|
||||||
.help("Set user USER in the target security context.")
|
.help(get_message("chcon-help-user"))
|
||||||
.value_parser(ValueParser::os_string()),
|
.value_parser(ValueParser::os_string()),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -217,7 +225,7 @@ pub fn uu_app() -> Command {
|
||||||
.short('r')
|
.short('r')
|
||||||
.long(options::ROLE)
|
.long(options::ROLE)
|
||||||
.value_name("ROLE")
|
.value_name("ROLE")
|
||||||
.help("Set role ROLE in the target security context.")
|
.help(get_message("chcon-help-role"))
|
||||||
.value_parser(ValueParser::os_string()),
|
.value_parser(ValueParser::os_string()),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -225,7 +233,7 @@ pub fn uu_app() -> Command {
|
||||||
.short('t')
|
.short('t')
|
||||||
.long(options::TYPE)
|
.long(options::TYPE)
|
||||||
.value_name("TYPE")
|
.value_name("TYPE")
|
||||||
.help("Set type TYPE in the target security context.")
|
.help(get_message("chcon-help-type"))
|
||||||
.value_parser(ValueParser::os_string()),
|
.value_parser(ValueParser::os_string()),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -233,14 +241,14 @@ pub fn uu_app() -> Command {
|
||||||
.short('l')
|
.short('l')
|
||||||
.long(options::RANGE)
|
.long(options::RANGE)
|
||||||
.value_name("RANGE")
|
.value_name("RANGE")
|
||||||
.help("Set range RANGE in the target security context.")
|
.help(get_message("chcon-help-range"))
|
||||||
.value_parser(ValueParser::os_string()),
|
.value_parser(ValueParser::os_string()),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::RECURSIVE)
|
Arg::new(options::RECURSIVE)
|
||||||
.short('R')
|
.short('R')
|
||||||
.long(options::RECURSIVE)
|
.long(options::RECURSIVE)
|
||||||
.help("Operate on files and directories recursively.")
|
.help(get_message("chcon-help-recursive"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -251,10 +259,7 @@ pub fn uu_app() -> Command {
|
||||||
options::sym_links::FOLLOW_DIR_SYM_LINKS,
|
options::sym_links::FOLLOW_DIR_SYM_LINKS,
|
||||||
options::sym_links::NO_FOLLOW_SYM_LINKS,
|
options::sym_links::NO_FOLLOW_SYM_LINKS,
|
||||||
])
|
])
|
||||||
.help(
|
.help(get_message("chcon-help-follow-arg-dir-symlink"))
|
||||||
"If a command line argument is a symbolic link to a directory, \
|
|
||||||
traverse it. Only valid when -R is specified.",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -265,10 +270,7 @@ pub fn uu_app() -> Command {
|
||||||
options::sym_links::FOLLOW_ARG_DIR_SYM_LINK,
|
options::sym_links::FOLLOW_ARG_DIR_SYM_LINK,
|
||||||
options::sym_links::NO_FOLLOW_SYM_LINKS,
|
options::sym_links::NO_FOLLOW_SYM_LINKS,
|
||||||
])
|
])
|
||||||
.help(
|
.help(get_message("chcon-help-follow-dir-symlinks"))
|
||||||
"Traverse every symbolic link to a directory encountered. \
|
|
||||||
Only valid when -R is specified.",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -279,17 +281,14 @@ pub fn uu_app() -> Command {
|
||||||
options::sym_links::FOLLOW_ARG_DIR_SYM_LINK,
|
options::sym_links::FOLLOW_ARG_DIR_SYM_LINK,
|
||||||
options::sym_links::FOLLOW_DIR_SYM_LINKS,
|
options::sym_links::FOLLOW_DIR_SYM_LINKS,
|
||||||
])
|
])
|
||||||
.help(
|
.help(get_message("chcon-help-no-follow-symlinks"))
|
||||||
"Do not traverse any symbolic links (default). \
|
|
||||||
Only valid when -R is specified.",
|
|
||||||
)
|
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(options::VERBOSE)
|
Arg::new(options::VERBOSE)
|
||||||
.short('v')
|
.short('v')
|
||||||
.long(options::VERBOSE)
|
.long(options::VERBOSE)
|
||||||
.help("Output a diagnostic for every file processed.")
|
.help(get_message("chcon-help-verbose"))
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -319,30 +318,24 @@ fn parse_command_line(config: Command, args: impl uucore::Args) -> Result<Option
|
||||||
let (recursive_mode, affect_symlink_referent) = if matches.get_flag(options::RECURSIVE) {
|
let (recursive_mode, affect_symlink_referent) = if matches.get_flag(options::RECURSIVE) {
|
||||||
if matches.get_flag(options::sym_links::FOLLOW_DIR_SYM_LINKS) {
|
if matches.get_flag(options::sym_links::FOLLOW_DIR_SYM_LINKS) {
|
||||||
if matches.get_flag(options::dereference::NO_DEREFERENCE) {
|
if matches.get_flag(options::dereference::NO_DEREFERENCE) {
|
||||||
return Err(Error::ArgumentsMismatch(format!(
|
return Err(Error::ArgumentsMismatch(get_message(
|
||||||
"'--{}' with '--{}' require '-P'",
|
"chcon-error-recursive-no-dereference-require-p",
|
||||||
options::RECURSIVE,
|
|
||||||
options::dereference::NO_DEREFERENCE
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
(RecursiveMode::RecursiveAndFollowAllDirSymLinks, true)
|
(RecursiveMode::RecursiveAndFollowAllDirSymLinks, true)
|
||||||
} else if matches.get_flag(options::sym_links::FOLLOW_ARG_DIR_SYM_LINK) {
|
} else if matches.get_flag(options::sym_links::FOLLOW_ARG_DIR_SYM_LINK) {
|
||||||
if matches.get_flag(options::dereference::NO_DEREFERENCE) {
|
if matches.get_flag(options::dereference::NO_DEREFERENCE) {
|
||||||
return Err(Error::ArgumentsMismatch(format!(
|
return Err(Error::ArgumentsMismatch(get_message(
|
||||||
"'--{}' with '--{}' require '-P'",
|
"chcon-error-recursive-no-dereference-require-p",
|
||||||
options::RECURSIVE,
|
|
||||||
options::dereference::NO_DEREFERENCE
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
(RecursiveMode::RecursiveAndFollowArgDirSymLinks, true)
|
(RecursiveMode::RecursiveAndFollowArgDirSymLinks, true)
|
||||||
} else {
|
} else {
|
||||||
if matches.get_flag(options::dereference::DEREFERENCE) {
|
if matches.get_flag(options::dereference::DEREFERENCE) {
|
||||||
return Err(Error::ArgumentsMismatch(format!(
|
return Err(Error::ArgumentsMismatch(get_message(
|
||||||
"'--{}' with '--{}' require either '-H' or '-L'",
|
"chcon-error-recursive-dereference-require-h-or-l",
|
||||||
options::RECURSIVE,
|
|
||||||
options::dereference::DEREFERENCE
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,12 +509,19 @@ fn process_file(
|
||||||
let mut entry = fts.last_entry_ref().unwrap();
|
let mut entry = fts.last_entry_ref().unwrap();
|
||||||
|
|
||||||
let file_full_name = entry.path().map(PathBuf::from).ok_or_else(|| {
|
let file_full_name = entry.path().map(PathBuf::from).ok_or_else(|| {
|
||||||
Error::from_io("File name validation", io::ErrorKind::InvalidInput.into())
|
Error::from_io(
|
||||||
|
get_message("chcon-op-file-name-validation"),
|
||||||
|
io::ErrorKind::InvalidInput.into(),
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let fts_access_path = entry.access_path().ok_or_else(|| {
|
let fts_access_path = entry.access_path().ok_or_else(|| {
|
||||||
let err = io::ErrorKind::InvalidInput.into();
|
let err = io::ErrorKind::InvalidInput.into();
|
||||||
Error::from_io1("File name validation", &file_full_name, err)
|
Error::from_io1(
|
||||||
|
get_message("chcon-op-file-name-validation"),
|
||||||
|
&file_full_name,
|
||||||
|
err,
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let err = |s, k: io::ErrorKind| Error::from_io1(s, &file_full_name, k.into());
|
let err = |s, k: io::ErrorKind| Error::from_io1(s, &file_full_name, k.into());
|
||||||
|
@ -535,7 +535,10 @@ fn process_file(
|
||||||
let file_dev_ino: DeviceAndINode = if let Some(st) = entry.stat() {
|
let file_dev_ino: DeviceAndINode = if let Some(st) = entry.stat() {
|
||||||
st.try_into()?
|
st.try_into()?
|
||||||
} else {
|
} else {
|
||||||
return Err(err("Getting meta data", io::ErrorKind::InvalidInput));
|
return Err(err(
|
||||||
|
get_message("chcon-op-getting-meta-data"),
|
||||||
|
io::ErrorKind::InvalidInput,
|
||||||
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut result = Ok(());
|
let mut result = Ok(());
|
||||||
|
@ -554,7 +557,10 @@ fn process_file(
|
||||||
// Ensure that we do not process "/" on the second visit.
|
// Ensure that we do not process "/" on the second visit.
|
||||||
let _ignored = fts.read_next_entry();
|
let _ignored = fts.read_next_entry();
|
||||||
|
|
||||||
return Err(err("Modifying root path", io::ErrorKind::PermissionDenied));
|
return Err(err(
|
||||||
|
get_message("chcon-op-modifying-root-path"),
|
||||||
|
io::ErrorKind::PermissionDenied,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -579,17 +585,20 @@ fn process_file(
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
result = fts_err("Accessing");
|
result = fts_err(get_message("chcon-op-accessing"));
|
||||||
}
|
}
|
||||||
|
|
||||||
fts_sys::FTS_ERR => result = fts_err("Accessing"),
|
fts_sys::FTS_ERR => result = fts_err(get_message("chcon-op-accessing")),
|
||||||
|
|
||||||
fts_sys::FTS_DNR => result = fts_err("Reading directory"),
|
fts_sys::FTS_DNR => result = fts_err(get_message("chcon-op-reading-directory")),
|
||||||
|
|
||||||
fts_sys::FTS_DC => {
|
fts_sys::FTS_DC => {
|
||||||
if cycle_warning_required(options.recursive_mode.fts_open_options(), &entry) {
|
if cycle_warning_required(options.recursive_mode.fts_open_options(), &entry) {
|
||||||
emit_cycle_warning(&file_full_name);
|
emit_cycle_warning(&file_full_name);
|
||||||
return Err(err("Reading cyclic directory", io::ErrorKind::InvalidData));
|
return Err(err(
|
||||||
|
get_message("chcon-op-reading-cyclic-directory"),
|
||||||
|
io::ErrorKind::InvalidData,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,15 +610,23 @@ fn process_file(
|
||||||
&& root_dev_ino_check(root_dev_ino, file_dev_ino)
|
&& root_dev_ino_check(root_dev_ino, file_dev_ino)
|
||||||
{
|
{
|
||||||
root_dev_ino_warn(&file_full_name);
|
root_dev_ino_warn(&file_full_name);
|
||||||
result = Err(err("Modifying root path", io::ErrorKind::PermissionDenied));
|
result = Err(err(
|
||||||
|
get_message("chcon-op-modifying-root-path"),
|
||||||
|
io::ErrorKind::PermissionDenied,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if result.is_ok() {
|
if result.is_ok() {
|
||||||
if options.verbose {
|
if options.verbose {
|
||||||
println!(
|
println!(
|
||||||
"{}: changing security context of {}",
|
"{}",
|
||||||
uucore::util_name(),
|
get_message_with_args(
|
||||||
file_full_name.quote()
|
"chcon-verbose-changing-context",
|
||||||
|
HashMap::from([
|
||||||
|
("util_name".to_string(), uucore::util_name().to_string()),
|
||||||
|
("file".to_string(), file_full_name.quote().to_string())
|
||||||
|
])
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,7 +654,7 @@ fn change_file_context(
|
||||||
let err0 = || -> Result<()> {
|
let err0 = || -> Result<()> {
|
||||||
// If the file doesn't have a context, and we're not setting all of the context
|
// If the file doesn't have a context, and we're not setting all of the context
|
||||||
// components, there isn't really an obvious default. Thus, we just give up.
|
// components, there isn't really an obvious default. Thus, we just give up.
|
||||||
let op = "Applying partial security context to unlabeled file";
|
let op = get_message("chcon-op-applying-partial-context");
|
||||||
let err = io::ErrorKind::InvalidInput.into();
|
let err = io::ErrorKind::InvalidInput.into();
|
||||||
Err(Error::from_io1(op, path, err))
|
Err(Error::from_io1(op, path, err))
|
||||||
};
|
};
|
||||||
|
@ -647,20 +664,30 @@ fn change_file_context(
|
||||||
Ok(Some(context)) => context,
|
Ok(Some(context)) => context,
|
||||||
|
|
||||||
Ok(None) => return err0(),
|
Ok(None) => return err0(),
|
||||||
Err(r) => return Err(Error::from_selinux("Getting security context", r)),
|
Err(r) => {
|
||||||
|
return Err(Error::from_selinux(
|
||||||
|
get_message("chcon-op-getting-security-context"),
|
||||||
|
r,
|
||||||
|
));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let c_file_context = match file_context.to_c_string() {
|
let c_file_context = match file_context.to_c_string() {
|
||||||
Ok(Some(context)) => context,
|
Ok(Some(context)) => context,
|
||||||
|
|
||||||
Ok(None) => return err0(),
|
Ok(None) => return err0(),
|
||||||
Err(r) => return Err(Error::from_selinux("Getting security context", r)),
|
Err(r) => {
|
||||||
|
return Err(Error::from_selinux(
|
||||||
|
get_message("chcon-op-getting-security-context"),
|
||||||
|
r,
|
||||||
|
));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let se_context =
|
let se_context =
|
||||||
OpaqueSecurityContext::from_c_str(c_file_context.as_ref()).map_err(|_r| {
|
OpaqueSecurityContext::from_c_str(c_file_context.as_ref()).map_err(|_r| {
|
||||||
let err = io::ErrorKind::InvalidInput.into();
|
let err = io::ErrorKind::InvalidInput.into();
|
||||||
Error::from_io1("Creating security context", path, err)
|
Error::from_io1(get_message("chcon-op-creating-security-context"), path, err)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
type SetValueProc = fn(&OpaqueSecurityContext, &CStr) -> selinux::errors::Result<()>;
|
type SetValueProc = fn(&OpaqueSecurityContext, &CStr) -> selinux::errors::Result<()>;
|
||||||
|
@ -676,24 +703,34 @@ fn change_file_context(
|
||||||
if let Some(new_value) = new_value {
|
if let Some(new_value) = new_value {
|
||||||
let c_new_value = os_str_to_c_string(new_value).map_err(|_r| {
|
let c_new_value = os_str_to_c_string(new_value).map_err(|_r| {
|
||||||
let err = io::ErrorKind::InvalidInput.into();
|
let err = io::ErrorKind::InvalidInput.into();
|
||||||
Error::from_io1("Creating security context", path, err)
|
Error::from_io1(
|
||||||
|
get_message("chcon-op-creating-security-context"),
|
||||||
|
path,
|
||||||
|
err,
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
set_value_proc(&se_context, &c_new_value)
|
set_value_proc(&se_context, &c_new_value).map_err(|r| {
|
||||||
.map_err(|r| Error::from_selinux("Setting security context user", r))?;
|
Error::from_selinux(
|
||||||
|
get_message("chcon-op-setting-security-context-user"),
|
||||||
|
r,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let context_string = se_context
|
let context_string = se_context.to_c_string().map_err(|r| {
|
||||||
.to_c_string()
|
Error::from_selinux(get_message("chcon-op-getting-security-context"), r)
|
||||||
.map_err(|r| Error::from_selinux("Getting security context", r))?;
|
})?;
|
||||||
|
|
||||||
if c_file_context.as_ref().to_bytes() == context_string.as_ref().to_bytes() {
|
if c_file_context.as_ref().to_bytes() == context_string.as_ref().to_bytes() {
|
||||||
Ok(()) // Nothing to change.
|
Ok(()) // Nothing to change.
|
||||||
} else {
|
} else {
|
||||||
SecurityContext::from_c_str(&context_string, false)
|
SecurityContext::from_c_str(&context_string, false)
|
||||||
.set_for_path(path, options.affect_symlink_referent, false)
|
.set_for_path(path, options.affect_symlink_referent, false)
|
||||||
.map_err(|r| Error::from_selinux("Setting security context", r))
|
.map_err(|r| {
|
||||||
|
Error::from_selinux(get_message("chcon-op-setting-security-context"), r)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,10 +738,16 @@ fn change_file_context(
|
||||||
if let Some(c_context) = context.to_c_string()? {
|
if let Some(c_context) = context.to_c_string()? {
|
||||||
SecurityContext::from_c_str(c_context.as_ref(), false)
|
SecurityContext::from_c_str(c_context.as_ref(), false)
|
||||||
.set_for_path(path, options.affect_symlink_referent, false)
|
.set_for_path(path, options.affect_symlink_referent, false)
|
||||||
.map_err(|r| Error::from_selinux("Setting security context", r))
|
.map_err(|r| {
|
||||||
|
Error::from_selinux(get_message("chcon-op-setting-security-context"), r)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
let err = io::ErrorKind::InvalidInput.into();
|
let err = io::ErrorKind::InvalidInput.into();
|
||||||
Err(Error::from_io1("Setting security context", path, err))
|
Err(Error::from_io1(
|
||||||
|
get_message("chcon-op-setting-security-context"),
|
||||||
|
path,
|
||||||
|
err,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -733,16 +776,28 @@ fn root_dev_ino_check(root_dev_ino: Option<DeviceAndINode>, dir_dev_ino: DeviceA
|
||||||
fn root_dev_ino_warn(dir_name: &Path) {
|
fn root_dev_ino_warn(dir_name: &Path) {
|
||||||
if dir_name.as_os_str() == "/" {
|
if dir_name.as_os_str() == "/" {
|
||||||
show_warning!(
|
show_warning!(
|
||||||
"It is dangerous to operate recursively on '/'. \
|
"{}",
|
||||||
Use --{} to override this failsafe.",
|
get_message_with_args(
|
||||||
options::preserve_root::NO_PRESERVE_ROOT,
|
"chcon-warning-dangerous-recursive-root",
|
||||||
|
HashMap::from([(
|
||||||
|
"option".to_string(),
|
||||||
|
options::preserve_root::NO_PRESERVE_ROOT.to_string()
|
||||||
|
)])
|
||||||
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
show_warning!(
|
show_warning!(
|
||||||
"It is dangerous to operate recursively on {} (same as '/'). \
|
"{}",
|
||||||
Use --{} to override this failsafe.",
|
get_message_with_args(
|
||||||
dir_name.quote(),
|
"chcon-warning-dangerous-recursive-dir",
|
||||||
options::preserve_root::NO_PRESERVE_ROOT,
|
HashMap::from([
|
||||||
|
("dir".to_string(), dir_name.to_string_lossy().to_string()),
|
||||||
|
(
|
||||||
|
"option".to_string(),
|
||||||
|
options::preserve_root::NO_PRESERVE_ROOT.to_string()
|
||||||
|
)
|
||||||
|
])
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -763,11 +818,11 @@ fn cycle_warning_required(fts_options: c_int, entry: &fts::EntryRef) -> bool {
|
||||||
|
|
||||||
fn emit_cycle_warning(file_name: &Path) {
|
fn emit_cycle_warning(file_name: &Path) {
|
||||||
show_warning!(
|
show_warning!(
|
||||||
"Circular directory structure.\n\
|
"{}",
|
||||||
This almost certainly means that you have a corrupted file system.\n\
|
get_message_with_args(
|
||||||
NOTIFY YOUR SYSTEM MANAGER.\n\
|
"chcon-warning-circular-directory",
|
||||||
The following directory is part of the cycle {}.",
|
HashMap::from([("file".to_string(), file_name.to_string_lossy().to_string())])
|
||||||
file_name.quote()
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,23 +4,26 @@
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
#![cfg(target_os = "linux")]
|
#![cfg(target_os = "linux")]
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
|
use uucore::locale::{get_message, get_message_with_args};
|
||||||
|
|
||||||
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub(crate) enum Error {
|
pub(crate) enum Error {
|
||||||
#[error("No context is specified")]
|
#[error("{}", get_message("chcon-error-no-context-specified"))]
|
||||||
MissingContext,
|
MissingContext,
|
||||||
|
|
||||||
#[error("No files are specified")]
|
#[error("{}", get_message("chcon-error-no-files-specified"))]
|
||||||
MissingFiles,
|
MissingFiles,
|
||||||
|
|
||||||
#[error("Data is out of range")]
|
#[error("{}", get_message("chcon-error-data-out-of-range"))]
|
||||||
OutOfRange,
|
OutOfRange,
|
||||||
|
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
|
@ -29,45 +32,57 @@ pub(crate) enum Error {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
CommandLine(#[from] clap::Error),
|
CommandLine(#[from] clap::Error),
|
||||||
|
|
||||||
#[error("{operation} failed")]
|
#[error("{}", get_message_with_args("chcon-error-operation-failed", HashMap::from([("operation".to_string(), operation.clone())])))]
|
||||||
SELinux {
|
SELinux {
|
||||||
operation: &'static str,
|
operation: String,
|
||||||
|
#[source]
|
||||||
source: selinux::errors::Error,
|
source: selinux::errors::Error,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("{operation} failed")]
|
#[error("{}", get_message_with_args("chcon-error-operation-failed", HashMap::from([("operation".to_string(), operation.clone())])))]
|
||||||
Io {
|
Io {
|
||||||
operation: &'static str,
|
operation: String,
|
||||||
|
#[source]
|
||||||
source: io::Error,
|
source: io::Error,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("{operation} failed on {}", .operand1.quote())]
|
#[error("{}", get_message_with_args("chcon-error-operation-failed-on", HashMap::from([("operation".to_string(), operation.clone()), ("operand".to_string(), operand1.quote().to_string())])))]
|
||||||
Io1 {
|
Io1 {
|
||||||
operation: &'static str,
|
operation: String,
|
||||||
operand1: OsString,
|
operand1: OsString,
|
||||||
|
#[source]
|
||||||
source: io::Error,
|
source: io::Error,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
pub(crate) fn from_io(operation: &'static str, source: io::Error) -> Self {
|
pub(crate) fn from_io(operation: impl Into<String>, source: io::Error) -> Self {
|
||||||
Self::Io { operation, source }
|
Self::Io {
|
||||||
|
operation: operation.into(),
|
||||||
|
source,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_io1(
|
pub(crate) fn from_io1(
|
||||||
operation: &'static str,
|
operation: impl Into<String>,
|
||||||
operand1: impl Into<OsString>,
|
operand1: impl Into<OsString>,
|
||||||
source: io::Error,
|
source: io::Error,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::Io1 {
|
Self::Io1 {
|
||||||
operation,
|
operation: operation.into(),
|
||||||
operand1: operand1.into(),
|
operand1: operand1.into(),
|
||||||
source,
|
source,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_selinux(operation: &'static str, source: selinux::errors::Error) -> Self {
|
pub(crate) fn from_selinux(
|
||||||
Self::SELinux { operation, source }
|
operation: impl Into<String>,
|
||||||
|
source: selinux::errors::Error,
|
||||||
|
) -> Self {
|
||||||
|
Self::SELinux {
|
||||||
|
operation: operation.into(),
|
||||||
|
source,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue