Class: HomeFS

Inherits:
Object
  • Object
show all
Defined in:
lib/homefs/homefs.rb

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ HomeFS

Returns a new instance of HomeFS.



4
5
6
7
8
# File 'lib/homefs/homefs.rb', line 4

def initialize(path)
    @relpath = path
    @dirlinks = Hash.new
    read_passwd
end

Instance Method Details

#can_delete?(path) ⇒ Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/homefs/homefs.rb', line 87

def can_delete?(path)
    writable?(File.dirname(homepath(path)))
end

#can_mkdir?(path) ⇒ Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/homefs/homefs.rb', line 79

def can_mkdir?(path)
    writable?(File.dirname(homepath(path)))
end

#can_rmdir?(path) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/homefs/homefs.rb', line 71

def can_rmdir?(path)
    File.writable?(homepath(path))
end

#can_write?(path) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
102
103
104
105
106
107
# File 'lib/homefs/homefs.rb', line 99

def can_write?(path)
    hpath = homepath(path)
    if File.exist?(hpath)
        writable?(hpath)
    else
        # FIXME: We don't support sticky bits
        writable?(File.dirname(hpath))
    end
end

#contents(path) ⇒ Object



126
127
128
# File 'lib/homefs/homefs.rb', line 126

def contents(path)
    Dir.new(homepath(path)).to_a
end

#delete(path) ⇒ Object



83
84
85
# File 'lib/homefs/homefs.rb', line 83

def delete(path)
    FileUtils.rm(homepath(path))
end

#directory?(path) ⇒ Boolean

Returns:

  • (Boolean)


138
139
140
# File 'lib/homefs/homefs.rb', line 138

def directory?(path)
    File.directory?(homepath(path))
end

#executable?(path) ⇒ Boolean

Returns:

  • (Boolean)


116
117
118
# File 'lib/homefs/homefs.rb', line 116

def executable?(path)
    mode_mask(homepath(path), 0111)
end

#file?(path) ⇒ Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/homefs/homefs.rb', line 134

def file?(path)
    File.file?(homepath(path))
end

#homepath(path = nil) ⇒ Object

Raises:

  • (Errno::ENOENT)


23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/homefs/homefs.rb', line 23

def homepath(path = nil)
    uid = FuseFS.reader_uid
    basepath = @homedirs[uid]
    # basepath shouldn't ever be nil, but fail gracefully just
    # in case.
    raise Errno::ENOENT if basepath == nil
    if path
        "#{basepath}/#{@relpath}/#{path}"
    else
        "#{basepath}/#{@relpath}"
    end
end

#mkdir(path) ⇒ Object



75
76
77
# File 'lib/homefs/homefs.rb', line 75

def mkdir(path)
    FileUtils.mkdir(homepath(path))
end

#mode_mask(file, mask, check_ids = true) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/homefs/homefs.rb', line 36

def mode_mask(file, mask, check_ids = true)
    stat = File.stat(file)
    # First digit: setuid (4), setgid (2), sticky bit (1)
    # Second, third, and fourth digits: user, group, and
    # world permissions for read (4), write (2), execute (1)
    # (see `man chmod` for more)
    fmode = stat.mode
    if check_ids
        fuid, fgid = stat.uid, stat.gid
        uid, gid = FuseFS.reader_uid, FuseFS.reader_gid
        # Zero out the third digit (in octal).
        # We could use a constant here, but this works
        # for a mask of any length
        if uid != fuid
            mask &= ~(mask & 0700)
        end
        if gid != fgid
            mask &= ~(mask & 0070)
        end
    end
    fmode & mask != 0
end

#raw_close(path, raw = nil) ⇒ Object



162
163
164
165
# File 'lib/homefs/homefs.rb', line 162

def raw_close(path, raw = nil)
    return if raw.nil? # ???
    raw.close
end

#raw_open(path, mode, rfusefs = nil) ⇒ Object



142
143
144
145
146
147
148
149
# File 'lib/homefs/homefs.rb', line 142

def raw_open(path, mode, rfusefs = nil)
    mode = case mode
           when "rw" then File::RDWR | File::CREAT | File::BINARY
           when "r"  then File::RDONLY | File::BINARY
           when "w"  then File::WRONLY | File::CREAT | File::BINARY
           end
    File.open(homepath(path), mode)
end

#raw_read(path, offset, size, raw = nil) ⇒ Object



151
152
153
154
155
# File 'lib/homefs/homefs.rb', line 151

def raw_read(path, offset, size, raw = nil)
    raw ||= raw_open(path, "r")
    raw.seek(offset, :SET)
    raw.read(size)
end

#raw_sync(path, datasync, raw = nil) ⇒ Object



157
158
159
160
# File 'lib/homefs/homefs.rb', line 157

def raw_sync(path, datasync, raw = nil)
    return if raw.nil? # Should we sync anyway?
    raw.fdatasync
end

#raw_write(path, off, sz, buf, raw = nil) ⇒ Object



167
168
169
170
171
# File 'lib/homefs/homefs.rb', line 167

def raw_write(path, off, sz, buf, raw = nil)
    raw ||= File.open(path, "w")
    raw.seek(off, :SET)
    raw.write(buf[0...sz])
end

#read_file(path) ⇒ Object



120
121
122
123
124
# File 'lib/homefs/homefs.rb', line 120

def read_file(path)
    File.open(homepath(path), "rb") do |file|
        file.read
    end
end

#read_passwdObject



10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/homefs/homefs.rb', line 10

def read_passwd
    # Here we map each line in /etc/passwd to an array,
    # which Hash interprets as a key, value pair.
    @homedirs = Hash[
      File.readlines('/etc/passwd').map do |line|
          next if line.strip.empty?
          values = line.split(':')
          # UID, home directory
          [Integer(values[2]), values[5]]
      end
    ]
end

#rename(from_path, to_path) ⇒ Object



59
60
61
# File 'lib/homefs/homefs.rb', line 59

def rename(from_path, to_path)
    FileUtils.mv(homepath(from_path), homepath(to_path))
end

#rmdir(path) ⇒ Object



67
68
69
# File 'lib/homefs/homefs.rb', line 67

def rmdir(path)
    FileUtils.rmdir(homepath(path))
end

#size(path) ⇒ Object



130
131
132
# File 'lib/homefs/homefs.rb', line 130

def size(path)
    File.size(homepath(path))
end

#times(path) ⇒ Object



109
110
111
112
113
114
# File 'lib/homefs/homefs.rb', line 109

def times(path)
    atime = File.atime(homepath(path))
    mtime = File.mtime(homepath(path))
    ctime = File.ctime(homepath(path))
    [atime, mtime, ctime]
end

#touch(path, modtime) ⇒ Object



63
64
65
# File 'lib/homefs/homefs.rb', line 63

def touch(path, modtime)
    File.utime(modtime, modtime, homepath(path))
end

#writable?(path) ⇒ Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/homefs/homefs.rb', line 95

def writable?(path)
    mode_mask(path, 0222)
end

#write_to(path, str) ⇒ Object



91
92
93
# File 'lib/homefs/homefs.rb', line 91

def write_to(path, str)
    File.open(homepath(path), "wb") {|file| file.write(str) }
end