diff --git a/Cargo.toml b/Cargo.toml index 80e0a89e6947a418811071631c1b956d8b9ba14c..b1cf51db546780042b4a567c2b1270637dcb95a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,11 @@ name = "redoxfs" path = "src/bin/mount.rs" doc = false +[[bin]] +name = "redoxfs-ar" +path = "src/bin/ar.rs" +doc = false + [[bin]] name = "redoxfs-mkfs" path = "src/bin/mkfs.rs" diff --git a/src/bin/ar.rs b/src/bin/ar.rs new file mode 100644 index 0000000000000000000000000000000000000000..b403337a66aa52c888ac7f0bc4a2f0094da8864a --- /dev/null +++ b/src/bin/ar.rs @@ -0,0 +1,131 @@ +extern crate redoxfs; +extern crate syscall; +extern crate uuid; + +use std::{env, fs, process, time}; +use std::io::{self, Read}; +use std::path::Path; +use std::time::{SystemTime, UNIX_EPOCH}; + +use redoxfs::{Disk, DiskFile, FileSystem, Node}; +use uuid::Uuid; + +fn syscall_err(err: syscall::Error) -> io::Error { + io::Error::from_raw_os_error(err.errno) +} + +fn archive<D: Disk, P: AsRef<Path>>(fs: &mut FileSystem<D>, parent_block: u64, parent_path: P) -> io::Result<()> { + for entry_res in fs::read_dir(parent_path)? { + let entry = entry_res?; + + let name = entry.file_name().into_string().map_err(|_| + io::Error::new( + io::ErrorKind::InvalidData, + "filename is not valid UTF-8" + ) + )?; + let path = entry.path(); + + let dir = path.is_dir(); + let (mode_type, mode_perm) = if dir { + (Node::MODE_DIR, 0o755) + } /* else if flags & O_SYMLINK == O_SYMLINK { + Node::MODE_SYMLINK + } */ else { + (Node::MODE_FILE, 0o644) + }; + + let mode = mode_type | (mode_perm & Node::MODE_PERM); + let ctime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + let mut node = fs.create_node( + mode, + &name, + parent_block, + ctime.as_secs(), + ctime.subsec_nanos() + ).map_err(syscall_err)?; + node.1.uid = 0; + node.1.gid = 0; + fs.write_at(node.0, &node.1).map_err(syscall_err)?; + + if dir { + archive(fs, node.0, path)?; + } else { + let data = fs::read(path)?; + fs.write_node( + node.0, + 0, + &data, + ctime.as_secs(), + ctime.subsec_nanos() + ).map_err(syscall_err)?; + } + } + + Ok(()) +} + +fn main() { + let mut args = env::args().skip(1); + + let disk_path = if let Some(path) = args.next() { + path + } else { + println!("redoxfs-ar: no disk image provided"); + println!("redoxfs-ar DISK FOLDER [BOOTLOADER]"); + process::exit(1); + }; + + let folder_path = if let Some(path) = args.next() { + path + } else { + println!("redoxfs-ar: no folder provided"); + println!("redoxfs-ar DISK FOLDER [BOOTLOADER]"); + process::exit(1); + }; + + let bootloader_path_opt = args.next(); + + let disk = match DiskFile::open(&disk_path) { + Ok(disk) => disk, + Err(err) => { + println!("redoxfs-ar: failed to open image {}: {}", disk_path, err); + process::exit(1); + } + }; + + let mut bootloader = vec![]; + if let Some(bootloader_path) = bootloader_path_opt { + match fs::File::open(&bootloader_path) { + Ok(mut file) => match file.read_to_end(&mut bootloader) { + Ok(_) => (), + Err(err) => { + println!("redoxfs-ar: failed to read bootloader {}: {}", bootloader_path, err); + process::exit(1); + } + }, + Err(err) => { + println!("redoxfs-ar: failed to open bootloader {}: {}", bootloader_path, err); + process::exit(1); + } + } + }; + + let ctime = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap(); + match FileSystem::create_reserved(disk, &bootloader, ctime.as_secs(), ctime.subsec_nanos()) { + Ok(mut filesystem) => { + let root = filesystem.header.1.root; + if let Err(err) = archive(&mut filesystem, root, &folder_path) { + println!("redoxfs-ar: failed to archive {}: {}", folder_path, err); + process::exit(1); + } + + let uuid = Uuid::from_bytes(&filesystem.header.1.uuid).unwrap(); + println!("redoxfs-ar: created filesystem on {}, reserved {} blocks, size {} MB, uuid {}", disk_path, filesystem.block, filesystem.header.1.size/1000/1000, uuid.hyphenated()); + }, + Err(err) => { + println!("redoxfs-ar: failed to create filesystem on {}: {}", disk_path, err); + process::exit(1); + } + } +} diff --git a/src/bin/mkfs.rs b/src/bin/mkfs.rs index b32a4e6cea9df787efd67d26b409f1ccf8890931..6fb686ad219ece41ce4c705488eab48b08f49e7a 100644 --- a/src/bin/mkfs.rs +++ b/src/bin/mkfs.rs @@ -1,5 +1,3 @@ -#![deny(warnings)] - extern crate redoxfs; extern crate uuid; diff --git a/src/bin/mount.rs b/src/bin/mount.rs index d7587a8ca4017bf69617579110db0f396be877a0..78820415f2d1122a40f8ea45f54970747df573e5 100644 --- a/src/bin/mount.rs +++ b/src/bin/mount.rs @@ -1,4 +1,3 @@ -#![deny(warnings)] #![cfg_attr(unix, feature(libc))] #[cfg(unix)] diff --git a/src/lib.rs b/src/lib.rs index a92ea06a637ee92db147fe200c876497ec45add4..2e51ab15e20c5e093b5036034ad89aa2268a8801 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,6 @@ #![crate_name="redoxfs"] #![crate_type="lib"] -//#![deny(warnings)] - extern crate syscall; extern crate uuid;