Separation of concerns. We now have a trait for identifying

a database type, and an implementation for mLocate.  That's a
start.
This commit is contained in:
Elf M. Sternberg 2021-07-06 18:03:30 -07:00
parent 3f7ae7bd8b
commit 965df106d9
3 changed files with 61 additions and 25 deletions

3
src/database.rs Normal file
View File

@ -0,0 +1,3 @@
pub trait LocateDb {
fn is(magic: &[u8]) -> bool;
}

View File

@ -1,15 +1,33 @@
extern crate structview;
use structview::{u32_be, View};
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#[derive(Clone, Copy, View)]
#[repr(C)]
pub struct MlHeader {
magic: [u8; 8], /* '\0', 'm', 'l', 'o', 'c', 'a', 't', 'e' */
conf_size: u32_be,
version: u8,
check_visibility: u8,
pad: [u8; 2],
}
//! MLocate
//!
//! The readme has the full explanation, but the `locate` suite of
//! tools present in all Linux distributions is used to locate files
//! on your storage device. Rather than search the device directly,
//! `locate` scans a catalog file created during downtime.
//!
//! `MLocate` is the most popular implementation of the locate system,
//! but it has three annoying flaws:
//!
//! 1. The archive file isn't very compressed.
//! 2. The archive file is always an average of 12 hours out of date.
//! 3. The archive is accessible only through a command line program.
//!
//! This program intends to read one of two different formats, the
//! classic mlocate format, or a new format that exploits a few nifty
//! tricks to try and make the database file smaller and access
//! faster.
extern crate structview;
pub mod database;
pub mod mlocate_db;
use crate::database::LocateDb;
use crate::mlocate_db::MlHeader;
#[cfg(test)]
mod tests {
@ -22,20 +40,10 @@ mod tests {
let db = File::open("/var/lib/mlocate/mlocate.db").expect("Unable to open file");
let mut reader = BufReader::new(db);
match reader.fill_buf() {
Ok(buffer) => match MlHeader::view(&buffer[0..32]) {
Ok(header) => {
let text = &header.magic[1..8];
assert_eq!(text, *b"mlocate");
assert_eq!(header.version, 0);
let magic = std::str::from_utf8(text).unwrap_or("ERROR");
println!(
"magic: {}\nversion: {}\nconf_size: {}\nvisibility: {}",
magic, header.version, header.conf_size, header.check_visibility
);
Ok(buffer) => {
assert!(MlHeader::is(buffer), "Could not read DB");
Ok(())
}
Err(_) => Err("The header did not unpack.".to_owned()),
},
Err(_) => Err("The header could not be read".to_owned()),
}
}

25
src/mlocate_db/mod.rs Normal file
View File

@ -0,0 +1,25 @@
use crate::database::LocateDb;
use structview::{u32_be, View};
#[derive(Clone, Copy, View)]
#[repr(C)]
pub struct MlHeader {
magic: [u8; 8], /* '\0', 'm', 'l', 'o', 'c', 'a', 't', 'e' */
conf_size: u32_be,
version: u8,
check_visibility: u8,
pad: [u8; 2],
}
impl LocateDb for MlHeader {
fn is(magic: &[u8]) -> bool {
if magic.len() < 32 {
false
} else {
match MlHeader::view(&magic[0..32]) {
Ok(header) => header.magic[0..8] == *b"\0mlocate" && header.version == 0,
Err(_) => false,
}
}
}
}