1*4bff34e3Sthurlow /*
2*4bff34e3Sthurlow  * CDDL HEADER START
3*4bff34e3Sthurlow  *
4*4bff34e3Sthurlow  * The contents of this file are subject to the terms of the
5*4bff34e3Sthurlow  * Common Development and Distribution License (the "License").
6*4bff34e3Sthurlow  * You may not use this file except in compliance with the License.
7*4bff34e3Sthurlow  *
8*4bff34e3Sthurlow  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4bff34e3Sthurlow  * or http://www.opensolaris.org/os/licensing.
10*4bff34e3Sthurlow  * See the License for the specific language governing permissions
11*4bff34e3Sthurlow  * and limitations under the License.
12*4bff34e3Sthurlow  *
13*4bff34e3Sthurlow  * When distributing Covered Code, include this CDDL HEADER in each
14*4bff34e3Sthurlow  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4bff34e3Sthurlow  * If applicable, add the following below this CDDL HEADER, with the
16*4bff34e3Sthurlow  * fields enclosed by brackets "[]" replaced with your own identifying
17*4bff34e3Sthurlow  * information: Portions Copyright [yyyy] [name of copyright owner]
18*4bff34e3Sthurlow  *
19*4bff34e3Sthurlow  * CDDL HEADER END
20*4bff34e3Sthurlow  */
21*4bff34e3Sthurlow /*
22*4bff34e3Sthurlow  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*4bff34e3Sthurlow  * Use is subject to license terms.
24*4bff34e3Sthurlow  */
25*4bff34e3Sthurlow 
26*4bff34e3Sthurlow #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*4bff34e3Sthurlow 
28*4bff34e3Sthurlow /*
29*4bff34e3Sthurlow  * smbfs umount
30*4bff34e3Sthurlow  */
31*4bff34e3Sthurlow 
32*4bff34e3Sthurlow #include <stdio.h>
33*4bff34e3Sthurlow #include <stdlib.h>
34*4bff34e3Sthurlow #include <string.h>
35*4bff34e3Sthurlow #include <stdarg.h>
36*4bff34e3Sthurlow #include <signal.h>
37*4bff34e3Sthurlow #include <unistd.h>
38*4bff34e3Sthurlow #include <kstat.h>
39*4bff34e3Sthurlow #include <rpc/rpc.h>
40*4bff34e3Sthurlow #include <sys/mnttab.h>
41*4bff34e3Sthurlow #include <sys/mount.h>
42*4bff34e3Sthurlow #include <sys/mntent.h>
43*4bff34e3Sthurlow #include <errno.h>
44*4bff34e3Sthurlow #include <locale.h>
45*4bff34e3Sthurlow #include <fslib.h>
46*4bff34e3Sthurlow #include <priv.h>
47*4bff34e3Sthurlow 
48*4bff34e3Sthurlow #define	RET_OK	0
49*4bff34e3Sthurlow #define	RET_ERR	32
50*4bff34e3Sthurlow 
51*4bff34e3Sthurlow static void pr_err(const char *fmt, ...);
52*4bff34e3Sthurlow static void usage();
53*4bff34e3Sthurlow static int smbfs_unmount(char *, int);
54*4bff34e3Sthurlow static struct extmnttab *mnttab_find();
55*4bff34e3Sthurlow 
56*4bff34e3Sthurlow static char *myname;
57*4bff34e3Sthurlow static char typename[64];
58*4bff34e3Sthurlow 
59*4bff34e3Sthurlow int
60*4bff34e3Sthurlow main(int argc, char *argv[])
61*4bff34e3Sthurlow {
62*4bff34e3Sthurlow 	extern int optind;
63*4bff34e3Sthurlow 	int c;
64*4bff34e3Sthurlow 	int umnt_flag = 0;
65*4bff34e3Sthurlow 
66*4bff34e3Sthurlow 	(void) setlocale(LC_ALL, "");
67*4bff34e3Sthurlow 
68*4bff34e3Sthurlow #if !defined(TEXT_DOMAIN)
69*4bff34e3Sthurlow #define	TEXT_DOMAIN "SYS_TEST"
70*4bff34e3Sthurlow #endif
71*4bff34e3Sthurlow 	(void) textdomain(TEXT_DOMAIN);
72*4bff34e3Sthurlow 
73*4bff34e3Sthurlow 	myname = strrchr(argv[0], '/');
74*4bff34e3Sthurlow 	myname = myname ? myname+1 : argv[0];
75*4bff34e3Sthurlow 	(void) sprintf(typename, "smbfs %s", myname);
76*4bff34e3Sthurlow 	argv[0] = typename;
77*4bff34e3Sthurlow 
78*4bff34e3Sthurlow 	/*
79*4bff34e3Sthurlow 	 * Set options
80*4bff34e3Sthurlow 	 */
81*4bff34e3Sthurlow 	while ((c = getopt(argc, argv, "f")) != EOF) {
82*4bff34e3Sthurlow 		switch (c) {
83*4bff34e3Sthurlow 		case 'f':
84*4bff34e3Sthurlow 			umnt_flag |= MS_FORCE; /* forced unmount is desired */
85*4bff34e3Sthurlow 			break;
86*4bff34e3Sthurlow 		default:
87*4bff34e3Sthurlow 			usage();
88*4bff34e3Sthurlow 			exit(RET_ERR);
89*4bff34e3Sthurlow 		}
90*4bff34e3Sthurlow 	}
91*4bff34e3Sthurlow 	if (argc - optind != 1) {
92*4bff34e3Sthurlow 		usage();
93*4bff34e3Sthurlow 		exit(RET_ERR);
94*4bff34e3Sthurlow 	}
95*4bff34e3Sthurlow 
96*4bff34e3Sthurlow 	return (smbfs_unmount(argv[optind], umnt_flag));
97*4bff34e3Sthurlow }
98*4bff34e3Sthurlow 
99*4bff34e3Sthurlow static void
100*4bff34e3Sthurlow pr_err(const char *fmt, ...)
101*4bff34e3Sthurlow {
102*4bff34e3Sthurlow 	va_list ap;
103*4bff34e3Sthurlow 
104*4bff34e3Sthurlow 	va_start(ap, fmt);
105*4bff34e3Sthurlow 	(void) fprintf(stderr, "%s: ", typename);
106*4bff34e3Sthurlow 	(void) vfprintf(stderr, fmt, ap);
107*4bff34e3Sthurlow 	(void) fflush(stderr);
108*4bff34e3Sthurlow 	va_end(ap);
109*4bff34e3Sthurlow }
110*4bff34e3Sthurlow 
111*4bff34e3Sthurlow static void
112*4bff34e3Sthurlow usage()
113*4bff34e3Sthurlow {
114*4bff34e3Sthurlow 	(void) fprintf(stderr,
115*4bff34e3Sthurlow 	    gettext("Usage: smbfs umount [-o opts] {//server/share | dir}\n"));
116*4bff34e3Sthurlow 	exit(RET_ERR);
117*4bff34e3Sthurlow }
118*4bff34e3Sthurlow 
119*4bff34e3Sthurlow static int
120*4bff34e3Sthurlow smbfs_unmount(char *pathname, int umnt_flag)
121*4bff34e3Sthurlow {
122*4bff34e3Sthurlow 	struct extmnttab *mntp;
123*4bff34e3Sthurlow 
124*4bff34e3Sthurlow 	mntp = mnttab_find(pathname);
125*4bff34e3Sthurlow 	if (mntp) {
126*4bff34e3Sthurlow 		pathname = mntp->mnt_mountp;
127*4bff34e3Sthurlow 	}
128*4bff34e3Sthurlow 
129*4bff34e3Sthurlow 	if (umount2(pathname, umnt_flag) < 0) {
130*4bff34e3Sthurlow 		pr_err(gettext("%s: %s\n"), pathname, strerror(errno));
131*4bff34e3Sthurlow 		return (RET_ERR);
132*4bff34e3Sthurlow 	}
133*4bff34e3Sthurlow 
134*4bff34e3Sthurlow 	return (RET_OK);
135*4bff34e3Sthurlow }
136*4bff34e3Sthurlow 
137*4bff34e3Sthurlow /*
138*4bff34e3Sthurlow  *  Find the mnttab entry that corresponds to "name".
139*4bff34e3Sthurlow  *  We're not sure what the name represents: either
140*4bff34e3Sthurlow  *  a mountpoint name, or a special name (server:/path).
141*4bff34e3Sthurlow  *  Return the last entry in the file that matches.
142*4bff34e3Sthurlow  */
143*4bff34e3Sthurlow static struct extmnttab *
144*4bff34e3Sthurlow mnttab_find(dirname)
145*4bff34e3Sthurlow 	char *dirname;
146*4bff34e3Sthurlow {
147*4bff34e3Sthurlow 	FILE *fp;
148*4bff34e3Sthurlow 	struct extmnttab mnt;
149*4bff34e3Sthurlow 	struct extmnttab *res = NULL;
150*4bff34e3Sthurlow 
151*4bff34e3Sthurlow 	fp = fopen(MNTTAB, "r");
152*4bff34e3Sthurlow 	if (fp == NULL) {
153*4bff34e3Sthurlow 		pr_err("%s: %s\n", MNTTAB, strerror(errno));
154*4bff34e3Sthurlow 		return (NULL);
155*4bff34e3Sthurlow 	}
156*4bff34e3Sthurlow 	while (getextmntent(fp, &mnt, sizeof (struct extmnttab)) == 0) {
157*4bff34e3Sthurlow 		if (strcmp(mnt.mnt_mountp, dirname) == 0 ||
158*4bff34e3Sthurlow 		    strcmp(mnt.mnt_special, dirname) == 0) {
159*4bff34e3Sthurlow 			if (res)
160*4bff34e3Sthurlow 				fsfreemnttab(res);
161*4bff34e3Sthurlow 			res = fsdupmnttab(&mnt);
162*4bff34e3Sthurlow 		}
163*4bff34e3Sthurlow 	}
164*4bff34e3Sthurlow 
165*4bff34e3Sthurlow 	fclose(fp);
166*4bff34e3Sthurlow 	return (res);
167*4bff34e3Sthurlow }
168