11.1Sagc/*
21.3Slukem * Copyright (c) 2007 Alistair Crooks.  All rights reserved.
31.1Sagc *
41.1Sagc * Redistribution and use in source and binary forms, with or without
51.1Sagc * modification, are permitted provided that the following conditions
61.1Sagc * are met:
71.1Sagc * 1. Redistributions of source code must retain the above copyright
81.1Sagc *    notice, this list of conditions and the following disclaimer.
91.1Sagc * 2. Redistributions in binary form must reproduce the above copyright
101.1Sagc *    notice, this list of conditions and the following disclaimer in the
111.1Sagc *    documentation and/or other materials provided with the distribution.
121.1Sagc * 3. The name of the author may not be used to endorse or promote
131.1Sagc *    products derived from this software without specific prior written
141.1Sagc *    permission.
151.1Sagc *
161.1Sagc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
171.1Sagc * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
181.1Sagc * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
191.1Sagc * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
201.1Sagc * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
211.1Sagc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
221.1Sagc * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
231.1Sagc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
241.1Sagc * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
251.1Sagc * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
261.1Sagc * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271.1Sagc */
281.1Sagc#include <sys/cdefs.h>
291.1Sagc
301.1Sagc#ifndef lint
311.3Slukem__COPYRIGHT("@(#) Copyright (c) 2007\
321.3Slukem The NetBSD Foundation, Inc.  All rights reserved.");
331.4Sandvar__RCSID("$NetBSD: fusermount.c,v 1.4 2023/04/05 21:53:56 andvar Exp $");
341.1Sagc#endif
351.1Sagc
361.1Sagc#include <sys/types.h>
371.1Sagc#include <sys/param.h>
381.1Sagc#include <sys/mount.h>
391.1Sagc
401.1Sagc#include <err.h>
411.1Sagc#include <stdio.h>
421.1Sagc#include <stdlib.h>
431.1Sagc#include <string.h>
441.1Sagc#include <unistd.h>
451.1Sagc
461.2Sagc#ifndef FUSERMOUNT_VERSION
471.2Sagc#define FUSERMOUNT_VERSION	"2.6.0"
481.2Sagc#endif
491.2Sagc
501.1Sagcenum {
511.1Sagc	FlagCheckPerm = 1,
521.1Sagc	FlagKernelCache,
531.1Sagc	FlagNonrootUsers,
541.1Sagc
551.1Sagc	ActionMount,
561.1Sagc	ActionUnmount
571.1Sagc};
581.1Sagc
591.1Sagc/* unmount mount point(s) */
601.1Sagcstatic int
611.1Sagcrefuse_unmount(int argc, char **argv)
621.1Sagc{
631.1Sagc	int	ret;
641.1Sagc	int	i;
651.1Sagc
661.1Sagc	for (ret = 1, i = 0 ; i < argc ; i++) {
671.1Sagc		if (unmount(argv[i], 0) < 0) {
681.1Sagc			warn("can't unmount `%s'", argv[i]);
691.1Sagc			ret = 0;
701.1Sagc		}
711.1Sagc	}
721.1Sagc	return ret;
731.1Sagc}
741.1Sagc
751.4Sandvar/* print the usage message */
761.1Sagcstatic void
771.1Sagcusage(const char *prog)
781.1Sagc{
791.1Sagc	(void) fprintf(stderr,
801.1Sagc		"Usage: %s [-c] [-d name] [-h] [-p] [-u] [-x] mountpoint...\n",
811.1Sagc		prog);
821.1Sagc	(void) fprintf(stderr, "\t-c\tuse kernel cache\n");
831.1Sagc	(void) fprintf(stderr, "\t-d name\tuse name in mount information\n");
841.1Sagc	(void) fprintf(stderr, "\t-h\tprint help information\n");
851.1Sagc	(void) fprintf(stderr, "\t-p\tcheck file permissions\n");
861.1Sagc	(void) fprintf(stderr, "\t-u\tunmount mount point(s)\n");
871.1Sagc	(void) fprintf(stderr,
881.1Sagc		"\t-x\tallow access to mortal (non-root) users\n");
891.1Sagc}
901.1Sagc
911.1Sagcint
921.1Sagcmain(int argc, char **argv)
931.1Sagc{
941.1Sagc	char	*progname;
951.1Sagc	char	*execme;
961.1Sagc	int	 flags;
971.1Sagc	int	 action;
981.1Sagc	int	 i;
991.1Sagc
1001.1Sagc	progname = NULL;
1011.1Sagc	flags = 0;
1021.1Sagc	action = ActionMount;
1031.2Sagc	while ((i = getopt(argc, argv, "Vcd:hpux")) != -1) {
1041.1Sagc		switch(i) {
1051.2Sagc		case 'V':
1061.2Sagc			printf("fusermount version: %s\n", FUSERMOUNT_VERSION);
1071.2Sagc			exit(EXIT_SUCCESS);
1081.2Sagc			/* NOTREACHED */
1091.1Sagc		case 'c':
1101.1Sagc			flags |= FlagKernelCache;
1111.1Sagc			break;
1121.1Sagc		case 'd':
1131.1Sagc			progname = optarg;
1141.1Sagc			break;
1151.1Sagc		case 'h':
1161.1Sagc			usage(*argv);
1171.1Sagc			exit(EXIT_SUCCESS);
1181.1Sagc		case 'p':
1191.1Sagc			flags |= FlagCheckPerm;
1201.1Sagc			break;
1211.1Sagc		case 'u':
1221.1Sagc			action = ActionUnmount;
1231.1Sagc			break;
1241.1Sagc		case 'x':
1251.1Sagc			if (geteuid() != 0) {
1261.1Sagc				err(EXIT_FAILURE,
1271.1Sagc				"-x option is only allowed for use by root");
1281.1Sagc			}
1291.1Sagc			flags |= FlagNonrootUsers;
1301.1Sagc			break;
1311.1Sagc		default:
1321.1Sagc			warnx("Unrecognised argument `%c'", i);
1331.1Sagc			usage(*argv);
1341.1Sagc			exit(EXIT_FAILURE);
1351.1Sagc		}
1361.1Sagc	}
1371.1Sagc	if (optind >= argc - 2) {
1381.1Sagc		warnx("Not enough command line arguments");
1391.1Sagc		usage(*argv);
1401.1Sagc		exit(EXIT_FAILURE);
1411.1Sagc	}
1421.1Sagc	execme = argv[optind + 1];
1431.1Sagc	if (progname) {
1441.1Sagc		argv[optind + 1] = progname;
1451.1Sagc	}
1461.1Sagc	/* mountpoint = argv[optind]; */
1471.1Sagc	switch(action) {
1481.1Sagc	case ActionMount:
1491.1Sagc		execvp(execme, &argv[optind + 1]);
1501.1Sagc		break;
1511.1Sagc	case ActionUnmount:
1521.1Sagc		if (!refuse_unmount(argc - optind, argv + optind)) {
1531.1Sagc			exit(EXIT_FAILURE);
1541.1Sagc		}
1551.1Sagc		break;
1561.1Sagc	}
1571.1Sagc	exit(EXIT_SUCCESS);
1581.1Sagc}
159