cmake_minimum_required(VERSION 2.8)
project(fuse_xattrs C)
+set(FUSE_XATTRS_VERSION_MAJOR 0)
+set(FUSE_XATTRS_VERSION_MINOR 2)
+
+set(BINARY_SIDECAR_EXT \".xattr\")
+
+set(MAX_METADATA_SIZE "8*1024*1024") # 8 MiB
+set(XATTR_NAME_MAX 255) # chars in an extended attribute name
+set(XATTR_SIZE_MAX 65536) # size of an extended attribute value (64k)
+set(XATTR_LIST_MAX 65536) # size of extended attribute namelist (64k)
+
+configure_file (
+ "${PROJECT_SOURCE_DIR}/fuse_xattrs_config.h.in"
+ "${PROJECT_BINARY_DIR}/fuse_xattrs_config.h"
+)
+include_directories(
+ "${PROJECT_BINARY_DIR}"
+)
+
# Check xattr headers
include (CheckIncludeFile)
check_include_file (sys/xattr.h HAVE_SYS_XATTR_H)
endif(ENABLE_CODECOVERAGE)
set(SOURCE_FILES
- compat/fuse_opt.c
- compat/fuse_opt.h
fuse_xattrs.c
passthrough.c
- passthrough.h
binary_storage.c
- binary_storage.h
utils.c
- utils.h
- const.h
- fuse_xattrs_config.h)
+)
add_executable(fuse_xattrs ${SOURCE_FILES})
+Release 0.2 (2017-02-16)
+------------------------
+
+* Fix tests
+* Added support to specify source directory (not mirroring the full fs /)
+* Hide sidecar files by default
+
Release 0.1 (2016-10-23)
------------------------
#include "binary_storage.h"
#include "utils.h"
-#include "const.h"
+#include "fuse_xattrs_config.h"
#include <attr/xattr.h>
+++ /dev/null
-/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
-
- This program can be distributed under the terms of the GNU LGPL.
- See the file COPYING.LIB
-*/
-
-#include "fuse_opt.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-struct fuse_opt_context {
- void *data;
- const struct fuse_opt *opt;
- fuse_opt_proc_t proc;
- int argctr;
- int argc;
- char **argv;
- struct fuse_args outargs;
- char *opts;
- int nonopt;
-};
-
-void fuse_opt_free_args(struct fuse_args *args)
-{
- if (args && args->argv && args->allocated) {
- int i;
- for (i = 0; i < args->argc; i++)
- free(args->argv[i]);
- free(args->argv);
- args->argv = NULL;
- args->allocated = 0;
- }
-}
-
-static int alloc_failed(void)
-{
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
-}
-
-int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
-{
- char **newargv;
- char *newarg;
-
- assert(!args->argv || args->allocated);
-
- newargv = realloc(args->argv, (args->argc + 2) * sizeof(char *));
- newarg = newargv ? strdup(arg) : NULL;
- if (!newargv || !newarg)
- return alloc_failed();
-
- args->argv = newargv;
- args->allocated = 1;
- args->argv[args->argc++] = newarg;
- args->argv[args->argc] = NULL;
- return 0;
-}
-
-int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg)
-{
- assert(pos <= args->argc);
- if (fuse_opt_add_arg(args, arg) == -1)
- return -1;
-
- if (pos != args->argc - 1) {
- char *newarg = args->argv[args->argc - 1];
- memmove(&args->argv[pos + 1], &args->argv[pos],
- sizeof(char *) * (args->argc - pos - 1));
- args->argv[pos] = newarg;
- }
- return 0;
-}
-
-static int next_arg(struct fuse_opt_context *ctx, const char *opt)
-{
- if (ctx->argctr + 1 >= ctx->argc) {
- fprintf(stderr, "fuse: missing argument after `%s'\n", opt);
- return -1;
- }
- ctx->argctr++;
- return 0;
-}
-
-static int add_arg(struct fuse_opt_context *ctx, const char *arg)
-{
- return fuse_opt_add_arg(&ctx->outargs, arg);
-}
-
-int fuse_opt_add_opt(char **opts, const char *opt)
-{
- char *newopts;
- if (!*opts)
- newopts = strdup(opt);
- else {
- unsigned oldlen = strlen(*opts);
- newopts = realloc(*opts, oldlen + 1 + strlen(opt) + 1);
- if (newopts) {
- newopts[oldlen] = ',';
- strcpy(newopts + oldlen + 1, opt);
- }
- }
- if (!newopts)
- return alloc_failed();
-
- *opts = newopts;
- return 0;
-}
-
-static int add_opt(struct fuse_opt_context *ctx, const char *opt)
-{
- return fuse_opt_add_opt(&ctx->opts, opt);
-}
-
-static int call_proc(struct fuse_opt_context *ctx, const char *arg, int key,
- int iso)
-{
- if (key == FUSE_OPT_KEY_DISCARD)
- return 0;
-
- if (key != FUSE_OPT_KEY_KEEP && ctx->proc) {
- int res = ctx->proc(ctx->data, arg, key, &ctx->outargs);
- if (res == -1 || !res)
- return res;
- }
- if (iso)
- return add_opt(ctx, arg);
- else
- return add_arg(ctx, arg);
-}
-
-static int match_template(const char *t, const char *arg, unsigned *sepp)
-{
- int arglen = strlen(arg);
- const char *sep = strchr(t, '=');
- sep = sep ? sep : strchr(t, ' ');
- if (sep && (!sep[1] || sep[1] == '%')) {
- int tlen = sep - t;
- if (sep[0] == '=')
- tlen ++;
- if (arglen >= tlen && strncmp(arg, t, tlen) == 0) {
- *sepp = sep - t;
- return 1;
- }
- }
- if (strcmp(t, arg) == 0) {
- *sepp = 0;
- return 1;
- }
- return 0;
-}
-
-static const struct fuse_opt *find_opt(const struct fuse_opt *opt,
- const char *arg, unsigned *sepp)
-{
- for (; opt && opt->templ; opt++)
- if (match_template(opt->templ, arg, sepp))
- return opt;
- return NULL;
-}
-
-int fuse_opt_match(const struct fuse_opt *opts, const char *opt)
-{
- unsigned dummy;
- return find_opt(opts, opt, &dummy) ? 1 : 0;
-}
-
-static int process_opt_param(void *var, const char *format, const char *param,
- const char *arg)
-{
- assert(format[0] == '%');
- if (format[1] == 's') {
- char *copy = strdup(param);
- if (!copy)
- return alloc_failed();
-
- *(char **) var = copy;
- } else {
- if (sscanf(param, format, var) != 1) {
- fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg);
- return -1;
- }
- }
- return 0;
-}
-
-static int process_opt(struct fuse_opt_context *ctx,
- const struct fuse_opt *opt, unsigned sep,
- const char *arg, int iso)
-{
- if (opt->offset == -1U) {
- if (call_proc(ctx, arg, opt->value, iso) == -1)
- return -1;
- } else {
- void *var = ctx->data + opt->offset;
- if (sep && opt->templ[sep + 1]) {
- const char *param = arg + sep;
- if (opt->templ[sep] == '=')
- param ++;
- if (process_opt_param(var, opt->templ + sep + 1,
- param, arg) == -1)
- return -1;
- } else
- *(int *)var = opt->value;
- }
- return 0;
-}
-
-static int process_opt_sep_arg(struct fuse_opt_context *ctx,
- const struct fuse_opt *opt, unsigned sep,
- const char *arg, int iso)
-{
- int res;
- char *newarg;
- char *param;
-
- if (next_arg(ctx, arg) == -1)
- return -1;
-
- param = ctx->argv[ctx->argctr];
- newarg = malloc(sep + strlen(param) + 1);
- if (!newarg)
- return alloc_failed();
-
- memcpy(newarg, arg, sep);
- strcpy(newarg + sep, param);
- res = process_opt(ctx, opt, sep, newarg, iso);
- free(newarg);
-
- return res;
-}
-
-static int process_gopt(struct fuse_opt_context *ctx, const char *arg, int iso)
-{
- unsigned sep;
- const struct fuse_opt *opt = find_opt(ctx->opt, arg, &sep);
- if (opt) {
- for (; opt; opt = find_opt(opt + 1, arg, &sep)) {
- int res;
- if (sep && opt->templ[sep] == ' ' && !arg[sep])
- res = process_opt_sep_arg(ctx, opt, sep, arg, iso);
- else
- res = process_opt(ctx, opt, sep, arg, iso);
- if (res == -1)
- return -1;
- }
- return 0;
- } else
- return call_proc(ctx, arg, FUSE_OPT_KEY_OPT, iso);
-}
-
-static int process_real_option_group(struct fuse_opt_context *ctx, char *opts)
-{
- char *sep;
-
- do {
- int res;
- sep = strchr(opts, ',');
- if (sep)
- *sep = '\0';
- res = process_gopt(ctx, opts, 1);
- if (res == -1)
- return -1;
- opts = sep + 1;
- } while (sep);
-
- return 0;
-}
-
-static int process_option_group(struct fuse_opt_context *ctx, const char *opts)
-{
- int res;
- char *copy;
- const char *sep = strchr(opts, ',');
- if (!sep)
- return process_gopt(ctx, opts, 1);
-
- copy = strdup(opts);
- if (!copy) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
- }
- res = process_real_option_group(ctx, copy);
- free(copy);
- return res;
-}
-
-static int process_one(struct fuse_opt_context *ctx, const char *arg)
-{
- if (ctx->nonopt || arg[0] != '-')
- return call_proc(ctx, arg, FUSE_OPT_KEY_NONOPT, 0);
- else if (arg[1] == 'o') {
- if (arg[2])
- return process_option_group(ctx, arg + 2);
- else {
- if (next_arg(ctx, arg) == -1)
- return -1;
-
- return process_option_group(ctx, ctx->argv[ctx->argctr]);
- }
- } else if (arg[1] == '-' && !arg[2]) {
- if (add_arg(ctx, arg) == -1)
- return -1;
- ctx->nonopt = ctx->outargs.argc;
- return 0;
- } else
- return process_gopt(ctx, arg, 0);
-}
-
-static int opt_parse(struct fuse_opt_context *ctx)
-{
- if (ctx->argc) {
- if (add_arg(ctx, ctx->argv[0]) == -1)
- return -1;
- }
-
- for (ctx->argctr = 1; ctx->argctr < ctx->argc; ctx->argctr++)
- if (process_one(ctx, ctx->argv[ctx->argctr]) == -1)
- return -1;
-
- if (ctx->opts) {
- if (fuse_opt_insert_arg(&ctx->outargs, 1, "-o") == -1 ||
- fuse_opt_insert_arg(&ctx->outargs, 2, ctx->opts) == -1)
- return -1;
- }
- if (ctx->nonopt && ctx->nonopt == ctx->outargs.argc) {
- free(ctx->outargs.argv[ctx->outargs.argc - 1]);
- ctx->outargs.argv[--ctx->outargs.argc] = NULL;
- }
-
- return 0;
-}
-
-int fuse_opt_parse(struct fuse_args *args, void *data,
- const struct fuse_opt opts[], fuse_opt_proc_t proc)
-{
- int res;
- struct fuse_opt_context ctx = {
- .data = data,
- .opt = opts,
- .proc = proc,
- };
-
- if (!args || !args->argv || !args->argc)
- return 0;
-
- ctx.argc = args->argc;
- ctx.argv = args->argv;
-
- res = opt_parse(&ctx);
- if (res != -1) {
- struct fuse_args tmp = *args;
- *args = ctx.outargs;
- ctx.outargs = tmp;
- }
- free(ctx.opts);
- fuse_opt_free_args(&ctx.outargs);
- return res;
-}
+++ /dev/null
-/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
-
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
-*/
-
-#ifndef _FUSE_OPT_H_
-#define _FUSE_OPT_H_
-
-/* This file defines the option parsing interface of FUSE */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Option description
- *
- * This structure describes a single option, and and action associated
- * with it, in case it matches.
- *
- * More than one such match may occur, in which case the action for
- * each match is executed.
- *
- * There are three possible actions in case of a match:
- *
- * i) An integer (int or unsigned) variable determined by 'offset' is
- * set to 'value'
- *
- * ii) The processing function is called, with 'value' as the key
- *
- * iii) An integer (any) or string (char *) variable determined by
- * 'offset' is set to the value of an option parameter
- *
- * 'offset' should normally be either set to
- *
- * - 'offsetof(struct foo, member)' actions i) and iii)
- *
- * - -1 action ii)
- *
- * The 'offsetof()' macro is defined in the <stddef.h> header.
- *
- * The template determines which options match, and also have an
- * effect on the action. Normally the action is either i) or ii), but
- * if a format is present in the template, then action iii) is
- * performed.
- *
- * The types of templates are:
- *
- * 1) "-x", "-foo", "--foo", "--foo-bar", etc. These match only
- * themselves. Invalid values are "--" and anything beginning
- * with "-o"
- *
- * 2) "foo", "foo-bar", etc. These match "-ofoo", "-ofoo-bar" or
- * the relevant option in a comma separated option list
- *
- * 3) "bar=", "--foo=", etc. These are variations of 1) and 2)
- * which have a parameter
- *
- * 4) "bar=%s", "--foo=%lu", etc. Same matching as above but perform
- * action iii).
- *
- * 5) "-x ", etc. Matches either "-xparam" or "-x param" as
- * two separate arguments
- *
- * 6) "-x %s", etc. Combination of 4) and 5)
- *
- * If the format is "%s", memory is allocated for the string unlike
- * with scanf().
- */
-struct fuse_opt {
- /** Matching template and optional parameter formatting */
- const char *templ;
-
- /**
- * Offset of variable within 'data' parameter of fuse_opt_parse()
- * or -1
- */
- unsigned long offset;
-
- /**
- * Value to set the variable to, or to be passed as 'key' to the
- * processing function. Ignored if template has a format
- */
- int value;
-};
-
-/**
- * Key option. In case of a match, the processing function will be
- * called with the specified key.
- */
-#define FUSE_OPT_KEY(templ, key) { templ, -1U, key }
-
-/**
- * Last option. An array of 'struct fuse_opt' must end with a NULL
- * template value
- */
-#define FUSE_OPT_END { .templ = NULL }
-
-/**
- * Argument list
- */
-struct fuse_args {
- /** Argument count */
- int argc;
-
- /** Argument vector. NULL terminated */
- char **argv;
-
- /** Is 'argv' allocated? */
- int allocated;
-};
-
-/**
- * Initializer for 'struct fuse_args'
- */
-#define FUSE_ARGS_INIT(argc, argv) { argc, argv, 0 }
-
-/**
- * Key value passed to the processing function if an option did not
- * match any template
- */
-#define FUSE_OPT_KEY_OPT -1
-
-/**
- * Key value passed to the processing function for all non-options
- *
- * Non-options are the arguments beginning with a charater other than
- * '-' or all arguments after the special '--' option
- */
-#define FUSE_OPT_KEY_NONOPT -2
-
-/**
- * Special key value for options to keep
- *
- * Argument is not passed to processing function, but behave as if the
- * processing function returned 1
- */
-#define FUSE_OPT_KEY_KEEP -3
-
-/**
- * Special key value for options to discard
- *
- * Argument is not passed to processing function, but behave as if the
- * processing function returned zero
- */
-#define FUSE_OPT_KEY_DISCARD -4
-
-/**
- * Processing function
- *
- * This function is called if
- * - option did not match any 'struct fuse_opt'
- * - argument is a non-option
- * - option did match and offset was set to -1
- *
- * The 'arg' parameter will always contain the whole argument or
- * option including the parameter if exists. A two-argument option
- * ("-x foo") is always converted to single arguemnt option of the
- * form "-xfoo" before this function is called.
- *
- * Options of the form '-ofoo' are passed to this function without the
- * '-o' prefix.
- *
- * The return value of this function determines whether this argument
- * is to be inserted into the output argument vector, or discarded.
- *
- * @param data is the user data passed to the fuse_opt_parse() function
- * @param arg is the whole argument or option
- * @param key determines why the processing function was called
- * @param outargs the current output argument list
- * @return -1 on error, 0 if arg is to be discarded, 1 if arg should be kept
- */
-typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key,
- struct fuse_args *outargs);
-
-/**
- * Option parsing function
- *
- * If 'args' was returned from a previous call to fuse_opt_parse() or
- * it was constructed from
- *
- * A NULL 'args' is equivalent to an empty argument vector
- *
- * A NULL 'opts' is equivalent to an 'opts' array containing a single
- * end marker
- *
- * A NULL 'proc' is equivalent to a processing function always
- * returning '1'
- *
- * @param args is the input and output argument list
- * @param data is the user data
- * @param opts is the option description array
- * @param proc is the processing function
- * @return -1 on error, 0 on success
- */
-int fuse_opt_parse(struct fuse_args *args, void *data,
- const struct fuse_opt opts[], fuse_opt_proc_t proc);
-
-/**
- * Add an option to a comma separated option list
- *
- * @param opts is a pointer to an option list, may point to a NULL value
- * @param opt is the option to add
- * @return -1 on allocation error, 0 on success
- */
-int fuse_opt_add_opt(char **opts, const char *opt);
-
-/**
- * Add an argument to a NULL terminated argument vector
- *
- * @param args is the structure containing the current argument list
- * @param arg is the new argument to add
- * @return -1 on allocation error, 0 on success
- */
-int fuse_opt_add_arg(struct fuse_args *args, const char *arg);
-
-/**
- * Add an argument at the specified position in a NULL terminated
- * argument vector
- *
- * Adds the argument to the N-th position. This is useful for adding
- * options at the beggining of the array which must not come after the
- * special '--' option.
- *
- * @param args is the structure containing the current argument list
- * @param pos is the position at which to add the argument
- * @param arg is the new argument to add
- * @return -1 on allocation error, 0 on success
- */
-int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg);
-
-/**
- * Free the contents of argument list
- *
- * The structure itself is not freed
- *
- * @param args is the structure containing the argument list
- */
-void fuse_opt_free_args(struct fuse_args *args);
-
-
-/**
- * Check if an option matches
- *
- * @param opts is the option description array
- * @param opt is the option to match
- * @return 1 if a match is found, 0 if not
- */
-int fuse_opt_match(const struct fuse_opt opts[], const char *opt);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FUSE_OPT_H_ */
+++ /dev/null
-/*
- fuse_xattrs - Add xattrs support using sidecar files
-
- Copyright (C) 2016 Felipe Barriga Richards <felipe {at} felipebarriga.cl>
-
- This program can be distributed under the terms of the GNU GPL.
- See the file COPYING.
-*/
-
-#ifndef FUSE_XATTRS_CONST_H
-#define FUSE_XATTRS_CONST_H
-
-#define SIDECAR_EXT ".xattr"
-// TODO: This is just arbitrary...
-#define MAX_METADATA_SIZE 8 * 1024 * 1024 // 8 MiB
-
-#define XATTR_NAME_MAX 255 /* # chars in an extended attribute name */
-#define XATTR_SIZE_MAX 65536 /* size of an extended attribute value (64k) */
-#define XATTR_LIST_MAX 65536 /* size of extended attribute namelist (64k) */
-
-#endif //FUSE_XATTRS_CONST_H
-.TH FUSE_XATTRS "1" "October 2016" "FUSE_XATTRS version 0.1" "User Commands"
+.TH FUSE_XATTRS "1" "February 2017" "FUSE_XATTRS version 0.2" "User Commands"
.SH NAME
FUSE_XATTRS \- Add xattrs support using sidecar files
.SH SYNOPSIS
.SS mounting
.TP
-\fBfuse_xattrs\fP \fBmountpoint\fP
+\fBfuse_xattrs\fP \fBsource_dir\fP \fBmountpoint\fP
.SS unmounting
.TP
\fB__UNMOUNT_COMMAND__ mountpoint\fP
/*
fuse_xattrs - Add xattrs support using sidecar files
- Copyright (C) 2016 Felipe Barriga Richards <felipe {at} felipebarriga.cl>
+ Copyright (C) 2016-2017 Felipe Barriga Richards <felipe {at} felipebarriga.cl>
Based on passthrough.c (libfuse example)
#include <fuse.h>
#include <sys/xattr.h>
+#include "fuse_xattrs_config.h"
+
+#include "xattrs_config.h"
#include "utils.h"
#include "passthrough.h"
-#include "fuse_xattrs_config.h"
#include "binary_storage.h"
-#include "const.h"
static int xmp_setxattr(const char *path, const char *name, const char *value, size_t size, int flags)
{
exit(1);
case KEY_VERSION:
+ printf("FUSE_XATTRS version %d.%d\n", FUSE_XATTRS_VERSION_MAJOR, FUSE_XATTRS_VERSION_MINOR);
fuse_opt_add_arg(outargs, "--version");
fuse_main(outargs->argc, outargs->argv, &xmp_oper, NULL);
exit(0);
+++ /dev/null
-//
-// Copyright (C) 2017 Felipe Barriga Richards <felipe {at} felipebarriga.cl>
-//
-
-#ifndef FUSE_XATTRS_FUSE_XATTRS_CONFIG_H
-#define FUSE_XATTRS_FUSE_XATTRS_CONFIG_H
-
-struct xattrs_config {
- const char *source_dir;
-} xattrs_config;
-
-#endif //FUSE_XATTRS_FUSE_XATTRS_CONFIG_H
--- /dev/null
+//
+// Copyright (C) 2017 Felipe Barriga Richards <felipe {at} felipebarriga.cl>
+//
+
+#ifndef CMAKE_FUSE_XATTRS_CONFIG_H
+#define CMAKE_FUSE_XATTRS_CONFIG_H
+
+#define FUSE_XATTRS_VERSION_MAJOR @FUSE_XATTRS_VERSION_MAJOR@
+#define FUSE_XATTRS_VERSION_MINOR @FUSE_XATTRS_VERSION_MINOR@
+
+#define BINARY_SIDECAR_EXT @BINARY_SIDECAR_EXT@
+
+#define MAX_METADATA_SIZE @MAX_METADATA_SIZE@
+
+#define XATTR_NAME_MAX @XATTR_NAME_MAX@
+#define XATTR_SIZE_MAX @XATTR_SIZE_MAX@
+#define XATTR_LIST_MAX @XATTR_LIST_MAX@
+
+
+
+
+#endif //CMAKE_FUSE_XATTRS_CONFIG_H
/*
fuse_xattrs - Add xattrs support using sidecar files
- Copyright (C) 2016 Felipe Barriga Richards <felipe {at} felipebarriga.cl>
+ Copyright (C) 2016-2017 Felipe Barriga Richards <felipe {at} felipebarriga.cl>
Based on passthrough.c (libfuse example)
#include <errno.h>
#include "fuse_xattrs_config.h"
+
+#include "xattrs_config.h"
#include "utils.h"
int xmp_getattr(const char *path, struct stat *stbuf) {
#include <string.h>
#include "utils.h"
-#include "const.h"
+#include "fuse_xattrs_config.h"
char *prepend_source_directory(const char *a, const char *b) {
size_t len = strlen(a) + strlen(b) + 1;
char *get_sidecar_path(const char *path)
{
const size_t path_len = strlen(path);
- const size_t sidecar_ext_len = strlen(SIDECAR_EXT); // this can be optimized
+ const size_t sidecar_ext_len = strlen(BINARY_SIDECAR_EXT); // this can be optimized
const size_t sidecar_path_len = path_len + sidecar_ext_len + 1;
char *sidecar_path = (char *) malloc(sidecar_path_len);
memset(sidecar_path, '\0', sidecar_path_len);
memcpy(sidecar_path, path, path_len);
- memcpy(sidecar_path + path_len, SIDECAR_EXT, sidecar_ext_len);
+ memcpy(sidecar_path + path_len, BINARY_SIDECAR_EXT, sidecar_ext_len);
return sidecar_path;
}
--- /dev/null
+/*
+ fuse_xattrs - Add xattrs support using sidecar files
+
+ Copyright (C) 2017 Felipe Barriga Richards <felipe {at} felipebarriga.cl>
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#ifndef FUSE_XATTRS_CONFIG_H
+#define FUSE_XATTRS_CONFIG_H
+
+struct xattrs_config {
+ const char *source_dir;
+} xattrs_config;
+
+
+#endif //FUSE_XATTRS_CONFIG_H