22#ifdef HAVE_ATTR_XATTR_H
23#include <attr/xattr.h>
24#elif defined(HAVE_SYS_XATTR_H)
29#define ENOATTR ENODATA
31#ifdef HAVE_ATTR_ATTRIBUTES_H
32#include <attr/attributes.h>
39#define XATTR_NAME "user.epoc"
45#define ENOMEDIUM ENODEV
59 if (vasprintf(&buf, fmt, ap) == -1)
60 syslog(LOG_DEBUG,
"vasprintf error in debuglog");
62 syslog(LOG_DEBUG,
"%s", buf);
69xattr2pattr(
long *psisattr,
long *psidattr,
const char *oxattr,
const char *nxattr)
71 if ((strchr(oxattr,
'a') == NULL) != (strchr(nxattr,
'a') == NULL)) {
72 if (strchr(nxattr,
'a'))
77 if ((strchr(oxattr,
'h') == NULL) != (strchr(nxattr,
'h') == NULL)) {
78 if (strchr(nxattr,
'h'))
83 if ((strchr(oxattr,
's') == NULL) != (strchr(nxattr,
's') == NULL)) {
84 if (strchr(nxattr,
's'))
92attr2pattr(
long oattr,
long nattr,
char *oxattr,
char *nxattr,
long *psisattr,
long *psidattr)
94 *psisattr = *psidattr = 0;
95 if ((oattr & 0400) != (nattr & 0400)) {
101 if ((oattr & 0200) != (nattr & 0200)) {
124pattr2attr(
long psiattr,
long size,
long ftime,
struct stat *st,
char *xattr)
126 struct fuse_context *ct = fuse_get_context();
128 memset(st, 0,
sizeof(*st));
129 st->st_uid = ct->uid;
130 st->st_gid = ct->gid;
133 st->st_mode = 0700 | S_IFDIR;
141 st->st_mode = S_IFREG;
148 st->st_mtime = st->st_ctime = st->st_atime = ftime;
160 for (dp =
devices; dp; dp = np) {
174 static char *namebuf = NULL;
177 if (asprintf(&namebuf,
"%s\\", dir) == -1)
186 if ((p = (
char *) rindex(dir,
'\\')))
219static int getlinks(
const char *path,
struct stat *st)
224 st->st_nlink = dcount + 2;
227#if FUSE_USE_VERSION >= 30
228static int plp_getattr(
const char *path,
struct stat *st,
struct fuse_file_info *fi)
235#if FUSE_USE_VERSION >= 30
238 debuglog(
"plp_getattr `%s'", ++path);
240 if (strcmp(path,
"") == 0) {
247 debuglog(
"root has %d links", st->st_nlink);
251 long pattr, psize, ptime;
253 if (strlen(path) == 2 && path[1] ==
':') {
260 if (dp->
letter == path[0])
263 debuglog(
"device: %s", dp ?
"exists" :
"does not exist");
271 if ((ret =
rfsv_getattr(path, &pattr, &psize, &ptime)) == 0) {
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)
279 debuglog(
"getattr: returned %d", ret);
286 debuglog(
"plp_access `%s'", ++path);
294 debuglog(
"plp_readlink `%s'", ++path);
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)
302static int plp_readdir(
const char *path,
void *buf, fuse_fill_dir_t filler,
303 off_t offset,
struct fuse_file_info *fi)
309#if FUSE_USE_VERSION >= 30
310 enum fuse_fill_dir_flags fill_flags = FUSE_FILL_DIR_DEFAULTS;
312 if (flags & FUSE_READDIR_PLUS) {
313 fill_flags |= FUSE_FILL_DIR_PLUS;
316 debuglog(
"plp_readdir `%s'", ++path);
321 if (strcmp(path,
"") == 0) {
326 unsigned char name[3];
332#if FUSE_USE_VERSION >= 30
333 if (filler(buf, (
char *)name, &st, 0, fill_flags))
335 if (filler(buf, (
char *)name, &st, 0))
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))
357 if (filler(buf, name, &st, 0))
371static int plp_mknod(
const char *path, mode_t mode, dev_t dev)
375 debuglog(
"plp_mknod `%s' %o", ++path, mode);
377 if (S_ISREG(mode) && dev == 0) {
388 debuglog(
"plp_mkdir `%s' %o", ++path, mode);
394 debuglog(
"plp_unlink `%s'", ++path);
406 debuglog(
"plp_symlink `%s' -> `'%s'", ++from, ++to);
410#if FUSE_USE_VERSION >= 30
411static int plp_rename(
const char *from,
const char *to,
unsigned int flag)
416#if FUSE_USE_VERSION >= 30
419 debuglog(
"plp_rename `%s' -> `%s'", ++from, ++to);
424static int plp_link(
const char *from,
const char *to)
426 debuglog(
"plp_link `%s' -> `%s'", ++from, ++to);
430#if FUSE_USE_VERSION >= 30
431static int plp_chmod(
const char *path, mode_t mode,
struct fuse_file_info *fi)
437 long psisattr, psidattr, pattr, psize, ptime;
441#if FUSE_USE_VERSION >= 30
446 if ((ret =
rfsv_getattr(path, &pattr, &psize, &ptime)) == 0) {
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)
457static int plp_getxattr(
const char *path,
const char *name,
char *value,
size_t size
459 , _GL_UNUSED uint32_t position
463 debuglog(
"plp_getxattr `%s' %s", ++path, name);
466 long pattr, psize, ptime;
468 if ((ret =
rfsv_getattr(path, &pattr, &psize, &ptime)) == 0) {
470 debuglog(
"getxattr succeeded: %s", value);
471 return strlen(value);
482static int plp_setxattr(
const char *path,
const char *name,
const char *value,
size_t size,
int flags
484 , _GL_UNUSED uint32_t position
488 debuglog(
"plp_setxattr `%s'", ++path);
491 long psisattr, psidattr;
495 if (flags & XATTR_CREATE)
507 psisattr = psidattr = 0;
509 debuglog(
"attrs set %x delete %x; %s, %s", psisattr, psidattr, oxattr, value);
510 if ((ret =
rfsv_setattr(path, psisattr, psidattr)) != 0)
517 if (flags & XATTR_REPLACE)
527 debuglog(
"plp_listxattr `%s'", ++path);
535 debuglog(
"plp_removexattr `%s'", ++path);
540#if FUSE_USE_VERSION >= 30
541static int plp_chown(
const char *path, uid_t uid, gid_t gid,
struct fuse_file_info *fi)
543static int plp_chown(
const char *path, uid_t uid, gid_t gid)
548#if FUSE_USE_VERSION >= 30
555#if FUSE_USE_VERSION >= 30
556static int plp_truncate(
const char *path, off_t size,
struct fuse_file_info *fi)
561#if FUSE_USE_VERSION >= 30
564 debuglog(
"plp_truncate `%s'", ++path);
568#if FUSE_USE_VERSION >= 30
569static int plp_utimens(
const char *path,
const struct timespec ts[2],
struct fuse_file_info *fi)
571static int plp_utimens(
const char *path,
const struct timespec ts[2])
574#if FUSE_USE_VERSION >= 30
577 debuglog(
"plp_utimens `%s'", ++path);
581static int plp_open(
const char *path,
struct fuse_file_info *fi)
588static int plp_read(
const char *path,
char *buf,
size_t size, off_t offset,
589 struct fuse_file_info *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);
600static int plp_write(
const char *path,
const char *buf,
size_t size,
601 off_t offset,
struct fuse_file_info *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);
612static int plp_statfs(
const char *path,
struct statvfs *stbuf)
627 stbuf->f_bavail = stbuf->f_bfree;
631 stbuf->f_ffree = stbuf->f_favail = 0;
635 stbuf->f_namemax = 255;
static int plp_unlink(const char *path)
static int getlinks(const char *path, struct stat *st)
static int plp_link(const char *from, const char *to)
static int plp_utimens(const char *path, const struct timespec ts[2])
void debuglog(const char *fmt,...)
static int plp_removexattr(const char *path, const char *name)
static int plp_mknod(const char *path, mode_t mode, dev_t dev)
static int plp_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
static int plp_open(const char *path, struct fuse_file_info *fi)
static int plp_readlink(const char *path, char *buf, size_t size)
static char * dirname(const char *dir)
static int plp_listxattr(const char *path, char *list, size_t size)
static void attr2pattr(long oattr, long nattr, char *oxattr, char *nxattr, long *psisattr, long *psidattr)
static int plp_rename(const char *from, const char *to)
static int plp_mkdir(const char *path, mode_t mode)
static int plp_access(const char *path, int mask)
static int query_devices(void)
static void pattr2attr(long psiattr, long size, long ftime, struct stat *st, char *xattr)
static int plp_rmdir(const char *path)
static void xattr2pattr(long *psisattr, long *psidattr, const char *oxattr, const char *nxattr)
static int plp_setxattr(const char *path, const char *name, const char *value, size_t size, int flags)
static int plp_getattr(const char *path, struct stat *st)
struct fuse_operations plp_oper
static int plp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
static int plp_statfs(const char *path, struct statvfs *stbuf)
static int plp_symlink(const char *from, const char *to)
static int dircount(const char *path, long *count)
static int plp_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
static int plp_chown(const char *path, uid_t uid, gid_t gid)
static int plp_chmod(const char *path, mode_t mode)
static int plp_truncate(const char *path, off_t size)
static int plp_getxattr(const char *path, const char *name, char *value, size_t size)
static const char * filname(const char *dir)
static void pattr2xattr(long psiattr, char *xattr)
int rfsv_rmdir(const char *name)
int rfsv_dir(const char *file, dentry **e)
int rfsv_drivelist(int *cnt, device **dlist)
int rfsv_mkdir(const char *file)
int rfsv_getattr(const char *name, long *attr, long *size, long *time)
int rfsv_remove(const char *file)
int rfsv_setmtime(const char *name, long time)
int rfsv_write(const char *buf, long offset, long len, const char *name)
int rfsv_fcreate(long attr, const char *file, uint32_t *handle)
int rfsv_setattr(const char *name, long sattr, long dattr)
int rfsv_fclose(long handle)
int rfsv_rename(const char *oldname, const char *newname)
int rfsv_setsize(const char *name, long size)
int rfsv_read(char *buf, long offset, long len, const char *name)