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
15 changes: 15 additions & 0 deletions src/uu/sync/locales/en-US.ftl
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
sync-about = Synchronize cached writes to persistent storage
sync-usage = sync [OPTION]... FILE...

# Help messages
sync-help-file-system = sync the file systems that contain the files (Linux and Windows only)
sync-help-data = sync only file data, no unneeded metadata (Linux only)

# Error messages
sync-error-data-needs-argument = --data needs at least one argument
sync-error-opening-file = error opening { $file }
sync-error-no-such-file = error opening { $file }: No such file or directory

# Windows-specific error messages
sync-error-flush-file-buffer = failed to flush file buffer
sync-error-create-volume-handle = failed to create volume handle
sync-error-find-first-volume = failed to find first volume
sync-error-find-next-volume = failed to find next volume
17 changes: 17 additions & 0 deletions src/uu/sync/locales/fr-FR.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
sync-about = Synchroniser les écritures en cache vers le stockage persistant
sync-usage = sync [OPTION]... FICHIER...

# Messages d'aide
sync-help-file-system = synchroniser les systèmes de fichiers qui contiennent les fichiers (Linux et Windows uniquement)
sync-help-data = synchroniser seulement les données des fichiers, pas les métadonnées inutiles (Linux uniquement)

# Messages d'erreur
sync-error-data-needs-argument = --data nécessite au moins un argument
sync-error-opening-file = erreur lors de l'ouverture de { $file }
sync-error-no-such-file = erreur lors de l'ouverture de { $file } : Aucun fichier ou répertoire de ce type

# Messages d'erreur spécifiques à Windows
sync-error-flush-file-buffer = échec du vidage du tampon de fichier
sync-error-create-volume-handle = échec de la création du handle de volume
sync-error-find-first-volume = échec de la recherche du premier volume
sync-error-find-next-volume = échec de la recherche du volume suivant
39 changes: 26 additions & 13 deletions src/uu/sync/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ use nix::errno::Errno;
use nix::fcntl::{OFlag, open};
#[cfg(any(target_os = "linux", target_os = "android"))]
use nix::sys::stat::Mode;
use std::collections::HashMap;
use std::path::Path;
use uucore::display::Quotable;
#[cfg(any(target_os = "linux", target_os = "android"))]
use uucore::error::FromIo;
use uucore::error::{UResult, USimpleError};
use uucore::format_usage;

use uucore::locale::get_message;
use uucore::locale::{get_message, get_message_with_args};

pub mod options {
pub static FILE_SYSTEM: &str = "file-system";
Expand Down Expand Up @@ -67,6 +67,7 @@ mod platform {
use std::os::windows::prelude::*;
use std::path::Path;
use uucore::error::{UResult, USimpleError};
use uucore::locale::get_message;
use uucore::wide::{FromWide, ToWide};
use windows_sys::Win32::Foundation::{
ERROR_NO_MORE_FILES, GetLastError, HANDLE, INVALID_HANDLE_VALUE, MAX_PATH,
Expand All @@ -92,15 +93,15 @@ mod platform {
if unsafe { FlushFileBuffers(file.as_raw_handle() as HANDLE) } == 0 {
Err(USimpleError::new(
get_last_error() as i32,
"failed to flush file buffer",
get_message("sync-error-flush-file-buffer"),
))
} else {
Ok(())
}
}
Err(e) => Err(USimpleError::new(
e.raw_os_error().unwrap_or(1),
"failed to create volume handle",
get_message("sync-error-create-volume-handle"),
)),
}
} else {
Expand All @@ -115,7 +116,7 @@ mod platform {
if handle == INVALID_HANDLE_VALUE {
return Err(USimpleError::new(
get_last_error() as i32,
"failed to find first volume",
get_message("sync-error-find-first-volume"),
));
}
Ok((String::from_wide_null(&name), handle))
Expand All @@ -137,7 +138,10 @@ mod platform {
unsafe { FindVolumeClose(next_volume_handle) };
Ok(volumes)
}
err => Err(USimpleError::new(err as i32, "failed to find next volume")),
err => Err(USimpleError::new(
err as i32,
get_message("sync-error-find-next-volume"),
)),
};
} else {
volumes.push(String::from_wide_null(&name));
Expand Down Expand Up @@ -172,14 +176,16 @@ mod platform {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let matches = uu_app().try_get_matches_from(args)?;

let files: Vec<String> = matches
.get_many::<String>(ARG_FILES)
.map(|v| v.map(ToString::to_string).collect())
.unwrap_or_default();

if matches.get_flag(options::DATA) && files.is_empty() {
return Err(USimpleError::new(1, "--data needs at least one argument"));
return Err(USimpleError::new(
1,
get_message("sync-error-data-needs-argument"),
));
}

for f in &files {
Expand All @@ -189,17 +195,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let path = Path::new(&f);
if let Err(e) = open(path, OFlag::O_NONBLOCK, Mode::empty()) {
if e != Errno::EACCES || (e == Errno::EACCES && path.is_dir()) {
e.map_err_context(|| format!("error opening {}", f.quote()))?;
e.map_err_context(|| {
get_message_with_args(
"sync-error-opening-file",
HashMap::from([("file".to_string(), f.quote().to_string())]),
)
})?;
}
}
}

#[cfg(not(any(target_os = "linux", target_os = "android")))]
{
if !Path::new(&f).exists() {
return Err(USimpleError::new(
1,
format!("error opening {}: No such file or directory", f.quote()),
get_message_with_args(
"sync-error-no-such-file",
HashMap::from([("file".to_string(), f.quote().to_string())]),
),
));
}
}
Expand Down Expand Up @@ -229,15 +242,15 @@ pub fn uu_app() -> Command {
.short('f')
.long(options::FILE_SYSTEM)
.conflicts_with(options::DATA)
.help("sync the file systems that contain the files (Linux and Windows only)")
.help(get_message("sync-help-file-system"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::DATA)
.short('d')
.long(options::DATA)
.conflicts_with(options::FILE_SYSTEM)
.help("sync only file data, no unneeded metadata (Linux only)")
.help(get_message("sync-help-data"))
.action(ArgAction::SetTrue),
)
.arg(
Expand Down
Loading