rfuse-ng 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/CHANGELOG.txt +2 -0
- data/LICENSE +482 -0
- data/README.ng +11 -0
- data/README.rfuse +57 -0
- data/Rakefile +23 -0
- data/THANKS +1 -0
- data/TODO.txt +6 -0
- data/ext/context.c +47 -0
- data/ext/context.h +5 -0
- data/ext/extconf.rb +12 -0
- data/ext/file_info.c +45 -0
- data/ext/file_info.h +11 -0
- data/ext/filler.c +33 -0
- data/ext/filler.h +13 -0
- data/ext/helper.c +20 -0
- data/ext/helper.h +7 -0
- data/ext/intern_rfuse.c +32 -0
- data/ext/intern_rfuse.h +21 -0
- data/ext/rfuse.c +864 -0
- data/ext/rfuse.h +3 -0
- data/ext/rfuse_mod.c +12 -0
- data/sample/test-ruby.rb +353 -0
- data/test/runtest +7 -0
- metadata +82 -0
data/ext/rfuse.h
ADDED
data/ext/rfuse_mod.c
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#include "rfuse.h"
|
2
|
+
#include "filler.h"
|
3
|
+
#include "file_info.h"
|
4
|
+
#include "context.h"
|
5
|
+
|
6
|
+
void Init_rfuse_ng() {
|
7
|
+
VALUE mRFuse=rb_define_module("RFuse");
|
8
|
+
file_info_init(mRFuse);
|
9
|
+
context_init(mRFuse);
|
10
|
+
rfiller_init(mRFuse);
|
11
|
+
rfuse_init(mRFuse);
|
12
|
+
}
|
data/sample/test-ruby.rb
ADDED
@@ -0,0 +1,353 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require "rfuse_ng"
|
4
|
+
|
5
|
+
class MyDir < Hash
|
6
|
+
attr_accessor :name, :mode , :actime, :modtime, :uid, :gid
|
7
|
+
def initialize(name,mode)
|
8
|
+
@uid=0
|
9
|
+
@gid=0
|
10
|
+
@actime=0 #of couse you should use now() here!
|
11
|
+
@modtime=0 # -''-
|
12
|
+
@xattr=Hash.new
|
13
|
+
@name=name
|
14
|
+
@mode=mode | (4 << 12) #yes! we have to do this by hand
|
15
|
+
end
|
16
|
+
def listxattr()
|
17
|
+
@xattr.each {|key,value| list=list+key+"\0"}
|
18
|
+
end
|
19
|
+
def setxattr(name,value,flag)
|
20
|
+
@xattr[name]=value #TODO:don't ignore flag
|
21
|
+
end
|
22
|
+
def getxattr(name)
|
23
|
+
return @xattr[name]
|
24
|
+
end
|
25
|
+
def removexattr(name)
|
26
|
+
@xattr.delete(name)
|
27
|
+
end
|
28
|
+
def dir_mode
|
29
|
+
return (@mode & 170000)>> 12 #see dirent.h
|
30
|
+
end
|
31
|
+
def size
|
32
|
+
return 48 #for testing only
|
33
|
+
end
|
34
|
+
def isdir
|
35
|
+
true
|
36
|
+
end
|
37
|
+
def insert_obj(obj,path)
|
38
|
+
d=self.search(File.dirname(path))
|
39
|
+
if d.isdir then
|
40
|
+
d[obj.name]=obj
|
41
|
+
else
|
42
|
+
raise Errno::ENOTDIR.new(d.name)
|
43
|
+
end
|
44
|
+
return d
|
45
|
+
end
|
46
|
+
def search(path)
|
47
|
+
puts "searching: " + path
|
48
|
+
p=path.split('/').delete_if {|x| x==''}
|
49
|
+
if p.length==0 then
|
50
|
+
puts "found root"
|
51
|
+
return self
|
52
|
+
else
|
53
|
+
return self.follow(p)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
def follow (path_array)
|
57
|
+
puts "following: " + path_array.to_s
|
58
|
+
if path_array.length==0 then
|
59
|
+
puts "found me!" + @name
|
60
|
+
return self
|
61
|
+
else
|
62
|
+
d=self[path_array.shift]
|
63
|
+
if d then
|
64
|
+
return d.follow(path_array)
|
65
|
+
else
|
66
|
+
raise Errno::ENOENT.new
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
def to_s
|
71
|
+
return "Dir: " + @name + "(" + @mode.to_s + ")"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class MyFile
|
76
|
+
attr_accessor :name, :mode, :actime, :modtime, :uid, :gid, :content
|
77
|
+
def initialize(name,mode,uid,gid)
|
78
|
+
@actime=0
|
79
|
+
@modtime=0
|
80
|
+
@xattr=Hash.new
|
81
|
+
@content=""
|
82
|
+
@uid=uid
|
83
|
+
@gid=gid
|
84
|
+
@name=name
|
85
|
+
@mode=mode
|
86
|
+
end
|
87
|
+
def listxattr() #hey this is a raw interface you have to care about the \0
|
88
|
+
list=""
|
89
|
+
@xattr.each {|key,value|
|
90
|
+
list=list+key+"\0"}
|
91
|
+
return list
|
92
|
+
end
|
93
|
+
def setxattr(name,value,flag)
|
94
|
+
@xattr[name]=value #TODO:don't ignore flag
|
95
|
+
end
|
96
|
+
def getxattr(name)
|
97
|
+
return @xattr[name]
|
98
|
+
end
|
99
|
+
def removexattr(name)
|
100
|
+
@xattr.delete(name)
|
101
|
+
end
|
102
|
+
def size
|
103
|
+
return content.size
|
104
|
+
end
|
105
|
+
def dir_mode
|
106
|
+
return (@mode & 170000) >> 12
|
107
|
+
end
|
108
|
+
def isdir
|
109
|
+
false
|
110
|
+
end
|
111
|
+
def follow(path_array)
|
112
|
+
if path_array.length != 0 then
|
113
|
+
raise Errno::ENOTDIR.new
|
114
|
+
else
|
115
|
+
return self
|
116
|
+
end
|
117
|
+
end
|
118
|
+
def to_s
|
119
|
+
return "File: " + @name + "(" + @mode.to_s + ")"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
#TODO: atime,mtime,ctime...nicer classes not only fixnums
|
124
|
+
class Stat
|
125
|
+
attr_accessor :uid,:gid,:mode,:size,:atime,:mtime,:ctime
|
126
|
+
attr_accessor :dev,:ino,:nlink,:rdev,:blksize,:blocks
|
127
|
+
def initialize(uid,gid,mode,size,atime,mtime,ctime,rdev,blocks,nlink,dev,ino,blksize)
|
128
|
+
@uid=uid
|
129
|
+
@gid=gid
|
130
|
+
@mode=mode
|
131
|
+
@size=size
|
132
|
+
@atime=atime
|
133
|
+
@mtime=mtime
|
134
|
+
@ctime=ctime
|
135
|
+
@dev=dev
|
136
|
+
@ino=ino
|
137
|
+
@nlink=nlink
|
138
|
+
@rdev=rdev
|
139
|
+
@blksize=blksize
|
140
|
+
@blocks=blocks
|
141
|
+
end
|
142
|
+
end #class Stat
|
143
|
+
|
144
|
+
module RFuse
|
145
|
+
class Context
|
146
|
+
def to_s
|
147
|
+
'uid:' + uid.to_s + ' gid:' + gid.to_s + ' pid:' + pid.to_s
|
148
|
+
end
|
149
|
+
end
|
150
|
+
class FileInfo
|
151
|
+
def to_s
|
152
|
+
'File_Info:---' + flags.to_s #+ ' writepage:' + writepage.to_s
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
class MyFuse < RFuse::Fuse
|
157
|
+
def initialize(mnt,kernelopt,libopt,root)
|
158
|
+
super(mnt,kernelopt,libopt)
|
159
|
+
@root=root
|
160
|
+
end
|
161
|
+
def readdir(ctx,path,filler,offset,ffi)
|
162
|
+
puts "readdir:"+path
|
163
|
+
puts ctx
|
164
|
+
d=@root.search(path)
|
165
|
+
if d.isdir then
|
166
|
+
puts "getdir: listing directory"
|
167
|
+
d.each {|name,obj|
|
168
|
+
stat=Stat.new(obj.uid,obj.gid,obj.mode,obj.size,obj.actime,obj.modtime,
|
169
|
+
0,0,0,0,0,0,0)
|
170
|
+
filler.push(name,stat,0)
|
171
|
+
}
|
172
|
+
else
|
173
|
+
raise Errno::ENOTDIR.new(path)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def getattr(ctx,path)
|
178
|
+
puts "getattr:" + path
|
179
|
+
puts ctx
|
180
|
+
d=@root.search(path)
|
181
|
+
stat=Stat.new(d.uid,d.gid,d.mode,d.size,d.actime,d.modtime,
|
182
|
+
0,0,0,0,0,0,0)
|
183
|
+
puts d
|
184
|
+
return stat
|
185
|
+
end #getattr
|
186
|
+
|
187
|
+
def mkdir(ctx,path,mode)
|
188
|
+
puts "mkdir:" + path + " Mode:" + mode.to_s
|
189
|
+
puts ctx
|
190
|
+
@root.insert_obj(MyDir.new(File.basename(path),mode),path)
|
191
|
+
end #mkdir
|
192
|
+
|
193
|
+
def mknod(ctx,path,mode,dev)
|
194
|
+
puts "mknod:" + path + " Mode:" + mode.to_s + " Device:" + dev.to_s
|
195
|
+
puts ctx
|
196
|
+
@root.insert_obj(MyFile.new(File.basename(path),mode,ctx.uid,ctx.gid),path)
|
197
|
+
end #mknod
|
198
|
+
def open(ctx,path,ffi)
|
199
|
+
puts "open:" + path
|
200
|
+
puts ctx
|
201
|
+
# puts fi
|
202
|
+
end
|
203
|
+
def release(ctx,path,fi)
|
204
|
+
puts "release:" + path
|
205
|
+
puts ctx
|
206
|
+
# puts fi
|
207
|
+
end
|
208
|
+
def flush(ctx,path,fi)
|
209
|
+
puts "flush:" + path
|
210
|
+
puts ctx
|
211
|
+
# puts fi
|
212
|
+
end
|
213
|
+
def chmod(ctx,path,mode)
|
214
|
+
puts "chmod:" + path + " Mode:" + mode.to_s
|
215
|
+
puts ctx
|
216
|
+
d=@root.search(path)
|
217
|
+
d.mode=mode #TODO: check if this is ok for dir
|
218
|
+
#raise Errno::EPERM.new(path)
|
219
|
+
end
|
220
|
+
def chown(ctx,path,uid,gid)
|
221
|
+
puts "chown:" + path + " UID:" + uid.to_s + " GID:" + gid.to_s
|
222
|
+
puts ctx
|
223
|
+
d=@root.search(path)
|
224
|
+
d.uid=uid
|
225
|
+
d.gid=gid
|
226
|
+
end
|
227
|
+
def truncate(ctx,path,offset)
|
228
|
+
puts "truncate:" + path + " offset: " + offset.to_s
|
229
|
+
puts ctx
|
230
|
+
end
|
231
|
+
def utime(ctx,path,actime,modtime)
|
232
|
+
puts "utime:" + path + " actime:" + actime.to_s +
|
233
|
+
" modtime:" + modtime.to_s
|
234
|
+
puts ctx
|
235
|
+
d=@root.search(path)
|
236
|
+
d.actime=actime
|
237
|
+
d.modtime=modtime
|
238
|
+
end
|
239
|
+
def unlink(ctx,path)
|
240
|
+
puts "utime:" + path
|
241
|
+
puts ctx
|
242
|
+
end
|
243
|
+
def rmdir(ctx,path)
|
244
|
+
puts "rmdir:" + path
|
245
|
+
puts ctx
|
246
|
+
end
|
247
|
+
def symlink(ctx,path,as)
|
248
|
+
puts "symlink:" + path + " as:" + as
|
249
|
+
puts ctx
|
250
|
+
end
|
251
|
+
def rename(ctx,path,as)
|
252
|
+
puts "rename:" + path + " as:" + as
|
253
|
+
puts ctx
|
254
|
+
end
|
255
|
+
def link(ctx,path,as)
|
256
|
+
puts "link:" + path + " as:" + as
|
257
|
+
puts ctx
|
258
|
+
end
|
259
|
+
def read(ctx,path,size,offset,fi)
|
260
|
+
puts "read:" + path + " size:" + size.to_s + " offset:" + offset.to_s
|
261
|
+
puts ctx
|
262
|
+
d=@root.search(path)
|
263
|
+
if (d.isdir)
|
264
|
+
raise Errno::EISDIR.new(path)
|
265
|
+
return nil
|
266
|
+
else
|
267
|
+
return d.content
|
268
|
+
end
|
269
|
+
end
|
270
|
+
def write(ctx,path,buf,size,offset,fi)
|
271
|
+
puts "write:" + path + " size:" + size.to_s + " offset:" + offset.to_s
|
272
|
+
puts ctx
|
273
|
+
puts "content:" + buf
|
274
|
+
d=@root.search(path)
|
275
|
+
if (d.isdir)
|
276
|
+
raise Errno::EISDIR.new(path)
|
277
|
+
else
|
278
|
+
d.content=buf
|
279
|
+
end
|
280
|
+
return nil
|
281
|
+
end
|
282
|
+
def setxattr(ctx,path,name,value,size,flags)
|
283
|
+
puts "setxattr:" + path + " name:" + name +
|
284
|
+
" value:" + value.inspect + " size:" + size.to_s + " flags:" + flags.to_s +
|
285
|
+
" rubysize:" + value.size.to_s
|
286
|
+
puts ctx
|
287
|
+
d=@root.search(path)
|
288
|
+
d.setxattr(name,value,flags)
|
289
|
+
end
|
290
|
+
def getxattr(ctx,path,name,size)
|
291
|
+
puts "getxattr:" + path + " name:" + name +
|
292
|
+
" size:" + size.to_s
|
293
|
+
puts ctx
|
294
|
+
d=@root.search(path)
|
295
|
+
if (d)
|
296
|
+
puts "found:" + d.name
|
297
|
+
value=d.getxattr(name)
|
298
|
+
if (value)
|
299
|
+
puts "return: "+value.to_s + " size:"+value.size.to_s
|
300
|
+
else
|
301
|
+
value=""
|
302
|
+
#raise Errno::ENOENT.new #TODO raise the correct error :
|
303
|
+
#NOATTR which is not implemented in Linux/glibc
|
304
|
+
end
|
305
|
+
else
|
306
|
+
raise Errno::ENOENT.new #TODO put this into DIR and FILE?
|
307
|
+
end
|
308
|
+
return value
|
309
|
+
end
|
310
|
+
def listxattr(ctx,path,size)
|
311
|
+
puts "listxattr:" + path + " size:" + size.to_s
|
312
|
+
puts ctx
|
313
|
+
d=@root.search(path)
|
314
|
+
value= d.listxattr()
|
315
|
+
puts "listxattr return: "+ value
|
316
|
+
return value
|
317
|
+
end
|
318
|
+
def removexattr(ctx,path,name)
|
319
|
+
puts "removexattr:" + path + " name:" + name
|
320
|
+
puts ctx
|
321
|
+
d=@root.search(path)
|
322
|
+
d.removexattr(name)
|
323
|
+
end
|
324
|
+
def opendir(ctx,path,ffi)
|
325
|
+
puts 'opendir:'+ path
|
326
|
+
end
|
327
|
+
def releasedir(ctx,path,ffi)
|
328
|
+
puts 'releasedir:'+ path
|
329
|
+
end
|
330
|
+
def fsyncdir(ctx,path,meta,ffi)
|
331
|
+
puts 'fsyncdir:'+ path
|
332
|
+
end
|
333
|
+
end #class Fuse
|
334
|
+
|
335
|
+
fo=MyFuse.new("/tmp/fuse","allow_other","debug",MyDir.new("",493));
|
336
|
+
#kernel: default_permissions,allow_other,kernel_cache,large_read,direct_io
|
337
|
+
# max_read=N,fsname=NAME
|
338
|
+
#library: debug,hard_remove
|
339
|
+
|
340
|
+
Signal.trap("TERM") do
|
341
|
+
fo.exit
|
342
|
+
fo.unmount
|
343
|
+
end
|
344
|
+
|
345
|
+
begin
|
346
|
+
fo.loop
|
347
|
+
rescue
|
348
|
+
f=File.new("/tmp/error","w+")
|
349
|
+
f.puts "Error:" + $!
|
350
|
+
f.close
|
351
|
+
end
|
352
|
+
|
353
|
+
|
data/test/runtest
ADDED
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rfuse-ng
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- !binary |
|
8
|
+
VGFtw6FzIEzDoXN6bMOzIEbDoWJpw6Fu
|
9
|
+
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2010-05-01 00:00:00 +02:00
|
15
|
+
default_executable:
|
16
|
+
dependencies: []
|
17
|
+
|
18
|
+
description: Ruby language binding for FUSE. It was forked from rfuse
|
19
|
+
email: giganetom@gmail.com
|
20
|
+
executables: []
|
21
|
+
|
22
|
+
extensions:
|
23
|
+
- ext/extconf.rb
|
24
|
+
extra_rdoc_files:
|
25
|
+
- LICENSE
|
26
|
+
- README.ng
|
27
|
+
- README.rfuse
|
28
|
+
files:
|
29
|
+
- .gitignore
|
30
|
+
- CHANGELOG.txt
|
31
|
+
- LICENSE
|
32
|
+
- README.ng
|
33
|
+
- README.rfuse
|
34
|
+
- Rakefile
|
35
|
+
- THANKS
|
36
|
+
- TODO.txt
|
37
|
+
- ext/context.c
|
38
|
+
- ext/context.h
|
39
|
+
- ext/extconf.rb
|
40
|
+
- ext/file_info.c
|
41
|
+
- ext/file_info.h
|
42
|
+
- ext/filler.c
|
43
|
+
- ext/filler.h
|
44
|
+
- ext/helper.c
|
45
|
+
- ext/helper.h
|
46
|
+
- ext/intern_rfuse.c
|
47
|
+
- ext/intern_rfuse.h
|
48
|
+
- ext/rfuse.c
|
49
|
+
- ext/rfuse.h
|
50
|
+
- ext/rfuse_mod.c
|
51
|
+
- sample/test-ruby.rb
|
52
|
+
- test/runtest
|
53
|
+
has_rdoc: true
|
54
|
+
homepage: http://rubyforge.org/projects/rfuse-ng
|
55
|
+
licenses:
|
56
|
+
- LGPL
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options:
|
59
|
+
- --charset=UTF-8
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project: rfuse-ng
|
77
|
+
rubygems_version: 1.3.5
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: Ruby language binding for FUSE
|
81
|
+
test_files: []
|
82
|
+
|