1/* 2 * Copyright (c) 2007 Alistair Crooks. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. The name of the author may not be used to endorse or promote 13 * products derived from this software without specific prior written 14 * permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28#include <sys/cdefs.h> 29 30#ifndef lint 31__COPYRIGHT("@(#) Copyright (c) 2007\ 32 The NetBSD Foundation, Inc. All rights reserved."); 33__RCSID("$NetBSD: fusermount.c,v 1.2 2007/06/11 21:16:23 agc Exp $"); 34#endif 35 36#include <sys/types.h> 37#include <sys/param.h> 38#include <sys/mount.h> 39 40#include <err.h> 41#include <stdio.h> 42#include <stdlib.h> 43#include <string.h> 44#include <unistd.h> 45 46#ifndef FUSERMOUNT_VERSION 47#define FUSERMOUNT_VERSION "2.6.0" 48#endif 49 50enum { 51 FlagCheckPerm = 1, 52 FlagKernelCache, 53 FlagNonrootUsers, 54 55 ActionMount, 56 ActionUnmount 57}; 58 59/* unmount mount point(s) */ 60static int 61refuse_unmount(int argc, char **argv) 62{ 63 int ret; 64 int i; 65 66 for (ret = 1, i = 0 ; i < argc ; i++) { 67 if (unmount(argv[i], 0) < 0) { 68 warn("can't unmount `%s'", argv[i]); 69 ret = 0; 70 } 71 } 72 return ret; 73} 74 75/* print the usage meessage */ 76static void 77usage(const char *prog) 78{ 79 (void) fprintf(stderr, 80 "Usage: %s [-c] [-d name] [-h] [-p] [-u] [-x] mountpoint...\n", 81 prog); 82 (void) fprintf(stderr, "\t-c\tuse kernel cache\n"); 83 (void) fprintf(stderr, "\t-d name\tuse name in mount information\n"); 84 (void) fprintf(stderr, "\t-h\tprint help information\n"); 85 (void) fprintf(stderr, "\t-p\tcheck file permissions\n"); 86 (void) fprintf(stderr, "\t-u\tunmount mount point(s)\n"); 87 (void) fprintf(stderr, 88 "\t-x\tallow access to mortal (non-root) users\n"); 89} 90 91int 92main(int argc, char **argv) 93{ 94 char *progname; 95 char *execme; 96 int flags; 97 int action; 98 int i; 99 100 progname = NULL; 101 flags = 0; 102 action = ActionMount; 103 while ((i = getopt(argc, argv, "Vcd:hpux")) != -1) { 104 switch(i) { 105 case 'V': 106 printf("fusermount version: %s\n", FUSERMOUNT_VERSION); 107 exit(EXIT_SUCCESS); 108 /* NOTREACHED */ 109 case 'c': 110 flags |= FlagKernelCache; 111 break; 112 case 'd': 113 progname = optarg; 114 break; 115 case 'h': 116 usage(*argv); 117 exit(EXIT_SUCCESS); 118 case 'p': 119 flags |= FlagCheckPerm; 120 break; 121 case 'u': 122 action = ActionUnmount; 123 break; 124 case 'x': 125 if (geteuid() != 0) { 126 err(EXIT_FAILURE, 127 "-x option is only allowed for use by root"); 128 } 129 flags |= FlagNonrootUsers; 130 break; 131 default: 132 warnx("Unrecognised argument `%c'", i); 133 usage(*argv); 134 exit(EXIT_FAILURE); 135 } 136 } 137 if (optind >= argc - 2) { 138 warnx("Not enough command line arguments"); 139 usage(*argv); 140 exit(EXIT_FAILURE); 141 } 142 execme = argv[optind + 1]; 143 if (progname) { 144 argv[optind + 1] = progname; 145 } 146 /* mountpoint = argv[optind]; */ 147 switch(action) { 148 case ActionMount: 149 execvp(execme, &argv[optind + 1]); 150 break; 151 case ActionUnmount: 152 if (!refuse_unmount(argc - optind, argv + optind)) { 153 exit(EXIT_FAILURE); 154 } 155 break; 156 } 157 exit(EXIT_SUCCESS); 158} 159