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;