From 36f17d24955ce912c79bf587c37de3da2cbe7667 Mon Sep 17 00:00:00 2001 From: Alessandro Strada Date: Sun, 11 Feb 2024 22:12:21 +0100 Subject: [PATCH] Better command line parsing --- lib/Fuse_main.c | 102 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 28 deletions(-) diff --git a/lib/Fuse_main.c b/lib/Fuse_main.c index 3616274..d0c67be 100644 --- a/lib/Fuse_main.c +++ b/lib/Fuse_main.c @@ -28,8 +28,8 @@ #endif #include -#include +#include #include #include #include @@ -40,54 +40,100 @@ char **insert_foreground_option(int argc, char **argv); void free_fuse_argv(int n, char **fuse_argv); +void start_program(int argc, char **argv, char *mountpoint, int foreground); +void parse_fuse_args(int argc, char **argv, struct fuse_args *args); +bool is_fuse_arg(char *arg, char *prev); /* https://v2.ocaml.org/releases/5.1/htmlman/intfc.html#ss:main-c */ int main(int argc, char **argv) { - int c; - int foreground = 0; - int res; - char **fuse_argv = argv; + struct fuse_args args = FUSE_ARGS_INIT(0, NULL); + char *mountpoint; + int foreground; - opterr = 0; - while ((c = getopt(argc, argv, "f")) != -1) { - switch (c) { - case 'f': - foreground = 1; - break; - default: - break; + parse_fuse_args(argc, argv, &args); + if (fuse_parse_cmdline(&args, &mountpoint, NULL, &foreground) != -1) { + start_program(argc, argv, mountpoint, foreground); + + fuse_opt_free_args(&args); + return 0; + } + + fuse_opt_free_args(&args); + return 1; +} + +void parse_fuse_args(int argc, char **argv, struct fuse_args *args) { + int i = 1; + + fuse_opt_add_arg(args, argv[0]); + while (i < argc) { + if (is_fuse_arg(argv[i], argv[i - 1])) { + fuse_opt_add_arg(args, argv[i]); } + ++i; } +} - /* https://github.com/libfuse/libfuse/blob/d04687923194d906fe5ad82dcd546c9807bf15b6/include/fuse_common.h#L246 - */ - if (fuse_daemonize(foreground) == -1) { - perror("fuse_daemonize"); - return 1; +bool is_fuse_arg(char *arg, char *prev) { + if (strcmp(arg, "--help") == 0) { + return true; } + if (strcmp(arg, "--version") == 0) { + return true; + } + if (arg[0] == '-') { + switch (arg[1]) { + case 'o': + case 'h': + case 'V': + case 'd': + case 'f': + case 's': + return true; + } + } else { + if (prev != NULL && strcmp(prev, "-o") == 0) { + return true; + } else { + if (access(arg, F_OK) == 0) { + return true; + } + } + } + return false; +} + +void start_program(int argc, char **argv, char *mountpoint, int foreground) { + char **fuse_argv = argv; + + if (mountpoint != NULL) { + /* https://github.com/libfuse/libfuse/blob/d04687923194d906fe5ad82dcd546c9807bf15b6/include/fuse_common.h#L246 + */ + if (fuse_daemonize(foreground) == -1) { + perror("fuse_daemonize"); + exit(1); + } - if (foreground == 0) { - fuse_argv = insert_foreground_option(argc, argv); + if (!foreground) { + fuse_argv = insert_foreground_option(argc, argv); + } } caml_main(fuse_argv); - if (foreground == 0) { + if (fuse_argv != argv) { free_fuse_argv(argc + 1, fuse_argv); } - - return 0; } char **insert_foreground_option(int argc, char **argv) { - char *mountpoint = argv[argc - 1]; char **new_argv = malloc((argc + 2) * sizeof(*new_argv)); - for (int i = 0; i < argc - 1; ++i) { - new_argv[i] = strdup(argv[i]); + new_argv[0] = strdup(argv[0]); + new_argv[1] = strdup("-f"); + for (int i = 1; i < argc; ++i) { + new_argv[i + 1] = strdup(argv[i]); } - new_argv[argc - 1] = strdup("-f"); - new_argv[argc] = strdup(mountpoint); return new_argv; }