This commit is contained in:
Dennis Schwerdel 2018-02-25 01:03:18 +01:00
parent 9ca22008c7
commit 2f6c3b239e
7 changed files with 1202 additions and 1069 deletions

View File

@ -3,7 +3,7 @@ MO_FILES = de.mo
default: default.pot ${MO_FILES} default: default.pot ${MO_FILES}
default.pot: excluded.po ../src default.pot: excluded.po ../src
(cd ../src; find . -name '*.rs') | xargs xgettext -D ../src --debug -L python -n -F -a -E --from-code UTF-8 -x ../lang/excluded.po -o default.pot find ../src -name '*.rs' | xargs xgettext --debug -L python -n -F -a -E --from-code UTF-8 -x ../lang/excluded.po -o default.pot
%.mo : %.po %.mo : %.po
msgfmt $< -o $@ msgfmt $< -o $@

1102
lang/de.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -140,6 +140,7 @@ impl BundleDb {
fn load_bundle_list( fn load_bundle_list(
&mut self, &mut self,
online: bool
) -> Result<(Vec<StoredBundle>, Vec<StoredBundle>), BundleDbError> { ) -> Result<(Vec<StoredBundle>, Vec<StoredBundle>), BundleDbError> {
if let Ok(list) = StoredBundle::read_list_from(&self.layout.local_bundle_cache_path()) { if let Ok(list) = StoredBundle::read_list_from(&self.layout.local_bundle_cache_path()) {
for bundle in list { for bundle in list {
@ -169,6 +170,9 @@ impl BundleDb {
&self.layout.local_bundle_cache_path() &self.layout.local_bundle_cache_path()
)); ));
} }
if !online {
return Ok((vec![], vec![]))
}
let (new, gone) = try!(load_bundles( let (new, gone) = try!(load_bundles(
&self.layout.remote_bundles_path(), &self.layout.remote_bundles_path(),
base_path, base_path,
@ -237,9 +241,10 @@ impl BundleDb {
pub fn open( pub fn open(
layout: RepositoryLayout, layout: RepositoryLayout,
crypto: Arc<Mutex<Crypto>>, crypto: Arc<Mutex<Crypto>>,
online: bool
) -> Result<(Self, Vec<BundleInfo>, Vec<BundleInfo>), BundleDbError> { ) -> Result<(Self, Vec<BundleInfo>, Vec<BundleInfo>), BundleDbError> {
let mut self_ = Self::new(layout, crypto); let mut self_ = Self::new(layout, crypto);
let (new, gone) = try!(self_.load_bundle_list()); let (new, gone) = try!(self_.load_bundle_list(online));
try!(self_.update_cache()); try!(self_.update_cache());
let new = new.into_iter().map(|s| s.info).collect(); let new = new.into_iter().map(|s| s.info).collect();
let gone = gone.into_iter().map(|s| s.info).collect(); let gone = gone.into_iter().map(|s| s.info).collect();

View File

@ -112,9 +112,9 @@ macro_rules! checked {
}; };
} }
fn open_repository(path: &Path) -> Result<Repository, ErrorCode> { fn open_repository(path: &Path, online: bool) -> Result<Repository, ErrorCode> {
Ok(checked!( Ok(checked!(
Repository::open(path), Repository::open(path, online),
"load repository", "load repository",
ErrorCode::LoadRepository ErrorCode::LoadRepository
)) ))
@ -478,7 +478,7 @@ pub fn run() -> Result<(), ErrorCode> {
no_default_excludes, no_default_excludes,
tar tar
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, true));
if repo.has_backup(&backup_name) { if repo.has_backup(&backup_name) {
tr_error!("A backup with that name already exists"); tr_error!("A backup with that name already exists");
return Err(ErrorCode::BackupAlreadyExists); return Err(ErrorCode::BackupAlreadyExists);
@ -595,7 +595,7 @@ pub fn run() -> Result<(), ErrorCode> {
dst_path, dst_path,
tar tar
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, true));
let backup = try!(get_backup(&repo, &backup_name)); let backup = try!(get_backup(&repo, &backup_name));
let inode = if let Some(inode) = inode { let inode = if let Some(inode) = inode {
checked!( checked!(
@ -635,7 +635,7 @@ pub fn run() -> Result<(), ErrorCode> {
tr_error!("Can only run copy on same repository"); tr_error!("Can only run copy on same repository");
return Err(ErrorCode::InvalidArgs); return Err(ErrorCode::InvalidArgs);
} }
let mut repo = try!(open_repository(&repo_path_src)); let mut repo = try!(open_repository(&repo_path_src, false));
if repo.has_backup(&backup_name_dst) { if repo.has_backup(&backup_name_dst) {
tr_error!("A backup with that name already exists"); tr_error!("A backup with that name already exists");
return Err(ErrorCode::BackupAlreadyExists); return Err(ErrorCode::BackupAlreadyExists);
@ -653,7 +653,7 @@ pub fn run() -> Result<(), ErrorCode> {
inode, inode,
force force
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, true));
if let Some(inode) = inode { if let Some(inode) = inode {
let mut backup = try!(get_backup(&repo, &backup_name)); let mut backup = try!(get_backup(&repo, &backup_name));
checked!( checked!(
@ -705,7 +705,7 @@ pub fn run() -> Result<(), ErrorCode> {
yearly, yearly,
force force
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, true));
if daily + weekly + monthly + yearly == 0 { if daily + weekly + monthly + yearly == 0 {
tr_error!("This would remove all those backups"); tr_error!("This would remove all those backups");
return Err(ErrorCode::UnsafeArgs); return Err(ErrorCode::UnsafeArgs);
@ -725,7 +725,7 @@ pub fn run() -> Result<(), ErrorCode> {
force, force,
combine combine
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, true));
let info_before = repo.info(); let info_before = repo.info();
checked!( checked!(
repo.vacuum(ratio, combine, force), repo.vacuum(ratio, combine, force),
@ -751,7 +751,7 @@ pub fn run() -> Result<(), ErrorCode> {
bundle_data, bundle_data,
repair repair
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, true));
checked!( checked!(
repo.check_repository(repair), repo.check_repository(repair),
"check repository", "check repository",
@ -797,7 +797,7 @@ pub fn run() -> Result<(), ErrorCode> {
backup_name, backup_name,
inode inode
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, false));
let backup_map = if let Some(backup_name) = backup_name { let backup_map = if let Some(backup_name) = backup_name {
if repo.layout.backups_path().join(&backup_name).is_dir() { if repo.layout.backups_path().join(&backup_name).is_dir() {
repo.get_backups(&backup_name) repo.get_backups(&backup_name)
@ -845,7 +845,7 @@ pub fn run() -> Result<(), ErrorCode> {
backup_name, backup_name,
inode inode
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, false));
if let Some(backup_name) = backup_name { if let Some(backup_name) = backup_name {
let backup = try!(get_backup(&repo, &backup_name)); let backup = try!(get_backup(&repo, &backup_name));
if let Some(inode) = inode { if let Some(inode) = inode {
@ -868,7 +868,7 @@ pub fn run() -> Result<(), ErrorCode> {
inode, inode,
mount_point mount_point
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, true));
let fs = if let Some(backup_name) = backup_name { let fs = if let Some(backup_name) = backup_name {
if repo.layout.backups_path().join(&backup_name).is_dir() { if repo.layout.backups_path().join(&backup_name).is_dir() {
checked!( checked!(
@ -916,7 +916,7 @@ pub fn run() -> Result<(), ErrorCode> {
); );
} }
Arguments::Analyze { repo_path } => { Arguments::Analyze { repo_path } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, true));
print_analysis(&checked!( print_analysis(&checked!(
repo.analyze_usage(), repo.analyze_usage(),
"analyze repository", "analyze repository",
@ -924,7 +924,7 @@ pub fn run() -> Result<(), ErrorCode> {
)); ));
} }
Arguments::BundleList { repo_path } => { Arguments::BundleList { repo_path } => {
let repo = try!(open_repository(&repo_path)); let repo = try!(open_repository(&repo_path, true));
for bundle in repo.list_bundles() { for bundle in repo.list_bundles() {
print_bundle_one_line(bundle); print_bundle_one_line(bundle);
} }
@ -933,7 +933,7 @@ pub fn run() -> Result<(), ErrorCode> {
repo_path, repo_path,
bundle_id bundle_id
} => { } => {
let repo = try!(open_repository(&repo_path)); let repo = try!(open_repository(&repo_path, true));
if let Some(bundle) = repo.get_bundle(&bundle_id) { if let Some(bundle) = repo.get_bundle(&bundle_id) {
print_bundle(bundle); print_bundle(bundle);
} else { } else {
@ -954,7 +954,7 @@ pub fn run() -> Result<(), ErrorCode> {
tr_info!("Import finished"); tr_info!("Import finished");
} }
Arguments::Versions { repo_path, path } => { Arguments::Versions { repo_path, path } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, true));
let mut found = false; let mut found = false;
for (name, mut inode) in for (name, mut inode) in
checked!( checked!(
@ -983,7 +983,7 @@ pub fn run() -> Result<(), ErrorCode> {
tr_error!("Can only run diff on same repository"); tr_error!("Can only run diff on same repository");
return Err(ErrorCode::InvalidArgs); return Err(ErrorCode::InvalidArgs);
} }
let mut repo = try!(open_repository(&repo_path_old)); let mut repo = try!(open_repository(&repo_path_old, true));
let backup_old = try!(get_backup(&repo, &backup_name_old)); let backup_old = try!(get_backup(&repo, &backup_name_old));
let backup_new = try!(get_backup(&repo, &backup_name_new)); let backup_new = try!(get_backup(&repo, &backup_name_new));
let inode1 = let inode1 =
@ -1026,7 +1026,7 @@ pub fn run() -> Result<(), ErrorCode> {
encryption, encryption,
hash hash
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, false));
let mut changed = false; let mut changed = false;
if let Some(bundle_size) = bundle_size { if let Some(bundle_size) = bundle_size {
repo.config.bundle_size = bundle_size; repo.config.bundle_size = bundle_size;
@ -1083,7 +1083,7 @@ pub fn run() -> Result<(), ErrorCode> {
password, password,
file file
} => { } => {
let mut repo = try!(open_repository(&repo_path)); let mut repo = try!(open_repository(&repo_path, false));
let (public, secret) = if let Some(file) = file { let (public, secret) = if let Some(file) = file {
checked!( checked!(
Crypto::load_keypair_from_file(file), Crypto::load_keypair_from_file(file),

View File

@ -72,8 +72,8 @@ pub trait Value: Clone + Copy + Default {}
#[repr(packed)] #[repr(packed)]
#[derive(Default)] #[derive(Default)]
pub struct Entry<K, V> { pub struct Entry<K, V> {
pub key: K, key: K,
pub data: V data: V
} }
impl<K: Key, V> Entry<K, V> { impl<K: Key, V> Entry<K, V> {
@ -86,15 +86,43 @@ impl<K: Key, V> Entry<K, V> {
fn clear(&mut self) { fn clear(&mut self) {
unsafe { self.key.clear() } unsafe { self.key.clear() }
} }
#[inline]
fn get(&self) -> (&K, &V) {
unsafe { (&self.key, &self.data) }
} }
impl<K: Clone, V: Clone> Clone for Entry<K, V> { #[inline]
fn clone(&self) -> Self { fn get_mut(&mut self) -> (&K, &mut V) {
unsafe { unsafe { (&self.key, &mut self.data) }
Entry {
key: self.key.clone(),
data: self.data.clone()
} }
#[inline]
fn get_key(&self) -> &K {
unsafe { &self.key }
}
#[inline]
fn get_mut_key(&mut self) -> &mut K {
unsafe { &mut self.key }
}
#[inline]
fn get_data(&self) -> &V {
unsafe { &self.data }
}
#[inline]
fn get_mut_data(&mut self) -> &mut V {
unsafe { &mut self.data }
}
}
impl<K: Clone + Key, V: Clone> Clone for Entry<K, V> {
fn clone(&self) -> Self {
Entry {
key: *self.get_key(),
data: self.get_data().clone()
} }
} }
} }
@ -115,7 +143,7 @@ impl<'a, K: Key, V> Iterator for Iter<'a, K, V> {
while let Some((first, rest)) = self.0.split_first() { while let Some((first, rest)) = self.0.split_first() {
self.0 = rest; self.0 = rest;
if first.is_used() { if first.is_used() {
unsafe { return Some((&first.key, &first.data)) } return Some(first.get())
} }
} }
None None
@ -135,7 +163,7 @@ impl<'a, K: Key, V> Iterator for IterMut<'a, K, V> {
Some((first, rest)) => { Some((first, rest)) => {
self.0 = rest; self.0 = rest;
if first.is_used() { if first.is_used() {
unsafe { return Some((&first.key, &mut first.data)) } return Some(first.get_mut())
} }
} }
} }
@ -312,7 +340,7 @@ impl<K: Key, V: Value> Index<K, V> {
continue; continue;
} }
entries += 1; entries += 1;
match unsafe { self.locate(&entry.key) } { match self.locate(entry.get_key()) {
LocateResult::Found(p) if p == pos => true, LocateResult::Found(p) if p == pos => true,
found => return Err(IndexError::WrongPosition(pos, found)) found => return Err(IndexError::WrongPosition(pos, found))
}; };
@ -356,10 +384,10 @@ impl<K: Key, V: Value> Index<K, V> {
if !entry.is_used() { if !entry.is_used() {
return LocateResult::Hole(pos); return LocateResult::Hole(pos);
} }
if entry.key == *key { if entry.get_key() == key {
return LocateResult::Found(pos); return LocateResult::Found(pos);
} }
let odist = (pos + self.capacity - (entry.key.hash() as usize & self.mask)) & self.mask; let odist = (pos + self.capacity - (entry.get_key().hash() as usize & self.mask)) & self.mask;
if dist > odist { if dist > odist {
return LocateResult::Steal(pos); return LocateResult::Steal(pos);
} }
@ -382,7 +410,7 @@ impl<K: Key, V: Value> Index<K, V> {
// we found a hole, stop shifting here // we found a hole, stop shifting here
break; break;
} }
if entry.key.hash() as usize & self.mask == pos { if entry.get_key().hash() as usize & self.mask == pos {
// we found an entry at the right position, stop shifting here // we found an entry at the right position, stop shifting here
break; break;
} }
@ -398,7 +426,7 @@ impl<K: Key, V: Value> Index<K, V> {
match self.locate(key) { match self.locate(key) {
LocateResult::Found(pos) => { LocateResult::Found(pos) => {
let mut old = *data; let mut old = *data;
mem::swap(&mut old, &mut self.data[pos].data); mem::swap(&mut old, self.data[pos].get_mut_data());
Ok(Some(old)) Ok(Some(old))
}, },
LocateResult::Hole(pos) => { LocateResult::Hole(pos) => {
@ -425,8 +453,8 @@ impl<K: Key, V: Value> Index<K, V> {
cur_pos = (cur_pos + 1) & self.mask; cur_pos = (cur_pos + 1) & self.mask;
let entry = &mut self.data[cur_pos]; let entry = &mut self.data[cur_pos];
if entry.is_used() { if entry.is_used() {
mem::swap(&mut stolen_key, &mut entry.key); mem::swap(&mut stolen_key, entry.get_mut_key());
mem::swap(&mut stolen_data, &mut entry.data); mem::swap(&mut stolen_data, entry.get_mut_data());
} else { } else {
entry.key = stolen_key; entry.key = stolen_key;
entry.data = stolen_data; entry.data = stolen_data;
@ -472,7 +500,7 @@ impl<K: Key, V: Value> Index<K, V> {
debug_assert!(self.check().is_ok(), tr!("Inconsistent before get")); debug_assert!(self.check().is_ok(), tr!("Inconsistent before get"));
match self.locate(key) { match self.locate(key) {
LocateResult::Found(pos) => { LocateResult::Found(pos) => {
unsafe { f(&mut self.data[pos].data) }; f(self.data[pos].get_mut_data());
true true
}, },
_ => false _ => false
@ -498,7 +526,7 @@ impl<K: Key, V: Value> Index<K, V> {
while pos < self.capacity { while pos < self.capacity {
{ {
let entry = &mut self.data[pos]; let entry = &mut self.data[pos];
if !entry.is_used() || f(&entry.key, &entry.data) { if !entry.is_used() || f(entry.get_key(), entry.get_data()) {
pos += 1; pos += 1;
continue; continue;
} }
@ -518,6 +546,7 @@ impl<K: Key, V: Value> Index<K, V> {
} }
#[inline] #[inline]
#[allow(dead_code)]
pub fn iter_mut(&mut self) -> IterMut<K, V> { pub fn iter_mut(&mut self) -> IterMut<K, V> {
IterMut(self.data) IterMut(self.data)
} }
@ -533,6 +562,7 @@ impl<K: Key, V: Value> Index<K, V> {
} }
#[inline] #[inline]
#[allow(dead_code)]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.entries == 0 self.entries == 0
} }

View File

@ -118,11 +118,11 @@ impl Repository {
)); ));
try!(BundleMap::create().save(layout.bundle_map_path())); try!(BundleMap::create().save(layout.bundle_map_path()));
try!(fs::create_dir_all(layout.backups_path())); try!(fs::create_dir_all(layout.backups_path()));
Self::open(path) Self::open(path, true)
} }
#[allow(unknown_lints, useless_let_if_seq)] #[allow(unknown_lints, useless_let_if_seq)]
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, RepositoryError> { pub fn open<P: AsRef<Path>>(path: P, online: bool) -> Result<Self, RepositoryError> {
let layout = RepositoryLayout::new(path.as_ref().to_path_buf()); let layout = RepositoryLayout::new(path.as_ref().to_path_buf());
if !layout.remote_exists() { if !layout.remote_exists() {
return Err(RepositoryError::NoRemote); return Err(RepositoryError::NoRemote);
@ -133,7 +133,7 @@ impl Repository {
let local_locks = LockFolder::new(layout.local_locks_path()); let local_locks = LockFolder::new(layout.local_locks_path());
let lock = try!(local_locks.lock(false)); let lock = try!(local_locks.lock(false));
let crypto = Arc::new(Mutex::new(try!(Crypto::open(layout.keys_path())))); let crypto = Arc::new(Mutex::new(try!(Crypto::open(layout.keys_path()))));
let (bundles, new, gone) = try!(BundleDb::open(layout.clone(), crypto.clone())); let (bundles, new, gone) = try!(BundleDb::open(layout.clone(), crypto.clone(), online));
let (index, mut rebuild_index) = let (index, mut rebuild_index) =
match unsafe { Index::open(layout.index_path(), &INDEX_MAGIC, INDEX_VERSION) } { match unsafe { Index::open(layout.index_path(), &INDEX_MAGIC, INDEX_VERSION) } {
Ok(index) => (index, false), Ok(index) => (index, false),
@ -227,7 +227,7 @@ impl Repository {
for file in key_files { for file in key_files {
try!(repo.crypto.lock().unwrap().register_keyfile(file)); try!(repo.crypto.lock().unwrap().register_keyfile(file));
} }
repo = try!(Repository::open(path)); repo = try!(Repository::open(path, true));
let mut backups: Vec<(String, Backup)> = try!(repo.get_all_backups()).into_iter().collect(); let mut backups: Vec<(String, Backup)> = try!(repo.get_all_backups()).into_iter().collect();
backups.sort_by_key(|&(_, ref b)| b.timestamp); backups.sort_by_key(|&(_, ref b)| b.timestamp);
if let Some((name, backup)) = backups.pop() { if let Some((name, backup)) = backups.pop() {