plptools
Loading...
Searching...
No Matches
fuse.c
Go to the documentation of this file.
1/*
2 plpfuse: Expose EPOC's file system via FUSE
3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4 Copyright (C) 2007-2024 Reuben Thomas <rrt@sc3d.org>
5 Copyright (C) 2026 Syed Shahrukh Hussain <syed.shahrukh@ossrevival.org>
6
7 This program can be distributed under the terms of the GNU GPL.
8 See the file COPYING.
9*/
10
11#include "config.h"
12
13#include <stdarg.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <unistd.h>
18#include <fcntl.h>
19#include <errno.h>
20#include <sys/time.h>
21#include <syslog.h>
22#ifdef HAVE_ATTR_XATTR_H
23#include <attr/xattr.h>
24#elif defined(HAVE_SYS_XATTR_H)
25#include <sys/xattr.h>
26#endif
27
28#ifndef ENOATTR
29#define ENOATTR ENODATA
30#endif
31#ifdef HAVE_ATTR_ATTRIBUTES_H
32#include <attr/attributes.h>
33#endif
34
35#include "plpfuse.h"
36#include "rfsv_api.h"
37
38/* Name of our extended attribute */
39#define XATTR_NAME "user.epoc"
40
41/* Maximum length of a generated psion xattr string */
42#define XATTR_MAXLEN 3
43
44#ifndef ENOMEDIUM
45#define ENOMEDIUM ENODEV
46#endif
47
49
50void
51debuglog(const char *fmt, ...)
52{
53 va_list ap;
54 char *buf;
55
56 if (!debug)
57 return;
58 va_start(ap, fmt);
59 if (vasprintf(&buf, fmt, ap) == -1)
60 syslog(LOG_DEBUG, "vasprintf error in debuglog");
61 else {
62 syslog(LOG_DEBUG, "%s", buf);
63 free(buf);
64 }
65 va_end(ap);
66}
67
68static void
69xattr2pattr(long *psisattr, long *psidattr, const char *oxattr, const char *nxattr)
70{
71 if ((strchr(oxattr, 'a') == NULL) != (strchr(nxattr, 'a') == NULL)) { /* a = archive */
72 if (strchr(nxattr, 'a'))
73 *psisattr |= PSI_A_ARCHIVE;
74 else
75 *psidattr |= PSI_A_ARCHIVE;
76 }
77 if ((strchr(oxattr, 'h') == NULL) != (strchr(nxattr, 'h') == NULL)) { /* h = hidden */
78 if (strchr(nxattr, 'h'))
79 *psisattr |= PSI_A_HIDDEN;
80 else
81 *psidattr |= PSI_A_HIDDEN;
82 }
83 if ((strchr(oxattr, 's') == NULL) != (strchr(nxattr, 's') == NULL)) { /* s = system */
84 if (strchr(nxattr, 's'))
85 *psisattr |= PSI_A_SYSTEM;
86 else
87 *psidattr |= PSI_A_SYSTEM;
88 }
89}
90
91static void
92attr2pattr(long oattr, long nattr, char *oxattr, char *nxattr, long *psisattr, long *psidattr)
93{
94 *psisattr = *psidattr = 0;
95 if ((oattr & 0400) != (nattr & 0400)) {
96 if (nattr & 0400) /* readable */
97 *psisattr |= PSI_A_READ;
98 else
99 *psidattr |= PSI_A_READ;
100 }
101 if ((oattr & 0200) != (nattr & 0200)) {
102 if (nattr & 0200) /* Not writable -> readonly */
103 *psidattr |= PSI_A_RDONLY;
104 else
105 *psisattr |= PSI_A_RDONLY;
106 }
107 xattr2pattr(psisattr, psidattr, oxattr, nxattr);
108}
109
110static void
111pattr2xattr(long psiattr, char *xattr)
112{
113 *xattr = '\0';
114
115 if (psiattr & PSI_A_HIDDEN)
116 strcat(xattr, "h");
117 if (psiattr & PSI_A_SYSTEM)
118 strcat(xattr, "s");
119 if (psiattr & PSI_A_ARCHIVE)
120 strcat(xattr, "a");
121}
122
123static void
124pattr2attr(long psiattr, long size, long ftime, struct stat *st, char *xattr)
125{
126 struct fuse_context *ct = fuse_get_context();
127
128 memset(st, 0, sizeof(*st));
129 st->st_uid = ct->uid;
130 st->st_gid = ct->gid;
131
132 if (psiattr & PSI_A_DIR) {
133 st->st_mode = 0700 | S_IFDIR;
134 st->st_blocks = 1;
135 st->st_size = BLOCKSIZE;
136 st->st_nlink = 2; /* Call getlinks for more accurate count */
137 } else {
138 st->st_blocks = (size + BLOCKSIZE - 1) / BLOCKSIZE;
139 st->st_size = size;
140 st->st_nlink = 1;
141 st->st_mode = S_IFREG;
142
143 if (psiattr & PSI_A_READ)
144 st->st_mode |= 0400; /* File readable */
145 if (!(psiattr & PSI_A_RDONLY))
146 st->st_mode |= 0200; /* File writeable */
147 }
148 st->st_mtime = st->st_ctime = st->st_atime = ftime;
149 pattr2xattr(psiattr, xattr);
150}
151
153
154static int
156{
157 device *dp, *np;
158 int link_count = 2; /* set the root link count */
159
160 for (dp = devices; dp; dp = np) {
161 np = dp->next;
162 free(dp->name);
163 free(dp);
164 }
165 devices = NULL;
166 if (rfsv_drivelist(&link_count, &devices))
167 return 1;
168 return 0;
169}
170
171static char *
172dirname(const char *dir)
173{
174 static char *namebuf = NULL;
175 if (namebuf)
176 free(namebuf);
177 if (asprintf(&namebuf, "%s\\", dir) == -1)
178 return NULL;
179 return namebuf;
180}
181
182static const char *
183filname(const char *dir)
184{
185 char *p;
186 if ((p = (char *) rindex(dir, '\\')))
187 return p + 1;
188 else
189 return dir;
190}
191
192static int
193dircount(const char *path, long *count)
194{
195 dentry *e = NULL;
196 long ret = 0;
197
198 *count = 0;
199 debuglog("dircount: %s", path);
200 debuglog("RFSV dir %s", path);
201 if ((ret = rfsv_dir(dirname(path), &e)) != 0)
202 return ret;
203 while (e) {
204 struct stat st;
205 dentry *o = e;
206 char xattr[XATTR_MAXLEN + 1];
207 pattr2attr(e->attr, e->size, e->time, &st, xattr);
208 free(e->name);
209 e = e->next;
210 free(o);
211 if (st.st_nlink > 1)
212 (*count)++;
213 }
214
215 debuglog("count %d", *count);
216 return ret;
217}
218
219static int getlinks(const char *path, struct stat *st)
220{
221 long dcount;
222 int ret = dircount(path, &dcount);
223 if (ret == 0)
224 st->st_nlink = dcount + 2;
225 return ret;
226}
227#if FUSE_USE_VERSION >= 30
228static int plp_getattr(const char *path, struct stat *st, struct fuse_file_info *fi)
229#else
230static int plp_getattr(const char *path, struct stat *st)
231#endif
232{
233 char xattr[XATTR_MAXLEN + 1];
234 int ret = 0;
235#if FUSE_USE_VERSION >= 30
236 (void)fi;
237#endif
238 debuglog("plp_getattr `%s'", ++path);
239
240 if (strcmp(path, "") == 0) {
241 pattr2attr(PSI_A_DIR, 0, 0, st, xattr);
242 if (!query_devices()) {
243 device *dp;
244
245 for (dp = devices; dp; dp = dp->next)
246 st->st_nlink++;
247 debuglog("root has %d links", st->st_nlink);
248 } else
249 return rfsv_isalive() ? -ENOENT : -ENOMEDIUM;
250 } else {
251 long pattr, psize, ptime;
252
253 if (strlen(path) == 2 && path[1] == ':') {
254 debuglog("getattr: device");
255 if (!query_devices()) {
256 device *dp;
257
258 for (dp = devices; dp; dp = dp->next) {
259 debuglog("cmp '%c', '%c'", dp->letter, path[0]);
260 if (dp->letter == path[0])
261 break;
262 }
263 debuglog("device: %s", dp ? "exists" : "does not exist");
264 pattr2attr(PSI_A_DIR, 0, 0, st, xattr);
265 return getlinks(path, st);
266 } else
267 return rfsv_isalive() ? -ENOENT : -ENOMEDIUM;
268 }
269
270 debuglog("getattr: fileordir");
271 if ((ret = rfsv_getattr(path, &pattr, &psize, &ptime)) == 0) {
272 pattr2attr(pattr, psize, ptime, st, xattr);
273 debuglog(" attrs Psion: %x %d %d, UNIX modes: %o, xattrs: %s", pattr, psize, ptime, st->st_mode, xattr);
274 if (st->st_nlink > 1)
275 ret = getlinks(path, st);
276 }
277 }
278
279 debuglog("getattr: returned %d", ret);
280 return ret;
281}
282
283static int plp_access(const char *path, int mask)
284{
285 (void)mask;
286 debuglog("plp_access `%s'", ++path);
287 return 0;
288}
289
290static int plp_readlink(const char *path, char *buf, size_t size)
291{
292 (void)buf;
293 (void)size;
294 debuglog("plp_readlink `%s'", ++path);
295 return -EINVAL;
296}
297
298#if FUSE_USE_VERSION >= 30
299static int plp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
300 off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags flags)
301#else
302static int plp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
303 off_t offset, struct fuse_file_info *fi)
304#endif
305{
306 device *dp;
307 dentry *e = NULL;
308 char xattr[XATTR_MAXLEN + 1];
309#if FUSE_USE_VERSION >= 30
310 enum fuse_fill_dir_flags fill_flags = FUSE_FILL_DIR_DEFAULTS;
311
312 if (flags & FUSE_READDIR_PLUS) {
313 fill_flags |= FUSE_FILL_DIR_PLUS;
314 }
315#endif
316 debuglog("plp_readdir `%s'", ++path);
317
318 (void)offset;
319 (void)fi;
320
321 if (strcmp(path, "") == 0) {
322 debuglog("readdir root");
323 if (query_devices() == 0) {
324 for (dp = devices; dp; dp = dp->next) {
325 struct stat st;
326 unsigned char name[3];
327
328 name[0] = dp->letter;
329 name[1] = ':';
330 name[2] = '\0';
331 pattr2attr(dp->attrib, 1, 0, &st, xattr);
332#if FUSE_USE_VERSION >= 30
333 if (filler(buf, (char *)name, &st, 0, fill_flags))
334#else
335 if (filler(buf, (char *)name, &st, 0))
336#endif
337 break;
338 }
339 }
340 } else {
341 int ret;
342 debuglog("RFSV dir `%s'", dirname(path));
343 if ((ret = rfsv_dir(dirname(path), &e)) != 0)
344 return ret;
345
346 debuglog("scanning contents");
347 while (e) {
348 dentry *o;
349 struct stat st;
350 const char *name = filname(e->name);
351
352 pattr2attr(e->attr, e->size, e->time, &st, xattr);
353 debuglog(" %s %o %d %d", name, st.st_mode, st.st_size, st.st_mtime);
354#if FUSE_USE_VERSION >= 30
355 if (filler(buf, name, &st, 0, fill_flags))
356#else
357 if (filler(buf, name, &st, 0))
358#endif
359 break;
360 free(e->name);
361 o = e;
362 e = e->next;
363 free(o);
364 }
365 }
366
367 debuglog("readdir OK");
368 return 0;
369}
370
371static int plp_mknod(const char *path, mode_t mode, dev_t dev)
372{
373 int ret = -EINVAL;
374
375 debuglog("plp_mknod `%s' %o", ++path, mode);
376
377 if (S_ISREG(mode) && dev == 0) {
378 uint32_t phandle;
379 if ((ret = rfsv_fcreate(0x200, path, &phandle)) == 0)
380 rfsv_fclose(phandle);
381 }
382
383 return ret;
384}
385
386static int plp_mkdir(const char *path, mode_t mode)
387{
388 debuglog("plp_mkdir `%s' %o", ++path, mode);
389 return rfsv_mkdir(path);
390}
391
392static int plp_unlink(const char *path)
393{
394 debuglog("plp_unlink `%s'", ++path);
395 return rfsv_remove(path);
396}
397
398static int plp_rmdir(const char *path)
399{
400 debuglog("plp_rmdir `%s'", ++path);
401 return rfsv_rmdir(path);
402}
403
404static int plp_symlink(const char *from, const char *to)
405{
406 debuglog("plp_symlink `%s' -> `'%s'", ++from, ++to);
407 return -EPERM;
408}
409
410#if FUSE_USE_VERSION >= 30
411static int plp_rename(const char *from, const char *to, unsigned int flag)
412#else
413static int plp_rename(const char *from, const char *to)
414#endif
415{
416#if FUSE_USE_VERSION >= 30
417 (void)flag;
418#endif
419 debuglog("plp_rename `%s' -> `%s'", ++from, ++to);
420 rfsv_remove(to);
421 return rfsv_rename(from, to);
422}
423
424static int plp_link(const char *from, const char *to)
425{
426 debuglog("plp_link `%s' -> `%s'", ++from, ++to);
427 return -EPERM;
428}
429
430#if FUSE_USE_VERSION >= 30
431static int plp_chmod(const char *path, mode_t mode, struct fuse_file_info *fi)
432#else
433static int plp_chmod(const char *path, mode_t mode)
434#endif
435{
436 int ret;
437 long psisattr, psidattr, pattr, psize, ptime;
438 struct stat st;
439 char xattr[XATTR_MAXLEN + 1];
440
441#if FUSE_USE_VERSION >= 30
442 (void)fi;
443#endif
444 debuglog("plp_chmod `%s'", ++path);
445
446 if ((ret = rfsv_getattr(path, &pattr, &psize, &ptime)) == 0) {
447 pattr2attr(pattr, psize, ptime, &st, xattr);
448 attr2pattr(st.st_mode, mode, "", "", &psisattr, &psidattr);
449 debuglog(" UNIX old, new: %o, %o; Psion set, clear: %x, %x", st.st_mode, mode, psisattr, psidattr);
450 if ((ret = rfsv_setattr(path, psisattr, psidattr)) == 0)
451 debuglog("chmod succeeded");
452 }
453
454 return ret;
455}
456
457static int plp_getxattr(const char *path, const char *name, char *value, size_t size
458#ifdef __APPLE__
459 , _GL_UNUSED uint32_t position
460#endif
461 )
462{
463 debuglog("plp_getxattr `%s' %s", ++path, name);
464 if (strcmp(name, XATTR_NAME) == 0) {
465 if (size >= XATTR_MAXLEN) {
466 long pattr, psize, ptime;
467 int ret;
468 if ((ret = rfsv_getattr(path, &pattr, &psize, &ptime)) == 0) {
469 pattr2xattr(pattr, value);
470 debuglog("getxattr succeeded: %s", value);
471 return strlen(value);
472 } else
473 return ret;
474 } else {
475 debuglog("only gave %d bytes, need %d", size, XATTR_MAXLEN);
476 return XATTR_MAXLEN;
477 }
478 }
479 return 0;
480}
481
482static int plp_setxattr(const char *path, const char *name, const char *value, size_t size, int flags
483#ifdef __APPLE__
484 , _GL_UNUSED uint32_t position
485#endif
486 )
487{
488 debuglog("plp_setxattr `%s'", ++path);
489 if (strcmp(name, XATTR_NAME) == 0) {
490 int ret;
491 long psisattr, psidattr;
492 char oxattr[XATTR_MAXLEN + 1], nxattr[XATTR_MAXLEN + 1];
493
494#ifdef XATTR_CREATE
495 if (flags & XATTR_CREATE)
496 return -EEXIST;
497#endif
498
499 strncpy(nxattr, value, size < XATTR_MAXLEN ? size : XATTR_MAXLEN);
500 nxattr[XATTR_MAXLEN] = '\0';
501 /* Need to undo earlier increment of path when calling plp_getxattr */
502 plp_getxattr(path - 1, name, oxattr, XATTR_MAXLEN
503#ifdef __APPLE__
504 , 0
505#endif
506 );
507 psisattr = psidattr = 0;
508 xattr2pattr(&psisattr, &psidattr, oxattr, value);
509 debuglog("attrs set %x delete %x; %s, %s", psisattr, psidattr, oxattr, value);
510 if ((ret = rfsv_setattr(path, psisattr, psidattr)) != 0)
511 return ret;
512
513 debuglog("setxattr succeeded");
514 return 0;
515 } else {
516#ifdef XATTR_REPLACE
517 if (flags & XATTR_REPLACE)
518 return -ENOATTR;
519 else
520#endif
521 return -ENOTSUP;
522 }
523}
524
525static int plp_listxattr(const char *path, char *list, size_t size)
526{
527 debuglog("plp_listxattr `%s'", ++path);
528 if (size > sizeof(XATTR_NAME))
529 strcpy(list, XATTR_NAME);
530 return sizeof(XATTR_NAME);
531}
532
533static int plp_removexattr(const char *path, const char *name)
534{
535 debuglog("plp_removexattr `%s'", ++path);
536 (void)name;
537 return -ENOTSUP;
538}
539
540#if FUSE_USE_VERSION >= 30
541static int plp_chown(const char *path, uid_t uid, gid_t gid, struct fuse_file_info *fi)
542#else
543static int plp_chown(const char *path, uid_t uid, gid_t gid)
544#endif
545{
546 (void)uid;
547 (void)gid;
548#if FUSE_USE_VERSION >= 30
549 (void)fi;
550#endif
551 debuglog("plp_chown `%s'", ++path);
552 return -EPERM;
553}
554
555#if FUSE_USE_VERSION >= 30
556static int plp_truncate(const char *path, off_t size, struct fuse_file_info *fi)
557#else
558static int plp_truncate(const char *path, off_t size)
559#endif
560{
561#if FUSE_USE_VERSION >= 30
562 (void)fi;
563#endif
564 debuglog("plp_truncate `%s'", ++path);
565 return rfsv_setsize(path, size);
566}
567
568#if FUSE_USE_VERSION >= 30
569static int plp_utimens(const char *path, const struct timespec ts[2], struct fuse_file_info *fi)
570#else
571static int plp_utimens(const char *path, const struct timespec ts[2])
572#endif
573{
574#if FUSE_USE_VERSION >= 30
575 (void)fi;
576#endif
577 debuglog("plp_utimens `%s'", ++path);
578 return rfsv_setmtime(path, ts[1].tv_sec);
579}
580
581static int plp_open(const char *path, struct fuse_file_info *fi)
582{
583 debuglog("plp_open `%s'", ++path);
584 (void)fi;
585 return 0;
586}
587
588static int plp_read(const char *path, char *buf, size_t size, off_t offset,
589 struct fuse_file_info *fi)
590{
591 long read;
592
593 (void)fi;
594 debuglog("plp_read `%s' offset %lld size %ld", ++path, offset, size);
595 read = rfsv_read(buf, (long)offset, size, path);
596 debuglog("read returned %ld", read);
597 return read;
598}
599
600static int plp_write(const char *path, const char *buf, size_t size,
601 off_t offset, struct fuse_file_info *fi)
602{
603 long written;
604
605 (void)fi;
606 debuglog("plp_write `%s' offset %lld size %ld", ++path, offset, size);
607 written = rfsv_write(buf, offset, size, path);
608 debuglog("write returned %ld", written);
609 return written;
610}
611
612static int plp_statfs(const char *path, struct statvfs *stbuf)
613{
614 device *dp;
615
616 (void)path;
617 debuglog("plp_statfs");
618
619 stbuf->f_bsize = BLOCKSIZE;
620 stbuf->f_frsize = BLOCKSIZE;
621 if (query_devices() == 0) {
622 for (dp = devices; dp; dp = dp->next) {
623 stbuf->f_blocks += (dp->total + BLOCKSIZE - 1) / BLOCKSIZE;
624 stbuf->f_bfree += (dp->free + BLOCKSIZE - 1) / BLOCKSIZE;
625 }
626 }
627 stbuf->f_bavail = stbuf->f_bfree;
628
629 /* Don't have numbers for these */
630 stbuf->f_files = 0;
631 stbuf->f_ffree = stbuf->f_favail = 0;
632
633 stbuf->f_fsid = FID;
634 stbuf->f_flag = 0; /* don't have mount flags */
635 stbuf->f_namemax = 255; /* KDMaxFileNameLen% */
636
637 return 0;
638}
639
640struct fuse_operations plp_oper = {
641 .getattr = plp_getattr,
642 .access = plp_access,
643 .readlink = plp_readlink,
644 .readdir = plp_readdir,
645 .mknod = plp_mknod,
646 .mkdir = plp_mkdir,
647 .symlink = plp_symlink,
648 .unlink = plp_unlink,
649 .rmdir = plp_rmdir,
650 .rename = plp_rename,
651 .link = plp_link,
652 .chmod = plp_chmod,
653 .setxattr = plp_setxattr,
654 .getxattr = plp_getxattr,
655 .listxattr = plp_listxattr,
656 .removexattr = plp_removexattr,
657 .chown = plp_chown,
658 .truncate = plp_truncate,
659 .utimens = plp_utimens,
660 .open = plp_open,
661 .read = plp_read,
662 .write = plp_write,
663 .statfs = plp_statfs,
664};
static int plp_unlink(const char *path)
Definition fuse.c:392
static int getlinks(const char *path, struct stat *st)
Definition fuse.c:219
#define XATTR_MAXLEN
Definition fuse.c:42
static device * devices
Definition fuse.c:152
static int plp_link(const char *from, const char *to)
Definition fuse.c:424
static int plp_utimens(const char *path, const struct timespec ts[2])
Definition fuse.c:571
void debuglog(const char *fmt,...)
Definition fuse.c:51
static int plp_removexattr(const char *path, const char *name)
Definition fuse.c:533
static int plp_mknod(const char *path, mode_t mode, dev_t dev)
Definition fuse.c:371
static int plp_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
Definition fuse.c:588
static int plp_open(const char *path, struct fuse_file_info *fi)
Definition fuse.c:581
#define ENOMEDIUM
Definition fuse.c:45
static int plp_readlink(const char *path, char *buf, size_t size)
Definition fuse.c:290
static char * dirname(const char *dir)
Definition fuse.c:172
#define XATTR_NAME
Definition fuse.c:39
#define ENOATTR
Definition fuse.c:29
static int plp_listxattr(const char *path, char *list, size_t size)
Definition fuse.c:525
static void attr2pattr(long oattr, long nattr, char *oxattr, char *nxattr, long *psisattr, long *psidattr)
Definition fuse.c:92
static int plp_rename(const char *from, const char *to)
Definition fuse.c:413
static int plp_mkdir(const char *path, mode_t mode)
Definition fuse.c:386
static int plp_access(const char *path, int mask)
Definition fuse.c:283
static int query_devices(void)
Definition fuse.c:155
static void pattr2attr(long psiattr, long size, long ftime, struct stat *st, char *xattr)
Definition fuse.c:124
static int plp_rmdir(const char *path)
Definition fuse.c:398
static void xattr2pattr(long *psisattr, long *psidattr, const char *oxattr, const char *nxattr)
Definition fuse.c:69
static int plp_setxattr(const char *path, const char *name, const char *value, size_t size, int flags)
Definition fuse.c:482
static int plp_getattr(const char *path, struct stat *st)
Definition fuse.c:230
struct fuse_operations plp_oper
Definition fuse.c:640
static int plp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
Definition fuse.c:302
static int plp_statfs(const char *path, struct statvfs *stbuf)
Definition fuse.c:612
static int plp_symlink(const char *from, const char *to)
Definition fuse.c:404
static int dircount(const char *path, long *count)
Definition fuse.c:193
static int plp_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
Definition fuse.c:600
static int plp_chown(const char *path, uid_t uid, gid_t gid)
Definition fuse.c:543
static int plp_chmod(const char *path, mode_t mode)
Definition fuse.c:433
int debug
Definition fuse.c:48
static int plp_truncate(const char *path, off_t size)
Definition fuse.c:558
static int plp_getxattr(const char *path, const char *name, char *value, size_t size)
Definition fuse.c:457
static const char * filname(const char *dir)
Definition fuse.c:183
static void pattr2xattr(long psiattr, char *xattr)
Definition fuse.c:111
int rfsv_rmdir(const char *name)
Definition main.cc:187
int rfsv_dir(const char *file, dentry **e)
Definition main.cc:157
int rfsv_drivelist(int *cnt, device **dlist)
Definition main.cc:311
int rfsv_mkdir(const char *file)
Definition main.cc:193
int rfsv_getattr(const char *name, long *attr, long *size, long *time)
Definition main.cc:292
int rfsv_remove(const char *file)
Definition main.cc:199
int rfsv_setmtime(const char *name, long time)
Definition main.cc:266
int rfsv_write(const char *buf, long offset, long len, const char *name)
Definition main.cc:251
int rfsv_fcreate(long attr, const char *file, uint32_t *handle)
Definition main.cc:211
int rfsv_setattr(const char *name, long sattr, long dattr)
Definition main.cc:286
int rfsv_fclose(long handle)
Definition main.cc:205
int rfsv_rename(const char *oldname, const char *newname)
Definition main.cc:305
int rfsv_isalive(void)
Definition main.cc:149
int rfsv_setsize(const char *name, long size)
Definition main.cc:272
int rfsv_read(char *buf, long offset, long len, const char *name)
Definition main.cc:236
#define FID
Definition plpfuse.h:65
#define BLOCKSIZE
Definition plpfuse.h:64
#define PSI_A_HIDDEN
Definition rfsv_api.h:49
#define PSI_A_SYSTEM
Definition rfsv_api.h:50
#define PSI_A_DIR
Definition rfsv_api.h:51
#define PSI_A_ARCHIVE
Definition rfsv_api.h:52
#define PSI_A_RDONLY
Definition rfsv_api.h:48
#define PSI_A_READ
Definition rfsv_api.h:57
long time
Definition plpfuse.h:53
long size
Definition plpfuse.h:55
struct p_dentry * next
Definition plpfuse.h:57
char * name
Definition plpfuse.h:52
long attr
Definition plpfuse.h:54
char * name
Definition plpfuse.h:39
long attrib
Definition plpfuse.h:41
long total
Definition plpfuse.h:42
char letter
Definition plpfuse.h:40
struct p_device * next
Definition plpfuse.h:44
long free
Definition plpfuse.h:43