rfuse-ng 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|