summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 89b1f4d0601623b57fc5dd5dfa270b10633fcfa3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
extern crate fuse;
extern crate libc;
extern crate rafs;
extern crate time;

use rafs::data::get_data1;
use rafs::data::{SimpleFsData, traverse_fs};
use fuse::{Filesystem, Request, ReplyEntry, ReplyAttr, ReplyDirectory, ReplyData, FileAttr, FileType};
use libc::ENOENT;
use std::ffi::OsStr;
use time::Timespec;

struct MemFs {
    data: SimpleFsData,
}

const CREATE_TIME: Timespec = Timespec { sec: 1494802762, nsec: 0 };
const TTL: Timespec = Timespec { sec: 1, nsec: 0 };

fn getAttr(file: &SimpleFsData) -> FileAttr {
    fn fileAttr(ino: u64, len: usize) -> FileAttr {
        FileAttr {
            ino: ino,
            size: len as u64,
            blocks: 1,
            atime: CREATE_TIME,
            mtime: CREATE_TIME,
            ctime: CREATE_TIME,
            crtime: CREATE_TIME,
            kind: FileType::RegularFile,
            perm: 0o755,
            nlink: 1,
            uid: 501,
            gid: 20,
            rdev: 0,
            flags: 0,
        }
    }

    fn dirAttr(ino: u64, children: usize) -> FileAttr {
        FileAttr {
            ino: ino,
            size: 0,
            blocks: 1,
            atime: CREATE_TIME,
            mtime: CREATE_TIME,
            ctime: CREATE_TIME,
            crtime: CREATE_TIME,
            kind: FileType::Directory,
            perm: 0o755,
            nlink: children as u32,
            uid: 501,
            gid: 20,
            rdev: 0,
            flags: 0,
        }
    }

    match file {
        &SimpleFsData::File(ino, ref name) => fileAttr(ino, name.len()),
        &SimpleFsData::Directory(ino, ref children) => dirAttr(ino, children.len()),
    }
}

impl Filesystem for MemFs {
    fn lookup(&mut self, _req: &Request, _parent: u64, _name: &OsStr,
              reply: ReplyEntry) {
        let mut result: Option<FileAttr> = None;
        {
            let mut f = |ref file: &SimpleFsData| {
                match *file {
                    &SimpleFsData::Directory(i, ref children) =>
                        if i == _parent {
                            for &(ref name, ref file) in children {
                                if Some(name.as_str()) == _name.to_str() {
                                    result = Some(getAttr(file));
                                }
                            };
                        },
                    _ => ()
                };
            };
            traverse_fs(&self.data, &mut f);
        }
        match result {
            Some(r) => reply.entry(&TTL, &r, 0),
            None => reply.error(ENOENT)
        }
    }

    fn getattr(&mut self, _req: &Request, _ino: u64, reply: ReplyAttr) {
        reply.error(ENOENT);
    }

    fn read(&mut self, _req: &Request, _ino: u64, _fh: u64, _offset: u64,
            _size: u32, reply: ReplyData) {
        reply.error(ENOENT);
    }
    fn readdir (&mut self, _req: &Request, ino: u64, _fh: u64, offset: u64,
                reply: ReplyDirectory) {
        reply.error(ENOENT);
    }
}

fn usage() {
    println!("{} <mountpoint>", std::env::args().nth(0).unwrap());
}

fn mount(mountpoint: &OsStr) {
    let fs = MemFs { data: get_data1() };
    fuse::mount(fs, &mountpoint, &[]).unwrap()
}

fn main() {
    println!("{:?}", get_data1());
    match std::env::args_os().nth(1) {
        Some(mountpoint) => mount(&mountpoint),
        None => usage(),
    }
}