1/* $NetBSD: refuse_lowlevel.c,v 1.4 2022/01/22 08:09:39 pho Exp $ */ 2 3/* 4 * Copyright (c) 2016 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote 16 * products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 25 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33#if !defined(lint) 34__RCSID("$NetBSD: refuse_lowlevel.c,v 1.4 2022/01/22 08:09:39 pho Exp $"); 35#endif /* !lint */ 36 37#include <fuse_internal.h> 38#include <fuse_opt.h> 39#include <stddef.h> 40#include <stdio.h> 41#include <stdlib.h> 42#include <string.h> 43 44#define REFUSE_LOWLEVEL_OPT(t, p, v) \ 45 { t, offsetof(struct fuse_cmdline_opts, p), v } 46 47static struct fuse_opt fuse_lowlevel_opts[] = { 48 REFUSE_LOWLEVEL_OPT("-h" , show_help , REFUSE_SHOW_HELP_FULL), 49 REFUSE_LOWLEVEL_OPT("--help" , show_help , REFUSE_SHOW_HELP_FULL), 50 REFUSE_LOWLEVEL_OPT("-ho" , show_help , REFUSE_SHOW_HELP_NO_HEADER), 51 REFUSE_LOWLEVEL_OPT("-V" , show_version , 1), 52 REFUSE_LOWLEVEL_OPT("--version", show_version , 1), 53 REFUSE_LOWLEVEL_OPT("-d" , debug , 1), 54 REFUSE_LOWLEVEL_OPT("debug" , debug , 1), 55 REFUSE_LOWLEVEL_OPT("-d" , foreground , 1), 56 REFUSE_LOWLEVEL_OPT("debug" , foreground , 1), 57 REFUSE_LOWLEVEL_OPT("-f" , foreground , 1), 58 REFUSE_LOWLEVEL_OPT("-s" , singlethread , 1), 59 REFUSE_LOWLEVEL_OPT("fsname=" , nodefault_fsname, 1), 60 FUSE_OPT_KEY ("fsname=" , FUSE_OPT_KEY_KEEP ), 61 FUSE_OPT_END 62}; 63 64void fuse_lowlevel_version(void) 65{ 66 /* XXX: Print something */ 67} 68 69void fuse_cmdline_help(void) 70{ 71 printf("refuse options:\n" 72 " -d, -o debug enable debug output, implies -f\n" 73 " -f foreground mode\n" 74 " -s single threaded mode (always enabled for now)\n" 75 " -o fsname=NAME explicitly set the name of the file system\n"); 76} 77 78static int refuse_lowlevel_opt_proc(void* data, const char *arg, int key, 79 struct fuse_args *outargs) 80{ 81 struct fuse_cmdline_opts *opts = data; 82 83 switch (key) { 84 case FUSE_OPT_KEY_NONOPT: 85 if (opts->mountpoint == NULL) { 86 return fuse_opt_add_opt(&opts->mountpoint, arg); 87 } 88 else { 89 (void)fprintf(stderr, "fuse: invalid argument: %s\n", arg); 90 return -1; 91 } 92 93 default: 94 return 1; /* keep the argument */ 95 } 96} 97 98static int add_default_fsname(struct fuse_args *args) 99{ 100 const char *arg0 = args->argv[0]; 101 const char *slash; 102 103 if (arg0 == NULL || arg0[0] == '\0') { 104 return fuse_opt_add_arg(args, "-ofsname=refuse"); 105 } else { 106 char *arg; 107 int rv; 108 109 if ((slash = strrchr(arg0, '/')) == NULL) { 110 slash = arg0; 111 } else { 112 slash += 1; 113 } 114 115 if (asprintf(&arg, "-ofsname=refuse:%s", slash) == -1) 116 return -1; 117 118 rv = fuse_opt_add_arg(args, arg); 119 free(arg); 120 return rv; 121 } 122} 123 124int 125__fuse_parse_cmdline(struct fuse_args *args, struct fuse_cmdline_opts *opts) 126{ 127 memset(opts, 0, sizeof(*opts)); 128 129 /* 130 * XXX: The single threaded mode is always enabled and cannot be 131 * disabled. This is because puffs currently does not support 132 * multithreaded operation. 133 */ 134 opts->singlethread = 1; 135 136 if (fuse_opt_parse(args, opts, fuse_lowlevel_opts, 137 refuse_lowlevel_opt_proc) == -1) 138 return -1; 139 140 if (!opts->nodefault_fsname) { 141 /* -o fsname=%s is not specified so add a default fsname 142 * generated from the program basename. 143 */ 144 if (add_default_fsname(args) == -1) 145 return -1; 146 } 147 148 return 0; 149} 150