#include <assert.h>
#include <fuse_opt.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
struct data {
int port;
char *fsname;
char *x;
char *optstring;
int debug;
int foreground;
int noatime;
int ssh_ver;
int count;
int cache;
int set_gid;
int gid;
int bad_opt;
};
enum {
KEY_DEBUG,
KEY_NOATIME,
KEY_PORT
};
#define DATA_OPT(o,m,v) {o, offsetof(struct data, m), v}
struct fuse_opt opts[] = {
FUSE_OPT_KEY("noatime", KEY_NOATIME ),
DATA_OPT("optstring=%s", optstring, 0),
DATA_OPT("-f=%s", fsname, 0),
DATA_OPT("-x %s", x, 0),
DATA_OPT("--count=%u", count, 0),
DATA_OPT("-1", ssh_ver, 5),
DATA_OPT("cache=yes", cache, 1),
DATA_OPT("cache=no", cache, 0),
DATA_OPT("debug", debug, 1),
DATA_OPT("debug", foreground, 1),
FUSE_OPT_KEY("debug", KEY_DEBUG ),
FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
DATA_OPT("-p", port, 25),
FUSE_OPT_KEY("-p ", KEY_PORT ),
DATA_OPT("gid=", set_gid, 1),
DATA_OPT("gid=%o", gid, 1),
FUSE_OPT_END
};
int
proc(void *data, const char *arg, int key, struct fuse_args *args)
{
struct data *conf = data;
if (conf == NULL)
return (1);
switch (key)
{
case KEY_PORT:
conf->port = atoi(&arg[2]);
return (0);
case KEY_DEBUG:
conf->debug = 2;
return (0);
case KEY_NOATIME:
conf->noatime = 1;
return (1);
}
if (strcmp("bad_opt", arg) == 0) {
conf->bad_opt = 1;
return (0);
}
return (1);
}
void
test_null_args(void) {
struct data data;
struct fuse_args args;
bzero(&data, sizeof(data));
assert(fuse_opt_parse(NULL, &data, opts, proc) == 0);
assert(data.port == 0);
assert(data.fsname == NULL);
assert(data.x == NULL);
assert(data.optstring == NULL);
assert(data.debug == 0);
assert(data.noatime == 0);
assert(data.ssh_ver == 0);
assert(data.count == 0);
assert(data.cache == 0);
assert(data.bad_opt == 0);
}
void
test_null_opts(void)
{
struct data data;
struct fuse_args args;
char *argv_null_opts[] = {
"progname",
"/mnt",
"bad_opt"
};
args.argc = sizeof(argv_null_opts) / sizeof(argv_null_opts[0]);
args.argv = argv_null_opts;
args.allocated = 0;
bzero(&data, sizeof(data));
assert(fuse_opt_parse(&args, &data, NULL, proc) == 0);
assert(data.port == 0);
assert(data.fsname == NULL);
assert(data.x == NULL);
assert(data.optstring == NULL);
assert(data.debug == 0);
assert(data.noatime == 0);
assert(data.ssh_ver == 0);
assert(data.count == 0);
assert(data.cache == 0);
assert(data.set_gid == 0);
assert(data.gid == 0);
assert(data.bad_opt == 1);
assert(args.argc == 2);
assert(strcmp(args.argv[0], "progname") == 0);
assert(strcmp(args.argv[1], "/mnt") == 0);
assert(args.allocated);
fuse_opt_free_args(&args);
}
void
test_null_proc(void)
{
struct data data;
struct fuse_args args;
char *argv_null_proc[] = {
"progname",
"-odebug,noatime,gid=077",
"-d",
"-p", "22",
"/mnt",
"-f=filename",
"-1",
"-x", "xanadu",
"-o", "optstring=",
"-o", "optstring=optstring",
"--count=10",
"bad_opt"
};
args.argc = sizeof(argv_null_proc) / sizeof(argv_null_proc[0]);
args.argv = argv_null_proc;
args.allocated = 0;
bzero(&data, sizeof(data));
assert(fuse_opt_parse(&args, &data, opts, NULL) == 0);
assert(data.port == 25);
assert(strcmp(data.fsname, "filename") == 0);
assert(strcmp(data.x, "xanadu") == 0);
assert(strcmp(data.optstring, "optstring") == 0);
assert(data.debug == 1);
assert(data.noatime == 0);
assert(data.ssh_ver == 5);
assert(data.count == 10);
assert(data.cache == 0);
assert(data.set_gid == 1);
assert(data.gid == 077);
assert(data.bad_opt == 0);
assert(args.argc == 9);
assert(strcmp(args.argv[0], "progname") == 0);
assert(strcmp(args.argv[1], "-o") == 0);
assert(strcmp(args.argv[2], "debug") == 0);
assert(strcmp(args.argv[3], "-o") == 0);
assert(strcmp(args.argv[4], "noatime") == 0);
assert(strcmp(args.argv[5], "-d") == 0);
assert(strcmp(args.argv[6], "-p22") == 0);
assert(strcmp(args.argv[7], "/mnt") == 0);
assert(strcmp(args.argv[8], "bad_opt") == 0);
assert(args.allocated);
fuse_opt_free_args(&args);
}
void
test_all_args(void)
{
struct data data;
struct fuse_args args;
char *argv[] = {
"progname",
"-odebug,noatime,gid=077",
"-d",
"-p", "22",
"/mnt",
"-f=filename",
"-1",
"-x", "xanadu",
"-o", "optstring=optstring,cache=no",
"--count=10",
"bad_opt"
};
args.argc = sizeof(argv) / sizeof(argv[0]);
args.argv = argv;
args.allocated = 0;
bzero(&data, sizeof(data));
assert(fuse_opt_parse(&args, &data, opts, proc) == 0);
assert(data.port == 22);
assert(strcmp(data.fsname, "filename") == 0);
assert(strcmp(data.x, "xanadu") == 0);
assert(strcmp(data.optstring, "optstring") == 0);
assert(data.debug == 2);
assert(data.noatime == 1);
assert(data.ssh_ver == 5);
assert(data.count == 10);
assert(data.cache == 0);
assert(data.set_gid == 1);
assert(data.gid == 077);
assert(data.bad_opt == 1);
assert(args.argc == 7);
assert(strcmp(args.argv[0], "progname") == 0);
assert(strcmp(args.argv[1], "-o") == 0);
assert(strcmp(args.argv[2], "debug") == 0);
assert(strcmp(args.argv[3], "-o") == 0);
assert(strcmp(args.argv[4], "noatime") == 0);
assert(strcmp(args.argv[5], "-d") == 0);
assert(strcmp(args.argv[6], "/mnt") == 0);
assert(args.allocated);
fuse_opt_free_args(&args);
}
int
main(void)
{
test_null_opts();
test_null_args();
test_null_proc();
test_all_args();
return (0);
}