fusermount.c revision 1.1
1/*
2 * Copyright � 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.1 2007/04/26 21:13:39 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
46enum {
47	FlagCheckPerm = 1,
48	FlagKernelCache,
49	FlagNonrootUsers,
50
51	ActionMount,
52	ActionUnmount
53};
54
55/* unmount mount point(s) */
56static int
57refuse_unmount(int argc, char **argv)
58{
59	int	ret;
60	int	i;
61
62	for (ret = 1, i = 0 ; i < argc ; i++) {
63		if (unmount(argv[i], 0) < 0) {
64			warn("can't unmount `%s'", argv[i]);
65			ret = 0;
66		}
67	}
68	return ret;
69}
70
71/* print the usage meessage */
72static void
73usage(const char *prog)
74{
75	(void) fprintf(stderr,
76		"Usage: %s [-c] [-d name] [-h] [-p] [-u] [-x] mountpoint...\n",
77		prog);
78	(void) fprintf(stderr, "\t-c\tuse kernel cache\n");
79	(void) fprintf(stderr, "\t-d name\tuse name in mount information\n");
80	(void) fprintf(stderr, "\t-h\tprint help information\n");
81	(void) fprintf(stderr, "\t-p\tcheck file permissions\n");
82	(void) fprintf(stderr, "\t-u\tunmount mount point(s)\n");
83	(void) fprintf(stderr,
84		"\t-x\tallow access to mortal (non-root) users\n");
85}
86
87int
88main(int argc, char **argv)
89{
90	char	*progname;
91	char	*execme;
92	int	 flags;
93	int	 action;
94	int	 i;
95
96	progname = NULL;
97	flags = 0;
98	action = ActionMount;
99	while ((i = getopt(argc, argv, "cd:hpux")) != -1) {
100		switch(i) {
101		case 'c':
102			flags |= FlagKernelCache;
103			break;
104		case 'd':
105			progname = optarg;
106			break;
107		case 'h':
108			usage(*argv);
109			exit(EXIT_SUCCESS);
110		case 'p':
111			flags |= FlagCheckPerm;
112			break;
113		case 'u':
114			action = ActionUnmount;
115			break;
116		case 'x':
117			if (geteuid() != 0) {
118				err(EXIT_FAILURE,
119				"-x option is only allowed for use by root");
120			}
121			flags |= FlagNonrootUsers;
122			break;
123		default:
124			warnx("Unrecognised argument `%c'", i);
125			usage(*argv);
126			exit(EXIT_FAILURE);
127		}
128	}
129	if (optind >= argc - 2) {
130		warnx("Not enough command line arguments");
131		usage(*argv);
132		exit(EXIT_FAILURE);
133	}
134	execme = argv[optind + 1];
135	if (progname) {
136		argv[optind + 1] = progname;
137	}
138	/* mountpoint = argv[optind]; */
139	switch(action) {
140	case ActionMount:
141		execvp(execme, &argv[optind + 1]);
142		break;
143	case ActionUnmount:
144		if (!refuse_unmount(argc - optind, argv + optind)) {
145			exit(EXIT_FAILURE);
146		}
147		break;
148	}
149	exit(EXIT_SUCCESS);
150}
151