rfusefs 1.0.2.RC0 → 1.1.0.rc202009.34

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- #No hidden files (except for .gitignore)
2
- .*
3
- !.gitignore
4
- !.travis.yml
5
- #Files generated by rake
6
- doc
7
- pkg
8
- #Jedit stupid default backup settings
9
- *'`'
@@ -1,8 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - "1.8.7"
4
- - "1.9.3"
5
- - "2.0.0"
6
- before_install:
7
- - sudo apt-get update -qq
8
- - sudo apt-get install -qq libfuse-dev
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- # Specify your gem's dependencies in rfusefs.gemspec
4
- gemspec
@@ -1,28 +0,0 @@
1
- === 1.0.1 / 2013-12-19
2
-
3
- * Add FuseFS.main to create pretty usage messages
4
-
5
- * Support extended attributes in filesystems
6
-
7
- * Updates and cleanup of PathMapperFS
8
-
9
- * Provide SqliteMapperFS
10
-
11
- === 1.0.0 / 2012-08-07
12
-
13
- * Depend on new rfuse 1.0.0, Ruby 1.9
14
-
15
- * API breaking changes
16
-
17
- * order of arguments to {FuseFS.mount}, {FuseFS.start} changed
18
- to account for better option handling in RFuse
19
-
20
- === 0.8.0 / 2011-02-19
21
-
22
- * Initial port from fusefs
23
-
24
- * Improved raw methods
25
- * new "times" api for including atime,mtime,ctime in stat results
26
- * metadir allow mv directories
27
- * includes PathMapperFS
28
-
@@ -1,105 +0,0 @@
1
- = rfusefs
2
-
3
- * https://rubygems.org/gems/rfusefs
4
- * https://github.com/lwoggardner/rfusefs
5
-
6
- == DESCRIPTION
7
-
8
- RFuseFS is a port of the FuseFS[http://rubygems.org/gems/fusefs/]
9
- library aimed at allowing Ruby programmers to quickly and easily create
10
- virtual filesystems with little more than a few lines of code.
11
-
12
- RFuseFS is api compatible with FuseFS (0.7.0)
13
-
14
- == SYNOPSIS
15
-
16
- FuseFS provides a layer of abstraction to a programmer who wants to create a
17
- virtual filesystem via FUSE.
18
-
19
- First define a virtual directory by subclassing {FuseFS::FuseDir}
20
-
21
- See samples under /samples and also the following starter classes
22
-
23
- * {FuseFS::FuseDir}
24
- * {FuseFS::MetaDir}
25
- * {FuseFS::DirLink}
26
- * {FuseFS::PathMapperFS}
27
- * {FuseFS::SqliteMapperFS}
28
-
29
- Then start your filesystem with
30
-
31
- * {FuseFS.start}
32
- * {FuseFS.main}
33
-
34
- Finally to use the filesystem open up your favourite file browser/terminal and
35
- explore the contents under <mountpoint>
36
-
37
- Happy Filesystem Hacking!
38
-
39
- === the hello world filesystem in 16 LOC
40
-
41
- require 'rfusefs'
42
-
43
- class HelloDir
44
- def contents(path)
45
- ['hello.txt']
46
- end
47
- def file?(path)
48
- path == '/hello.txt'
49
- end
50
- def read_file(path)
51
- "Hello, World!\n"
52
- end
53
- def size(path)
54
- read_file(path).size
55
- end
56
- end
57
-
58
- # Usage: #{$0} mountpoint [mount_options]
59
- FuseFS.main() { |options| HelloDir.new }
60
-
61
- == REQUIREMENTS:
62
-
63
- * FUSE (http://fuse.sourceforge.org)
64
- * Ruby (>=1.9)
65
- * rfuse (~> 1.0)
66
-
67
- == INSTALL:
68
-
69
- * gem install rfusefs
70
-
71
- == DEVELOPERS:
72
-
73
- After checking out the source, run:
74
-
75
- $ bundle install # install dependencies
76
- $ rake spec # run tests
77
- $ rake yard # generate docs
78
-
79
-
80
- == LICENSE:
81
-
82
- (The MIT License)
83
-
84
- * Copyright (c) 2005 Greg Millam. (FuseFS)
85
- * Copyright (c) 2009 Kyle Maxwell. (FuseFS)
86
- * Copyright (c) 2012 Grant Gardner. (RFuseFS)
87
-
88
- Permission is hereby granted, free of charge, to any person obtaining
89
- a copy of this software and associated documentation files (the
90
- 'Software'), to deal in the Software without restriction, including
91
- without limitation the rights to use, copy, modify, merge, publish,
92
- distribute, sublicense, and/or sell copies of the Software, and to
93
- permit persons to whom the Software is furnished to do so, subject to
94
- the following conditions:
95
-
96
- The above copyright notice and this permission notice shall be
97
- included in all copies or substantial portions of the Software.
98
-
99
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
100
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
101
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
102
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
103
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
104
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
105
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile DELETED
@@ -1,19 +0,0 @@
1
- # -*- ruby -*-
2
- require "bundler/gem_tasks"
3
- require 'yard'
4
- require 'rspec/core/rake_task'
5
-
6
- YARD::Rake::YardocTask.new do |t|
7
- # Need this because YardocTask does not read the gemspec
8
- t.files = ['lib/**/*.rb', '-','History.rdoc'] # optional
9
- end
10
-
11
- RSpec::Core::RakeTask.new(:spec)
12
-
13
- desc "FuseFS compatibility specs"
14
- RSpec::Core::RakeTask.new("spec:fusefs") do |t|
15
- t.pattern = 'spec-fusefs/**/*_spec.rb'
16
- end
17
-
18
- task :default => ["spec","spec:fusefs"]
19
- # vim: syntax=ruby
data/TODO.txt DELETED
@@ -1,6 +0,0 @@
1
-
2
- = TODO
3
-
4
- Fix (or remove) samples
5
-
6
-
@@ -1,229 +0,0 @@
1
- module FuseFS
2
-
3
- # This class is equivalent to using Object.new() as the virtual directory
4
- # for target for {FuseFS.start}. It exists primarily to document the API
5
- # but can also be used as a superclass for your filesystem
6
- #
7
- # == Method call sequences
8
- #
9
- # === Stat (getattr)
10
- #
11
- # FUSE itself will generally stat referenced files and validate the results
12
- # before performing any file/directory operations so this sequence is called
13
- # very often
14
- #
15
- # 1. {#directory?} is checked first
16
- # * {#can_write?} OR {#can_mkdir?} with .\_rfusefs_check\_ to determine write permissions
17
- # * {#times} is called to determine atime,mtime,ctime info for the directory
18
- #
19
- # 2. {#file?} is checked next
20
- # * {#can_write?}, {#executable?}, {#size}, {#times} are called to fill out the details
21
- #
22
- # 3. otherwise we tell FUSE that the path does not exist
23
- #
24
- # === List directory
25
- #
26
- # FUSE confirms the path is a directory (via stat above) before we call {#contents}
27
- #
28
- # FUSE will generally go on to stat each directory entry in the results
29
- #
30
- # === Reading files
31
- #
32
- # FUSE confirms path is a file before we call {#read_file}
33
- #
34
- # For fine control of file access see {#raw_open}, {#raw_read}, {#raw_close}
35
- #
36
- # === Writing files
37
- #
38
- # FUSE confirms path for the new file is a directory
39
- #
40
- # * {#can_write?} is checked at file open
41
- # * {#write_to} is called when the file is flushed or closed
42
- #
43
- # See also {#raw_open}, {#raw_truncate}, {#raw_write}, {#raw_close}
44
- #
45
- # === Deleting files
46
- #
47
- # FUSE confirms path is a file before we call {#can_delete?} then {#delete}
48
- #
49
- # === Creating directories
50
- #
51
- # FUSE confirms parent is a directory before we call {#can_mkdir?} then {#mkdir}
52
- #
53
- # === Deleting directories
54
- #
55
- # FUSE confirms path is a directory before we call {#can_rmdir?} then {#rmdir}
56
- #
57
- # === Renaming files and directories
58
- #
59
- # FUSE confirms the rename is valid (eg. not renaming a directory to a file)
60
- #
61
- # * Try {#rename} to see if the virtual directory wants to handle this itself
62
- # * If rename returns false/nil then we try to copy/delete (files only) ie.
63
- # * {#file?}(from), {#can_write?}(to), {#can_delete?}(from) and if all true
64
- # * {#read_file}(from), {#write_to}(to), {#delete}(from)
65
- # * otherwise reject the rename
66
- class FuseDir
67
- INIT_TIMES = Array.new(3,0)
68
-
69
- # base,rest = split_path(path)
70
- # @return [Array<String,String>] base,rest. base is the first directory in
71
- # path, and rest is nil> or the remaining path.
72
- # Typically if rest is not nil? you should
73
- # recurse the paths
74
- def split_path(path)
75
- cur, *rest = path.scan(/[^\/]+/)
76
- if rest.empty?
77
- [ cur, nil ]
78
- else
79
- [ cur, File::SEPARATOR + File.join(rest) ]
80
- end
81
- end
82
-
83
- # base,*rest = scan_path(path)
84
- # @return [Array<String>] all directory and file elements in path. Useful
85
- # when encapsulating an entire fs into one object
86
- def scan_path(path)
87
- path.scan(/[^\/]+/)
88
- end
89
-
90
- # @abstract FuseFS api
91
- # @return [Boolean] true if path is a directory
92
- def directory?(path);return false;end
93
-
94
- # @abstract FuseFS api
95
- # @return [Boolean] true if path is a file
96
- def file?(path);end
97
-
98
- # @abstract FuseFS api
99
- # @return [Array<String>] array of file and directory names within path
100
- def contents(path);return [];end
101
-
102
- # @abstract FuseFS api
103
- # @return [Boolean] true if path is an executable file
104
- def executable?(path);return false;end
105
-
106
- # File size
107
- # @abstract FuseFS api
108
- # @return [Fixnum] the size in byte of a file (lots of applications rely on this being accurate )
109
- def size(path);return 0;end
110
-
111
- # File time information. RFuseFS extension.
112
- # @abstract FuseFS api
113
- # @return [Array<Fixnum, Time>] a 3 element array [ atime, mtime. ctime ] (good for rsync etc)
114
- def times(path);return INIT_TIMES;end
115
-
116
- # @abstract FuseFS api
117
- # @return [String] the contents of the file at path
118
- def read_file(path);return "";end
119
-
120
- # @abstract FuseFS api
121
- # @return [Boolean] true if the user can write to file at path
122
- def can_write?(path);return false;end
123
-
124
- # Write the contents of str to file at path
125
- # @abstract FuseFS api
126
- # @return [void]
127
- def write_to(path,str);end
128
-
129
- # @abstract FuseFS api
130
- # @return [Boolean] true if the user can delete the file at path
131
- def can_delete?(path);return false;end
132
-
133
- # Delete the file at path
134
- # @abstract FuseFS api
135
- # @return [void]
136
- def delete(path);end
137
-
138
- # @abstract FuseFS api
139
- # @return [Boolean] true if user can make a directory at path
140
- def can_mkdir?(path);return false;end
141
-
142
- # Make a directory at path
143
- # @abstract FuseFS api
144
- # @return [void]
145
- def mkdir(path);end
146
-
147
- # @abstract FuseFS api
148
- # @return [Boolean] true if user can remove a directory at path
149
- def can_rmdir?(path);return false;end
150
-
151
- # Remove the directory at path
152
- # @abstract FuseFS api
153
- # @return [void]
154
- def rmdir(path);end
155
-
156
- # Neat toy. Called when a file is touched or has its timestamp explicitly modified
157
- # @abstract FuseFS api
158
- # @return [void]
159
- def touch(path,modtime);end
160
-
161
- # Move a file or directory.
162
- # @abstract FuseFS api
163
- # @return [Boolean] true to indicate the rename has been handled,
164
- # otherwise will fallback to copy/delete
165
- def rename(from_path,to_path);end
166
-
167
- # Raw file access
168
- # @abstract FuseFS api
169
- # @param mode [String] "r","w" or "rw", with "a" if file is opened for append
170
- # @param rfusefs [Boolean] will be "true" if RFuseFS extensions are available
171
- # @return [nil] to indicate raw operations are not implemented
172
- # @return [Object] a filehandle
173
- # Under RFuseFS this object will be passed back in to the other raw
174
- # methods as the optional parameter _raw_
175
- #
176
- def raw_open(path,mode,rfusefs = nil);end
177
-
178
- # RFuseFS extension.
179
- #
180
- # Truncate file at path (or filehandle raw) to offset bytes. Called immediately after a file is opened
181
- # for write without append.
182
- #
183
- # This method can also be invoked (without raw) outside of an open file context. See
184
- # FUSE documentation on truncate() vs ftruncate()
185
- # @abstract FuseFS api
186
- # @return [void]
187
- def raw_truncate(path,off,raw=nil);end
188
-
189
- # Read _sz_ bytes from file at path (or filehandle raw) starting at offset off
190
- #
191
- # @param [String] path
192
- # @param [Fixnum] offset
193
- # @param [Fixnum] size
194
- # @param [Object] raw the filehandle returned by {#raw_open}
195
- # @abstract FuseFS api
196
- # @return [void]
197
- def raw_read(path,offset,size,raw=nil);end
198
-
199
- # Write _sz_ bytes from file at path (or filehandle raw) starting at offset off
200
- # @abstract FuseFS api
201
- # @return [void]
202
- def raw_write(path,off,sz,buf,raw=nil);end
203
-
204
- # Close the file previously opened at path (or filehandle raw)
205
- # @abstract FuseFS api
206
- # @return [void]
207
- def raw_close(path,raw=nil);end
208
-
209
- # RFuseFS extension.
210
- # Extended attributes. These will be set/retrieved/removed directly
211
- # @param [String] path
212
- # @return [Hash] extended attributes for this path
213
- # @abstract FuseFS api
214
- def xattr(path); return {}; end
215
-
216
- # RFuseFS extension.
217
- # Called when the filesystem is mounted
218
- # @return [void]
219
- def mounted();end
220
-
221
- # RFuseFS extension.
222
- # Called when the filesystem is unmounted
223
- # @return [void]
224
- def unmounted();end
225
-
226
- end
227
-
228
- DEFAULT_FS = FuseDir.new()
229
- end
@@ -1,435 +0,0 @@
1
- # RFuseFS - FuseFS over RFuse
2
- require 'rfuse'
3
- require 'fcntl'
4
-
5
- module FuseFS
6
- #Which raw api should we use?
7
- RFUSEFS_COMPATIBILITY = true unless FuseFS.const_defined?(:RFUSEFS_COMPATIBILITY)
8
-
9
- class FileHandle
10
- @@fh = 0
11
- attr_reader :id,:flags,:path
12
- attr_accessor :raw,:contents
13
- def initialize(path,flags)
14
- @id = (@@fh += 1)
15
- @flags = flags
16
- @path = path
17
- @modified = false
18
- @contents = ""
19
- end
20
-
21
- def read(offset,size)
22
- contents[offset,size]
23
- end
24
-
25
- def write(offset,data)
26
- if append? || offset >= contents.length
27
- #ignore offset
28
- contents << data
29
- else
30
- contents[offset,data.length]=data
31
- end
32
- @modified = true
33
- return data.length
34
- end
35
-
36
- def flush
37
- @modified = false
38
- contents
39
- end
40
-
41
- def modified?
42
- @modified
43
- end
44
-
45
- def accmode
46
- flags & Fcntl::O_ACCMODE
47
- end
48
-
49
- def rdwr?
50
- accmode == Fcntl::O_RDWR
51
- end
52
-
53
- def wronly?
54
- accmode == Fcntl::O_WRONLY
55
- end
56
-
57
- def rdonly?
58
- accmode == Fcntl::O_RDONLY
59
- end
60
-
61
- def append?
62
- writing? && (flags & Fcntl::O_APPEND != 0)
63
- end
64
-
65
- def reading?
66
- rdonly? || rdwr?
67
- end
68
-
69
- def writing?
70
- wronly? || rdwr?
71
- end
72
-
73
- def raw_mode
74
- mode_str = case accmode
75
- when Fcntl::O_RDWR; "rw"
76
- when Fcntl::O_RDONLY; "r"
77
- when Fcntl::O_WRONLY; "w"
78
- end
79
-
80
- mode_str << "a" if append?
81
- return mode_str
82
- end
83
- end
84
-
85
- # Implements RFuseFS
86
- # The path supplied to these methods is generally validated by FUSE itself
87
- # with a prior "getattr" call so we do not revalidate here.
88
- # http://sourceforge.net/apps/mediawiki/fuse/index.php?title=FuseInvariants
89
- class RFuseFS
90
- CHECK_FILE="/._rfuse_check_"
91
-
92
- def initialize(root)
93
- @root = root
94
- @created_files = { }
95
-
96
- #Define method missing for our filesystem
97
- #so we can just call all the API methods as required.
98
- def @root.method_missing(method,*args)
99
- # our filesystem might implement method_missing itself
100
- super
101
- rescue NoMethodError
102
- DEFAULT_FS.send(method,*args)
103
- end
104
- end
105
-
106
- def readdir(ctx,path,filler,offset,ffi)
107
-
108
- return wrap_context(ctx,__method__,path,filler,offset,ffi) if ctx
109
-
110
- #Always have "." and ".."
111
- filler.push(".",nil,0)
112
- filler.push("..",nil,0)
113
-
114
- files = @root.contents(path)
115
-
116
- files.each do | filename |
117
- filler.push(filename,nil,0)
118
- end
119
-
120
- end
121
-
122
- def getattr(ctx,path)
123
-
124
- return wrap_context(ctx,__method__,path) if ctx
125
-
126
- uid = Process.gid
127
- gid = Process.uid
128
-
129
- if path == "/" || @root.directory?(path)
130
- #set "w" flag based on can_mkdir? || can_write? to path + "/._rfuse_check"
131
- write_test_path = (path == "/" ? "" : path) + CHECK_FILE
132
-
133
- mode = (@root.can_mkdir?(write_test_path) || @root.can_write?(write_test_path)) ? 0777 : 0555
134
- atime,mtime,ctime = @root.times(path)
135
- #nlink is set to 1 because apparently this makes find work.
136
- return RFuse::Stat.directory(mode,{ :uid => uid, :gid => gid, :nlink => 1, :atime => atime, :mtime => mtime, :ctime => ctime })
137
- elsif @created_files.has_key?(path)
138
- now = Time.now.to_i
139
- return RFuse::Stat.file(@created_files[path],{ :uid => uid, :gid => gid, :atime => now, :mtime => now, :ctime => now })
140
- elsif @root.file?(path)
141
- #Set mode from can_write and executable
142
- mode = 0444
143
- mode |= 0222 if @root.can_write?(path)
144
- mode |= 0111 if @root.executable?(path)
145
- size = @root.size(path)
146
- atime,mtime,ctime = @root.times(path)
147
- return RFuse::Stat.file(mode,{ :uid => uid, :gid => gid, :size => size, :atime => atime, :mtime => mtime, :ctime => ctime })
148
- else
149
- raise Errno::ENOENT.new(path)
150
- end
151
-
152
- end #getattr
153
-
154
- def mkdir(ctx,path,mode)
155
-
156
- return wrap_context(ctx,__method__,path,mode) if ctx
157
-
158
- unless @root.can_mkdir?(path)
159
- raise Errno::EACCES.new(path)
160
- end
161
-
162
- @root.mkdir(path)
163
- end #mkdir
164
-
165
- def mknod(ctx,path,mode,major,minor)
166
-
167
- return wrap_context(ctx,__method__,path,mode,major,minor) if ctx
168
-
169
- unless ((RFuse::Stat::S_IFMT & mode) == RFuse::Stat::S_IFREG ) && @root.can_write?(path)
170
- raise Errno::EACCES.new(path)
171
- end
172
-
173
- @created_files[path] = mode
174
- end #mknod
175
-
176
- #ftruncate - eg called after opening a file for write without append
177
- def ftruncate(ctx,path,offset,ffi)
178
-
179
- return wrap_context(ctx,__method__,path,offset,ffi) if ctx
180
-
181
- fh = ffi.fh
182
-
183
- if fh.raw
184
- @root.raw_truncate(path,offset,fh.raw)
185
- elsif (offset <= 0)
186
- fh.contents = ""
187
- else
188
- fh.contents = fh.contents[0..offset]
189
- end
190
- end
191
-
192
- #truncate a file outside of open files
193
- def truncate(ctx,path,offset)
194
- return wrap_context(ctx,__method__,path,offset) if ctx
195
-
196
- unless @root.can_write?(path)
197
- raise Errno::EACESS.new(path)
198
- end
199
-
200
- unless @root.raw_truncate(path,offset)
201
- contents = @root.read_file(path)
202
- if (offset <= 0)
203
- @root.write_to(path,"")
204
- elsif offset < contents.length
205
- @root.write_to(path,contents[0..offset] )
206
- end
207
- end
208
- end #truncate
209
-
210
- # Open. Create a FileHandler and store in fuse file info
211
- # This will be returned to us in read/write
212
- # No O_CREATE (mknod first?), no O_TRUNC (truncate first)
213
- def open(ctx,path,ffi)
214
- return wrap_context(ctx,__method__,path,ffi) if ctx
215
- fh = FileHandle.new(path,ffi.flags)
216
-
217
- #Save the value return from raw_open to be passed back in raw_read/write etc..
218
- if (FuseFS::RFUSEFS_COMPATIBILITY)
219
- fh.raw = @root.raw_open(path,fh.raw_mode,true)
220
- else
221
- fh.raw = @root.raw_open(path,fh.raw_mode)
222
- end
223
-
224
- unless fh.raw
225
-
226
- if fh.rdonly?
227
- fh.contents = @root.read_file(path)
228
- elsif fh.rdwr? || fh.wronly?
229
- unless @root.can_write?(path)
230
- raise Errno::EACCES.new(path)
231
- end
232
-
233
- if @created_files.has_key?(path)
234
- #we have an empty file
235
- fh.contents = "";
236
- else
237
- if fh.rdwr? || fh.append?
238
- fh.contents = @root.read_file(path)
239
- else #wronly && !append
240
- #We should get a truncate 0, but might as well play it safe
241
- fh.contents = ""
242
- end
243
- end
244
- else
245
- raise Errno::ENOPERM.new(path)
246
- end
247
- end
248
- #If we get this far, save our filehandle in the FUSE structure
249
- ffi.fh=fh
250
-
251
- end
252
-
253
- def read(ctx,path,size,offset,ffi)
254
- return wrap_context(ctx,__method__,path,size,offset,ffi) if ctx
255
-
256
- fh = ffi.fh
257
-
258
- if fh.raw
259
- if FuseFS::RFUSEFS_COMPATIBILITY
260
- return @root.raw_read(path,offset,size,fh.raw)
261
- else
262
- return @root.raw_read(path,offset,size)
263
- end
264
- elsif offset >= 0
265
- return fh.read(offset,size)
266
- else
267
- #TODO: Raise? what does a negative offset mean
268
- return ""
269
- end
270
- rescue EOFError
271
- return ""
272
- end
273
-
274
- def write(ctx,path,buf,offset,ffi)
275
- return wrap_context(ctx,__method__,path,buf,offset,ffi) if ctx
276
- fh = ffi.fh
277
-
278
- if fh.raw
279
- if FuseFS::RFUSEFS_COMPATIBILITY
280
- return @root.raw_write(path,offset,buf.length,buf,fh.raw)
281
- else
282
- @root.raw_write(path,offset,buf.length,buf)
283
- return buf.length
284
- end
285
- else
286
- return fh.write(offset,buf)
287
- end
288
-
289
- end
290
-
291
- def flush(ctx,path,ffi)
292
- return wrap_context(ctx,__method__,path,ffi) if ctx
293
- fh = ffi.fh
294
-
295
- if fh && !fh.raw && fh.modified?
296
- #write contents to the file and mark it unmodified
297
- @root.write_to(path,fh.flush())
298
- #if it was created with mknod it now exists in the filesystem...
299
- @created_files.delete(path)
300
- end
301
-
302
- end
303
-
304
- def release(ctx,path,ffi)
305
- return wrap_context(ctx,__method__,path,ffi) if ctx
306
-
307
- flush(nil,path,ffi)
308
-
309
- fh = ffi.fh
310
- if fh && fh.raw
311
- if (FuseFS::RFUSEFS_COMPATIBILITY)
312
- @root.raw_close(path,fh.raw)
313
- else
314
- @root.raw_close(path)
315
- end
316
- end
317
-
318
- end
319
-
320
- #def chmod(path,mode)
321
- #end
322
-
323
- #def chown(path,uid,gid)
324
- #end
325
-
326
- def utime(ctx,path,actime,modtime)
327
- return wrap_context(ctx,__method__,path,actime,modtime) if ctx
328
-
329
- #Touch...
330
- if @root.respond_to?(:touch)
331
- @root.touch(path,modtime)
332
- end
333
- end
334
-
335
- def unlink(ctx,path)
336
- return wrap_context(ctx,__method__,path) if ctx
337
-
338
- unless @root.can_delete?(path)
339
- raise Errno::EACCES.new(path)
340
- end
341
- @created_files.delete(path)
342
- @root.delete(path)
343
- end
344
-
345
- def rmdir(ctx,path)
346
- return wrap_context(ctx,__method__,path) if ctx
347
-
348
- unless @root.can_rmdir?(path)
349
- raise Errno::EACCES.new(path)
350
- end
351
- @root.rmdir(path)
352
- end
353
-
354
- #def symlink(path,as)
355
- #end
356
-
357
- def rename(ctx,from,to)
358
- return wrap_context(ctx,__method__,from,to) if ctx
359
-
360
- if @root.rename(from,to)
361
- # nothing to do
362
- elsif @root.file?(from) && @root.can_write?(to) && @root.can_delete?(from)
363
- contents = @root.read_file(from)
364
- @root.write_to(to,contents)
365
- @root.delete(from)
366
- else
367
- raise Errno::EACCES.new("Unable to move directory #{from}")
368
- end
369
- end
370
-
371
- #def link(path,as)
372
- #end
373
-
374
- def setxattr(ctx,path,name,value)
375
- return wrap_context(ctx,__method__,path,name,value) if ctx
376
- @root.xattr(path)[name]=value
377
- end
378
-
379
- def getxattr(ctx,path,name)
380
- return wrap_context(ctx,__method__,path,name) if ctx
381
- result = @root.xattr(path)[name]
382
- raise Errno::ENODATA.new("No attribute #{name}") unless result
383
- result.to_s
384
- end
385
-
386
- def listxattr(ctx,path)
387
- return wrap_context(ctx,__method__,path) if ctx
388
- @root.xattr(path).keys
389
- end
390
-
391
- def removexattr(ctx,path,name)
392
- return wrap_context(ctx,__method__,path,name) if ctx
393
- @root.xattr(path).delete(name)
394
- end
395
-
396
- #def opendir(path,ffi)
397
- #end
398
-
399
- #def releasedir(path,ffi)
400
- #end
401
-
402
- #def fsyncdir(path,meta,ffi)
403
- #end
404
-
405
- # Some random numbers to show with df command
406
- #def statfs(path)
407
- #end
408
-
409
- def mounted()
410
- @root.mounted()
411
- end
412
-
413
- def unmounted()
414
- @root.unmounted()
415
- end
416
-
417
- def self.context(ctx,&block)
418
- begin
419
- Thread.current[:fusefs_reader_uid] = ctx.uid
420
- Thread.current[:fusefs_reader_gid] = ctx.gid
421
- yield
422
- ensure
423
- Thread.current[:fusefs_reader_uid] = nil
424
- Thread.current[:fusefs_reader_gid] = nil
425
- end
426
- end
427
-
428
- private
429
-
430
- def wrap_context(ctx,method,*args)
431
- self.class.context(ctx) { send(method,nil,*args) }
432
- end
433
-
434
- end #class RFuseFS
435
- end #Module FuseFS