diff --git a/Cargo.lock b/Cargo.lock index 9a025e95e0f5a73909ad69360bc32295273d1e6d..bd85205f42980f7fe3113ff1cd665206f3745308 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,7 +2,7 @@ # It is not intended for manual editing. [[package]] name = "cfg-if" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -15,7 +15,7 @@ name = "fuse" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -24,7 +24,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.54" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -40,7 +40,7 @@ name = "log" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -53,7 +53,7 @@ name = "rand" version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -63,7 +63,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -92,16 +92,16 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.54" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "redoxfs" -version = "0.3.3" +version = "0.3.4" dependencies = [ "fuse 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -116,8 +116,8 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -149,10 +149,10 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" +"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fuse 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e57070510966bfef93662a81cb8aa2b1c7db0964354fa9921434f04b9e8660" -"checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6" +"checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" @@ -161,7 +161,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" +"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bcbb6aa301e5d3b0b5ef639c9a9c7e2f1c944f177b460c04dc24c69b1fa2bd99" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" diff --git a/Cargo.toml b/Cargo.toml index 636417a7ee7ccec2d35120304c2daaf84938b81e..310080d3de787b221ef23a5cc11e65410c996838 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "redoxfs" description = "The Redox Filesystem" repository = "https://gitlab.redox-os.org/redox-os/redoxfs" -version = "0.3.3" +version = "0.3.4" license-file = "LICENSE" readme = "README.md" authors = ["Jeremy Soller <jackpot51@gmail.com>"] diff --git a/src/archive.rs b/src/archive.rs new file mode 100644 index 0000000000000000000000000000000000000000..f5ad9b68d24a13540d33e3b41eff458ec2099a45 --- /dev/null +++ b/src/archive.rs @@ -0,0 +1,101 @@ +use std::fs; +use std::io; +use std::path::Path; +use std::os::unix::ffi::OsStrExt; +use std::os::unix::fs::MetadataExt; + +use crate::{BLOCK_SIZE, Disk, Extent, FileSystem, Node}; + +fn syscall_err(err: syscall::Error) -> io::Error { + io::Error::from_raw_os_error(err.errno) +} + +fn archive_at<D: Disk, P: AsRef<Path>>(fs: &mut FileSystem<D>, parent_path: P, parent_block: u64) -> io::Result<()> { + for entry_res in fs::read_dir(parent_path)? { + let entry = entry_res?; + + let metadata = entry.metadata()?; + let file_type = metadata.file_type(); + + let name = entry.file_name().into_string().map_err(|_| + io::Error::new( + io::ErrorKind::InvalidData, + "filename is not valid UTF-8" + ) + )?; + + let mode_type = if file_type.is_dir() { + Node::MODE_DIR + } else if file_type.is_file() { + Node::MODE_FILE + } else if file_type.is_symlink() { + Node::MODE_SYMLINK + } else { + return Err(io::Error::new( + io::ErrorKind::Other, + format!("Does not support parsing {:?}", file_type) + )); + }; + + let mode = mode_type | (metadata.mode() as u16 & Node::MODE_PERM); + let mut node = fs.create_node( + mode, + &name, + parent_block, + metadata.ctime() as u64, + metadata.ctime_nsec() as u32 + ).map_err(syscall_err)?; + node.1.uid = metadata.uid(); + node.1.gid = metadata.gid(); + fs.write_at(node.0, &node.1).map_err(syscall_err)?; + + let path = entry.path(); + if file_type.is_dir() { + archive_at(fs, path, node.0)?; + } else if file_type.is_file() { + let data = fs::read(path)?; + fs.write_node( + node.0, + 0, + &data, + metadata.mtime() as u64, + metadata.mtime_nsec() as u32 + ).map_err(syscall_err)?; + } else if file_type.is_symlink() { + let destination = fs::read_link(path)?; + let data = destination.as_os_str().as_bytes(); + fs.write_node( + node.0, + 0, + &data, + metadata.mtime() as u64, + metadata.mtime_nsec() as u32 + ).map_err(syscall_err)?; + } else { + return Err(io::Error::new( + io::ErrorKind::Other, + format!("Does not support creating {:?}", file_type) + )); + } + } + + Ok(()) +} + +pub fn archive<D: Disk, P: AsRef<Path>>(fs: &mut FileSystem<D>, parent_path: P) -> io::Result<u64> { + let root_block = fs.header.1.root; + archive_at(fs, parent_path, root_block)?; + + let free_block = fs.header.1.free; + let mut free = fs.node(free_block).map_err(syscall_err)?; + let end_block = free.1.extents[0].block; + let end_size = end_block * BLOCK_SIZE; + free.1.extents[0] = Extent::default(); + fs.write_at(free.0, &free.1).map_err(syscall_err)?; + + fs.header.1.size = end_size; + let header = fs.header; + fs.write_at(header.0, &header.1).map_err(syscall_err)?; + + Ok(header.0 * BLOCK_SIZE + end_size) +} diff --git a/src/bin/ar.rs b/src/bin/ar.rs index 139b893380a2352377a2621ee53689341fed29ff..1b7ac036bf52ed35b11b9f052770956638831e92 100644 --- a/src/bin/ar.rs +++ b/src/bin/ar.rs @@ -3,110 +3,12 @@ extern crate syscall; extern crate uuid; use std::{env, fs, process}; -use std::io::{self, Read}; -use std::path::Path; +use std::io::Read; use std::time::{SystemTime, UNIX_EPOCH}; -use std::os::unix::ffi::OsStrExt; -use std::os::unix::fs::MetadataExt; -use redoxfs::{BLOCK_SIZE, Disk, DiskSparse, Extent, FileSystem, Node}; +use redoxfs::{DiskSparse, FileSystem, archive}; use uuid::Uuid; -fn syscall_err(err: syscall::Error) -> io::Error { - io::Error::from_raw_os_error(err.errno) -} - -fn archive_at<D: Disk, P: AsRef<Path>>(fs: &mut FileSystem<D>, parent_path: P, parent_block: u64) -> io::Result<()> { - for entry_res in fs::read_dir(parent_path)? { - let entry = entry_res?; - - let metadata = entry.metadata()?; - let file_type = metadata.file_type(); - - let name = entry.file_name().into_string().map_err(|_| - io::Error::new( - io::ErrorKind::InvalidData, - "filename is not valid UTF-8" - ) - )?; - - let mode_type = if file_type.is_dir() { - Node::MODE_DIR - } else if file_type.is_file() { - Node::MODE_FILE - } else if file_type.is_symlink() { - Node::MODE_SYMLINK - } else { - return Err(io::Error::new( - io::ErrorKind::Other, - format!("Does not support parsing {:?}", file_type) - )); - }; - - let mode = mode_type | (metadata.mode() as u16 & Node::MODE_PERM); - let mut node = fs.create_node( - mode, - &name, - parent_block, - metadata.ctime() as u64, - metadata.ctime_nsec() as u32 - ).map_err(syscall_err)?; - node.1.uid = metadata.uid(); - node.1.gid = metadata.gid(); - fs.write_at(node.0, &node.1).map_err(syscall_err)?; - - let path = entry.path(); - if file_type.is_dir() { - archive_at(fs, path, node.0)?; - } else if file_type.is_file() { - let data = fs::read(path)?; - fs.write_node( - node.0, - 0, - &data, - metadata.mtime() as u64, - metadata.mtime_nsec() as u32 - ).map_err(syscall_err)?; - } else if file_type.is_symlink() { - let destination = fs::read_link(path)?; - let data = destination.as_os_str().as_bytes(); - fs.write_node( - node.0, - 0, - &data, - metadata.mtime() as u64, - metadata.mtime_nsec() as u32 - ).map_err(syscall_err)?; - } else { - return Err(io::Error::new( - io::ErrorKind::Other, - format!("Does not support creating {:?}", file_type) - )); - } - } - - Ok(()) -} - - -fn archive<D: Disk, P: AsRef<Path>>(fs: &mut FileSystem<D>, parent_path: P) -> io::Result<u64> { - let root_block = fs.header.1.root; - archive_at(fs, parent_path, root_block)?; - - let free_block = fs.header.1.free; - let mut free = fs.node(free_block).map_err(syscall_err)?; - let end_block = free.1.extents[0].block; - let end_size = end_block * BLOCK_SIZE; - free.1.extents[0] = Extent::default(); - fs.write_at(free.0, &free.1).map_err(syscall_err)?; - - fs.header.1.size = end_size; - let header = fs.header; - fs.write_at(header.0, &header.1).map_err(syscall_err)?; - - Ok(header.0 * BLOCK_SIZE + end_size) -} - fn main() { let mut args = env::args().skip(1); diff --git a/src/lib.rs b/src/lib.rs index a6bc8147810238d96f105e53afbf0eac747b71d0..b9c6cd4f78658d87b43a4cfccfdc0ced22aaa763 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,7 @@ pub const SIGNATURE: &'static [u8; 8] = b"RedoxFS\0"; pub const VERSION: u64 = 3; pub static IS_UMT: AtomicUsize = AtomicUsize::new(0); +pub use self::archive::archive; pub use self::disk::{Disk, DiskCache, DiskFile, DiskSparse}; pub use self::ex_node::ExNode; pub use self::extent::Extent; @@ -19,6 +20,7 @@ pub use self::header::Header; pub use self::mount::mount; pub use self::node::Node; +mod archive; mod disk; mod ex_node; mod extent;