aboutsummaryrefslogtreecommitdiffstats
path: root/src/bindfs.c
diff options
context:
space:
mode:
authorMartin Pärtel <martin.partel@gmail.com>2021-02-13 15:56:57 +0200
committerMartin Pärtel <martin.partel@gmail.com>2021-02-13 15:56:57 +0200
commitbc5313dc583cad9a3949bd798995ab1ee398ecf6 (patch)
tree3eef96d1b7cbb7a4e05a3ea954b1bc75231c1fd8 /src/bindfs.c
parent2cf41a75c11472bd6737b48c61f0a3d30cd6f242 (diff)
downloadbindfs-bc5313dc583cad9a3949bd798995ab1ee398ecf6.tar.gz
Refactored and unit-tested filter_special_opts. Shaved a bunch of yaks on the way.
Diffstat (limited to 'src/bindfs.c')
-rw-r--r--src/bindfs.c150
1 files changed, 26 insertions, 124 deletions
diff --git a/src/bindfs.c b/src/bindfs.c
index 57d0a8e..96f909b 100644
--- a/src/bindfs.c
+++ b/src/bindfs.c
@@ -31,20 +31,6 @@
#include <config.h>
-/* For >= 500 for pread/pwrite; >= 700 for utimensat */
-#define _XOPEN_SOURCE 700
-
-/* For flock() on FreeBSD. It otherwise gets hidden by _XOPEN_SOURCE */
-#define __BSD_VISIBLE 1
-
-/* For stat() nanosecond precision and lutimes() */
-#define _BSD_SOURCE
-/* The new non-deprecated version of _BSD_SOURCE */
-#define _DEFAULT_SOURCE
-
-/* Fix MacOS realpath() broken around Catalina (#83) */
-#define _DARWIN_BETTER_REALPATH
-
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
@@ -97,6 +83,7 @@
#include <fuse.h>
#include <fuse_opt.h>
+#include "arena.h"
#include "debug.h"
#include "misc.h"
#include "permchain.h"
@@ -367,6 +354,7 @@ Why? Because some of those options like "nofail"
are special ones interpreted by systemd in /etc/fstab
*/
struct fuse_args filter_special_opts(struct fuse_args *args);
+static bool keep_option(const char* opt);
static int is_mirroring_enabled()
{
@@ -2085,8 +2073,8 @@ static int parse_map_file(UserMap *map, UserMap *reverse_map, char *file, int as
UsermapStatus status;
// Toggle between UID (passwd) and GID (group)
- const int (*value_to_id)(const char *username, uid_t *ret);
- const UsermapStatus (*usermap_add)(UserMap *map, uid_t from, uid_t to);
+ int (*value_to_id)(const char *username, uid_t *ret);
+ UsermapStatus (*usermap_add)(UserMap *map, uid_t from, uid_t to);
const char *label_name, *label_id;
if (as_gid) {
value_to_id = &group_gid;
@@ -2336,11 +2324,27 @@ static void atexit_func()
struct fuse_args filter_special_opts(struct fuse_args *args)
{
- bool ignore;
+ struct arena arena;
+ arena_init(&arena);
+ int tmp_argc = args->argc;
+ char **tmp_argv;
+
+ filter_o_opts(&keep_option, args->argc, (const char * const *)args->argv, &tmp_argc, &tmp_argv, &arena);
+
struct fuse_args new_args = FUSE_ARGS_INIT(0, (void*)0);
+ for (int i = 0; i < tmp_argc; i++) {
+ fuse_opt_add_arg(&new_args, tmp_argv[i]);
+ }
+
+ arena_free(&arena);
+ fuse_opt_free_args(args);
+ return new_args;
+}
+static bool keep_option(const char* opt)
+{
// Copied from "libfuse/util/mount.fuse.c" (fuse-3.10.1)
- const char *ignore_opts[] = {
+ static const char * const ignored_opts[] = {
"",
"user",
"nofail",
@@ -2352,114 +2356,12 @@ struct fuse_args filter_special_opts(struct fuse_args *args)
NULL
};
- for (int i = 0; i < args->argc; i++) {
- ignore = false;
-
- /* If current element is exactly "-o" modify/check the following element */
- if (strcmp(args->argv[i], "-o") == 0 && (i+1) < args->argc) {
-
- /* remove ignored option from a comma separated list */
- if (strchr(args->argv[i+1], ',') != NULL) {
- char *tmpStr = (char*) calloc(strlen(args->argv[i+1]) + 1, sizeof(char));
- char *ptr = strtok(args->argv[i+1], ",");
- while (ptr != NULL) {
- ignore = false;
- for (int j = 0; ignore_opts[j]; j++) {
- if (strcmp(ptr, ignore_opts[j]) == 0) {
- ignore = true;
- break;
- }
- }
- if (!ignore) {
- if (strlen(tmpStr) > 0) strcat(tmpStr, ",");
- strcat(tmpStr, ptr);
- }
- ptr = strtok(NULL, ",");
- }
- if (strlen(tmpStr) > 0) {
- args->argv[i+1] = (char*) calloc(strlen(tmpStr) + 1, sizeof(char));
- strcpy(args->argv[i+1], tmpStr);
- free(tmpStr);
- ignore = false;
- }
- else {
- ignore = true;
- ++i;
- }
- }
-
- /* ignore this and the following element if it has exactly the ignored option */
- else {
- for (int j = 0; ignore_opts[j]; j++) {
- if (strcmp(args->argv[i+1], ignore_opts[j]) == 0) {
- ignore = true;
- ++i;
- break;
- }
- }
- }
- }
-
- /* else if element starts with "-o" */
- else if (strncmp(args->argv[i], "-o", 2) == 0) {
-
- /* remove ignored option from a comma seperated list */
- if (strchr(args->argv[i], ',') != NULL) {
- char *tmpStr = (char*) calloc(strlen(args->argv[i]) + 1, sizeof(char));
- char *tmpStr2 = (char*) calloc(strlen(args->argv[i]) + 1 - 2, sizeof(char));
- // remove first 2 chars from args->argv[i] and save this to tmpStr2
- memcpy(tmpStr2, args->argv[i] + 2, strlen(args->argv[i]) - 2);
- char *ptr = strtok(tmpStr2, ",");
- while (ptr != NULL) {
- ignore = false;
- for (int j = 0; ignore_opts[j]; j++) {
- if (strcmp(ptr, ignore_opts[j]) == 0) {
- ignore = true;
- break;
- }
- }
- if (!ignore) {
- if (strlen(tmpStr) > 0) strcat(tmpStr, ",");
- strcat(tmpStr, ptr);
- }
- ptr = strtok(NULL, ",");
- }
- if (strlen(tmpStr) > 0) {
- args->argv[i] = (char*) calloc(2 + strlen(tmpStr) + 1, sizeof(char));
- strcat(args->argv[i], "-o");
- strcat(args->argv[i], tmpStr);
- free(tmpStr);
- free(tmpStr2);
- ignore = false;
- }
- else {
- ignore = true;
- }
- }
-
- /* ignore this element if it has exactly the ignored option */
- else {
- for (int j = 0; ignore_opts[j]; j++) {
- char* tmpStr = (char*) calloc(2 + strlen(ignore_opts[j]) + 1, sizeof(char));
- strcat(tmpStr, "-o");
- strcat(tmpStr, ignore_opts[j]);
- if (strcmp(args->argv[i], tmpStr) == 0) {
- ignore = true;
- free(tmpStr);
- break;
- }
- free(tmpStr);
- }
- }
- }
- if (!ignore) {
- fuse_opt_add_arg(&new_args, strdup(args->argv[i]));
+ for (int i = 0; ignored_opts[i] != NULL; ++i) {
+ if (strcmp(ignored_opts[i], opt) == 0) {
+ return false;
}
}
-
- fuse_opt_free_args(args);
-
- return new_args;
+ return true;
}
int main(int argc, char *argv[])