EA operations added
diff --git a/lib/fuse.c b/lib/fuse.c
index 2ca30bb..77532a4 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -25,25 +25,29 @@
static const char *opname(enum fuse_opcode opcode)
{
switch(opcode) {
- case FUSE_LOOKUP: return "LOOKUP";
- case FUSE_FORGET: return "FORGET";
- case FUSE_GETATTR: return "GETATTR";
- case FUSE_SETATTR: return "SETATTR";
- case FUSE_READLINK: return "READLINK";
- case FUSE_SYMLINK: return "SYMLINK";
- case FUSE_GETDIR: return "GETDIR";
- case FUSE_MKNOD: return "MKNOD";
- case FUSE_MKDIR: return "MKDIR";
- case FUSE_UNLINK: return "UNLINK";
- case FUSE_RMDIR: return "RMDIR";
- case FUSE_RENAME: return "RENAME";
- case FUSE_LINK: return "LINK";
- case FUSE_OPEN: return "OPEN";
- case FUSE_READ: return "READ";
- case FUSE_WRITE: return "WRITE";
- case FUSE_STATFS: return "STATFS";
- case FUSE_RELEASE: return "RELEASE";
- case FUSE_FSYNC: return "FSYNC";
+ case FUSE_LOOKUP: return "LOOKUP";
+ case FUSE_FORGET: return "FORGET";
+ case FUSE_GETATTR: return "GETATTR";
+ case FUSE_SETATTR: return "SETATTR";
+ case FUSE_READLINK: return "READLINK";
+ case FUSE_SYMLINK: return "SYMLINK";
+ case FUSE_GETDIR: return "GETDIR";
+ case FUSE_MKNOD: return "MKNOD";
+ case FUSE_MKDIR: return "MKDIR";
+ case FUSE_UNLINK: return "UNLINK";
+ case FUSE_RMDIR: return "RMDIR";
+ case FUSE_RENAME: return "RENAME";
+ case FUSE_LINK: return "LINK";
+ case FUSE_OPEN: return "OPEN";
+ case FUSE_READ: return "READ";
+ case FUSE_WRITE: return "WRITE";
+ case FUSE_STATFS: return "STATFS";
+ case FUSE_RELEASE: return "RELEASE";
+ case FUSE_FSYNC: return "FSYNC";
+ case FUSE_SETXATTR: return "SETXATTR";
+ case FUSE_GETXATTR: return "GETXATTR";
+ case FUSE_LISTXATTR: return "LISTXATTR";
+ case FUSE_REMOVEXATTR: return "REMOVEXATTR";
default: return "???";
}
}
@@ -968,6 +972,110 @@
send_reply(f, in, res, NULL, 0);
}
+static void do_setxattr(struct fuse *f, struct fuse_in_header *in,
+ struct fuse_setxattr_in *arg)
+{
+ int res;
+ char *path;
+ char *name = PARAM(arg);
+ unsigned char *value = name + strlen(name) + 1;
+
+ res = -ENOENT;
+ path = get_path(f, in->ino);
+ if (path != NULL) {
+ res = -EOPNOTSUPP; /* or is it ENOTSUPP ??? */
+ if (f->op.setxattr)
+ res = f->op.setxattr(path, name, value, arg->size, arg->flags);
+ free(path);
+ }
+ send_reply(f, in, res, NULL, 0);
+}
+
+static void do_getxattr(struct fuse *f, struct fuse_in_header *in,
+ struct fuse_getlistxattr_in *arg)
+{
+ int res;
+ char *path;
+ char *name = PARAM(arg);
+ char *outbuf = (char *) malloc(sizeof(struct fuse_out_header) + arg->size);
+ struct fuse_out_header *out = (struct fuse_out_header *) outbuf;
+ char *value = outbuf + sizeof(struct fuse_out_header);
+ size_t size;
+ size_t outsize;
+
+ res = -ENOENT;
+ path = get_path(f, in->ino);
+ if (path != NULL) {
+ res = -EOPNOTSUPP; /* or is it ENOTSUPP ??? */
+ if (f->op.getxattr)
+ res = f->op.getxattr(path, name, value, arg->size);
+ free(path);
+ }
+ size = 0;
+ if(res > 0) {
+ size = res;
+ res = 0;
+ }
+ memset(out, 0, sizeof(struct fuse_out_header));
+ out->unique = in->unique;
+ out->error = res;
+ outsize = sizeof(struct fuse_out_header) + size;
+
+ send_reply_raw(f, outbuf, outsize);
+ free(outbuf);
+}
+
+static void do_listxattr(struct fuse *f, struct fuse_in_header *in,
+ struct fuse_getlistxattr_in *arg)
+{
+ int res;
+ char *path;
+ char *outbuf = (char *) malloc(sizeof(struct fuse_out_header) + arg->size);
+ struct fuse_out_header *out = (struct fuse_out_header *) outbuf;
+ char *value = outbuf + sizeof(struct fuse_out_header);
+ size_t size;
+ size_t outsize;
+
+ res = -ENOENT;
+ path = get_path(f, in->ino);
+ if (path != NULL) {
+ res = -EOPNOTSUPP; /* or is it ENOTSUPP ??? */
+ if (f->op.listxattr)
+ res = f->op.listxattr(path, value, arg->size);
+ free(path);
+ }
+ size = 0;
+ if(res > 0) {
+ size = res;
+ res = 0;
+ }
+ memset(out, 0, sizeof(struct fuse_out_header));
+ out->unique = in->unique;
+ out->error = res;
+ outsize = sizeof(struct fuse_out_header) + size;
+
+ send_reply_raw(f, outbuf, outsize);
+ free(outbuf);
+}
+
+static void do_removexattr(struct fuse *f, struct fuse_in_header *in,
+ char *name)
+{
+ int res;
+ char *path;
+
+ res = -ENOENT;
+ path = get_path(f, in->ino);
+ if (path != NULL) {
+ res = -EOPNOTSUPP; /* or is it ENOTSUPP ??? */
+ if (f->op.removexattr)
+ res = f->op.removexattr(path, name);
+ free(path);
+ }
+ send_reply(f, in, res, NULL, 0);
+}
+
+
static void free_cmd(struct fuse_cmd *cmd)
{
free(cmd->buf);
@@ -1069,6 +1177,22 @@
do_fsync(f, in, (struct fuse_fsync_in *) inarg);
break;
+ case FUSE_SETXATTR:
+ do_setxattr(f, in, (struct fuse_setxattr_in *) inarg);
+ break;
+
+ case FUSE_GETXATTR:
+ do_getxattr(f, in, (struct fuse_getlistxattr_in *) inarg);
+ break;
+
+ case FUSE_LISTXATTR:
+ do_listxattr(f, in, (struct fuse_getlistxattr_in *) inarg);
+ break;
+
+ case FUSE_REMOVEXATTR:
+ do_removexattr(f, in, (char *) inarg);
+ break;
+
default:
send_reply(f, in, -ENOSYS, NULL, 0);
}