Thu Apr 23 04:21:13 2020 UTC ()
make umount NAME= work


(christos)
diff -r1.19 -r1.20 src/sbin/umount/Makefile
diff -r1.52 -r1.53 src/sbin/umount/umount.c

cvs diff -r1.19 -r1.20 src/sbin/umount/Makefile (switch to unified diff)

--- src/sbin/umount/Makefile 2019/10/13 07:28:13 1.19
+++ src/sbin/umount/Makefile 2020/04/23 04:21:13 1.20
@@ -1,21 +1,23 @@ @@ -1,21 +1,23 @@
1# $NetBSD: Makefile,v 1.19 2019/10/13 07:28:13 mrg Exp $ 1# $NetBSD: Makefile,v 1.20 2020/04/23 04:21:13 christos Exp $
2# @(#)Makefile 8.4 (Berkeley) 6/22/95 2# @(#)Makefile 8.4 (Berkeley) 6/22/95
3 3
4.include <bsd.own.mk> 4.include <bsd.own.mk>
5 5
6PROG= umount 6PROG= umount
7SRCS= umount.c 7SRCS= umount.c
8MAN= umount.8 8MAN= umount.8
9 9
10.ifdef SMALLPROG 10.ifdef SMALLPROG
11CPPFLAGS+= -DSMALL 11CPPFLAGS+= -DSMALL
12.else 12.else
13MOUNT= ${NETBSDSRCDIR}/sbin/mount 13MOUNT= ${NETBSDSRCDIR}/sbin/mount
14CPPFLAGS+= -I${MOUNT} 14CPPFLAGS+= -I${MOUNT}
15.PATH: ${MOUNT} 15.PATH: ${MOUNT}
16SRCS+= vfslist.c 16SRCS+= vfslist.c
17.endif 17.endif
 18LDADD+=-lutil
 19DPADD+=${LIBUTIL}
18 20
19COPTS.umount.c+= ${GCC_NO_CAST_FUNCTION_TYPE} 21COPTS.umount.c+= ${GCC_NO_CAST_FUNCTION_TYPE}
20 22
21.include <bsd.prog.mk> 23.include <bsd.prog.mk>

cvs diff -r1.52 -r1.53 src/sbin/umount/umount.c (switch to unified diff)

--- src/sbin/umount/umount.c 2016/06/26 04:01:30 1.52
+++ src/sbin/umount/umount.c 2020/04/23 04:21:13 1.53
@@ -1,452 +1,462 @@ @@ -1,452 +1,462 @@
1/* $NetBSD: umount.c,v 1.52 2016/06/26 04:01:30 dholland Exp $ */ 1/* $NetBSD: umount.c,v 1.53 2020/04/23 04:21:13 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1980, 1989, 1993 4 * Copyright (c) 1980, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors 15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software 16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission. 17 * without specific prior written permission.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#ifndef lint 33#ifndef lint
34__COPYRIGHT("@(#) Copyright (c) 1980, 1989, 1993\ 34__COPYRIGHT("@(#) Copyright (c) 1980, 1989, 1993\
35 The Regents of the University of California. All rights reserved."); 35 The Regents of the University of California. All rights reserved.");
36#endif /* not lint */ 36#endif /* not lint */
37 37
38#ifndef lint 38#ifndef lint
39#if 0 39#if 0
40static char sccsid[] = "@(#)umount.c 8.8 (Berkeley) 5/8/95"; 40static char sccsid[] = "@(#)umount.c 8.8 (Berkeley) 5/8/95";
41#else 41#else
42__RCSID("$NetBSD: umount.c,v 1.52 2016/06/26 04:01:30 dholland Exp $"); 42__RCSID("$NetBSD: umount.c,v 1.53 2020/04/23 04:21:13 christos Exp $");
43#endif 43#endif
44#endif /* not lint */ 44#endif /* not lint */
45 45
46#include <sys/param.h> 46#include <sys/param.h>
47#include <sys/stat.h> 47#include <sys/stat.h>
48#include <sys/mount.h> 48#include <sys/mount.h>
49#include <sys/time.h> 49#include <sys/time.h>
50#ifndef SMALL 50#ifndef SMALL
51#include <sys/socket.h> 51#include <sys/socket.h>
52 52
53#include <netdb.h> 53#include <netdb.h>
54#include <rpc/rpc.h> 54#include <rpc/rpc.h>
55#include <rpc/pmap_clnt.h> 55#include <rpc/pmap_clnt.h>
56#include <rpc/pmap_prot.h> 56#include <rpc/pmap_prot.h>
57#include <nfs/rpcv2.h> 57#include <nfs/rpcv2.h>
58#include <nfs/nfsmount.h> 58#include <nfs/nfsmount.h>
59#endif /* !SMALL */ 59#endif /* !SMALL */
60 60
61#include <err.h> 61#include <err.h>
62#include <errno.h> 62#include <errno.h>
63#include <fstab.h> 63#include <fstab.h>
64#include <stdio.h> 64#include <stdio.h>
65#include <stdlib.h> 65#include <stdlib.h>
66#include <string.h> 66#include <string.h>
67#include <unistd.h> 67#include <unistd.h>
 68#include <util.h>
68 69
69typedef enum { MNTANY, MNTON, MNTFROM } mntwhat; 70typedef enum { MNTANY, MNTON, MNTFROM } mntwhat;
70 71
71#ifndef SMALL 72#ifndef SMALL
72#include "mountprog.h" 73#include "mountprog.h"
73 74
74static int fake, verbose; 75static int fake, verbose;
75static char *nfshost; 76static char *nfshost;
76static struct addrinfo *nfshost_ai = NULL; 77static struct addrinfo *nfshost_ai = NULL;
77 78
78static int namematch(const struct addrinfo *); 79static int namematch(const struct addrinfo *);
79static int sacmp(const struct sockaddr *, const struct sockaddr *); 80static int sacmp(const struct sockaddr *, const struct sockaddr *);
80static int xdr_dir(XDR *, char *); 81static int xdr_dir(XDR *, char *);
81static const char *getmntproto(const char *); 82static const char *getmntproto(const char *);
82#endif /* !SMALL */ 83#endif /* !SMALL */
83 84
84static int fflag; 85static int fflag;
85static char *getmntname(const char *, mntwhat, char **); 86static char *getmntname(const char *, mntwhat, char **);
86static int umountfs(const char *, const char **, int); 87static int umountfs(const char *, const char **, int);
87static void usage(void) __dead; 88static void usage(void) __dead;
88 89
89int 90int
90main(int argc, char *argv[]) 91main(int argc, char *argv[])
91{ 92{
92 int ch, errs, all = 0, raw = 0; 93 int ch, errs, all = 0, raw = 0;
 94 char mntfromname[MAXPATHLEN];
93#ifndef SMALL 95#ifndef SMALL
94 int mnts; 96 int mnts;
95 struct statvfs *mntbuf; 97 struct statvfs *mntbuf;
96 struct addrinfo hints; 98 struct addrinfo hints;
97#endif /* SMALL */ 99#endif /* SMALL */
98 const char **typelist = NULL; 100 const char **typelist = NULL;
99 101
100#ifdef SMALL 102#ifdef SMALL
101#define OPTS "fR" 103#define OPTS "fR"
102#else 104#else
103#define OPTS "AaFfh:Rt:v" 105#define OPTS "AaFfh:Rt:v"
104#endif 106#endif
105 while ((ch = getopt(argc, argv, OPTS)) != -1) 107 while ((ch = getopt(argc, argv, OPTS)) != -1)
106 switch (ch) { 108 switch (ch) {
107 case 'f': 109 case 'f':
108 fflag = MNT_FORCE; 110 fflag = MNT_FORCE;
109 break; 111 break;
110 case 'R': 112 case 'R':
111 raw = 1; 113 raw = 1;
112 break; 114 break;
113#ifndef SMALL 115#ifndef SMALL
114 case 'A': 116 case 'A':
115 case 'a': 117 case 'a':
116 all = 1; 118 all = 1;
117 break; 119 break;
118 case 'F': 120 case 'F':
119 fake = 1; 121 fake = 1;
120 break; 122 break;
121 case 'h': /* -h implies -A. */ 123 case 'h': /* -h implies -A. */
122 all = 1; 124 all = 1;
123 nfshost = optarg; 125 nfshost = optarg;
124 break; 126 break;
125 case 't': 127 case 't':
126 if (typelist != NULL) 128 if (typelist != NULL)
127 errx(1, "only one -t option may be specified."); 129 errx(1, "only one -t option may be specified.");
128 typelist = makevfslist(optarg); 130 typelist = makevfslist(optarg);
129 break; 131 break;
130 case 'v': 132 case 'v':
131 verbose = 1; 133 verbose = 1;
132 break; 134 break;
133#endif /* !SMALL */ 135#endif /* !SMALL */
134 default: 136 default:
135 usage(); 137 usage();
136 /* NOTREACHED */ 138 /* NOTREACHED */
137 } 139 }
138 argc -= optind; 140 argc -= optind;
139 argv += optind; 141 argv += optind;
140 142
141 if ((argc == 0 && !all) || (argc != 0 && all) || (all && raw)) 143 if ((argc == 0 && !all) || (argc != 0 && all) || (all && raw))
142 usage(); 144 usage();
143 145
144#ifndef SMALL 146#ifndef SMALL
145 /* -h implies "-t nfs" if no -t flag. */ 147 /* -h implies "-t nfs" if no -t flag. */
146 if ((nfshost != NULL) && (typelist == NULL)) 148 if ((nfshost != NULL) && (typelist == NULL))
147 typelist = makevfslist("nfs"); 149 typelist = makevfslist("nfs");
148 150
149 if (nfshost != NULL) { 151 if (nfshost != NULL) {
150 memset(&hints, 0, sizeof hints); 152 memset(&hints, 0, sizeof hints);
151 if (getaddrinfo(nfshost, NULL, &hints, &nfshost_ai) != 0) { 153 if (getaddrinfo(nfshost, NULL, &hints, &nfshost_ai) != 0) {
152 nfshost_ai = NULL; 154 nfshost_ai = NULL;
153 } 155 }
154 } 156 }
155  157
156 errs = 0; 158 errs = 0;
157 if (all) { 159 if (all) {
158 if ((mnts = getmntinfo(&mntbuf, ST_NOWAIT)) == 0) { 160 if ((mnts = getmntinfo(&mntbuf, ST_NOWAIT)) == 0) {
159 warn("getmntinfo"); 161 warn("getmntinfo");
160 errs = 1; 162 errs = 1;
161 } 163 }
162 for (errs = 0, mnts--; mnts > 0; mnts--) { 164 for (errs = 0, mnts--; mnts > 0; mnts--) {
163 if (checkvfsname(mntbuf[mnts].f_fstypename, typelist)) 165 if (checkvfsname(mntbuf[mnts].f_fstypename, typelist))
164 continue; 166 continue;
165 if (umountfs(mntbuf[mnts].f_mntonname, typelist, 167 if (umountfs(mntbuf[mnts].f_mntonname, typelist,
166 1) != 0) 168 1) != 0)
167 errs = 1; 169 errs = 1;
168 } 170 }
169 } else  171 } else
170#endif /* !SMALL */ 172#endif /* !SMALL */
171 for (errs = 0; *argv != NULL; ++argv) 173 for (errs = 0; *argv != NULL; ++argv) {
172 if (umountfs(*argv, typelist, raw) != 0) 174 if (getfsspecname(mntfromname, sizeof(mntfromname),
 175 *argv) == NULL)
 176 err(EXIT_FAILURE, "%s", mntfromname);
 177 if (umountfs(mntfromname, typelist, raw) != 0)
173 errs = 1; 178 errs = 1;
 179 }
174 return errs; 180 return errs;
175} 181}
176 182
177static int 183static int
178umountfs(const char *name, const char **typelist, int raw) 184umountfs(const char *name, const char **typelist, int raw)
179{ 185{
180#ifndef SMALL 186#ifndef SMALL
181 enum clnt_stat clnt_stat; 187 enum clnt_stat clnt_stat;
182 struct timeval try; 188 struct timeval try;
183 CLIENT *clp; 189 CLIENT *clp;
184 char *hostp = NULL; 190 char *hostp = NULL;
185 struct addrinfo *ai = NULL, hints; 191 struct addrinfo *ai = NULL, hints;
186 const char *proto = NULL; 192 const char *proto = NULL;
187#endif /* !SMALL */ 193#endif /* !SMALL */
188 const char *mntpt; 194 const char *mntpt;
189 char *type, rname[MAXPATHLEN], umountprog[MAXPATHLEN]; 195 char *type, rname[MAXPATHLEN], umountprog[MAXPATHLEN];
190 mntwhat what; 196 mntwhat what;
191 struct stat sb; 197 struct stat sb;
192 198
193 if (raw) { 199 if (raw) {
194 mntpt = name; 200 mntpt = name;
195 } else { 201 } else {
196 202
197 what = MNTANY; 203 what = MNTANY;
198 if (realpath(name, rname) != NULL) { 204 if (realpath(name, rname) != NULL) {
199 name = rname; 205 name = rname;
200 206
201 if (stat(name, &sb) == 0) { 207 if (stat(name, &sb) == 0) {
202 if (S_ISBLK(sb.st_mode)) 208 if (S_ISBLK(sb.st_mode))
203 what = MNTON; 209 what = MNTON;
204 else if (S_ISDIR(sb.st_mode)) 210 else if (S_ISDIR(sb.st_mode))
205 what = MNTFROM; 211 what = MNTFROM;
206 } 212 }
207 } 213 }
208#ifdef SMALL 214#ifdef SMALL
209 else { 215 else {
210 warn("%s", name); 216 warn("%s", name);
211 return 1; 217 return 1;
212 } 218 }
213#endif /* SMALL */ 219#endif /* SMALL */
214 mntpt = name; 220 mntpt = name;
215 221
216 switch (what) { 222 switch (what) {
217 case MNTON: 223 case MNTON:
218 if ((mntpt = getmntname(name, MNTON, &type)) == NULL) { 224 if ((mntpt = getmntname(name, MNTON, &type)) == NULL) {
219 warnx("%s: not currently mounted", name); 225 warnx("%s: not currently mounted", name);
220 return (1); 226 return (1);
221 } 227 }
222 break; 228 break;
223 case MNTFROM: 229 case MNTFROM:
224 if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) { 230 if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) {
225 warnx("%s: not currently mounted", mntpt); 231 warnx("%s: not currently mounted", mntpt);
226 return (1); 232 return (1);
227 } 233 }
228 break; 234 break;
229 default: 235 default:
230 if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) { 236 if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) {
231 name = mntpt; 237 name = mntpt;
232 if ((mntpt = getmntname(name, MNTON, &type)) == NULL) { 238 if ((mntpt = getmntname(name, MNTON, &type)) == NULL) {
233 warnx("%s: not currently mounted", name); 239 warnx("%s: not currently mounted", name);
234 return 1; 240 return 1;
235 } 241 }
236 } 242 }
237 } 243 }
238 244
239#ifndef SMALL 245#ifndef SMALL
240 if (checkvfsname(type, typelist)) 246 if (checkvfsname(type, typelist))
241 return 1; 247 return 1;
242 248
243 (void)memset(&hints, 0, sizeof hints); 249 (void)memset(&hints, 0, sizeof hints);
244 if (!strncmp(type, MOUNT_NFS, 250 if (!strncmp(type, MOUNT_NFS,
245 sizeof(((struct statvfs *)NULL)->f_fstypename))) { 251 sizeof(((struct statvfs *)NULL)->f_fstypename))) {
246 char *delimp; 252 char *delimp;
247 proto = getmntproto(mntpt); 253 proto = getmntproto(mntpt);
248 /* look for host:mountpoint */ 254 /* look for host:mountpoint */
249 if ((delimp = strrchr(name, ':')) != NULL) { 255 if ((delimp = strrchr(name, ':')) != NULL) {
250 int len = delimp - name; 256 int len = delimp - name;
251 hostp = malloc(len + 1); 257 hostp = malloc(len + 1);
252 if (hostp == NULL) 258 if (hostp == NULL)
253 return 1; 259 return 1;
254 memcpy(hostp, name, len); 260 memcpy(hostp, name, len);
255 hostp[len] = 0; 261 hostp[len] = 0;
256 name += len + 1; 262 name += len + 1;
257 if (getaddrinfo(hostp, NULL, &hints, &ai) != 0) 263 if (getaddrinfo(hostp, NULL, &hints, &ai) != 0)
258 ai = NULL; 264 ai = NULL;
259 } 265 }
260 } 266 }
261 267
262 if (!namematch(ai)) 268 if (!namematch(ai))
263 return 1; 269 return 1;
264#endif /* ! SMALL */ 270#endif /* ! SMALL */
265 snprintf(umountprog, sizeof(umountprog), "umount_%s", type); 271 snprintf(umountprog, sizeof(umountprog), "umount_%s", type);
266 } 272 }
267 273
268#ifndef SMALL 274#ifndef SMALL
269 if (verbose) { 275 if (verbose) {
270 (void)printf("%s: unmount from %s\n", name, mntpt); 276 (void)printf("%s: unmount from %s\n", name, mntpt);
271 /* put this before the test of FAKE */  277 /* put this before the test of FAKE */
272 if (!raw) { 278 if (!raw) {
273 (void)printf("Trying unmount program %s\n", 279 (void)printf("Trying unmount program %s\n",
274 umountprog); 280 umountprog);
275 } 281 }
276 } 282 }
277 if (fake) 283 if (fake)
278 return 0; 284 return 0;
279#endif /* ! SMALL */ 285#endif /* ! SMALL */
280 286
281 if (!raw) { 287 if (!raw) {
282 /* 288 /*
283 * The only options that need to be passed on are -f 289 * The only options that need to be passed on are -f
284 * and -v. 290 * and -v.
285 */ 291 */
286 char *args[3]; 292 char *args[3];
287 unsigned nargs = 0; 293 unsigned nargs = 0;
288 294
289 args[nargs++] = umountprog; 295 args[nargs++] = umountprog;
290 if (fflag == MNT_FORCE) { 296 if (fflag == MNT_FORCE) {
291 args[nargs++] = __UNCONST("-f"); 297 args[nargs++] = __UNCONST("-f");
292 } 298 }
293#ifndef SMALL 299#ifndef SMALL
294 if (verbose) { 300 if (verbose) {
295 args[nargs++] = __UNCONST("-v"); 301 args[nargs++] = __UNCONST("-v");
296 } 302 }
297#endif 303#endif
298 execvp(umountprog, args); 304 execvp(umountprog, args);
299 if (errno != ENOENT) { 305 if (errno != ENOENT) {
300 warn("%s: execvp", umountprog); 306 warn("%s: execvp", umountprog);
301 } 307 }
302 } 308 }
303 309
304#ifndef SMALL 310#ifndef SMALL
305 if (verbose) 311 if (verbose)
306 (void)printf("(No separate unmount program.)\n"); 312 (void)printf("(No separate unmount program.)\n");
307#endif 313#endif
308 314
309 if (unmount(mntpt, fflag) == -1) { 315 if (unmount(mntpt, fflag) == -1) {
310 warn("%s", mntpt); 316 warn("%s", mntpt);
311 return 1; 317 return 1;
312 } 318 }
313 319
314#ifndef SMALL 320#ifndef SMALL
315 if (ai != NULL && !(fflag & MNT_FORCE)) { 321 if (ai != NULL && !(fflag & MNT_FORCE)) {
316 clp = clnt_create(hostp, RPCPROG_MNT, RPCMNT_VER1, proto); 322 clp = clnt_create(hostp, RPCPROG_MNT, RPCMNT_VER1, proto);
317 if (clp == NULL) { 323 if (clp == NULL) {
318 clnt_pcreateerror("Cannot MNT PRC"); 324 clnt_pcreateerror("Cannot MNT PRC");
319 return 1; 325 return 1;
320 } 326 }
321 clp->cl_auth = authsys_create_default(); 327 clp->cl_auth = authsys_create_default();
322 try.tv_sec = 20; 328 try.tv_sec = 20;
323 try.tv_usec = 0; 329 try.tv_usec = 0;
324 clnt_stat = clnt_call(clp, RPCMNT_UMOUNT, xdr_dir, 330 clnt_stat = clnt_call(clp, RPCMNT_UMOUNT, xdr_dir,
325 __UNCONST(name), xdr_void, NULL, try); 331 __UNCONST(name), xdr_void, NULL, try);
326 if (clnt_stat != RPC_SUCCESS) { 332 if (clnt_stat != RPC_SUCCESS) {
327 clnt_perror(clp, "Bad MNT RPC"); 333 clnt_perror(clp, "Bad MNT RPC");
328 return 1; 334 return 1;
329 } 335 }
330 auth_destroy(clp->cl_auth); 336 auth_destroy(clp->cl_auth);
331 clnt_destroy(clp); 337 clnt_destroy(clp);
332 } 338 }
333#endif /* ! SMALL */ 339#endif /* ! SMALL */
334 return 0; 340 return 0;
335} 341}
336 342
337static char * 343static char *
338getmntname(const char *name, mntwhat what, char **type) 344getmntname(const char *name, mntwhat what, char **type)
339{ 345{
340 static struct statvfs *mntbuf; 346 static struct statvfs *mntbuf;
341 static int mntsize; 347 static int mntsize;
 348 static char mntfromname[MAXPATHLEN];
342 int i; 349 int i;
343 350
344 if (mntbuf == NULL && 351 if (mntbuf == NULL &&
345 (mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { 352 (mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
346 warn("getmntinfo"); 353 warn("getmntinfo");
347 return (NULL); 354 return (NULL);
348 } 355 }
349 for (i = mntsize - 1; i >= 0; i--) { 356 for (i = mntsize - 1; i >= 0; i--) {
350 if ((what == MNTON) && !strcmp(mntbuf[i].f_mntfromname, name)) { 357 if ((what == MNTON) && !strcmp(mntbuf[i].f_mntfromname, name)) {
351 if (type) 358 if (type)
352 *type = mntbuf[i].f_fstypename; 359 *type = mntbuf[i].f_fstypename;
353 return (mntbuf[i].f_mntonname); 360 return (mntbuf[i].f_mntonname);
354 } 361 }
355 if ((what == MNTFROM) && !strcmp(mntbuf[i].f_mntonname, name)) { 362 if ((what == MNTFROM) && !strcmp(mntbuf[i].f_mntonname, name)) {
356 if (type) 363 if (type)
357 *type = mntbuf[i].f_fstypename; 364 *type = mntbuf[i].f_fstypename;
358 return (mntbuf[i].f_mntfromname); 365 if (getfsspecname(mntfromname, sizeof(mntfromname),
 366 mntbuf[i].f_mntfromname) == NULL)
 367 err(EXIT_FAILURE, "%s", mntfromname);
 368 return mntfromname;
359 } 369 }
360 } 370 }
361 return (NULL); 371 return (NULL);
362} 372}
363 373
364#ifndef SMALL 374#ifndef SMALL
365static int 375static int
366sacmp(const struct sockaddr *sa1, const struct sockaddr *sa2) 376sacmp(const struct sockaddr *sa1, const struct sockaddr *sa2)
367{ 377{
368 const void *p1, *p2; 378 const void *p1, *p2;
369 size_t len; 379 size_t len;
370 380
371 if (sa1->sa_family != sa2->sa_family) 381 if (sa1->sa_family != sa2->sa_family)
372 return 1; 382 return 1;
373 383
374 switch (sa1->sa_family) { 384 switch (sa1->sa_family) {
375 case AF_INET: 385 case AF_INET:
376 p1 = &((const struct sockaddr_in *)sa1)->sin_addr; 386 p1 = &((const struct sockaddr_in *)sa1)->sin_addr;
377 p2 = &((const struct sockaddr_in *)sa2)->sin_addr; 387 p2 = &((const struct sockaddr_in *)sa2)->sin_addr;
378 len = 4; 388 len = 4;
379 break; 389 break;
380 case AF_INET6: 390 case AF_INET6:
381 p1 = &((const struct sockaddr_in6 *)sa1)->sin6_addr; 391 p1 = &((const struct sockaddr_in6 *)sa1)->sin6_addr;
382 p2 = &((const struct sockaddr_in6 *)sa2)->sin6_addr; 392 p2 = &((const struct sockaddr_in6 *)sa2)->sin6_addr;
383 len = 16; 393 len = 16;
384 if (((const struct sockaddr_in6 *)sa1)->sin6_scope_id != 394 if (((const struct sockaddr_in6 *)sa1)->sin6_scope_id !=
385 ((const struct sockaddr_in6 *)sa2)->sin6_scope_id) 395 ((const struct sockaddr_in6 *)sa2)->sin6_scope_id)
386 return 1; 396 return 1;
387 break; 397 break;
388 default: 398 default:
389 return 1; 399 return 1;
390 } 400 }
391 401
392 return memcmp(p1, p2, len); 402 return memcmp(p1, p2, len);
393} 403}
394 404
395static int 405static int
396namematch(const struct addrinfo *ai) 406namematch(const struct addrinfo *ai)
397{ 407{
398 struct addrinfo *aip; 408 struct addrinfo *aip;
399 409
400 if (nfshost == NULL || nfshost_ai == NULL) 410 if (nfshost == NULL || nfshost_ai == NULL)
401 return (1); 411 return (1);
402 412
403 while (ai != NULL) { 413 while (ai != NULL) {
404 aip = nfshost_ai; 414 aip = nfshost_ai;
405 while (aip != NULL) { 415 while (aip != NULL) {
406 if (sacmp(ai->ai_addr, aip->ai_addr) == 0) 416 if (sacmp(ai->ai_addr, aip->ai_addr) == 0)
407 return 1; 417 return 1;
408 aip = aip->ai_next; 418 aip = aip->ai_next;
409 } 419 }
410 ai = ai->ai_next; 420 ai = ai->ai_next;
411 } 421 }
412 422
413 return 0; 423 return 0;
414} 424}
415 425
416/* 426/*
417 * xdr routines for mount rpc's 427 * xdr routines for mount rpc's
418 */ 428 */
419static int 429static int
420xdr_dir(XDR *xdrsp, char *dirp) 430xdr_dir(XDR *xdrsp, char *dirp)
421{ 431{
422 return xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN); 432 return xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN);
423} 433}
424 434
425static const char * 435static const char *
426getmntproto(const char *name) 436getmntproto(const char *name)
427{ 437{
428 struct nfs_args nfsargs; 438 struct nfs_args nfsargs;
429 struct sockaddr_storage ss; 439 struct sockaddr_storage ss;
430 440
431 nfsargs.sotype = SOCK_DGRAM; 441 nfsargs.sotype = SOCK_DGRAM;
432 nfsargs.addr = (struct sockaddr *)&ss;  442 nfsargs.addr = (struct sockaddr *)&ss;
433 nfsargs.addrlen = sizeof(ss); 443 nfsargs.addrlen = sizeof(ss);
434 (void)mount("nfs", name, MNT_GETARGS, &nfsargs, sizeof(nfsargs)); 444 (void)mount("nfs", name, MNT_GETARGS, &nfsargs, sizeof(nfsargs));
435 return nfsargs.sotype == SOCK_STREAM ? "tcp" : "udp"; 445 return nfsargs.sotype == SOCK_STREAM ? "tcp" : "udp";
436} 446}
437#endif /* !SMALL */ 447#endif /* !SMALL */
438 448
439static void 449static void
440usage(void) 450usage(void)
441{ 451{
442#ifdef SMALL 452#ifdef SMALL
443 (void)fprintf(stderr, 453 (void)fprintf(stderr,
444 "Usage: %s [-fR] special | node\n", getprogname()); 454 "Usage: %s [-fR] special | node\n", getprogname());
445#else 455#else
446 (void)fprintf(stderr, 456 (void)fprintf(stderr,
447 "Usage: %s [-fvFR] [-t fstypelist] special | node\n" 457 "Usage: %s [-fvFR] [-t fstypelist] special | node\n"
448 "\t %s -a[fvF] [-h host] [-t fstypelist]\n", getprogname(), 458 "\t %s -a[fvF] [-h host] [-t fstypelist]\n", getprogname(),
449 getprogname()); 459 getprogname());
450#endif /* SMALL */ 460#endif /* SMALL */
451 exit(1); 461 exit(1);
452} 462}