rfuse-ng 0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ }