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/ext/rfuse.c ADDED
@@ -0,0 +1,864 @@
1
+ #ifdef linux
2
+ /* For pread()/pwrite() */
3
+ #define _XOPEN_SOURCE 500
4
+ #endif
5
+ //FOR LINUX ONLY
6
+ #include <linux/stat.h>
7
+
8
+ #include <ruby.h>
9
+ #include <fuse.h>
10
+ #include <errno.h>
11
+ #include <sys/statfs.h>
12
+ #ifdef HAVE_SETXATTR
13
+ #include <sys/xattr.h>
14
+ #endif
15
+
16
+ #include "helper.h"
17
+ #include "intern_rfuse.h"
18
+ #include "filler.h"
19
+ #include "context.h"
20
+ #include "file_info.h"
21
+
22
+ static VALUE fuse_object; //this is a global variable where we store the fuse object
23
+
24
+ static int unsafe_return_error(VALUE *args){
25
+ VALUE info;
26
+ info = rb_inspect(ruby_errinfo);
27
+ rb_backtrace();
28
+ printf ("ERROR %s\n",STR2CSTR(info));
29
+ return rb_funcall(info,rb_intern("errno"),0);
30
+ }
31
+ static int return_error(int def_error){
32
+ /*if the raised error has a method errno the return that value else
33
+ return def(ault)_error */
34
+ VALUE res;
35
+ int error = 0;
36
+ res=rb_protect((VALUE (*)())unsafe_return_error,Qnil,&error);
37
+ if (error) { //this exception has no errno method or something else
38
+ //went wrong
39
+ printf ("ERROR: Not an Errno::xxx error or exception in exception!\n");
40
+ return def_error;
41
+ } else {
42
+ return FIX2INT(res);
43
+ }
44
+ }
45
+
46
+ static VALUE unsafe_readdir(VALUE *args){
47
+ VALUE *values=(VALUE*)args;
48
+ VALUE path = values[0];
49
+ VALUE filler = values[1];
50
+ VALUE offset = values[2];
51
+ VALUE ffi = values[3];
52
+ struct fuse_context *ctx = fuse_get_context();
53
+ return rb_funcall(fuse_object,rb_intern("readdir"),5,wrap_context(ctx),path,filler,
54
+ offset,ffi);
55
+ }
56
+
57
+ //call readdir with an Filler object
58
+ static int rf_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
59
+ off_t offset,struct fuse_file_info *ffi)
60
+ {
61
+ VALUE fuse_module;
62
+ VALUE rfiller_class;
63
+ VALUE rfiller_instance;
64
+ VALUE args[4];
65
+ VALUE res;
66
+ struct filler_t *fillerc;
67
+ int error = 0;
68
+
69
+ //create a filler object
70
+ args[0]=rb_str_new2(path);
71
+
72
+ fuse_module = rb_const_get(rb_cObject, rb_intern("RFuse"));
73
+ rfiller_class=rb_const_get(fuse_module,rb_intern("Filler"));
74
+ rfiller_instance=rb_funcall(rfiller_class,rb_intern("new"),0);
75
+ Data_Get_Struct(rfiller_instance,struct filler_t,fillerc);
76
+ fillerc->filler=filler;//Init the filler by hand.... TODO: cleaner
77
+ fillerc->buffer=buf;
78
+ args[1]=rfiller_instance;
79
+ args[2]=INT2NUM(offset);
80
+ args[3]=wrap_file_info(ffi);
81
+ res=rb_protect((VALUE (*)())unsafe_readdir,(VALUE)args,&error);
82
+ if (error) {
83
+ return -(return_error(ENOENT));
84
+ } else {
85
+ return 0;
86
+ };
87
+ }
88
+ //----------------------------------------------
89
+
90
+ static VALUE unsafe_readlink(VALUE *args){
91
+ VALUE *values=(VALUE*)args;
92
+ VALUE path = values[0];
93
+ VALUE size = values[1];
94
+ struct fuse_context *ctx = fuse_get_context();
95
+ return rb_funcall(fuse_object,rb_intern("readlink"),3,wrap_context(ctx),path,size);
96
+ }
97
+
98
+ static int rf_readlink(const char *path, char *buf, size_t size)
99
+ {
100
+ VALUE args[2];
101
+ VALUE res;
102
+ int error = 0;
103
+ args[0]=rb_str_new2(path);
104
+ args[1]=INT2NUM(size);
105
+ char *rbuf;
106
+ res=rb_protect((VALUE (*)())unsafe_readlink,(VALUE)args,&error);
107
+ if (error) {
108
+ return -(return_error(ENOENT));
109
+ } else {
110
+ rbuf=STR2CSTR(res);
111
+ strncpy(buf,rbuf,size);
112
+ return 0;
113
+ }
114
+ }
115
+ //-----------------------------------------
116
+ static VALUE unsafe_getattr(VALUE *args){
117
+ VALUE *values=(VALUE*)args;
118
+ VALUE path = values[0];
119
+ struct fuse_context *ctx=fuse_get_context();
120
+ return rb_funcall(fuse_object,rb_intern("getattr"),2,wrap_context(ctx),path);
121
+ }
122
+
123
+ //calls getattr with path and expects something like FuseStat back
124
+ static int rf_getattr(const char *path, struct stat *stbuf)
125
+ {
126
+ VALUE args[1];
127
+ VALUE res;
128
+ int error = 0;
129
+ args[0]=rb_str_new2(path);
130
+ res=rb_protect((VALUE (*)())unsafe_getattr,(VALUE) args,&error);
131
+ if (error || (res == Qnil)) {
132
+ return -(return_error(ENOENT));
133
+ } else {
134
+ rstat2stat(res,stbuf);
135
+ return 0;
136
+ }
137
+ }
138
+ //----------------------MKDIR
139
+ static VALUE unsafe_mkdir(VALUE *args){
140
+ VALUE *values=(VALUE*)args;
141
+ VALUE path = values[0];
142
+ VALUE mode = values[1];
143
+ struct fuse_context *ctx=fuse_get_context();
144
+ return rb_funcall(fuse_object,rb_intern("mkdir"),3,wrap_context(ctx),path,mode);
145
+ }
146
+
147
+ //calls getattr with path and expects something like FuseStat back
148
+ static int rf_mkdir(const char *path, mode_t mode)
149
+ {
150
+ VALUE args[2];
151
+ VALUE res;
152
+ int error = 0;
153
+ args[0]=rb_str_new2(path);
154
+ args[1]=INT2FIX(mode);
155
+ res=rb_protect((VALUE (*)())unsafe_mkdir,(VALUE) args,&error);
156
+ if (error) {
157
+ return -(return_error(ENOENT));
158
+ } else {
159
+ return 0;
160
+ };
161
+ }
162
+ //----------------------
163
+
164
+ //----------------------MKNOD
165
+ static VALUE unsafe_mknod(VALUE *args){
166
+ VALUE *values=(VALUE*)args;
167
+ VALUE path = values[0];
168
+ VALUE mode = values[1];
169
+ VALUE dev = values[2];
170
+ struct fuse_context *ctx=fuse_get_context();
171
+ return rb_funcall(fuse_object,rb_intern("mknod"),4,wrap_context(ctx),path,mode,dev);
172
+ }
173
+
174
+ //calls getattr with path and expects something like FuseStat back
175
+ static int rf_mknod(const char *path, mode_t mode,dev_t dev)
176
+ {
177
+ VALUE args[3];
178
+ VALUE res;
179
+ int error = 0;
180
+ args[0]=rb_str_new2(path);
181
+ args[1]=INT2FIX(mode);
182
+ args[2]=INT2FIX(dev);
183
+ res=rb_protect((VALUE (*)())unsafe_mknod,(VALUE) args,&error);
184
+ if (error) {
185
+ return -(return_error(ENOENT));
186
+ } else {
187
+ return 0;
188
+ };
189
+ }
190
+ //----------------------
191
+ //----------------------OPEN
192
+ static VALUE unsafe_open(VALUE *args){
193
+ VALUE *values=(VALUE*)args;
194
+ VALUE path = values[0];
195
+ VALUE ffi = values[1];
196
+ struct fuse_context *ctx=fuse_get_context();
197
+ return rb_funcall(fuse_object,rb_intern("open"),3,wrap_context(ctx),path,ffi);
198
+ }
199
+
200
+ //calls getattr with path and expects something like FuseStat back
201
+ static int rf_open(const char *path,struct fuse_file_info *ffi)
202
+ {
203
+ VALUE args[2];
204
+ VALUE res;
205
+ int error = 0;
206
+ args[0]=rb_str_new2(path);
207
+ args[1]=wrap_file_info(ffi);
208
+ res=rb_protect((VALUE (*)())unsafe_open,(VALUE) args,&error);
209
+ if (error) {
210
+ return -(return_error(ENOENT));
211
+ } else {
212
+ return 0;
213
+ };
214
+ }
215
+ //----------------------
216
+ //----------------------RELEASE
217
+ static VALUE unsafe_release(VALUE *args){
218
+ VALUE *values=(VALUE*)args;
219
+ VALUE path = values[0];
220
+ VALUE ffi = values[1];
221
+ struct fuse_context *ctx=fuse_get_context();
222
+ return rb_funcall(fuse_object,rb_intern("release"),3,wrap_context(ctx),path,ffi);
223
+ }
224
+
225
+ static int rf_release(const char *path, struct fuse_file_info *ffi)
226
+ {
227
+ VALUE args[2];
228
+ VALUE res;
229
+ int error = 0;
230
+ args[0]=rb_str_new2(path);
231
+ args[1]=wrap_file_info(ffi);
232
+ res=rb_protect((VALUE (*)())unsafe_release,(VALUE) args,&error);
233
+ if (error) {
234
+ return -(return_error(ENOENT));
235
+ } else {
236
+ return 0;
237
+ };
238
+ }
239
+ //----------------------
240
+ //----------------------FLUSH
241
+ static VALUE unsafe_flush(VALUE *args){
242
+ VALUE *values=(VALUE*)args;
243
+ VALUE path = values[0];
244
+ VALUE ffi=values[1];
245
+ struct fuse_context *ctx=fuse_get_context();
246
+ return rb_funcall(fuse_object,rb_intern("flush"),3,wrap_context(ctx),path,ffi);
247
+ }
248
+
249
+ static int rf_flush(const char *path,struct fuse_file_info *ffi)
250
+ {
251
+ VALUE args[2];
252
+ VALUE res;
253
+ int error = 0;
254
+ args[0]=rb_str_new2(path);
255
+ args[1]=wrap_file_info(ffi);
256
+ res=rb_protect((VALUE (*)())unsafe_flush,(VALUE) args,&error);
257
+ if (error) {
258
+ return -(return_error(ENOENT));
259
+ } else {
260
+ return 0;
261
+ };
262
+ }
263
+ //----------------------
264
+ //----------------------TRUNCATE
265
+ static VALUE unsafe_truncate(VALUE *args){
266
+ VALUE *values=(VALUE*)args;
267
+ VALUE path = values[0];
268
+ VALUE offset = values[1];
269
+ struct fuse_context *ctx=fuse_get_context();
270
+ return rb_funcall(fuse_object,rb_intern("truncate"),3,wrap_context(ctx),path,offset);
271
+ }
272
+
273
+ static int rf_truncate(const char *path,off_t offset)
274
+ {
275
+ VALUE args[2];
276
+ VALUE res;
277
+ int error = 0;
278
+ args[0]=rb_str_new2(path);
279
+ args[1]=INT2FIX(offset);
280
+ res=rb_protect((VALUE (*)())unsafe_truncate,(VALUE) args,&error);
281
+ if (error) {
282
+ return -(return_error(ENOENT));
283
+ } else {
284
+ return 0;
285
+ };
286
+ }
287
+ //----------------------
288
+ //----------------------UTIME
289
+ static VALUE unsafe_utime(VALUE *args){
290
+ VALUE *values=(VALUE*)args;
291
+ VALUE path = values[0];
292
+ VALUE actime = values[1];
293
+ VALUE modtime = values[2];
294
+ struct fuse_context *ctx=fuse_get_context();
295
+ return rb_funcall(fuse_object,rb_intern("utime"),4,wrap_context(ctx),path,actime,modtime);
296
+ }
297
+
298
+ static int rf_utime(const char *path,struct utimbuf *utim)
299
+ {
300
+ VALUE args[3];
301
+ VALUE res;
302
+ int error = 0;
303
+ args[0]=rb_str_new2(path);
304
+ args[1]=INT2NUM(utim->actime);
305
+ args[2]=INT2NUM(utim->modtime);
306
+ res=rb_protect((VALUE (*)())unsafe_utime,(VALUE) args,&error);
307
+ if (error) {
308
+ return -(return_error(ENOENT));
309
+ } else {
310
+ return 0;
311
+ };
312
+ }
313
+ //----------------------
314
+ //----------------------CHOWN
315
+ static VALUE unsafe_chown(VALUE *args){
316
+ VALUE *values=(VALUE*)args;
317
+ VALUE path = values[0];
318
+ VALUE uid = values[1];
319
+ VALUE gid = values[2];
320
+ struct fuse_context *ctx=fuse_get_context();
321
+ return rb_funcall(fuse_object,rb_intern("chown"),4,wrap_context(ctx),path,uid,gid);
322
+ }
323
+
324
+ static int rf_chown(const char *path,uid_t uid,gid_t gid)
325
+ {
326
+ VALUE args[3];
327
+ VALUE res;
328
+ int error = 0;
329
+ args[0]=rb_str_new2(path);
330
+ args[1]=INT2FIX(uid);
331
+ args[2]=INT2FIX(gid);
332
+ res=rb_protect((VALUE (*)())unsafe_chown,(VALUE) args,&error);
333
+ if (error) {
334
+ return -(return_error(ENOENT));
335
+ } else {
336
+ return 0;
337
+ };
338
+ }
339
+ //----------------------
340
+ //----------------------CHMOD
341
+ static VALUE unsafe_chmod(VALUE *args){
342
+ VALUE *values=(VALUE*)args;
343
+ VALUE path = values[0];
344
+ VALUE mode = values[1];
345
+ struct fuse_context *ctx=fuse_get_context();
346
+ return rb_funcall(fuse_object,rb_intern("chmod"),3,wrap_context(ctx),path,mode);
347
+ }
348
+
349
+ static int rf_chmod(const char *path,mode_t mode)
350
+ {
351
+ VALUE args[2];
352
+ VALUE res;
353
+ int error = 0;
354
+ args[0]=rb_str_new2(path);
355
+ args[1]=INT2FIX(mode);
356
+ res=rb_protect((VALUE (*)())unsafe_chmod,(VALUE) args,&error);
357
+ if (error) {
358
+ return -(return_error(ENOENT));
359
+ } else {
360
+ return 0;
361
+ };
362
+ }
363
+ //----------------------
364
+ //----------------------UNLINK
365
+ static VALUE unsafe_unlink(VALUE *args){
366
+ VALUE *values=(VALUE*)args;
367
+ VALUE path = values[0];
368
+ struct fuse_context *ctx=fuse_get_context();
369
+ return rb_funcall(fuse_object,rb_intern("unlink"),2,wrap_context(ctx),path);
370
+ }
371
+
372
+ static int rf_unlink(const char *path)
373
+ {
374
+ VALUE args[1];
375
+ VALUE res;
376
+ int error = 0;
377
+ args[0]=rb_str_new2(path);
378
+ res=rb_protect((VALUE (*)())unsafe_unlink,(VALUE) args,&error);
379
+ if (error) {
380
+ return -(return_error(ENOENT));
381
+ } else {
382
+ return 0;
383
+ };
384
+ }
385
+ //----------------------
386
+ //----------------------RMDIR
387
+ static VALUE unsafe_rmdir(VALUE *args){
388
+ VALUE *values=(VALUE*)args;
389
+ VALUE path = values[0];
390
+ struct fuse_context *ctx=fuse_get_context();
391
+ return rb_funcall(fuse_object,rb_intern("rmdir"),2,wrap_context(ctx),path);
392
+ }
393
+
394
+ static int rf_rmdir(const char *path)
395
+ {
396
+ VALUE args[1];
397
+ VALUE res;
398
+ int error = 0;
399
+ args[0]=rb_str_new2(path);
400
+ res=rb_protect((VALUE (*)())unsafe_rmdir,(VALUE) args,&error);
401
+ if (error) {
402
+ return -(return_error(ENOENT));
403
+ } else {
404
+ return 0;
405
+ };
406
+ }
407
+ //----------------------
408
+ //----------------------SYMLINK
409
+ static VALUE unsafe_symlink(VALUE *args){
410
+ VALUE *values=(VALUE*)args;
411
+ VALUE path = values[0];
412
+ VALUE as = values[1];
413
+ struct fuse_context *ctx=fuse_get_context();
414
+ return rb_funcall(fuse_object,rb_intern("symlink"),3,wrap_context(ctx),path,as);
415
+ }
416
+
417
+ static int rf_symlink(const char *path,const char *as)
418
+ {
419
+ VALUE args[2];
420
+ VALUE res;
421
+ int error = 0;
422
+ args[0]=rb_str_new2(path);
423
+ args[1]=rb_str_new2(as);
424
+ res=rb_protect((VALUE (*)())unsafe_symlink,(VALUE) args,&error);
425
+ if (error) {
426
+ return -(return_error(ENOENT));
427
+ } else {
428
+ return 0;
429
+ };
430
+ }
431
+ //----------------------
432
+ //----------------------RENAME
433
+ static VALUE unsafe_rename(VALUE *args){
434
+ VALUE *values=(VALUE*)args;
435
+ VALUE path = values[0];
436
+ VALUE as = values[1];
437
+ struct fuse_context *ctx=fuse_get_context();
438
+ return rb_funcall(fuse_object,rb_intern("rename"),3,wrap_context(ctx),path,as);
439
+ }
440
+
441
+ static int rf_rename(const char *path,const char *as)
442
+ {
443
+ VALUE args[2];
444
+ VALUE res;
445
+ int error = 0;
446
+ args[0]=rb_str_new2(path);
447
+ args[1]=rb_str_new2(as);
448
+ res=rb_protect((VALUE (*)())unsafe_rename,(VALUE) args,&error);
449
+ if (error) {
450
+ return -(return_error(ENOENT));
451
+ } else {
452
+ return 0;
453
+ };
454
+ }
455
+ //----------------------
456
+ //----------------------LINK
457
+ static VALUE unsafe_link(VALUE *args){
458
+ VALUE *values=(VALUE*)args;
459
+ VALUE path = values[0];
460
+ VALUE as = values[1];
461
+ struct fuse_context *ctx=fuse_get_context();
462
+ return rb_funcall(fuse_object,rb_intern("link"),3,wrap_context(ctx),path,as);
463
+ }
464
+
465
+ static int rf_link(const char *path,const char * as)
466
+ {
467
+ VALUE args[2];
468
+ VALUE res;
469
+ int error = 0;
470
+ args[0]=rb_str_new2(path);
471
+ args[1]=rb_str_new2(as);
472
+ res=rb_protect((VALUE (*)())unsafe_link,(VALUE) args,&error);
473
+ if (error) {
474
+ return -(return_error(ENOENT));
475
+ } else {
476
+ return 0;
477
+ };
478
+ }
479
+ //----------------------
480
+ //----------------------READ
481
+ static VALUE unsafe_read(VALUE *args){
482
+ VALUE *values=(VALUE*)args;
483
+ VALUE path = values[0];
484
+ VALUE size = values[1];
485
+ VALUE offset = values[2];
486
+ VALUE ffi = values[3];
487
+ struct fuse_context *ctx=fuse_get_context();
488
+ return rb_funcall(fuse_object,rb_intern("read"),5,
489
+ wrap_context(ctx),path,size,offset,ffi);
490
+ }
491
+
492
+ static int rf_read(const char *path,char * buf, size_t size,off_t offset,struct fuse_file_info *ffi)
493
+ {
494
+ VALUE args[4];
495
+ VALUE res;
496
+ int error = 0;
497
+ long length=0;
498
+ char* rbuf;
499
+ args[0]=rb_str_new2(path);
500
+ args[1]=INT2NUM(size);
501
+ args[2]=INT2NUM(offset);
502
+ args[3]=wrap_file_info(ffi);
503
+ res=rb_protect((VALUE (*)())unsafe_read,(VALUE) args,&error);
504
+ if (error) {
505
+ return -(return_error(ENOENT));
506
+ } else {
507
+ rbuf=rb_str2cstr(res,&length); //TODO protect this, too
508
+ if (length<=size) {
509
+ memcpy(buf,rbuf,length);
510
+ return length;
511
+ } else {
512
+ memcpy(buf,rbuf,size); //TODO: This could be dangerous.
513
+ //Perhaps raise an exception or return an error
514
+ return size;
515
+ }
516
+ };
517
+ }
518
+ //----------------------
519
+ //----------------------WRITE
520
+ static VALUE unsafe_write(VALUE *args){
521
+ VALUE *values=(VALUE*)args;
522
+ VALUE path = values[0];
523
+ VALUE buffer = values[1];
524
+ VALUE size = values[2];
525
+ VALUE offset = values[3];
526
+ VALUE ffi = values[4];
527
+ struct fuse_context *ctx=fuse_get_context();
528
+ return rb_funcall(fuse_object,rb_intern("write"),6,
529
+ wrap_context(ctx),path,buffer,size,offset,ffi);
530
+ }
531
+
532
+ static int rf_write(const char *path,const char *buf,size_t size, off_t offset,struct fuse_file_info *ffi)
533
+ {
534
+ VALUE args[5];
535
+ VALUE res;
536
+ int error = 0;
537
+ args[0]=rb_str_new2(path);
538
+ args[1]=rb_str_new2(buf);
539
+ args[2]=INT2NUM(size);
540
+ args[3]=INT2NUM(offset);
541
+ args[4]=wrap_file_info(ffi);
542
+ res=rb_protect((VALUE (*)())unsafe_write,(VALUE) args,&error);
543
+ if (error) {
544
+ return -(return_error(ENOENT));
545
+ } else {
546
+ return 0;
547
+ };
548
+ }
549
+ //----------------------
550
+ //----------------------SETXATTR
551
+ static VALUE unsafe_setxattr(VALUE *args){
552
+ VALUE *values=(VALUE*)args;
553
+ VALUE path = values[0];
554
+ VALUE name = values[1];
555
+ VALUE value = values[2];
556
+ VALUE size = values[3];
557
+ VALUE flags = values[4];
558
+ struct fuse_context *ctx=fuse_get_context();
559
+ return rb_funcall(fuse_object,rb_intern("setxattr"),6,
560
+ wrap_context(ctx),path,name,value,size,flags);
561
+ }
562
+
563
+ static int rf_setxattr(const char *path,const char *name,
564
+ const char *value, size_t size, int flags)
565
+ {
566
+ VALUE args[5];
567
+ VALUE res;
568
+ int error = 0;
569
+ args[0]=rb_str_new2(path);
570
+ args[1]=rb_str_new2(name);
571
+ args[2]=rb_str_new(value,size);
572
+ args[3]=INT2NUM(size); //TODO:FIX would be faster
573
+ args[4]=INT2NUM(flags);
574
+ res=rb_protect((VALUE (*)())unsafe_setxattr,(VALUE) args,&error);
575
+ if (error) {
576
+ return -(return_error(ENOENT));
577
+ } else {
578
+ return 0;
579
+ };
580
+ }
581
+ //----------------------
582
+ //----------------------GETXATTR
583
+ static VALUE unsafe_getxattr(VALUE *args){
584
+ VALUE *values=(VALUE*)args;
585
+ VALUE path = values[0];
586
+ VALUE name = values[1];
587
+ VALUE size = values[2];
588
+ struct fuse_context *ctx=fuse_get_context();
589
+ return rb_funcall(fuse_object,rb_intern("getxattr"),4,
590
+ wrap_context(ctx),path,name,size);
591
+ }
592
+
593
+ static int rf_getxattr(const char *path,const char *name,char *buf,
594
+ size_t size)
595
+ {
596
+ VALUE args[3];
597
+ VALUE res;
598
+ char *rbuf;
599
+ long length = 0;
600
+ int error = 0;
601
+ args[0]=rb_str_new2(path);
602
+ args[1]=rb_str_new2(name);
603
+ args[2]=INT2NUM(size);
604
+ res=rb_protect((VALUE (*)())unsafe_getxattr,(VALUE) args,&error);
605
+ if (error) {
606
+ return -(return_error(ENOENT));
607
+ } else {
608
+ rbuf=rb_str2cstr(res,&length); //TODO protect this, too
609
+ if (buf != NULL) {
610
+ memcpy(buf,rbuf,length); //First call is just to get the length
611
+ //TODO optimize
612
+ }
613
+ return length;
614
+ }
615
+ }
616
+ //----------------------
617
+ //----------------------LISTXATTR
618
+ static VALUE unsafe_listxattr(VALUE *args){
619
+ VALUE *values=(VALUE*)args;
620
+ VALUE path = values[0];
621
+ VALUE size = values[1];
622
+ struct fuse_context *ctx=fuse_get_context();
623
+ return rb_funcall(fuse_object,rb_intern("listxattr"),3,
624
+ wrap_context(ctx),path,size);
625
+ }
626
+
627
+ static int rf_listxattr(const char *path,char *buf,
628
+ size_t size)
629
+ {
630
+ VALUE args[2];
631
+ VALUE res;
632
+ char *rbuf;
633
+ size_t length =0;
634
+ int error = 0;
635
+ args[0]=rb_str_new2(path);
636
+ args[1]=INT2NUM(size);
637
+ res=rb_protect((VALUE (*)())unsafe_listxattr,(VALUE) args,&error);
638
+ if (error) {
639
+ return -(return_error(ENOENT));
640
+ } else {
641
+ rbuf=rb_str2cstr(res,(long *)&length); //TODO protect this, too
642
+ if (buf != NULL){
643
+ if (length<=size) {
644
+ memcpy(buf,rbuf,length); //check for size
645
+ } else {
646
+ return -ERANGE;
647
+ }
648
+ printf("destination: %s,%d\n",buf,size);
649
+ printf("source: %s,%d\n",rbuf,length);
650
+ return length;
651
+ //TODO optimize,check lenght
652
+ } else {
653
+ printf ("not copied: %s, %d\n",buf,length);
654
+ return length;
655
+ }
656
+ }
657
+ }
658
+ //----------------------
659
+ //----------------------REMOVEXATTR
660
+ static VALUE unsafe_removexattr(VALUE *args){
661
+ VALUE *values=(VALUE*)args;
662
+ VALUE path = values[0];
663
+ VALUE name = values[1];
664
+ struct fuse_context *ctx=fuse_get_context();
665
+ return rb_funcall(fuse_object,rb_intern("removexattr"),3,
666
+ wrap_context(ctx),path,name);
667
+ }
668
+
669
+ static int rf_removexattr(const char *path,const char *name)
670
+ {
671
+ VALUE args[2];
672
+ VALUE res;
673
+ int error = 0;
674
+ args[0]=rb_str_new2(path);
675
+ args[1]=rb_str_new2(name);
676
+ res=rb_protect((VALUE (*)())unsafe_removexattr,(VALUE) args,&error);
677
+ if (error) {
678
+ return -(return_error(ENOENT));
679
+ } else {
680
+ return 0;
681
+ };
682
+ }
683
+ //----------------------
684
+ //----------------------OPENDIR
685
+ static VALUE unsafe_opendir(VALUE *args){
686
+ VALUE *values=(VALUE*)args;
687
+ VALUE path = values[0];
688
+ VALUE ffi = values[1];
689
+ struct fuse_context *ctx=fuse_get_context();
690
+ return rb_funcall(fuse_object,rb_intern("opendir"),3,wrap_context(ctx),path,ffi);
691
+ }
692
+
693
+ static int rf_opendir(const char *path,struct fuse_file_info *ffi)
694
+ {
695
+ VALUE args[2];
696
+ VALUE res;
697
+ int error = 0;
698
+ args[0]=rb_str_new2(path);
699
+ args[1]=wrap_file_info(ffi);
700
+ res=rb_protect((VALUE (*)())unsafe_opendir,(VALUE) args,&error);
701
+ if (error) {
702
+ return -(return_error(ENOENT));
703
+ } else {
704
+ return 0;
705
+ };
706
+ }
707
+ //----------------------
708
+ //----------------------RELEASEDIR
709
+ static VALUE unsafe_releasedir(VALUE *args){
710
+ VALUE *values=(VALUE*)args;
711
+ VALUE path = values[0];
712
+ VALUE ffi = values[1];
713
+ struct fuse_context *ctx=fuse_get_context();
714
+ return rb_funcall(fuse_object,rb_intern("releasedir"),3,wrap_context(ctx),path,ffi);
715
+ }
716
+
717
+ static int rf_releasedir(const char *path,struct fuse_file_info *ffi)
718
+ {
719
+ VALUE args[2];
720
+ VALUE res;
721
+ int error = 0;
722
+ args[0]=rb_str_new2(path);
723
+ args[1]=wrap_file_info(ffi);
724
+ res=rb_protect((VALUE (*)())unsafe_releasedir,(VALUE) args,&error);
725
+ if (error) {
726
+ return -(return_error(ENOENT));
727
+ } else {
728
+ return 0;
729
+ };
730
+ }
731
+ //----------------------
732
+ //----------------------FSYNCDIR
733
+ static VALUE unsafe_fsyncdir(VALUE *args){
734
+ VALUE *values=(VALUE*)args;
735
+ VALUE path = values[0];
736
+ VALUE meta = values[1];
737
+ VALUE ffi = values[2];
738
+ struct fuse_context *ctx=fuse_get_context();
739
+ return rb_funcall(fuse_object,rb_intern("fsyncdir"),3,wrap_context(ctx),path,
740
+ meta,ffi);
741
+ }
742
+
743
+ static int rf_fsyncdir(const char *path,int meta,struct fuse_file_info *ffi)
744
+ {
745
+ VALUE args[3];
746
+ VALUE res;
747
+ int error = 0;
748
+ args[0]=rb_str_new2(path);
749
+ args[1]=INT2NUM(meta);
750
+ args[2]=wrap_file_info(ffi);
751
+ res=rb_protect((VALUE (*)())unsafe_fsyncdir,(VALUE) args,&error);
752
+ if (error) {
753
+ return -(return_error(ENOENT));
754
+ } else {
755
+ return 0;
756
+ };
757
+ }
758
+ //----------------------
759
+
760
+ static VALUE rf_loop(VALUE self){
761
+ struct intern_fuse *inf;
762
+ Data_Get_Struct(self,struct intern_fuse,inf);
763
+ fuse_loop(inf->fuse);
764
+ return Qnil;
765
+ }
766
+
767
+ /*static VALUE rf_loop_mt(VALUE self){
768
+ struct intern_fuse *inf;
769
+ Data_Get_Struct(self,struct intern_fuse,inf);
770
+ fuse_loop_mt(inf->fuse);
771
+ return Qnil;
772
+ }*/
773
+
774
+ VALUE rf_exit(VALUE self){
775
+ struct intern_fuse *inf;
776
+ Data_Get_Struct(self,struct intern_fuse,inf);
777
+ fuse_exit(inf->fuse);
778
+ return Qnil;
779
+ }
780
+
781
+ VALUE rf_unmount(VALUE self){
782
+ struct intern_fuse *inf;
783
+ Data_Get_Struct(self,struct intern_fuse,inf);
784
+ fuse_unmount(inf->mountname);
785
+ return Qnil;
786
+ }
787
+
788
+ VALUE rf_mountname(VALUE self){
789
+ struct intern_fuse *inf;
790
+ Data_Get_Struct(self,struct intern_fuse,inf);
791
+ return rb_str_new2(inf->mountname);
792
+ }
793
+ VALUE rf_invalidate(VALUE self,VALUE path){
794
+ struct intern_fuse *inf;
795
+ Data_Get_Struct(self,struct intern_fuse,inf);
796
+ return fuse_invalidate(inf->fuse,STR2CSTR(path)); //TODO: check if str?
797
+ }
798
+ //-------------RUBY
799
+
800
+
801
+ static VALUE rf_initialize(VALUE self,VALUE mountpoint,VALUE kernelopts,
802
+ VALUE libopts) {
803
+ struct intern_fuse *inf;
804
+ Data_Get_Struct(self,struct intern_fuse,inf);
805
+ inf->fuse_op.getattr=rf_getattr;
806
+ // inf->fuse_op.getdir=rf_getdir;
807
+ inf->fuse_op.readlink=rf_readlink;
808
+ inf->fuse_op.mkdir=rf_mkdir;
809
+ inf->fuse_op.mknod=rf_mknod;
810
+ inf->fuse_op.open=rf_open;
811
+ inf->fuse_op.release=rf_release; //optional
812
+ inf->fuse_op.flush=rf_flush; //optional
813
+ inf->fuse_op.chmod=rf_chmod; //setattr
814
+ inf->fuse_op.chown=rf_chown; //setattr
815
+ inf->fuse_op.truncate=rf_truncate;//setattr
816
+ inf->fuse_op.utime=rf_utime; //settattr
817
+ inf->fuse_op.unlink=rf_unlink;
818
+ inf->fuse_op.rmdir=rf_rmdir;
819
+ inf->fuse_op.symlink=rf_symlink;
820
+ inf->fuse_op.rename=rf_rename;
821
+ inf->fuse_op.link=rf_link;
822
+ inf->fuse_op.read=rf_read;
823
+ inf->fuse_op.write=rf_write;
824
+ inf->fuse_op.setxattr=rf_setxattr;
825
+ inf->fuse_op.getxattr=rf_getxattr;
826
+ inf->fuse_op.listxattr=rf_listxattr;
827
+ inf->fuse_op.removexattr=rf_removexattr;
828
+ inf->fuse_op.readdir=rf_readdir;
829
+ inf->fuse_op.opendir=rf_opendir;
830
+ inf->fuse_op.releasedir=rf_releasedir;
831
+ inf->fuse_op.fsyncdir=rf_fsyncdir;
832
+
833
+ /* TODO
834
+ inf->fuse_op.statfs=rf_statfs;
835
+ inf->fuse_op.fsnyc=rf_fsync; //option
836
+ */
837
+
838
+ intern_fuse_init(inf,STR2CSTR(mountpoint),STR2CSTR(kernelopts),
839
+ STR2CSTR(libopts));
840
+ fuse_object=self; // this won't work with multithreading!!!
841
+ return self;
842
+ }
843
+
844
+ static VALUE rf_new(VALUE class){
845
+ struct intern_fuse *inf;
846
+ VALUE self;
847
+ inf = intern_fuse_new();
848
+ self=Data_Wrap_Struct(class, 0,intern_fuse_destroy,inf);
849
+ return self;
850
+ }
851
+
852
+ VALUE rfuse_init(VALUE module){
853
+ VALUE cFuse=rb_define_class_under(module,"Fuse",rb_cObject);
854
+ rb_define_alloc_func(cFuse,rf_new);
855
+ //initialize: string mountpoint,string kernel_opts,string lib_opts
856
+ rb_define_method(cFuse,"initialize",rf_initialize,3);
857
+ rb_define_method(cFuse,"loop",rf_loop,0);
858
+ //rb_define_method(cFuse,"loop_mt",rf_loop_mt,0); TODO: not until RIKE!
859
+ rb_define_method(cFuse,"exit",rf_exit,0);
860
+ rb_define_method(cFuse,"invalidate",rf_invalidate,1);
861
+ rb_define_method(cFuse,"unmount",rf_unmount,0);
862
+ rb_define_method(cFuse,"mountname",rf_mountname,0);
863
+ return cFuse;
864
+ }